什么是双向情感障碍| 回肠荡气什么意思| 献血前检查什么项目| 四次元是什么意思啊| 乳腺腺体是什么| 早熟是什么意思| 颈椎酸胀是什么原因| 尿酸高能吃什么水果| 为什么印度人叫阿三| 阳历12月是什么星座| 儿化音是什么意思| 苏轼是什么派诗人| 吃什么最补血而且最快| 目字旁与什么有关| 乐山大佛是什么佛| 晚上七八点是什么时辰| 桂鱼是什么鱼| 拉稀吃什么食物好| 电风扇什么牌子质量好| swag是什么意思| 相宜的意思是什么| 脱发应该挂什么科室| 月经量多是什么原因| 痢疾是什么意思| 为什么手| btob是什么意思| 上海立秋吃什么| 冬至说什么祝福语| 气血不足吃什么补最快| 早上7点多是什么时辰| 浑身疼是什么原因| 补气血吃什么药| 子宫平滑肌瘤什么意思| 坐月子什么不能吃| 企鹅代表什么生肖| 祭是什么意思| 3a是什么| 直肠炎是什么症状| 四川是什么气候| 六盘水为什么叫凉都| 属鸡女和什么属相最配| 甲状旁腺分泌什么激素| 6代表什么意思| 什么叫碳水化合物| 红色的海鱼是什么鱼| ca125是什么| 冰镇情人果是什么水果| 三七是什么| 酸奶能做什么美食| 红顶商人是什么意思| 戴银饰变黑是什么原因| 节节草有什么功效| 口苦吃什么好得快| 脱臼是指什么从什么中滑脱| 嘴下面起痘是什么原因| 我好想你是什么歌| 无住生心是什么意思| 7月15什么星座| 心肌缺血是什么原因引起的| 人的胆量由什么决定| 嘴唇起小水泡是什么原因| 妇科彩超主要检查什么| 碍事是什么意思| 肚子疼拉肚子挂什么科| 荆芥的别名叫什么| pt代表什么| 什么叫红肉| 比利时说什么语言| 海虫草是什么| 卟啉病是什么病| 氯雷他定片是什么药| 180度是什么角| 治甲沟炎用什么药膏好| 补血补气吃什么最快最好| 勃艮第红是什么颜色| 组织部副部长是什么级别| ccp是什么意思| 室上性心动过速是什么原因引起的| 什么是癌胚抗原| 睡眠不好什么原因| 官杀混杂是什么意思| 略是什么意思| 猪肝补什么功效与作用| 消纳是什么意思| 孙俪最新电视剧叫什么| 王八羔子是什么意思| ins风格是什么| 京兆尹是什么官| 善罢甘休的意思是什么| 孩子贫血吃什么补血最快| 维生素b1有什么作用| 乳腺发炎有什么症状| 子宫粘连有什么症状| 更年期燥热吃什么食物| 怀孕一个月有点见红是什么情况| 总是打嗝是什么原因引起的| 91年什么命| 身上长红疙瘩很痒是什么原因| 复诊是什么意思| 什么办法| 肝风上扰会有什么症状| 遥祝是什么意思| 天下之奇是什么生肖| 菜花病是什么| 朝鲜面是什么原料做的| 欲钱知吃月饼是什么生肖| 急性胃肠炎用什么药| 龙延香是什么| 脸上长癣用什么药膏| 梦到狗什么意思| 剪不断理还乱什么意思| 什么油锯好| 古筝是什么乐器| 梦见血是什么预兆解梦| 四季平安是什么生肖| 湿气重吃什么药最有效| 姜子牙是什么神仙| 眼睛雾化的作用是什么| 什么是化学| 同一首歌为什么停播了| 手突然发痒是什么原因| 胃病吃什么药| 交织是什么意思| 调理神经吃什么药好| 什么牛不吃草| 高手过招下一句是什么| 鲻鱼是什么鱼| 什么运动瘦肚子| 草莓什么时候成熟| 塞翁失马什么意思| 氯雷他定有什么副作用| 元参别名叫什么| 泌尿科主要检查什么| 狗的胡须有什么用| 元参别名叫什么| 肺气肿挂什么科| 项羽为什么不杀项伯| 便溏什么意思| 女人30如狼40如虎是什么意思| 补血最快的方法是什么| 静水流深什么意思| 脚环肿是什么原因引起的| 浅表性胃炎什么症状| 化学性肝损伤是指什么| 四肢发麻是什么原因| 板蓝根长什么样| 卡卡西为什么要杀琳| 天团是什么意思| a4纸可以折什么| 外强中干是什么意思| 5.29什么星座| 牛肉汤配什么菜好吃| 胆固醇偏高是什么意思| 永加一个日念什么| 乙肝两对半和乙肝五项有什么区别| 虾皮有什么营养价值| 碧玺是什么材质| 圣女果是什么水果| 茉莉茶叶属于什么茶| 短效避孕药什么时候吃| 梦见金蛇有什么预兆| 比是什么| 芬太尼是什么| 阴虚火旺吃什么中药| 沸去掉三点水念什么| 湿疹长什么样| 发烧腿疼是什么原因| 儿童看小鸡挂什么科| 古怪是什么意思| 妈妈的手像什么| 抽油烟机买什么样的好| babies是什么意思| 白菜什么时候种| 阴囊潮湿是什么原因造成的| 心脏供血不足用什么药| 玉米的种子是什么| only什么意思| 新疆在古代叫什么| 牙龈萎缩 用什么牙膏好| 进击的巨人真相是什么| 载脂蛋白a偏高是什么意思| 性价比高什么意思| 天热头疼吃什么药| 有氧运动是指什么| 为什么我| 异物进入气管什么症状| 12月7日是什么星座| 生理盐水和食用盐水有什么区别| 枕头发黄是什么原因| 喝盐水有什么作用和功效| 七四年属什么生肖| 名号是什么意思| 感冒喝什么茶| mild是什么意思| 什么的枣| 霜降穿什么衣服| 24节气分别是什么| 艾滋病皮肤有什么症状| 光合作用是什么| 女生的隐私长什么样子| 啤酒不能和什么一起吃| 什么叫原研药| 梦见买楼房有什么预兆| 京畿是什么意思| 神疲乏力吃什么中成药| 刮痧的痧是什么东西| 大便酸臭味是什么原因| 石斛念什么| 骞字五行属什么| 22是什么意思| 鳄龟吃什么食物| 葛根和什么搭配泡水好| 镇团委书记是什么级别| 胃肠型感冒吃什么药| 四月二十一是什么星座| 啵啵是什么| andy是什么意思| ov是什么意思| 下午1点是什么时辰| 子午相冲是什么意思| 白油是什么油| 篦子是什么东西| 一日清闲一日仙是什么生肖| 阴道炎用什么药| rop是什么意思| 稀盐酸是什么| 破伤风伤口有什么症状| 铁达时手表什么档次| 常州为什么叫龙城| 醋酸菌是什么菌| 男孩子送什么礼物| 男生适合学什么专业| 新生儿眼屎多是什么原因| 口臭是什么病| 提溜是什么意思| 血脂稠吃什么食物好| 男生叫你姑娘什么意思| 吃什么补钾| 表白是什么意思| 帅是什么意思| 霜降是什么意思| 为什么一吃饭就胃疼| 卧虎藏龙是什么生肖| 脂肪肝中医叫什么名字| hr医学上是什么意思| 上午九点多是什么时辰| 1948年是什么年| 拉绿色的屎是什么原因| 唾液酸偏低意味什么| 梅毒滴度是什么意思| 什么食物降尿酸效果好| 正直是什么意思| 水痘是什么病毒| 脱疽是什么意思| 类风湿是什么原因引起的| 室上性心动过速是什么原因引起的| 拔牙挂什么科室| 嗓子疼发烧吃什么药| 牛皮癣用什么药膏最好| 羊水污染是什么原因造成的| 小孩便秘吃什么食物好| 咳嗽有痰吃什么好的快| 黑壳虾吃什么食物| 经常肚子疼拉肚子是什么原因| 百度
这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 ? 论坛首页 ? 高校专区 ? 湖北理工TEA ? IC验证“UVM验证平台加入objection机制和virtualinterfa

共1条 1/1 1 跳转至

IC验证“UVM验证平台加入objection机制和virtualinterface机制“(七)

菜鸟
2025-08-04 18:23:40     打赏
百度 而且,现在还能有空带儿子出国旅游,报最好的补习班,老二一生,这样的开支真的难以继续。

在上一节中,**《IC验证"UVM验证平台加入factory机制"(六)》**虽然输出了“main_phase is called”,但是“data is drived”并没有输出。而main_phase是一个完整的任务,没有理由 只执行第一句,而后面的代码不执行。看上去似乎main_phase在执行的过程中被外力“杀死”了,事实上也确实如此。


 UVM中通过objection机制来控制验证平台的关闭。细心的读者可能发现,在上节的例子中,并没有如**《IC验证"一个简单的UVM验证平台"是如何搭建的(五)》**所示显式地调用 finish语句来结束仿真。但是在运行上节例子时,仿真平台确实关闭了。在每个phase中,UVM会检查是否有objection被提起 (raise_objection),如果有,那么等待这个objection被撤销(drop_objection)后停止仿真;如果没有,则马上结束当前phase。


 **加入了objection机制的driver如下所示:**


```

 文件: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); 

5225 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中第一个消耗仿真时间 [1]的语句之前。如$display语句是不消耗仿真时间的,这些语句可 以放在raise_objection之前,但是类似@(posedge top.clk)等语句是要消耗仿真时间的。按照如下的方式使用raise_objection是无法 起到作用的:

 ```

 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); 

53top_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 

```



## 加入virtual interface


在前几节的例子中,driver中等待时钟事件(@posedge top.clk)、给DUT中输入端口赋值(top.rx_dv<=1‘b1)都是使用绝对路 径,绝对路径的使用大大减弱了验证平台的可移植性。一个最简单的例子就是假如clk信号的层次从top.clk变成了top.clk_inst.clk, 那么就需要对driver中的相关代码做大量修改。因此,从根本上来说,应该尽量杜绝在验证平台中使用绝对路径。 

**避免绝对路径的一个方法是使用宏:** 


```

`define TOP top_tb 

task my_driver::main_phase(uvm_phase phase); 

phase.raise_objection(this); 

`uvm_info("my_driver", "main_phase is called", UVM_LOW); 

`TOP.rxd <= 8'b0; 

`TOP.rx_dv <= 1'b0; 

while(!`TOP.rst_n) 

@(posedge `TOP.clk); 

for(int i = 0; i < 256; i++)begin 

@(posedge `TOP.clk); 

`TOP.rxd <= $urandom_range(0, 255); 

`TOP.rx_dv <= 1'b1; 

`uvm_info("my_driver", "data is drived", UVM_LOW); 

end 

@(posedge `TOP.clk); 

`TOP.rx_dv <= 1'b0; 

phase.drop_objection(this); 

endtask 

```



这样,当路径修改时,只需要修改宏的定义即可。但是假如clk的路径变为了top_tb.clk_inst.clk,而rst_n的路径变为了 top_tb.rst_inst.rst_n,那么单纯地修改宏定义是无法起到作用的。 


避免绝对路径的另外一种方式是使用interface。在SystemVerilog中使用interface来连接验证平台与DUT的端口。interface的定义 比较简单: 


```

文件:src/ch2/section2.2/2.2.4/my_if.sv 

4 interface my_if(input clk, input rst_n); 

5

6 logic [7:0] data; 

7 logic valid; 

8 endinterface 

```



定义了interface后,在top_tb中实例化DUT时,就可以直接使用: 


```

文件:src/ch2/section2.2/2.2.4/top_tb.sv 

17 my_if input_if(clk, rst_n); 

18 my_if output_if(clk, rst_n); 

5619

20 dut my_dut(.clk(clk), 

21 .rst_n(rst_n), 

22 .rxd(input_if.data), 

23 .rx_dv(input_if.valid), 

24 .txd(output_if.data), 

25 .tx_en(output_if.valid)); 

```



那么如何在driver中使用interface呢?一种想法是在driver中声明如下语句,然后再通过赋值的形式将top_tb中的input_if传递给 它:


```

class my_driver extends uvm_driver; 

my_if drv_if; 

endclass 

```



读者可以试一下,这样的使用方式是会报语法错误的,因为my_driver是一个类,在类中不能使用上述方式声明一个 interface,只有在类似top_tb这样的模块(module)中才可以。在类中使用的是virtual interface: 


```

文件:src/ch2/section2.2/2.2.4/my_driver.sv 

3 class my_driver extends uvm_driver; 

574

5 virtual my_if vif; 

```



在声明了vif后,就可以在main_phase中使用如下方式驱动其中的信号: 


```

文件:src/ch2/section2.2/2.2.4/my_driver.sv 

23 task my_driver::main_phase(uvm_phase phase); 

24 phase.raise_objection(this); 

25 `uvm_info("my_driver", "main_phase is called", UVM_LOW); 

26 vif.data <= 8'b0; 

27 vif.valid <= 1'b0; 

28 while(!vif.rst_n) 

29 @(posedge vif.clk); 

30 for(int i = 0; i < 256; i++)begin 

31 @(posedge vif.clk); 

32 vif.data <= $urandom_range(0, 255); 

33 vif.valid <= 1'b1; 

34 `uvm_info("my_driver", "data is drived", UVM_LOW); 

35 end 

36 @(posedge vif.clk); 

37 vif.valid <= 1'b0; 

38 phase.drop_objection(this); 

39 endtask 

```



可以清楚看到,代码中的绝对路径已经消除了,大大提高了代码的可移植性和可重用性。 

58剩下的最后一个问题就是,如何把top_tb中的input_if和my_driver中的vif对应起来呢?最简单的方法莫过于直接赋值。此时一 个新的问题又摆在了面前:在top_tb中,通过run_test语句建立了一个my_driver的实例,但是应该如何引用这个实例呢?不可能像 

引用my_dut那样直接引用my_driver中的变量:top_tb.my_dut.xxx是可以的,但是top_tb.my_driver.xxx是不可以的。这个问题的终极 原因在于UVM通过run_test语句实例化了一个脱离了top_tb层次结构的实例,建立了一个新的层次结构。 

对于这种脱离了top_tb层次结构,同时又期望在top_tb中对其进行某些操作的实例,UVM引进了config_db机制。在config_db机 制中,分为set和get两步操作。所谓set操作,读者可以简单地理解成是“寄信”,而get则相当于是“收信”。在top_tb中执行set操作: 


```

文件:src/ch2/section2.2/2.2.4/top_tb.sv 

44 initial begin 

45 uvm_config_db#(virtual my_if)::set(null, "uvm_test_top", "vif", input_if); 

46 end 

```



在my_driver中,执行get操作: 


```

文件:src/ch2/section2.2/2.2.4/my_driver.sv 

13 virtual function void build_phase(uvm_phase phase); 

14 super.build_phase(phase); 

15 `uvm_info("my_driver", "build_phase is called", UVM_LOW); 

5916 if(!uvm_config_db#(virtual my_if)::get(this, "", "vif", vif)) 

17 `uvm_fatal("my_driver", "virtual interface must be set for vif!!!") 

18 endfunction 

```



这里引入了build_phase。与main_phase一样,build_phase也是UVM中内建的一个phase。当UVM启动后,会自动执行 build_phase。build_phase在new函数之后main_phase之前执行。在build_phase中主要通过config_db的set和get操作来传递一些数据, 以及实例化成员变量等。需要注意的是,这里需要加入super.build_phase语句,因为在其父类的build_phase中执行了一些必要的操 作,这里必须显式地调用并执行它。build_phase与main_phase不同的一点在于,build_phase是一个函数phase,而main_phase是一个 任务phase,build_phase是不消耗仿真时间的。build_phase总是仿真时间($time函数打印出的时间)为0时执行。 

在build_phase中出现了uvm_fatal宏,uvm_fatal宏是一个类似于uvm_info的宏,但是它只有两个参数,这两个参数与uvm_info宏 的前两个参数的意义完全一样。与uvm_info宏不同的是,当它打印第二个参数所示的信息后,会直接调用Verilog的finish函数来结 

束仿真。uvm_fatal的出现表示验证平台出现了重大问题而无法继续下去,必须停止仿真并做相应的检查。所以对于uvm_fatal来 说,uvm_info中出现的第三个参数的冗余度级别是完全没有意义的,只要是uvm_fatal打印的信息,就一定是非常关键的,所以无 需设置第三个参数。 


config_db的set和get函数都有四个参数,这两个函数的第三个参数必须完全一致。set函数的第四个参数表示要将哪个interface 通过config_db传递给my_driver,get函数的第四个参数表示把得到的interface传递给哪个my_driver的成员变量。set函数的第二个参 

数表示的是路径索引,即在2.2.1节介绍uvm_info宏时提及的路径索引。在top_tb中通过run_test创建了一个my_driver的实例,那么 这个实例的名字是什么呢?


答案是uvm_test_top:UVM通过run_test语句创建一个名字为uvm_test_top的实例。读者可以通过把代码 

`$display("the full name of current component is: %s", get_full_name());中的语句插入my_driver(build_phase或者main_phase)`中来验证。 


无论传递给run_test的参数是什么,创建的实例的名字都为uvm_test_top。由于set操作的目标是my_driver,所以set函数的第二 个参数就是uvm_test_top。set函数的第一个参数null以及get函数的第一和第二个参数可以暂时放在一边,后文会详细说明。 

set函数与get函数让人疑惑的另外一点是其古怪的写法。使用双冒号是因为这两个函数都是静态函数,而 uvm_config_db#(virtual my_if)则是一个参数化的类,其参数就是要寄信的类型,这里是virtual my_if。假如要向my_driver的var变 量传递一个int类型的数据,那么可以使用如下方式: 


```

initial begin 

uvm_config_db#(int)::set(null, "uvm_test_top", "var", 100); 

end 

```



而在my_driver中应该使用如下方式: 


```

class my_driver extends uvm_driver; 

int var; 

virtual function void build_phase(uvm_phase phase); 

super.build_phase(phase); 

`uvm_info("my_driver", "build_phase is called", UVM_LOW); 

61if(!uvm_config_db#(virtual my_if)::get(this, "", "vif", vif)) 

`uvm_fatal("my_driver", "virtual interface must be set for vif!!!") 

if(!uvm_config_db#(int)::get(this, "", "var", var)) 

`uvm_fatal("my_driver", "var must be set!!!") 

endfunction 

```



从这里可以看出,可以向my_driver中“寄”许多信。上文列举的两个例子是top_tb向my_driver传递了两个不同类型的数据,其 实也可以传递相同类型的不同数据。假如my_driver中需要两个my_if,那么可以在top_tb中这么做: 


```

initial begin 

uvm_config_db#(virtual my_if)::set(null, "uvm_test_top", "vif", input_if); 

uvm_config_db#(virtual my_if)::set(null, "uvm_test_top", "vif2", output_if); 

end 

```



在my_driver中这么做: 


```

virtual my_if vif; 

virtual my_if vif2; 

virtual function void build_phase(uvm_phase phase); 

super.build_phase(phase); 

`uvm_info("my_driver", "build_phase is called", UVM_LOW); 

if(!uvm_config_db#(virtual my_if)::get(this, "", "vif", vif)) 

62`uvm_fatal("my_driver", "virtual interface must be set for vif!!!") 

if(!uvm_config_db#(virtual my_if)::get(this, "", "vif2", vif2)) 

`uvm_fatal("my_driver", "virtual interface must be set for vif2!!!") 

endfunction 

```






关键词: ic设计     微电子就业     集成电路    

共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]
胃息肉吃什么药治疗 草木皆兵的意思是什么 instagram是什么 为什么会长水泡 牛肉和什么包饺子好吃
木棉是什么面料 女性为什么会肾结石 小儿急性喉炎吃什么药 九个月的宝宝吃什么辅食食谱 乳腺结节3类什么意思
塔罗是什么 孕妇尿回收是干什么用的 大腿后侧肌肉叫什么 多尿什么原因 国字脸适合什么发型男
1990属什么生肖 国窖1573是什么香型 飞刃是什么意思 生物酶是什么东西 心脏支架和搭桥有什么区别
什么是前列腺增生gangsutong.com 右手发麻是什么原因hcv8jop2ns4r.cn 后背痛是什么病的先兆hcv9jop8ns1r.cn 教头菜有什么功效hcv8jop0ns0r.cn 咳嗽挂什么科室hcv8jop5ns0r.cn
甘油是什么成分hcv8jop7ns4r.cn 红男绿女是什么生肖hcv9jop0ns6r.cn 6月12日是什么日子hcv8jop9ns3r.cn erke是什么牌子hcv9jop6ns1r.cn 男人梦见猫是什么意思hcv9jop4ns5r.cn
狗狗拉虫子又细又长吃什么药hcv8jop4ns1r.cn 白带异常吃什么药hcv8jop7ns2r.cn 秋葵和什么不能一起吃dajiketang.com 考教师资格证需要什么条件hcv7jop5ns1r.cn 什么河水hcv9jop1ns4r.cn
口五行属什么hcv9jop3ns5r.cn 饿了么什么时候成立的hcv8jop7ns8r.cn 太阳鱼吃什么食物hcv9jop5ns9r.cn 老年人心跳过快是什么原因hcv8jop4ns5r.cn 蛋白粉有什么功效jasonfriends.com
百度