问题描述
我想基于实例化模块时设置的参数来设置参数.我有以下内容.
I'd like to set a parameter based on a parameter which is set when the module is instantiated. I have the following.
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时会出错,但是它编译并运行并显示以下内容.
I expected to get an error for redefining P00 but it compiled and ran and displayed the following instead.
WORDS = 8
tmp = bb
P00 = 33
如果我注释参数P00 = 33"分配,则会得到尚未声明标识符P00".错误.
If I comment the "parameter P00 = 33" assignment, I get a "Identifier P00 has not been declared yet." error.
似乎generate块被忽略了.怎么了?
It seems that the generate block is being ignored. What is wrong here?
推荐答案
将参数定义放在generate块内会生成一个相对于generate块内的分层范围的新局部参数. defparam
通常是覆盖参数值的方法.但是 IEEE std 1800-2012 明确声明defparam
不能在§ 23.10.1中影响其父范围:
Placing a parameter definition inside a generate block generates a new local parameter relative to the hierarchical scope within the generate block. defparam
is the usually the way to override a parameter value. However the IEEE std 1800-2012 explicitly states a defparam
cannot effect its parent scope in §23.10.1:
对于复杂的派生参数分配,您可以使用函数.例如:
For complex derived parameter assignments you can use functions. For example:
parameter P01 = FUNC01(WORDS,P00);
function byte FUNC01(input byte w,p);
/* ... */
endfunction
这也是合法的:module foo #(parameter WORDS, P00=FUNC00(WORDS));
一个挑战可能是每个参数可能需要其自己的功能.将参数与struct数据类型一起使用是将分配分组为单个函数的一种可能的解决方法.这种方法需要您的模拟器,合成器和其他工具进行评估.示例:
A challenge could be that each parameter may need its own function. Using a parameter with a struct data type is a potential work around to group the assignments into a single function. This approach needs to be evaluated by your simulator, synthesizer and other tools. Example:
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:
As Morgan has stated, you could define most of the parameters
as logic
and use a combination block. However I would strongly insist on using an always_comb
block instead of a always @*
to guarantee the values are calculation. As stated in the LRM §9.2.2.2.2:
这篇关于生成块中的系统Verilog参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!