前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >数字IC验证系列之objection mechanism

数字IC验证系列之objection mechanism

作者头像
AsicWonder
发布2020-06-12 09:09:09
6620
发布2020-06-12 09:09:09
举报

UVM中,component的task phase是消耗仿真时间的,各个components的task phase之间需要完成同步。只有在所有components的相同task phase结束之后,才能进入下一个task phase。

UVM中通过objection mechanism中的raise/drop objection来控制phase的开始和停止。

当仿真器进入某个消耗时间的task phase时,首先会收集所有component提起(raise)的objection,然后按顺序执行所有component各自的task phase,直到所有component提起的objection都被撤销(drop)该phase的执行才算结束。

//driver中提起objection

代码语言:javascript
复制
task driver::main_phase(uvm_phase phase);phase.raise_objection(this);     .....phase.drop_objection(this);endtask

//monitor中提起objection

代码语言:javascript
复制
task monitor::main_phase(uvm_phase phase);    phase.raise_objection(this);     .....phase.drop_objection(this);endtask

例如在上述代码中,仿真器收集driver和monitor各自提起的objection,按顺序执行省略代码,直到driver和monitor都撤销objection才算main_phase执行结束

如果某个component的相应task phase没有被提起,则永远也不会执行消耗仿真时间的语句。同样,如果才task phase被提起后不被撤销,则该phase永远也不会结束。

在前面的代码中,main phase具有一个uvm_phase参数,这就是为具体实现raise/drop objection而设置的,这样每个component才能通过phase.raise_objection来提起相应的objection

UVM中的run_phase和其他task phase是并行关系,如果其他task phase中的objection被提起,run_phase也会执行,直到所有objection被撤销,run_phase才会结束。

下面通过几个例子展示objection的用法:

示例1:不加raise objection

代码语言:javascript
复制
class my_driver extends uvm_driver;
  `uvm_component_utils(my_driver)  function new(string name = "my_driver", uvm_component parent =null);     super.new(name, parent);     `uvm_info("my_driver", "new is called", UVM_LOW);  endfunction  extern virtual task main_phase(uvm_phase phase);endclass
task my_driver::main_phase(uvm_phasephase);  `uvm_info("my_driver", "main_phase is called",UVM_LOW);     @(posedge top_tb.clk);     `uvm_info("my_driver", "data is drived", UVM_LOW);endtask

输出:

代码语言:javascript
复制
UVM_INFO my_driver.sv(8) @ 0: uvm_test_top[my_driver] new is calledUVM_INFO my_driver.sv(15) @ 0: uvm_test_top[my_driver] main_phase is called

没有输出"data is drived"

示例2:raise objection没有加在仿真时间0时刻

代码语言:javascript
复制
class my_driver extends uvm_driver;
  `uvm_component_utils(my_driver)  function new(string name = "my_driver", uvm_component parent =null);     super.new(name, parent);     `uvm_info("my_driver", "new is called", UVM_LOW);  endfunction  extern virtual task main_phase(uvm_phase phase);endclass
task my_driver::main_phase(uvm_phasephase);  @(posedge top_tb.clk);  phase.raise_objection(this);  `uvm_info("my_driver", "main_phase is called",UVM_LOW);     @(posedge top_tb.clk);     `uvm_info("my_driver", "data is drived", UVM_LOW);  phase.drop_objection(this);endtask

输出:

代码语言:javascript
复制
UVM_INFO my_driver.sv(6) @ 0: uvm_test_top[my_driver] new is called

没有输出 "main_phase is called"和"data is drived"

示例3:不加drop objection

代码语言:javascript
复制
 class my_driver extends uvm_driver;  `uvm_component_utils(my_driver)  function new(string name = "my_driver", uvm_component parent =null);     super.new(name, parent);     `uvm_info("my_driver", "new is called", UVM_LOW);  endfunction  extern virtual task main_phase(uvm_phase phase);endclass
task my_driver::main_phase(uvm_phasephase);  phase.raise_objection(this);  `uvm_info("my_driver", "main_phase is called",UVM_LOW);  while(1) begin     @(posedge top_tb.clk);     `uvm_info("my_driver", "data is drived", UVM_LOW);  //phase.drop_objection(this);  endendtask

输出:

代码语言:javascript
复制
UVM_INFO my_driver.sv(8) @ 0: uvm_test_top[my_driver] new is calledUVM_INFO my_driver.sv(15) @ 0: uvm_test_top[my_driver] main_phase is called
UVM_INFO my_driver.sv(16) @ 125840500000:uvm_test_top [my_driver] data is drivedUVM_INFO my_driver.sv(16) @ 125840700000:uvm_test_top [my_driver] data is drivedUVM_INFO my_driver.sv(16) @ 125840900000:uvm_test_top [my_driver] data is drived…UVM_INFO my_driver.sv(16) @ 125841100000:uvm_test_top [my_driver] data is drivedUVM_INFO my_driver.sv(16) @ 125841300000:uvm_test_top [my_driver] data is drivedUVM_INFO my_driver.sv(16) @ 125841500000:uvm_test_top [my_driver] data is drivedUVM_INFO my_driver.sv(16) @ 125841700000:uvm_test_top [my_driver] data is drived

陷入死循环

示例4:增加drop objection

代码语言:javascript
复制
class my_driver extends uvm_driver;
  `uvm_component_utils(my_driver)  function new(string name = "my_driver", uvm_component parent =null);     super.new(name, parent);     `uvm_info("my_driver", "new is called", UVM_LOW);  endfunction  extern virtual task main_phase(uvm_phase phase);endclass
task my_driver::main_phase(uvm_phasephase);  phase.raise_objection(this);  `uvm_info("my_driver", "main_phase is called",UVM_LOW);  while(1) begin     @(posedge top_tb.clk);     `uvm_info("my_driver", "data is drived", UVM_LOW);  phase.drop_objection(this);  endendtask

输出:

代码语言:javascript
复制
UVM_INFO my_driver.sv(6) @ 0: uvm_test_top[my_driver] new is called
UVM_INFO my_driver.sv(13) @ 0: uvm_test_top[my_driver] main_phase is calledUVM_INFO my_driver.sv(16) @ 100000:uvm_test_top [my_driver] data is drived

正常输出

从上面几个示例可以看出,要想正确地实现对设计的仿真,必须合理地控制objection的提起和撤销,并且raise objection要发生在消耗时间的仿真语句之前

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-03-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 数字芯片实验室 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档