I am trying to port some Verilog source code to SystemVerilog. This question is specific to Icarus Verilog (tested with 10.3 and 11 providing the same result), since I did not get any errors with tools (e.g. Yosys 0.9.0, Cadence Xcelium 19.09). The issue I have boils down to the following minimal example:
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
Apparently, I want to create some val_o
value in subout
and wire it up in main
to pass it to subin
. subin
takes the value and returns one bit which is monitored. In other words, a value is passed from one submodule to the other.
The error, I get with iverilog <file-with-above-content>
is:
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.
As far as I understand the situation, it should create one register for val_o
in subout
and one register sel
in main
. Everything else are just wires. Since, we are using SystemVerilog, I use logic
and do not specify wire
/reg
. To me the conclusion reg show;
is already incorrect.
- How does Icarus Verilog conclude
reg show;
? - Can you make this example run with iverilog?