我正在尝试实现一个可合成的 verilog模块,它产生2个向量/数组的向量积,每个包含8个16位无符号整数。 Design Compiler报告错误symbol i must be a constant or parameter
。我不知道如何解决它。这是我的代码。
module VecMul16bit (a, b, c, clk, rst);
// Two vector inner product, each has 8 elements
// Each element is 16 bits
// So the Output should be at least 2^32*2^3 = 2^35 in order to
// prevent overflow
// Output is 35 bits
input clk;
input rst;
input [127:0] a,b;
output [35:0] c;
reg [15:0] a_cp [0:7];
reg [15:0] b_cp [0:7];
reg [35:0] c_reg;
reg k,c_done;
integer i;
always @ (a)
begin
for (i=0; i<=7; i=i+1) begin
a_cp[i] = a[i*15:i*15+15];
end
end
always @ (b)
begin
for (i=0; i<=7; i=i+1) begin
b_cp[i] = b[i*15:i*15+15];
end
end
assign c = c_reg;
always @(posedge clk or posedge rst)
begin
if (rst) begin
c_reg <= 0;
k <= 0;
c_done <= 0;
end else begin
c_reg <= c_done ? c_reg : (c_reg + a_cp[k]*b_cp[k]);
k <= c_done ? k : k + 1;
c_done <= c_done ? 1 : (k == 7);
end
end
endmodule
正如您所看到的,我尝试通过循环将a
复制到a_cp
,这是正确的方法吗?
如果是,我该如何定义i
并且常量可以用作for循环中的步进器?
答案 0 :(得分:1)
verilog中的部分选择必须具有常量边界。所以这是不允许的:
a_cp[i] = a[i*15:i*15+15];
Verilog-2001引入了一个新的索引部分选择语法,您可以在其中指定所选位组的起始位置和宽度。因此,您需要将以上行替换为:
a_cp[i] = a[i*15+:16];
这需要从位a
开始的i*15
的16位宽度切片向右计数。您可以使用-:
代替+:
,在这种情况下,您可以向左计数。
注意:输入:+
而不是+:
非常容易,而:+
是有效的语法,因此编译器可能无法识别(但仍可能是错误) 。事实上,在输入EDA Playground example时我确实做到了这一点,尽管在这种情况下我的拼写错误被编译器捕获了。