UVM复位测试方法有两种方法。第一种方法是自己写复位函数,将环境返回到初始状态。第二种方法是调用环境的uvm 的reset_phase 进行自动复位,但是如何触发跳转很关键,否则会导致死循环。
方案一:
step1 . 修改driver
class cpu_driver extends uvm_driver#(cpu_tr);
virtual task run_phase(uvm_phase phase);
@(posedge vif.rst_n);
get_and_driver();
reset_signals(); //使用该 task对环境进行复位处理。
endtask
virtual task get_and_driver();
...
endtask
vitual task reset_signals();
forever begin
@(negedge vif.rst_n);
// disable task ,顺序从里到外disable
#0; disable driver_transfer;
#0; disable get_and_driver;
vif.cpu_re <= #`DLY 'h0;
vif.cpu_we <= #`DLY 'h0;
vif.cpu_addr <= #`DLY 'h0;
vif.cpu_rdata <= #`DLY 'h0;
@(posedge vif.rst_n);
fork
get_and_driver();
join_none;
end
endtask
endclass
step2 修改monitor
class cpu_monitor extends uvm_monitor;
virtual task run_phase(uvm_phase phase);
@(posedge vif.rst_n);
collect_tansaction();
reset_signals(); //使用该 task对环境进行复位处理。
endtask
vitual task reset_signals();
forever begin
@(negedge vif.rst_n);
// disable task ,顺序从里到外disable
#0; collect_tansaction;
@(posedge vif.rst_n);
fork
collect_tansaction();
join_none
end
endtask
endclass
step3 修改checker
checker和上述类似
virtual task run_phase(uvm_phase phase);
check_cmd();
reset_signals();
endtask
vitual task reset_signals();
forever begin
@(negedge vif.rst_n);
// disable task ,顺序从里到外disable
#0; check_cmd;
//delete队列, 清掉全局变量的值 .....
@(posedge vif.rst_n);
fork
check_cmd();
join_none
end
endtask
方案二:UVM可以通过jump方法让环境跳到reset_phase。
virtual task run_phase(uvm_phase phase);
fork
begin
@(posedge vif.rst_n);
get_and_driver();
end
begin
@(negedge vif.rst_n);
phase.jump(uvm_reset_phase::get());
end
join
endtask
该方法rst_n的下降沿无法用sequence发激励来实现。只能明确一个时间点,在top中用force进行复位。因为如果是在sequence中进行复位,每次复位之后会从reset_phase进入main_phse, sequence重新启动发送复位激励,就会导致死循环。