From cfd3b893be43b3a4e06febeb0a3e1bc2ad9bfdda Mon Sep 17 00:00:00 2001 From: Vamsi Vytla Date: Thu, 16 Mar 2017 07:41:10 -0700 Subject: [PATCH] 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 --- PGate.h | 2 ++ elab_scope.cc | 8 ++++++++ parse.y | 3 +-- pform.cc | 17 +++++++++++------ pform.h | 3 ++- pform_dump.cc | 1 + 6 files changed, 25 insertions(+), 9 deletions(-) diff --git a/PGate.h b/PGate.h index 5d9bde9f2..ee6f10f79 100644 --- a/PGate.h +++ b/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 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; diff --git a/elab_scope.cc b/elab_scope.cc index 182518bb0..9796ce7fc 100644 --- a/elab_scope.cc +++ b/elab_scope.cc @@ -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 diff --git a/parse.y b/parse.y index 34d9064c3..882509da8 100644 --- a/parse.y +++ b/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 diff --git a/pform.cc b/pform.cc index 329b8a797..9bfa23b8b 100644 --- a/pform.cc +++ b/pform.cc @@ -2213,7 +2213,8 @@ static void pform_make_modgate(perm_string type, struct parmvalue_t*overrides, list*wires, PExpr*msb, PExpr*lsb, - const char*fn, unsigned ln) + const char*fn, unsigned ln, + std::list*attr) { for (list::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*bind, PExpr*msb, PExpr*lsb, - const char*fn, unsigned ln) + const char*fn, unsigned ln, + std::list*attr) { unsigned npins = bind->size(); named*pins = new named[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*gates) + svector*gates, + std::list*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*wires = new list; pform_make_modgate(type, cur_name, overrides, wires, cur.range.first, cur.range.second, - cur.file, cur.lineno); + cur.file, cur.lineno, attr); } } diff --git a/pform.h b/pform.h index e9d553127..8666386eb 100644 --- a/pform.h +++ b/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*gates); + svector*gates, + list*attr); /* Make a continuous assignment node, with optional bit- or part- select. */ extern void pform_make_pgassign_list(list*alist, diff --git a/pform_dump.cc b/pform_dump.cc index 6d2d3a9cd..de03de673 100644 --- a/pform_dump.cc +++ b/pform_dump.cc @@ -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