Join GitHub today
GitHub is home to over 40 million developers working together to host and review code, manage projects, and build software together.Sign up
Improve Verilating speed for large designs with repetition #2182
This is a related to #2140 (comment).
I'd like to improve verilating speed and C++ compilation time for large designs, especially with repetition such as many core SoC.
Skip per-scope optimization for large module which is repeated.
I found that passes after per-scope optimization consumes a lot of CPU time and memory.
On the other hand, per-instance optimization for larger block such as processor is expensive.
Disabling per-instance opt. for such large module will
Here is a statistics for my test design ( 128 instances of processor core https://github.com/lowRISC/ibex)
Improving large design handling would be very valuable. A lot of the potential gain may be making the gcc time less (versus Verilation time). BTW 22 seconds is pretty fast in the grand context, but I presume that was just a test case to show the point.
I'm not sure of the tradeoffs of what you suggest versus say making "protect-like" modules. This idea should be much faster in runtime, but likely significant effort. Maybe the ideas can be combined, that is you mark pragmas that are the repeated module boundaries, and Verilator understands how to make the repeated sub-modules at those boundaries with separate sub-runs?
A problem I see are items like JTAG and similar chains that wind through the modules. The order of evaluation will need to be correct across the little pieces, and called in a different order per repetition, or it will run too slow. I think you'll need to order the "meta-module" considering all submodule repetitions at once.
%m ties in with VPI/DPI, which must know the full design scope. I would think you can maintain a AstScope as currently for the whole design hierarchy. A given scope would then know it's a repetition and point at another module. Currently every class that composes a module already can have multiple instances with different names.
I'd suggest maybe handcrafting what the output C++ code would look like for a trivial design and we can discuss. Then propose the steps and algorithms.
Related to this, is your biggest pain point the initial time it takes you to compile the entire design? Or is it when you are iterating on a file in the edit-compile-test loop? I'd also be glad to see improvements on either front, but the latter would impact my daily workflow more and I would expect it to have a lower floor on execution time since there's less (new) work to be done.
Thanks for the comments.
Right. The example is just an example that can be shown in public.
JTAG example is good point. It seems I thought things too easy.
Well, I didn't separate them in my mind, but it is important to ask myself and check my usecase.
After I explored the ordering code, I think protect-lib based approach is better because the feature is already working great and enhancement for the feature may be beneficial for more users.
I think the following items will help users with large design. (including me)
Usability for the usecase of veirlating speed
C++ compile time
I'd like to start from the usability, simple hierarchical verilation based on protect-lib feature.
Here is what I am thinking.
Assume the design looks like this. Note that sub_s, sub_b, and sub_c are marked
module sub_a() /*verilator hier_block*/; endmodule module sub_b() /*verilator hier_block*/; sub_a i_sub_a(); endmodule module sub_c() /*verilator hier_block*/; endmodule module sub_d(); endmodule module top(); sub_b i_sub_b(); sub_c i_sub_c(); sub_d i_sub_d(); endmodule
Running verilator and make as below would generate an executable. There will be nothing special.
verilator --cc --exe --top-module top sub_a.sv sub_b.sv sub_c.sv sub_d.sv top.sv make -f Vtop.mk -C obj_dir
Internally verilator would create protect lib for sub_a, sub_b, and sub_c to shorten verilation time.
obj_dir/Vtop.mk obj_dir/Vtop_*.h obj_dir/Vtop_*.cpp obj_dir/Vsub_a/Vsub_a.mk obj_dir/Vsub_a/Vsub_a_*.h obj_dir/Vsub_a/Vsub_a_*.cpp obj_dir/Vsub_b/Vsub_b.mk obj_dir/Vsub_b/Vsub_b_*.h obj_dir/Vsub_b/Vsub_b_*.cpp obj_dir/Vsub_c/Vsub_c.mk obj_dir/Vsub_c/Vsub_c_*.h obj_dir/Vsub_c/Vsub_c_*.cpp
The same thing can be done with the current verilator, but user have to call verilator for each protect-libs and need to pass correct file list and library flags.
Any comment is appreciated including meta comment name :)