diff --git a/PExpr.cc b/PExpr.cc index 51c0de605..bbc7b1ff6 100644 --- a/PExpr.cc +++ b/PExpr.cc @@ -72,7 +72,7 @@ NetNet* PExpr::elaborate_bi_net(Design*, NetScope*) const return 0; } -bool PExpr::is_collapsible_net(Design*, NetScope*) const +bool PExpr::is_collapsible_net(Design*, NetScope*, NetNet::PortType) const { return false; } diff --git a/PExpr.h b/PExpr.h index 369464f9a..344f95fb5 100644 --- a/PExpr.h +++ b/PExpr.h @@ -1,7 +1,7 @@ #ifndef IVL_PExpr_H #define IVL_PExpr_H /* - * Copyright (c) 1998-2019 Stephen Williams + * Copyright (c) 1998-2020 Stephen Williams * Copyright CERN 2013 / Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it @@ -181,7 +181,8 @@ class PExpr : public LineInfo { // structural net that can have multiple drivers. This is // used to test whether an input port connection can be // collapsed to a single wire. - virtual bool is_collapsible_net(Design*des, NetScope*scope) const; + virtual bool is_collapsible_net(Design*des, NetScope*scope, + NetNet::PortType port_type) const; // This method returns true if that expression is the same as // this expression. This method is used for comparing @@ -256,7 +257,8 @@ class PEConcat : public PExpr { NetScope*scope, bool is_cassign, bool is_force) const; - virtual bool is_collapsible_net(Design*des, NetScope*scope) const; + virtual bool is_collapsible_net(Design*des, NetScope*scope, + NetNet::PortType port_type) const; private: NetNet* elaborate_lnet_common_(Design*des, NetScope*scope, bool bidirectional_flag) const; @@ -377,7 +379,8 @@ class PEIdent : public PExpr { verinum* eval_const(Design*des, NetScope*sc) const; - virtual bool is_collapsible_net(Design*des, NetScope*scope) const; + virtual bool is_collapsible_net(Design*des, NetScope*scope, + NetNet::PortType port_type) const; const PPackage* package() const { return package_; } diff --git a/elab_net.cc b/elab_net.cc index c96b4cf2f..5c36436fb 100644 --- a/elab_net.cc +++ b/elab_net.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2014 Stephen Williams (steve@icarus.com) + * Copyright (c) 1999-2020 Stephen Williams (steve@icarus.com) * Copyright CERN 2012 / Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it @@ -168,7 +168,8 @@ NetNet* PEConcat::elaborate_bi_net(Design*des, NetScope*scope) const return elaborate_lnet_common_(des, scope, true); } -bool PEConcat::is_collapsible_net(Design*des, NetScope*scope) const +bool PEConcat::is_collapsible_net(Design*des, NetScope*scope, + NetNet::PortType port_type) const { assert(scope); @@ -183,7 +184,7 @@ bool PEConcat::is_collapsible_net(Design*des, NetScope*scope) const if (parms_[idx] == 0) return false; - if (!parms_[idx]->is_collapsible_net(des, scope)) + if (!parms_[idx]->is_collapsible_net(des, scope, port_type)) return false; } @@ -1065,7 +1066,8 @@ NetNet*PEIdent::elaborate_unpacked_net(Design*des, NetScope*scope) const return sig; } -bool PEIdent::is_collapsible_net(Design*des, NetScope*scope) const +bool PEIdent::is_collapsible_net(Design*des, NetScope*scope, + NetNet::PortType port_type) const { assert(scope); @@ -1086,9 +1088,10 @@ bool PEIdent::is_collapsible_net(Design*des, NetScope*scope) const /* If this is SystemVerilog and the variable is not yet assigned by anything, then convert it to an unresolved wire. */ - if (gn_var_can_be_uwire() - && (sig->type() == NetNet::REG) - && (sig->peek_eref() == 0) ) { + if (gn_var_can_be_uwire() && + (sig->type() == NetNet::REG) && + (sig->peek_eref() == 0) && + (port_type == NetNet::POUTPUT)) { sig->type(NetNet::UNRESOLVED_WIRE); } diff --git a/elaborate.cc b/elaborate.cc index 9738a74ab..3195d3e64 100644 --- a/elaborate.cc +++ b/elaborate.cc @@ -1446,8 +1446,9 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const assert(prts_vector_width % instance.size() == 0); if (!prts.empty() && (prts[0]->port_type() == NetNet::PINPUT) - && prts[0]->pin(0).nexus()->drivers_present() - && pins[idx]->is_collapsible_net(des, scope)) { + && prts[0]->pin(0).nexus()->drivers_present() + && pins[idx]->is_collapsible_net(des, scope, + prts[0]->port_type())) { prts[0]->port_type(NetNet::PINOUT); cerr << pins[idx]->get_fileline() << ": warning: input port " @@ -1455,9 +1456,10 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const } if (!prts.empty() && (prts[0]->port_type() == NetNet::POUTPUT) - && (prts[0]->type() != NetNet::REG) - && prts[0]->pin(0).nexus()->has_floating_input() - && pins[idx]->is_collapsible_net(des, scope)) { + && (prts[0]->type() != NetNet::REG) + && prts[0]->pin(0).nexus()->has_floating_input() + && pins[idx]->is_collapsible_net(des, scope, + prts[0]->port_type())) { prts[0]->port_type(NetNet::PINOUT); cerr << pins[idx]->get_fileline() << ": warning: output port "