我正在尝试想出一种方法来添加寄存器的各个位。例如,if regA = 111000 then regB = 3
(的位总和regA
)。1) Verilog 或 SystemVerilog 中是否有任何可合成的函数/运算符可以直接用于执行此操作?
如果不是,那么问题可能有点有趣,特别是因为操作必须在一个时钟周期内完成(纯组合逻辑)并且寄存器宽度是可参数化的。
2) 如果没有内置的 Verilog 或 SystemVerilog 运算符,那么可以做什么?
谢谢, 乌杰瓦尔
我正在尝试想出一种方法来添加寄存器的各个位。例如,if regA = 111000 then regB = 3
(的位总和regA
)。1) Verilog 或 SystemVerilog 中是否有任何可合成的函数/运算符可以直接用于执行此操作?
如果不是,那么问题可能有点有趣,特别是因为操作必须在一个时钟周期内完成(纯组合逻辑)并且寄存器宽度是可参数化的。
2) 如果没有内置的 Verilog 或 SystemVerilog 运算符,那么可以做什么?
谢谢, 乌杰瓦尔
Verilog(IEEE 标准 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 标准 1800-2005 或更新版本):
always_comb begin
B = '0; // fill 0
foreach(A[i])
B += A[i];
end
两者都将合成为组合逻辑。没有闩锁或触发器。
SystemVerilog 确实有$countones()
,但我不确定它是否可合成。那么是这样的:always_comb B = $countones(A)
你可以尝试这样的事情。我不确定它会合成什么,但它应该可以工作。
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);