Verilog二维数组语法

时间:2014-02-12 04:10:54

标签: debugging verilog bit

我想实例化一个寄存器数组,并根据某个函数声明它们。这是我希望构建的乘数块。

我正在使用的代码如下,但这是编译器不理解的代码:

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”

2 个答案:

答案 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:loopend;你复制了一个单一的陈述,所以它们毫无意义。

下一个问题:生成循环现在正在创建并发并行语句;在Verilog中,它们是模块级语句。它们意味着它们必须是连续分配,即它们必须在它们前面有一个assign,而不仅仅是普通的程序分配,就像你编写它们一样。这也意味着必须将q声明为wire,而不是reg。这没有充分的理由;这就是Verilog的样子。

您现在有第二个always块,它是并发(模块级)语句,必须包含顺序/过程代码。您在此块中引用的i是原始genvar,但不起作用。 genvar只能用于特定的与生成相关的情况;这不在generate内,你需要一个普通的变量作为你的索引。您可以通过命名外部begin / end,并在其中声明变量或任何其他方式来执行此操作。您现在将发现您正在为网络stop创建程序分配;这是非法的,所以将stop的声明更改为reg。这应该足以让你的代码编译。

BTW,@(*)是冗长且不必要的,并且历史上至少混淆了一种工具。 @*更简洁。

你还有其他问题。你的第二个always包含一个循环。看起来它可能在逻辑上是正确的,但你的合成器必须展开它,并执行8次添加,并设置stop。这在现实生活中无法奏效。考虑将这些添加并发并将它们放在generate中,或者创建一个时钟管道,以及一些更健壮(时钟)的方式来创建stop