Here's a collapsed set of questions asked during the live web seminar along with Chris's answers. If you don't see your question here, or need further clarification, you can always ask on the Verification Academy Forums.
Is UVM relevant for FPGA?
With multi-million gate FPGAs, UVM is not only relevant, but crucial to the verification flow. Just because you can debug some bugs in the lab does not mean you can find them all. Some problems require not only sophisticated, replayable stimulus, but also immediate access to design information across the system, which is a strength of UVM, and software simulation. As your hardware design grows more complex, you need a strong testbench to find and diagnose bugs.
Is it correct to sample covergroups inside driver or monitor classes?
Best practice in UVM is to keep your component classes small so you don’t have to change them for the life of the project. The functional coverage at the start of the project is very different than at the end, so you need to constantly create new covergroups. If you build them into the driver and monitor classes, you will need to constantly update these classes, a bad idea. Instead, keep these component classes more abstract and perform analysis in separate analysis components, often extended from uvm_subscriber.
Would you recommend using interface signals values as the randomizable values of a sequence item?
A UVM sequence item typically holds a transaction. Your class will contain random properties (variables) that describe the transaction. Some of those properties might hold values that are drive interface signals directly, such as address and data, while other might hold more abstract information such as delays between transactions, error injection, or even routing and response info. Declare all these properties as rand so you can leverage the constraint solver to pick meaningful values.
What is the name of the switch that Chris forgot during the webinar?
+UVM_CONFIG_DB_TRACE.
This writes all uvm_config_db set() and get() calls to the log file, and is a good way to debug issues with the DB. You can check the spelling of the scope, the name, value, and data type.
How can we control configuration object variables from command line?
UVM supports the following run-time switch which creates an uvm_config_db entry at the uvm_test_top scope called “addr” with the value 123.
% vsim +uvm_set_config_int=uvm_test_top,addr,123
Your code can call the get() to save the value in any appropriate variable, including one in a configuration object. The one gotcha with this approach is that UVM does not store the value as an int data type, as that would restrict you to just 32 bits of 2 state values. Instead, UVM uses the type uvm_bitstream_t which is 4096 4-state bits. In general, these you are optionally setting values, otherwise they will have their default values. The following code does an optional uvm_config_db get() and stores the value into the USB agent configuration object.
void'(uvm_config_db #(uvm_bitstream_t)::get(this, "", "addr", usb_cfg.addr));
Do the UVM field macros affect simulation performance?
Today, not appreciably. There are well written studies that compare the UVM field macros to the do methods, and they show that the macros run slower. Dig deeper, and you will see that there is no real RTL code so all the simulation does is copy and compare objects. Your real world simulations have RTL code in SystemVerilog and VHDL, assertions, code and functional coverage, bus functional models written in C or SystemC, MatLab models, and more. Build your sequence item classes so they are easy to write, debug, reuse, and extend, either with field macros or do methods. These two approaches have tradeoffs, but simulation performance is a low priority.
Is set_config() a predefined method?
(This is the method that Chris showed as a replacement for most uvm_config_db calls.) No, this method is purely user-defined. It allows a component such as a test, environment, or agent pass configuration objects to their child components. It is based on a standard OOP pattern of get()/set() methods so that two objects can share data.
Do #0 and #1 delays help or worsen verification?
SystemVerilog is an event-based simulation language. Sometimes you may want a very short delay before a statement executes. You could use a #0 to delay that statement after currently scheduled statements. However, another block of code may use the same trick to put their statement at the end. A #1 moves the statement into the next timeslot, however is that #1ns, #1ps? These delays can make verification harder to debug, but sometimes they are the only way to solve an ordering problem. UVM uses this technique.
How to handle resets? Reset in between some transactions?
An asynchronous reset is difficult to verify. Your testbench needs to model the behavior of the design under test. One problem is that some UVM classes cannot be easily reset. For example, consider your sequence, when it is in the middle of a stream of transactions, some that are being transmitted by the driver. If a hardware reset happens, there is no easy way to reset the sequence or driver. Worse yet, the uvm_sequencer class does not have a clean way to reset, and can easily be hung.
Is SystemVerilog the replacement of Verilog?
I think “replacement” is too harsh for this relationship, as it is closer to an evolutionary flow. You probably already took the first step when you tried some Verilog 2000 features such as C-style module ports. You can still describe your hardware with classic Verilog, and now verify it with some of the new SystemVerilog features. Incrementally adopt some of the concepts such as immediate assertions to check signal values, and case-inside which easier to understand than the old casez and casex.
The slides showed $urandom(lo,hi) – shouldn’t the arguments be the other way around?
I asked Accellera to add the following to the SystemVerilog standard as I knew many people would reverse the order. "If maxval is less than minval, the arguments are automatically reversed so that the first argument is larger than the second argument." This helps prevent a testbench bug.
Does randomize() print an error when it fails?
Yes, if randomize() fails, an error message is printed, but simulation continues, and the variables keep their old values. You should treat this as a testbench bug and end simulation as the values may not be correct.
The streaming operator example had a bug where 1’hC should have been 8’hC
Yes, this was a bug in my slides. Questa still can't read PowerPoint so there is always a chance these mistakes can creep in. Good catch - you must be a verification engineer!
Is the SystemVerilog for Verification course included in the On-Demand Training or do we need to pay?
You will get access to the SystemVerilog for Verification, UVM, UVM Framework, UVM Intermediate and many more verification courses by subscribing to the On-Demand Functional Verification Library. For details, please see: https://www.mentor.com/training/courses/functional-verification-training-library.