Jump to content
    

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

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

Но мегафункция-то работает! В Квартусе, на Verilog (ну, или AHDL, какая разница).

Смотришь в эту функцию lpm_counter.tdf - ничего не понимаешь :)

Тоже, наверное, индусы писали :)

Share this post


Link to post
Share on other sites

Но мегафункция-то работает! В Квартусе, на Verilog (ну, или AHDL, какая разница).

Если бы еще мегафункция не работала, то это бы вообще ни в какие ворота не лезло. Ведь по сути мегафункция это вставка RPM, а так разработчики синтезатора с языка Verilog сильно упростили себе задачу, положив два с половиной режима LE вместо 4-х %)

Share this post


Link to post
Share on other sites

Если бы еще мегафункция не работала, то это бы вообще ни в какие ворота не лезло.

Вопрос принципиальный. Можно конвертировать из *.tdf в *.v (если б это что-то упростило:), синтезировать счетчик в упакованном виде. Что же не дает? Может быть, настройки какие-то хитрые есть, атрибуты?

Share this post


Link to post
Share on other sites

Вопрос принципиальный. Можно конвертировать из *.tdf в *.v (если б это что-то упростило:), синтезировать счетчик в упакованном виде. Что же не дает? Может быть, настройки какие-то хитрые есть, атрибуты?

не дает, то, что при синтезе tdf используется синтезатор с языка AHDL, а при синтезе с v синтезатор с языка Verilog. И далеко не факт что команда разработчиков обоих синтезаторов была одна и та же. Просто кто-то, в свое время, сильно схалявил, а команда тестеров вовремя эту халяву не заметила. Потом пошли сыклоны, вторые, третьи и как то всем стало не до асексов. Своего рода плевок в вечность (как в свое время с шиной ISA) %)

Share this post


Link to post
Share on other sites

Вопрос принципиальный. Можно конвертировать из *.tdf в *.v

 

Сранивать с tdf некорректно. Это описание по сути - графическое представление lpm функций в текстовом виде (нет понятия в этом языке фронта клока)

При переходе на поведенческое описание - меняется даже стиль описания.

используйте lpm в крайних случаях. Например когда по ресурсам не проходите.

В чем принцип, да еще на ацексе. (5 лет назад рисовал его в максе, если надо в нем и дорисую)

Share this post


Link to post
Share on other sites

Я его сделал (Quartus, Coutner, Carry)! :)

module  CountCarry
#(parameter    WIDTH = 24)
  (
  input        rst,
  input        clk,
  input        clk_en,
  input        cnt_en,
  input        load,
  input        [WIDTH-1:0] data,
  output    [WIDTH-1:0] cnt,
  output    cout, cout2
  );
  
  wire [WIDTH:0] cnt_reg;
  wire [WIDTH:0] cnt_next;
  wire [WIDTH:0] cnt_carry;
  wire [WIDTH:0] cnt_init = {1'b0, data};

  genvar i;
  generate
    for (i=0; i<=WIDTH; i++) begin : dff_gen

      carry  carry
      (
        .in    ((i ? cnt_carry[i-1] : cnt_en) & cnt_reg[i]),
        .out    (cnt_carry[i])
      );

      dffeas  dffeas
      (
        .clk    (clk),
        .d    ((i ? cnt_carry[i-1] : cnt_en) ^ cnt_reg[i]),
        .ena    (clk_en),
        .asdata    (cnt_init[i]),
        .clrn    (rst),
        .sload    (load),
        .q    (cnt_reg[i])
      );
    end
  endgenerate

  assign cnt = cnt_reg[WIDTH-1:0];
  assign cout = cnt_reg[WIDTH];
  assign cout2 = cnt_next[WIDTH];

endmodule

28 ЛЭ для ACEX, один из которых - чисто инвертор для load.

Не зря в хэлпе говорится, что CARRY оставлен для совместимости с проектами на MAXPlus.

Благодарю "коллективный разум" форума, и des00 персонально! :cheers:

Share this post


Link to post
Share on other sites

Я его сделал (Quartus, Coutner, Carry)! :)

хмм, странно в процессе ковыряния я делал что то подобное, давало 50 плиток. Сейчас еще раз проверил дало 28 плиток :biggrin:

Share this post


Link to post
Share on other sites

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

Вот - "правильный" счетчик, со всеми достоинствами - регулярной структурой, предсказуемым быстродействием, и компакный. Только выбирайте синхронный выход переполнения (там их два).

module  CountPrim
#(
  parameter    WIDTH = 8,        // number of bits
  parameter    DIRECT = "UP"        // count direction: "UP" or "DOWN"
  )
  (
  input        rst_n,        // async reset
  input        clk_en,        // clock enable all flip-flops
  input        clk,
  input        cnt_en,        // count enable
  input        load,        // hi-level sync load
  input        [WIDTH-1:0] data,    // data for sync load
  output bit    [WIDTH-1:0] cnt,    // bits of counter
  output bit    rcry,            // ripple carry
  output bit    tcry            // triggered (sync) carry
  );
  
  wire [WIDTH:-1] cnt_cry;

  carry  cryin (
    .in        (cnt_en),
    .out    (cnt_cry[-1]) );

  genvar i;
  generate
    for (i=0; i<WIDTH; i++) begin : bitgen
      if (DIRECT == "DOWN")
        carry  crycnt (
          .in    (cnt_cry[i-1] & !cnt[i]),
          .out    (cnt_cry[i]) );
      else                // "UP"
        carry  crycnt (
          .in    (cnt_cry[i-1] & cnt[i]),
          .out    (cnt_cry[i]) );
      
      dffeas  dffcnt (
        .clk    (clk),
        .d    (cnt_cry[i-1] ^ cnt[i]),
        .ena    (clk_en),
        .asdata    (data[i]),
        .clrn    (rst_n),
        .sload    (load),
        .q    (cnt[i]) );
    end
  endgenerate

  assign rcry = cnt_cry[WIDTH-1];
  dffeas  dffcry (
    .clk    (clk),
    .d    (rcry),
    .ena    (clk_en),
    .clrn    (rst_n),
    .q    (tcry) );
endmodule

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...