基于启用 Verilog 的位的值总和
Sum of Values based on bits enabled Verilog
我是 Verilog 的新手,我试图编写一个简单的代码,但我不确定如何以专家的方式进行。
我有一个 12 位寄存器 "data",该寄存器的每一位都有一个特定的值。例如
Bit 0 = 12;
Bit 1 = 16;
Bit 2 = 33;
......
Bit 11 = 180;
现在如果"data"寄存器的任何一位为1,那么结果应该是对应于该位值的所有值的总和。例如
data = 12'b100000000101
result = 225 (180+33+12)
现在我正在检查每一位数据,如果它是1那么我注册相应的值并将其添加到之前的注册值中。此方法需要循环数。
我怎样才能在verilog中快速完成。
谢谢
你可以试试下面的方法:-
reg [15:0] sum;
always @(*)begin
for (i=0;i<12;i++)begin
if (data[i])
sum = sum+Bit[i];
end //for
end //always
assign finalSum = |data ? finalSum: 'h0;
这取决于你所说的 "fast" 是什么意思。大概你指的是时间,但请记住 time=cycles/frequency - 减少周期数通常会降低电路可以运行的最大频率。
例如,这是一个在一个周期内完成整个加法运算的电路:
always@(*) begin
tempsum = 0;
tempsum = tempsum + (data[0]? 12:0);
tempsum = tempsum + (data[1]? 16:0);
tempsum = tempsum + (data[2]? 33:0);
//...
end
always@(posedge clock)
result <= tempsum;
如果您合成此电路,您会看到一长串加法器。 In 可以在单个周期内计算出结果,但关键路径很长,因此 fMax 较低。这是否是 "faster" 在综合之前是不可能知道的(有太多因素无法猜测)。
更好的多循环方法可能是使用树,即:
reg [31:0] sum [29:0];
always @ (posedge clock) begin
// level 0
sum[0] <= (data[0]? 12:0) + (data[1]? 16:0);
sum[1] <= (data[2]? 33:0) + (data[3]? 40:0);
// ...
sum[15] <= (data[30]? 160:0) + (data[31]? 180:0);
// level 1
sum[16] <= sum [0] + sum [1];
sum[17] <= sum [2] + sum [3];
// ...
sum[23] <= sum [14] + sum [15];
// level 2
sum[24] <= sum [16] + sum [17];
sum[25] <= sum [18] + sum [19];
// ...
// level 3
sum[28] <= sum [24] + sum [25];
sum[29] <= sum [26] + sum [27];
result <= sum [28] + sum [29];
end
综上所述,"fastest" 方法最终还取决于您系统的其他要求、您在什么基础上实施它等。
我是 Verilog 的新手,我试图编写一个简单的代码,但我不确定如何以专家的方式进行。 我有一个 12 位寄存器 "data",该寄存器的每一位都有一个特定的值。例如
Bit 0 = 12;
Bit 1 = 16;
Bit 2 = 33;
......
Bit 11 = 180;
现在如果"data"寄存器的任何一位为1,那么结果应该是对应于该位值的所有值的总和。例如
data = 12'b100000000101
result = 225 (180+33+12)
现在我正在检查每一位数据,如果它是1那么我注册相应的值并将其添加到之前的注册值中。此方法需要循环数。 我怎样才能在verilog中快速完成。
谢谢
你可以试试下面的方法:-
reg [15:0] sum;
always @(*)begin
for (i=0;i<12;i++)begin
if (data[i])
sum = sum+Bit[i];
end //for
end //always
assign finalSum = |data ? finalSum: 'h0;
这取决于你所说的 "fast" 是什么意思。大概你指的是时间,但请记住 time=cycles/frequency - 减少周期数通常会降低电路可以运行的最大频率。
例如,这是一个在一个周期内完成整个加法运算的电路:
always@(*) begin
tempsum = 0;
tempsum = tempsum + (data[0]? 12:0);
tempsum = tempsum + (data[1]? 16:0);
tempsum = tempsum + (data[2]? 33:0);
//...
end
always@(posedge clock)
result <= tempsum;
如果您合成此电路,您会看到一长串加法器。 In 可以在单个周期内计算出结果,但关键路径很长,因此 fMax 较低。这是否是 "faster" 在综合之前是不可能知道的(有太多因素无法猜测)。
更好的多循环方法可能是使用树,即:
reg [31:0] sum [29:0];
always @ (posedge clock) begin
// level 0
sum[0] <= (data[0]? 12:0) + (data[1]? 16:0);
sum[1] <= (data[2]? 33:0) + (data[3]? 40:0);
// ...
sum[15] <= (data[30]? 160:0) + (data[31]? 180:0);
// level 1
sum[16] <= sum [0] + sum [1];
sum[17] <= sum [2] + sum [3];
// ...
sum[23] <= sum [14] + sum [15];
// level 2
sum[24] <= sum [16] + sum [17];
sum[25] <= sum [18] + sum [19];
// ...
// level 3
sum[28] <= sum [24] + sum [25];
sum[29] <= sum [26] + sum [27];
result <= sum [28] + sum [29];
end
综上所述,"fastest" 方法最终还取决于您系统的其他要求、您在什么基础上实施它等。