Wildcard named port connections.
Implements Section 23.3.2.4 of IEEE 1800-2009.
This commit is contained in:
parent
ab265c6373
commit
5ba1814e64
47
elaborate.cc
47
elaborate.cc
|
|
@ -1100,6 +1100,7 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
|
|||
// bind by order, this is the same as the source list. Otherwise,
|
||||
// the source list is rearranged by name binding into this list.
|
||||
vector<PExpr*>pins (rmod->port_count());
|
||||
vector<bool>pins_fromwc (rmod->port_count(), false);
|
||||
|
||||
// If the instance has a pins_ member, then we know we are
|
||||
// binding by name. Therefore, make up a pins array that
|
||||
|
|
@ -1110,6 +1111,28 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
|
|||
// Scan the bindings, matching them with port names.
|
||||
for (unsigned idx = 0 ; idx < npins_ ; idx += 1) {
|
||||
|
||||
// Handle wildcard named port
|
||||
if (pins_[idx].name[0] == '*') {
|
||||
for (unsigned j = 0 ; j < nexp ; j += 1) {
|
||||
if (!pins[j]) {
|
||||
pins_fromwc[j] = true;
|
||||
NetNet* net = 0;
|
||||
const NetExpr*par = 0;
|
||||
NetEvent* eve = 0;
|
||||
pform_name_t path_;
|
||||
path_.push_back(name_component_t(rmod->ports[j]->name));
|
||||
symbol_search(this, des, scope,
|
||||
path_, net, par, eve);
|
||||
if (net != 0) {
|
||||
pins[j] = new PEIdent(rmod->ports[j]->name, true);
|
||||
pins[j]->set_lineno(get_lineno());
|
||||
pins[j]->set_file(get_file());
|
||||
}
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// Given a binding, look at the module port names
|
||||
// for the position that matches the binding name.
|
||||
unsigned pidx = rmod->find_port(pins_[idx].name);
|
||||
|
|
@ -1125,10 +1148,17 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
|
|||
continue;
|
||||
}
|
||||
|
||||
// If I already bound something to this port, then
|
||||
// the pins array will already have a pointer
|
||||
// value where I want to place this expression.
|
||||
if (pins[pidx]) {
|
||||
// If I am overriding a wildcard port, delete and
|
||||
// override it
|
||||
if (pins_fromwc[pidx]) {
|
||||
delete pins[pidx];
|
||||
pins_fromwc[pidx] = false;
|
||||
|
||||
// If I already explicitely bound something to
|
||||
// this port, then the pins array will already
|
||||
// have a pointer value where I want to place this
|
||||
// expression.
|
||||
} else if (pins[pidx]) {
|
||||
cerr << get_fileline() << ": error: port ``" <<
|
||||
pins_[idx].name << "'' already bound." <<
|
||||
endl;
|
||||
|
|
@ -1204,6 +1234,15 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
|
|||
// null parameter is passed in.
|
||||
|
||||
if (pins[idx] == 0) {
|
||||
|
||||
if (pins_fromwc[idx]) {
|
||||
cerr << get_fileline() << ": error: Wildcard named port " <<
|
||||
"connection (.*) did not find a matching identifier " <<
|
||||
"for port '" << rmod->ports[idx]->name << "'." << endl;
|
||||
des->errors += 1;
|
||||
return;
|
||||
}
|
||||
|
||||
// We need this information to support the
|
||||
// unconnected_drive directive and for a
|
||||
// unconnected input warning when asked for.
|
||||
|
|
|
|||
|
|
@ -136,6 +136,7 @@ TU [munpf]
|
|||
|
||||
"(*" { return K_PSTAR; }
|
||||
"*)" { return K_STARP; }
|
||||
".*" { return K_DOTSTAR; }
|
||||
"<<" { return K_LS; }
|
||||
"<<<" { return K_LS; /* Note: Functionally, <<< is the same as <<. */}
|
||||
">>" { return K_RS; }
|
||||
|
|
|
|||
8
parse.y
8
parse.y
|
|
@ -300,7 +300,7 @@ static list<named_pexpr_t>* make_named_number(perm_string name, PExpr*val =0)
|
|||
/* K_CONTRIBUTE is <+, the contribution assign. */
|
||||
%token K_CONTRIBUTE
|
||||
%token K_PO_POS K_PO_NEG K_POW
|
||||
%token K_PSTAR K_STARP
|
||||
%token K_PSTAR K_STARP K_DOTSTAR
|
||||
%token K_LOR K_LAND K_NAND K_NOR K_NXOR K_TRIGGER
|
||||
%token K_edge_descriptor
|
||||
|
||||
|
|
@ -3318,6 +3318,12 @@ port_name
|
|||
delete[]$2;
|
||||
$$ = tmp;
|
||||
}
|
||||
| K_DOTSTAR
|
||||
{ named_pexpr_t*tmp = new named_pexpr_t;
|
||||
tmp->name = lex_strings.make("*");
|
||||
tmp->parm = 0;
|
||||
$$ = tmp;
|
||||
}
|
||||
;
|
||||
|
||||
port_name_list
|
||||
|
|
|
|||
Loading…
Reference in New Issue