Verifying error conditions and UVM testbench checkers just got easier! The SVUnit UVM report mock lets you automate testing of UVM errors and fatals to increase confidence that the checkers in your testbench are defect free. The SVUnit UVM report mock is a scoreboard style checker where actual and expected errors are logged and compared to trigger a PASS/FAIL result.
Here’s how it works…
In a unit test, a user would go through the following steps to verify a uvm_error is being triggered properly:
- set the expectation of a particular error by calling the svunit_uvm_report_mock::expect_error(…) function
- apply the error causing scenario to the UUT
- call svunit_uvm_report_mock::verify_complete() to ensure actual errors are trapped in the UUT as expected (and that there are no expected errors left outstanding).
To help get those points across, we’ll look at the uvm_report_mock example that’s packaged with SVUnit. In this example we have a UUT with a method called verify_arg_is_not_99(). In case it’s not obvious, verify_arg_is_not_99() is designed to trap variables that are set to 99 by asserting a uvm_error. Other values are ignored.
To verify our UUT is working as we expect, we of course need a few tests. Here’s the first from the example that tests the error condition.
That test exactly follows the bullet steps above. We call the expect_error() method once because we expect one error. That pushes an item onto the expected queue of our log message scoreboard inside the svunit_uvm_report_mock. Then we call our UUT function with 99 as the argument. That pushes an item onto the actual queue of our log message scoreboard. Finally, we call the verify_complete. That does an in-order comparison between the actual and expected queues to confirm we’re getting the errors we expect.
To pass this test, this is the code we need in our UUT. An error is triggered for 99; nothing happens otherwise.
At this point, you might be wondering how the svunit_uvm_report_mock knows about UVM errors. Well it’s not as magical as you might think. To do it, we redefine the uvm_error macro to call the svunit_uvm_report_mock::actual_error(…) function instead of the normal UVM reporter. The macros are redefined in the svunit_uvm_mock_defines.sv and they look like this…
So instead of sending errors to your log file where you’d have to visually confirm they’re being asserted, we redirect them by mocking out the UVM reporting and automate the confirmation. For that to work, we have to make sure the macros are redefined as we intend. That’s done with includes at the top of the unit test file. The uvm_macros are loaded first, then the svunit_uvm_mock_defines are loaded to redefine the macros.
To exhaustively verify our UUT, we need one more test to make sure values other than 99 don’t cause a problem. In this test, you’ll see we still call verify_complete() to make sure we get what we expect, but we don’t call expect_error() because we’re… uhh… not expecting an error.
In this case, verify_complete() will return 1. That tells us no errors were expected and none were detected.
A final feature that we’ll talk about is the ability to expect a specific MSG and ID from your error. To do that, you pass in strings to the expect_error() function (the defaults are null strings which means the content of the message isn’t checked).
You can see that test is the same as the first except that the MSG and ID are passed to the expect_error(). Just getting the error in this test case isn’t enough, the content of the message has to match also. If it doesn’t, the test fails.
That’s how to automate checking of uvm_error logging with the SVUnit UVM report mock. FYI… uvm_fatal is also supported so if that’s what you’re looking for, just do a search-and-replace to swap error for fatal. The mechanisms for both are the same.
Lastly, I’ll mention that this is version 0.1 functionality so if you’ve got any better ideas for doing the same kind of automation, I’d love to hear it!
Q. If you don’t test your checkers, how do you know they’re working?