2014-02-12 230 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