When I learned the SystemVerilog verification features, one concept had me baffled – virtual interfaces. What are these and why are they needed?
What is an interface?
Start with an interface. Quick summary: Back in Verilog days, a module had ports, which were individual signals. To connect two modules, each with 9 ports, you had to list all 9 signals. This is very error prone.
When you connect your TV to a DVD player, do you connect individual wires? No, you plug an HDMI cable, click, and are done. You don’t even have to know how many wires are in an HDMI cable (20). In SystemVerilog, a bundle of wires is called an interface. In this diagram, the SystemVerilog test module has a single interface port, while the old Verilog design still has individual port signals.
An interface contains wires and synthesizable methods to perform operations such as sending and receiving transactions. An interface is RTL, just like your design. Here is an interface with 7 signals and a task to receive a transaction.
task receive(output logic [31:0] data);
Real hardware is static. If your chip is fabricated with 3M gates, it can’t suddenly have 4M gates just because you need a little boost. In simulation, the RTL design is specified at compile time and can’t grow or shrink. Likewise, your simulation has a fixed number of interfaces, specified at compile time, and can’t change at run time.
SystemVerilog classes and objects are dynamic. If you need to send 1000 transactions, just construct 1000 objects. Need 2000? Just construct more. If your UVM testbench decides it needs 2 drivers instead of the default of 1, it just creates another driver (or agent) at runtime.
Since objects are dynamic, they can’t contain interfaces. Otherwise, when you construct that second driver at runtime, it would create a second interface, which is not allowed.
But an object can contain pointers. For example, an agent has a pointer (handle / class variable) to the objects for the driver, monitor, etc. How can you make a pointer to the RTL interface?
Tip: In SystemVerilog, the keyword “virtual” usually means pointer. A virtual interface is a just pointer to an interface.
Here is the test module with a colors interface and a driver. When it constructs the driver, it passes a pointer to the (physical) interface.
module test(color_ifc c_ifc); Driver d; initial begin d = new(c_ifc); // Pass interface d.send(42); end endmodule
The driver class saves the pointer in a virtual interface, so it can use it later to drive signals.
class Driver; virtual color_ifc v_ifc; // Pointer to RTL instance function new(input virtual color_ifc c_ifc); v_ifc = c_ifc; endfunction task send(input logic [31:0] data); v_ifc.r = data; … endtask endclass
The Driver class is reusable as it can point to any color_ifc. If your testbench need to connect to two interfaces, it just constructs two Driver objects, passing in each interface instance.
You can learn more about these topics including Oriented Programming with the Siemens SystemVerilog for Verification course. It is offered in instructor led format by our industry expert instructors, or in a self-paced on-demand format. It can also be tailored to address your specific design goals and show you how to set up an environment for reuse for additional designs. Also, you can now earn a digital badge/level 1 certificate by taking our Advanced Topics Badging Exam. This will enable you to showcase your knowledge of this topic by displaying the badge in your social media and email signature.