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
中以将其传递给 subin
。 subin
取值和 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;
已经不正确了。
- Icarus Verilog 如何得出结论
reg show;
?
- 你能用 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 只允许 wire
s 由 assign
语句或输出端口驱动。
SystemVerilog 放宽了规则,因此 reg
和 logic
由 assign
语句或输出端口驱动,只要它是唯一的驱动程序即可。 (有点偏离主题,但我个人更喜欢遵循更严格的 Verilog 规则,因为并非所有工具都具有强大的单一源驱动程序检查由 assign
语句或输出端口驱动的 reg
和 logic
)
无论如何,试试这个命令:
iverilog -Wall -g2012 <file-with-above-content>
我正在尝试将一些 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
中以将其传递给 subin
。 subin
取值和 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;
已经不正确了。
- Icarus Verilog 如何得出结论
reg show;
? - 你能用 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 只允许 wire
s 由 assign
语句或输出端口驱动。
SystemVerilog 放宽了规则,因此 reg
和 logic
由 assign
语句或输出端口驱动,只要它是唯一的驱动程序即可。 (有点偏离主题,但我个人更喜欢遵循更严格的 Verilog 规则,因为并非所有工具都具有强大的单一源驱动程序检查由 assign
语句或输出端口驱动的 reg
和 logic
)
无论如何,试试这个命令:
iverilog -Wall -g2012 <file-with-above-content>