diff --git a/src/V3Tristate.cpp b/src/V3Tristate.cpp index 39aa49a8d..64691bba7 100644 --- a/src/V3Tristate.cpp +++ b/src/V3Tristate.cpp @@ -411,9 +411,9 @@ class TristateVisitor final : public TristateBaseVisitor { // TYPES struct RefStrength final { - AstVarRef* m_varrefp; + AstNodeVarRef* m_varrefp; VStrength m_strength; - RefStrength(AstVarRef* varrefp, VStrength strength) + RefStrength(AstNodeVarRef* varrefp, VStrength strength) : m_varrefp{varrefp} , m_strength{strength} {} }; @@ -471,7 +471,7 @@ class TristateVisitor final : public TristateBaseVisitor { } AstNodeExpr* getEnp(AstNode* nodep) { if (nodep->user1p()) { - if (AstVarRef* const refp = VN_CAST(nodep, VarRef)) { + if (AstNodeVarRef* const refp = VN_CAST(nodep, NodeVarRef)) { if (refp->varp()->isIO()) { // When reading a tri-state port, we can always use the value // because such port will have resolution logic in upper module. @@ -561,7 +561,7 @@ class TristateVisitor final : public TristateBaseVisitor { return newp; } - void mapInsertLhsVarRef(AstVarRef* nodep) { + void mapInsertLhsVarRef(AstNodeVarRef* nodep) { UINFO(9, " mapInsertLhsVarRef " << nodep); AstVar* const key = nodep->varp(); const auto pair = m_lhsmap.emplace(key, nullptr); @@ -663,7 +663,7 @@ class TristateVisitor final : public TristateBaseVisitor { AstNodeExpr* enp = nullptr; for (auto it = beginStrength; it != endStrength; it++) { - AstVarRef* refp = it->m_varrefp; + AstNodeVarRef* refp = it->m_varrefp; // create the new lhs driver for this var AstVar* const newLhsp = new AstVar{varp->fileline(), VVarType::MODULETEMP, @@ -1752,7 +1752,7 @@ class TristateVisitor final : public TristateBaseVisitor { } } - void visit(AstVarRef* nodep) override { + void handleNodeVarRef(AstNodeVarRef* nodep) { UINFO(9, dbgState() << nodep); if (m_graphing) { if (nodep->access().isWriteOrRW()) associateLogic(nodep, nodep->varp()); @@ -1794,6 +1794,9 @@ class TristateVisitor final : public TristateBaseVisitor { } } + void visit(AstVarRef* nodep) override { handleNodeVarRef(nodep); } + void visit(AstVarXRef* nodep) override { handleNodeVarRef(nodep); } + void visit(AstVar* nodep) override { iterateChildren(nodep); UINFO(9, dbgState() << nodep); diff --git a/test_regress/t/t_interface_modport.v b/test_regress/t/t_interface_modport.v index c4a6580b5..a49d6a172 100644 --- a/test_regress/t/t_interface_modport.v +++ b/test_regress/t/t_interface_modport.v @@ -24,6 +24,25 @@ module counter_ansi end endmodule : counter_ansi +// Issue 3466: inout inside interface modport +interface inout_if; + wire we; + wire d; + modport ctrl (output we, inout d); + modport prph (input we, inout d); +endinterface + +module inout_mod(inout_if.prph io_if); + assign io_if.d = io_if.we ? 1'b1 : 1'bz; +endmodule + +module inout_mod_wrap(input we, inout d); + inout_if io_if(); + assign io_if.we = we; + assign io_if.d = d; + inout_mod prph (.*); +endmodule + module t (/*AUTOARG*/ // Inputs clk @@ -52,11 +71,16 @@ module t (/*AUTOARG*/ .c_data(c4_data), .i_value(4'h4)); + logic inout_we; + tri inout_d; + inout_mod_wrap inout_u (.we(inout_we), .d(inout_d)); + initial begin c1_data.value = 4'h4; c2_data.value = 4'h5; c3_data.value = 4'h6; c4_data.value = 4'h7; + inout_we = 1'b0; end always @ (posedge clk) begin