ViKo 1 April 8, 2010 Posted April 8, 2010 · Report post Хотел написать, что у меня сложилось впечатление, что Альтеровцы в Quartus намеренно душат семейства, не рекомендуемые к новым разработкам. Но Stratix IV ?? Quote Share this post Link to post Share on other sites More sharing options...
sazh 9 April 8, 2010 Posted April 8, 2010 · Report post Приоритетность нарушаю? :unsure: Ну накрутили. Снимаю шляпу. module CountDownReload #(parameter PERIOD = 16) ( input Reset_n, Clock, Enable, output reg [WIDTH:0] Count ); localparam WIDTH = clogb2(PERIOD); function integer clogb2 (input [31:0] value); if (value < 2) clogb2 = 1; else begin value = value - 1; for (clogb2 = 0; value > 0; clogb2 = clogb2 + 1) value = value >> 1; end endfunction always @(negedge Reset_n, posedge Clock) if (!Reset_n) Count <= PERIOD-2; else if (Enable) if (Count[WIDTH]) Count <= PERIOD-2; else Count <= Count - 1'b1; endmodule Quote Share this post Link to post Share on other sites More sharing options...
des00 26 April 9, 2010 Posted April 9, 2010 · Report post Приведите свой модуль. как разберусь откуда берутся лишние плитки приведу %) и вот опять старый мега баг квартуса, с неумением работать с сигналом sload %) немного подрихтованный slon module slon ( input clk, input rst, input clk_en, input cnt_en, input [23:0] data, input load, output bit [23:0] cnt, output bit cout, cout2 ); bit [24:0] cnt_reg; wire [24:0] cnt_next = cnt_reg + 1'b1; always_ff @(posedge clk, posedge rst) begin if(rst) begin cnt_reg <= 0; end else begin if(clk_en) begin if(load) begin cnt_reg <= {1'b0, data}; end else begin if(cnt_en) begin cnt_reg <= cnt_next; end end end end end assign cnt = cnt_reg[23:0]; assign cout = cnt_reg[24]; assign cout2 = cnt_next[24]; endmodule 51 плитка, стоит убрать cout2 или sload 26 плиток. Несмотря на то, что согласно "Figure 2–3. Cyclone III Family Devices LEs in Arithmetic Mode" снять сигнал переноса с последнего сумматора можно легко, ква делает для cout2, при наличии сигнала sload, отдельный сумматор. Мозгов ему в этом "крайне сложном" деле не хватает %) С MWLPM_Counter такого эффекта нет Quote Share this post Link to post Share on other sites More sharing options...
des00 26 April 9, 2010 Posted April 9, 2010 · Report post UPD. Ну так и есть, немного хендмейда и те же 26 плиток на третьем сыклоне %) wire [24:0] cnt_reg; wire [24:0] cnt_next = cnt_reg + cnt_en; wire [24:0] cnt_init = {1'b0, data}; genvar i; generate for (i = 0; i < $size(cnt_reg); i++) begin : dff_gen dffeas dffeas ( .clk ( clk ) , .d ( cnt_next [i] ) , .ena ( clk_en ) , .asdata ( cnt_init [i] ) , .clrn ( rst ) , .sload ( load ) , .q ( cnt_reg [i] ) ); end endgenerate assign cnt = cnt_reg[23:0]; assign cout = cnt_reg[24]; assign cout2 = cnt_next[24]; Не любит ква сигнал sload, ох как не любит. Если мне память не изменяет, тянется это еще с 7 ой версии %) Quote Share this post Link to post Share on other sites More sharing options...
ViKo 1 April 9, 2010 Posted April 9, 2010 · Report post Ну накрутили. Снимаю шляпу. Хотел, чтобы загрузка в ACEX шла нулем, согласно архитектуре. Ваш пример работает в Cyclone III быстрее. Наверное, потому, что в Циклон загрузка идет единицей sload . to des00 Посмотрите на картинку для последнего slon'а. По-моему, все проблемы в сигнале cnt_en, который, вообще говоря, хрен знает зачем нужен. Есть же clk_en. Quote Share this post Link to post Share on other sites More sharing options...
des00 26 April 9, 2010 Posted April 9, 2010 · Report post Посмотрите на картинку для последнего slon'а. я думал что вы уже поняли что квартусовскому RTL вьюверу не верю и им не пользуюсь. Только Technology mapper. %) По-моему, все проблемы в сигнале cnt_en, который, вообще говоря, хрен знает зачем нужен. Есть же clk_en. Ну почему, нужна вещь в некоторых применениях. Да и в мегафункции lpm_counter он был с ее основания %) Quote Share this post Link to post Share on other sites More sharing options...
ViKo 1 April 9, 2010 Posted April 9, 2010 · Report post Смотрю в картинку "Figure 2–5. Cyclone III Family Devices LEs in Arithmetic Mode" (у меня 2-5). Не могу представить, как можно сделать сумматор для счетчика, и обходной путь, когда cnt_en запрещает счет, и выход переноса для следующего разряда. Левый нижний мультиплексор сообще нарисован по-идиотски, что выбирает, чем выбирает? Дальше-то просто - sload, data3, clock, ena. Т.е., возможно, это не глюк, а суровая реальность. P.S. Впрочем, и без cnt_en результат тот же :( Upd. Устройство ЛЭ лучше смотреть в Resource Property Editor (который выскакивает в Chip Planner) - там все видно, как надо. День провозился с последним slon'ом, но так и не смог добиться того, что выдал des00 с использованием dffeas. Хочется верить, что это не глюк, а какая-то логическая нестыковка между Verilog и Cyclone. Вот и получается, что без примитивов перфект-качества не получить? Quote Share this post Link to post Share on other sites More sharing options...
des00 26 April 10, 2010 Posted April 10, 2010 · Report post Не могу представить, как можно сделать сумматор для счетчика, и обходной путь, когда cnt_en запрещает счет, и выход переноса для следующего разряда. за счет цепей register bypass можно получить на тех же ресурсах комбинационный и регистровый выход сумматора. в lpm_counter cnt_en запрещает счет, но не запрещает формирование сигнала переноса. Кодом его можно описать двояко : 1) как в приведенном мной коде (кстати в этом случае cout завязан на cnt_en) 2) сумматор сделать константным (развязав cout и cnt_en), но усложнив логику формирования сигнала ena типа так clk_ena & (sload | (~sload & cnt_en)) Upd. Устройство ЛЭ лучше смотреть в Resource Property Editor (который выскакивает в Chip Planner) - там все видно, как надо. мне даташита хватает %) Вот и получается, что без примитивов перфект-качества не получить? вообще ква достаточно оптимально разводит, но вот сей эффект имеет место быть, когда я что-то делаю под альтеру, что должно использовать sload, я пишу два варианта и добавляю `ifdef __USE_ALTERA_MACRO__ %) Хочется верить, что это не глюк, а какая-то логическая нестыковка между Verilog и Cyclone. Вот за что мне нравиться форум, что ответы порой находятся сами собой. Читая ваш вопрос, случайно открыл даташит на второй сыклон и сравнил с третьим. Вуаля. Во втором сыклоне в арифметическом режиме нет register bypass. А ква не хватает ума что бы поставить последний LE в цепочке в нормальный режим (в котором register bypass есть). Ребята с альтеры сэкономили, архитектуру чипа улучшили, а вот маппер похоже оставили от второго сыклона. Индусы блин %( Quote Share this post Link to post Share on other sites More sharing options...
ViKo 1 April 10, 2010 Posted April 10, 2010 · Report post Приколы продолжаются. "Хэндмэйд" des00 отказался укладываться в ACEX1K (Auto device selected by fitter), наверное, каналов не хватило? Error: Cannot route source node "dff_gen[11].dffeas" of type logic cell to destination node "cnt[11]" of type I/O pin Error: Cannot route source node "dff_gen[11].dffeas" of type logic cell to destination node "lpm_add_sub:Add0|addcore:adder|a_csnbuffer:result_node|cs_buffer[11]" of type logic cell Error: Cannot route source node "dff_gen[24].dffeas" of type logic cell to destination node "cout" of type I/O pin Error: Cannot route source node "dff_gen[24].dffeas" of type logic cell to destination node "lpm_add_sub:Add0|addcore:adder|unreg_res_node[24]" of type logic cell Error: Cannot route source node "lpm_add_sub:Add0|addcore:adder|a_csnbuffer:result_node|cs_buffer[5]" of type logic cell to destination node "dff_gen[5].dffeas" of type logic cell Error: Cannot route source node "lpm_add_sub:Add0|addcore:adder|a_csnbuffer:result_node|cs_buffer[7]" of type logic cell to destination node "dff_gen[7].dffeas" of type logic cell Error: Can't find fit Error: Quartus II Fitter was unsuccessful. 7 errors, 0 warnings А в ACEX1K100 - влез. Немного видоизмененный (и только с асинхронным выходом переноса) влез в удвоенное количество ЛЭ. module CounterDFFEAS #(parameter WIDTH = 24) ( input Reset_n, input Clock, input Enable, input Load, input [WIDTH-1:0] Data, output [WIDTH-1:0] CntOut, output POut ); wire [WIDTH-1:0] Count; wire [WIDTH:0] Next = Count + 1; genvar i; generate for (i=0; i<WIDTH; i++) begin : ffc dffeas dffeas ( .d (Next[i]), .clk (Clock), .clrn (Reset_n), .ena (Enable), .asdata (Data[i]), .sload (Load), .q (Count[i]) ); end endgenerate assign CntOut = Count; assign POut = Next[WIDTH]; endmodule И только MWLPM_Counter, как уже говорилось, упаковался компактно. Еще одна особенность - если длина счетчика небольшая (смотрел для приведенного выше счетчика при длине 4 на Cyclone III), то цепи переноса из разряда в разряд не используются. Quote Share this post Link to post Share on other sites More sharing options...
des00 26 April 11, 2010 Posted April 11, 2010 · Report post Приколы продолжаются. "Хэндмэйд" des00 отказался укладываться в ACEX1K (Auto device selected by fitter), наверное, каналов не хватило? у меня 9.0сп2 собрал без каких либо проблем а так, wire [24:0] cnt_reg; wire [24:0] cnt_next; wire [24:0] carry_cnt; wire [24:0] cnt_init = {1'b0, data}; genvar i; generate for (i = 0; i < $size(cnt_reg); i++) begin : dff_gen carry_sum carry_sum ( .sin ( cnt_reg [i] ), .cin ( (i == 0) ? 1'b1 : carry_cnt[i-1] ), .sout ( cnt_next [i] ), .cout ( carry_cnt [i] ) ); dffeas dffeas ( .clk ( clk ) , .d ( cnt_next [i] ) , .ena ( clk_en ) , .asdata ( cnt_init [i] ) , .clrn ( rst ) , .sload ( load ) , .q ( cnt_reg [i] ) ); end endgenerate assign cnt = cnt_reg[23:0]; assign cout = cnt_reg[24]; assign cout2 = cnt_next[24]; даже уложился в 27 плиток для асекса (как MWLPM_Counter для него же), и в 1 у плитку для сыклонов %) Еще одна особенность - если длина счетчика небольшая (смотрел для приведенного выше счетчика при длине 4 на Cyclone III), то цепи переноса из разряда в разряд не используются. это не удивительно и достаточно очевидно %) Quote Share this post Link to post Share on other sites More sharing options...
ViKo 1 April 11, 2010 Posted April 11, 2010 · Report post у меня 9.0сп2 собрал без каких либо проблем У меня 9.0 без СП, придется по-новее пошукать. а так,... ...не работает, потому что нет сумматора. Об этом я уже писал в начале. Я уже было обрадовался - вот оно! Похоже, остался еще шаг до цели :) это не удивительно и достаточно очевидно %) Точно! Где можно обойтись параллельным выполнением операции, последовательное не нужно. Quote Share this post Link to post Share on other sites More sharing options...
des00 26 April 11, 2010 Posted April 11, 2010 · Report post ...не работает, потому что нет сумматора. Об этом я уже писал в начале. а так carry_sum carry_sum ( .sin ( cnt_reg [i] ), .cin ( (i == 0) ? cnt_en : carry_cnt[i-1] ), .sout ( cnt_next [i] ), .cout ( carry_cnt [i] ) ); чем не сумматор %))) ЗЫ. Те же 27 плиток %) UPD. бугааа, повелся на поводу у людей, взято из файла altera_primitives.v module carry_sum (sin, cin, sout, cout); input sin; input cin; output sout; output cout; assign sout = sin; assign cout = cin; endmodule это не сумматор, это всего лишь указание использовать быстрые цепи переноса Quote Share this post Link to post Share on other sites More sharing options...
ViKo 1 April 11, 2010 Posted April 11, 2010 · Report post это не сумматор, это всего лишь указание использовать быстрые цепи переноса Ja-ja, naturlich! (как-то так :) Меня терзает предчувствие, что не упакуется сумматор с триггерами даже если между ними и забить CARRY_SUM. У ацекса одна судьба - пакет max+II Все больше склоняюсь к этому. Уже проверил, где там у меня MAXPlus+II инсталлятор :) Quote Share this post Link to post Share on other sites More sharing options...
des00 26 April 11, 2010 Posted April 11, 2010 · Report post Ja-ja, naturlich! (как-то так :) Меня терзает предчувствие, что не упакуется сумматор с триггерами даже если между ними и забить CARRY_SUM. Все больше склоняюсь к этому. Уже проверил, где там у меня MAXPlus+II инсталлятор :) так сумматор получили, теперь осталось только втолковать квартусу что все это ложиться в одну плитку в соответствии с режимом "Clearable Counter Mode" LE асекса указанного в даташите ACEX 1K Programmable Logic Device Family Data Sheet wire [1:0] sum [0 : 24]; wire cnt_en_wire = cnt_en; genvar i; generate for (i = 0; i < $size(cnt_reg); i++) begin : dff_gen assign sum[i][0] = cnt_reg[i] ^ ((i == 0) ? cnt_en_wire : carry_cnt[i-1]); assign sum[i][1] = cnt_reg[i] & ((i == 0) ? cnt_en_wire : carry_cnt[i-1]); carry_sum carry_sum ( .sin ( sum[i][0] ), .cin ( sum[i][1] ), .sout ( cnt_next [i] ), .cout ( carry_cnt [i] ) ); Quote Share this post Link to post Share on other sites More sharing options...
des00 26 April 11, 2010 Posted April 11, 2010 · Report post Путем ковыряния даташита на асекс и квартуса у меня сложилось следующее понимание : альтеровцы как всегда всех ввели в заблуждение. Режим работы ячейки асекса Clearable Counter Mode The clearable counter mode is similar to the up/down counter mode, but it supports a synchronous clear instead of the up/down control. The clear function is substituted for the cascade-in signal in the up/down counter mode. Two 3-input LUTs are used; one generates the counter data, and the other generates the fast carry bit. Synchronous loading is provided by a 2-to-1 multiplexer. The output of this multiplexer is AND ed with a synchronous clear signal. квартусу недоступен, он слишком туп для этого. Он ставит лют в арифметический регистр и sload в такой LE уже не ложиться, (см даташит на асекс). Помимо этого добавление к вышеуказанному коду сигнала sclr раздувает код до 74 плиток, хотя по даташиту это должно лечь в аппаратный AND в LE. Вывод : Надо пользовать в таких тяжелых случаях мегафункцию и не париться %) Quote Share this post Link to post Share on other sites More sharing options...