From 4efb601fee0f1400c6538d6244ea8faabc761d83 Mon Sep 17 00:00:00 2001 From: Martin Whitaker Date: Sun, 19 May 2013 11:05:01 +0100 Subject: [PATCH] V0.9: Fix for br930 - support attributes on old-style port declarations. --- parse.y | 76 +++++++++++++++++++++++++++----------------------------- pform.cc | 25 ++++++++++++++----- pform.h | 3 ++- 3 files changed, 57 insertions(+), 47 deletions(-) diff --git a/parse.y b/parse.y index 1801008e6..edfc53c99 100644 --- a/parse.y +++ b/parse.y @@ -2093,7 +2093,6 @@ module_item yyerror(@6, "sorry: net delays not supported."); delete $6; } - if ($1) delete $1; } /* Very similar to the rule above, but this takes a list of @@ -2140,58 +2139,55 @@ module_item delete $4; } - | port_type signed_opt range_opt delay3_opt list_of_identifiers ';' - { pform_set_port_type(@1, $5, $3, $2, $1); - } + | attribute_list_opt port_type signed_opt range_opt delay3_opt list_of_identifiers ';' + { pform_set_port_type(@2, $6, $4, $3, $2, $1); } /* The next two rules handle Verilog 2001 statements of the form: input wire signed [h:l] ; This creates the wire and sets the port type all at once. */ - | port_type net_type signed_opt range_opt list_of_identifiers ';' - { pform_makewire(@1, $4, $3, $5, $2, $1, IVL_VT_NO_TYPE, 0, - SR_BOTH); - } + | attribute_list_opt port_type net_type signed_opt range_opt list_of_identifiers ';' + { pform_makewire(@2, $5, $4, $6, $3, $2, IVL_VT_NO_TYPE, $1, SR_BOTH); } - | K_output var_type signed_opt range_opt list_of_port_identifiers ';' - { list >::const_iterator pp; - list*tmp = new list; - for (pp = $5->begin(); pp != $5->end(); pp++) { - tmp->push_back((*pp).first); - } - pform_makewire(@1, $4, $3, tmp, $2, NetNet::POUTPUT, - IVL_VT_NO_TYPE, 0, SR_BOTH); - for (pp = $5->begin(); pp != $5->end(); pp++) { - if ((*pp).second) { - pform_make_reginit(@1, (*pp).first, (*pp).second); - } - } - delete $5; - } + | attribute_list_opt K_output var_type signed_opt range_opt list_of_port_identifiers ';' + { list >::const_iterator pp; + list*tmp = new list; + for (pp = $6->begin(); pp != $6->end(); ++ pp ) { + tmp->push_back((*pp).first); + } + pform_makewire(@2, $5, $4, tmp, $3, NetNet::POUTPUT, + IVL_VT_NO_TYPE, $1, SR_BOTH); + for (pp = $6->begin(); pp != $6->end(); ++ pp ) { + if ((*pp).second) { + pform_make_reginit(@2, (*pp).first, (*pp).second); + } + } + delete $6; + } /* var_type declaration (reg variables) cannot be input or output, because the port declaration implies an external driver, which cannot be attached to a reg. These rules catch that error early. */ - | K_input var_type signed_opt range_opt list_of_identifiers ';' - { pform_makewire(@1, $4, $3, $5, $2, NetNet::PINPUT, - IVL_VT_NO_TYPE, 0); - yyerror(@2, "error: reg variables cannot be inputs."); - } + | attribute_list_opt K_input var_type signed_opt range_opt list_of_identifiers ';' + { pform_makewire(@2, $5, $4, $6, $3, NetNet::PINPUT, + IVL_VT_NO_TYPE, $1); + yyerror(@3, "error: reg variables cannot be inputs."); + } - | K_inout var_type signed_opt range_opt list_of_identifiers ';' - { pform_makewire(@1, $4, $3, $5, $2, NetNet::PINOUT, - IVL_VT_NO_TYPE, 0); - yyerror(@2, "error: reg variables cannot be inouts."); - } + | attribute_list_opt K_inout var_type signed_opt range_opt list_of_identifiers ';' + { pform_makewire(@2, $5, $4, $6, $3, NetNet::PINOUT, + IVL_VT_NO_TYPE, $1); + yyerror(@3, "error: reg variables cannot be inouts."); + } - | port_type signed_opt range_opt delay3_opt error ';' - { yyerror(@1, "error: Invalid variable list" - " in port declaration."); - if ($3) delete $3; - if ($4) delete $4; - yyerrok; - } + | attribute_list_opt port_type signed_opt range_opt delay3_opt error ';' + { yyerror(@2, "error: Invalid variable list in port declaration."); + if ($1) delete $1; + if ($4) delete $4; + if ($5) delete $5; + yyerrok; + } /* Maybe this is a discipline declaration? If so, then the lexor will see the discipline name as an identifier. We match it to the diff --git a/pform.cc b/pform.cc index 6f3f2f493..3dc8d1e8a 100644 --- a/pform.cc +++ b/pform.cc @@ -1094,7 +1094,8 @@ static void pform_set_net_range(perm_string name, const svector*range, bool signed_flag, ivl_variable_type_t dt, - PWSRType rt) + PWSRType rt, + svector*attr) { PWire*cur = pform_get_wire_in_scope(name); if (cur == 0) { @@ -1117,6 +1118,13 @@ static void pform_set_net_range(perm_string name, if (dt != IVL_VT_NO_TYPE) cur->set_data_type(dt); + + if (attr) { + for (unsigned idx = 0 ; idx < attr->count() ; idx += 1) { + named_pexpr_t*tmp = (*attr)[idx]; + cur->attributes[tmp->name] = tmp->parm; + } + } } void pform_set_net_range(list*names, @@ -1131,7 +1139,7 @@ void pform_set_net_range(list*names, ; cur != names->end() ; cur ++ ) { perm_string txt = *cur; - pform_set_net_range(txt, range, signed_flag, dt, rt); + pform_set_net_range(txt, range, signed_flag, dt, rt, 0); } delete names; @@ -1614,13 +1622,15 @@ void pform_makewire(const vlltype&li, pform_makewire(li, txt, type, pt, dt, attr); /* This has already been done for real variables. */ if (dt != IVL_VT_REAL) { - pform_set_net_range(txt, range, signed_flag, dt, rt); + pform_set_net_range(txt, range, signed_flag, dt, rt, 0); } } delete names; if (range) delete range; + if (attr) + delete attr; } /* @@ -1645,7 +1655,7 @@ void pform_makewire(const vlltype&li, /* This has already been done for real variables. */ if (dt != IVL_VT_REAL) { pform_set_net_range(first->name, range, signed_flag, dt, - SR_NET); + SR_NET, 0); } PWire*cur = pform_get_wire_in_scope(first->name); @@ -2044,7 +2054,8 @@ void pform_set_port_type(const struct vlltype&li, list*names, svector*range, bool signed_flag, - NetNet::PortType pt) + NetNet::PortType pt, + svector*attr) { for (list::iterator cur = names->begin() ; cur != names->end() @@ -2052,12 +2063,14 @@ void pform_set_port_type(const struct vlltype&li, perm_string txt = *cur; pform_set_port_type(txt, pt, li.text, li.first_line); pform_set_net_range(txt, range, signed_flag, IVL_VT_NO_TYPE, - SR_PORT); + SR_PORT, attr); } delete names; if (range) delete range; + if (attr) + delete attr; } static void pform_set_reg_integer(perm_string name) diff --git a/pform.h b/pform.h index c61c2f142..0887dd2a3 100644 --- a/pform.h +++ b/pform.h @@ -254,7 +254,8 @@ extern void pform_set_port_type(const struct vlltype&li, list*names, svector*range, bool signed_flag, - NetNet::PortType); + NetNet::PortType, + svector*attr); extern void pform_set_port_type(perm_string nm, NetNet::PortType pt, const char*file, unsigned lineno);