天天看點

uvm-1.2 examples —— 2.8 interfaces2.8 interfaces前言一、基本介紹二、代碼分析總結

2.8 interfaces

文章目錄

  • 2.8 interfaces
  • 前言
  • 一、基本介紹
  • 二、代碼分析
    • 1、interface.sv
    • 2、仿真結果
  • 總結

前言

本文以uvm-1.2/examples/simple/interfaces為例,通過代碼了解UVM中的一些用法。通過這個例子可以基本了解以下知識點:

  • interface的作用
  • 如何建立一個interface
  • 如何使用modport封裝信号
  • resource_db機制及其dump
  • 如何interface實作驗證環境與待測設計DUT之間的連接配接

一、基本介紹

interface翻譯過來就是接口的意思,interface的作用就是将接口單獨封裝出來,用于驗證環境與待測設計DUT之間的連接配接。将接口單獨封裝出來的好處是,避免接口很多的時候,連接配接的時候容易出錯,另外,當接口有改動的時候,隻需要改變一個檔案即可,不用在每個接口例化的地方全部改一遍。

在這個測試用例中,将通過interface封裝一個接口,在接口内部再通過modport關鍵字,對接口進行分類,最後通過interface,實作驗證環境和待測設計DUT之間的連接配接。

二、代碼分析

代碼比較簡單,隻有一個interface.sv檔案

1、interface.sv

/*
About: uvm_exmples/mechanism/interfaces

This example will illustrate how to create a pin interface and mod port interfaces for a simple dut.

Connect a component "driver" to the pin interfaces, then to the dut.
*/



//----------------------------------------------------------------------
// interface mem_pins_if
//----------------------------------------------------------------------
interface pin_if (input clk);
  bit [15:0] address;
  bit [7:0]  wr_data;
  bit [7:0] rd_data;
  bit rst;
  bit rw;
  bit req;
  bit ack;
  bit err;

  modport master_mp(             
   input  clk,
   input  rst,          
   output address,
   output wr_data,  
   input  rd_data,            
   output req,
   output rw,           
   input  ack,
   input  err );         
                                 
  modport slave_mp(              
   input  clk,
   input  rst,          
   input  address,
   input  wr_data,  
   output rd_data,            
   input  req,
   input  rw,           
   output ack,
   output err );         
                                 
  modport monitor_mp(            
   input  clk,
   input  rst,          
   input  address,
   input  wr_data,  
   input  rd_data,            
   input  req,
   input  rw ,
   input  ack,
   input  err );
endinterface

import uvm_pkg::*;

package top_pkg;
   typedef virtual pin_if pin_vif;
endpackage


package user_pkg;
import uvm_pkg::*;
import top_pkg::*;
`include "uvm_macros.svh"

//---------------------------------------------------------------------
// component driver
//----------------------------------------------------------------------
class driver extends uvm_component;

  pin_vif pif;

  function new(string name, uvm_component parent = null);
    super.new(name, parent);
  endfunction

  function void connect_phase(uvm_phase phase);
     assert(uvm_resource_db#(pin_vif)::read_by_name(get_full_name(),
                                                    "pif", pif));
  endfunction

  task run_phase(uvm_phase phase);
    forever begin
      @(posedge pif.clk);
      `uvm_info("driver", "posedge clk", UVM_NONE);
      //...
    end
  endtask

endclass

//----------------------------------------------------------------------
// environment env
//----------------------------------------------------------------------
class env extends uvm_env;

  local pin_vif pif;
  driver d;

  function new(string name, uvm_component parent = null);
    super.new(name, parent);
    d = new("driver", this);
  endfunction

  task run_phase(uvm_phase phase);
    phase.raise_objection(this);
     #100;
    phase.drop_objection(this);
  endtask

endclass

endpackage
//import user_pkg::*;

//----------------------------------------------------------------------
// module dut
//----------------------------------------------------------------------
module dut(pin_if pif);

  always @(posedge pif.clk) begin
    `uvm_info("dut", "posedge clk", UVM_NONE);
    //...
  end
endmodule

//----------------------------------------------------------------------
// module clkgen
//----------------------------------------------------------------------
module clkgen(output bit clk);

  initial begin
    forever begin
      #5 clk = 1;
      #5 clk = 0;
    end
  end

endmodule

//----------------------------------------------------------------------
// module top
//----------------------------------------------------------------------
module top;

  import top_pkg::*;
  import user_pkg::*;

  bit clk;
  clkgen ck(clk);
  pin_if pif(clk);

  env e;
  dut d(pif.slave_mp);

  initial begin
    e = new("env");
    uvm_resource_db#(pin_vif)::set("env.driver", "pif", pif);
    uvm_resource_db#(pin_vif)::dump();
    run_test();
    //$finish;
  end
  
endmodule
           

第14到56行,利用interface——endinterface關鍵字封裝了一組接口。

14行interface封裝的名字是pin_if,參數clk。

15到22行利用bit聲明了一系列的端口名,其實這裡用logic聲明端口名會更好,因為logic聲明的變量支援四個狀态,包括0、1、x、z,而bit聲明的變量隻支援兩個狀态,包括0和1。

24到55行利用modport關鍵字,将信号進行了分組,并指定了每組中變量的輸入輸出狀态。這裡分了三組,包括master_mp、slave_mp和monitor_mp,前兩組用于驅動,最後一組用于監控。

60到62行,通過package封裝了top_pkg,在top_pkg中,利用typedef關鍵字,将virtual pin_if取名叫pin_vif。

65行到117行,通過package封裝了user_pkg,在user_pkg中,聲明了driver和env。

73到94行聲明了dirver元件,其中關鍵的是81到84行的connect_phase,通過調用uvm_resource_db實作驗證環境和待測設計DUT的連接配接,resource_db機制中,存在一個資源池,在頂層将interface放入這個資源池,這裡将資源池裡面的interface按照名字讀出來,進而實作連接配接。assert關鍵字是斷言,用于判斷uvm_resource_db連接配接是否成功,如果連接配接失敗,斷言就會報錯。

99到115行聲明了env元件,env中聲明并例化了drver元件,另外,在109到113的run_phase中,通過“舉手”和“放手”來保證仿真執行的時間。這裡的舉手和放手可以參考張強《UVM實戰》的5.2節objection機制。

123到143行,聲明了兩個簡單的dut和clkgen子產品。dut子產品帶interface參數,clkgen子產品帶時鐘clk參數。

148到168行,聲明了頂層top子產品。在該子產品中例化了interface、dut、clkgen以及env子產品。

其中,153到158行,clkgen用于産生時鐘信号,interface封裝了端口信号,env構成了驗證環境,dut是待測設計(design under test)。clkgen産生的時鐘信号,送入了interface;interface封裝的slave_mp送入了dut。

160到166行,先例化了env,再通過uvm_resource_db的set函數,将interface送入resource_db機制的資源池中,這裡set函數的第一個參數是路徑,第二個參數是辨別符,第三個參數是變量。

163行調用uvm_resource_db的dump函數,列印資源池中的信号用于debug調試。列印的結果如下所示:

UVM_INFO ../../../src/base/uvm_resource.svh(1347) @ 0: reporter [UVM/RESOURCE/DUMP] 
=== resource pool ===
 pif [/^env\.driver$/] : (virtual interface pin_if) '{clk:'h0, address:'h0, wr_data:'h0, rd_data:'h0, rst:'h0, rw:'h0, req:'h0, ack:'h0, err:'h0}
           

164行執行仿真。

2、仿真結果

UVM_INFO ../../../src/base/uvm_resource.svh(1347) @ 0: reporter [UVM/RESOURCE/DUMP] 
=== resource pool ===
 pif [/^env\.driver$/] : (virtual interface pin_if) '{clk:'h0, address:'h0, wr_data:'h0, rd_data:'h0, rst:'h0, rw:'h0, req:'h0, ack:'h0, err:'h0}   
UVM_INFO ../../../src/base/uvm_resource.svh(1354) @ 0: reporter [UVM/RESOURCE/DUMP] === end of resource pool ===
UVM_INFO @ 0: reporter [RNTST] Running test ...
UVM_INFO interface.sv(89) @ 5: env.driver [driver] posedge clk
UVM_INFO interface.sv(126) @ 5: reporter [dut] posedge clk
UVM_INFO interface.sv(89) @ 15: env.driver [driver] posedge clk
UVM_INFO interface.sv(126) @ 15: reporter [dut] posedge clk
UVM_INFO interface.sv(89) @ 25: env.driver [driver] posedge clk
UVM_INFO interface.sv(126) @ 25: reporter [dut] posedge clk
UVM_INFO interface.sv(89) @ 35: env.driver [driver] posedge clk
UVM_INFO interface.sv(126) @ 35: reporter [dut] posedge clk
UVM_INFO interface.sv(89) @ 45: env.driver [driver] posedge clk
UVM_INFO interface.sv(126) @ 45: reporter [dut] posedge clk
UVM_INFO interface.sv(89) @ 55: env.driver [driver] posedge clk
UVM_INFO interface.sv(126) @ 55: reporter [dut] posedge clk
UVM_INFO interface.sv(89) @ 65: env.driver [driver] posedge clk
UVM_INFO interface.sv(126) @ 65: reporter [dut] posedge clk
UVM_INFO interface.sv(89) @ 75: env.driver [driver] posedge clk
UVM_INFO interface.sv(126) @ 75: reporter [dut] posedge clk
UVM_INFO interface.sv(89) @ 85: env.driver [driver] posedge clk
UVM_INFO interface.sv(126) @ 85: reporter [dut] posedge clk
UVM_INFO interface.sv(89) @ 95: env.driver [driver] posedge clk
UVM_INFO interface.sv(126) @ 95: reporter [dut] posedge clk
UVM_INFO ../../../src/base/uvm_objection.svh(1270) @ 100: reporter [TEST_DONE] 'run' phase is ready to proceed to the 'extract' phase
UVM_INFO ../../../src/base/uvm_report_server.svh(847) @ 100: reporter [UVM/REPORT/SERVER] 
--- UVM Report Summary ---

** Report counts by severity
UVM_INFO :   25
UVM_WARNING :    0
UVM_ERROR :    0
UVM_FATAL :    0
** Report counts by id
[RNTST]     1
[TEST_DONE]     1
[UVM/RELNOTES]     1
[UVM/RESOURCE/DUMP]     2
[driver]    10
[dut]    10

$finish called from file "../../../src/base/uvm_root.svh", line 517.
$finish at simulation time                  100
           V C S   S i m u l a t i o n   R e p o r t 
Time: 100 ns
           

通過log可以看到,首先在82行設定的斷言沒有報錯,其次driver列印一個posedge clk,同一時刻dut也列印了一個posedge clk,這說明驗證環境和dut已經完成連接配接。

總結

這個測試用例非常簡單,利用resource_db實作了驗證環境與待測設計之間,通過interface進行連接配接。其實,還可以利用config_db機制進行連接配接,具體可以參考張強的《UVM實戰》3.5節config_db機制。