在UVM中虚接口传递interface的方式

虚接口的使用绿皮书中虚接口传递的方式:
module dut(input clk,input rst_n,input [3 : 0] load_value,input load_vld,output reg [3 : 0] q);always@(posedge clk or negedge rst_n)beginif(!rst_n) q <= 'd0;else if(load_vld) q <= load_value;endendmoduleinterface dut_if(input logic clk);logic [3 : 0] load_value;logic load_vld;endinterface class transaction;randc logic [3 : 0] load_value;randc logic load_vld;endclassclass driver;virtual dut_if vif;function new (input virtual dut_if vif);this.vif = vif;endfunctiontransaction tr;task run(input int n);for (int i = 0; i < n ; i++)begintr = new();tr.randomize();$display("tr.load_value=http://www.kingceram.com/post/%0d, tr.load_vld=%0d", tr.load_value, tr.load_vld);@(posedge vif.clk)beginvif.load_value <= tr.load_value;vif.load_vld <= tr.load_vld;endendendtaskendclassmodule tb_dut();logic clk, rst_n;logic [3 : 0] q;//==================parameterparameter PERIOD = 10;//==================definaitondut_if dutif(clk);driver my_driver;//==================initialinitial beginclk = 0;forever #(PERIOD / 2) clk = ~clk;endinitial beginrst_n = 0;repeat(5) @(posedge clk);rst_n = 1;repeat(50) @(posedge clk);$finish;endinitial beginmy_driver = new(dutif);@(rst_n);repeat(5) @(posedge clk);my_driver.run(20);end//===================dutdut u_dut(.clk(clk),.rst_n(rst_n),.load_value(dutif.load_value),.load_vld(dutif.load_vld),.q(q));`ifdef FSDBinitial begin$fsdbDumpfile("dut.fsdb");$fsdbDumpvars;$fsdbDumpMDA();end`endifendmodule
这里的虚接口,在给类的句柄创建对象时将接口传递给类中的虚接口,从而完成连线,这样在类中可以调用接口内的变量 。
在测试平台中使用 时,需要满足以下3个要求
1、 实例化的接口必须正确连接到DUT 。
2、 必须在类中声明 句柄
3、必须将指定模块的赋值给
在UVM中虚接口传递的方式

在UVM中虚接口传递interface的方式

文章插图
这里时顶层`timescale 1ns/1ps`include "uvm_macros.svh"import uvm_pkg::*;`include "my_if.sv"`include "my_driver.sv"module top_tb;reg clk;reg rst_n;reg[7:0] rxd;reg rx_dv;wire[7:0] txd;wire tx_en;my_if input_if(clk, rst_n);my_if output_if(clk, rst_n);dut my_dut(.clk(clk),.rst_n(rst_n),.rxd(input_if.data),.rx_dv(input_if.valid),.txd(output_if.data),.tx_en(output_if.valid));initial beginclk = 0;forever begin#100 clk = ~clk;endendinitial beginrst_n = 1'b0;#1000;rst_n = 1'b1;endinitial beginrun_test("my_driver");endinitial beginuvm_config_db#(virtual my_if)::set(null, "uvm_test_top", "vif", input_if);endendmodule/这里时接口interface my_if(input clk, input rst_n);logic [7:0] data;logic valid;endinterface/这里时my_driver类class my_driver extends uvm_driver;virtual my_if vif;`uvm_component_utils(my_driver)function new(string name = "my_driver", uvm_component parent = null);super.new(name, parent);`uvm_info("my_driver", "new is called", UVM_LOW);endfunctionvirtual function void build_phase(uvm_phase phase);super.build_phase(phase);`uvm_info("my_driver", "build_phase is called", UVM_LOW);if(!uvm_config_db#(virtual my_if)::get(this, "", "vif", vif))`uvm_fatal("my_driver", "virtual interface must be set for vif!!!")endfunctionextern virtual task main_phase(uvm_phase phase);endclasstask my_driver::main_phase(uvm_phase phase);phase.raise_objection(this);`uvm_info("my_driver", "main_phase is called", UVM_LOW);vif.data <= 8'b0; vif.valid <= 1'b0;while(!vif.rst_n)@(posedge vif.clk);for(int i = 0; i < 256; i++)begin@(posedge vif.clk);vif.data <= $urandom_range(0, 255);vif.valid <= 1'b1;`uvm_info("my_driver", "data is drived", UVM_LOW);end@(posedge vif.clk);vif.valid <= 1'b0;phase.drop_objection(this);endtask
在UVM中,由于使用了机制,使用内置函数自动创建实例,从而就不能在创建对象时传递(绿皮书中就是在创建对象时传递的) 。这时就使用来传递 。
使用举例
set函数和get函数的原型是:
set函数和get函数的使用方法是: