uvm testbench简介(作用,结构以及搭建步骤)
参考资料:
(1) 《uvm cookbook》;
(2) 公众号-芯片学堂;
(3) 《uvm user guide》;
(4) 从run_test浅谈Test Bench的启动 (qq.com)
(5) 《practical UVM step by step with IEEE》第二章;
1.uvm tb
1.1 uvm tb作用
(1) 实例化DUT模块以及UVM Test class(通过在tb.sv的initial begin-end块内调用run_test函数实现);
(2) 实现DUT与验证环境的连接(interface binding以及uvm_config_db::set(), uvm_config_db::get());
(3) 时钟产生(复位信号由UVM testbench提供);
注1:需要指明timescale;
注2:时钟生成放到module内部实现,不要在testbench中产生时钟;(《practical UVM step by step with IEEE》2.7章)
1 //tb.sv 2 module tb; 3 my_if input_if(clk, rst_n, **); 4 my_if output_if(clk, rst_n, **); 5 6 dut my_dut(.clk(clk), .rst_n(rst_n), 7 .rxd(input_if.data), .rx_dv(input_if.valid), 8 .txd(output_if.data), .tx_en(output_if.valid), 9 ); 10 11 initial begin 12 run_test(); 13 end 14 15 initial begin 16 uvm_config_db #(virtual my_if)::set(**); 17 uvm_config_db #(virtual my_if)::set(**); 18 end 19 endmodule
1 //top-level testbench; 2 module wb_env_top_mod(); 3 logic clk; 4 parameter sim_cycle=10; 5 parameter rst_delay=5; 6 7 initial begin 8 clk=0; 9 forever clk=#(sim_cycle/2) ~clk; 10 end 11 12 wb_master_if mast_if(clk); 13 wb_slave_if slave_if(clk); 14 15 wb_env_tb_mod test(); 16 dut dut(mast_if, slave_if); 17 18 endmodule: wb_env_top_mod
1 `include "wb_test.pkg" 2 module wb_env_tb_mod; 3 import uvm_pkg::*; 4 import wb_tests::*; 5 6 typedef virtual wb_master_if v_if1; 7 typedef virtual wb_slave_if v_if2; 8 9 initial begin 10 uvm_config_db #(v_if1)::set(null, "uvm_test_top.env.rst_agent", "mst_if", wb_env_top_mod.mast_if); 11 uvm_config_db #(v_if1)::set(null, "uvm_test_top.env.master_agent", "mst_if", wb_env_top_mod.mast_if); 12 uvm_config_db #(v_if2)::set(null, "uvm_test_top.env.slave_agent", "slv_if", wb_env_top_mod.slave_if); 13 run_test(); 14 end 15 16 endmodule: wb_env_tb_mod
1.2 uvm tb框图
2.two top level module testbench(hdl_top & hvl_top)
(1) hdl_top包含interface和DUT;
(2) hvl_top包含启动uvm验证平台的initial begin-end块;
注:详见uvm cookbook;
3.uvm tb搭建具体步骤(需要有如下环节,但顺序可能有所不同)
3.1构建transaction
(1) 作用: DUT激励;
(2) 派生关系: UVM class library提供uvm_sequence_item基类(uvm_sequence_item派生于uvm_transaction);每一个user-defined data item都应该直接或间接派生于uvm_sequence_item;
(3) 创建user-defined transaction:
(3.1) 根据DUT transaction spec,弄清楚专用的约束、任务与函数;
(3.2) 从uvm_sequence_item基类或其派生类构建新的派生类;
(3.3) 定义构造函数;
(3.4) 为transaction类添加成员变量;
(3.5) 使用uvm field宏以便于直接使用print, copy, compare等函数;
(4) 示例
3.2 构建sequence & virtual sequence
详见seq部分文档(声明seq&启动seq);
3.3 构建sequencer & virtual sequencer
详见sequencer部分文档;
3.4 构建driver
(1)作用:从sequencer获取data item,然后按照接口协议把data item驱动到总线上;
(2)派生关系:UVM类库提供uvm_driver基类,所有的driver类都应该直接或间接的派生自uvm_driver;
(3)创建
(3.1) 从uvm_driver类派生;
(3.2) 使用UVM field automation机制实现print, copy, compare等函数的自动定义;
(3.3) 获取来自sequencer的下一个data item;
(3.4) 在driver中声明一个virtual interface,为了实现driver与DUT的连接;
(4)示例
3.5 构建monitor
(1)作用:负责从bus上提取信号信息,转换成事件,数据和状态信息,然后通过TLM port将信息传递给其他uvc;
(2)示例:
3.6 构建agent
(1)作用:实例化driver, monitor, sequencer并采用TLM port实现其连接(为了提高灵活性, agent也会包含配置信息以及其他参数);
(2) 工作模式(active mode与passive mode)
(2.1) active mode: agent需要实例化driver, sequencer, monitor;
(2.2) passive mode: agent不需要实例化driver,sequencer,仅仅需要实例化monitor;
(3) 示例
3.7 实现check与coverage收集
(1) assertion check示例
(2) 函数check示例
(3) 功能覆盖率的收集
(3.1) 功能覆盖率的收集是通过sv的covergroup实现的; covergroup的关键在于coverpoint与bin的确定以及什么时候收集覆盖率;
3.8 构建env
(1)作用:可复用组件的容器,它实例化并配置所有的子组件;
(2)示例:
3.9 构建test
篇?-uvm_test - 蚕食鲸吞 - 博客园 (cnblogs.com)