реклама на сайте
подробности

 
 
> Как сделать большой параллельный параметризируемый сумматор?
count_enable
сообщение Jun 5 2014, 13:30
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 310
Регистрация: 28-01-13
Из: Лондон
Пользователь №: 75 384



Есть N М-битных входов. Числа N и М это параметры в диапазоне N=[2..64], M=[6..16]. Как правильно написать параллельный сумматор, считающий сумму всех входов за один такт? Насколько эффективна такая конструкция в реальном железе? А то такой параллелизм мне очень упрощает задачу. Я конечно знаю что такое loop, но краем уха слышал что для большого количества входов лучше строить дерево из сумматоров вручную.
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
des00
сообщение Jun 5 2014, 23:49
Сообщение #2


Вечный ламер
******

Группа: Модераторы
Сообщений: 7 248
Регистрация: 18-03-05
Из: Томск
Пользователь №: 3 453



Код
module adder_tree
#(
  parameter int pDAT_W =  8 ,
  parameter int pNUM   = 16
)
(
  iclk ,
  iena ,
  idat ,
  oena ,
  odat
);

  //------------------------------------------------------------------------------------------------------
  //
  //------------------------------------------------------------------------------------------------------

  input  logic                iclk            ;
  input  logic                iena            ;
  input  logic [pDAT_W-1 : 0] idat [0 : pNUM-1];
  output logic                oena            ;
  output logic [pDAT_W-1 : 0] odat            ;

  //------------------------------------------------------------------------------------------------------
  //
  //------------------------------------------------------------------------------------------------------

  localparam int cADDER_NUM_PER_STAGE = pNUM/2;
  localparam int cADDER_STAGE_NUM     = clogb2(pNUM);

  logic [pDAT_W-1 : 0] acc[0 : cADDER_STAGE_NUM-1][0 : cADDER_NUM_PER_STAGE-1];
  logic                ena[0 : cADDER_STAGE_NUM-1];

  genvar i, stage;

  generate
    for (stage = 0; stage < cADDER_STAGE_NUM; stage++) begin : adder_stage_gen

      always_ff @(posedge iclk) begin
        ena[stage] <= (stage == 0) ? iena : ena[stage-1];
      end

      for (i = 0; i < (cADDER_NUM_PER_STAGE >> stage); i++) begin : adder_in_stage_gen

        always_ff @(posedge iclk) begin
          if (stage == 0) begin
            if (iena)
              acc[stage][i] <= idat[2*i] + idat[2*i+1];
          end
          else begin
            if (ena[stage-1])
              acc[stage][i] <= acc[stage-1][2*i] + acc[stage-1][2*i+1];
          end
        end

      end // adder_in_stage_gen
    end // adder_stage_gen
  endgenerate

  assign oena = ena[cADDER_STAGE_NUM-1];
  assign odat = acc[cADDER_STAGE_NUM-1][0];

endmodule


--------------------
Go to the top of the page
 
+Quote Post
doom13
сообщение Jun 6 2014, 01:59
Сообщение #3


Профессионал
*****

Группа: Свой
Сообщений: 1 404
Регистрация: 11-03-11
Из: Минск, Беларусь
Пользователь №: 63 539



Цитата(des00 @ Jun 6 2014, 06:59) *

Только не универсальный сумматор получается, работает только для (pNUM == 2^n), как же быть для всех остальных случаев?
Go to the top of the page
 
+Quote Post
des00
сообщение Jun 6 2014, 02:49
Сообщение #4


Вечный ламер
******

Группа: Модераторы
Сообщений: 7 248
Регистрация: 18-03-05
Из: Томск
Пользователь №: 3 453



Цитата(doom13 @ Jun 6 2014, 13:09) *
Только не универсальный сумматор получается, работает только для (pNUM == 2^n), как же быть для всех остальных случаев?

Код
    if (pORDER <= 8) begin : adder_tree_8_gen
      logic [cMULT_W-1 : 0] adder_tree__idat[0 : 7];

      always_comb begin : adder_tree_remap
        int i;
        for (i = 0; i < 8; i++) begin
          adder_tree__idat[i] = (i < pORDER) ? pipa [i] : '0;
        end
      end
  .........

это уж как нить сами .....


--------------------
Go to the top of the page
 
+Quote Post
doom13
сообщение Jun 6 2014, 03:35
Сообщение #5


Профессионал
*****

Группа: Свой
Сообщений: 1 404
Регистрация: 11-03-11
Из: Минск, Беларусь
Пользователь №: 63 539



Цитата(des00 @ Jun 6 2014, 09:59) *

Опять не универсально получается, что со значениями (8 < pNUM < 16), (16 < pNUM < 32) и .т.д. Наверное, придётся схему на два куска бить, часть схемы до максимально возможного 2^n строить по Вашему алгоритму, второй кусок (то, что остаётся) просто сгенерить generate-ом и на выходе сложить. Получится универсальное решение.
Можно как-то применить floor() или что-то подобное для SystemVerilog?
Go to the top of the page
 
+Quote Post
des00
сообщение Jun 6 2014, 04:34
Сообщение #6


Вечный ламер
******

Группа: Модераторы
Сообщений: 7 248
Регистрация: 18-03-05
Из: Томск
Пользователь №: 3 453



Цитата(doom13 @ Jun 6 2014, 14:45) *
Опять не универсально получается, что со значениями (8 < pNUM < 16), (16 < pNUM < 32) и .т.д. Наверное, придётся схему на два куска бить, часть схемы до максимально возможного 2^n строить по Вашему алгоритму, второй кусок (то, что остаётся) просто сгенерить generate-ом и на выходе сложить. Получится универсальное решение.

Ну вот вы это для всех и сделайте sm.gif зачем мне всю мою либу компонентов выкладывать sm.gif


--------------------
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 23rd July 2025 - 00:19
Рейтинг@Mail.ru


Страница сгенерированна за 0.01421 секунд с 7
ELECTRONIX ©2004-2016