Add semantics check in component instantiation

There have been applied rules for port and signal
association in component instatiation statements
described in the VHDL standard.
This commit is contained in:
Pawel Szostek 2011-07-12 18:09:50 +02:00 committed by Stephen Williams
parent e19089e838
commit 981425fcce
3 changed files with 29 additions and 6 deletions

View File

@ -54,10 +54,12 @@ int ComponentInstantiation::elaborate(Entity*ent, Architecture*arc)
return 1;
}
map<perm_string,const InterfacePort*> port_match;
for (multimap<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
*/
const InterfacePort*iport = base->find_port(cur->first);
if (iport == 0) {
cerr << get_fileline() << ": error: No port " << cur->first
@ -68,9 +70,10 @@ int ComponentInstantiation::elaborate(Entity*ent, Architecture*arc)
ExpName* tmp;
if (cur->second && (tmp = dynamic_cast<ExpName*>(cur->second)))
errors += tmp->elaborate_rval(ent, arc);
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 */
if (cur->second)
cur->second->elaborate_expr(ent, arc, iport->type);
}

View File

@ -21,6 +21,7 @@
# include "StringHeap.h"
# include "LineInfo.h"
# include "entity.h"
# include <inttypes.h>
# include <list>
# include <vector>
@ -322,7 +323,7 @@ class ExpName : public Expression {
public: // Base methods
int elaborate_lval(Entity*ent, Architecture*arc, bool);
int elaborate_rval(Entity*ent, Architecture*arc);
int elaborate_rval(Entity*ent, Architecture*arc, const InterfacePort*);
const VType* probe_type(Entity*ent, Architecture*arc) const;
int elaborate_expr(Entity*ent, Architecture*arc, const VType*ltype);
int emit(ostream&out, Entity*ent, Architecture*arc);

View File

@ -71,13 +71,32 @@ int ExpName::elaborate_lval(Entity*ent, Architecture*arc, bool is_sequ)
return errors;
}
int ExpName::elaborate_rval(Entity*ent, Architecture*arc)
int ExpName::elaborate_rval(Entity*ent, Architecture*arc, const InterfacePort*lval)
{
int errors = 0;
if (const InterfacePort*cur = ent->find_port(name_)) {
/* OK */
/* IEEE 1076-2008, p.80:
* For a formal port IN, associated port should be IN, OUT, INOUT or BUFFER
* For a formal port OUT, associated port should be OUT, INOUT or BUFFER
* For a formal port INOUT, associated prot should be OUT, INOUT or BUFFER
* For a formal port BUFFER, associated port should be OUT, INOUT or BUFFER
*/
switch(lval->mode) {
case PORT_OUT:
//case PORT_INOUT:
if (cur->mode == PORT_IN) {
cerr << get_fileline() << ": error: Connecting "
"formal output port " << lval->name << " to actual input port "
<< name_ << "." << endl;
errors += 1;
}
break;
case PORT_IN:
case PORT_NONE:
default:
break;
}
} else if (Signal* fs = arc->find_signal(name_)) {
/* OK */