testbench wrapper
Added by Jiang Long over 1 year ago
Hello all,
I am working on a synthesis tool that translate Verilog RTL into netlist. To ensure correctness, I would like to use Verilator to simulate and compare both model by random simulations. Does verilator has an option to generate a testbench template such that it can be enhanced with stimulus generation?
I am looking to automate the process such that after reading in the RTL, a testbench can be created to compare the results.
Hope I explain what I want to achieve.
Also, is there a way to extract/access the value of hierarchical signals: say
e.g. top.sub1.sub2.A it is something like
top->sub1->sub2->A from the .cpp file?
-leon
Replies (6)
RE: testbench wrapper - Added by Wilson Snyder over 1 year ago
Verilator doesn't have a testbench template. You can access signals if they are declared /*verilator public*/, see the docs.
Maybe I'm missing something about your problem, but I think your looking at the wrong solution, what you want is called Formal Equivalence Checking, that will mathematically prove your synthesis is correct. (And even if not, you wouldn't want random patterns, but specialized generated test patterns.) I'd expect a good reference book on synthesis would also talk about boolean equivalence.
RE: testbench wrapper - Added by Jiang Long over 1 year ago
Thanks for the note.
I was able to use /*verilator public*/ and access the internal signals. I noticed there is --public which suppose declare everything as public, but it does not seems to work as /*verilator public*/(would it be a bug or there is some other flag for which I got every signal by default /*verilator public*/).
I don't have access to equivalence checking tools from academia, a quick solution is just to compare the two models using random simulation. Though it is not 100% assurance, but it should sweep away 99% of the simple bugs. Also, my test cases at the beginning would be very small.
This exercise can potentially benefit 'verilator' as a correctness checker as well( in case verilator is in developing mode). Or my question is how Verilator assumes the correct implementation of the simulation semantics? What is the testing methodology, I am basically facing the same problem which I am struggling to find a solution ( not using an equivalence checker).
-leon
RE: testbench wrapper - Added by Wilson Snyder over 1 year ago
--public is old and can cause problems with clocks, you're better off only setting it on those signals you care about.
Unfortunately you're way off on what random simulation can do. Think of testing something as simple as a 64 bit counter, you'd simulate forever. Maybe you're thinking of using public so you can put compare points at all outputs and flops (great - this is absolutely necessary to get any sort of good coverage). Unfortunately the fanin of a standard design is still too large to do well. You are unlikely to get above 97% on a real design, and that's with compare points at all flops and an excellent algorithmically generated test set.
Anyhow, I'll assume you only care about finding a few counter examples to test a tool that isn't production worthy. I don't think you want or need "public". What I would suggest would be to make a wrapper generating script that
1. Creates a verilog model that instantiates the RTL and the gates as two modules, then in that module uses a.b.c to scope into every flop in each model and check equivalence at the correct clock edge. It also compares outputs; and doesn't need to even drive the outputs out of the model. Since so much is in Verilog, verilator will optimize it well, and in simple cases can even prove some RTL and Gate signals are equivelent and will optimize away the comparisons entirely.
2. Creates a C wrapper that feed clocks on clock pins, and randomly drives all other inputs.
The only challenge is knowing what is a clock. It's probably easiest to just look for flops in the synthesis output. Alternatively run verilator with --debug and use the clocks.txt file, which lists clocking domains for every RTL signal.
RE: testbench wrapper - Added by Jiang Long over 1 year ago
Thanks again. I think I almost got the pieces together. My parser would tell me what is the clock and registers and other hierarchical signal names. It maybe possible to dump a test bench based on these information such it can user verilator to compare ( I agree the coverage might not be good for 100% comparison, but I think it should give me some more confidence about my implementation to move forward).
For about item 1, how do I access a.b.c in the generated C++ code? If I do the /*verilator public*/ I trick, I can access the following :
Vour* top = new Vour;
while (!Verilated::gotFinish()) {
int a = top->v->k;
int b = top->v->s0->uvw;
top->eval(); }
exit(0);
where I have the following module declarations:
module sub; wire uvw/*verilator public*/; ... endmodule module top; sub s0; wire k/*verilator public*/;
...
endmodule
What is the mechanism to directly access top.k and top.s0.k?
-Jiang
RE: testbench wrapper - Added by Wilson Snyder over 1 year ago
What is the mechanism to directly access top.k and top.s0.k?
Sorry I don't understand, your example is right, it's top->v->k.
If you can avoid poking in using C and use Verilog instead, it will be faster.
RE: testbench wrapper - Added by Jiang Long over 1 year ago
I seem to get what you mean to access the hierarchical names by using the verilog wrapper to do the comparison.
Though, it seems still valuable to access the internals using C which would allow a flexible programming environment if I want to control the simulator by monitoring certain signals or integrate the simulator with some outside tools/procedures. But I think I can use hierarchical names in the verilog wrapper to achieve it.
module top; wire a /*verilator public*/ endmodule
assign a = sub0.sub1.x;
sub sub0(...);
In C++, I can use top->v->a to access the top.sub0.sub1.x in the RTL etc.
-Jiang
(1-6/6)
![[logo]](/img/veripool_small.png)