关键词不能为空

当前您在: 主页 > 英语 >

如何从零开始构建一个可用的UVM验证平台

作者:高考题库网
来源:https://www.bjmy2z.cn/gaokao
2021-02-08 19:56
tags:

-

2021年2月8日发(作者:nootbook)


如何从零开始构建一个可用的


UVM


验证平台< /p>








前面大体说明了

< br>uvm


的结构,类型关系以及启动过程。


现在最关心的大 概也就是


uvm


是如何把一串激励发送给被

测对象的了。


对于传统的基于


verilog


的验证平台,


基本套路


就是各种

module


中的


task


相互调 用,


最终把激励施加到顶


层模块例化的被测对象中,但是具体步 骤各个团队又有挺大


差异。基于


UVM


的平台,本质其实也是这样,但是它把各


种调用关系进行了更严格的限定,


所以所有使用


uvm


的团队,


实现的验证平台都更加相似。下面以之前的


apb/spi


接 口为


例具体讲解一下。这里把之前的图再贴过来一下。之前已经


说过有关


sequencer,driver,monitor,env


等的大体功能,


这些


可以被认为是验证平台的硬体,除 此之外,还有一些在这之


间流动的软体需要近一步说明一下。


u vm_sequence_item



是这种软体最基本的构造 单元。比如可以定义


apb


端的


seq uence_item,


其中包括读写信息,数据地址这些成员。


class apb_transfer extendsuvm_sequence_item;






















rand bit[31:0]











addr;




randapb_direction_enum



direction;




rand bit[31:0]











data;




rand intunsigned









delay = 0;





constraint c_direction { direction inside {APB_READ,


APB_WRITE }; }





constraint c_delay { delay



//


这里需要将其中的变量注册一下,这些后边具体讲





`uvm_object_utils_begin(apb_transfer)





`uvm_field_int(addr, UVM_DEFAULT)





`uvm_field_enum(apb_direction_enum, direction,


UVM_DEFAULT)





`uvm_field_int(data, UVM_DEFAULT)




`uvm_object_utils_end



function new (string name


='apb_transfer');





(name);




endfunction


//


对其他方法没有进行特别的设定



endclass : apb_transfer



uvm_sequence_item


稍微高一层


极的信息单元是


uvm_sequence


,这个可以认为是 一连串的


uvm_sequence_item


,可以表达一个 完整的操作,下面是读


fifo


的一个例子。

< br>class read_rx_fifo_seq extends


uvm_sequence#(apb_pkg::apb_transfer); < /p>


//


此类从


uvm_sequence< /p>


派生得到,


uvm_sequence


是 一个


参数化的类,这里类型赋值为


apb_transfer< /p>


,它被定义在


apb_pkg


这个包中< /p>







functionnew(string name='read_rx_fifo_seq');







(name);





endfunction





// Registersequence with a sequencer





`uvm_object_utils(read_rx_fifo_seq)





rand bit[31:0]


read_addr;






rand intunsigned del = 0;






rand intunsigned num_of_rd;






constraintnum_of_rd_ct { (num_of_rd







constraintdel_ct { (del







constraintaddr_ct {(read_addr[1:0] == 0); }


//


一个


sequence


最重要的行为就是


body


,里边定义这个信


息序列都发送什么东西

< p>






virtual taskbody();







`uvm_info(get_type_name(), $$sformatf('Starting


Reads...',num_of_rd), UVM_LOW)







response_queue_error_report_disabled = 1;






for


(int i = 0; i










read_addr =`RX_FIFO_REG;






//rx fifo address











`uvm_do_with(req,













{ == read_addr;















ion == APB_READ;















== del; } )







end





endtask



//uvm_do_with


这个宏负责把各个最基本的


sequence_item


加上约束发送出去。



endclass : read_rx_fifo_seq


如 何把这个


sequence


发送出去


呢 ?这就需要在


testcase


里边把这个

sequence


通过


sequencer


发出去。


class read_rx_fifo_test extends


uvm_test;



`uvm_component_utils(read_rx_fifo_test)



spi_apb_env spi_apb_env_0;//test


中例化


env



function


new(string name ='read_rx_fifo_test',





uvm_component parent=null);





(name,parent);




endfunction : new



virtual function void


build_phase(uvm_phasephase);





_phase(phase);





spi_apb_env_0 =


spi_apb_env::type_id::create('spi_apb_env_0',this) ;




endfunction : build_phasevirtual




taskmain_phase(uvm_phase phase);





_phase(phase);


//


执行基类的任务










read_rx_fifo_seq_inst


=read_ rx_fifo_seq::type_id::create('read_rx_fifo_seq_ins t',t


his);


//


产生一个


seq









rea d_rx_fifo_seq_(spi_apb_env__agent_


b_sqr );


//



seq

< br>通过


sqr


发送






endtaskendclass : read_rx_fifo_testsequ encer


得到了这


个序列,就要把它交给

driver


,然后


driver


把其中的信息元


素放置到与


dut


连接 的接口上。这样就将需要的激励施加给


了被测对象。


class apb_master_driver extends uvm_driver


#(apb_transfer);



//


连接


driver



dut


的虚接口


.




virtual apb_if vif;





function new (string name, uvm_componentparent);





(name, parent);




endfunction : new



//


在外部定义以下任务





extern virtual function voidbuild_phase(uvm_phase


phase);




extern virtual function voidconnect_phase(uvm_phase


phase);




extern virtual task run_phase(uvm_phasephase);




extern virtual protected taskget_and_drive();




extern virtual protected task drive_transfer(apb_transfer


trans);




extern virtual protected taskdrive_address_phase


(apb_transfer trans);




extern virtual protected task


drive_data_phase(apb_transfer trans);endclass :


apb_master_driverfunction void

< br>apb_master_driver::connect_phase(uvm_phasephase );




t_phase(phase);




if (!uvm_config_db#(virtual apb_if)::get(this,'', 'vif', vif))





`uvm_error('NOVIF',{'virtual interface must be set


for:',get_full_name(),'.vif'})

< br>//


将虚接口通过配置从顶层取出来,并赋值给


vif


endfunction : connect_phasetask


apb_master_driver::run_phase(uvm_phase phase);




get_and_drive();


endtask : run_phase//


在执行时一直在从


sqr

< p>


item


并且赋


值给< /p>


vif


task apb_master_driver::get_and_drive();




while (1) begin






fork

-


-


-


-


-


-


-


-



本文更新与2021-02-08 19:56,由作者提供,不代表本网站立场,转载请注明出处:https://www.bjmy2z.cn/gaokao/616619.html

如何从零开始构建一个可用的UVM验证平台的相关文章