Add support to handle attributes at module instantiation sites.
(* my_fancy_attribute *)
foobar1 foobar (clk(clk), rst(rst) ...);
- Modifies PGModule to hold the attribute map (can be verified with pform_dump)
- pform_make_modgate(s) bind the attributes from the parser to the above map
- The attributes from PGModule are inserted into the NetScope of that module
PGModule::elaborate_scope_mod_instances_
- Currently these attributes automatically make it into netlist
- These attributes are accessible via ivl_scope_attr_cnt and ivl_scope_attr_val
from ivl_target.h
This commit is contained in:
parent
fbd69e1774
commit
cfd3b893be
2
PGate.h
2
PGate.h
|
|
@ -217,6 +217,8 @@ class PGModule : public PGate {
|
|||
// method to pass the range to the pform.
|
||||
void set_range(PExpr*msb, PExpr*lsb);
|
||||
|
||||
map<perm_string,PExpr*> attributes;
|
||||
|
||||
virtual void dump(ostream&out, unsigned ind =4) const;
|
||||
virtual void elaborate(Design*, NetScope*scope) const;
|
||||
virtual void elaborate_scope(Design*des, NetScope*sc) const;
|
||||
|
|
|
|||
|
|
@ -1728,6 +1728,10 @@ void PGModule::elaborate_scope_mod_instances_(Design*des, Module*mod, NetScope*s
|
|||
<< "." << endl;
|
||||
}
|
||||
|
||||
struct attrib_list_t*attrib_list;
|
||||
unsigned attrib_list_n = 0;
|
||||
attrib_list = evaluate_attributes(attributes, attrib_list_n, des, sc);
|
||||
|
||||
// Run through the module instances, and make scopes out of
|
||||
// them. Also do parameter overrides that are done on the
|
||||
// instantiation line.
|
||||
|
|
@ -1762,6 +1766,9 @@ void PGModule::elaborate_scope_mod_instances_(Design*des, Module*mod, NetScope*s
|
|||
get_lineno(), mod->get_lineno());
|
||||
my_scope->set_module_name(mod->mod_name());
|
||||
|
||||
for (unsigned adx = 0 ; adx < attrib_list_n ; adx += 1)
|
||||
my_scope->attribute(attrib_list[adx].key, attrib_list[adx].val);
|
||||
|
||||
instances[idx] = my_scope;
|
||||
|
||||
set_scope_timescale(des, my_scope, mod);
|
||||
|
|
@ -1820,6 +1827,7 @@ void PGModule::elaborate_scope_mod_instances_(Design*des, Module*mod, NetScope*s
|
|||
mod->elaborate_scope(des, my_scope, replace);
|
||||
|
||||
}
|
||||
delete[]attrib_list;
|
||||
|
||||
/* Stash the instance array of scopes into the parent
|
||||
scope. Later elaboration passes will use this vector to
|
||||
|
|
|
|||
3
parse.y
3
parse.y
|
|
@ -4855,9 +4855,8 @@ module_item
|
|||
| attribute_list_opt
|
||||
IDENTIFIER parameter_value_opt gate_instance_list ';'
|
||||
{ perm_string tmp1 = lex_strings.make($2);
|
||||
pform_make_modgates(@2, tmp1, $3, $4);
|
||||
pform_make_modgates(@2, tmp1, $3, $4, $1);
|
||||
delete[]$2;
|
||||
if ($1) delete $1;
|
||||
}
|
||||
|
||||
| attribute_list_opt
|
||||
|
|
|
|||
17
pform.cc
17
pform.cc
|
|
@ -2213,7 +2213,8 @@ static void pform_make_modgate(perm_string type,
|
|||
struct parmvalue_t*overrides,
|
||||
list<PExpr*>*wires,
|
||||
PExpr*msb, PExpr*lsb,
|
||||
const char*fn, unsigned ln)
|
||||
const char*fn, unsigned ln,
|
||||
std::list<named_pexpr_t>*attr)
|
||||
{
|
||||
for (list<PExpr*>::iterator idx = wires->begin()
|
||||
; idx != wires->end() ; ++idx) {
|
||||
|
|
@ -2244,6 +2245,7 @@ static void pform_make_modgate(perm_string type,
|
|||
pform_cur_generate->add_gate(cur);
|
||||
else
|
||||
pform_cur_module.front()->add_gate(cur);
|
||||
pform_bind_attributes(cur->attributes, attr);
|
||||
}
|
||||
|
||||
static void pform_make_modgate(perm_string type,
|
||||
|
|
@ -2251,7 +2253,8 @@ static void pform_make_modgate(perm_string type,
|
|||
struct parmvalue_t*overrides,
|
||||
list<named_pexpr_t>*bind,
|
||||
PExpr*msb, PExpr*lsb,
|
||||
const char*fn, unsigned ln)
|
||||
const char*fn, unsigned ln,
|
||||
std::list<named_pexpr_t>*attr)
|
||||
{
|
||||
unsigned npins = bind->size();
|
||||
named<PExpr*>*pins = new named<PExpr*>[npins];
|
||||
|
|
@ -2288,12 +2291,14 @@ static void pform_make_modgate(perm_string type,
|
|||
pform_cur_generate->add_gate(cur);
|
||||
else
|
||||
pform_cur_module.front()->add_gate(cur);
|
||||
pform_bind_attributes(cur->attributes, attr);
|
||||
}
|
||||
|
||||
void pform_make_modgates(const struct vlltype&loc,
|
||||
perm_string type,
|
||||
struct parmvalue_t*overrides,
|
||||
svector<lgate>*gates)
|
||||
svector<lgate>*gates,
|
||||
std::list<named_pexpr_t>*attr)
|
||||
{
|
||||
assert(! pform_cur_module.empty());
|
||||
if (pform_cur_module.front()->program_block) {
|
||||
|
|
@ -2315,7 +2320,7 @@ void pform_make_modgates(const struct vlltype&loc,
|
|||
pform_make_modgate(type, cur_name, overrides,
|
||||
cur.parms_by_name,
|
||||
cur.range.first, cur.range.second,
|
||||
cur.file, cur.lineno);
|
||||
cur.file, cur.lineno, attr);
|
||||
|
||||
} else if (cur.parms) {
|
||||
|
||||
|
|
@ -2329,14 +2334,14 @@ void pform_make_modgates(const struct vlltype&loc,
|
|||
pform_make_modgate(type, cur_name, overrides,
|
||||
cur.parms,
|
||||
cur.range.first, cur.range.second,
|
||||
cur.file, cur.lineno);
|
||||
cur.file, cur.lineno, attr);
|
||||
|
||||
} else {
|
||||
list<PExpr*>*wires = new list<PExpr*>;
|
||||
pform_make_modgate(type, cur_name, overrides,
|
||||
wires,
|
||||
cur.range.first, cur.range.second,
|
||||
cur.file, cur.lineno);
|
||||
cur.file, cur.lineno, attr);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
3
pform.h
3
pform.h
|
|
@ -478,7 +478,8 @@ extern void pform_makegates(const struct vlltype&loc,
|
|||
extern void pform_make_modgates(const struct vlltype&loc,
|
||||
perm_string type,
|
||||
struct parmvalue_t*overrides,
|
||||
svector<lgate>*gates);
|
||||
svector<lgate>*gates,
|
||||
list<named_pexpr_t>*attr);
|
||||
|
||||
/* Make a continuous assignment node, with optional bit- or part- select. */
|
||||
extern void pform_make_pgassign_list(list<PExpr*>*alist,
|
||||
|
|
|
|||
|
|
@ -729,6 +729,7 @@ void PGModule::dump(ostream&out, unsigned ind) const
|
|||
dump_pins(out);
|
||||
}
|
||||
out << ");" << endl;
|
||||
dump_attributes_map(out, attributes, 8);
|
||||
}
|
||||
|
||||
void Statement::dump(ostream&out, unsigned ind) const
|
||||
|
|
|
|||
Loading…
Reference in New Issue