quick.gif

space2.gif

space2.gif

space2.gif

space2.gif

space2.gif

space2.gif

space2.gif

   

space.gif

   

space.gif

  ../images/main/bulllet_4dots_orange.gif Virtual Interface

In Vera and E (Specman), it is possible to writing Drivers (BFM), independant fo the signal names used by DUV, This is done with usage of "ports" in Vera. This ports are bind to DUT through a interface.

   

space.gif

Same thing is possible in SystemVerilog also by usage of Virtual Interface. Virtual interfaces provide a mechanism for separating abstract models and test programs from the actual signals that make up the design. By abstracting the connectivity and functionality of a set of blocks, virtual interfaces promote code reuse.

   

space.gif

Some of the features of Virtual Interfaces are

   

space.gif

  • Virtual interface can be passed to task or function, just like any other data type.
  • Virtual interface should be initilized before using it.
  • Virtual interface default value before initilization is null.
  • Components inside a Virtual interface can be only used in procedural assignment and not in continous assignment.
  • Driving of a net data type inside a virtual interface should be done through clocking.
  • Virtual interfaces can be declared as class properties, which can be initialized procedurally or by an argument to new().
   

space.gif

Note : Virtual interfaces is used in writing testbenches.

   

space.gif

   

space.gif

  ../images/main/bullet_star_pink.gif Example 1 : Virtual Interface
   

space.gif


   1 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
   2 // Declare memory interface
   3 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
   4 interface memory (input bit clk);
   5   wire [7:0] addr;
   6   wire [7:0] data_i;
   7   wire [7:0] data_o;
   8   wire       rw;
   9   wire       ce;
  10   //==============================================
  11   // Define the DUT modport
  12   //==============================================
  13   modport  dut (input  addr, data_i, rw, ce, clk, output data_o);
  14   //==============================================
  15   // Define the Testbench Driver modport
  16   //==============================================
  17   modport  tb  (output addr, data_i, rw, ce, input data_o, clk);
  18   //==============================================
  19   // Define the Testbench Monitor modport
  20   //==============================================
  21   modport  mon (input  addr, data_i, rw, ce, clk, data_o);
  22 endinterface
  23 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  24 // Simple memory model
  25 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  26 module ram(memory.dut mif);
  27 
  28 reg [7:0] memr [0:255];
  29 //==============================================
  30 // Memory read operation
  31 //==============================================
  32 assign mif.data_o = (~mif.rw && mif.ce) ? 
  33      memr[mif.addr] : 8'b0;
  34 //==============================================
  35 // Memory write operation
  36 //==============================================
  37 always @ (posedge mif.clk)
  38 if (mif.ce && mif.rw) 
  39   memr[mif.addr] = mif.data_i;
  40 
  41 endmodule
  42 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  43 // Top level of memory model
  44 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  45 module ram_top(memory.dut mif0,memory.dut mif1,memory.dut mif2);
  46 
  47 ram U_ram0(mif0);
  48 ram U_ram1(mif1);
  49 ram U_ram2(mif2);
  50 
  51 endmodule
  52 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  53 // Memory top level with DUT and testbench
  54 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  55 module mem_tb();
  56   logic clk = 0;
  57   always  #1  clk = ~clk;
  58   //==============================================
  59   // interface with clock connected
  60   //==============================================
  61   memory mem_if0(clk);
  62   memory mem_if1(clk);
  63   memory mem_if2(clk);
  64   //==============================================
  65   // Connect the DUT
  66   //==============================================
  67   ram_top U_ram_top(
  68     .mif0(mem_if0.dut),
  69     .mif1(mem_if1.dut),
  70     .mif2(mem_if2.dut)
  71   );
  72   //==============================================
  73   // Connect the testbench
  74   //==============================================
  75   test U_test(
  76    .tbf0(mem_if0),
  77    .tbf1(mem_if1),
  78    .tbf2(mem_if2)
  79   );
  80 endmodule
  81 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  82 // Testbench top level program
  83 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  84 program test(memory tbf0,memory tbf1,memory tbf2);
  85   //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  86   // Driver class
  87   //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  88   class driver;
  89     virtual memory.tb ports;
  90     //==============================================
  91     // Constructor
  92     //==============================================
  93     function new(virtual memory.tb ports);
  94        this.ports = ports;
  95     endfunction
  96     //==============================================
  97     // Test vector generation
  98     //==============================================
  99     task run_t();
 100       integer i = 0;
 101       for (i= 0; i < 4; i ++) begin
 102          @ (posedge ports.clk);
 103          $display("Writing address %0d with data %0d",i,i);
 104          ports.addr = i;
 105          ports.data_i = i;
 106          ports.ce = 1;
 107          ports.rw = 1;
 108          @ (posedge ports.clk);
 109          ports.addr = 0;
 110          ports.data_i = 0;
 111          ports.ce = 0;
 112          ports.rw = 0;
 113       end
 114       for (i= 0; i < 4; i ++) begin
 115          @ (posedge ports.clk);
 116          $display("Read address %0d",i);
 117          ports.addr = i;
 118          ports.data_i = i;
 119          ports.ce = 1;
 120          ports.rw = 0;
 121          @ (posedge ports.clk);
 122          ports.addr = 0;
 123          ports.data_i = 0;
 124          ports.ce = 0;
 125          ports.rw = 0;
 126       end
 127     endtask
 128   endclass
 129   //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 130   // Monitor class
 131   //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 132   class monitor;
 133     reg  [7:0] tbmem [255];
 134     virtual memory.mon ports;
 135     //==============================================
 136     // Constructor
 137     //==============================================
 138     function new(virtual memory.mon ports);
 139        this.ports = ports;
 140     endfunction
 141     //==============================================
 142     // Monitor method
 143     //==============================================
 144     task run_t();
 145       while(1) begin
 146          @ (negedge ports.clk);
 147          if (ports.ce) begin
 148            if (ports.rw) begin
 149              tbmem[ports.addr] = ports.data_i;
 150            end else begin
 151              if (ports.data_o  ! = tbmem[ports.addr]) begin
 152                $display("Error : Expected %0x Got %0x",
 153                  tbmem[ports.addr],ports.data_o);
 154              end else begin
 155                $display("Pass  : Expected %0x Got %0x",
 156                  tbmem[ports.addr],ports.data_o);
 157              end
 158            end
 159          end
 160       end
 161     endtask
 162   endclass
 163   //==============================================
 164   // Initial block to start the testbench
 165   //==============================================
 166   initial begin
 167     driver   tb_driver0  = new(tbf0.tb);
 168     monitor  tb_monitor0 = new(tbf0.mon);
 169     driver   tb_driver1  = new(tbf1.tb);
 170     monitor  tb_monitor1 = new(tbf1.mon);
 171     driver   tb_driver2  = new(tbf2.tb);
 172     monitor  tb_monitor2 = new(tbf2.mon);
 173     fork 
 174       begin
 175         tb_monitor0.run_t();
 176       end
 177       begin
 178         tb_monitor1.run_t();
 179       end
 180       begin
 181         tb_monitor2.run_t();
 182       end
 183    join_none
 184    fork
 185       begin
 186         tb_driver0.run_t();
 187       end
 188       begin
 189          #100  tb_driver1.run_t();
 190       end
 191       begin
 192          #200  tb_driver2.run_t();
 193       end
 194      join
 195      #10  $finish;
 196   end
 197 endprogram
You could download file if_modport_multi.sv here
   

space.gif

  ../images/main/4blue_dots_bullets.gif Simulation 1 : Virtual Interface
   

space.gif

 Writing address 0 with data 0
 Writing address 1 with data 1
 Writing address 2 with data 2
 Writing address 3 with data 3
 Read address 0
 Pass  : Expected 0 Got 0
 Read address 1
 Pass  : Expected 1 Got 1
 Read address 2
 Pass  : Expected 2 Got 2
 Read address 3
 Pass  : Expected 3 Got 3
 Writing address 0 with data 0
 Writing address 1 with data 1
 Writing address 2 with data 2
 Writing address 3 with data 3
 Read address 0
 Pass  : Expected 0 Got 0
 Read address 1
 Pass  : Expected 1 Got 1
 Read address 2
 Pass  : Expected 2 Got 2
 Read address 3
 Pass  : Expected 3 Got 3
 Writing address 0 with data 0
 Writing address 1 with data 1
 Writing address 2 with data 2
 Writing address 3 with data 3
 Read address 0
 Pass  : Expected 0 Got 0
 Read address 1
 Pass  : Expected 1 Got 1
 Read address 2
 Pass  : Expected 2 Got 2
 Read address 3
 Pass  : Expected 3 Got 3
   

space.gif

   

space.gif

   

space.gif

   

space.gif

space2.gif

space2.gif

space2.gif

space2.gif

space2.gif

  

Copyright © 1998-2014

Deepak Kumar Tala - All rights reserved

Do you have any Comment? mail me at:deepak@asic-world.com