[英]System Verilog parameters in generate block
我想基於實例化模塊時設置的參數來設置參數。 我有以下幾點。
module foo #(WORDS = 8);
parameter P00 = 33;
logic [7:0] tmp;
generate
case (WORDS)
4: begin : A
assign tmp = 8'haa;
parameter P00 = 4;
end
8: begin : B
assign tmp = 8'hbb;
parameter P00 = 8;
end
16: begin : C
assign tmp = 8'hcc;
parameter P00 = 16;
end
default: begin : D
assign tmp = 8'hdd;
parameter P00 = 8;
end
endcase
endgenerate
initial begin
$display ("WORDS = %d", WORDS);
$display ("tmp = %h", tmp);
$display ("P00 = %d", P00);
end
endmodule
我預期會因重新定義P00而出錯,但它編譯並運行並顯示以下內容。
WORDS = 8
tmp = bb
P00 = 33
如果注釋“參數P00 = 33”分配,則會得到“尚未聲明標識符P00”。 錯誤。
似乎generate塊被忽略了。 怎么了
將參數定義放置在generate塊內會生成一個相對於generate塊內的分層范圍的新局部參數。 defparam
通常是覆蓋參數值的方法。 但是, IEEE std 1800-2012在§23.10.1中明確聲明defparam
不會影響其父范圍:
生成塊實例(請參見第27章)中或實例下的層次結構或實例數組(請參見28.3.5和23.3.2)中或之下的defparam語句不得在該層次結構之外更改參數值。
對於復雜的派生參數分配,可以使用函數。 例如:
parameter P01 = FUNC01(WORDS,P00);
function byte FUNC01(input byte w,p);
/* ... */
endfunction
這也是合法的: module foo #(parameter WORDS, P00=FUNC00(WORDS));
一個挑戰可能是每個參數可能需要自己的功能。 將參數與struct數據類型一起使用是將分配分組為單個函數的一種可能的解決方法。 該方法需要由模擬器,合成器和其他工具進行評估。 例:
typedef struct packed {
int sub00;
byte sub01;
/* ... */
bit [13:0] subNN
} param_t;
paramter param_t P = FUNC_P(/* inputs */);
function param_t FUNC_P(/* inputs */);
param_t rtn;
/* assign all rtn.sub* */
return rtn;
endfunction
logic [P.sub01-1:0] tmpvar;
正如Morgan所言,您可以將大多數parameters
定義為logic
並使用組合塊。 但是,我強烈建議使用always_comb
塊而不是always @*
來保證值是計算值。 正如指出LRM §9.2.2.2.2:
always_comb在零時間自動執行一次,而always @ *等待直到推斷出的靈敏度列表中的信號發生變化。
最近在這里有很多關於使用生成和分配的問題,不確定是否分配了不正確地教授這些內容的新教程。
參數或Localparams不應定義超過一次,它們是常量,因此不能更改值。 我認為您也缺少模塊foo中的parameter關鍵字。
module foo #(
parameter WORDS = 8
);
localparam P00 = WORD;
通常用作縮放因子:
module foo #(
parameter WIDTH = 8
parameter MAX_VALUE = 2**WIDTH
);
您定義的內容看起來應該只是在使用邏輯而非參數來保存值。
我將整個內容重寫為:
module foo #(WORDS = 8);
logic [31:0] P00 = 33;
logic [7:0] tmp;
always @* begin
case (WORDS)
4: begin : A
tmp = 8'haa;
P00 = 4;
end
8: begin : B
tmp = 8'hbb;
P00 = 8;
end
16: begin : C
tmp = 8'hcc;
P00 = 16;
end
default: begin : D
tmp = 8'hdd;
P00 = 8;
end
endcase
end
對於您要在此處實現的目標,無需使用generate。
這有效(通常說您需要使所有4個生成塊的名稱都相同):
module foo #(WORDS = 8);
parameter P00 = 33;
logic [7:0] tmp;
generate
case (WORDS)
4: begin : B
assign tmp = 8'haa;
parameter P00 = 4;
end
8: begin : B
assign tmp = 8'hbb;
parameter P00 = 8;
end
16: begin : B
assign tmp = 8'hcc;
parameter P00 = 16;
end
default: begin : B
assign tmp = 8'hdd;
parameter P00 = 8;
end
endcase
endgenerate
initial begin
$display ("WORDS = %d", WORDS);
$display ("tmp = %h", tmp);
$display ("P00 = %d", B.P00);
end
endmodule
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.