circt
circt copied to clipboard
[Verif][Sim][Feature] Inline Simulation Tests
Current testing infrastructure in CIRCT makes it inconvenient to express test intent in the IR, these thus often rely on external tools and/or libraries implemented in the front-end languages to write out simulation unit-tests.
Similarly to the verif.formal
ops and the firrtl formal constructs, we would like to be able to express simulation test code along-side the designs.
This could potentially be done through the following steps:
- Create simulation test intent ops:
-
verif.simulate @TestName { /* Procedural Region */ }
: Simulation intent op that has a referable symbol and exists at the top-level, similar to verif.formal. The main difference is that this op supports simulation ops and has a procedural region. - [Optional]
sim.instance @DUT(...)
: potentially optional op that refers to an instance used in simulation. This can be interacted with through ops such as peek and poke. This could potentially be replaced with hw.instance mixed with block arguments to generate the original inputs, e.g.
verif.simulate @sim1 {
^bb0(%a: i1, %b: i1, %clk: !seq.clock):
%foo = hw.instance "dut" @Foo(clk: %clk : !seq.clock, a: %a : i1, b : %b : i1) -> (i1)
%true = hw.constant 1 : i1
sim.poke %a, %true : i1 // set a to 1
sim.poke %b, %true : i1 // set b to 1
sim.step %clk, 1 //; advance the clock by 1 cycle
sim.eval "foo" // commit the changes
%foo1 = sim.peek %foo : i1 // get the value of foo at that clock cycle
%cond = comb.icmp bin eq %foo1, %true: i1
verif.assert %cond : i1
}
-
sim.peek
,sim.poke
,sim.eval
,sim.step
: DUT interaction operations that allow to set and get i/o values at specific cylces. Peeks and steps are only committed during ansim.eval
.
- Create a lowering from these ops to the arc dialect.
- [potentially tricky] Update the verilog emission (in export verilog) to generate a testbench file for each simulation region and emits these as individual tests.
There are of course various other issues to think about such as:
- How can we represent control flow?
- How can we drive our test using arbitrary code blocks?
- How can we minimize the number of DPI calls made in our tests?
Please feel free to reach out to me if you want to tackle this problem, this issue can hopefully be a good starting point to getting a working inline simulation test backend. Also feel free to comment on this issue if there are any other things that should be considered to solve this problem!