我是Verilog的新手,我试图写一个简单的代码,但我不知道如何以专家的方式做到这一点。 我有一个12位寄存器"数据",该寄存器的每一位都有一个特定的值。例如
Bit 0 = 12;
Bit 1 = 16;
Bit 2 = 33;
......
Bit 11 = 180;
现在,如果有任何"数据"寄存器为1然后结果应该是与该位值相对应的所有值的总和。 e.g。
data = 12'b100000000101
result = 225 (180+33+12)
现在我正在检查每一位数据,如果它是1,那么我将注册该相应的值并将其添加到先前的注册值。此方法需要多个周期。 我怎样才能在verilog中快速完成。
谢谢
答案 0 :(得分:1)
这取决于你所说的“快”。大概你的意思是时间,但要记住时间=周期/频率 - 减少周期数通常会降低电路工作的最大频率。
例如,这是一个在一个周期内完成整个加法的电路:
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。在你合成它之前,这是否会“更快”是不可能知道的(有太多的因素需要猜测)。
更好的多周期方法可能是使用树,即:
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
所有这一切,最终“最快”的方法还将取决于您系统的其他要求,您正在实施的内容等。
答案 1 :(得分:0)
您可以尝试以下内容: -
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;