V3Tristate: handle AstVarXRef as AstVarRef (#3466)
This commit is contained in:
parent
7c923bb330
commit
6ba6447483
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue