Jump to content
    

Счетчик на примитивах CARRY_SUM и DFFE

Хотел написать, что у меня сложилось впечатление, что Альтеровцы в Quartus намеренно душат семейства, не рекомендуемые к новым разработкам.

Но Stratix IV ??

Share this post


Link to post
Share on other sites

Приоритетность нарушаю? :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

Share this post


Link to post
Share on other sites

Приведите свой модуль.

 

как разберусь откуда берутся лишние плитки приведу %)

 

и вот опять старый мега баг квартуса, с неумением работать с сигналом 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 такого эффекта нет

Share this post


Link to post
Share on other sites

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 ой версии %)

Share this post


Link to post
Share on other sites

Ну накрутили. Снимаю шляпу.

Хотел, чтобы загрузка в ACEX шла нулем, согласно архитектуре.

Ваш пример работает в Cyclone III быстрее. Наверное, потому, что в Циклон загрузка идет единицей sload .

 

to des00

Посмотрите на картинку для последнего slon'а.

По-моему, все проблемы в сигнале cnt_en, который, вообще говоря, хрен знает зачем нужен. Есть же clk_en.

post-10362-1270803656_thumb.jpg

Share this post


Link to post
Share on other sites

Посмотрите на картинку для последнего slon'а.

я думал что вы уже поняли что квартусовскому RTL вьюверу не верю и им не пользуюсь. Только Technology mapper. %)

 

По-моему, все проблемы в сигнале cnt_en, который, вообще говоря, хрен знает зачем нужен. Есть же clk_en.

Ну почему, нужна вещь в некоторых применениях. Да и в мегафункции lpm_counter он был с ее основания %)

Share this post


Link to post
Share on other sites

Смотрю в картинку "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.

Вот и получается, что без примитивов перфект-качества не получить?

Share this post


Link to post
Share on other sites

Не могу представить, как можно сделать сумматор для счетчика, и обходной путь, когда 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 есть). Ребята с альтеры сэкономили, архитектуру чипа улучшили, а вот маппер похоже оставили от второго сыклона. Индусы блин %(

post-3453-1270866083_thumb.png

post-3453-1270866089_thumb.png

Share this post


Link to post
Share on other sites

Приколы продолжаются.

"Хэндмэйд" 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), то цепи переноса из разряда в разряд не используются.

Share this post


Link to post
Share on other sites

Приколы продолжаются.

"Хэндмэйд" 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), то цепи переноса из разряда в разряд не используются.

это не удивительно и достаточно очевидно %)

Share this post


Link to post
Share on other sites

у меня 9.0сп2 собрал без каких либо проблем

У меня 9.0 без СП, придется по-новее пошукать.

 

а так,...

...не работает, потому что нет сумматора. Об этом я уже писал в начале.

Я уже было обрадовался - вот оно!

Похоже, остался еще шаг до цели :)

 

это не удивительно и достаточно очевидно %)

Точно! Где можно обойтись параллельным выполнением операции, последовательное не нужно.

Share this post


Link to post
Share on other sites

...не работает, потому что нет сумматора. Об этом я уже писал в начале.

а так

    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

это не сумматор, это всего лишь указание использовать быстрые цепи переноса

post-3453-1270971918_thumb.png

Share this post


Link to post
Share on other sites

это не сумматор, это всего лишь указание использовать быстрые цепи переноса

Ja-ja, naturlich! (как-то так :)

Меня терзает предчувствие, что не упакуется сумматор с триггерами даже если между ними и забить CARRY_SUM.

 

У ацекса одна судьба - пакет max+II

Все больше склоняюсь к этому. Уже проверил, где там у меня MAXPlus+II инсталлятор :)

Share this post


Link to post
Share on other sites

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] )
    );

Share this post


Link to post
Share on other sites

Путем ковыряния даташита на асекс и квартуса у меня сложилось следующее понимание : альтеровцы как всегда всех ввели в заблуждение. Режим работы ячейки асекса 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.

 

Вывод : Надо пользовать в таких тяжелых случаях мегафункцию и не париться %)

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...