目录
1.env集成了其他component,对于简单的模块,一个env就可以组成一个完整的tb。
2.env通过配置可以重用于复杂的验证环境,例如agt的active和passive;
1.uvm_test派生自uvm_component类,没有增加新的功能。
2.testcase中实例化和配置env,使env模拟不同的测试环境不同的测试行为;
1.如何实现UT环境到IT环境的重用?(单元级→多个单元级)
4.run_test()和+UVM_TEST_NAME=的case参数不同时,最终会执行哪个case?
1.uvm_env
1.env集成了其他component,对于简单的模块,一个env就可以组成一个完整的tb。
2.env通过配置可以重用于复杂的验证环境,例如agt的active和passive;
3.代码示例
`ifndef _GUARD_HELLO_ENV_SV_
`define _GUARD_HELLO_ENV_SV_ //两句连用,防止重复编译(C语言内容)
class hello_env extends uvm_agent;
hello_agent input_agt;
hello_agent output_agt;
hello_model my_hello_model;
hello_scoreboard mmy_hello_scb;
//env内例化i_agt,o_agt,reference_model,scoreboard
uvm_tlm_analysis_fifo #(hello_transaction) agt_scb_fifo;
uvm_tlm_analysis_fifo #(hello_transaction) agt_mdl_fifo;
uvm_tlm_analysis_fifo #(hello_transaction) mdl_scb_fifo;
//声明三个fifo端口
extern function new(string name,uvm_component parent);
extern virtual function void build_phase(uvm_phase phase);
extern virtual function void connect_phase(uvm_phase phase);
`uvm_component_utils(hello_env) //uvm 工厂机制 宏注册
endclass
function hello_env::new(string name,uvm_component parent)
super.new(name,parent);
endfunction
//执行uvm_env的构造函数
function void hello_env::build_phase(uvm_phase phase)
super.build_phase(phase);
input_agt = hello_agent::type_id::create("input_agt",this);
output_agt = hello_agent::type_id::create("output_agt",this);
input_agt.is_active = UVM_ACTIVE;
output_agt.is_active = UVM_PASSIVE;
my_hello_model = hello_model::type_id::create("my_hello_model",this);
mmy_hello_scb = hello_scoreboard::type_id::create("my_hello_scb",this);
agt_scb_fifo = new("agt_scb_fifo",this);
agt_mdl_fifo = new("agt_mdl_fifo",this);;
mdl_scb_fifo = new("mdl_scn_fifo",this);;
endfunction
function void hello_agent::connect_phase(uvm_phase phase);
super.connect_phase(phase);
input_agt.ap.connect(agt_mdl_fifo.analysis_export);
my_hello_model.port.connect(agt_mdl_fifo.blocking_get_export);
my_hello_model.ap.connect(mdl_scb_fifo.analysis_export);
my_hello_scb.exp_port.connect(mdl_scb_fifo.blocking_get_export);
output_agt.ap.connect(agt_scb_fifo.analysis_export);
my_hello_scb.act_port.connect(agt_scb_fifo.blocking_get_export);
endfunction
注意:虽然在env中没有声明ap,但是在之前的mon中声明过了,所以可以直接使用
2.uvm_test
1.uvm_test派生自uvm_component类,没有增加新的功能。
2.testcase中实例化和配置env,使env模拟不同的测试环境不同的测试行为;
3.代码示例
`ifndef _GUARD_HELLO_BASE_TEST_SV_
`define _GUARD_HELLO_BASE_TEST_SV_ //两句连用,防止重复编译(C语言内容)
class hello_base_test extends uvm_test
hello_env env;
extern virtual function new(string name,uvm_component parent);
extern virtual function void build_phase(uvm_phase phase);
extern virtual function void start_of_simulation_phase(uvm_phase phase);
//???????????????????????????????????????????????????????????????????????????????
extern virtual function void build_phase(uvm_phase phase);
`uvm_component_utils(hello_base_test) //uvm 工厂机制 宏注册
endclass
function hello_sequencer::new(string name="hello_base_test",uvm_component parent=null)
super.new(name,parent);
endfunction
//执行base_test的new函数
function void hello_model::build_phase(uvm_phase phase)
super.build_phase(phase);
env = hello_env::type_id::create("env",this);
endfunction
function hello_base_test::start_of_simulation_phase(uvm_phase phase)
super.start_of_simulation_phase(phase);
uvm_top.print_topology(uvm_default_tree_printer) //打印uvm树形结构
endfunction
function void hello_base_test::report_phase(uvm_phase phase);
uvm_report_server server;
int err_num;
super.report_phase(phase);
server = get_report_server();
err_num = server.get_severity_count(UVM_ERROR);
if (err_num != 0) begin
$display("TEST CASE FAILED");
else begin
$display("TEST CASE PASSED");
end
endfunction
通过base_test衍生出其他testcase
3.总结
1.如何实现UT环境到IT环境的重用?(单元级→多个单元级)
UT——单元级验证(例如单独的uart模块或apb协议)
IT ——集成级验证(例如利用APB访问UART)
将子模块的env当做更高一级模块的uvc进行复用
2.连接组件必须在connect_phase(env)执行吗?
不一定。可以在test_case中进行连接。但是一般在connect_phase中进行。通常来讲,一个组件的连接在其父类(上一级)中已经完成,为了避免跨节点去处理任务,不建议在其他地方进行connect。
3.为什么需要实现一个base_test?
base_test可以完成组件的连接、信息打印、设置信息冗余度、仿真时间等。其余的case继承于base_test,节省代码量。
4.run_test()和+UVM_TEST_NAME=的case参数不同时,最终会执行哪个case?
命令行语言会覆盖run_test()命令,这样只需要一次编译,可以节省时间。
5.fifo和imp通信方式的选择
在用FIFO时,完全隐藏了imp,这是uvm特有的,我们在用时就不需要完全去关心imp,只需要知道analysis_port,blocking_get_port就可以了,尤其是在scoreboard面临多个imp时。
不过FIFO连接增加了env代码的复杂性,尤其是当连接的端口数量众多时。不过对于端口数组,fifo要优于imp,fifo可以利用for循环进行连接,而ap与imp只能端对端的直接连接,他们实现的目标是一样的,所以自己习惯哪一种,就用哪一种