文章目录
前言:典型的uvm验证平台框图
1.UVM组件家族
UVM组件家族是从UVM基类继承的一个核心分支即uvm_component类
1.1 uvm_driver
- 该类会从uvm_sequncer中获取事务(Transaction),经过转化进而在接口中对DUT进行时序激励
- 该类是参数化类,在定义时需要声明参数类型
- 用户在定义新的driver类时,应当声明该类所需要获取的事务参数REQ类型,默认情况下,RSP参数类型同REQ类型保持一致
class uvm_driver #(type REQ=uvm_sequence_item, type RSP=REQ)
- uvm_driver在uvm_component基础上没有扩展新的函数,而只是扩展了一些用来通信的端口和变量
uvm_seq_item_pull_port #(REQ,RSP) seq_item_port;
uvm_analysis_port #(RSP) rsp_port;
REQ req;
RSP rsp;
driver和sequence类之间的通信就是为了获取新的事务对象,通过pull的方式实现
driver.seq_item_port.connect(sequencer.seq_item_export);
driver.rsp_port.connect(sequencer.rsp_export);
自己定义一个driver
class dut_driver extends uvm_driver #(basic_transaction);//sequence item类型
virtual chip_if vif;//virtual interface
bit[7:0] addr,data;
'uvm_component_utils(dut_driver) //在factory中注册dut_driver
function new(string name, uvm_component parent);
super.new(name,parent);
endfunction:new
extern task run_phase(uvm_phase phase);//在运行过程中自动执行的run_phase
endclass:dut driver
extern可以在现在这个类中预定义,然后在这个类的外部重新定义
1.2 uvm_monitor
uvm_monitor:所有的monitor都要派生自uvm_monitor。monitor做的事情与driver相反,driver向DUT的pin上发送数据,而monitor则是从DUT的pin上接收数据,并且把接收到的数据转换成transaction级别的sequence_item,再把转换后的数据发送给scoreboard,供其比较。
与uvm_component相比uvm_monitor几乎没有做任何扩展。
通常所执行的功能包括:
- 观测DUT的interface,并且收集总线信息
- 永远保持PASSIVE模式,即永远不会驱动DUT
- 在总线协议或者内部信号协议观察时,可以做一些功能和时序的检查
- 对于更加复杂的检查要求,它们可以将数据发送至其它验证组件
virtual class uvm_monitor extends uvm_component;
function new (string name, uvm_component parent);
super.new(name, parent);
endfunction
const static string type_name = "uvm_monitor";
virtual function string get_type_name();
return type_name;
endfunction
endclass
1.3 uvm_sequencer
- uvm_sequencer就如同一个管道,从这个管道中会产生连续的激励事务,并最终通过TLM端口送至driver一侧
- uvm_sequence也可以从uvm_driver那里获取随后的RSP对象来得知数据通信是否正常
- 属于参数类,需要在定义sequence时声明REQ的类型
class my_sequencer externs uvm_sequencer #(basic_transaction)//sequence item 类型
'uvm_component_util(uvm_sequencer)
function new();
super.new(name, parent);
endfunction:new
endclass:my_sequence
1.4 uvm_agent
- uvm_agent是一个标准的验证环境“单元”,通常包含一个driver、monitor、sequence
- 为了复用,有时uvm_agent中只需要包含一个monitor,而不需要driver和sequence,需要通过一个变量来进行有条件的例化
uvm_active_passive_enum is_active = UVM_ACTIVE;
is_active取值 | 模式 | 含义 |
---|---|---|
UVM_ACTIVE(缺省值) | active | agent需要例化driver 、monitor 、sequence |
UVM_PASSIVE | passive | agent只可以例化monitor |
- active模式:agent既有激励功能也有监测功能
- passive模式:agent只有监测功能
class my_agent extends uvm_agent;
//agent中所包含的常见组件
my_sequence m_sqr;
my_driver m_drv;
my_monitor m_mon;
//决定agent内部结构的变量is_active
uvm_active_passive_enum is_active = UVM_ACTIVE;
...
extern function void build_phase(uvm_phase phase);
extern function void connect_phase(uvm_phase phase);
'uvm_component_utils(my_agent)
endclass:my_agent
1.5 uvm_scoreboard
uvm_scoreboard的功能就是比较 reference model和 monitor分别发送来的数据,根据比较结果判断DUT是否正常工作。
reference module的作用就是模仿DUT,完成与DUT相同的功能。DUT是用verilog写成的时序电路,而reference model则可以直接使用Systen Verilog高级语言特性,同时通过DPI等接口调用其他语言来完成与DUT相同的功能。
uvm_scoreboard相比于uvm_component,没有添加额外的成员变量和方法
1.6 uvm_env
uvm_env(environment的缩写)将验证平台上用到的固定不变的component都封装在一起。当要运行不同的测试用例时,只要在测试用例中实例化次env即可。
uvm_env的角色就是一个结构化的容器,它可以容纳其它组件,同时它也可以作为子环境在更高层的集成中被嵌入。
uvm_env和uvm_agent的嵌套关系:
- uvm_agent作为一个标准单元,在更上层的集成中应该被例化到uvm_env
- uvm_env在更高层的复用中,可以被其它uvm_env所嵌套
1.6 uvm_test
uvm_test类本身没有什么新成员,作为测试用例的“代言人”,它不但决定着环境的结构和连接关系,也决定着使用哪一个测试序列
- uvm_test是验证环境的唯一入口,只有通过它才能正常运转UVM的phase机制
- 推荐uvm_test中只例化一个顶层uvm_test,这便于提供一个唯一环境节点以形成树状的拓扑结构,而这种树状环境结构也会对应这一种树状配置结构
从下面的示例看到,在一个顶层test中可以例化多个组件,如uvm_env、uvm_agent,在仿真时通过uvm_test可以实现验证环境的运转
//env
class env extends uvm_env;
'uvm_component_utill(env)//注册
...
endclass
//agent
class agent extends uvm_agent;
'uvm_component_util(agent)
...
endclass
// test
class test1 extends uvm_test;
'uvm_component_util(test1)
env e1,e2;
agent a1;
...
function void build_phase(uvm_phase phase)
e1 = env::type_id::create("c1",this);
e1 = env::type_id::create("c2",this);
a1 = agent::type_id::create("a1",this);
endfunction
endcalss
2. UVM树的根
UVM中真正的树根是一个称为uvm_top的东西。
完整的UVM树:
uvm_top是一个全局变量,它是uvm_root的一个实例,uvm_top本质上是一个uvm_component
我们知道,所有component在实例化时将this指针传递给parent参数
env = my_env::type_id::create("env",this);
如果一个component在实例化时,其parent被设置为null,那么这个component的parent将会被系统设置为系统中唯一的uvm_root的实例uvm_top
uvm_root的存在可以保证整个验证平台中只有一颗树,所有节点都是uvm_top的子节点