Verilog: добавление отдельных битов регистра (комбинационная логика, ширина регистра параметризуется)

Я пытаюсь придумать способ добавить отдельные биты регистра. например, if regA = 111000 then regB = 3 (сумма битов regA). 1) Есть ли в Verilog или SystemVerilog синтезируемая функция / оператор, которые я могу напрямую использовать для выполнения этой операции?

Если нет, то, возможно, проблема немного интересна, особенно потому, что операция должна выполняться за один такт (чистая комбинационная логика), а ширина регистра параметризуется.

2) Что можно сделать, если нет встроенного оператора Verilog или SystemVerilog?

Спасибо, Удджвал


person Ujjwal    schedule 18.06.2013    source источник


Ответы (2)


Verilog (IEEE Std 1364-2001 или новее):

integer i;
always @* begin
  B = WIDTH_LOG2'b0;
  for (i=0; i<WIDTH; i=i+1)
    B = B + A[i];
end

SystemVerilog (IEEE Std 1800-2005 или новее):

always_comb begin
  B = '0; // fill 0
  foreach(A[i])
    B += A[i];
end

Оба будут синтезироваться в комбинационную логику. Никаких защелок и шлепков.

В SystemVerilog есть $countones(), но я не уверен, можно ли его синтезировать. Ff это тогда: always_comb B = $countones(A)

person Greg    schedule 18.06.2013
comment
Привет @Greg, Спасибо за ответ. Я попытался запустить тестовый код как в Xilinx ISE, так и в инструменте синтеза Altera Quartus, я не получаю чистую комбинационную схему (Синтезированная схема RTL из Quartus2). Это код, который я использовал: module test( A, C); parameter A_WIDTH = 8; parameter C_WIDTH = 3; input [A_WIDTH-1:0] A; output reg [C_WIDTH-1:0] C; integer i; always @ * begin C<=3'd0; for (i = 0; i<A_WIDTH;i=i+1) begin C <= C + A[i]; end end endmodule Не уверен, что он читается, дайте мне знать, если да. - person Ujjwal; 18.06.2013
comment
Решено! Я ошибся между блокирующим и неблокирующим назначением. - person Ujjwal; 18.06.2013
comment
@Ujjwal, правильно, блокировка предназначена для комбинированной логики, а неблокирование - для флопов и защелок. Одним из преимуществ SystemVerilog является always_comb обязательная комбинация всех инструментов (симулятор, синтезатор, линтер, RTL и компаратор гейта и т. Д.). - person Greg; 18.06.2013
comment
Обычно я пишу код Verilog (сейчас чувствую себя глупо, поскольку для меня не принято ошибаться при назначении). Я впервые вхожу в мир SV (осознавая его силу). Спасибо, что нашли время ответить на вопрос! - person Ujjwal; 18.06.2013
comment
Использование НБА в комбинаторной логике - не ошибка; Единственным потенциальным недостатком является то, что моделирование может занять немного больше времени. НБА не превращает что-то из «комбинаторного» в «последовательное». always_comb исправляет проблему инициализации always Verilog - он больше похож на процесс VHDL. - person EML; 18.06.2013
comment
@EML В данном случае это ошибка. Запустите неблокирование с помощью тестового стенда и обратите внимание, что C останется прежним, если A[A_WIDTH-1]==0 и будет увеличиваться на @(A)и A[A_WIDTH-1]==1. Блокировка даст правильный результат на том же стенде. Лучшая практика - блокирование для комбинированной логики и неблокирование для синхронной логики. - person Greg; 18.06.2013
comment
Ошибка в коде Ujjwal заключается в том, что у него есть цикл с нулевой задержкой, и он предполагал, что может прочитать новое значение C после присвоения ему с помощью NBA. Это не имеет ничего общего с тем, является ли его процесс комбинаторным или последовательным; у него была бы точно такая же ошибка, если бы его процесс был синхронизирован, потому что он содержит цикл с нулевой задержкой. Другими словами, если бы у него было @ (posedge clk) вместо @ *, это не имело бы никакого значения. Я согласен с тем, что использовать блокирующие присваивания в комбинаторных процессах - это хороший стиль, но это всего лишь стиль, и это не ошибка. - person EML; 18.06.2013
comment
Написанная здесь версия IEEE Std 1364-2001 на самом деле в основном SV, а не Verilog, но я понимаю. - person travisbartley; 02.09.2014

Вы можете попробовать что-то подобное. Я не совсем уверен, с чем он будет синтезироваться, но он должен работать.

int i; 
reg [`WIDTH-1:0]    A;
reg [`WIDTH_LOG2:0] B;

B = 0;

for(i = 0; i < `WIDTH; i = i + 1)
begin
   B = B + A[i];
 end

Конечно, есть более сложные способы, которые могут иметь лучшую производительность, в зависимости от вашего потока инструментов и того, что доступно, где вы можете создавать свои собственные сумматоры и каскадировать их параллельно, уменьшая размер на каждом шаге. Предполагая, что ширина была 32-битной, что-то вроде:

 adder1bit_1(output1, A[31:24]); 
 adder1bit_2(output2, A[23:16]);
 adder1bit_3(output3, A[15:8]);
 adder1bit_4(output4, A[7:0]);

 adder3bit_1(output5, output1, output2);
 adder3bit_2(output6, output3, output4);

 adder4bit(final_ouput, output5, output6);
person Josh    schedule 18.06.2013
comment
Я думаю, что это должно быть синтезировано, просто убедитесь, что вы поместили его в блок always @(A) (и вы должны инициализировать B до нуля перед циклом). - person Tim; 18.06.2013
comment
Спасибо, Джош и Тим за ответы. @Josh Вот и загвоздка: если я использую цикл for, то во время синтеза он воспринимается как триггер. Так что в основном я буду использовать несколько триггеров, которые будут конвейером всех сумматоров B = B + A [i]. Так что этот подход не может быть реализован. - person Ujjwal; 18.06.2013
comment
Использование индивидуальных сумматоров слишком утомительно и не масштабируется. Я могу использовать с ним оператор генерации и цикл for, что по существу дублирует оборудование, упомянутое внутри оператора цикла for, но я уверен, что кто-то, возможно, сделал это лучше. - person Ujjwal; 18.06.2013
comment
Это на самом деле создание шлепанцев или защелок? Я мог видеть, как он генерирует непреднамеренные защелки, но если у инструментов нет какой-то специальной настройки, я не знаю, почему он генерирует триггеры. - person Josh; 18.06.2013
comment
@ Джош, да ты прав, моя беда. Так как он запускается по уровню, а не по фронту синхронизации, он должен быть защелкивающимся, а не триггером (FF), извините за это. Использование защелок - не лучшая идея для меня, так как я работаю над FPGA, каждый логический блок имеет FF. К тому же в FF проще сопоставить время. - person Ujjwal; 18.06.2013
comment
Как сказал @Tim, он может создавать непреднамеренные защелки, если вы не инициализируете значение до нуля. Когда вы пробовали цикл for, был ли у вас оператор B = 0 перед циклом? - person Josh; 18.06.2013
comment
@Josh: module test( A, C); parameter A_WIDTH = 8; parameter C_WIDTH = 3; input [A_WIDTH-1:0] A; output reg [C_WIDTH-1:0] C = 0; integer i; always @ * begin for (i = 0; i<A_WIDTH;i=i+1) begin C <= C + A[i]; end end endmodule Это код, который я написал и синтезировал только что. У меня после синтеза получаются защелки. - person Ujjwal; 18.06.2013
comment
Что ж, если вы используете неблокирующее присвоение ‹=, обычно оно будет создавать защелки или триггеры. Есть ли причина, по которой вы его используете? Использование обычного присваивания = должно быть нормальным, если вы не собираетесь делать что-то еще. - person Josh; 18.06.2013
comment
Ах! Никогда не думал, что совершу эту ошибку. Большое спасибо, Джош !! Он прекрасно синтезируется .. - person Ujjwal; 18.06.2013