(八)SV虚接口及包的使用

一、虚接口:

interface 简化了模块之间的连接,但是无法很好地适用于基于OOP的测试平台,无法在program  、class 中进行实例化,所以引入了虚接口,virtual interface的本质是指针,是指向interface的指针,即virtual interface是可以在class中实例化的数据类型,interface将测试平台与DUT分开,
virtual interface可以在TB的不同位置操纵一组虚拟信号,而不是直接操纵实际的信号。

//1.create DUT file counter.sv:
module counter(
	input  logic       resetn    ,
	input  logic 	   clk       ,
	input  logic [3:0] load_value,
	input  logic 	   load_valid,
	output logic [3:0] q
);

always_ff @(posedge clk or negedge resetn)
begin
	if(!resetn)
		q <= 4'd0;
	else if (load_valid)
		q <= load_value;
	else
		q <= q+1;
end
endmodule

//2.create interface file counter_if.sv: 
interface counter_if (input logic clk);
	logic 		load_valid;
	logic [3:0] load_value;
endinterface

//2.create transaction.sv:
class transaction;
	rand logic 		 load_valid;
	rand logic [3:0] load_value;
endclass

//4.create file driver.sv:
class driver;
	virtual counter_if vif;//声明虚接口的句柄
	transaction tr;
function new(input virtual counter_if vif);//形参也是虚接口
	this.vif=vif;
endfunction

task run (int n = 10);
for(int i=0;i<n;i++) 
begin
	tr=new();
	assert(tr.randomize());
	$display("tr.load_valid=%d,tr.load_value=%d", tr.load_valid, tr.load_value);
	@(posedge vif.clk) 
	begin
		vif.load_valid <= tr.load_valid;
		vif.load_value <= tr.load_value;
	end
end
endtask
endclass

//5.create tb_top.sv:
module tb_top;
	logic       clk;
	logic		rstn;
	logic [3:0] out;
	counter_if dutif(clk);//实例化接口
	driver my_driver;     //声明my_driver对象的句柄
	
initial begin
	my_driver=new(dutif);//使虚接口指向实例化的接口dutif
	repeat(2)@(posedge clk);
	@(posedge rstn);
	repeat(5)@(posedge clk);
	my_driver.run(20);
end

initial begin
	clk=1'b0; 
	forever #5 clk=~clk;
end

initial begin
	rstn=1; repeat(2)  @(posedge clk);
	rstn=0; repeat(5)  @(posedge clk);
	rstn=1; repeat(50) @(posedge clk);
	$finish;
end

counter u_counter (

	.resetn    (rstn			),
	.clk       (clk				),
	.load_valid(dutif.load_valid),
	.load_value(dutif.load_value),
	.q         (out				) 
);

endmodule

打印的随机结果:
tr.load_valid=0,tr.load_value= 4
tr.load_valid=0,tr.load_value=14
tr.load_valid=1,tr.load_value= 4
tr.load_valid=1,tr.load_value= 5
tr.load_valid=1,tr.load_value=11
tr.load_valid=1,tr.load_value= 4
tr.load_valid=0,tr.load_value=15
tr.load_valid=1,tr.load_value=12
tr.load_valid=1,tr.load_value=13
tr.load_valid=0,tr.load_value=12
tr.load_valid=1,tr.load_value= 6
tr.load_valid=0,tr.load_value=14
tr.load_valid=0,tr.load_value=12
tr.load_valid=1,tr.load_value=15
tr.load_valid=0,tr.load_value=14
tr.load_valid=1,tr.load_value= 6
tr.load_valid=0,tr.load_value= 9
tr.load_valid=1,tr.load_value= 7
tr.load_valid=1,tr.load_value= 5
tr.load_valid=1,tr.load_value= 7

说明:

  1. 实例化的接口必须正确连接到DUT
  2. 必须在类中用关键词virtual声明虚接口的句柄,并且有相应驱动
  3. 必须将virtual interface指向实例化的interface

二、包(package)

一、包

SV提供了一种在多个module、interface和program中共享parameter、data、type、task、function、class等的方法,包就是把相关的方法封装起来,也可以对类封装,将相关的类封装到一起,每个包分配单独的命名空间,这样对于不同的验证模块,有相同名字的类(这个类的内容和功能是不同的)也可以通过包来区别,sv中包不支持包含module、interface(会报错)。

包的定义:(关键词:package.....endpackage)

package regs_pkg;
`include "stimulator.sv"
`include "monitor.sv"
`include "checker.sv"
`include "env.sv"
endpackage

package arb_pkg;
`include "stimulator.sv"
`include "monitor.sv"
`include "checker.sv"
`include "env.sv"
endpackage

module arbiter_tb;
regs_pkg::monitor mon1 = new();
arb_pkg::monitor mon2 = new();
endmodule

说明:

  1. 上示代码,定义了regs_pkg、arb_pkg两个包,但其中包含的类的文件名和类的名字相同,当调用时需要用包的名字来指明调用的是哪个包的类。
  2. 包的命名一般要求要独一无二,便于区分命名空间。
package regs_pkg;
`include "regs_stm.sv"
`include "regs_mon.sv"
`include "regs_chk.sv"
`include "regs_env.sv“
endpackage

package arb_pkg;
`include "arb_stm.sv"
`include "arb_mon.sv"
`include "arb_chk.sv"
`include "arb_env.sv"
endpackage

module test_tb;
import regs_pkg::*;///regs_pkg中的所有元素都可以被当前文件直接调用
import arb_pkg::*;
regs_mon mon1= new();
arb_mon mon2 = new();
endmodule

说明:

  1. 在上示代码中,包的名字和类的文件名和名类的名字都不同时(代码风格文件名和类名一般相同),可以"import pkg_name::*"来导入pkg_name中包所有的类,因为类名不同,所以也可以直接引用。
  2. 包中可以定义类、静态方法和静态变量。
  3. 在包中include的文件的路径是默认路径,若包含的文件不在默认路径时,在编译时需要把文件相对路径包含进去,可以在Makefile中包含。在使用`include的关键词完成类在包中的封装,要注意编译的前后顺序来放置各个`include的类文件。

另:

  • generator产生这个激励数据 ,driver把激励加载到接口去驱动DUT,stimulator=generator+driver

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值