//------------UVM基础知识篇------------
package pack1; //pack1头
import uvm_pkg::*; //+UVM
`include "uvm_macros.svh"//+工厂
//目标类与组件类,目标类可以游离的存在,组件类必须挂在某个位置,或许是
//root或许是其他组件
//目标类
class obj1 extends uvm_object;
//顺序1:属性
bit [7:0] data0 = 'haa;
bit [7:0] data1 = 'hbb;
//顺序2:工厂
`uvm_object_utils(obj1)
//顺序3:方法
function new();//构造函数
super.new();//调用父类构造函数
`uvm_info("class:obj1",$sformatf("data0:%x!",data0),UVM_LOW)
`uvm_info("class:obj1",$sformatf("data1:%x!",data1),UVM_LOW)
//UVM信息:组别,打印信息,优先级(UVM_LOW优先级很高)
endfunction
//也可以定义类的外部方法,来解决一个类中方法过长的现象
extern task xxx();
endclass
task obj1::xxx();
`uvm_info("class:obj1",$sformatf("this is xxx task"),UVM_LOW)
endtask
//目标类
class obj2 extends obj1;
bit [7:0] data1 = 'hcc;//这个data1并不会覆盖掉父类的data1
//而是会分化成this.data1 和 super.data1
//直接使用data1默认为this.data1
`uvm_object_utils(obj2)
function new();//构造函数
//super.new();
//如果你使用了extends,即使你不super.new,实际上系统还
//是会帮你调用你父类的构造函数new
`uvm_info("class:obj2",$sformatf("data1:%x!",data1),UVM_LOW)
`uvm_info("class:obj2",$sformatf("super.data1:%x!",super.data1),UVM_LOW)
`uvm_info("class:obj2",$sformatf("this.data1:%x!",this.data1),UVM_LOW)
endfunction
endclass
//组件类
class comp1 extends uvm_component;
`uvm_component_utils(comp1)
function new(string name = "comp1",uvm_component parent = null);
//组件类的构造函数,必须要有名字和指明挂载父类
//parent = null 代表该组件被例化后默认挂载在uvm_root下
super.new(name,parent);
`uvm_info("class:comp1",$sformatf("handle is %s",name), UVM_LOW)
endfunction
endclass
//组件类
class comp2 extends comp1;
`uvm_component_utils(comp2)
function new(string name = "comp2", uvm_component parent = null);
super.new(name, parent);
`uvm_info("class:comp2",$sformatf("handle is %s",name), UVM_LOW)
endfunction
endclass
//UVM_TEST
//可由run_test函数直接例化,并执行phase机制
class test1 extends uvm_test;
comp2 a,b,c;
`uvm_component_utils(test1)
function new(string name = "test1", uvm_component parent = null);
super.new(name, parent);
endfunction
function void build_phase(uvm_phase phase);
super.build_phase(phase);
`uvm_info("test1",$sformatf("build"), UVM_LOW)
a = new("a",null);//这个会被挂在root下
b = new("b",this);//这个会被挂在test1下
c = comp2::type_id::create("c",null);//使用工厂的实例化方法
endfunction
task run_phase(uvm_phase phase);
phase.raise_objection(this);//进入run_phase需要先举手
`uvm_info("test1",$sformatf("run0"), UVM_LOW)
#1us;
`uvm_info("test1",$sformatf("run1"), UVM_LOW)
phase.drop_objection(this);//退出run_phase需要先落手
endtask
endclass
//----------------------------类覆盖------------------------------
//有类xy,且y是x子类
//在类x中,声明了类a的句柄
//在类y中,想把类a覆盖为类b,可以使用类覆盖
//但类b也必须是类a的子类,经过测试a需要是组件类,而目标类跑不通。
class a extends uvm_component;
bit [3:0] va ='ha;
`uvm_component_utils(a)
function new(string name = "a", uvm_component parent = null);
super.new(name, parent);
endfunction
endclass
class b extends a;
`uvm_component_utils(b)
function new(string name = "b", uvm_component parent = null);
super.new(name, parent);
super.va = 'hb; //改变类a的属性
endfunction
endclass
class x extends uvm_test;
a handle0,handle1;
`uvm_component_utils(x)
function new(string name = "x", uvm_component parent = null);
super.new(name, parent);
endfunction
function void build_phase(uvm_phase phase);
super.build_phase(phase);
handle0 = a::type_id::create("handle0",this);//使用工厂的实例化方法
handle1 = a::type_id::create("handle1",this);//使用工厂的实例化方法
`uvm_info("x build phase",$sformatf("handle0.va=%x",handle0.va), UVM_LOW)
`uvm_info("x build phase",$sformatf("handle1.va=%x",handle1.va), UVM_LOW)
endfunction
endclass
class y extends x;
`uvm_component_utils(y)
function new(string name = "y", uvm_component parent = null);
super.new(name, parent);
endfunction
function void build_phase(uvm_phase phase);
set_type_override("a", "b");//类覆盖
//另一个实现类覆盖的方法
//set_type_override_by_type(a::get_type(),b::get_type());
super.build_phase(phase);
//这个super是要放在后面的,因为要先替换后例化
endfunction
endclass
endpackage //pack1尾
//--------------------------------------module1---------------------------------
module hardware1;
import pack1::*;
import uvm_pkg::*; //+UVM
initial begin
obj2 handle0;
obj1 handle1;
handle0 = new();
handle1 = new();
handle1.xxx();
run_test("y");//直接例化test,并执行phase机制
end
endmodule
//----------------------------------------------------------------------------
//
//
//
//
//
//
//
interface interf1;
logic [31:0] addr;
logic [31:0] data;
endinterface
package pack2; //pack2头
import uvm_pkg::*; //+UVM
`include "uvm_macros.svh"//+工厂
//----------------------------config机制------------------------------
//UVMconfig机制,在相对上层的位置,为相对下层的位置来配置信息,这个信息
//大致有三种:虚接口、单一变量、对象
//上层把要传递的信息贴上标号,然后甩到某个UVM层级下,在questasim中sim栏
//的instance中可以看到这个UVM层级关系。
//下层要按照标号,去指定的层级搜索,由上层传递下来的配置信息
//"虚接口"传递
class comp2 extends uvm_component;
virtual interf1 vif;
`uvm_component_utils(comp2)
function new(string name = "comp2", uvm_component parent = null);
super.new(name, parent);
`uvm_info("CREATE", $sformatf("unit type [%s] created", name), UVM_LOW)
endfunction
function void build_phase(uvm_phase phase);
super.build_phase(phase);
//*
if(!uvm_config_db#(virtual interf1)::get(this, "", "label0", vif))begin
//到当前层级下找
//标号为label0的
//interf1的实例
//放入vif中
`uvm_error("config_db", "can't find label0 in this hierarchy!")
end
else begin
`uvm_info("config_db","config_success!", UVM_LOW)
end
endfunction
endclass
//"单一变量"传递
class comp1 extends uvm_component;
int value;
`uvm_component_utils(comp1)
function new(string name = "comp1", uvm_component parent = null);
super.new(name, parent);
`uvm_info("CREATE", $sformatf("unit type [%s] created", name), UVM_LOW)
endfunction
function void build_phase(uvm_phase phase);
super.build_phase(phase);
//*
if(!uvm_config_db#(int)::get(this, "", "val", value))begin
//到当前层级下找
//标号为val的
//放入value中
`uvm_error("config_db", "can't find val in this hierarchy!")
end
else begin
`uvm_info("config_db","config_success!", UVM_LOW)
`uvm_info("config_db", $sformatf("Value is %h!", value), UVM_LOW)
end
endfunction
endclass
//"对象"传递
class obj1 extends uvm_object;
bit [7:0] data0 = 'haa;
`uvm_object_utils(obj1)
function new();
super.new();
endfunction
endclass
class comp0 extends uvm_component;
obj1 o1;
`uvm_component_utils(comp0)
function new(string name = "comp0", uvm_component parent = null);
super.new(name, parent);
`uvm_info("CREATE", $sformatf("unit type [%s] created", name), UVM_LOW)
endfunction
function void build_phase(uvm_phase phase);
super.build_phase(phase);
//*
if(!uvm_config_db#(obj1)::get(this, "", "object", o1))begin
//到当前层级下找
//标号为object的
//放入o1中
`uvm_error("config_db", "can't find object in this hierarchy!")
end
else begin
`uvm_info("config_db","config_success!", UVM_LOW)
`uvm_info("config_db", $sformatf("o1.data0 is %h!", o1.data0), UVM_LOW)
end
endfunction
endclass
//test--------------------------------------------------------------------------------
class uvm_config_test extends uvm_test;
comp2 c2;
comp1 c1;
comp0 c0;
obj1 o;
`uvm_component_utils(uvm_config_test)
function new(string name = "uvm_config_test", uvm_component parent = null);
super.new(name, parent);
endfunction
function void build_phase(uvm_phase phase);
super.build_phase(phase);
c2 = comp2::type_id::create("c2",this);
//单一变量传递
uvm_config_db#(int)::set
(uvm_root::get(), "uvm_test_top.*", "val", 'ha5a5_5a5a);
c1 = comp1::type_id::create("c1",this);
//对象传递
o = obj1::type_id::create();
o.data0 = 8'haa;
uvm_config_db#(obj1)::set
(uvm_root::get(), "uvm_test_top.*", "object",o);
c0 = comp0::type_id::create("c0",this);
endfunction
task run_phase(uvm_phase phase);
super.run_phase(phase);
phase.raise_objection(this);
#1us;
phase.drop_objection(this);
endtask
endclass
endpackage //pack2尾
//----------------------------------------------------------------------------
//--------------------------------------module2---------------------------------
module hardware2;
import pack2::*;
import uvm_pkg::*; //+UVM
interf1 if0();
initial begin
//虚接口传递
uvm_config_db#(virtual interf1)::set
(uvm_root::get(), "uvm_test_top.*", "label0", if0);
//一共有五个参数
//=>第一个参数指明要配置信息的类型:这里是虚接口
//=>第二个和第三个参数联合起来组成目标路径,就是你所配置的这个
// 信息放到哪个层级下面,这里是:uvm_root->uvm_test_top->*。
// 第二个参数必须是component实例的指针,即为真实存在的组件,这里用的是uvm_root。
// uvm_root::get()也可以写成null
// 第三个参数是相对此实例的路径。
//=>第四个参数是一个标号,相同标号的set和get才可以共享资源
//=>第五个参数是具体的值
//接口传递应发生在run_test()之前。
//这保证了组件在进入build_phase要get之前,
//virtual interface已经被放入到特定区域中
run_test("uvm_config_test");
end
endmodule