1 UVM组件
1.1 vif
(virtual interface)
从根本上来说,应该尽量杜绝在验证平台中使用绝对路径。避免绝对路径的另外一种方式是使用interface。
例:定义了interface后,在top_tb中实例化DUT时,就可以直接使用。
# xxx_if.sv
interface xxx_if;
logic sig_clk;
logic sig_rst;
logic sig_data;
logic [6:0] sig_crc;
endinterface: xxx_if
# top_tb.sv
crc7 dut(vif.sig_clk,
vif.sig_rst,
vif.sig_data,
vif.sig_crc);
在driver中使用interface需要声明virtual interface
:
virtual xxx_if vif;
之后就可以在main_phase
中使用vif类
来驱动其中的信号。
virtual task drive();
...
vif.data = 1'b0;
vif.rst = 1'b0;
...
endtask: drive
1.2 transaction
transaction是一个抽象的概念。
一般来说,物理协议中的数据交换都是以帧或者包为单位的,通常在一帧或者一个包中要定义好各项参数,每个包的大小不一样。
很少会有协议是以bit
或者byte
为单位来进行数据交换的。
- my_transaction的基类是
uvm_sequence_item
。在UVM中,所有的transaction都要从uvm_sequence_item派生,只有uvm_sequence_item派生的transaction才可以sequence机制。 - 没有使用
uvm_component_utils
宏而是使用了uvm_object_utils
来实现factory机制。从本质上来说,transaction与 driver是有区别的,在整个仿真期间,my_driver是一直存在的,my_transaction则有生命周期。它在仿真的某一时间产生,处理运行之后其生命周期就结束了。派生自uvm_object的类都要使用uvm_object_utils
宏来实现。
1.3 agent
1.3.1 agent:env
env
是一个容器类,在这个容器类中实例化driver
、monitor
、reference model
和scoreboard
等。
class xxx_env extends uvm_env;
`uvm_component_utils(my_env)
my_driver drv;
function new(string name = "my_env", uvm_component parent);
super.new(name, parent);
endfunction
virtual function void build_phase(uvm_phase phase);
super.build_phase(phase);
drv = my_driver::type_id::create("drv", this);
endfunction
endclass: xxx_env
实例化组件时没有直接调用其new
函数,而是使用了一种古怪的方式。这种方式就是factory机制
带来的独特的实例化方式。只有使用factory机制注册过的类才能使用这种方式实例化。才能使用factory机制中最为强大的重载功能。
验证平台中的组件在实例化时都应该使用type_name::type_id::create
的方式。
在drv实例化时,传递了两个参数,一个是名字,另外一个是this指针
,表示my_env:
c7_agent = crc7_agent::type_id::create
(.name("c7_agent"), .parent(this));
c7_sb = crc7_scoreboard::type_id::create
(.name("c7_sb"), .parent(this));
同时,top_tb.sv
中run_test
的参数也从my_driver
变为了my_env
。
1.3.2 agent:monitor
验证平台必须监测DUT
的行为,只有知道DUT的Input/Output
变化之后,才能根据这些信号变化来判定DUT
的行为是否正确。
class my_monitor extends uvm_monitor;
virtual my_if vif;
`uvm_component_utils(my_monitor)
function new(string name = "my_monitor", uvm_component parent = null);
super.new(name, parent);
endfunction
virtual function void build_phase(uvm_phase phase);
...
endfunction
task main_phase(uvm_phase phase);
...
endtask:main_phase
task collect_one_pkt(my_transaction tr);
...
endtask:collect_one_pkt
endclass
uvm_monitor
在整个仿真中是一直存在的,所以它是一个component
,要使用uvm_component_utils
宏注册。
1.3.3 agent
driver
和monitor
之间存在联系,因为两者之间的代码高度相似。其本质是因为二者
处理的是同一种协议,在同样一套既定的规则下做着不同的事情。
class my_agent extends uvm_agent ;
`uvm_component_utils(my_agent)
my_driver drv;
my_monitor mon;
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction
...
endclass
由于agent
的加入,driver和monitor
的层次结构改变了,在top_tb
中使用config_db
设置if
时要注意改变路径。
UVM中约定俗成的还是在build_phase
中完成实例化工作。因此,强烈建议仅在build_phase中完成实例化。
1.4 reference model
reference model
用于完成和DUT相同的功能。
reference model的输出
被scoreboard接收,用于和DUT的输出
相比较。DUT如果很复杂,那么reference model也会相当复杂。
my_scoreboard要比较的数据来源:
- 一是来源于reference model
- 二是来源于dut输出数据后的的monitor(monitor_before)。
前者通过exp_port
获取,而后者通过act_port获取。
8 条评论
文章紧扣主题,观点鲜明,展现出深刻的思考维度。
字里行间流露出真挚的情感,让人感同身受,共鸣不已。
建议补充发展中国家案例,避免视角局限。
文献引用规范,学术态度严谨,值得借鉴。
立意高远,以小见大,引发读者对社会/人性的深层共鸣。
真好呢
不错不错,我喜欢看 www.jiwenlaw.com
怎么收藏这篇文章?