Add full genvar support and name space checking.
This patch adds genvars to the elaboration process. It adds checks that a genvar is defined for a generate loop and that a genvar does not conflict with any other items in its name space.
This commit is contained in:
parent
d7fe9c613c
commit
72a98e85cb
133
elab_scope.cc
133
elab_scope.cc
|
|
@ -174,6 +174,15 @@ static void elaborate_scope_parameters_(Design*des, NetScope*scope,
|
|||
for (mparm_it_t cur = parameters.begin()
|
||||
; cur != parameters.end() ; cur ++) {
|
||||
|
||||
// A parameter can not have the same name as a genvar.
|
||||
if (scope->find_genvar((*cur).first)) {
|
||||
cerr << cur->second.get_fileline()
|
||||
<< ": error: parameter and genvar in '"
|
||||
<< scope->fullname() << "' have the same name '"
|
||||
<< (*cur).first << "'." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
elaborate_parm_item_((*cur).first, (*cur).second, des, scope);
|
||||
}
|
||||
}
|
||||
|
|
@ -184,6 +193,15 @@ static void elaborate_scope_localparams_(Design*des, NetScope*scope,
|
|||
for (mparm_it_t cur = localparams.begin()
|
||||
; cur != localparams.end() ; cur ++) {
|
||||
|
||||
// A localparam can not have the same name as a genvar.
|
||||
if (scope->find_genvar((*cur).first)) {
|
||||
cerr << cur->second.get_fileline()
|
||||
<< ": error: localparam and genvar in '"
|
||||
<< scope->fullname() << "' have the same name '"
|
||||
<< (*cur).first << "'." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
elaborate_parm_item_((*cur).first, (*cur).second, des, scope);
|
||||
}
|
||||
}
|
||||
|
|
@ -249,6 +267,15 @@ static void elaborate_scope_tasks(Design*des, NetScope*scope,
|
|||
continue;
|
||||
}
|
||||
|
||||
// A task can not have the same name as a genvar.
|
||||
if (scope->find_genvar((*cur).first)) {
|
||||
cerr << cur->second->get_fileline()
|
||||
<< ": error: task and genvar in '"
|
||||
<< scope->fullname() << "' have the same name '"
|
||||
<< (*cur).first << "'." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
// A task can not have the same name as a parameter.
|
||||
const NetExpr *ex_msb, *ex_lsb;
|
||||
const NetExpr *parm = scope->get_parameter((*cur).first, ex_msb,
|
||||
|
|
@ -296,6 +323,15 @@ static void elaborate_scope_funcs(Design*des, NetScope*scope,
|
|||
continue;
|
||||
}
|
||||
|
||||
// A function can not have the same name as a genvar.
|
||||
if (scope->find_genvar((*cur).first)) {
|
||||
cerr << cur->second->get_fileline()
|
||||
<< ": error: function and genvar in '"
|
||||
<< scope->fullname() << "' have the same name '"
|
||||
<< (*cur).first << "'." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
// A function can not have the same name as a parameter.
|
||||
const NetExpr *ex_msb, *ex_lsb;
|
||||
const NetExpr *parm = scope->get_parameter((*cur).first, ex_msb,
|
||||
|
|
@ -361,6 +397,12 @@ bool Module::elaborate_scope(Design*des, NetScope*scope,
|
|||
<< scope_path(scope) << "." << endl;
|
||||
}
|
||||
|
||||
// Add the genvars to the scope.
|
||||
typedef map<perm_string,LineInfo*>::const_iterator genvar_it_t;
|
||||
for (genvar_it_t cur = genvars.begin(); cur != genvars.end(); cur++ ) {
|
||||
scope->add_genvar((*cur).first, (*cur).second);
|
||||
}
|
||||
|
||||
// Generate all the parameters that this instance of this
|
||||
// module introduces to the design. This loop elaborates the
|
||||
// parameters, but doesn't evaluate references to
|
||||
|
|
@ -521,12 +563,13 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
|
|||
{
|
||||
// Check that the loop_index variable was declared in a
|
||||
// genvar statement.
|
||||
|
||||
// MISSING CODE!
|
||||
//
|
||||
// Also the genvar checks below need to be moved/changed
|
||||
// when this is implemented. They currently work, but do
|
||||
// not reference the genvar statement.
|
||||
if (container->find_genvar(loop_index) == 0) {
|
||||
cerr << get_fileline() << ": error: genvar is missing for "
|
||||
"generate \"loop\" variable '" << loop_index << "'."
|
||||
<< endl;
|
||||
des->errors += 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
// We're going to need a genvar...
|
||||
int genvar;
|
||||
|
|
@ -558,6 +601,15 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
|
|||
des->errors += 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
// A generate "loop" can not have the same name as a genvar.
|
||||
if (container->find_genvar(scope_name)) {
|
||||
cerr << get_fileline() << ": error: generate \"loop\" and "
|
||||
"genvar in '" << container->fullname()
|
||||
<< "' have the same name '" << scope_name << "'." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
// A generate "loop" can not have the same name as a named event.
|
||||
const NetEvent *event = container->find_event(scope_name);
|
||||
if (event) {
|
||||
|
|
@ -578,17 +630,11 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
|
|||
des->errors += 1;
|
||||
}
|
||||
|
||||
// Since we will be adding the genvar value as a local parameter
|
||||
// to each instances scope. We need to make sure a parameter does
|
||||
// not already exist.
|
||||
texpr = container->get_parameter(loop_index, tmsb, tlsb);
|
||||
if (texpr != 0) {
|
||||
cerr << get_fileline() << ": error: genvar and "
|
||||
"parameter in '" << container->fullname()
|
||||
<< "' have the same name '" << loop_index << "'." << endl;
|
||||
des->errors += 1;
|
||||
return false;
|
||||
}
|
||||
// These have all been checked so we just need to skip the actual
|
||||
// generation for these name conflicts. Not skipping these two will
|
||||
// cause the compiler to have problems (assert, inf. loop, etc.).
|
||||
if (container->get_parameter(loop_index, tmsb, tlsb)) return false;
|
||||
if (container->find_event(loop_index)) return false;
|
||||
|
||||
genvar = init->value().as_long();
|
||||
delete init_ex;
|
||||
|
|
@ -672,7 +718,7 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
|
|||
}
|
||||
|
||||
// Clear the genvar_tmp field in the scope to reflect that the
|
||||
// genvar is no longer value for evaluating expressions.
|
||||
// genvar is no longer valid for evaluating expressions.
|
||||
container->genvar_tmp = perm_string();
|
||||
|
||||
return true;
|
||||
|
|
@ -717,6 +763,14 @@ bool PGenerate::generate_scope_condit_(Design*des, NetScope*container, bool else
|
|||
return false;
|
||||
}
|
||||
|
||||
// A generate "if" can not have the same name as a genvar.
|
||||
if (container->find_genvar(scope_name)) {
|
||||
cerr << get_fileline() << ": error: generate \"if\" and "
|
||||
"genvar in '" << container->fullname()
|
||||
<< "' have the same name '" << scope_name << "'." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
// A generate "if" can not have the same name as a named event.
|
||||
const NetEvent *event = container->find_event(scope_name);
|
||||
if (event) {
|
||||
|
|
@ -855,6 +909,14 @@ bool PGenerate::generate_scope_case_(Design*des, NetScope*container)
|
|||
return false;
|
||||
}
|
||||
|
||||
// A generate "case" can not have the same name as a genvar.
|
||||
if (container->find_genvar(item->scope_name)) {
|
||||
cerr << get_fileline() << ": error: generate \"case\" and "
|
||||
"genvar in '" << container->fullname()
|
||||
<< "' have the same name '" << use_name << "'." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
// A generate "case" can not have the same name as a named event.
|
||||
const NetEvent *event = container->find_event(item->scope_name);
|
||||
if (event) {
|
||||
|
|
@ -895,7 +957,8 @@ bool PGenerate::generate_scope_case_(Design*des, NetScope*container)
|
|||
bool PGenerate::generate_scope_nblock_(Design*des, NetScope*container)
|
||||
{
|
||||
hname_t use_name (scope_name);
|
||||
// A generate "case" can not have the same name as another scope object.
|
||||
// A generate "block" can not have the same name as another scope
|
||||
// object.
|
||||
const NetScope *child = container->child(use_name);
|
||||
if (child) {
|
||||
cerr << get_fileline() << ": error: generate \"block\" and ";
|
||||
|
|
@ -906,6 +969,14 @@ bool PGenerate::generate_scope_nblock_(Design*des, NetScope*container)
|
|||
return false;
|
||||
}
|
||||
|
||||
// A generate "block" can not have the same name as a genvar.
|
||||
if (container->find_genvar(scope_name)) {
|
||||
cerr << get_fileline() << ": error: generate \"block\" and "
|
||||
"genvar in '" << container->fullname()
|
||||
<< "' have the same name '" << scope_name << "'." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
// A generate "block" can not have the same name as a named event.
|
||||
const NetEvent *event = container->find_event(scope_name);
|
||||
if (event) {
|
||||
|
|
@ -1057,6 +1128,14 @@ void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const
|
|||
return;
|
||||
}
|
||||
|
||||
// A module instance can not have the same name as a genvar.
|
||||
if (sc->find_genvar(get_name())) {
|
||||
cerr << get_fileline() << ": error: module <" << mod->mod_name()
|
||||
<< "> instance and genvar in '" << sc->fullname()
|
||||
<< "' have the same name '" << get_name() << "'." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
// A module instance can not have the same name as a parameter.
|
||||
const NetExpr *ex_msb, *ex_lsb;
|
||||
const NetExpr *parm = sc->get_parameter(get_name(), ex_msb, ex_lsb);
|
||||
|
|
@ -1314,6 +1393,14 @@ void PEvent::elaborate_scope(Design*des, NetScope*scope) const
|
|||
des->errors += 1;
|
||||
}
|
||||
|
||||
// A named event can not have the same name as a genvar.
|
||||
if (scope->find_genvar(name_)) {
|
||||
cerr << get_fileline() << ": error: named event and "
|
||||
<< "genvar in '" << scope->fullname()
|
||||
<< "' have the same name '" << name_ << "'." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
// A named event can not have the same name as a parameter.
|
||||
const NetExpr *ex_msb, *ex_lsb;
|
||||
const NetExpr *parm = scope->get_parameter(name_, ex_msb, ex_lsb);
|
||||
|
|
@ -1416,6 +1503,14 @@ void PBlock::elaborate_scope(Design*des, NetScope*scope) const
|
|||
return;
|
||||
}
|
||||
|
||||
// A named block can not have the same name as a genvar.
|
||||
if (scope->find_genvar(pscope_name())) {
|
||||
cerr << get_fileline() << ": error: named block and "
|
||||
"genvar in '" << scope->fullname()
|
||||
<< "' have the same name '" << use_name << "'." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
// A named block can not have the same name as a parameter.
|
||||
const NetExpr *ex_msb, *ex_lsb;
|
||||
const NetExpr *parm = scope->get_parameter(pscope_name(), ex_msb,
|
||||
|
|
|
|||
|
|
@ -878,6 +878,14 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
|||
cerr << " in '" << scope->fullname()
|
||||
<< "' have the same name '" << name_ << "'." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
// A signal can not have the same name as a genvar.
|
||||
const LineInfo *genvar = scope->find_genvar(name_);
|
||||
if (genvar) {
|
||||
cerr << get_fileline() << ": error: signal and genvar in '"
|
||||
<< scope->fullname() << "' have the same name '" << name_
|
||||
<< "'." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
// A signal can not have the same name as a parameter.
|
||||
const NetExpr *ex_msb, *ex_lsb;
|
||||
|
|
|
|||
24
net_scope.cc
24
net_scope.cc
|
|
@ -395,6 +395,30 @@ NetEvent* NetScope::find_event(perm_string name)
|
|||
return 0;
|
||||
}
|
||||
|
||||
// We only add genvars to a module scope, so we do not need to search
|
||||
// for the module scope here.
|
||||
void NetScope::add_genvar(perm_string name, LineInfo *li)
|
||||
{
|
||||
genvars_[name] = li;
|
||||
}
|
||||
|
||||
LineInfo* NetScope::find_genvar(perm_string name)
|
||||
{
|
||||
// genvars are only added to the module so we need to find it
|
||||
// if we are in a sub scope.
|
||||
NetScope *scope = this;
|
||||
while (scope->type() != NetScope::MODULE) {
|
||||
scope = scope->parent();
|
||||
assert(scope != NULL);
|
||||
}
|
||||
|
||||
if (scope->genvars_.find(name) != scope->genvars_.end()) {
|
||||
return scope->genvars_[name];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void NetScope::add_signal(NetNet*net)
|
||||
{
|
||||
signals_map_[net->name()]=net;
|
||||
|
|
|
|||
|
|
@ -720,6 +720,9 @@ class NetScope : public Attrib {
|
|||
void rem_event(NetEvent*);
|
||||
NetEvent*find_event(perm_string name);
|
||||
|
||||
/* These methods add or find a genvar that lives in this scope. */
|
||||
void add_genvar(perm_string name, LineInfo *li);
|
||||
LineInfo* find_genvar(perm_string name);
|
||||
|
||||
/* These methods manage signals. The add_ and rem_signal
|
||||
methods are used by the NetNet objects to make themselves
|
||||
|
|
@ -899,6 +902,8 @@ class NetScope : public Attrib {
|
|||
|
||||
NetEvent *events_;
|
||||
|
||||
map<perm_string,LineInfo*> genvars_;
|
||||
|
||||
typedef std::map<perm_string,NetNet*>::const_iterator signals_map_iter_t;
|
||||
std::map <perm_string,NetNet*> signals_map_;
|
||||
perm_string module_name_;
|
||||
|
|
|
|||
11
pform.cc
11
pform.cc
|
|
@ -131,7 +131,7 @@ PTask* pform_push_task_scope(const struct vlltype&loc, char*name, bool is_auto)
|
|||
if (pform_cur_generate->tasks.find(task->pscope_name()) !=
|
||||
pform_cur_generate->tasks.end()) {
|
||||
cerr << task->get_fileline() << ": error: duplicate "
|
||||
" definition for task '" << name << "' in '"
|
||||
"definition for task '" << name << "' in '"
|
||||
<< pform_cur_module->mod_name() << "' (generate)."
|
||||
<< endl;
|
||||
error_count += 1;
|
||||
|
|
@ -681,7 +681,14 @@ void pform_genvars(const struct vlltype&li, list<perm_string>*names)
|
|||
for (cur = names->begin(); cur != names->end() ; *cur++) {
|
||||
LineInfo*lni = new LineInfo();
|
||||
FILE_NAME(lni, li);
|
||||
pform_cur_module->genvars[*cur] = lni;
|
||||
if (pform_cur_module->genvars.find(*cur) !=
|
||||
pform_cur_module->genvars.end()) {
|
||||
cerr << lni->get_fileline() << ": error: duplicate "
|
||||
"definition for genvar '" << *cur << "' in '"
|
||||
<< pform_cur_module->mod_name() << "'." << endl;
|
||||
error_count += 1;
|
||||
delete lni;
|
||||
} else pform_cur_module->genvars[*cur] = lni;
|
||||
}
|
||||
|
||||
delete names;
|
||||
|
|
|
|||
Loading…
Reference in New Issue