2014-02-12 232 views
-1

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

我正在使用的代码如下,但是这是编译器并不领情行:

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行:程序分配到非注册我是不允许的,左侧应该是reg/integer/time/genvar“

+0

'q [0] [7:0] = {8 {a [0]}}&b [7:0];'不是有效的verilog。它需要一个“分配”用于导线类型,或者在一个reg类型的“always”内。 – Morgan

+0

如果我把它放在“初始”里面,它仍然不接受它。一如既往。在我的op上编辑也有一个不起作用的代码。 – triplebig

+0

任何人都可以提供洞察力,为什么我是downvoted,所以我可以改善未来? – triplebig

回答

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

你有各种各样的问题在这里。首先,你对于什么是generate声明以及你想要生成什么感到困惑。您是否(1)试图生成一个单一的always区块,其中必须包含顺序/程序代码,还是您(2)试图生成/复制8个连续分配?

你大概没做(1),因为没有必要生成一个单独的块always; generate是多余的。这留下了(2)。所以,在generate之后摆脱always begin。循环中的i现在是'genvar'或生成变量,并且您正在复制8个赋值;到现在为止还挺好。摆脱begin:loopend;你正在复制一个单一的陈述,所以他们毫无意义的言辞。

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

您现在有第二个always块,它是一个并发(模块级)语句,它必须包含顺序/过程代码。你在这个块中提到的i是原始的genvar,这不起作用。 A genvar只能用于特定的与发电有关的情况;这不在generate里面,你需要一个普通变量作为索引。你可以通过命名你的外部begin/end,并在其中声明一个变量或者以其他方式来做到这一点。您现在会发现您正在创建一个程序性作业,以净值stop;这是非法的,所以将stop的声明更改为reg。这应该足以让你的代码编译。

顺便说一句,@(*)是冗长和不必要的,历史上至少混淆了一个工具。 @*更简洁。

您还有其他问题。你的第二个always包含一个循环。它看起来可能在逻辑上是正确的,但是你的合成器必须展开这个,并且执行8个增加,并且设置stop。这在现实生活中不起作用。考虑将这些新增内容并发放入generate中,或者创建一个时钟管道,以及一些更强大(定时)的方式来创建stop

+0

是的,我很困惑什么是生成。我发现它在预编译的时候是有效的,所以我认为可以包含必要的寄存器,但现在我发现我正在混淆的东西。 为什么第二个循环不能在现实生活中工作? – triplebig

+2

@triplebig你有'stop = 1'b0;''stop = 1'b1;'在同一个组合语句中。组合语句理想地在0时间内模拟。所以在块的一次运行期间有一个在2个值之间变化的信号不会起作用。 – Morgan