Verilog小白学编程
聊点实际的坑。区别都知道,但用的时候容易出错。
只用interface的场景:你的testbench非常非常简单,所有激励生成、驱动、监测都写在module里,用initial块和always块搞定。或者,你把一些简单的任务(task)和函数(function)直接定义在interface内部。这种情况下,interface本身就能提供连接和封装,不需要virtual interface。但这不是现代验证的方法。
必须用virtual interface的场景:只要你用了UVM,或者任何基于class的验证结构,就是必须的。因为UVM的组件(uvm_driver, uvm_monitor等)都是class,这是铁律。
关键步骤:
1. 在interface里定义好clocking block和modport,规范时序域和方向。
2. 在顶层TB module里例化interface,连接DUT。
3. 声明virtual interface并赋值:`virtual my_if vif = my_if_inst;`
4. 使用 `uvm_config_db#(virtual my_if)::set(null, "uvm_test_top.env.agent.drv", "vif", vif);` 将其放入数据库。
5. 在driver的class里,声明 `virtual my_if vif;`,并在build_phase用 `uvm_config_db#(virtual my_if)::get(this, "", "vif", vif);` 获取。
6. 一定要检查get是否成功!if(!vif) `uvm_fatal("NOVIF", "vif not set")`。这是最常见的坑,仿真跑起来发现信号没驱动,多半是vif是null。
7. 在run_phase里,通过vif.clocking_block来驱动和采样信号,保证时序正确。
好处除了复用性,还有利于封装。interface里可以定义协议检查的assertion,而virtual interface让这些assertion在class控制的交易中也能被关联触发,使得验证更严密。
