Support VHDL component instantiations with generics as Verilog parameters.
This commit is contained in:
parent
eeeadea3ac
commit
2be682f8a5
|
|
@ -20,6 +20,8 @@
|
|||
# include "architec.h"
|
||||
# include "expression.h"
|
||||
# include "parse_types.h"
|
||||
// Need this for parse_errors?
|
||||
# include "parse_api.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
|
@ -66,22 +68,45 @@ SignalAssignment::~SignalAssignment()
|
|||
}
|
||||
|
||||
ComponentInstantiation::ComponentInstantiation(perm_string i, perm_string c,
|
||||
list<named_expr_t*>*parms,
|
||||
list<named_expr_t*>*ports)
|
||||
: iname_(i), cname_(c)
|
||||
{
|
||||
while (! ports->empty()) {
|
||||
typedef pair<map<perm_string,Expression*>::iterator,bool> insert_rc;
|
||||
|
||||
while (parms && ! parms->empty()) {
|
||||
named_expr_t*cur = parms->front();
|
||||
parms->pop_front();
|
||||
insert_rc rc = generic_map_.insert(make_pair(cur->name(), cur->expr()));
|
||||
if (! rc.second) {
|
||||
cerr << "?:?: error: Duplicate map of generic " << cur->name()
|
||||
<< " ignored." << endl;
|
||||
parse_errors += 1;
|
||||
}
|
||||
}
|
||||
|
||||
while (ports && ! ports->empty()) {
|
||||
named_expr_t*cur = ports->front();
|
||||
ports->pop_front();
|
||||
port_map_.insert(make_pair(cur->name(), cur->expr()));
|
||||
insert_rc rc = port_map_.insert(make_pair(cur->name(), cur->expr()));
|
||||
if (! rc.second) {
|
||||
cerr << "?:?: error: Duplicate map of port " << cur->name()
|
||||
<< " ignored." << endl;
|
||||
parse_errors += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ComponentInstantiation::~ComponentInstantiation()
|
||||
{
|
||||
for(multimap<perm_string, Expression*>::iterator it = port_map_.begin()
|
||||
; it != port_map_.end(); ++it) {
|
||||
delete it->second;
|
||||
}
|
||||
for (map<perm_string,Expression*>::iterator it = generic_map_.begin()
|
||||
; it != generic_map_.end() ; ++it) {
|
||||
delete it->second;
|
||||
}
|
||||
for (map<perm_string,Expression*>::iterator it = port_map_.begin()
|
||||
; it != port_map_.end(); ++it) {
|
||||
delete it->second;
|
||||
}
|
||||
}
|
||||
|
||||
ProcessStatement::ProcessStatement(perm_string iname,
|
||||
|
|
|
|||
|
|
@ -111,6 +111,7 @@ class ComponentInstantiation : public Architecture::Statement {
|
|||
|
||||
public:
|
||||
ComponentInstantiation(perm_string iname, perm_string cname,
|
||||
std::list<named_expr_t*>*parms,
|
||||
std::list<named_expr_t*>*ports);
|
||||
~ComponentInstantiation();
|
||||
|
||||
|
|
@ -122,7 +123,8 @@ class ComponentInstantiation : public Architecture::Statement {
|
|||
perm_string iname_;
|
||||
perm_string cname_;
|
||||
|
||||
std::multimap<perm_string,Expression*> port_map_;
|
||||
std::map<perm_string,Expression*> generic_map_;
|
||||
std::map<perm_string,Expression*> port_map_;
|
||||
};
|
||||
|
||||
class ProcessStatement : public Architecture::Statement {
|
||||
|
|
|
|||
|
|
@ -54,12 +54,30 @@ int ComponentInstantiation::elaborate(Entity*ent, Architecture*arc)
|
|||
return 1;
|
||||
}
|
||||
|
||||
for (map<perm_string,Expression*>::const_iterator cur = generic_map_.begin()
|
||||
; cur != generic_map_.end() ; ++cur) {
|
||||
// check if generic from component instantiation
|
||||
// exists in the component declaration
|
||||
const InterfacePort*iparm = base->find_generic(cur->first);
|
||||
if (iparm == 0) {
|
||||
cerr << get_fileline() << ": error: No generic " << cur->first
|
||||
<< " in component " << cname_ << "." << endl;
|
||||
errors += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
for (multimap<perm_string,Expression*>::const_iterator cur = port_map_.begin()
|
||||
ExpName* tmp;
|
||||
if (cur->second && (tmp = dynamic_cast<ExpName*>(cur->second)))
|
||||
errors += tmp->elaborate_rval(ent, arc, iparm);
|
||||
|
||||
if (cur->second)
|
||||
errors += cur->second->elaborate_expr(ent, arc, iparm->type);
|
||||
}
|
||||
|
||||
for (map<perm_string,Expression*>::const_iterator cur = port_map_.begin()
|
||||
; cur != port_map_.end() ; ++cur) {
|
||||
/* check if a port from component instantiation
|
||||
exists in the component declaration
|
||||
*/
|
||||
// check if a port from component instantiation
|
||||
// exists in the component declaration
|
||||
const InterfacePort*iport = base->find_port(cur->first);
|
||||
if (iport == 0) {
|
||||
cerr << get_fileline() << ": error: No port " << cur->first
|
||||
|
|
@ -68,9 +86,9 @@ int ComponentInstantiation::elaborate(Entity*ent, Architecture*arc)
|
|||
continue;
|
||||
}
|
||||
|
||||
ExpName* tmp;
|
||||
if (cur->second && (tmp = dynamic_cast<ExpName*>(cur->second)))
|
||||
errors += tmp->elaborate_rval(ent, arc, iport);
|
||||
ExpName* tmp;
|
||||
if (cur->second && (tmp = dynamic_cast<ExpName*>(cur->second)))
|
||||
errors += tmp->elaborate_rval(ent, arc, iport);
|
||||
/* It is possible for the port to be explicitly
|
||||
unconnected. In that case, the Expression will be nil */
|
||||
|
||||
|
|
@ -78,15 +96,6 @@ int ComponentInstantiation::elaborate(Entity*ent, Architecture*arc)
|
|||
cur->second->elaborate_expr(ent, arc, iport->type);
|
||||
}
|
||||
|
||||
//each formal (component's) port should be associated at most once
|
||||
for(multimap<perm_string,Expression*>::const_iterator cur = port_map_.begin()
|
||||
; cur != port_map_.end() ; ++cur)
|
||||
if(port_map_.count(cur->first) != 1) {
|
||||
//at least one port is associated twice or more
|
||||
cerr << cur->second->get_fileline() << ": error: At least one port is associated"
|
||||
<< " twice or more in a single component instantiation." << endl;
|
||||
errors += 1;
|
||||
}
|
||||
return errors;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@
|
|||
# include "vsignal.h"
|
||||
# include <iostream>
|
||||
# include <typeinfo>
|
||||
# include <cassert>
|
||||
# include <ivl_assert.h>
|
||||
|
||||
int Scope::emit_signals(ostream&out, Entity*entity, Architecture*arc)
|
||||
{
|
||||
|
|
@ -116,7 +116,7 @@ int SignalAssignment::emit(ostream&out, Entity*ent, Architecture*arc)
|
|||
{
|
||||
int errors = 0;
|
||||
|
||||
assert(rval_.size() == 1);
|
||||
ivl_assert(*this, rval_.size() == 1);
|
||||
Expression*rval = rval_.front();
|
||||
|
||||
out << "// " << get_fileline() << endl;
|
||||
|
|
@ -132,16 +132,32 @@ int SignalAssignment::emit(ostream&out, Entity*ent, Architecture*arc)
|
|||
|
||||
int ComponentInstantiation::emit(ostream&out, Entity*ent, Architecture*arc)
|
||||
{
|
||||
const char*comma = "";
|
||||
int errors = 0;
|
||||
|
||||
out << cname_ << " " << iname_ << "(";
|
||||
const char*comma = "";
|
||||
for (multimap<perm_string,Expression*>::iterator cur = port_map_.begin()
|
||||
out << cname_;
|
||||
if (generic_map_.size() > 0) {
|
||||
out << " #(";
|
||||
comma = "";
|
||||
for (map<perm_string,Expression*>::iterator cur = generic_map_.begin()
|
||||
; cur != generic_map_.end() ; ++cur) {
|
||||
ivl_assert(*this, cur->second);
|
||||
out << comma << ".\\" << cur->first << " (";
|
||||
errors += cur->second->emit(out, ent, arc);
|
||||
out << ")";
|
||||
comma = ", ";
|
||||
}
|
||||
out << ")";
|
||||
}
|
||||
|
||||
out << " \\" << iname_ << " (";
|
||||
comma = "";
|
||||
for (map<perm_string,Expression*>::iterator cur = port_map_.begin()
|
||||
; cur != port_map_.end() ; ++cur) {
|
||||
// Skip unconnected ports
|
||||
if (cur->second == 0)
|
||||
continue;
|
||||
out << comma << "." << cur->first << "(";
|
||||
out << comma << ".\\" << cur->first << " (";
|
||||
errors += cur->second->emit(out, ent, arc);
|
||||
out << ")";
|
||||
comma = ", ";
|
||||
|
|
|
|||
|
|
@ -256,6 +256,7 @@ const VType*parse_type_by_name(perm_string name)
|
|||
|
||||
%type <named_expr> association_element
|
||||
%type <named_expr_list> association_list port_map_aspect port_map_aspect_opt
|
||||
%type <named_expr_list> generic_map_aspect generic_map_aspect_opt
|
||||
|
||||
%type <vtype> subtype_indication type_definition
|
||||
|
||||
|
|
@ -366,11 +367,12 @@ association_list
|
|||
;
|
||||
|
||||
binding_indication
|
||||
: K_use entity_aspect_opt
|
||||
port_map_aspect_opt
|
||||
generic_map_aspect_opt
|
||||
{ //TODO: do sth with generic map aspect
|
||||
$$ = $2;
|
||||
: K_use entity_aspect_opt port_map_aspect_opt generic_map_aspect_opt
|
||||
{ $$ = $2;
|
||||
if ($3) sorrymsg(@3, "Port map aspect not supported here. (binding_indication)\n");
|
||||
if ($4) sorrymsg(@4, "Generic map aspect not supported here. (binding_indication)\n");
|
||||
delete $3;
|
||||
delete $4;
|
||||
}
|
||||
;
|
||||
|
||||
|
|
@ -524,22 +526,22 @@ component_configuration
|
|||
|
||||
component_declaration
|
||||
: K_component IDENTIFIER K_is_opt
|
||||
port_clause_opt
|
||||
generic_clause_opt port_clause_opt
|
||||
K_end K_component identifier_opt ';'
|
||||
{ perm_string name = lex_strings.make($2);
|
||||
if($7 && name != $7) {
|
||||
errormsg(@7, "Identifier %s doesn't match component name %s.\n",
|
||||
$7, name.str());
|
||||
if($8 && name != $8) {
|
||||
errormsg(@8, "Identifier %s doesn't match component name %s.\n",
|
||||
$8, name.str());
|
||||
}
|
||||
|
||||
ComponentBase*comp = new ComponentBase(name);
|
||||
if ($4) {
|
||||
comp->set_interface(0, $4);
|
||||
delete $4;
|
||||
}
|
||||
comp->set_interface($4, $5);
|
||||
if ($4) delete $4;
|
||||
if ($5) delete $5;
|
||||
|
||||
active_scope->bind_name(name, comp);
|
||||
delete[]$2;
|
||||
if ($7) delete[] $7;
|
||||
if ($8) delete[] $8;
|
||||
}
|
||||
|
||||
| K_component IDENTIFIER K_is_opt error K_end K_component identifier_opt ';'
|
||||
|
|
@ -551,11 +553,12 @@ component_declaration
|
|||
;
|
||||
|
||||
component_instantiation_statement
|
||||
: IDENTIFIER ':' K_component_opt IDENTIFIER port_map_aspect_opt ';'
|
||||
: IDENTIFIER ':' K_component_opt IDENTIFIER generic_map_aspect_opt port_map_aspect_opt ';'
|
||||
{ perm_string iname = lex_strings.make($1);
|
||||
perm_string cname = lex_strings.make($4);
|
||||
ComponentInstantiation*tmp = new ComponentInstantiation(iname, cname, $5);
|
||||
delete $5;
|
||||
ComponentInstantiation*tmp = new ComponentInstantiation(iname, cname, $5, $6);
|
||||
delete $5;
|
||||
delete $6;
|
||||
FILE_NAME(tmp, @1);
|
||||
delete[]$1;
|
||||
delete[]$4;
|
||||
|
|
@ -958,14 +961,17 @@ generic_clause
|
|||
;
|
||||
|
||||
generic_map_aspect_opt
|
||||
: generic_map_aspect
|
||||
|
|
||||
: generic_map_aspect { $$ = $1; }
|
||||
| { $$ = 0; }
|
||||
;
|
||||
|
||||
generic_map_aspect
|
||||
: K_generic K_map '(' association_list ')'
|
||||
{
|
||||
sorrymsg(@1, "Generic map aspect not yet supported.\n");
|
||||
{ $$ = $4; }
|
||||
| K_generic K_map '(' error ')'
|
||||
{ errormsg(@4, "Error in association list for generic map.\n");
|
||||
yyerrok;
|
||||
$$ = 0;
|
||||
}
|
||||
;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue