Fix for br930 - support attributes on old-style port declarations.

This commit is contained in:
Martin Whitaker 2013-05-19 09:16:24 +01:00
parent 10ec58703f
commit 6364aba975
3 changed files with 47 additions and 46 deletions

83
parse.y
View File

@ -4169,63 +4169,60 @@ module_item
delete $4; delete $4;
} }
| port_direction unsigned_signed_opt range_opt delay3_opt list_of_identifiers ';' | attribute_list_opt port_direction unsigned_signed_opt range_opt delay3_opt list_of_identifiers ';'
{ pform_set_port_type(@1, $5, $3, $2, $1); { pform_set_port_type(@2, $6, $4, $3, $2, $1); }
}
/* The next two rules handle Verilog 2001 statements of the form: /* The next two rules handle Verilog 2001 statements of the form:
input wire signed [h:l] <list>; input wire signed [h:l] <list>;
This creates the wire and sets the port type all at once. */ This creates the wire and sets the port type all at once. */
| port_direction net_type unsigned_signed_opt range_opt list_of_identifiers ';' | attribute_list_opt 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, { pform_makewire(@2, $5, $4, $6, $3, $2, IVL_VT_NO_TYPE, $1, SR_BOTH); }
SR_BOTH);
}
| K_output var_type unsigned_signed_opt range_opt list_of_port_identifiers ';' | attribute_list_opt K_output var_type unsigned_signed_opt range_opt list_of_port_identifiers ';'
{ list<pair<perm_string,PExpr*> >::const_iterator pp; { list<pair<perm_string,PExpr*> >::const_iterator pp;
list<perm_string>*tmp = new list<perm_string>; list<perm_string>*tmp = new list<perm_string>;
for (pp = $5->begin(); pp != $5->end(); ++ pp ) { for (pp = $6->begin(); pp != $6->end(); ++ pp ) {
tmp->push_back((*pp).first); tmp->push_back((*pp).first);
} }
pform_makewire(@1, $4, $3, tmp, $2, NetNet::POUTPUT, pform_makewire(@2, $5, $4, tmp, $3, NetNet::POUTPUT,
IVL_VT_NO_TYPE, 0, SR_BOTH); IVL_VT_NO_TYPE, $1, SR_BOTH);
for (pp = $5->begin(); pp != $5->end(); ++ pp ) { for (pp = $6->begin(); pp != $6->end(); ++ pp ) {
if ((*pp).second) { if ((*pp).second) {
pform_make_reginit(@1, (*pp).first, (*pp).second); pform_make_reginit(@2, (*pp).first, (*pp).second);
} }
} }
delete $5; delete $6;
} }
| port_direction K_wreal list_of_identifiers ';' | attribute_list_opt port_direction K_wreal list_of_identifiers ';'
{ pform_makewire(@1, 0, true, $3, NetNet::WIRE, $1, { pform_makewire(@2, 0, true, $4, NetNet::WIRE, $2,
IVL_VT_REAL, 0, SR_BOTH); IVL_VT_REAL, $1, SR_BOTH);
} }
/* var_type declaration (reg variables) cannot be input or output, /* var_type declaration (reg variables) cannot be input or output,
because the port declaration implies an external driver, which because the port declaration implies an external driver, which
cannot be attached to a reg. These rules catch that error early. */ cannot be attached to a reg. These rules catch that error early. */
| K_input var_type unsigned_signed_opt range_opt list_of_identifiers ';' | attribute_list_opt K_input var_type unsigned_signed_opt range_opt list_of_identifiers ';'
{ pform_makewire(@1, $4, $3, $5, $2, NetNet::PINPUT, { pform_makewire(@2, $5, $4, $6, $3, NetNet::PINPUT,
IVL_VT_NO_TYPE, 0); IVL_VT_NO_TYPE, $1);
yyerror(@2, "error: reg variables cannot be inputs."); yyerror(@3, "error: reg variables cannot be inputs.");
} }
| K_inout var_type unsigned_signed_opt range_opt list_of_identifiers ';' | attribute_list_opt K_inout var_type unsigned_signed_opt range_opt list_of_identifiers ';'
{ pform_makewire(@1, $4, $3, $5, $2, NetNet::PINOUT, { pform_makewire(@2, $5, $4, $6, $3, NetNet::PINOUT,
IVL_VT_NO_TYPE, 0); IVL_VT_NO_TYPE, $1);
yyerror(@2, "error: reg variables cannot be inouts."); yyerror(@3, "error: reg variables cannot be inouts.");
} }
| port_direction unsigned_signed_opt range_opt delay3_opt error ';' | attribute_list_opt port_direction unsigned_signed_opt range_opt delay3_opt error ';'
{ yyerror(@1, "error: Invalid variable list" { yyerror(@2, "error: Invalid variable list in port declaration.");
" in port declaration."); if ($1) delete $1;
if ($3) delete $3; if ($4) delete $4;
if ($4) delete $4; if ($5) delete $5;
yyerrok; yyerrok;
} }
/* Maybe this is a discipline declaration? If so, then the lexor /* Maybe this is a discipline declaration? If so, then the lexor
will see the discipline name as an identifier. We match it to the will see the discipline name as an identifier. We match it to the

View File

@ -2297,6 +2297,7 @@ void pform_makewire(const vlltype&li,
delete names; delete names;
delete range; delete range;
delete attr;
} }
/* /*
@ -2916,7 +2917,8 @@ void pform_set_port_type(const struct vlltype&li,
list<perm_string>*names, list<perm_string>*names,
list<pform_range_t>*range, list<pform_range_t>*range,
bool signed_flag, bool signed_flag,
NetNet::PortType pt) NetNet::PortType pt,
list<named_pexpr_t>*attr)
{ {
assert(pt != NetNet::PIMPLICIT && pt != NetNet::NOT_A_PORT); 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; perm_string txt = *cur;
pform_set_port_type(txt, pt, li.text, li.first_line); 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, pform_set_net_range(txt, NetNet::NONE, range, signed_flag, IVL_VT_NO_TYPE,
SR_PORT, 0); SR_PORT, attr);
} }
delete names; delete names;
delete range; delete range;
delete attr;
} }
static void pform_set_integer_2atom(uint64_t width, bool signed_flag, perm_string name, NetNet::Type net_type, list<named_pexpr_t>*attr) static void pform_set_integer_2atom(uint64_t width, bool signed_flag, perm_string name, NetNet::Type net_type, list<named_pexpr_t>*attr)

View File

@ -340,7 +340,8 @@ extern void pform_set_port_type(const struct vlltype&li,
list<perm_string>*names, list<perm_string>*names,
list<pform_range_t>*range, list<pform_range_t>*range,
bool signed_flag, bool signed_flag,
NetNet::PortType); NetNet::PortType,
list<named_pexpr_t>*attr);
extern void pform_set_reg_idx(perm_string name, extern void pform_set_reg_idx(perm_string name,
std::list<pform_range_t>*indices); std::list<pform_range_t>*indices);