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:
Vamsi Vytla 2017-03-16 07:41:10 -07:00 committed by Vamsi Vytla
parent fbd69e1774
commit cfd3b893be
6 changed files with 25 additions and 9 deletions

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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);
}
}

View File

@ -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,

View File

@ -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