Add support for recursive modules inside generate blocks
This patch adds support for recursive module loops if the loop contains a generate block. The assumption is that the user is doing the right thing in the generate block to make the loop terminate. For this case there is also a check that limits the number of loops (default 10). This prevents the system from crashing when the user did not correctly terminate the looping structure. The limit can be changed by the user if needed.
This commit is contained in:
parent
a7741d2bd5
commit
5e723bfd61
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef __compiler_H
|
||||
#define __compiler_H
|
||||
/*
|
||||
* Copyright (c) 1999-2008 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1999-2009 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
|
|
@ -36,6 +36,12 @@
|
|||
*/
|
||||
extern unsigned integer_width;
|
||||
|
||||
/*
|
||||
* This is the maximum number of recursive module loops allowed within
|
||||
* a generate block.
|
||||
*/
|
||||
extern unsigned recursive_mod_limit;
|
||||
|
||||
/* The TIME_WIDTH is the width of time variables. */
|
||||
#ifndef TIME_WIDTH
|
||||
# define TIME_WIDTH 64
|
||||
|
|
|
|||
|
|
@ -919,21 +919,44 @@ void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const
|
|||
// check for recursive instantiation by scanning the current
|
||||
// scope and its parents. Look for a module instantiation of
|
||||
// the same module, but farther up in the scope.
|
||||
|
||||
unsigned rl_count = 0;
|
||||
bool in_genblk = false;
|
||||
for (NetScope*scn = sc ; scn ; scn = scn->parent()) {
|
||||
if (scn->type() != NetScope::MODULE)
|
||||
// We need to know if we are inside a generate block to allow
|
||||
// recursive instances.
|
||||
if (scn->type() == NetScope::GENBLOCK) {
|
||||
in_genblk = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strcmp(mod->mod_name(), scn->module_name()) != 0)
|
||||
if (scn->type() != NetScope::MODULE) continue;
|
||||
|
||||
if (strcmp(mod->mod_name(), scn->module_name()) != 0) continue;
|
||||
|
||||
// We allow nested scopes if they are inside a generate block,
|
||||
// but only to a certain nesting depth.
|
||||
if (in_genblk) {
|
||||
rl_count += 1;
|
||||
if (rl_count > recursive_mod_limit) {
|
||||
cerr << get_fileline() << ": error: instance "
|
||||
<< scope_path(sc) << "." << get_name()
|
||||
<< " of module " << mod->mod_name()
|
||||
<< " is nested too deep." << endl;
|
||||
cerr << get_fileline() << ": : check for "
|
||||
"proper recursion termination or increase the "
|
||||
"limit (" << recursive_mod_limit
|
||||
<< ") with the -pRECURSIVE_MOD_LIMIT flag."
|
||||
<< endl;
|
||||
des->errors += 1;
|
||||
return;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
cerr << get_fileline() << ": error: You cannot instantiate "
|
||||
<< "module " << mod->mod_name() << " within itself." << endl;
|
||||
|
||||
cerr << get_fileline() << ": : The offending instance is "
|
||||
<< scope_path(sc) << "." << get_name() << " within "
|
||||
<< scope_path(scn) << "." << endl;
|
||||
|
||||
<< get_name() << " within " << scope_path(scn) << "." << endl;
|
||||
des->errors += 1;
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
5
main.cc
5
main.cc
|
|
@ -133,6 +133,7 @@ bool debug_optimizer = false;
|
|||
*/
|
||||
bool disable_virtual_pins = false;
|
||||
unsigned long array_size_limit = 16777216; // Minimum required by IEEE-1364?
|
||||
unsigned recursive_mod_limit = 10;
|
||||
|
||||
/*
|
||||
* Verbose messages enabled.
|
||||
|
|
@ -717,9 +718,13 @@ int main(int argc, char*argv[])
|
|||
|
||||
const char *flag_tmp = flags["DISABLE_VIRTUAL_PINS"];
|
||||
if (flag_tmp) disable_virtual_pins = strcmp(flag_tmp,"true")==0;
|
||||
|
||||
flag_tmp = flags["ARRAY_SIZE_LIMIT"];
|
||||
if (flag_tmp) array_size_limit = strtoul(flag_tmp,NULL,0);
|
||||
|
||||
flag_tmp = flags["RECURSIVE_MOD_LIMIT"];
|
||||
if (flag_tmp) recursive_mod_limit = strtoul(flag_tmp,NULL,0);
|
||||
|
||||
/* Parse the input. Make the pform. */
|
||||
int rc = pform_parse(argv[optind]);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue