先拷贝大牛们的例子:https://www.cnblogs.com/bettty/p/5285785.html
Abstract
本文介绍UVM框架,并以crc7为例进行UVM的验证,最后指出常见的UVM验证开发有哪些坑,以及怎么避免。
Introduction
本例使用环境:ModelSim 10.2c,UVM-1.1d,Quartus II 13.1(64 bit),器件库MAX V
1. UVM介绍
对UVM结构熟悉的读者可跳过本节。
叫UVM“框架”可能并不确切(只是便于理解,可类比软件界的“框架”)。UVM全称为通用验证方法论。在硬件开发过程中,验证是十分重要的环节。可以说,左手开发,右手验证。在历史上,为了实现通用化的验证,前人摸爬滚打,创造出了UVM这一套框架。UVM前身是OVM,两者都是Accellera提出,UVM在OVM的基础上有所改进。
本文旨在用一种简单的方式介绍UVM的结构。期望读者能够读完本文后,成功搭建一个完整的UVM验证系统。
Part 1:
UVM的功能
请看下图,一个典型的testbench验证过程如图所示。即,我们写testbench,将激励信号传入DUT(待验证模块),然后观察输出波形,或者查看输出结果,是否和预期的一致。通过这样的过程,我们判断我们编写的Verilog是否正确。
请看下图,UVM如同一个管家,将“输入激励”和“观察波形”的动作管理了起来。基于UVM进行开发,UVM提供了很多机制,也能够快速的产生我们想要输入的激励。
问题是,我们完全可以使用testbench解决问题,为什么还要使用UVM呢?
UVM是一个通用验证平台,基于它,我们可以产生复杂、大量、可定制化的随机激励,并可以提高大型验证工程的协作性和扩展性。举个例子,UVM框架就像软件开发的分层结构,定义好了统一的接口,那么,各个层次就可以交给各个团队来开发。验证项目也是如此,产生激励的工程如果有改动,并不会影响“观察波形”(实质是观察结果)的团队。实际上,UVM分的更细,它将各个流程都拆分开来,包括transaction、driver、sequence、sequencer、monitor、agent、test、env、top等部分。此外,UVM提供了优秀的factory机制、objection机制、reg机制,为我们简化开发过程。比如,reg机制就封装了我们在硬件开发中读写寄存器的一些操作。我们调用UVM的函数,就能够迅速的开发读写reg的过程。
Part 2:
UVM的结构
如前所述,UVM包括transaction、interface、driver、sequence、sequencer、monitor、reference model、agent、test、env、top等部分,其相互关系极其复杂。不如说,UVM牺牲简洁性换来“通用”性。
借用Pedro Araujo的结构图。
1) 正如这个图片所展示的,UVM是除了DUT(待验证模块)的其他所有部分。其中,sequencer产生sequence(图上没画),sequence产生transaction。
transaction,类似于软件中的一个package。在硬件中,以一个transaction为单位进行传输,一个完整的transaction传输结束,才拉高或拉低电平。
2)通过UVM的专门的类型——port把数据给driver。driver通过interface把产生的激励(也就是transaction)输入DUT。同时,DUT的输出也是和interface相连接的。一个monitor(monitor after)监测driver吐给DUT的输入,一个monitor(monitor before)监测DUT吐出来的输出。
3) 这里,看到一个agent把整个monitor、sequencer、driver都装起来了。这个agent实现的功能是转换。因为整个UVM都是systemverilog的,并且理论上是仿真的,都不是“硬件”。DUT在这里是真正的“硬件”。两者之间不能直接通信,只能通过一个agent,来对协议进行转换。不过,我们可以不用管agent怎么实现的。在开发的时候,只要把相关的模块连接好就行了。
4)这个图还少了一个reference model。因为reference model的工作在这个例子中,实际是在monitor after里面实现的。- -不过没关系。reference model完成的工作是,把DUT做的事完全的再做一遍。reference model接入monitor采到的输入激励,按照DUT的逻辑,产生一个结果。
5)同样通过port,把reference model产生的结果同monitor before采到的数据都丢到scoreboard上。在scoreboard上,我们会对两个结果进行比较。如果两个结果一致,则为正确。如果不一致,则为错误。
UVM本身用700页来写也完全可以。因为UVM极其复杂。本文不在此赘述。
2. 以crc7为例进行UVM的验证
Part 1:
搭建环境。
本文使用的Quartus II 13.1(64 bit),器件库MAX V。写了一个Verilog的简单的crc7。
仿真环境是ModelSim 10.2c。虽说自带UVM库。但是,没找到Modelsim自带的uvm_dpi.dll,于是,还重新编译了一番。
本文在win 10下。下载uvm-1.1d(现在最新版本有1.2d了),放好。安装好ModelSim 10.2c后,在命令提示符>后,输入
编辑环境变量
set UVM_HOME c:/tool/uvm-1.1d
set MODEL_TECH c:/modeltech_10.2c/win32
编译UCM_DPI动态链接库。编好一次就不用再编了。
c:/modeltech_10.2c/gcc-4.2.1-mingw32vc9/bin/g++.exe -g -DQUESTA -W -shared -Bsymbolic -I $MODEL_TECH/../include $UVM_HOME/src/dpi/uvm_dpi.cc -o $UVM_HOME/lib/uvm_dpi.dll $MODEL_TECH/mtipli.dll -lregex
Part 2:
编写待验证模块。
module crc7(clk,
rst,
data,
crc);
input wire clk;
input wire rst;
input wire data;
output reg[6:0] crc;
reg g0;
assign g0 = data ^ crc[6];
always @(posedge rst or negedge clk)
if (rst)
begin
crc <= 7'b0000000;
end
else
begin
crc[6] <= crc[5];
crc[5] <= crc[4];
crc[4] <= crc[3];
crc[3] <= crc[2] ^ g0;
crc[2] <= crc[1];
crc[1] <= crc[0];
crc[0] <= g0;
end
endmodule
在Quartus中编译通过。
Part 3:
编写验证代码。
在Modelsim中新建一个项目,新建如图所示多个.sv文件。
crc7_tb_top.sv如下所示
`include "uvm_pkg.sv"
`include "crc7_pkg.sv"
`include "crc7.v"
`include "crc7_if.sv"
module crc7_tb_top;
import uvm_pkg::*;
import crc7_pkg::*;
//interface declaration
crc7_if vif();
//connect the interface to the DUT
crc7 dut(vif.sig_clk,
vif.sig_rst,
vif.sig_data,
vif.sig_crc);
initial begin
uvm_resource_db#(virtual crc7_if)::set
(.scope("ifs"), .name("crc7_if"), .val(vif));
run_test("crc7_test");
end
initial begin
vif.sig_clk <= 1'b1;
end
always
#5 vif.sig_clk =~ vif.sig_clk;
endmodule
crc7_monitor.sv如下所示
class crc7_monitor_before extends uvm_monitor;
`uvm_component_utils(crc7_monitor_before)
uvm_analysis_port#(crc7_transaction) mon_ap_before;
virtual crc7_if vif;
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction: new
function void build_phase(uvm_phase phase);
super.build_phase(phase);
void'(uvm_resource_db#(virtual crc7_if)::read_by_name(.scope("ifs"), .name("crc7_if"), .val(vif)));
mon_ap_before = new(.name("mon_ap_before"), .parent(this));
endfunction: build_phase
task run_phase(uvm_phase phase);
crc7_transaction c7_tx;
c7_tx = crc7_transaction::type_id::create(.name("c7_tx"), .contxt(get_full_name()));
forever begin
@(negedge vif.sig_clk)
begin
c7_tx.crc = vif.sig_crc;
`uvm_info("monitor_before",$sformatf("c7_tx.crc is '%b'", c7_tx.crc), UVM_LOW);
mon_ap_before.write(c7_tx);
end
end
endtask: run_phase
endclass: crc7_monitor_before
class crc7_monitor_after extends uvm_monitor;
`uvm_component_utils(crc7_monitor_after)
uvm_analysis_port#(crc7_transaction) mon_ap_after;
virtual crc7_if vif;
crc7_transaction c7_tx;
//For coverage
crc7_transaction c7_tx_cg;
//Define coverpoints
covergroup crc7_cg;
endgroup: crc7_cg
function new(string name, uvm_component parent);
super.new(name, parent);
crc7_cg = new;
endfunction: new
function void build_phase(uvm_phase phase);
super.build_phase(phase);
void'(uvm_resource_db#(virtual crc7_if)::read_by_name(.scope("ifs"), .name("crc7_if"), .val(vif)));
mon_ap_after = new(.name("mon_ap_after"), .parent(this));
endfunction: build_phase
task run_phase(uvm_phase phase);
integer count = 42, rst = 0;
c7_tx = crc7_transaction::type_id::create(.name("c7_tx"), .contxt(get_full_name()));
forever begin
@(negedge vif.sig_clk)
begin
rst = 0;
count = count - 1;
if(count == 0)
begin
rst = 1;
count = 42;
predictor();
`uvm_info("monitor_after",$sformatf("c7_tx.crc is '%b'", c7_tx.crc), UVM_LOW);
c7_tx_cg = c7_tx;
crc7_cg.sample();
mon_ap_after.write(c7_tx);
end
end
end
endtask: run_phase
virtual function void predictor();
c7_tx.crc = 7'b0101010;
endfunction: predictor
endclass: crc7_monitor_after
crc7_sequencer.sv如下所示
class crc7_transaction extends uvm_sequence_item;
bit[6:0] crc;
function new(string name = "");
super.new(name);
endfunction: new
`uvm_object_utils_begin(crc7_transaction)
`uvm_field_int(crc, UVM_ALL_ON)
`uvm_object_utils_end
endclass: crc7_transaction
class crc7_sequence extends uvm_sequence#(crc7_transaction);
`uvm_object_utils(crc7_sequence)
function new(string name = "");
super.new(name);
endfunction: new
task body();
crc7_transaction c7_tx;
repeat (1) begin
c7_tx = crc7_transaction::type_id::create(.name("c7_tx"), .contxt(get_full_name()));
start_item(c7_tx);
assert(c7_tx.randomize());
finish_item(c7_tx);
//c7_tx.end_event.wait_on();
end
endtask: body
endclass: crc7_sequence
typedef uvm_sequencer#(crc7_transaction) crc7_sequencer;
crc7_driver.sv如下所示
class crc7_driver extends uvm_driver#(crc7_transaction);
`uvm_component_utils(crc7_driver)
virtual crc7_if vif;
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction: new
function void build_phase(uvm_phase phase);
super.build_phase(phase);
void'(uvm_resource_db#(virtual crc7_if)::read_by_name(.scope("ifs"), .name("crc7_if"), .val(vif)));
endfunction: build_phase
task run_phase(uvm_phase phase);
drive();
endtask: run_phase
virtual task drive();
crc7_transaction c7_tx;
integer counter = 40;
bit[39:0] data;
data = 40'b0101000100000000000000000000000000000000;
vif.sig_data = 1'b0;
vif.sig_rst = 1'b0;
forever begin
//seq_item_port.get_next_item(c7_tx);
@(negedge vif.sig_clk)
begin
vif.sig_rst = 1'b0;
vif.sig_data = data[counter - 1];
counter = counter - 1;
if(counter == 0) begin
#28 counter = 40;
vif.sig_rst = 1'b1;
end
end
//seq_item_port.item_done();
end
endtask: drive
endclass: crc7_driver
(其余代码请在文章末尾下载。 )
其中,crc7_tb_top.sv第31行:
#5 vif.sig_clk =~ vif.sig_clk;
表示每5个时钟单位反向一次。即时钟周期为10ns。
crc7_monitor.sv中第1行和第34行,分别新建一个名为crc7_monitor_before和crc7_monitor_after的类。第26行,
c7_tx.crc = vif.sig_crc;
crc7_monitor_before类采集DUT输出的信号。本测试用例中只有一个输出信号,即计算出的crc。vif是interface类的实例。前文中说过,monitor是从interface上采集的。
第27行,
`uvm_info("monitor_before",$sformatf("c7_tx.crc is '%b'", c7_tx.crc), UVM_LOW);
使用UVM提供的宏打印格式化的数据。UVM提供的宏可类比软件中的库函数。就是无需声明,只管调用。
第28行,
mon_ap_before.write(c7_tx);
将采集到的数据写入ap中。ap是什么?ap是UVM中的port类型之一,叫analysis_port。简单说就像硬件的一个接口,协议UVM已经搞好了。我们只管读写就好了。
从第66行到第84行,都是本来应该在reference model里面实现的。就是说,从结构上来说,monitor采集到了driver发到interface上的信号,会丢给reference model来计算出一个结果(这是比较标准的结构)。本例中,由于reference model要做的事情太简单,就直接放在monitor里面做了。当monitor_after采集到了输入激励后,就在自己内部算了一把,然后把结果写出去。这就是66-84行所起的作用。由于crc7的运算结果可以查表。本例就直接查了表。也就是说,UVM完全可以实现输入激励的随机化。但是本例没用。本例使用了一对输入/输出数据。并且在第88行,直接把输出数据返回了。这对输入/输出数据为:40'b0101000100000000000000000000000000000000;7'b0101010;
同样,在第81行,
mon_ap_after.write(c7_tx);
把正确的结果写入ap。注意,ap是成对的。有写就有读。
crc7_sequencer.sv中,第26-28行,
@(negedge vif.sig_clk)
begin
vif.sig_rst = 1'b0;
vif.sig_data = data[counter - 1];
counter = counter - 1;
if(counter == 0) begin
#28 counter = 40;
vif.sig_rst = 1'b1;
end
end
完成的工作是,每一个时钟节拍打出data的1位。data见第24行。本来应该由sequence产生随机激励的,由于本例使用的是查表验证,因此,并没有使用UVM的随机功能。因此,要随机的数据没有在sequence里面写进去,要打入的数据在driver模块中写入了vif。这样完成了设定数据的输入。
Part 4:
编译仿真。
编译crc7_tb_top.sv,
vlog +incdir+C:/modeltech_10.2c/verilog_src/uvm-1.1d/src -L mtiAvm -L mtiOvm -L mtiUvm -L mtiUPF crc7_tb_top.sv
crc7_tb_top是整个工程的入口。
仿真crc7_tb_top,
vsim -ldflags "-lregex" -t 1ns -c -sv_lib c:/modeltech_10.2c/uvm-1.1d/win32/uvm_dpi work.crc7_tb_top
vsim的-ldflags参数是将后面的字符串“-lregex”作为参数传入到mingw里面。mingw会原封不动的传入给其调用的g++。至于为什么要这么做?因为按照命令,
vsim -c -sv_lib $UVM_HOME/lib/uvm_dpi work.hello_world_example
编译的时候报错了,提示找不到uvm_dpi。明明编译了放在对的地方,可是就是找不到。于是,将路径写死在命令里。成功仿真。
添加波形,得到波形如图(截取部分):
查看打印结果。仿真结果和正确值相比,如图所示:
其中,每一个时钟周期打印的是,当前时刻移位后的crc7值。在40个bit结束后,移位结果为0101010,正确结果也是0101010,因此,compare OK。
3. UVM验证开发常见有哪些坑?怎样避免。
Q1:为什么状态机走入了未预料的分支?
在时钟边沿采集与时钟同样跳变的信号时,这一瞬间采集到的信号可能是高,也可能是低。此时,若做逻辑判断,可能出现无法预料的情况。
解决的方法是,加入其它逻辑判断条件,确保程序逻辑正确。
Q2:为什么reference model和DUT的结果计算时序不一致?
一般来说,一组数据经过DUT的处理,会有一定的时延。而reference model没有时延。我们希望在同一时刻,对reference model和DUT计算的结果在scoreboard中比较,则须考虑两者运行的时间差。
有两种方法解决:一是手动添加时延,比较简单,但是有可能出错;二是使用UVM的FIFO机制,把先到达的reference model输出的数据放入到一个队列中。确保仿真时间结束后,用来比较的两个结果都是基于同样的激励输入。
本文用例完整代码下载:uvm-crc-test.zip
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
1、首先安装modeltech64_10.4没的说,不然没得玩。
2、创建几个脚本:
hello_world_example.sv
`include "uvm_pkg.sv"
module hello_world_example;
import uvm_pkg::*;
`include "uvm_macros.svh"
initial begin
`uvm_info("info1","Hello UVM!",UVM_LOW)
end
endmodule: hello_world_example
sim_hello_world_example.do(hello_word_example.sv的例子)
#Time: 2016-07-19
#By : times_poem
#Time: 2019-07-25
#Mod: houwenbin
#
quit -sim
#
set UVM_HOME D:/AI/altera/modeltech64_10.4
#
if [file exists work] {
vdel -all
}
#1. Create project
vlib work
#2. Compile hello_world_example.sv
vlog +incdir+$UVM_HOME/verilog_src/uvm-1.1d/src -L mtiAvm -L mtiOvm -L mtiUvm -L mtiUPF hello_world_example.sv
#3. Sim work.hello_world_example
vsim -ldflags "-lregex" -t 1ns -c -sv_lib $UVM_HOME/uvm-1.1d/win64/uvm_dpi work.hello_world_example
#vsim -64 -c -sv_lib $UVM_HOME/uvm-1.1d/win64/uvm_dpi work.hello_world_example
#4. Run test 1000ns
run 1000
#5. Quit
#quit -sim
quit -f
sim_crc7_tb_top.do
#Time: 2016-07-19
#By : times_poem
#Time: 2019-07-25
#Mod: houwenbin
#
quit -sim
#
set UVM_HOME D:/AI/altera/modeltech64_10.4
#
if [file exists work] {
vdel -all
}
#1. Create project
vlib work
#2. Compile crc7_tb_top.sv
vlog +incdir+$UVM_HOME/verilog_src/uvm-1.1d/src -L mtiAvm -L mtiOvm -L mtiUvm -L mtiUPF crc7_tb_top.sv
#3. Sim work.crc7_tb_top
vsim -64 -c -sv_lib $UVM_HOME/uvm-1.1d/win64/uvm_dpi work.crc7_tb_top
#vsim -ldflags "-lregex" -t 1ns -c -sv_lib $UVM_HOME/uvm-1.1d/win64/uvm_dpi work.crc7_tb_top
#4. Run test 1000ns
run 1000
#5. Quit
#quit -sim
#quit -f
运行脚本run.bat:
@echo off
::
:: Important here Env setting
::
set PATH=D:/AI/altera/modeltech64_10.4/win64;D:\AI\altera\15.0\quartus\bin64\cygwin\bin;D:\AI\altera\15.0\quartus\bin64;%PATH%
::Test_1
::vsim -do sim_hello_world_example.do
::Test_2
vsim -do sim_crc7_tb_top.do
我没有编译UVM源码,因为 ModelSim 中已经有了,况且我自己编译的居然不能用,一跑就卡住。
运行run.bat,得到结果:
# // ModelSim SE-64 10.4 Dec 3 2014
# //
# // Copyright 1991-2014 Mentor Graphics Corporation
# // All Rights Reserved.
# //
# // THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION
# // WHICH IS THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS
# // LICENSORS AND IS SUBJECT TO LICENSE TERMS.
# // THIS DOCUMENT CONTAINS TRADE SECRETS AND COMMERCIAL OR FINANCIAL
# // INFORMATION THAT ARE PRIVILEGED, CONFIDENTIAL, AND EXEMPT FROM
# // DISCLOSURE UNDER THE FREEDOM OF INFORMATION ACT, 5 U.S.C. SECTION 552.
# // FURTHERMORE, THIS INFORMATION IS PROHIBITED FROM DISCLOSURE UNDER
# // THE TRADE SECRETS ACT, 18 U.S.C. SECTION 1905.
# //
# do sim_crc7_tb_top.do
# D:/AI/altera/modeltech64_10.4
# Model Technology ModelSim SE-64 vlog 10.4 Compiler 2014.12 Dec 3 2014
# Start time: 15:44:23 on Jul 25,2019
# vlog -reportprogress 300 "+incdir+D:/AI/altera/modeltech64_10.4/verilog_src/uvm-1.1d/src" -L mtiAvm -L mtiOvm -L mtiUvm -L mtiUPF crc7_tb_top.sv
# -- Compiling package uvm_pkg (uvm-1.1d Built-in)
# -- Compiling package crc7_pkg
# -- Importing package uvm_pkg (uvm-1.1d Built-in)
# -- Compiling module crc7
# -- Compiling interface crc7_if
# -- Compiling module crc7_tb_top
# -- Importing package crc7_pkg
#
# Top level modules:
# crc7_tb_top
# End time: 15:44:24 on Jul 25,2019, Elapsed time: 0:00:01
# Errors: 0, Warnings: 0
# vsim -do "sim_crc7_tb_top.do"
# Start time: 15:44:27 on Jul 25,2019
# ** Warning: (vsim-159) Mode option -64 is not supported in this context and will be ignored.
#
# ** Note: (vsim-3812) Design is being optimized...
#
# Loading sv_std.std
# Loading work.uvm_pkg(fast)
# Loading work.crc7_pkg(fast)
# ** Note: (vsim-8785) UVM-aware debugging capabilities will be disabled since no compiled "questa_uvm_pkg" can be found.
#
# This also means that later if you turn on UVM-aware debugging your debug simulations may have
#
# different random seeds from your non-debug simulations.
#
# Loading work.crc7_tb_top(fast)
# Loading work.crc7_if(fast)
# Loading D:/AI/altera/modeltech64_10.4/uvm-1.1d/win64/uvm_dpi.dll
# ----------------------------------------------------------------
# UVM-1.1d
# (C) 2007-2013 Mentor Graphics Corporation
# (C) 2007-2013 Cadence Design Systems, Inc.
# (C) 2006-2013 Synopsys, Inc.
# (C) 2011-2013 Cypress Semiconductor Corp.
# ----------------------------------------------------------------
#
# *********** IMPORTANT RELEASE NOTES ************
#
# You are using a version of the UVM library that has been compiled
# with `UVM_NO_DEPRECATED undefined.
# See http://www.eda.org/svdb/view.php?id=3313 for more details.
#
# You are using a version of the UVM library that has been compiled
# with `UVM_OBJECT_MUST_HAVE_CONSTRUCTOR undefined.
# See http://www.eda.org/svdb/view.php?id=3770 for more details.
#
# (Specify +UVM_NO_RELNOTES to turn off this notice)
#
# UVM_INFO @ 0: reporter [RNTST] Running test crc7_test...
# UVM_INFO crc7_monitor.sv(28) @ 5: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '0000000'
# UVM_INFO crc7_monitor.sv(28) @ 15: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '0000000'
# UVM_INFO crc7_monitor.sv(28) @ 25: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '0000000'
# UVM_INFO crc7_monitor.sv(28) @ 35: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '0000000'
# UVM_INFO crc7_monitor.sv(28) @ 45: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '0000000'
# UVM_INFO crc7_monitor.sv(28) @ 55: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '0000000'
# UVM_INFO crc7_monitor.sv(28) @ 65: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '0000000'
# UVM_INFO crc7_monitor.sv(28) @ 75: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '0000000'
# UVM_INFO crc7_monitor.sv(28) @ 85: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '0000000'
# UVM_INFO crc7_monitor.sv(28) @ 95: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '0000000'
# UVM_INFO crc7_monitor.sv(28) @ 105: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '0000000'
# UVM_INFO crc7_monitor.sv(28) @ 115: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '0000000'
# UVM_INFO crc7_monitor.sv(28) @ 125: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '0000000'
# UVM_INFO crc7_monitor.sv(28) @ 135: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '0000000'
# UVM_INFO crc7_monitor.sv(28) @ 145: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '0000000'
# UVM_INFO crc7_monitor.sv(28) @ 155: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '0000000'
# UVM_INFO crc7_monitor.sv(28) @ 165: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '0000000'
# UVM_INFO crc7_monitor.sv(28) @ 175: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '0000000'
# UVM_INFO crc7_monitor.sv(28) @ 185: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '0000000'
# UVM_INFO crc7_monitor.sv(28) @ 195: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '0000000'
# UVM_INFO crc7_monitor.sv(28) @ 205: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '0000000'
# UVM_INFO crc7_monitor.sv(28) @ 215: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '0000000'
# UVM_INFO crc7_monitor.sv(28) @ 225: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '0000000'
# UVM_INFO crc7_monitor.sv(28) @ 235: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '0000000'
# UVM_INFO crc7_monitor.sv(28) @ 245: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '0000000'
# UVM_INFO crc7_monitor.sv(28) @ 255: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '0000000'
# UVM_INFO crc7_monitor.sv(28) @ 265: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '0000000'
# UVM_INFO crc7_monitor.sv(28) @ 275: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '0000000'
# UVM_INFO crc7_monitor.sv(28) @ 285: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '0000000'
# UVM_INFO crc7_monitor.sv(28) @ 295: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '0000000'
# UVM_INFO crc7_monitor.sv(28) @ 305: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '0000000'
# UVM_INFO crc7_monitor.sv(28) @ 315: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '0000000'
# UVM_INFO crc7_monitor.sv(28) @ 325: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '0000000'
# UVM_INFO crc7_monitor.sv(28) @ 335: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '0000000'
# UVM_INFO crc7_monitor.sv(28) @ 345: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '0000000'
# UVM_INFO crc7_monitor.sv(28) @ 355: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '0000000'
# UVM_INFO crc7_monitor.sv(28) @ 365: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '0000000'
# UVM_INFO crc7_monitor.sv(28) @ 375: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '0000000'
# UVM_INFO crc7_monitor.sv(28) @ 385: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '0000000'
# UVM_INFO crc7_monitor.sv(28) @ 395: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '0000000'
# UVM_INFO crc7_monitor.sv(28) @ 405: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '0000000'
# UVM_INFO crc7_monitor.sv(28) @ 415: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '0000000'
# UVM_INFO crc7_monitor.sv(77) @ 415: uvm_test_top.c7_env.c7_agent.c7_mon_after [monitor_after] c7_tx.crc is '0101010'
# UVM_INFO crc7_scoreboard.sv(54) @ 415: uvm_test_top.c7_env.c7_sb [sb_compare] ---transaction_after.crc '0101010'
# UVM_INFO crc7_scoreboard.sv(55) @ 415: uvm_test_top.c7_env.c7_sb [sb_compare] ---transaction_before.crc '0000000'
# UVM_INFO crc7_scoreboard.sv(56) @ 415: uvm_test_top.c7_env.c7_sb [compare] Test: Fail!
# UVM_INFO crc7_monitor.sv(28) @ 425: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '0000000'
# UVM_INFO crc7_monitor.sv(28) @ 435: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '0000000'
# UVM_INFO crc7_monitor.sv(28) @ 445: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '0000000'
# UVM_INFO crc7_monitor.sv(28) @ 455: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '0001001'
# UVM_INFO crc7_monitor.sv(28) @ 465: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '0010010'
# UVM_INFO crc7_monitor.sv(28) @ 475: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '0101101'
# UVM_INFO crc7_monitor.sv(28) @ 485: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '1011010'
# UVM_INFO crc7_monitor.sv(28) @ 495: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '0111101'
# UVM_INFO crc7_monitor.sv(28) @ 505: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '1111010'
# UVM_INFO crc7_monitor.sv(28) @ 515: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '1110100'
# UVM_INFO crc7_monitor.sv(28) @ 525: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '1100001'
# UVM_INFO crc7_monitor.sv(28) @ 535: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '1001011'
# UVM_INFO crc7_monitor.sv(28) @ 545: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '0011111'
# UVM_INFO crc7_monitor.sv(28) @ 555: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '0111110'
# UVM_INFO crc7_monitor.sv(28) @ 565: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '1111100'
# UVM_INFO crc7_monitor.sv(28) @ 575: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '1110001'
# UVM_INFO crc7_monitor.sv(28) @ 585: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '1101011'
# UVM_INFO crc7_monitor.sv(28) @ 595: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '1011111'
# UVM_INFO crc7_monitor.sv(28) @ 605: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '0110111'
# UVM_INFO crc7_monitor.sv(28) @ 615: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '1101110'
# UVM_INFO crc7_monitor.sv(28) @ 625: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '1010101'
# UVM_INFO crc7_monitor.sv(28) @ 635: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '0100011'
# UVM_INFO crc7_monitor.sv(28) @ 645: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '1000110'
# UVM_INFO crc7_monitor.sv(28) @ 655: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '0000101'
# UVM_INFO crc7_monitor.sv(28) @ 665: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '0001010'
# UVM_INFO crc7_monitor.sv(28) @ 675: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '0010100'
# UVM_INFO crc7_monitor.sv(28) @ 685: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '0101000'
# UVM_INFO crc7_monitor.sv(28) @ 695: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '1010000'
# UVM_INFO crc7_monitor.sv(28) @ 705: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '0101001'
# UVM_INFO crc7_monitor.sv(28) @ 715: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '1010010'
# UVM_INFO crc7_monitor.sv(28) @ 725: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '0101101'
# UVM_INFO crc7_monitor.sv(28) @ 735: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '1011010'
# UVM_INFO crc7_monitor.sv(28) @ 745: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '0111101'
# UVM_INFO crc7_monitor.sv(28) @ 755: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '1111010'
# UVM_INFO crc7_monitor.sv(28) @ 765: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '1111101'
# UVM_INFO crc7_monitor.sv(28) @ 775: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '1110011'
# UVM_INFO crc7_monitor.sv(28) @ 785: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '1101111'
# UVM_INFO crc7_monitor.sv(28) @ 795: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '1010111'
# UVM_INFO crc7_monitor.sv(28) @ 805: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '0100111'
# UVM_INFO crc7_monitor.sv(28) @ 815: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '1001110'
# UVM_INFO crc7_monitor.sv(28) @ 825: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '0010101'
# UVM_INFO crc7_monitor.sv(28) @ 835: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '0101010'
# UVM_INFO crc7_monitor.sv(77) @ 835: uvm_test_top.c7_env.c7_agent.c7_mon_after [monitor_after] c7_tx.crc is '0101010'
# UVM_INFO crc7_scoreboard.sv(50) @ 835: uvm_test_top.c7_env.c7_sb [sb_compare] ---transaction_after.crc '0101010'
# UVM_INFO crc7_scoreboard.sv(51) @ 835: uvm_test_top.c7_env.c7_sb [sb_compare] ---transaction_before.crc '0101010'
# UVM_INFO crc7_scoreboard.sv(52) @ 835: uvm_test_top.c7_env.c7_sb [compare] Test: OK!
# UVM_INFO crc7_monitor.sv(28) @ 845: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '0000000'
# UVM_INFO crc7_monitor.sv(28) @ 855: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '0000000'
# UVM_INFO crc7_monitor.sv(28) @ 865: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '0000000'
# UVM_INFO crc7_monitor.sv(28) @ 875: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '0001001'
# UVM_INFO crc7_monitor.sv(28) @ 885: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '0010010'
# UVM_INFO crc7_monitor.sv(28) @ 895: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '0101101'
# UVM_INFO crc7_monitor.sv(28) @ 905: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '1011010'
# UVM_INFO crc7_monitor.sv(28) @ 915: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '0111101'
# UVM_INFO crc7_monitor.sv(28) @ 925: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '1111010'
# UVM_INFO crc7_monitor.sv(28) @ 935: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '1110100'
# UVM_INFO crc7_monitor.sv(28) @ 945: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '1100001'
# UVM_INFO crc7_monitor.sv(28) @ 955: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '1001011'
# UVM_INFO crc7_monitor.sv(28) @ 965: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '0011111'
# UVM_INFO crc7_monitor.sv(28) @ 975: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '0111110'
# UVM_INFO crc7_monitor.sv(28) @ 985: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '1111100'
# UVM_INFO crc7_monitor.sv(28) @ 995: uvm_test_top.c7_env.c7_agent.c7_mon_before [monitor_before] c7_tx.crc is '1110001'
add wave \
sim:/crc7_tb_top/vif/sig_clk
# End time: 16:04:23 on Jul 25,2019, Elapsed time: 0:19:56
# Errors: 0, Warnings: 1
高清大图来一下:
1、工程结构
2、运行结果
3、UVM DPI
4、UVM源码