Simulation
How It Works
Here are some technical details on how OrigenSim works which should provide some context when it comes to compiling your DUT design to work with OrigenSim.
Origen provides components that can be compiled into a simulation object along with the design under test (DUT), a high level view of the process looks like this:
The main Origen Ruby process is invoked by generating a pattern as usual, e.g. origen g my_pattern
,
but with the environment setup to instantiate an instance of OrigenSim::Tester
instead of say
OrigenTesters::V93K
.
The OrigenSim tester will start off a Verilog process in parallel which will run a simulation on an object that
has been created beforehand. This simulation object contains the DUT wrapped in an OrigenSim testbench, and which
has been compiled into a snapshot/object that also includes a Verilog VPI
extension which provides a communication interface between Origen and the simulation world.
When the simulation process starts, the VPI extension immediately takes control and halts the simulator while it
listens for further instructions from a Linux socket which was setup by OrigenSim before the simulation was started.
As the Origen pattern generation process executes, the OrigenSim::Tester
will translate any requests
to drive or expect pin values, or to generate a cycle, into messages which are passed into the Linux socket.
Upon receving these messages, the VPI process will manipulate the testbench’s pin drivers to drive or read from
the DUT and it will advance time by a cycle period every time a cycle is generated in the pattern.
The testbench to wrap and instantiate the DUT is generated by OrigenSim and it provides a standard interface through
which Origen can access any DUT.
In principle the DUT object can be any design view that is wrapped by a conventional top-level Verilog module, meaning that OrigenSim can be used to run RTL or gate-level simulations depending on what has been compiled into the snapshot.
Note also that the DUT can be either an IP-block or an SoC, and so OrigenSim can be used equally well for running both IP-level and top-level simulations.
The testbench is quite simple and it does little more than instantiate the DUT module and connect all of its pins to
instances of this pin driver module.
The testbench module is named origen
by default and all OrigenSim simulation dumps will have this same top-level structure:
.
└── my_pattern
└── origen
├── debug // Contains an error count, pattern name and comments, and other debug aids
├── dut // Your DUT
└── pins
├── tdi // Driver for the TDI pin (for example)
├── tdo
└── tck
The driver contains a number of registers which are written to directly by the VPI process, allowing it to drive or expect a
given data value (stored in origen.pins.MYPIN.data
) by writing a 1 to origen.pins.MYPIN.drive
or origen.pins.MYPIN.compare
respectively.
If the value being driven by the pin does not match the expect data during a cycle, then an error signal will be asserted by the
driver and this will increment an error counter that lives in origen.debug.errors[31:0]
.
An error count > 0 will result in the pattern simulation status being reported as a FAIL by Origen and this can be used to create simulation-based regression test suites for your application.