Fix #1268: Allow variables to be driven by primitive gate outputs

Per IEEE 1800-2017 6.5, variables can be written by one port, including
primitive gate outputs. The code incorrectly disallowed this with the
comment "Gates can never have variable output ports."

Changed elaborate_lnet/elaborate_bi_net calls for gate outputs to pass
true for var_allowed_in_sv, allowing variables as single-driver outputs.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Andrew Pullin 2026-01-23 14:27:46 -08:00
parent a03033e743
commit 68633814d1
5 changed files with 32 additions and 10 deletions

View File

@ -774,11 +774,13 @@ void PGBuiltin::elaborate(Design*des, NetScope*scope) const
des->errors += 1;
return;
}
// Gates can never have variable output ports.
// In SystemVerilog, variables can be driven by a single
// primitive/gate output (IEEE 1800-2017 6.5). Primitives always
// use default (strong) drive strength.
if (lval_count > gate_count)
lval_sigs[idx] = pin(idx)->elaborate_bi_net(des, scope, false);
lval_sigs[idx] = pin(idx)->elaborate_bi_net(des, scope, gn_system_verilog());
else
lval_sigs[idx] = pin(idx)->elaborate_lnet(des, scope, false);
lval_sigs[idx] = pin(idx)->elaborate_lnet(des, scope, gn_system_verilog());
// The only way this should return zero is if an error
// happened, so for that case just return.

View File

@ -2,8 +2,4 @@
./ivltests/br_gh1222.v:6: error: Variable 'rout_ca2' cannot be driven by a primitive or continuous assignment with non-default strength.
./ivltests/br_gh1222.v:7: error: Variable 'lout_ca1' cannot be driven by a primitive or continuous assignment with non-default strength.
./ivltests/br_gh1222.v:7: error: Variable 'lout_ca2' cannot be driven by a primitive or continuous assignment with non-default strength.
./ivltests/br_gh1222.v:12: error: Variable 'rout_gt' cannot be driven by a primitive or continuous assignment with non-default strength.
./ivltests/br_gh1222.v:12: error: Failed to elaborate primitive output expression top.rout_gt.
./ivltests/br_gh1222.v:13: error: Variable 'lout_gt' cannot be driven by a primitive or continuous assignment with non-default strength.
./ivltests/br_gh1222.v:13: error: Failed to elaborate primitive output expression top.lout_gt.
12 error(s) during elaboration.
8 error(s) during elaboration.

View File

@ -9,8 +9,8 @@ module top;
assign (strong1, strong0) rout_valid = in; // Ok, real cannot be in a concatenation
assign (strong1, strong0) {lout_valid1, lout_valid2} = in; // Ok, default strength
and (rout_gt, in, in); // Gates must drive a net
and (lout_gt, in, in); // Gates must drive a net
and (rout_gt, in, in); // Ok in SV, variables can be driven by primitives (IEEE 1800-2017 6.5)
and (lout_gt, in, in); // Ok in SV, variables can be driven by primitives (IEEE 1800-2017 6.5)
// When strength is added it should only be for the default strength!
udp_inv (rout_udp, in); // A UDP is like a module and can drive a variable

View File

@ -0,0 +1,23 @@
// Test for GitHub issue #1268
// Variable (output logic) should be allowed to be driven by primitive gate
// Per IEEE 1800-2017 6.5: variables can be written by one port (primitive output)
module driver(output logic c, input wire d);
not b(c, d);
endmodule
module test;
wire d = 1'b0;
wire c;
driver dut(.c(c), .d(d));
initial begin
#1;
if (c !== 1'b1) begin
$display("FAILED: c = %b, expected 1", c);
$finish;
end
$display("PASSED");
end
endmodule

View File

@ -992,3 +992,4 @@ real_edges CE,-g2012 ivltests gold=real_edges.gold
br_gh1112 CE,-g2009 ivltests gold=br_gh1112.gold
br_gh670 normal,-g2009 ivltests
br_gh1267 normal,-g2012 ivltests
br_gh1268 normal,-g2012 ivltests