reference model继承于uvm_component,作用是用于验证设计的正确性,通过模拟设计的行为并与设计进行比较,以确保符合设计的规范。通过reference model,可以提高验证的覆盖率和效率,减少人工干预。
reference model根据imonitor采样的输入接口的数据包计算出符合设计文档的输出接口的数据包,然后把数据包送到scoreboard去做数据的比较。
imonitor与reference model用了TLM FIFO的通信方式,在imonitor声明了端口uvm_analysis_port,在采样数据之后通过write发送出去。
part1/reference是UVM reference的实验,代码2.16是dadd_imonotor通过TLM把数据发送给reference model。
File:dadd_imonitor.sv
Class:dadd_imonitor
task dadd_imonitor :: main_phase(uvm_phase phase);
dadd_item item;
wait(tb_dadd.dadd_if.reset_n);
forever
begin
@(posedge tb_dadd.dadd_if.clk);
if(tb_dadd.dadd_if.pcb.dadd_in_en)
begin
item = new();
item.data_en = tb_dadd.dadd_if.pcb.dadd_in_en;
item.data = tb_dadd.dadd_if.pcb.dadd_in;
item.addr = tb_dadd.dadd_if.pcb.dadd_in_addr;
$display("dadd_imonitor,item.addr = %h, item.data = %h",item.addr,item.data);
ap.write(item);
end
end
endtask: main_phase
代码2.16 reference model加入后dadd_imonitor中采样的数据通过tlm port发送给refrence model的代码
由于agent对monitor进行了封装,agent是作为一个整体对外界交互的组件,因此把imonitor的uvm_analysis_port接入到iagent,通过iagent连接reference model。
File:dadd_iagent.sv
Class:dadd_iagent
function dadd_iagent :: new(string name ="dadd_iagent", uvm_component parent);
super.new(name, parent);
drv = new("drv",this);
sqr = new("sqr",this);
imon = new("imon",this);
drv.seq_item_port.connect(sqr.seq_item_export);
ap = imon.ap;
endfunction: new
代码2.17 reference model加入后在iagent中的port的连接的代码
在reference model声明了端口uvm_blocking_get_port,在get_dadd_pkt获取iagent送入的数据包,在main_phase中完成加1的操作。
File:dadd_refmodel.sv
Class:dadd_refmodel
task dadd_refmodel :: main_phase(uvm_phase phase);
dadd_item item;
while(1)
begin
get_dadd_pkt(item);
item.data =item.data+ 1;
$display("dadd_refmodel item.addr = %h, item.data = %h",item.addr,item.data);
end
endtask: main_phase
task dadd_refmodel :: get_dadd_pkt(output dadd_item item);
dadd_item item_tmp;
port.get(item_tmp);
item = new item_tmp;
endtask : get_dadd_pkt
代码2.18 reference model加入后dadd_reference的代码
在dadd_rand_test中对reference model进行实例化,声明了TLM FIFO与iagent和reference model相连。
File:dadd_test.sv
Class:dadd_rand_test
function dadd_rand_test :: new(string name ="dadd_rand_test",uvm_component parent = null);
super.new(name,parent);
iagt = new("iagt",this);
oagt = new("oagt",this);
refmdl = new("refmdl",this);
seq = new("seq");
dadd_iagt_to_refmdl_fifo = new("dadd_iagt_to_refmdl_fifo",this);
iagt.ap.connect(dadd_iagt_to_refmdl_fifo.analysis_export);
refmdl.port.connect(dadd_iagt_to_refmdl_fifo.blocking_get_export);
endfunction : new
代码2.19 reference model加入后在dadd_rand_test的代码
执行Makefile 脚本:
make all
编译仿真后查看sim.log的结果,reference model打印的信息与波形的输出信号是一致的。
图2.22 reference model加入后仿真log截图
图2.23 reference model加入后仿真波形截图
加入imonitor和omonitor之后UVM的树形结构为:
图2.24 reference model加入后UVM树形结构
平台结构框图为:
图2.25 reference model加入后UVM平台框图
本书(《UVM实验教程-从平台、脚本到方法学全代码解析-王建利》)及其实验代码已上传至GitHub 访问网址为: https://github.com/brentwang-lab/uvm_tb_gen