生成块中的系统Verilog参数 [英] System Verilog parameters in generate block

查看:200
本文介绍了生成块中的系统Verilog参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想基于实例化模块时设置的参数来设置参数.我有以下内容.

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:

generate块中或下面的层次结构中的defparam语句 实例(请参阅第27条)或实例数组(请参见28.3.5和 23.3.2)不得在该层次结构之外更改参数值.

a defparam statement in a hierarchy in or under a generate block instance (see Clause 27) or an array of instances (see 28.3.5 and 23.3.2) shall not change a parameter value outside that hierarchy.

对于复杂的派生参数分配,您可以使用函数.例如:

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:

always_comb在零时间自动执行一次,而始终 @ *等待,直到推断出的灵敏度发生信号变化为止 列表.

always_comb automatically executes once at time zero, whereas always @* waits until a change occurs on a signal in the inferred sensitivity list.

这篇关于生成块中的系统Verilog参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆