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:
parent
e19089e838
commit
981425fcce
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue