From e55e832ea0e197c2351ad7ea61efb0947753fc8f Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Sun, 23 Mar 2014 16:53:38 -0700 Subject: [PATCH] Handle unpacked arrays as output ports. --- elaborate.cc | 25 ++++++++++++++++++++++--- parse.y | 8 +++----- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/elaborate.cc b/elaborate.cc index 9ed0d089b..4c203db17 100644 --- a/elaborate.cc +++ b/elaborate.cc @@ -1570,12 +1570,31 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const } else { - // For now, do not support unpacked array outputs. - ivl_assert(*this, prts[0]->unpacked_dimensions()==0); - /* Port type must be OUTPUT here. */ ivl_assert(*this, prts[0]->port_type() == NetNet::POUTPUT); + // Special case: If the output port is an unpacked + // array, then there should be no sub-ports and + // the passed pexxpression is processed + // differently. Note that we are calling it the + // "r-value" expression, but since this is an + // output port, we assign to it from the internal object. + if (prts[0]->pin_count() > 1) { + ivl_assert(*this, prts.size()==1); + + PEIdent*rval_pident = dynamic_cast(pins[idx]); + ivl_assert(*this, rval_pident); + + NetNet*rval_net = rval_pident->elaborate_unpacked_net(des, scope); + ivl_assert(*this, rval_net->pin_count() == prts[0]->pin_count()); + + assign_unpacked_with_bufz(des, scope, this, rval_net, prts[0]); + continue; + } + + // At this point, arrays are handled. + ivl_assert(*this, prts[0]->unpacked_dimensions()==0); + /* Output from module. Elaborate the port expression as the l-value of a continuous assignment, as the port will continuous assign diff --git a/parse.y b/parse.y index 3fdcdd6f6..59e526e4e 100644 --- a/parse.y +++ b/parse.y @@ -3882,6 +3882,8 @@ port_declaration | attribute_list_opt K_output net_type_opt data_type_or_implicit IDENTIFIER dimensions_opt { Module::port_t*ptmp; perm_string name = lex_strings.make($5); + data_type_t*use_dtype = $4; + if ($6) use_dtype = new uarray_type_t(use_dtype, $6); NetNet::Type use_type = $3; if (use_type == NetNet::IMPLICIT) { if (vector_type_t*dtype = dynamic_cast ($4)) { @@ -3903,15 +3905,11 @@ port_declaration } } ptmp = pform_module_port_reference(name, @2.text, @2.first_line); - pform_module_define_port(@2, name, NetNet::POUTPUT, use_type, $4, $1); + pform_module_define_port(@2, name, NetNet::POUTPUT, use_type, use_dtype, $1); port_declaration_context.port_type = NetNet::POUTPUT; port_declaration_context.port_net_type = use_type; port_declaration_context.data_type = $4; delete[]$5; - if ($6) { - yyerror(@6, "sorry: Output ports with unpacked dimensions not supported."); - delete $6; - } $$ = ptmp; } | attribute_list_opt