Перейти к содержанию
    

При чем тут латентность не понял...

Ну как же - результат счета появляется с задержкой.

(вообще, здесь о сумматоре речь идет, мы уже на счетчик перескочили).

 

Может промоделируете, а потом уж советы?

Да, у вас это уже сделано. Проглядел. Ну и через сколько тактов появится результат для конкретного входного сигнала?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да, у вас это уже сделано. Проглядел. Ну и через сколько тактов появится результат для конкретного входного сигнала?

 

В реальной жизни этих тактов навалом.

А фантастику только в кино снимают.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ну как же - результат счета появляется с задержкой.

(вообще, здесь о сумматоре речь идет, мы уже на счетчик перескочили).

 

1) Про задержку не понял... результат появляется с задержкой всегда.

Если Вы имеете в виду задержку на какое-то число тактов - то в счетчиках на основе

CLA , о котором я пишу результат счета появляется в том-же такте.

 

2) Счетчик - вырожденный случай сумматора/аккумулятора с константой) :-)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В реальной жизни этих тактов навалом.

Это вы топикстартеру скажите.

 

Если Вы имеете в виду задержку на какое-то число тактов - то в счетчиках на основе

CLA , о котором я пишу результат счета появляется в том-же такте.

Можете поподробнее - что это, CLA? А, нашел, в ссылке. Carry LookAhead - как же, говорили об этом на форуме, совсем недавно.

Там тоже есть ограничения по быстродействию. 64 разряда - фантастически выглядит.

Не зря там дальше идет RCLA :)

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Это вы топикстартеру скажите.

 

 

Можете поподробнее - что это, CLA?

 

Carry-look-ahead

 

Вот из таких блоков собирается большей разрядности

(писалось давненько - потому привожу как есть - на AHDL).

Каскадируется соединением c_out с ena.

SUBDESIGN 4bit_cnt
(
    clk        :INPUT;
    res/        :INPUT;
    ena        :INPUT;
    d[3..0]    :INPUT;
    load        :INPUT;
    q[3..0]    :OUTPUT;
    c_out            :OUTPUT;
)
VARIABLE
    flip[3..0]    :DFFE;
BEGIN
    flip[].clk = clk;
    flip[].prn = res/;
    flip[].ena = ena # load;

    IF load THEN
        flip[].d = d[];
    ELSE
        flip[].d = flip[].q - 1;
    END IF;
    
    q[] = flip[];
    c_out = DFF((flip[] == 1), clk, res/, );
END;

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Каскадируется соединением c_out с ena.

Вот на этом каскадировании и возникает конвейер. Потому что следующий счетчик считает не сразу после того, как предыдущий был в состоянии 1111, а в следующем такте.

Я тоже делал практически также счетчик на 24 разряда с перезагрузкой, только выход переноса, подобный вашему, у меня был один. Работать мне нужно было на 100 MHz. А загружать приходилось число, на 2 меньше требуемого периода. Из-за той самой латентности, или как-там еще ее назвать...

P.S. у вас сделано в точности с моим сообщением №28 :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Потому что следующий счетчик считает не сразу после того, как предыдущий был в состоянии 1111, а в следующем такте.

 

Что-то Вы сами запутались и меня путаете.... О чем, собственно спор?

Счетчик работает на вычитание, перенос должен быть когда его значение будет "0000".

Но делается на такт раньше (когда его значение "1111") и задерживается (пайплайнинг или конвейер, если угодно).

и разрешает следующей ступени в каскаде переключиться.

 

Возьмите код, что я привел - промоделируйте и посмотрите.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

О чем, собственно спор?

Пока ехал домой, сообразил, что можно проверять на условие на 1 меньше (или больше в вашем случае, для вычитающего счетчика). И тогда, действительно, код всего счетчика будет изменяться, как положено. Получается, так можно сделать счетчик любой длины. Если делать счетчик с перезагрузкой, придется с загружаемыми кодами "поработать".

Но это работает для счетчика. Для сумматора нельзя предсказать, когда он должен выработать перенос заранее. Допустим, сумматор насчитал 0xfe, откуда знать, что придет на вход для суммирования?

 

P.S. Насчет кода от sazh - это самое подходящее решение для поставленной задачи. Оно работает благодаря тому, что входные данные - 8-разрядные. Поэтому за один такт нужно выполнять суммирование 8 разрядов входного сигнала с 8-разрядной накопленной суммой. Старшие разряды накопленной суммы можно вычислять в следующем такте. Если бы, однако, входное слово имело все 24 разряда, конвейерная обработка была бы невозможна.

upd. то же самое и у DmitryR (я, кажется, слегка попутал эти коды, когда отвечал)

P.P.S. Приведу ссылку на разговор в не столь отдаленном прошлом

http://electronix.ru/forum/index.php?showt...st&p=732059

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

спасибо всем за ответы

 

только что сделал сумматор по методу DmitryR. Сразу и не допер в чем его фишка, а оказалось очень красиво и ресурсов мало ест.

 

однако появились новые подводные камни в проекте - общая частота проекта маловастая.

 

Квартус 6.0. Выставляю нужную мне частоту в Individual Clocks... - квартус не вытягивает заданную 150 МГц.

 

 

стал использовать Physical Syntesys Optimization - установил все галочки. И вроде бы частота выдержалась нужная = 150 МГц.

Однако ради чистоты эксперимента немного убавил требуемую частоту в Individual Clocks... = 145 МГц

 

и теперь, даже при включенном Physical Syntesys Optimization, частота проекта провалилась Мегагерц на 10.

 

Возвращаю на исходную 150 МГц в Individual Clocks... и все норм становится.

 

Если повышать частоту в Individual Clocks... - снова провал...

 

Почему так?

 

 

 

 

 

 

 

 

 

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Если бы, однако, входное слово имело все 24 разряда, конвейерная обработка была бы невозможна.

 

Сегодня, явно не Ваш день.

module pipelined_accumulator //XAPP 039.001
(
input          clk,
input          rst,
input  [17:0] data,
output [17:0] result
);

reg [17:0] sync_reg = 18'd0;
reg  [7:0] regh_in = 8'd0;
reg  [9:0] accum_l = 10'd0;
reg           reg_crry = 1'b0;
reg  [7:0] accum_h = 8'd0;
reg  [9:0] regl_out = 10'd0;

wire [9:0] alu_l;
wire       cout;
wire       cin;
wire [7:0] alu_h;

always @ (posedge clk or posedge rst)
begin
if (rst)
    begin
    sync_reg <= 18'd0;
    regh_in <= 8'd0;
    accum_l <= 10'd0;
    reg_crry <= 1'b0;
    accum_h <= 8'd0;
    regl_out <= 10'd0;
    end
else
    begin
    sync_reg <= data;
    regh_in <= sync_reg[17:10];
    accum_l <= alu_l;
    reg_crry <= cout;
    accum_h <= alu_h;
    regl_out <= accum_l;
    end
end

assign result = {accum_h, regl_out};
///////////////////
add_10
    add_10_inst
        (
        .dataa        (accum_l),
        .datab        (sync_reg[9:0]),
        .cout        (cout),
        .result        (alu_l)
        );

add_8
    add_8_inst
        (
        .cin        (reg_crry),
        .dataa        (regh_in),
        .datab        (accum_h),
        .result        (alu_h)
        );

endmodule

 

 

Квартус 6.0.

 

Впечатляет.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 sazh

 

Пока я читаю ваш код, сходите по приведенной мной ссылке. И прокомментируйте, если можно.

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

И прокомментируйте, если можно.

 

Там ручная работа.

А это - поведенческое описание для получения приемлемого результата.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Почему так?

Непонятно, что Вы делаете.

Кстати, если модифицировать мой код под Ваши условия, получится код DmitryR. И результат на EPM1270T144A5 - 201МГц в MAXII, что с Таймквестом, что с Classic TA. Может, стоит обновить версию Quartus?

 

И что еще хуже, вот такой код дает 175МГц:

module testadd
(
input clk, input rst,
input [7:0] dataa,
output reg [23:0] result
);

reg [7:0] datareg;

always @ (negedge rst or posedge clk)
begin
    if (!rst)
    begin
        result <= 0;
        datareg <= 0;
    end
    else
    begin
        datareg <= dataa;
        result <= result+datareg;
    end
end

endmodule

 

О чем три страницы написали? :)

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 sazh

Разобрался в вашем коде. Вот это меня, действительно, впечатлило! Теперь мне уже странно, что до сих пор я пребывал в уверенности, что подобное невозможно. А оказалось все просто. Это ж можно ценой латентности складывать сколь угодно большие числа с максимальным быстродействием, невзирая на обратную связь.

 

О чем три страницы написали?

а я выставил в настройках "отображать 80 (кажется) сообщений на странице", и у меня все на одной:)

 

upd. Q9.1SP2 для последнего кода и той же микросхемы выдал "реалистичных" 127.88 MHz при оптимизации Balanced или Speed. Может быть, что-то нужно подкрутить в настройках?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

сделал в 8.0.

 

частота проекта стала равной нужной при включенном Physical Syntesys Optimization; без него не дотягивает 10 МГц.

Так можно его (Physical Syntesys Optimization) использовать?

 

 

спасибо

Изменено пользователем essev

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...