2017-03-03 82 views
1

我正在嘗試實現一個可合成的 verilog模塊,它產生2個向量/數組的向量乘積,每個向量包含八個16位無符號整數。 Design Compiler報告錯誤symbol i must be a constant or parameter。我不知道如何解決它。這是我的代碼。Verilog矢量內部產品

module VecMul16bit (a, b, c, clk, rst); 
// Two vector inner product, each has 8 elements 
// Each element is 16 bits 
// So the Output should be at least 2^32*2^3 = 2^35 in order to 
// prevent overflow 
// Output is 35 bits 
input clk; 
input rst; 
input [127:0] a,b; 
output [35:0] c; 
reg [15:0] a_cp [0:7]; 
reg [15:0] b_cp [0:7]; 
reg [35:0] c_reg; 
reg k,c_done; 

integer i; 
always @ (a) 
begin 
    for (i=0; i<=7; i=i+1) begin 
     a_cp[i] = a[i*15:i*15+15]; 
    end 
end 

always @ (b) 
begin 
    for (i=0; i<=7; i=i+1) begin 
     b_cp[i] = b[i*15:i*15+15]; 
    end 

end 

assign c = c_reg; 

always @(posedge clk or posedge rst) 
begin 
    if (rst) begin 
     c_reg <= 0; 
     k <= 0; 
     c_done <= 0; 
    end else begin 
     c_reg <= c_done ? c_reg : (c_reg + a_cp[k]*b_cp[k]); 
     k   <= c_done ?   k : k + 1; 
     c_done  <= c_done ?   1 : (k == 7); 
    end 
end 

endmodule 

正如你所看到的,我想通過一個循環來複制aa_cp,這是做正確的方式?

如果是的話,我應該如何定義它i並且常量可以用作for循環中的步進器?

回答

1

A 部分選擇在verilog中必須有恆定的邊界。因此,這是不允許的:

a_cp[i] = a[i*15:i*15+15]; 

的Verilog-2001推出了新的索引部分選擇語法,其中指定的起始位置,位選組的寬度。所以,你需要通過更換上述行:

a_cp[i] = a[i*15+:16]; 

這需要的a 16位寬度片起始於位i*15向右計數。您可以使用-:而不是+:,在這種情況下,您向左計數。

小心:鍵入:+而不是+::+是有效的語法,因此可能不會被您的編譯器發現(但仍然可能是一個錯誤)。事實上,當我輸入這個EDA Playground example時,我完全是這樣做的,儘管在這種情況下我的拼寫錯誤被編譯器捕獲了。

+1

該索引可能應該由'i * 16'移位,否則切片之間會有重疊。我建議在'+:'之前和之後加上空格以使其脫穎而出:'a [i * 15 +:16];' – Greg