Unit Testing UVM code with SVUnit
You see a UVM_ERROR in a simulation.
Now the debug begins. Is the bug in the RTL or in the Testbench? How do you know?
Your unit tests of your UVM code should be giving you the answer.
Learning Unit Testing with SVUnit
SVUnit Documentation
Videos about SVUnit
- Verification Academy Video Course
-
Verification Academy: Back to the Stone Ages for Advanced Verification
- Interesting datapoint from Harry Foster: Small sample, but unit testing brings the bug rate from 50 bugs per 1000 lines of code to 10 bugs per 1000 lines of code.
- EDA Playground Introduction to SVUnit
SVUnit articles
- Verification Horizons: First Time Unit Testing Experience Report with SVUnit
- Verification Horizons: Unit Testing Your Way to a Reliable Testbench
SVUnit Examples
- UVM Driver
- UVM Monitor
- UVM Sequence
- UVM Coverage
- UVM Checkers
- RTL
- APB Slave RTL Module: [svunit]/examples/modules/apb_slave
- APB Slave RTL Module at EDA Playground
- Simple example using multiple RTL files and directories: [svunit]/examples/modules/clk_and_reset
- APB example showing Wavedrom integration: [svunit]/examples/modules/wavedrom
- Other examples
Downloading SVUnit
You will need perl to run SVUnit. There is not specific requirement for a recent version. I have Perl v5.32.1 which works.
git clone https://github.com/svunit/svunit.git
or- Download official releases as zip or tar.gz files
Downloading SVMock
git clone https://github.com/tudortimi/svmock.git
Small tips when using SVUnit
- Always use -o/--out [dir] when calling runSVUnit or buildSVUnit. Both will generate a bunch of files — some hidden — in the current directory if you run them without a specific output directory.
- It is important to use -U/--uvm when you have any UVM code in your tests. It is also important to not use -U/--uvm when there is no UVM code under test.
Integrating SVUnit into any crazy simulator setup
Some companies have crazy simulator setups that make SVUnit harder to adopt.
But fear not. SVUnit has ways around this obstacle. SVUnit runs in two phases:
- A Build phase that generates all required SystemVerilog code and compile files.
- A Run phase where a simulator is called with all the generated code.
runSVUnit calls both phases, but the build phase is a separate script (buildSVUnit) that works in isolation.
You can call buildSVUnit directly like this:
buildSVUnit -o obj --uvm --mock
buildSVUnit will create all requred files in the obj directory. You can then invoke your simulator with your own crazy setup. SVUnit will print the full command that it is going to invoke the simulator with. You can use this string integrate SVUnit into your flow. For Example:
runSVUnit -o obj --uvm --sim ius
Assume that you want to integrate SVUnit into your flow that runs Cadence Incisive. Run runSVUnit in a temporary directory on a machine that doesn't have Cadence Incisive installed. Use the tail of the output from runSVUnit to integrate SVUnit into your flow:
cd obj; irun -l run.log -uvm -f .svunit.f +define+SVUNIT_VERSION='"SVUnit unrel"' +define+RUN_SVUNIT_WITH_UVM -top testrunner +SVUNIT_FILTER=*
sh: irun: command not found