|
DDS, dds с 40-разрядным сумматором |
|
|
|
Sep 28 2012, 07:03
|
Участник

Группа: Участник
Сообщений: 23
Регистрация: 8-09-12
Пользователь №: 73 445

|
Вообщем, в продолжение темы многоразрядного накопительного сумматора... Удалось-таки его написать, но при моделировании с учетом задержек в кристалле (после place&route) оказалось, что при суммировании числа (1111... + A) происходит огроменная задержка (т.е. старшие разряды числа долго-долго перекидываются в 0000...). Суммируем по фронту испульса, а значение из таблицы синусов в соответствии с 10 старшими разрядами суммы выдается по срезу. Т.о. задержка суммирования "залазит" на срез. Из-за этого на выход по таблице синусов отчего-то выдается значение, которого в этой таблице в принципе нет!! Тактовая частота 40 МГц, плис Actel apa300. Кто что может посоветовать?
|
|
|
|
|
Sep 28 2012, 09:59
|
Участник

Группа: Участник
Сообщений: 23
Регистрация: 8-09-12
Пользователь №: 73 445

|
Боюсь, что все организованные процессы по фронту могут вызвать "гонки и состязания"...
|
|
|
|
|
Sep 28 2012, 11:06
|
Знающий
   
Группа: Свой
Сообщений: 802
Регистрация: 11-05-07
Из: Томск
Пользователь №: 27 650

|
Цитата(kkosik @ Sep 28 2012, 14:03)  Вообщем, в продолжение темы многоразрядного накопительного сумматора... Удалось-таки его написать, но при моделировании с учетом задержек в кристалле (после place&route) оказалось, что при суммировании числа (1111... + A) происходит огроменная задержка (т.е. старшие разряды числа долго-долго перекидываются в 0000...). Суммируем по фронту испульса, а значение из таблицы синусов в соответствии с 10 старшими разрядами суммы выдается по срезу. Т.о. задержка суммирования "залазит" на срез. Из-за этого на выход по таблице синусов отчего-то выдается значение, которого в этой таблице в принципе нет!! Тактовая частота 40 МГц, плис Actel apa300. Кто что может посоветовать?  На 40 МГц даже 40-разрядный сумматор будет работать без проблем. Сдаётся мне, что вы сумматор этот криво описываете. В общем, код - в студию!
|
|
|
|
|
Sep 28 2012, 14:11
|
Гуру
     
Группа: Свой
Сообщений: 2 198
Регистрация: 23-12-04
Пользователь №: 1 640

|
Цитата(Bad0512 @ Sep 28 2012, 15:06)  На 40 МГц даже 40-разрядный сумматор будет работать без проблем. Сдаётся мне, что вы сумматор этот криво описываете. В общем, код - в студию! с проазиками дело имели? это не ксайлинсы  автору: если накопительный сумматор, то часто (зависит от приложения) его можно описать в виде нескольких коротких сумматоров с защелкиванием CARRY-ей между секциями как-то так always @(posedge clk) begin sum[39:20] <= sum[39:20] + adder[39:20] + co; {co,sum[19:0]} <= {1'b0,sum[19:0]} + adder[19:0]; end ну и так далее, при необходимости можно резать не на 2 а на 3,4,5 и т.д. ---------------- об этом, наверно, Serhiy_UA написал, я просто начал писать до его ответа  нет, там наверно, чуть другое. в моем примере, для разгрузки суматора (если нужны не отдельно старшие биты и каждый такт) нужно конвеер - задержка младший части на такт (регистр), ну и для многоступенчатого суматора - пирамида регистров. если в поток сумирования можно 0 вставлять, то конвеер на выходе не нужен, ну и т.д. - зависит от приложения
|
|
|
|
|
Sep 28 2012, 14:14
|
Участник

Группа: Участник
Сообщений: 23
Регистрация: 8-09-12
Пользователь №: 73 445

|
Цитата На 40 МГц даже 40-разрядный сумматор будет работать без проблем. Сдаётся мне, что вы сумматор этот криво описываете. В общем, код - в студию! Я даже попробовал сделать 2 сумматора. 1) "обычный", складываем два unsigned Код entity adder_simple is port( DataA : in std_logic_vector(31 downto 0); Aclr : in std_logic; Clock : in std_logic; Sum : out std_logic_vector(39 downto 0); Cout : out std_logic); end adder_simple;
architecture behavioral of adder_simple is
signal DataA_unsigned : UNSIGNED(39 downto 0); signal SumAPlusB_unsigned : UNSIGNED(39 downto 0); signal SumOut_unsigned : UNSIGNED(39 downto 0);
begin DataA_unsigned <= resize(UNSIGNED(DataA),40);
process (DataA_unsigned, SumOut_unsigned) variable sumAux_unsigned : UNSIGNED(40 downto 0);
begin sumAux_unsigned := ('0' & DataA_unsigned) + ('0' & SumOut_unsigned); SumAPlusB_unsigned <= sumAux_unsigned(39 downto 0); Cout <= not(std_logic(sumAux_unsigned (40))); end process;
process (AClr, Clock) begin if (Aclr = '1') then SumOut_unsigned <= TO_UNSIGNED(0, 40); elsif (Clock'event and Clock = '1')then SumOut_unsigned <= SumAPlusB_unsigned; end if; end process;
Sum <= std_logic_vector(SumOut_unsigned(39 downto 0));
end behavioral; 2) с ускоренным переносом. За основу взят код ускоренного сумматора из книжки VHDL: Справочное пособие по основам языка: Код entity adder_fast is port( DataA : in std_logic_vector(31 downto 0); Aclr : in std_logic; Clock : in std_logic; Sum : out std_logic_vector(39 downto 0); carry_out : out std_logic); end adder_fast;
architecture behavioral of adder_fast is
signal h_sum : unsigned(39 downto 0); signal carry_generate : unsigned(39 downto 0); signal carry_propogate : unsigned(39 downto 0); signal carry_in_internal : unsigned(39 downto 1);
signal sumout : unsigned(39 downto 0);
signal dataA_unsigned : unsigned(39 downto 0);
begin dataA_unsigned <= resize(UNSIGNED(DataA),40); h_sum <= dataA_unsigned xor sumout; carry_generate <= dataA_unsigned and sumout; carry_propogate <= dataA_unsigned or sumout;
process(carry_generate,carry_propogate,carry_in_internal) begin carry_in_internal(1) <= carry_generate(0); inst: for i in 1 to 38 loop carry_in_internal(i+1) <= carry_generate(i) or (carry_propogate(i) and carry_in_internal(i)); end loop;
carry_out <= carry_generate(39) or (carry_propogate(39) and carry_in_internal(39)); end process; process(AClr, Clock) begin if(Aclr = '1') then sumout <= TO_UNSIGNED(0, 40); elsif (Clock'event and Clock = '1')then sumout(0) <= h_sum(0) xor '0'; sumout(39 downto 1) <= h_sum(39 downto 1) xor carry_in_internal(39 downto 1); end if; end process; Sum <= std_logic_vector(sumout); end behavioral; Позже выложу графики из modelsim. Цитата always @(posedge clk) begin sum[39:20] <= sum[39:20] + adder[39:20] + co; {co,sum[19:0]} <= {1'b0,sum[19:0]} + adder[19:0]; end эммм, я vhdl учу. verilog воспринимаю пока что с трудом... Не могли бы переконвертировать? суть, в принципе, ясна. но вот эти {} ???
|
|
|
|
|
Sep 28 2012, 14:23
|
Гуру
     
Группа: Свой
Сообщений: 2 198
Регистрация: 23-12-04
Пользователь №: 1 640

|
Цитата(kkosik @ Sep 28 2012, 18:14)  эммм, я vhdl учу. verilog воспринимаю пока что с трудом... Не могли бы переконвертировать? суть, в принципе, ясна. но вот эти {} ??? в VHDL это co & sum по моему тоже может быть lvalue, ну или в скобочках то есть вектор на 1 битик длинее или добавьте еще один разряд
|
|
|
|
|
Sep 28 2012, 15:03
|
Участник

Группа: Участник
Сообщений: 23
Регистрация: 8-09-12
Пользователь №: 73 445

|
Это сумматор №1. Собственно, "обычный" сумматор. Из-за наличия задержки такой, на работе попросили что-нибудь придумать, чтобы быстрее суммировал...  После этого сделал в проекте 2 сумматора: обычный и с ускоренным переносом, дабы сравнить. Получилось, что пока при сложении мало разрядов "переносятся", 2-ой сумматор быстрее. А когда много - задержка больше:  Цитата в моем примере, для разгрузки суматора (если нужны не отдельно старшие биты и каждый такт) Как раз нужно суммировать число в 32 разряда и 40-разрядное число, а на выход только старшие 10 разрядов!
|
|
|
|
|
Sep 28 2012, 15:27
|
Профессионал
    
Группа: Свой
Сообщений: 1 088
Регистрация: 20-10-09
Из: Химки
Пользователь №: 53 082

|
Я так понимаю, что и Serhiy_UA и yes предложили Вам обычную конвейерную реализацию сумматора http://www.masters.donntu.edu.ua/2012/fknt...l/ACIT_2012.htmрис.1 Он будет работать быстрее, но имеет латентность. Чем больше уровней - тем быстрее, но и латентность выше. Соответственно, если у Вас есть обратная связь, то данный вариант наврядли подойдет.
|
|
|
|
|
Sep 28 2012, 16:04
|
Знающий
   
Группа: Свой
Сообщений: 802
Регистрация: 11-05-07
Из: Томск
Пользователь №: 27 650

|
Цитата(yes @ Sep 28 2012, 21:11)  с проазиками дело имели? это не ксайлинсы  Не имел. Решил потренироваться. Вот код (всё сделано "втупую", без хитростей с переносами) : Код module adder ( input logic [31:0] data, input logic reset, input logic clk, output logic [39:0] sum, output logic cout );
always_ff@(posedge clk) if(reset) begin sum <= '0; cout <= '0; end else {cout,sum} <= sum + data;
endmodule Собрал всё это в синплифае. Вот кусок репорта синплифая касательно быстродействия : Performance Summary ******************* Worst slack in design: -2.195 Requested Estimated Requested Estimated Clock Clock Starting Clock Frequency Frequency Period Period Slack Type Group ------------------------------------------------------------------------------------------------------------------------ adder|clk 80.4 MHz 68.3 MHz 12.437 14.631 -2.195 inferred Autoconstr_clkgroup_0 ================================================================================ ======================================== Ну то есть по оценкам Синплифая этот сумматор будет работать на 68 МГц. Может конечно Синплифай малость и привирает в сторону оптимизма, но не думаю что очень сильно. Вывод : на 40МГц даже Проасик сможет суммировать 40 битные числа. И никаких танцев с бубном. Автору топика : уберите из вашего дизайна работу по двум фронтам.О безусловном вреде этого писали на этом форуме неоднократно. Мой сорец написан на SV, но сути это не меняет, он делает то же что и ваш код, только сброс у меня синхронный(почему синхронный? - почитайте Кена Чапмена, у него есть хорошая статья на эту тему).
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|