V0.9: Fix for br930 - support attributes on old-style port declarations.
This commit is contained in:
parent
c8c0a298e4
commit
4efb601fee
76
parse.y
76
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] <list>;
|
||||
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<pair<perm_string,PExpr*> >::const_iterator pp;
|
||||
list<perm_string>*tmp = new list<perm_string>;
|
||||
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<pair<perm_string,PExpr*> >::const_iterator pp;
|
||||
list<perm_string>*tmp = new list<perm_string>;
|
||||
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
|
||||
|
|
|
|||
25
pform.cc
25
pform.cc
|
|
@ -1094,7 +1094,8 @@ static void pform_set_net_range(perm_string name,
|
|||
const svector<PExpr*>*range,
|
||||
bool signed_flag,
|
||||
ivl_variable_type_t dt,
|
||||
PWSRType rt)
|
||||
PWSRType rt,
|
||||
svector<named_pexpr_t*>*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<perm_string>*names,
|
||||
|
|
@ -1131,7 +1139,7 @@ void pform_set_net_range(list<perm_string>*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<perm_string>*names,
|
||||
svector<PExpr*>*range,
|
||||
bool signed_flag,
|
||||
NetNet::PortType pt)
|
||||
NetNet::PortType pt,
|
||||
svector<named_pexpr_t*>*attr)
|
||||
{
|
||||
for (list<perm_string>::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)
|
||||
|
|
|
|||
3
pform.h
3
pform.h
|
|
@ -254,7 +254,8 @@ extern void pform_set_port_type(const struct vlltype&li,
|
|||
list<perm_string>*names,
|
||||
svector<PExpr*>*range,
|
||||
bool signed_flag,
|
||||
NetNet::PortType);
|
||||
NetNet::PortType,
|
||||
svector<named_pexpr_t*>*attr);
|
||||
extern void pform_set_port_type(perm_string nm, NetNet::PortType pt,
|
||||
const char*file, unsigned lineno);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue