我在Verilog中有一个1023位向量。我想要做的就是检查第i位是否为1,如果是1,我必须添加' i'到另一个变量。
在C中,它将类似于:
int sum=0;
int i=0;
for(i=0;i<1023;i++) {
if(a[i]==1) {
sum=sum+i;
}
当然,我正在做的补充是在伽罗瓦场上。所以,我有一个名为Galois_Field_Adder的模块来进行计算。 所以,我现在的问题是如何有条件地检查特定位是否为1,如果是,请调用我的模块进行特定添加。
注意:1023位向量被声明为输入。
答案 0 :(得分:0)
如果没有看到您的模块,很难回答您的问题,因为我们无法衡量您在Verilog中的位置。你总是要考虑你的代码如何在门中翻译。如果我们想将您的C代码转换为可合成逻辑,我们可以采用相同的算法,逐个遍历每个位,并根据每个位添加总和。你会使用这样的东西:
module gallois (
input wire clk,
input wire rst,
input wire [1022:0] a,
input wire a_valid,
output reg [18:0] sum,
output reg sum_valid
);
reg [9:0] cnt;
reg [1021:0] shift_a;
always @(posedge clk)
if (rst)
begin
sum[18:0] <= {19{1'bx}};
sum_valid <= 1'b0;
cnt[9:0] <= 10'd0;
shift_a[1021:0] <= {1022{1'bx}};
end
else
if (a_valid)
begin
sum[18:0] <= 19'd0;
sum_valid <= 1'b0;
cnt[9:0] <= 10'd1;
shift_a[1021:0] <= a[1022:1];
end
else if (cnt[9:0])
begin
if (cnt[9:0] == 10'd1022)
begin
sum_valid <= 1'b1;
cnt[9:0] <= 10'd0;
end
else
cnt[9:0] <= cnt[9:0] + 10'd1;
if (shift_a[0])
sum[18:0] <= sum[18:0] + cnt[9:0];
shift_a[1021:0] <= {1'bx, shift_a[1021:1]};
end
endmodule
您将在1023个时钟周期后获得结果。这个代码需要根据它的变化,你想要的接口等进行修改...... 这里重要的是我们使用移位寄存器来测试每个位,因此添加和的逻辑只需要shift_a [0],sum和cnt作为输入。 基于以下内容的代码也适用于模拟:
if (a[cnt[9:0])
sum[18:0] <= sum[18:0] + cnt[9:0];
但是添加到sum的逻辑实际上将[]的所有1023位作为输入。这很难变成实际的查找表。
在模拟中,您还可以实现非常粗糙的内容,例如:
reg [1022:0]a;
reg [9:0] sum;
integer i;
always @(a)
begin
sum[9:0] = 10'd0;
for (i=0; i < 1023; i=i+1)
if (a[i])
sum[9:0] = sum[9:0] + i;
end
如果你试图综合这个,总和实际上会变成一大堆组合逻辑,因为总是&#39;阻止不依赖于时钟。这段代码实际上等同于:
always @(a)
case(a):
1023'd0: sum[18:0] = 19'd0;
1023'd1: sum[18:0] = 19'd1;
1023'd2: sum[18:0] = 19'd3;
etc...
毋庸置疑,具有1023个输入位的查找表是一个非常大的内存...
然后,如果您想改进代码,并将FPGA用作FPGA而不是CPU,则需要开始考虑并行性,例如在输入的不同范围内并行工作a。但这是另一个线索......