为啥没有在 Verilog 中正确传递参数?

Posted

技术标签:

【中文标题】为啥没有在 Verilog 中正确传递参数?【英文标题】:Why isn't parameter being passed properly in Verilog?为什么没有在 Verilog 中正确传递参数? 【发布时间】:2014-03-11 03:59:42 【问题描述】:

我有两个 verlog 模块,如下所示。参数语句应该也允许我传递我想实例化另一个模块的总线宽度。

我在尝试编译时不断收到错误消息,提示“端口表达式 64 与预期的宽度 1 或 2 不匹配”。

module LabL3;
parameter SIZE = 64;
reg [SIZE-1:0]a;
reg [SIZE-1:0]b;
reg c;
wire [SIZE-1:0]z;
integer i,j,k;
yMux #(SIZE) mux(z,a,b,c);

initial 
    begin
    for(i=0;i<4;i=i+1)begin
        for(j=0;j<4;j=j+1)begin
            for(k=0;k<2;k=k+1)begin
    a=i;b=j;c=k;
    #1$display("a=%d b=%d c=%d z=%d",a,b,c,z);
            end
        end
    end
    end
endmodule

另一个文件是:

module yMux(z,a,b,c);
parameter SIZE= 0;
output [SIZE-1:0]z;
input [SIZE-1:0]a,b;
input c;
yMux1 mux[SIZE-1:0](z,a,b,c);
endmodule

最后

module yMux1(z,a,b,c);
output z;
input a,b,c;
wire not_C, upper, lower;

not my_not(notC,c);
and upperAnd(upper,a,notC);
and lowerAnd(lower,c,b);
or my_or(z,upper,lower);

endmodule

我使用的命令是:iverilog LabL3.v yMux1.v yMux.v

我已经尝试了不同的参数传递语法。都给出相同的结果。 任何提示将不胜感激。 - 克里斯

【问题讨论】:

我试图在 Altera 的 Quartus II 上编译它。以 LabL3 为顶部,一个虚拟输出,虚拟 yMux1 和一些虚拟逻辑(所以它实际上可以编译成一些东西)。它编译得很好。 对不起,我忘了包括 yMux1。如果我正确理解语法, yMux #(SIZE) mux(z,a,b,c);应该把 yMux1 中的参数 SIZE 改成 64 吗? 它应该生成 64 个 yMux1 实例。也许回退到使用生成语句。以防万一。生成更明确。因为 a、b 和 z 的宽度与 c 的宽度不同。 错误指的是哪一行? 【参考方案1】:

您正在使用矢量实例:

yMux1 mux[SIZE-1:0](z,a,b,c);

你最终得到SIZE yMux1 实例的数量。这应该按位正确连接 z、a、b 并通过复制将单个位 c 连接到所有 yMux1 c 端口。

如果您真的想将所有 c 端口驱动到相同的值,我会尝试手动复制端口:

yMux1 mux[SIZE-1:0](z,a,b,SIZEc);

Example on EDAPlayground 在我看来很好。可能是特定工具无法正确支持矢量实例的问题。


如果可能,我建议使用SystemVerilog IEEE 1800-2012 Standard 的第 23.2.1 节中的命名端口连接(ANSI 标头样式)。

这种风格非常清楚您的设计意图,我发现它更容易阅读,这与更少的错误有关。由于命名连接并且不依赖于顺序,它还允许更轻松地重构代码。

module LabL3;
  parameter SIZE = 64;
  reg  [SIZE-1:0] a;
  reg  [SIZE-1:0] b;
  reg             c;
  wire [SIZE-1:0] z;

  yMux #(
    .SIZE(SIZE)
  ) mux (
    .z(z),
    .a(a),
    .b(b),
    .c(c)
  );

yMux 定义:

module yMux #(
 parameter SIZE= 0
) (
 output [SIZE-1:0] z,
 input  [SIZE-1:0] a,
 input  [SIZE-1:0] b,
 input             c
);
// ...
endmodule

EDAPlayground 上的上述代码示例。

【讨论】:

谢谢,但我遇到的问题是没有设置参数。例如,在您上面的代码中,我会收到一条错误消息,说“yMux 的警告端口 (1) z 需要 0 位,得到 64”我只想知道为什么我的参数没有被设置。所有模块都必须在同一个文件中才能正常工作吗? @kiwicomb123,不,它们不必在同一个文件中。 Here is my example working on EDAPlayground.

以上是关于为啥没有在 Verilog 中正确传递参数?的主要内容,如果未能解决你的问题,请参考以下文章

C语言中,数组名作为函数参数,属于啥传递,为啥?

为什么Java只有值传递?

调用函数时为啥形参的值不能传给实参

当需要一个形式参数直接改变对应实参的值时,该形式参数应说明为啥参数?

Verilog实例化时的参数传递

为啥 graphql 不接受我在查询中传递的参数?