文档库

最新最全的文档下载
当前位置:文档库 > 利用Systemverilog+UVM搭建SOC及ASIC的RTL验证环境

利用Systemverilog+UVM搭建SOC及ASIC的RTL验证环境

基于SV+UVM搭建SOC/ASIC验证平台

UVM-1.1中提供了一个UBUS的例子,但是该例子对于刚刚入门的人来说还是需要一定时间去消化的,本文对该例子进行一步一步的简化,可以帮助理解。

[1-11]如何顺序的写UVM平台(1)-Basic

[1-

1.平台可以在前期规划好,但是对于搭建平台的人来说,调试永远是最大的问题,如果都

将一个个component都写完了,调试起来还是有点痛苦的,所以我更倾向于一步一步的调试平台;先写一个可以pass的基本平台,然后在不断的扩展该平台,最后在各个component中加入所需要的function或者task。当然,当对搭建平台数量以后,现在基本对平台中的component一次性搭建完成,然后调试并添加需要的function或者task即可。

2.最简单的UVM平台,一个interface,一个DUT,一个TOP,一个test,一个ENV就

可以工作了,然后慢慢的添加各个component;

3.写interface

4.写top module,在top中例化DUT,interface和DUT在top中include

利用Systemverilog+UVM搭建SOC及ASIC的RTL验证环境

uvm_config_db#(virtual ubus_if)::set(uvm_root::get(),"*","vif",vif);

run_test();

5.写Makefile,此时编译可以通过

利用Systemverilog+UVM搭建SOC及ASIC的RTL验证环境

6.写自定义的package,然后在top中include该package

利用Systemverilog+UVM搭建SOC及ASIC的RTL验证环境

typedef uvm_config_db#(virtual ubus_if)ubus_vif_config;

typedef virtual ubus_if ubus_vif;

后来证明,这两句话在ubus的env中根本没有用上;

7.定义Environment,并将该文件加入到自定义的package中,这个时候编译不能通过

利用Systemverilog+UVM搭建SOC及ASIC的RTL验证环境

此处的get和top中的set是一对,如果top中没有set则会报告·uvm_fatal中的错误if(!uvm_config_db#(virtual ubus_if)::get(this,"","vif",vif))

`uvm_fatal("NOVIF",{"virtual interface must be set for: ",get_full_name(),".vif"});

8.定义base_test,需要在top中include该test文件,并在makefile中加入编译该test的

命令;此时可以再次编译通过,并运行最basic的testcase

利用Systemverilog+UVM搭建SOC及ASIC的RTL验证环境

利用Systemverilog+UVM搭建SOC及ASIC的RTL验证环境

编译第一次通过

总结一:在一个芯片的验证平台中,总会给一个最basic 的base_test ,但是可能每个人负责验证的部分是不一样的,比如说我要验证USB ,那我一定会从base_test 中派生一个usb_base_test 来给自己用,这样我可以在usb_base_test 加入任何我想要的函数,而不会影响到其他人。

总结二:如何从test 中传递参数到top_tb,如果用uvm_config_db 在base_test 中设置变量的值,那么这些变量在environment/agent/dirver 等等中可以get 到的,但是在top_tb 中不能get 到的?采用下面的方式就可以

uvm_config_db #(int)::set(null,"uvm_test_top","set_#(int)::set(null,"uvm_test_top","set_usb usb usb_single_test",1);

_single_test",1);总结三:需要注意的是,不要把定义interface 的文件include 在package 中,这会导致编译不过的。

总结四:uvm_report_info和宏`uvm_info在用法是没有区别的,都是用来打印消息的。

[1-22]如何顺序的写UVM平台(2)-MasterAgent

[1-

9.定义sequence item,注意,一种类型的transaction需要对应一个driver;

`uvm_object_utils_begin(ubus_transfer)

`uvm_field_int(addr,UVM_DEFAULT)

`uvm_field_enum(ubus_read_write_enum,read_write,UVM_DEFAULT)

`uvm_field_int(size,UVM_DEFAULT)

`uvm_field_array_int(data,UVM_DEFAULT)

`uvm_field_array_int(wait_state,UVM_DEFAULT)

`uvm_field_int(error_pos,UVM_DEFAULT)

`uvm_field_int(transmit_delay,UVM_DEFAULT)

`uvm_field_string(master,UVM_DEFAULT|UVM_NOCOMPARE)

`uvm_field_string(slave,UVM_DEFAULT|UVM_NOCOMPARE)

`uvm_object_utils_end

利用Systemverilog+UVM搭建SOC及ASIC的RTL验证环境

需要思考哪些内容需要在transaction中定义?

10.定义好了transaction,就可以开始定义base sequence了;注意,在base_sequence的

pre_body和post_body中定义raise_objection和drop_objection是很有好处的;将base

sequence定义成虚基类,只有派生后才能进行实例化;

利用Systemverilog+UVM搭建SOC及ASIC的RTL验证环境

11.派生sequence;先派生出一个sequence用于平台调试

利用Systemverilog+UVM搭建SOC及ASIC的RTL验证环境

12.用了sequence,就该写sequencer了;sequencer是整个环境中最简单的部分;

利用Systemverilog+UVM搭建SOC及ASIC的RTL验证环境

在driver中一定要get interface,因为driver直接和DUT做交互;

利用Systemverilog+UVM搭建SOC及ASIC的RTL验证环境

14.注意在driver中如何写get sequence:

利用Systemverilog+UVM搭建SOC及ASIC的RTL验证环境

15.有了sequencer,driver,实际上就可以定义master agent了,在agent中要实现dirver和

sequencer的连接

利用Systemverilog+UVM搭建SOC及ASIC的RTL验证环境

16.Agent实现了之后,就需要在env中例化

利用Systemverilog+UVM搭建SOC及ASIC的RTL验证环境

的数量;

利用Systemverilog+UVM搭建SOC及ASIC的RTL验证环境

但是一直会出现如下错误:make test_read_byte

利用Systemverilog+UVM搭建SOC及ASIC的RTL验证环境

可以正确的通过,但是此时平台中没有数据的流动,需要debug;

利用Systemverilog+UVM搭建SOC及ASIC的RTL验证环境

20.打开上面的屏蔽,到read_byte_seq中去,将task body()屏蔽掉也可以pass

利用Systemverilog+UVM搭建SOC及ASIC的RTL验证环境

21.到目前为止,该平台中有ENV,agent,driver,sequencer,sequence,transaction了,

可以进行最基本的test操作了,但是还需要monitor,scoreboard等等;

总结一:driver(sequencer也是)是和发送的sequence类型有关的,也就是一个driver 要发送的sequence的类型是固定死了的,那么我们需要将多种类型的sequence通

过一个driver来发送要怎么办?其实将多种类型的sequence不要做成sequence,做

成uvm_object,然后在一个大的uvm_object中random这些小的uvm_object(就是

小的sequence),然后用这个最大的uvm_object来做sequence_item就对了。

总结二:sequence_item中要具备哪些内容呢?严格的说是你当前module所要用到的所用data flow的数据类型。

总结三:别忘记在driver中get interface。

[1-

[1-33]如何顺序的写UVM平台(3)-Master Monitor

22.编写master_monitor;该component的主要作用是收集driver发出的各种数据类型的

coverage。然后需要在agent中例化

利用Systemverilog+UVM搭建SOC及ASIC的RTL验证环境

23.在agent中对master的monitor进行例化之后,master的部分就已经完成;

利用Systemverilog+UVM搭建SOC及ASIC的RTL验证环境

24.到目前为止,平台能动,但是没有sequence在里面流动,所以时间是没有动的;需要

在目前现有的资源下解决这个问题?这是因为在sequence中没有打开`uvm_do_*相关的函数;打开后时钟就开始动了,但是停止不下来,需要进一步debug

利用Systemverilog+UVM搭建SOC及ASIC的RTL验证环境

25.如何让平台停止下来呢?不能够停止是因为有一根信号没有驱动,导致一直等待

利用Systemverilog+UVM搭建SOC及ASIC的RTL验证环境

26.在top中对该信号进行驱动后,该平台就能自动停止了

利用Systemverilog+UVM搭建SOC及ASIC的RTL验证环境

[1-44]如何顺序的写UVM平台(4-1)-Slave Agent

[1-

27.前面完成了该平台最基本的部分工作,这个时候这个平台会有一些动作了,但是还需要

定义更多的东西,比如总线测试需要master和slave,DMA测试需要slave model,DDR 控制器测试需要slave model,SPI/UART/IIC/IIS/PCIE等都需要另外的model,我更倾向于model和验证方法学是独立开来的,这样在从一种验证方法学切换到另外一个验证方法学后不需要修改model,比如像micron提供的DDR model和NND model都是独立于验证方法学的;当然对于ubus总线测试则无所谓,因为整个DUT外面的东西都是不固定的;当然,如果能让slave固定则最好。

28.Slave driver的作用是返回Response,那么这个response的内容是从slave的sequencer

中来的,而sequencer的item则来自slave sequence lib,所以需要首先写slave的sequence;slave有两种sequence,第一种返回读写类型,第二种返回地址和数据等;

29.先编写sequence,在package中include,编译可以通过;

利用Systemverilog+UVM搭建SOC及ASIC的RTL验证环境

30.编写slave_sequencer,在package中include,注意,并没有地方例化它,编译可以通过

利用Systemverilog+UVM搭建SOC及ASIC的RTL验证环境

31.编写slave_agent,并在slave_agent中例化sequencer,在package中include,注意,并

没有地方例化这个agent,编译可以通过

利用Systemverilog+UVM搭建SOC及ASIC的RTL验证环境

32.然后需要做一系列动作,来设置slave的数量,并在env中例化slave_agent;

利用Systemverilog+UVM搭建SOC及ASIC的RTL验证环境

33.出现在slave部分,目前只有agent,sequencer,sequence,出现如下错误;

UVM_ERROR@0: uvm_test_top.ubus_example_tb0.ubus0.slaves[0].sequencer.addr_ph_port[Connection Error] connection count of0does not meet required minimum of1

这是因为在sequencer中声明了一个TLM port,但是一直没有连接它,所以需要屏蔽掉才可以;

利用Systemverilog+UVM搭建SOC及ASIC的RTL验证环境

34.完成上面的修改后,可以得到下面的结果:

利用Systemverilog+UVM搭建SOC及ASIC的RTL验证环境

利用Systemverilog+UVM搭建SOC及ASIC的RTL验证环境

利用Systemverilog+UVM搭建SOC及ASIC的RTL验证环境

[1-[1-5

5]如何顺序的写UVM 平台(4-2)-Slave Driver 35.Slave driver 的作用是针对master 的读写访问返回数据或者响应;当然还要驱动slave 方面该驱动的信号,首先需要获得Virtual interface 。然后获得slave_sequence_lib 中的sequence 并驱动到总线上;

利用Systemverilog+UVM搭建SOC及ASIC的RTL验证环境

36.驱动总线这个地方还是有点不明白?resp获得到写的数据后会存放起来吗?待解决,这

个确实会存放起来,在ubus_slave_req_lib.sv中的slave_memory_seq中的post_do函数

中可以看到。

利用Systemverilog+UVM搭建SOC及ASIC的RTL验证环境

连接起来;在package中include ubus_slave_driver.sv;此时slave并不会发送任何数据

出来,因为没有在test中设置default sequence;

利用Systemverilog+UVM搭建SOC及ASIC的RTL验证环境

38.我们需要让slave动起来,因为我们的case是读操作,那么就需要slave提供需要,所

以需要在slave_sequence_lib.sv中加入一个memory的sequence;在pre_do中将要读取的数据准备好,在post_do中将写入的数据存起来;

利用Systemverilog+UVM搭建SOC及ASIC的RTL验证环境

39.在task body中将sequencer中的trans peek出来,不知道有什么用处,但是这个地方得

到的req又是通过sequencer发送给driver的,需要更多的理解;

利用Systemverilog+UVM搭建SOC及ASIC的RTL验证环境

40.既然有了读写返回的sequence,就可以再test中设置slave的默认sequence了;

read_modify_write_seq::type_id::get());

uvm_config_db#(uvm_object_wrapper)::set(this,

"ubus_example_tb0.ubus0.slaves[0].sequencer.run_phase",

"default_sequence",

slave_memory_seq::type_id::get());

设置后出现如下错误:

ncvlog:*E,NOIPRT(ubus_slave_seq_lib.sv,31|49):Unrecognized declaration 'ubus_slave_sequencer'could be a spelling mistake[SystemVerilog].

(`define macro:uvm_declare_p_sequencer [/home/dengf/uvm-1.1/src/macros/uvm_sequence_defines.svh line446],`include file: ubus_slave_seq_lib.sv line31,`include file:ubus_pkg.sv line12,file:ubus_tb_top.sv line5)

利用Systemverilog+UVM搭建SOC及ASIC的RTL验证环境

在package中将sequencer的顺序调整到seq_lib的前面即可。

41.另外seq中用到了sequencer中的addr_ph_port,所以需要将原来的屏蔽打开,并且需要

连接addr_ph_port才可以;但是目前的monitor还没写好,所以先屏蔽掉所有用到这个port的地方吧,屏蔽后编译通过,但是出现如下错误:

UVM_INFO@0: uvm_test_top.ubus_example_tb0.ubus0.masters[0].sequencer@@read_byte_seq

[uvm_test_top.ubus_example_tb0.ubus0.masters[0].sequencer.read_byte_seq]sequence is okay

now,please FIXME.

UVM_INFO@150:uvm_test_top.ubus_example_tb0.ubus0.masters[0].driver [uvm_test_top.ubus_example_tb0.ubus0.masters[0].driver]enter get_and_drive.

Error!NULL pointer dereference

File:./ubus_slave_seq_lib.sv,line=38,pos=30

Scope:worklib.ubus_pkg::slave_memory_seq@8242_5.pre_do

Time:160NS+2

问题的原因就是在sequence中没有port来get到现有的sequence,所以需要重新例化一个,写一个util_transfer的new函数即可;

利用Systemverilog+UVM搭建SOC及ASIC的RTL验证环境

42.后面,testcase不能结束,问题的原因需要debug;问题的原因是在slave_sequence_lib.sv

中的task body中在forever begin。。。end中调用了starting_phase.raise_objection和starting_phase.drop_objection,将forever去掉后,能正确的结束,但是想想slave正常的工作吗?整个平台后来又是怎么停止的呢?拭目以待吧

利用Systemverilog+UVM搭建SOC及ASIC的RTL验证环境

[1-66]如何顺序的写UVM平台(4-3)-Slave Monitor [1-

43.个人觉得slave monitor和master monitor一个就足够了,我不知道为什么这个地方需要

用两个,因为看起来都是对coverage做统计而已;另外,monitor中有一个peek函数,这个函数是在seq_lib中,用来将monitor收到的trans送入到seq_lib中存储用的,采用的是addr_ph_port进行通信;

利用Systemverilog+UVM搭建SOC及ASIC的RTL验证环境

利用Systemverilog+UVM搭建SOC及ASIC的RTL验证环境

需要打开sequencer中屏蔽的addr_ph_port,并在seq_lib.sv中采用addr_ph_port来get transaction,而不是自己采用一个new()的构造函数;还要将sequencer的addr_ph_port 和monitor的addr_ph_imp连接起来;将slave_seq_lib中的slave_mem_seq中的task body

中的forever加上;

利用Systemverilog+UVM搭建SOC及ASIC的RTL验证环境

event,就不会raise_objection。