From 6364aba9754769afa1d83affc405907745e3cd36 Mon Sep 17 00:00:00 2001 From: Martin Whitaker Date: Sun, 19 May 2013 09:16:24 +0100 Subject: [PATCH] Fix for br930 - support attributes on old-style port declarations. --- parse.y | 83 +++++++++++++++++++++++++++----------------------------- pform.cc | 7 +++-- pform.h | 3 +- 3 files changed, 47 insertions(+), 46 deletions(-) diff --git a/parse.y b/parse.y index ad43be05d..20e62f77e 100644 --- a/parse.y +++ b/parse.y @@ -4169,63 +4169,60 @@ module_item delete $4; } - | port_direction unsigned_signed_opt range_opt delay3_opt list_of_identifiers ';' - { pform_set_port_type(@1, $5, $3, $2, $1); - } + | attribute_list_opt port_direction unsigned_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_direction net_type unsigned_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_direction net_type unsigned_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 unsigned_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 unsigned_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; + } - | port_direction K_wreal list_of_identifiers ';' - { pform_makewire(@1, 0, true, $3, NetNet::WIRE, $1, - IVL_VT_REAL, 0, SR_BOTH); - } + | attribute_list_opt port_direction K_wreal list_of_identifiers ';' + { pform_makewire(@2, 0, true, $4, NetNet::WIRE, $2, + IVL_VT_REAL, $1, SR_BOTH); + } /* 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 unsigned_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 unsigned_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 unsigned_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 unsigned_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_direction unsigned_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_direction unsigned_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 89afe6b25..a08d0827c 100644 --- a/pform.cc +++ b/pform.cc @@ -2297,6 +2297,7 @@ void pform_makewire(const vlltype&li, delete names; delete range; + delete attr; } /* @@ -2916,7 +2917,8 @@ void pform_set_port_type(const struct vlltype&li, list*names, list*range, bool signed_flag, - NetNet::PortType pt) + NetNet::PortType pt, + list*attr) { assert(pt != NetNet::PIMPLICIT && pt != NetNet::NOT_A_PORT); @@ -2925,11 +2927,12 @@ 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, NetNet::NONE, range, signed_flag, IVL_VT_NO_TYPE, - SR_PORT, 0); + SR_PORT, attr); } delete names; delete range; + delete attr; } static void pform_set_integer_2atom(uint64_t width, bool signed_flag, perm_string name, NetNet::Type net_type, list*attr) diff --git a/pform.h b/pform.h index c7457c5b9..e8c656fb8 100644 --- a/pform.h +++ b/pform.h @@ -340,7 +340,8 @@ extern void pform_set_port_type(const struct vlltype&li, list*names, list*range, bool signed_flag, - NetNet::PortType); + NetNet::PortType, + list*attr); extern void pform_set_reg_idx(perm_string name, std::list*indices);