我想实例化一个寄存器数组,并根据某个函数声明它们。这是我希望构建的乘数块。
我正在使用的代码如下,但这是编译器不理解的代码:
q[i][7:0] = {8{a[i]}} & b[7:0];
当代码被写出时,我希望寄存器q [0],q [1],.... q [7]都存储由上面的RHS定义的8位值。谁能告诉我这样做的正确方法是什么?
整个代码:
`timescale 1ns / 1ps
module multiplier_2(
input [7:0] A,
input [7:0] B,
output reg [15:0] P,
input start,
output stop
);
reg [7:0] q[7:0];
reg P = 0;
//create 8 bit vectors q[i]
genvar i;
generate
for (i = 0; i < 8;i = i+1)
begin: loop
q[i][7:0] = {8{a[i]}} & b[7:0];
end
endgenerate
always @ (*)
begin
if (start == 1'b1)
begin
for (i = 0; i < 8; i = i+1)
begin
P = P + (q[i] << i);
end
end
end
endmodule
编辑:此代码也不起作用:
`timescale 1ns / 1ps
module multiplier_2(
input [7:0] a,
input [7:0] b,
output reg [15:0] P = 16'd0,
input start,
output stop
);
reg [7:0] q[7:0];
//create 8 bit vectors q[i]
genvar i;
generate
always begin
for (i = 0; i < 8;i = i+1)
begin: loop
q[i] = {8{a[i]}} & b[7:0];
end
end
endgenerate
always @ (*)
begin
stop = 1'b0;
if (start == 1'b1)
begin
for (i = 0; i < 8; i = i+1)
begin
P = P + (q[i] << i);
end
end
stop = 1'b1;
end
endmodule
错误讯息:
“第16行:不允许对非寄存器i进行程序分配,左侧应为reg / integer / time / genvar”
答案 0 :(得分:2)
我认为这不需要生成语句。循环标准将起作用:
reg [7:0] q [0:7];
integer i;
always @* begin
for (i = 0; i < 8; i=i+1) begin: loop
q[i] = {8{a[i]}} & b[7:0];
end
end
请注意您所暗示的硬件。对于像生成语句这样的循环意味着并行硬件。
注意:列出深度从0到x的记忆更为常见,即:reg [7:0] q [0:7];
答案 1 :(得分:1)
你在这里遇到各种各样的问题。首先,你对generate
语句是什么以及你想要生成什么感到困惑。您是(1)尝试生成单个always
块,其中必须包含顺序/过程代码,还是(2)尝试生成/复制8个连续分配?
你可能没有做(1),因为生成单个always
块没有意义; generate
是多余的。离开(2)。所以,在always begin
之后摆脱generate
。循环中的i
现在是'genvar'或生成变量,并且您正在复制8个赋值;到现在为止还挺好。摆脱begin:loop
和end
;你复制了一个单一的陈述,所以它们毫无意义。
下一个问题:生成循环现在正在创建并发或并行语句;在Verilog中,它们是模块级语句。它们意味着它们必须是连续分配,即它们必须在它们前面有一个assign
,而不仅仅是普通的程序分配,就像你编写它们一样。这也意味着必须将q
声明为wire
,而不是reg
。这没有充分的理由;这就是Verilog的样子。
您现在有第二个always
块,它是并发(模块级)语句,必须包含顺序/过程代码。您在此块中引用的i
是原始genvar
,但不起作用。 genvar
只能用于特定的与生成相关的情况;这不在generate
内,你需要一个普通的变量作为你的索引。您可以通过命名外部begin
/ end
,并在其中声明变量或任何其他方式来执行此操作。您现在将发现您正在为网络stop
创建程序分配;这是非法的,所以将stop
的声明更改为reg。这应该足以让你的代码编译。
@(*)
是冗长且不必要的,并且历史上至少混淆了一种工具。 @*
更简洁。
你还有其他问题。你的第二个always
包含一个循环。看起来它可能在逻辑上是正确的,但你的合成器必须展开它,并执行8次添加,并设置stop
。这在现实生活中无法奏效。考虑将这些添加并发并将它们放在generate
中,或者创建一个时钟管道,以及一些更健壮(时钟)的方式来创建stop
。