Welcome ! This website will help YOU (recent graduates/professionals) learn verification languages like SystemVerilog and UVM. Register for free and access more content !

The input and output signals of a module are the main way to communicate with other blocks in the design. There can be hundreds of signals for complex designs that involve multiple bus protocols, memory interfaces and connections to various other peripherals. From a testbench perspective, such designs have to be instantiated and connected for each signal and it becomes time consuming to debug, prone to errors and difficult to maintain for design changes.

What is SystemVerilog interface ?

A SystemVerilog interface is a named bundle of nets or variables created specifically to encapsulate communication between blocks, hence assuring a smoother migration between different projects. Moreover it brings an element of abstraction by hiding away the details. It also enables different blocks to be connected to the testbench more easily.

Traditional way of connecting design with testbench

 
  module mydesign ( input clk,
                            reset,
                            enable,
                            ...
                      output gnt,
                             irq,
                             ... );
 
  module tb;
      reg clk;
      reg tb_reset;
      ...           
 
    mydesign top  (   .clk (tb_clk),
                      .reset (tb_reset)
                      ...
                      .gnt (tb_gnt),
                      ... );
  endmodule
 

As you can see, it becomes a little messy and hard to maintain as the port list grows. Now we'll see the power of an interface. It can also have functions, tasks, variables, and parameters making it more like a class template. Also it has the ability to define policies of directional information for different module ports via the modport construct alongwith testbench synchronization capabilities with clocking blocks. Last but not the least, it can also contain initial and always procedures and continuous assign statements. To make it a power punch, we can also put in assertions, coverage recording and other protocol checking elements.

Syntax

Interface blocks are defined and described within interface and endinterface keywords. It can be instantiated like a module with or without ports.

 
  interface [name] ([port_list]);
    ...
    // list of signals
    ...
  endinterface
 

In the example below an interface named myInterface with an empty port list is created and instantiated within the top level testbench module. It is also fine to omit the parenthesis for an empty port list and instead truncate the statement with a semicolon

 
  // interface myInterface;
 
  interface myInterface ();
    reg     gnt;
    reg     ack;
    reg [7:0]  irq;
 
    ... 
  endinterface
 
  module tb;
    myInterface   if0 ();
    myInterface   wb_if [3:0] ();
 
    ...
  endmodule
 

In this case a single interface called if0 is created and signals within it can be accessed via this handle, and an array of interfaces are instantiated that goes by the name wb_if[0] to wb_if[3]. Note that a module cannot be instantiated in an interface, but the other way is possible. Now let's create an interface called if0 and pass that as an argument to the design under verification which can be used to drive and sample signals. Look at how short this code became !

 
  module myDesign ( myInterface dut_if, 
                    input logic clk);
 
    always @(posedge clk)
      if (dut_if.ack)
        dut_if.gnt <= 1;
 
  endmodule
 
  module tb;
    reg clk;
 
    myInterface  if0;
    myDesign    top (if0, clk);
 
    // Or connect by name
    // myDesign  top (.dut_if(if0), .clk(clk));        
 
  endmodule
 

When an interface is referenced as a port, the variables and nets in it are assumed to have ref and inout access respectively. If same identifiers are used as interface instance name and port name in the design, then implicit port connections can also be used.

 
  module tb;
    reg clk;
 
    myInterface   dut_if();
 
    // Can use implicit port connection when all port signals have same name
    myDesign     top (.*);
 
  endmodule
 

Was this article helpful ?

We use cookies to personalize content and ads, to provide social media features and to analyze our traffic. You consent to our cookies if you continue to use our website. To find out more about the cookies we use and how to delete them, see our privacy policy.

  I accept cookies from this site.
Agree
EU Cookie Directive plugin by www.channeldigital.co.uk