diff --git a/design_dump.cc b/design_dump.cc index 5da7f9047..e3d14f3b0 100644 --- a/design_dump.cc +++ b/design_dump.cc @@ -221,6 +221,9 @@ void NetNet::dump_net(ostream&o, unsigned ind) const case NetNet::PINOUT: o << " inout"; break; + case NetNet::PREF: + o <<" ref"; + break; } if (ivl_discipline_t dis = get_discipline()) diff --git a/elab_net.cc b/elab_net.cc index 98180dab5..221769451 100644 --- a/elab_net.cc +++ b/elab_net.cc @@ -702,6 +702,7 @@ NetNet* PEIdent::elaborate_port(Design*des, NetScope*scope) const case NetNet::PINPUT: case NetNet::POUTPUT: case NetNet::PINOUT: + case NetNet::PREF: break; /* If the name matches, but the signal is not a port, @@ -769,6 +770,9 @@ NetNet* PEIdent::elaborate_port(Design*des, NetScope*scope) const sig = tmp; break; + case NetNet::PREF: + // For the purposes of module ports, treat ref ports + // just like inout ports. case NetNet::PINOUT: ps = new NetTran(scope, scope->local_symbol(), sig->vector_width(), swid, lidx); diff --git a/elab_sig.cc b/elab_sig.cc index 336a8e97e..42ed8c355 100644 --- a/elab_sig.cc +++ b/elab_sig.cc @@ -85,6 +85,14 @@ bool PScope::elaborate_sig_wires_(Design*des, NetScope*scope) const PWire*cur = (*wt).second; NetNet*sig = cur->elaborate_sig(des, scope); + if (sig && (sig->scope() == scope) + && (sig->port_type() == NetNet::PREF)) { + + cerr << cur->get_fileline() << ": sorry: " + << "Reference ports not supported yet." << endl; + des->errors += 1; + } + /* If the signal is an input and is also declared as a reg, then report an error. */ diff --git a/elaborate.cc b/elaborate.cc index ba5d8f019..e256a4df8 100644 --- a/elaborate.cc +++ b/elaborate.cc @@ -1069,6 +1069,10 @@ NetNet*PGModule::resize_net_to_port_(Design*des, NetScope*scope, ivl_assert(*this, 0); break; + case NetNet::PREF: + ivl_assert(*this, 0); + break; + default: ivl_assert(*this, 0); } @@ -1506,6 +1510,7 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const } else { /* Port type must be OUTPUT here. */ + ivl_assert(*this, prts[0]->port_type() == NetNet::POUTPUT); /* Output from module. Elaborate the port expression as the l-value of a continuous @@ -1640,6 +1645,9 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const /* This may not be correct! */ as_signed = prts[0]->get_signed() && sig->get_signed(); break; + case NetNet::PREF: + ivl_assert(*this, 0); + break; default: ivl_assert(*this, 0); } @@ -1786,6 +1794,12 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const } break; + case NetNet::PREF: + cerr << get_fileline() << ": sorry: " + << "Reference ports not supported yet." << endl; + des->errors += 1; + break; + case NetNet::PIMPLICIT: cerr << get_fileline() << ": internal error: " << "Unexpected IMPLICIT port" << endl; diff --git a/netlist.h b/netlist.h index 36f531dac..a99a41730 100644 --- a/netlist.h +++ b/netlist.h @@ -561,7 +561,7 @@ class NetNet : public NetObj { SUPPLY0, SUPPLY1, WAND, TRIAND, TRI0, WOR, TRIOR, REG, UNRESOLVED_WIRE }; - enum PortType { NOT_A_PORT, PIMPLICIT, PINPUT, POUTPUT, PINOUT }; + enum PortType { NOT_A_PORT, PIMPLICIT, PINPUT, POUTPUT, PINOUT, PREF }; struct range_t { inline range_t() : msb(0), lsb(0) { } diff --git a/parse.y b/parse.y index 5118dd2c6..81c71d14e 100644 --- a/parse.y +++ b/parse.y @@ -777,6 +777,27 @@ number : BASED_NUMBER based_size = 0; } ; +port_direction /* IEEE1800-2005 A.1.3 */ + : K_input { $$ = NetNet::PINPUT; } + | K_output { $$ = NetNet::POUTPUT; } + | K_inout { $$ = NetNet::PINOUT; } + | K_ref + { $$ = NetNet::PREF; + if (!gn_system_verilog()) { + yyerror(@1, "error: Reference ports (ref) require SystemVerilog."); + $$ = NetNet::PINPUT; + } + } + ; + + /* port_direction_opt is used in places where the prot direction is + option, and defaults to input. */ + +port_direction_opt + : port_direction { $$ = $1; } + | { $$ = NetNet::PINPUT; } + ; + /* real and realtime are exactly the same so save some code * with a common matching rule. */ real_or_realtime @@ -4443,17 +4464,6 @@ port_reference_list } ; -port_direction /* IEEE1800-2005 A.1.3 */ - : K_input { $$ = NetNet::PINPUT; } - | K_output { $$ = NetNet::POUTPUT; } - | K_inout { $$ = NetNet::PINOUT; } - ; - -port_direction_opt - : port_direction { $$ = $1; } - | { $$ = NetNet::PINPUT; } - ; - /* The range is a list of variable dimensions. */ range : variable_dimension diff --git a/pform_dump.cc b/pform_dump.cc index d9fa1286e..1ca78a67e 100644 --- a/pform_dump.cc +++ b/pform_dump.cc @@ -336,6 +336,9 @@ void PWire::dump(ostream&out, unsigned ind) const case NetNet::PINOUT: out << " inout"; break; + case NetNet::PREF: + out << " ref"; + break; case NetNet::NOT_A_PORT: break; }