unable to unroll for loop causing BLKLOOPINIT error
When compiling our RTL code with Verilator, we got "BLKLOOPINIT" errors. According to Verilator manual, we try to increase the
--unroll-count 256 and
--unroll-stmts 99999. However, still Verilator reports the "BLKLOOPINIT" errors.
After a bit investigation, we found the root of the error actually is that Verilator is unable to unroll the for loop which has a little bit complicated condition, e.g.
for (i=0; (i< 4) && (i > 2); i++).
Unsupported: Delayed assignment to array inside for loops (non-delayed is ok - see docs)
A test case to regenerate the issue is attached.
#1 Updated by Wilson Snyder almost 4 years ago
- Category set to Unsupported
- Status changed from New to Assigned
Yes, the unroller is pretty stupid, it predates the internals being able to emulate most code.
Perhaps you might be willing to look at providing a patch? Basically if you look at V3Unroll now it just looks for certain hardcoded constructs. Instead it should apply values in the initial part of the for, then execute the test and increment, and 'timeout' if too many loops are needed, or anything strange happens (like other variables are needed, or an unsupported construct like PLI call is seen). V3Table has good examples of how to execute code during compilation.
#3 Updated by Johan Bjork over 1 year ago
I wrote up an initial version of this over the weekend, it's mostly passing tests but needs some more work. I'm somewhat worried it'll have a negative performance impact though, especially for the cases where we decide to not unroll the loop. Previously it was a fairly quick check, but now we either have to 1) run the simulation for the incr/condition to determine size of loop, then bail if too big 2) Run the actual unrolling and then abort if it goes for too long. both which seems fairly slow.
Is there any performance benchmarks I can run to ensure things are looking good after this change?
#7 Updated by Wilson Snyder over 1 year ago
Sorry I missed providing feedback on this.
1. Nit, it's "if (...)" not "if(...)". There's no space after function names "fileline()" not "fileline ()". These match GNU conventions (in theory).
2. forUnroller now seems to return a bool indicating additional "did it" status, but this isn't tested in forUnrollCheck. Presumably it should be, otherwise the loop will get mis-deleted. (Try #3 below it might find this.)
3. I think you have them all covered, but to the test cases, please add a complicated non-simulatable thing to init, cond, and inc, for example
j = 0; for (i=$c32("1"); i<3; ++; if (j!=2) $stop; j = 0; for (i=1; i<$c32("3"); ++; if (j!=2) $stop; j = 0; for (i=1; i<3; i=i+$c32("1")) j++; if (j!=2) $stop;
4. I get a warning:
../V3Unroll.cpp:200:11: error: unused variable 'proceed' [-Werror=unused-variable]
In your .bashrc or whatever shell equivelent please
then reconfigure and build emacs, so you get warnings.
Also available in: Atom