diff --git a/src/V3Width.cpp b/src/V3Width.cpp index 1b823038d..8e3f54e14 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -2866,7 +2866,8 @@ class WidthVisitor final : public VNVisitor { const bool netPort = nodep->varp()->isNet() || nodep->varp()->varType() == VVarType::PORT; const bool contAssign = VN_IS(nodep->abovep(), AssignW); - if (!(hierRef && netPort && contAssign)) { + const bool pinConn = VN_IS(nodep->abovep(), Pin); + if (!(hierRef && netPort && (contAssign || pinConn))) { nodep->v3warn(ASSIGNIN, "Assigning to input/const variable: " << nodep->prettyNameQ()); } diff --git a/test_regress/t/t_interface_input_port_assign.v b/test_regress/t/t_interface_input_port_assign.v index fb2d77bef..6368e49eb 100644 --- a/test_regress/t/t_interface_input_port_assign.v +++ b/test_regress/t/t_interface_input_port_assign.v @@ -9,43 +9,64 @@ `define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0); // verilog_format: on -// Driving input ports from the instantiating scope via continuous assign -// is legal when port kind defaults to net (IEEE 1800-2023 23.2.2.3). -// All three forms below default to net for input ports. +// Driving interface net-type input ports from the instantiating scope is +// legal via both continuous assignment and port connection when port kind +// defaults to net (IEEE 1800-2023 23.2.2.3, 23.3.3.3). // Scenario 1: bare input (defaults to net) interface bare_if ( - input clk + input clk ); logic data; endinterface // Scenario 2: input with explicit data type (still net for input) interface logic_if ( - input logic clk + input logic clk ); logic data; endinterface // Scenario 3: input with explicit net kind interface wire_if ( - input wire clk + input wire clk ); logic data; endinterface module consumer ( - bare_if cif + bare_if cif ); logic sampled; always @(posedge cif.clk) sampled <= cif.data; endmodule +// Scenario 4: port connection driving interface input (AstPin path) +interface ifc_status ( + input wire busy +); +endinterface + +module dut ( + output logic sleep_o +); + initial sleep_o = 1'b1; +endmodule + +module dut_wrap ( + ifc_status sif +); + dut u_dut ( + .sleep_o(sif.busy) + ); +endmodule + module t; logic clk = 0; always #5 clk = ~clk; integer cyc = 0; + // Continuous assignment scenarios bare_if bif (.clk()); assign bif.clk = clk; assign bif.data = 1'b1; @@ -60,6 +81,10 @@ module t; consumer cons (.cif(bif)); + // Port connection scenario + ifc_status sif (.busy()); + dut_wrap u_wrap (.sif(sif)); + always @(posedge clk) begin cyc <= cyc + 1; if (cyc == 10) begin @@ -69,6 +94,7 @@ module t; `checkh(lif.data, 1'b1); `checkh(wif.clk, clk); `checkh(wif.data, 1'b1); + `checkh(sif.busy, 1'b1); $write("*-* All Finished *-*\n"); $finish; end