首页 > 代码库 > *2.2.3 加入objection机制
*2.2.3 加入objection机制
在上一节中,虽然输出了“main_phase is called”,但是“data is drived”并没有输出。而main_phase是一个完整的任务,没有理由只执行第一句,而后面的代码不执行。看上去似乎main_phase在执行的过程中被外力“杀死”了,事实上也确实如此。
UVM中通过objection机制来控制验证平台的关闭。细心的读者可能发现,在上节的例子中,并没有如2.2.1节所示显式地调用finish语句来结束仿真。但是在运行上节例子时,仿真平台确实关闭了。在每个phase中,UVM会检查是否有objection被提起(raise_objection),如果有,那么等待这个objection被撤销(drop_objection)后停止仿真;如果没有,则马上结束当前phase。
加入了objection机制的driver如下所示:
代码清单 2-9 文件:src/ch2/section2.2/2.2.3/my_driver.sv 13 task my_driver::main_phase(uvm_phase phase); 14 phase.raise_objection(this); 15 `uvm_info("my_driver", "main_phase is called", UVM_LOW); 16 top_tb.rxd <= 8‘b0; 17 top_tb.rx_dv <= 1‘b0; 18 while(!top_tb.rst_n) 19 @(posedge top_tb.clk); 20 for(int i = 0; i < 256; i++)begin 21 @(posedge top_tb.clk); 22 top_tb.rxd <= $urandom_range(0, 255); 23 top_tb.rx_dv <= 1‘b1; 24 `uvm_info("my_driver", "data is drived", UVM_LOW); 25 end 26 @(posedge top_tb.clk); 27 top_tb.rx_dv <= 1‘b0; 28 phase.drop_objection(this); 29 endtask
在开始学习时,读者可以简单地将drop_objection语句当成是finish函数的替代者,只是在drop_objection语句之前必须先调用raise_objection语句,raise_objection和drop_objection总是成对出现。加入objection机制后再运行验证平台,可以发现“data is drived”按照预期输出了256次。
raise_objection语句必须在main_phase中第一个消耗仿真时间的语句之前。
如$display语句是不消耗仿真时间的,这些语句可以放在raise_objection之前,但是类似@(posedge top.clk)等语句是要消耗仿真时间的。
按照如下的方式使用raise_objection是无法起到作用的:
代码清单 2-10 task my_driver::main_phase(uvm_phase phase); @(posedge top_tb.clk); phase.raise_objection(this); `uvm_info("my_driver", "main_phase is called", UVM_LOW); top_tb.rxd <= 8‘b0; top_tb.rx_dv <= 1‘b0; while(!top_tb.rst_n) @(posedge top_tb.clk); for(int i = 0; i < 256; i++)begin @(posedge top_tb.clk); top_tb.rxd <= $urandom_range(0, 255); top_tb.rx_dv <= 1‘b1; `uvm_info("my_driver", "data is drived", UVM_LOW); end @(posedge top_tb.clk); top_tb.rx_dv <= 1‘b0; phase.drop_objection(this); endtask
*2.2.3 加入objection机制