Icarus verilog:注册显示;不能由原语或连续赋值驱动

Icarus verilog: reg show; cannot be driven by primitives or continuous assignment

我正在尝试将一些 Verilog 源代码移植到 SystemVerilog。这个问题特定于 Icarus Verilog(使用 10.3 和 11 进行测试,结果相同),因为我使用工具(例如 Yosys 0.9.0、Cadence Xcelium 19.09)没有遇到任何错误。我的问题归结为以下最小示例:

module main();
  logic sel;
  wire [31:0] wired;
  logic show;

  initial begin
    $monitor("show = %d", show);

    sel = 1'b1;
    #10;
    sel = 1'b0;
  end

  subout a(.sel_i(sel), .val_o(wired));
  subin  b(.val_i(wired), .out_o(show));
endmodule

module subout(
  input logic sel_i,
  output logic [31:0] val_o
);
  always @(sel_i) begin
    val_o   = 32'b0;

    if (sel_i) begin
      val_o = 32'b101010;
    end
  end
endmodule

module subin(
  input logic [31:0] val_i,
  output logic out_o
);
  assign out_o = val_i[0];
endmodule

显然,我想在 subout 中创建一些 val_o 值并将其连接到 main 中以将其传递给 subinsubin 取值和 returns 一位被监视。换句话说,一个值从一个子模块传递到另一个子模块。

我用 iverilog <file-with-above-content> 得到的错误是:

iverilog_issue.sv:35: error: reg out_o; cannot be driven by primitives or continuous assignment.
iverilog_issue.sv:15: error: reg show; cannot be driven by primitives or continuous assignment.
iverilog_issue.sv:15: error: Output port expression must support continuous assignment.
iverilog_issue.sv:15:      : Port 2 (out_o) of subin is connected to show
3 error(s) during elaboration.

据我了解,它应该在subout中为val_o创建一个寄存器,在main中创建一个寄存器sel。其他一切都只是电线。因为,我们使用的是 SystemVerilog,所以我使用 logic 而没有指定 wire/reg。对我来说,结论 reg show; 已经不正确了。

  1. Icarus Verilog 如何得出结论 reg show;
  2. 你能用 iverilog 制作这个例子 运行 吗?

代码在 EDAplayground with an older Icarus 10.0. So my guess is you didn't enable the SystemVerilog flag -g2012. By default Icarus runs in Verilog IEEE1364-2005 [1] 上正确运行;这与设置标志相同 -g2005

Verilog 只允许 wires 由 assign 语句或输出端口驱动。 SystemVerilog 放宽了规则,因此 reglogicassign 语句或输出端口驱动,只要它是唯一的驱动程序即可。 (有点偏离主题,但我个人更喜欢遵循更严格的 Verilog 规则,因为并非所有工具都具有强大的单一源驱动程序检查由 assign 语句或输出端口驱动的 reglogic

无论如何,试试这个命令:

iverilog -Wall -g2012 <file-with-above-content>