我想用generate构造和二维存储器设计一个简单的乘法器。但我无法编译以下verilog代码。有人可以提一些暗示吗?
module classic_multiplier(
a, b,
a_by_b);
parameter M = 2;
input [M-1:0] a, b;
output reg [M-1:0] a_by_b [0:2*M-2];
//the first and
genvar i, k;
generate begin
for(k = 0; k <= M-1; k=k+1) begin
for(i = 0; i <= k; i=i+1) begin
a_by_b[k][i] = a[i] & b[k-i];
end
end
end
endgenerate
endmodule
答案 0 :(得分:1)
这里的问题似乎是你有一个2D输出端口(a_by_b
)。我不太清楚为什么你还需要它用于乘法器,输出端口大小应该是2*M
,所以:
output reg [(2*M-1):0] a_by_b;
此外,begin
之后不需要generate
(因此不需要匹配的end
),但是好的,这不是问题,你可以如果你愿意,可以添加它们。
接下来,需要命名generate
块内的循环,例如:
generate
for(k = 0; k <= M-1; k=k+1) begin : for_outer
for(i = 0; i <= k; i=i+1) begin : for_inner
a_by_b[k][i] = a[i] & b[k-i];
end
end
endgenerate
当然,如果更改a_by_b
的定义,则需要更改for循环中的代码。
答案 1 :(得分:0)
当工具看到a_by_b[k][i] = a[i] & b[k-i];
时,它确保a_bay_b是一个模块。在该行前加assign
或always @*
,该工具将接受接受该代码。
生成块在编译精化期间扩展代码。使用给定的代码:
genvar i, k;
generate
for(k = 0; k <= M-1; k=k+1) begin
for(i = 0; i <= k; i=i+1) begin
a_by_b[k][i] = a[i] & b[k-i]; // Error will happen here
end
end
endgenerate
将扩展为:
a_by_b[0][0] = a[0] & b[0-0]; // * Compile Error *
a_by_b[1][0] = a[0] & b[1-0]; // ** Assignment without assign, always @*
a_by_b[1][1] = a[1] & b[1-1]; // ** block statement (e.g. always,initial)
assign
的正确代码:
genvar i, k;
generate
for(k = 0; k <= M-1; k=k+1) begin
for(i = 0; i <= k; i=i+1) begin
assign a_by_b[k][i] = a[i] & b[k-i];
end
end
endgenerate
将评估为:
assign a_by_b[0][0] = a[0] & b[0-0];
assign a_by_b[1][0] = a[0] & b[1-0];
assign a_by_b[1][1] = a[1] & b[1-1];
或always @*
:
genvar i, k;
generate
for(k = 0; k <= M-1; k=k+1) begin
for(i = 0; i <= k; i=i+1) begin
always @* a_by_b[k][i] = a[i] & b[k-i];
end
end
endgenerate
将评估为:
always @* a_by_b[0][0] = a[0] & b[0-0];
always @* a_by_b[1][0] = a[0] & b[1-0];
always @* a_by_b[1][1] = a[1] & b[1-1];
或者,可以在没有生成块的情况下使用单个always块:
integer i,k;
always @* begin
for(k = 0; k <= M-1; k=k+1) begin
for(i = 0; i <= k; i=i+1) begin
a_by_b[k][i] = a[i] & b[k-i];
end
end