wenyu_yan的个人空间 https://blog.eetop.cn/1834169 [收藏] [复制] [分享] [RSS]

空间首页 动态 记录 日志 相册 主题 分享 留言板 个人资料

日志

2025-04-25

已有 53 次阅读| 2025-4-25 09:13 |个人分类:UVM基础|系统分类:其他

学习到一篇有趣的接口interface介绍   验证IP(VIP)编写-interface_验证 vip-CSDN博客

sv interface高级用法 - hematologist - 博客园

《UVM白皮书》关于接口的介绍

interface是用来连接DUT和验证环境的端口。

 一、定义一组接口

verilog;toolbar:false;" data-cke-widget-data="%7B%22lang%22%3A%22cs%22%2C%22code%22%3A%22interface%20avsbus_interface(input%20clk%2C%20input%20rst_n)%5Cn%20%20%20%20logic%20avsbus_md%3B%5Cn%20%20%20%20%E2%80%A6%5Cnendinterface%22%2C%22classes%22%3Anull%7D" data-cke-widget-keep-attr="0" data-cke-widget-upcasted="1" data-widget="codeSnippet">interface avsbus_interface(input clk, input rst_n)    logic avsbus_md;
    …
endinterface

 二、在top_tb和driver里声明这个接口

1. 定义了interface之后,在top_tb中(是个module)就可以连接dut使用:

module harness();
    …    avsbus_interface  u_avsbus_if(clk_avs,rst_n);
    …    dut my_dut(.clk(clk),
               .rst_n(rst_n),
               .AVSMADATA(u_avsbus_if.avsbus_md));

    OR

    initial begin
        force U_DUT.AVS_MDATA = u_avsbus_if.avsbus_md;
    end
    …
endmodule

2. 但是在driver中声明interface用上述方式的话,是会报错的,只有在module块里才可以。

    在driver这种class类里使用的是virtual interface

class avsbus_driver extends uvm_driver#(avsbus_xaction);
    …
    virtual avsbus_interface  vif;
    …
    function new(string name="avsbus_driver",uvm_component parent = null);
        super.new(name,parent);
    endfunction
    …
endclass

在声明了vif之后,就可以在main_phase等中驱动其中的信号了。

task avsbus_driver::run_phase(uvm_phase phase);
	super.run_phase(phase);
		
	…
	vif.avsbus_md <= 1'b1 ;
	…
endtask

这样做可以消除代码中的绝对路径,大大提高了代码的可移植性。

三、连接top_tb 和 driver 中的接口

但是怎么把top_tb中的u_avs_bus_if与driver中的vif连接起来呢?

这就要用到config_db机制了。

在config_db机制中,分为set“寄信”和get“收信”两步操作。

示例:

1. 在top_tb中进行set操作:

module harness();
    …    avsbus_interface  u_avsbus_if(clk_avs,rst_n);
    …
    initial begin
        force U_DUT.AVS_MDATA = u_avsbus_if.avsbus_md;
    end
    …
*******************************************************************************************
    initial begin
        uvm_config_db#(virtual avsbus_interface)::set(null,"*","vif",u_avsbus_if);
    end
*******************************************************************************************
endmodule

2. 在my_driver中进行get操作:

class avsbus_driver extends uvm_driver#(avsbus_xaction);
    …
    virtual avsbus_interface  vif;
    …
    function new(string name="avsbus_driver",uvm_component parent = null);
        super.new(name,parent);
    endfunction
*******************************************************************************************
	virtual function void build_phase(uvm_phase phase);
		super.build_phase(phase);
		if(!uvm_config_db#(virtual avsbus_interface)::get(this," ","vif",vif))
			`uvm_fatal(get_type_name(),"VIRTUAL INTERFACE MUST BE SET FOR VIF!!!")
    endfunction
*******************************************************************************************
    ...
endclass

 这里引入了build_phase,它是UVM_phase机制中的一个,在new函数之后main_phase之前执行。

  • build_phase 主要用来通过config_db机制的set,get来传递一些数据,以及实例化成员变量等。

  • 它是一个function phase函数phase,是不消耗仿真时间的,总是在仿真时间0执行;而其他main/ run_phase是task phase,是任务phase,需要消耗时间。

  • 在build_phase出现了uvm_fatal宏,倘若被打印,完成打印后会直接调用Verilog的finish函数结束仿真。

  • condig_db机制介绍:

        uvm_config_db#(virtual avsbus_interface)::set(null,"*","vif",u_avsbus_if);*******************************************************************************************
        uvm_config_db#(virtual avsbus_interface)::get(this," ","vif",vif)
  1. config_db的set和get函数都有4个参数。它们的第3个参数必须完全一致,第4个参数,set的表示要传递给driver的interface是哪个,get的表示把接收到的interface传递给自己的哪个变量。set的第2个参数表示路径索引,也即uvm_test_top(top_tb中UVM-run_test创建的固定名实例)

  2. set和get函数都是静态函数,所以使用双冒号::。

  3. uvm_condig_db#(virtual avsbus_interface)是一个参数化的类,其参数(括号里的)就是要寄信的类型。

应用举例 

向my_driver的var变量传递一个int类型的数据

top_tb.v:

initial begin
    uvm_config_db#(int)::set(null,"*","var",100);
end
*******************************************************
my_driver.sv:

virtual function void build_phase(uvm_phase phase);
    super.build_phase(phase);
    if(!uvm_config_db#(int)::get(this," ","var",var))begin
        `uvm_fatal(get_type_name(),"VAR MUST BE SET!!!");
    end
endfunction



END.

`ifndef A_INTERFACE_SV
`define A_INTERFACE_SVinterface a_interface(input clk, input rst_n);
    logic a_ck;
    logic a_md;
    logic a_sd;

    logic [15:0] vout_avs_raila;
    logic [15:0] vout_avs_railb;
    logic [15:0] trans_rate_wh_raila;
    logic [15:0] trans_rate_wh_railb;
    logic bus_idle;
    logic cnt_resync;
    logic cmd_reset_vol_raila;
    logic cmd_reset_vol_railb;
    logic vdone_ra;    logic vdone_rb;
    logic ocw_ra;      logic ocw_rb;
    logic uvw_ra;      logic uvw_rb;
    logic otw_ra;      logic otw_rb;
    logic opw_ra;      logic opw_rb;
    bit check;

    clocking m_drv_cb @(posedge clk);        default input #1 output #1;
        input  a_md;
        output a_sd;
    endclocking
    clocking m_mon_cb @(posedge clk);        default input #1 output #1;
        input  a_sd;    endclocking

    mmodport M_DRV(clocking m_drv_cb);    mmodport M_MON(clocking m_mon_cb);
endinterfce
`endif




点赞

评论 (0 个评论)

facelist

您需要登录后才可以评论 登录 | 注册

  • 关注TA
  • 加好友
  • 联系TA
  • 5

    周排名
  • 0

    月排名
  • 0

    总排名
  • 1

    关注
  • 0

    粉丝
  • 0

    好友
  • 0

    获赞
  • 0

    评论
  • 0

    访问数
关闭

站长推荐 上一条 /1 下一条

小黑屋| 手机版| 关于我们| 联系我们| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2025-4-26 03:48 , Processed in 0.020798 second(s), 16 queries , Gzip On, MemCached On.

eetop公众号 创芯大讲堂 创芯人才网
返回顶部