Add support for module instance arrays.
This commit is contained in:
parent
62cffe16f4
commit
9de786fc44
|
|
@ -344,9 +344,6 @@ constructs.
|
||||||
- tran primitives, i.e. tran, tranif1, tranif0, rtran, rtranif1
|
- tran primitives, i.e. tran, tranif1, tranif0, rtran, rtranif1
|
||||||
and rtranif0 are not supported.
|
and rtranif0 are not supported.
|
||||||
|
|
||||||
- Module instance arrays are not supported, although gate instance
|
|
||||||
arrays do work.
|
|
||||||
|
|
||||||
- Net delays, of the form "wire #N foo;" do not work. Delays in
|
- Net delays, of the form "wire #N foo;" do not work. Delays in
|
||||||
every other context do work properly, including the V2001 form
|
every other context do work properly, including the V2001 form
|
||||||
"wire #5 foo = bar;"
|
"wire #5 foo = bar;"
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: compiler.h,v 1.22 2004/03/10 04:51:24 steve Exp $"
|
#ident "$Id: compiler.h,v 1.23 2004/09/05 17:44:41 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include <list>
|
# include <list>
|
||||||
|
|
@ -81,6 +81,8 @@ extern bool warn_portbinding;
|
||||||
/* This is true if verbose output is requested. */
|
/* This is true if verbose output is requested. */
|
||||||
extern bool verbose_flag;
|
extern bool verbose_flag;
|
||||||
|
|
||||||
|
extern bool debug_scopes;
|
||||||
|
|
||||||
/* Path to a directory useful for finding subcomponents. */
|
/* Path to a directory useful for finding subcomponents. */
|
||||||
extern const char*basedir;
|
extern const char*basedir;
|
||||||
|
|
||||||
|
|
@ -132,6 +134,9 @@ extern int load_sys_func_table(const char*path);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: compiler.h,v $
|
* $Log: compiler.h,v $
|
||||||
|
* Revision 1.23 2004/09/05 17:44:41 steve
|
||||||
|
* Add support for module instance arrays.
|
||||||
|
*
|
||||||
* Revision 1.22 2004/03/10 04:51:24 steve
|
* Revision 1.22 2004/03/10 04:51:24 steve
|
||||||
* Add support for system function table files.
|
* Add support for system function table files.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
197
elab_scope.cc
197
elab_scope.cc
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: elab_scope.cc,v 1.33 2004/08/26 04:02:03 steve Exp $"
|
#ident "$Id: elab_scope.cc,v 1.34 2004/09/05 17:44:41 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -46,6 +46,11 @@
|
||||||
|
|
||||||
bool Module::elaborate_scope(Design*des, NetScope*scope) const
|
bool Module::elaborate_scope(Design*des, NetScope*scope) const
|
||||||
{
|
{
|
||||||
|
if (debug_scopes) {
|
||||||
|
cerr << get_line() << ": debug: Elaborate scope "
|
||||||
|
<< scope->name() << "." << endl;
|
||||||
|
}
|
||||||
|
|
||||||
// Generate all the parameters that this instance of this
|
// Generate all the parameters that this instance of this
|
||||||
// module introduces to the design. This loop elaborates the
|
// module introduces to the design. This loop elaborates the
|
||||||
// parameters, but doesn't evaluate references to
|
// parameters, but doesn't evaluate references to
|
||||||
|
|
@ -219,7 +224,6 @@ bool Module::elaborate_scope(Design*des, NetScope*scope) const
|
||||||
// scan all of them to create those scopes.
|
// scan all of them to create those scopes.
|
||||||
|
|
||||||
typedef list<PGate*>::const_iterator gates_it_t;
|
typedef list<PGate*>::const_iterator gates_it_t;
|
||||||
|
|
||||||
for (gates_it_t cur = gates_.begin()
|
for (gates_it_t cur = gates_.begin()
|
||||||
; cur != gates_.end() ; cur ++ ) {
|
; cur != gates_.end() ; cur ++ ) {
|
||||||
|
|
||||||
|
|
@ -305,80 +309,142 @@ void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the new scope as a MODULE with my name.
|
verinum*msb = msb_ ? msb_->eval_const(des, sc) : 0;
|
||||||
NetScope*my_scope = new NetScope(sc, get_name(), NetScope::MODULE);
|
verinum*lsb = lsb_ ? lsb_->eval_const(des, sc) : 0;
|
||||||
my_scope->set_module_name(mod->mod_name());
|
|
||||||
my_scope->default_nettype(mod->default_nettype);
|
|
||||||
|
|
||||||
// Set time units and precision.
|
assert( (msb == 0) || (lsb != 0) );
|
||||||
my_scope->time_unit(mod->time_unit);
|
|
||||||
my_scope->time_precision(mod->time_precision);
|
|
||||||
des->set_precision(mod->time_precision);
|
|
||||||
|
|
||||||
// This call actually arranges for the description of the
|
long instance_low = 0;
|
||||||
// module type to process this instance and handle parameters
|
long instance_high = 0;
|
||||||
// and sub-scopes that might occur. Parameters are also
|
long instance_count = 1;
|
||||||
// created in that scope, as they exist. (I'll override them
|
bool instance_array = false;
|
||||||
// later.)
|
|
||||||
mod->elaborate_scope(des, my_scope);
|
|
||||||
|
|
||||||
// Look for module parameter replacements. The "replace" map
|
if (msb) {
|
||||||
// maps parameter name to replacement expression that is
|
instance_array = true;
|
||||||
// passed. It is built up by the ordered overrides or named
|
instance_high = msb->as_long();
|
||||||
// overrides.
|
instance_low = lsb->as_long();
|
||||||
|
if (instance_high > instance_low)
|
||||||
|
instance_count = instance_high - instance_low + 1;
|
||||||
|
else
|
||||||
|
instance_count = instance_low - instance_high + 1;
|
||||||
|
}
|
||||||
|
|
||||||
typedef map<perm_string,PExpr*>::const_iterator mparm_it_t;
|
NetScope::scope_vec_t instances (instance_count);
|
||||||
map<perm_string,PExpr*> replace;
|
if (debug_scopes) {
|
||||||
|
cerr << get_line() << ": debug: Create " << instance_count
|
||||||
|
<< " instances of " << get_name()
|
||||||
|
<< "." << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run through the module instances, and make scopes out of
|
||||||
|
// them. Also do parameter overrides that are done on the
|
||||||
|
// instantiation line.
|
||||||
|
for (int idx = 0 ; idx < instance_count ; idx += 1) {
|
||||||
|
|
||||||
|
perm_string use_name = get_name();
|
||||||
|
|
||||||
|
if (instance_array) {
|
||||||
|
char name_buf[128];
|
||||||
|
int instance_idx = idx;
|
||||||
|
if (instance_low < instance_high)
|
||||||
|
instance_idx = instance_low + idx;
|
||||||
|
else
|
||||||
|
instance_idx = instance_low - idx;
|
||||||
|
|
||||||
|
snprintf(name_buf, sizeof name_buf,
|
||||||
|
"%s[%d]", get_name().str(), instance_idx);
|
||||||
|
use_name = lex_strings.make(name_buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (debug_scopes) {
|
||||||
|
cerr << get_line() << ": debug: Module instance " << use_name
|
||||||
|
<< " becomes child of " << sc->name()
|
||||||
|
<< "." << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the new scope as a MODULE with my name.
|
||||||
|
NetScope*my_scope = new NetScope(sc, use_name, NetScope::MODULE);
|
||||||
|
my_scope->set_module_name(mod->mod_name());
|
||||||
|
my_scope->default_nettype(mod->default_nettype);
|
||||||
|
|
||||||
|
instances[idx] = my_scope;
|
||||||
|
|
||||||
|
// Set time units and precision.
|
||||||
|
my_scope->time_unit(mod->time_unit);
|
||||||
|
my_scope->time_precision(mod->time_precision);
|
||||||
|
des->set_precision(mod->time_precision);
|
||||||
|
|
||||||
|
// This call actually arranges for the description of the
|
||||||
|
// module type to process this instance and handle parameters
|
||||||
|
// and sub-scopes that might occur. Parameters are also
|
||||||
|
// created in that scope, as they exist. (I'll override them
|
||||||
|
// later.)
|
||||||
|
mod->elaborate_scope(des, my_scope);
|
||||||
|
|
||||||
|
// Look for module parameter replacements. The "replace" map
|
||||||
|
// maps parameter name to replacement expression that is
|
||||||
|
// passed. It is built up by the ordered overrides or named
|
||||||
|
// overrides.
|
||||||
|
|
||||||
|
typedef map<perm_string,PExpr*>::const_iterator mparm_it_t;
|
||||||
|
map<perm_string,PExpr*> replace;
|
||||||
|
|
||||||
|
|
||||||
// Positional parameter overrides are matched to parameter
|
// Positional parameter overrides are matched to parameter
|
||||||
// names by using the param_names list of parameter
|
// names by using the param_names list of parameter
|
||||||
// names. This is an ordered list of names so the first name
|
// names. This is an ordered list of names so the first name
|
||||||
// is parameter 0, the second parameter 1, and so on.
|
// is parameter 0, the second parameter 1, and so on.
|
||||||
|
|
||||||
if (overrides_) {
|
if (overrides_) {
|
||||||
assert(parms_ == 0);
|
assert(parms_ == 0);
|
||||||
list<perm_string>::const_iterator cur = mod->param_names.begin();
|
list<perm_string>::const_iterator cur
|
||||||
unsigned idx = 0;
|
= mod->param_names.begin();
|
||||||
for (;;) {
|
unsigned idx = 0;
|
||||||
if (idx >= overrides_->count())
|
for (;;) {
|
||||||
break;
|
if (idx >= overrides_->count())
|
||||||
if (cur == mod->param_names.end())
|
break;
|
||||||
break;
|
if (cur == mod->param_names.end())
|
||||||
|
break;
|
||||||
|
|
||||||
replace[*cur] = (*overrides_)[idx];
|
replace[*cur] = (*overrides_)[idx];
|
||||||
|
|
||||||
idx += 1;
|
idx += 1;
|
||||||
cur ++;
|
cur ++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Named parameter overrides carry a name with each override
|
||||||
|
// so the mapping into the replace list is much easier.
|
||||||
|
if (parms_) {
|
||||||
|
assert(overrides_ == 0);
|
||||||
|
for (unsigned idx = 0 ; idx < nparms_ ; idx += 1)
|
||||||
|
replace[parms_[idx].name] = parms_[idx].parm;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// And here we scan the replacements we collected. Elaborate
|
||||||
|
// the expression in my context, then replace the sub-scope
|
||||||
|
// parameter value with the new expression.
|
||||||
|
|
||||||
|
for (mparm_it_t cur = replace.begin()
|
||||||
|
; cur != replace.end() ; cur ++ ) {
|
||||||
|
|
||||||
|
PExpr*tmp = (*cur).second;
|
||||||
|
NetExpr*val = tmp->elaborate_pexpr(des, sc);
|
||||||
|
bool flag = my_scope->replace_parameter((*cur).first, val);
|
||||||
|
if (! flag) {
|
||||||
|
cerr << val->get_line() << ": warning: parameter "
|
||||||
|
<< (*cur).first << " not found in "
|
||||||
|
<< sc->name() << "." << endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Named parameter overrides carry a name with each override
|
/* Stash the instance array of scopes into the parent
|
||||||
// so the mapping into the replace list is much easier.
|
scope. Later elaboration passes will use this vector to
|
||||||
if (parms_) {
|
further elaborate the array. */
|
||||||
assert(overrides_ == 0);
|
sc->instance_arrays[get_name()] = instances;
|
||||||
for (unsigned idx = 0 ; idx < nparms_ ; idx += 1)
|
|
||||||
replace[parms_[idx].name] = parms_[idx].parm;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// And here we scan the replacements we collected. Elaborate
|
|
||||||
// the expression in my context, then replace the sub-scope
|
|
||||||
// parameter value with the new expression.
|
|
||||||
|
|
||||||
for (mparm_it_t cur = replace.begin()
|
|
||||||
; cur != replace.end() ; cur ++ ) {
|
|
||||||
|
|
||||||
PExpr*tmp = (*cur).second;
|
|
||||||
NetExpr*val = tmp->elaborate_pexpr(des, sc);
|
|
||||||
bool flag = my_scope->replace_parameter((*cur).first, val);
|
|
||||||
if (! flag) {
|
|
||||||
cerr << val->get_line() << ": warning: parameter "
|
|
||||||
<< (*cur).first << " not found in "
|
|
||||||
<< sc->name() << "." << endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -568,6 +634,9 @@ void PWhile::elaborate_scope(Design*des, NetScope*scope) const
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: elab_scope.cc,v $
|
* $Log: elab_scope.cc,v $
|
||||||
|
* Revision 1.34 2004/09/05 17:44:41 steve
|
||||||
|
* Add support for module instance arrays.
|
||||||
|
*
|
||||||
* Revision 1.33 2004/08/26 04:02:03 steve
|
* Revision 1.33 2004/08/26 04:02:03 steve
|
||||||
* Add support for localparam ranges.
|
* Add support for localparam ranges.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
41
elab_sig.cc
41
elab_sig.cc
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: elab_sig.cc,v 1.34 2004/05/31 23:34:37 steve Exp $"
|
#ident "$Id: elab_sig.cc,v 1.35 2004/09/05 17:44:41 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -211,23 +211,31 @@ bool Module::elaborate_sig(Design*des, NetScope*scope) const
|
||||||
bool PGModule::elaborate_sig_mod_(Design*des, NetScope*scope,
|
bool PGModule::elaborate_sig_mod_(Design*des, NetScope*scope,
|
||||||
Module*rmod) const
|
Module*rmod) const
|
||||||
{
|
{
|
||||||
// Missing module instance names have already been rejected.
|
bool flag = true;
|
||||||
assert(get_name() != "");
|
|
||||||
|
NetScope::scope_vec_t instance = scope->instance_arrays[get_name()];
|
||||||
|
|
||||||
|
for (unsigned idx = 0 ; idx < instance.count() ; idx += 1) {
|
||||||
|
// I know a priori that the elaborate_scope created the scope
|
||||||
|
// already, so just look it up as a child of the current scope.
|
||||||
|
NetScope*my_scope = instance[idx];
|
||||||
|
assert(my_scope);
|
||||||
|
|
||||||
|
if (my_scope->parent() != scope) {
|
||||||
|
cerr << get_line() << ": internal error: "
|
||||||
|
<< "Instance " << my_scope->name()
|
||||||
|
<< " is in parent " << my_scope->parent()->name()
|
||||||
|
<< " instead of " << scope->name()
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
assert(my_scope->parent() == scope);
|
||||||
|
|
||||||
|
if (! rmod->elaborate_sig(des, my_scope))
|
||||||
|
flag = false;
|
||||||
|
|
||||||
if (msb_) {
|
|
||||||
cerr << get_line() << ": sorry: Module instantiation arrays "
|
|
||||||
"are not yet supported." << endl;
|
|
||||||
des->errors += 1;
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return flag;
|
||||||
// I know a priori that the elaborate_scope created the scope
|
|
||||||
// already, so just look it up as a child of the current scope.
|
|
||||||
NetScope*my_scope = scope->child(get_name());
|
|
||||||
assert(my_scope);
|
|
||||||
|
|
||||||
return rmod->elaborate_sig(des, my_scope);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -607,6 +615,9 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: elab_sig.cc,v $
|
* $Log: elab_sig.cc,v $
|
||||||
|
* Revision 1.35 2004/09/05 17:44:41 steve
|
||||||
|
* Add support for module instance arrays.
|
||||||
|
*
|
||||||
* Revision 1.34 2004/05/31 23:34:37 steve
|
* Revision 1.34 2004/05/31 23:34:37 steve
|
||||||
* Rewire/generalize parsing an elaboration of
|
* Rewire/generalize parsing an elaboration of
|
||||||
* function return values to allow for better
|
* function return values to allow for better
|
||||||
|
|
|
||||||
118
elaborate.cc
118
elaborate.cc
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: elaborate.cc,v 1.305 2004/06/30 15:32:02 steve Exp $"
|
#ident "$Id: elaborate.cc,v 1.306 2004/09/05 17:44:41 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -492,23 +492,9 @@ void PGBuiltin::elaborate(Design*des, NetScope*scope) const
|
||||||
*/
|
*/
|
||||||
void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
|
void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
|
||||||
{
|
{
|
||||||
// Missing module instance names have already been rejected.
|
|
||||||
assert(get_name() != 0);
|
|
||||||
|
|
||||||
if (msb_) {
|
|
||||||
cerr << get_line() << ": sorry: Module instantiation arrays "
|
|
||||||
"are not yet supported." << endl;
|
|
||||||
des->errors += 1;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(scope);
|
assert(scope);
|
||||||
|
|
||||||
// I know a priori that the elaborate_scope created the scope
|
|
||||||
// already, so just look it up as a child of the current scope.
|
|
||||||
NetScope*my_scope = scope->child(get_name());
|
|
||||||
assert(my_scope);
|
|
||||||
|
|
||||||
// This is the array of pin expressions, shuffled to match the
|
// This is the array of pin expressions, shuffled to match the
|
||||||
// order of the declaration. If the source instantiation uses
|
// order of the declaration. If the source instantiation uses
|
||||||
// bind by order, this is the same as the source
|
// bind by order, this is the same as the source
|
||||||
|
|
@ -589,11 +575,18 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
|
||||||
pins = get_pins();
|
pins = get_pins();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Elaborate this instance of the module. The recursive
|
|
||||||
|
// Elaborate these instances of the module. The recursive
|
||||||
// elaboration causes the module to generate a netlist with
|
// elaboration causes the module to generate a netlist with
|
||||||
// the ports represented by NetNet objects. I will find them
|
// the ports represented by NetNet objects. I will find them
|
||||||
// later.
|
// later.
|
||||||
rmod->elaborate(des, my_scope);
|
|
||||||
|
NetScope::scope_vec_t&instance = scope->instance_arrays[get_name()];
|
||||||
|
for (unsigned inst = 0 ; inst < instance.count() ; inst += 1) {
|
||||||
|
rmod->elaborate(des, instance[inst]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Now connect the ports of the newly elaborated designs to
|
// Now connect the ports of the newly elaborated designs to
|
||||||
// the expressions that are the instantiation parameters. Scan
|
// the expressions that are the instantiation parameters. Scan
|
||||||
|
|
@ -621,7 +614,7 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
|
||||||
if (mport.count() == 0)
|
if (mport.count() == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
NetNet*tmp = des->find_signal(my_scope,
|
NetNet*tmp = des->find_signal(instance[0],
|
||||||
mport[0]->path());
|
mport[0]->path());
|
||||||
assert(tmp);
|
assert(tmp);
|
||||||
|
|
||||||
|
|
@ -639,36 +632,48 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Inside the module, the port is zero or more signals
|
// Inside the module, the port is zero or more signals
|
||||||
// that were already elaborated. List all those signals
|
// that were already elaborated. List all those signals
|
||||||
// and the NetNet equivalents.
|
// and the NetNet equivalents, for all the instances.
|
||||||
svector<PEIdent*> mport = rmod->get_port(idx);
|
svector<PEIdent*> mport = rmod->get_port(idx);
|
||||||
svector<NetNet*>prts (mport.count());
|
svector<NetNet*>prts (mport.count() * instance.count());
|
||||||
|
|
||||||
// Count the internal pins of the port.
|
// Count the internal pins of the port.
|
||||||
unsigned prts_pin_count = 0;
|
unsigned prts_pin_count = 0;
|
||||||
for (unsigned ldx = 0 ; ldx < mport.count() ; ldx += 1) {
|
|
||||||
PEIdent*pport = mport[ldx];
|
|
||||||
assert(pport);
|
|
||||||
prts[ldx] = pport->elaborate_port(des, my_scope);
|
|
||||||
if (prts[ldx] == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
assert(prts[ldx]);
|
for (unsigned inst = 0 ; inst < instance.count() ; inst += 1) {
|
||||||
prts_pin_count += prts[ldx]->pin_count();
|
NetScope*inst_scope = instance[inst];
|
||||||
|
|
||||||
|
// Scan the module sub-ports for this instance...
|
||||||
|
for (unsigned ldx = 0 ; ldx < mport.count() ; ldx += 1) {
|
||||||
|
unsigned lbase = inst * mport.count();
|
||||||
|
PEIdent*pport = mport[ldx];
|
||||||
|
assert(pport);
|
||||||
|
prts[lbase + ldx]
|
||||||
|
= pport->elaborate_port(des, inst_scope);
|
||||||
|
if (prts[lbase + ldx] == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
assert(prts[lbase + ldx]);
|
||||||
|
prts_pin_count += prts[lbase + ldx]->pin_count();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If I find that the port in unconnected inside the
|
// If I find that the port in unconnected inside the
|
||||||
// module, then there is nothing to connect. Skip the
|
// module, then there is nothing to connect. Skip the
|
||||||
// parameter.
|
// argument.
|
||||||
if (prts_pin_count == 0) {
|
if (prts_pin_count == 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Elaborate the expression that connects to the module
|
// We know by design that each instance has the same
|
||||||
// port. sig is the thing outside the module that
|
// width port. Therefore, the prts_pin_count must be an
|
||||||
// connects to the port.
|
// even multiple of the instance count.
|
||||||
|
assert(prts_pin_count % instance.count() == 0);
|
||||||
|
|
||||||
|
// Elaborate the expression that connects to the
|
||||||
|
// module[s] port. sig is the thing outside the module
|
||||||
|
// that connects to the port.
|
||||||
|
|
||||||
NetNet*sig;
|
NetNet*sig;
|
||||||
if ((prts.count() >= 1)
|
if ((prts.count() >= 1)
|
||||||
|
|
@ -687,9 +692,18 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
/* Input to module. elaborate the expression to
|
||||||
|
the desired width. If this in an instance
|
||||||
|
array, then let the net determine it's own
|
||||||
|
width. We use that, then, to decide how to hook
|
||||||
|
it up. */
|
||||||
|
unsigned desired_pin_count = prts_pin_count;
|
||||||
|
if (instance.count() != 1)
|
||||||
|
desired_pin_count = 0;
|
||||||
|
|
||||||
sig = pins[idx]->elaborate_net(des, scope,
|
sig = pins[idx]->elaborate_net(des, scope,
|
||||||
prts_pin_count,
|
desired_pin_count,
|
||||||
0, 0, 0);
|
0, 0, 0);
|
||||||
if (sig == 0) {
|
if (sig == 0) {
|
||||||
cerr << pins[idx]->get_line()
|
cerr << pins[idx]->get_line()
|
||||||
<< ": internal error: Port expression "
|
<< ": internal error: Port expression "
|
||||||
|
|
@ -707,10 +721,25 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* If we are working with an instance array, then the
|
||||||
|
signal width must match the port width exactly. */
|
||||||
|
if ((instance.count() != 1)
|
||||||
|
&& (sig->pin_count() != prts_pin_count)
|
||||||
|
&& (sig->pin_count() != prts_pin_count/instance.count())) {
|
||||||
|
cerr << pins[idx]->get_line() << ": error: "
|
||||||
|
<< "Port expression width " << sig->pin_count()
|
||||||
|
<< " does not match expected width " << prts_pin_count
|
||||||
|
<< " or " << (prts_pin_count/instance.count())
|
||||||
|
<< "." << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// Check that the parts have matching pin counts. If
|
// Check that the parts have matching pin counts. If
|
||||||
// not, they are different widths. Note that idx is 0
|
// not, they are different widths. Note that idx is 0
|
||||||
// based, but users count parameter positions from 1.
|
// based, but users count parameter positions from 1.
|
||||||
if (prts_pin_count != sig->pin_count()) {
|
if ((instance.count() == 1)
|
||||||
|
&& (prts_pin_count != sig->pin_count())) {
|
||||||
cerr << get_line() << ": warning: Port " << (idx+1)
|
cerr << get_line() << ": warning: Port " << (idx+1)
|
||||||
<< " (" << rmod->ports[idx]->name << ") of "
|
<< " (" << rmod->ports[idx]->name << ") of "
|
||||||
<< type_ << " expects " << prts_pin_count <<
|
<< type_ << " expects " << prts_pin_count <<
|
||||||
|
|
@ -741,9 +770,17 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
|
||||||
// Connect this many of the port pins. If the expression
|
// Connect this many of the port pins. If the expression
|
||||||
// is too small, the reduce the number of connects.
|
// is too small, the reduce the number of connects.
|
||||||
unsigned ccount = prts_pin_count;
|
unsigned ccount = prts_pin_count;
|
||||||
if (sig->pin_count() < ccount)
|
if (instance.count() == 1 && sig->pin_count() < ccount)
|
||||||
ccount = sig->pin_count();
|
ccount = sig->pin_count();
|
||||||
|
|
||||||
|
// The spin_modulus is the width of the signal (not the
|
||||||
|
// port) if this is an instance array. This causes
|
||||||
|
// signals wide enough for a single instance to be
|
||||||
|
// connected to all the instances.
|
||||||
|
unsigned spin_modulus = prts_pin_count;
|
||||||
|
if (instance.count() != 1)
|
||||||
|
spin_modulus = sig->pin_count();
|
||||||
|
|
||||||
// Now scan the concatenation that makes up the port,
|
// Now scan the concatenation that makes up the port,
|
||||||
// connecting pins until we run out of port pins or sig
|
// connecting pins until we run out of port pins or sig
|
||||||
// pins.
|
// pins.
|
||||||
|
|
@ -754,7 +791,8 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
|
||||||
if (cnt > ccount)
|
if (cnt > ccount)
|
||||||
cnt = ccount;
|
cnt = ccount;
|
||||||
for (unsigned p = 0 ; p < cnt ; p += 1) {
|
for (unsigned p = 0 ; p < cnt ; p += 1) {
|
||||||
connect(sig->pin(spin), prts[ldx-1]->pin(p));
|
connect(sig->pin(spin%spin_modulus),
|
||||||
|
prts[ldx-1]->pin(p));
|
||||||
ccount -= 1;
|
ccount -= 1;
|
||||||
spin += 1;
|
spin += 1;
|
||||||
}
|
}
|
||||||
|
|
@ -766,6 +804,7 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
|
||||||
if (NetSubnet*tmp = dynamic_cast<NetSubnet*>(sig))
|
if (NetSubnet*tmp = dynamic_cast<NetSubnet*>(sig))
|
||||||
delete tmp;
|
delete tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -2720,6 +2759,9 @@ Design* elaborate(list<perm_string>roots)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: elaborate.cc,v $
|
* $Log: elaborate.cc,v $
|
||||||
|
* Revision 1.306 2004/09/05 17:44:41 steve
|
||||||
|
* Add support for module instance arrays.
|
||||||
|
*
|
||||||
* Revision 1.305 2004/06/30 15:32:02 steve
|
* Revision 1.305 2004/06/30 15:32:02 steve
|
||||||
* Propagate source line number in synthetic delay statements.
|
* Propagate source line number in synthetic delay statements.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
20
main.cc
20
main.cc
|
|
@ -19,7 +19,7 @@ const char COPYRIGHT[] =
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: main.cc,v 1.82 2004/03/10 04:51:24 steve Exp $"
|
#ident "$Id: main.cc,v 1.83 2004/09/05 17:44:42 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -106,6 +106,11 @@ bool warn_portbinding = false;
|
||||||
|
|
||||||
bool error_implicit = false;
|
bool error_implicit = false;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Debug message class flags.
|
||||||
|
*/
|
||||||
|
bool debug_scopes = false;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Verbose messages enabled.
|
* Verbose messages enabled.
|
||||||
*/
|
*/
|
||||||
|
|
@ -228,6 +233,9 @@ static void parm_to_flagmap(const string&flag)
|
||||||
* basedir:<path>
|
* basedir:<path>
|
||||||
* Location to look for installed sub-components
|
* Location to look for installed sub-components
|
||||||
*
|
*
|
||||||
|
* debug:<name>
|
||||||
|
* Activate a class of debug messages.
|
||||||
|
*
|
||||||
* depfile:<path>
|
* depfile:<path>
|
||||||
* Give the path to an output dependency file.
|
* Give the path to an output dependency file.
|
||||||
*
|
*
|
||||||
|
|
@ -295,6 +303,13 @@ static void read_iconfig_file(const char*ipath)
|
||||||
if (strcmp(buf, "basedir") == 0) {
|
if (strcmp(buf, "basedir") == 0) {
|
||||||
basedir = strdup(cp);
|
basedir = strdup(cp);
|
||||||
|
|
||||||
|
} else if (strcmp(buf, "debug") == 0) {
|
||||||
|
if (strcmp(cp, "scope") == 0) {
|
||||||
|
debug_scopes = true;
|
||||||
|
cerr << "debug: Enable scope debug" << endl;
|
||||||
|
} else {
|
||||||
|
}
|
||||||
|
|
||||||
} else if (strcmp(buf, "depfile") == 0) {
|
} else if (strcmp(buf, "depfile") == 0) {
|
||||||
depfile_name = strdup(cp);
|
depfile_name = strdup(cp);
|
||||||
|
|
||||||
|
|
@ -722,6 +737,9 @@ int main(int argc, char*argv[])
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: main.cc,v $
|
* $Log: main.cc,v $
|
||||||
|
* Revision 1.83 2004/09/05 17:44:42 steve
|
||||||
|
* Add support for module instance arrays.
|
||||||
|
*
|
||||||
* Revision 1.82 2004/03/10 04:51:24 steve
|
* Revision 1.82 2004/03/10 04:51:24 steve
|
||||||
* Add support for system function table files.
|
* Add support for system function table files.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
10
netlist.h
10
netlist.h
|
|
@ -19,7 +19,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: netlist.h,v 1.318 2004/09/04 04:24:15 steve Exp $"
|
#ident "$Id: netlist.h,v 1.319 2004/09/05 17:44:42 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -3168,6 +3168,11 @@ class NetScope : public Attrib {
|
||||||
map<perm_string,param_expr_t>parameters;
|
map<perm_string,param_expr_t>parameters;
|
||||||
map<perm_string,param_expr_t>localparams;
|
map<perm_string,param_expr_t>localparams;
|
||||||
|
|
||||||
|
/* Module instance arrays are collected here for access during
|
||||||
|
the multiple elaboration passes. */
|
||||||
|
typedef svector<NetScope*> scope_vec_t;
|
||||||
|
map<perm_string, scope_vec_t>instance_arrays;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TYPE type_;
|
TYPE type_;
|
||||||
perm_string name_;
|
perm_string name_;
|
||||||
|
|
@ -3356,6 +3361,9 @@ extern ostream& operator << (ostream&, NetNet::Type);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: netlist.h,v $
|
* $Log: netlist.h,v $
|
||||||
|
* Revision 1.319 2004/09/05 17:44:42 steve
|
||||||
|
* Add support for module instance arrays.
|
||||||
|
*
|
||||||
* Revision 1.318 2004/09/04 04:24:15 steve
|
* Revision 1.318 2004/09/04 04:24:15 steve
|
||||||
* PR1026: assignment statements can have sensitivities in the l-values.
|
* PR1026: assignment statements can have sensitivities in the l-values.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue