构建一个简单的UVM验证平台
本次构建的验证平台不包含DUT。
创建transaction和sequence
transaction代码如下:
class my_transaction extends uvm_sequence_item;
rand bit [4:0] sa;
rand bit [3:0] da;
rand reg [7:0] payload[$]; //定义数据成员
`uvm_object_utils_begin(my_transaction)
`uvm_field_int(sa, UVM_ALL_ON);
`uvm_field_int(da, UVM_ALL_ON);
`uvm_field_queue_int(payload, UVM_ALL_ON);
`uvm_object_utils_end
// 约束
constraint Limit{
sa inside { [0:15] };
da inside { [0:15] };
payload.size() inside { [2:4] };
}
function new(string name = "my_transaction");
super.new(name);
endfunction
endclass
sequence代码如下:
class my_sequence extends uvm_sequence #(my_transaction);
`uvm_object_utils(my_sequence)
function new(string name = "my_sequence");
super.new(name);
endfunction
virtual task body();
if(starting_phase != null)
starting_phase.raise_objection(this);
repeat(10) begin
`uvm_do(req);
end
#100;
if(starting_phase != null)
starting_phase.drop_objection(this);
endtask
endclass
创建sequencer和driver
sequencer的代码如下:
typedef uvm_sequencer #(my_transaction) my_sequencer;
driver的代码如下:
class my_driver extends uvm_driver #(my_transaction);
`uvm_component_utils(my_driver)
function new(string name = "my_driver", uvm_component parent);
super.new(name, parent);
endfunction
virtual task run_phase(uvm_phase phase);
forever begin
seq_item_port.get_next_item(req);
`uvm_info("DRV_RUN_PHASE", req.sprint(), UVM_MEDIUM)
#100;
seq_item_port.item_done();
end
endtask
endclass
seq_item_port为uvm_driver类内建的接口,用于与sequencer的TLM通信,即把transaction传输到driver。
创建monitor
class my_monitor extends uvm_monitor;
`uvm_component_utils(my_monitor);
function new(string name = "", uvm_component parent);
super.new(name, parent);
endfunction
virtual task run_phase(uvm_phase phase);
forever begin
`uvm_info("MON_RUN_PHASE", "Monitor run!", UVM_MEDIUM);
#100;
end
endtask
endclass
创建agent
class master_agent extends uvm_agent;
`uvm_component_utils(master_agent)
my_sequencer m_seqr;
my_driver m_driv;
my_monitor m_moni;
function new(string name = "", uvm_component parent);
super.new(name, parent);
endfunction
virtual function void build_phase(uvm_phase phase);
super.build_phase(phase);
if(is_active == UVM_ACTIVE) begin
m_seqr = my_sequencer::type_id::create("m_seqr", this);
m_driv = my_driver::type_id::create("m_driv", this);
end
m_moni = my_monitor::type_id::create("m_moni", this);
endfunction
virtual function void connect_phase(uvm_phase phase);
if(is_active == UVM_ACTIVE)
m_driv.seq_item_port.connect(m_seqr.seq_item_export);
endfunction
endclass
m_driv.seq_item_port.connect(m_seqr.seq_item_export);
实现driver和sequencer通信端口的连接。
创建envirenment和testcase
创建envirenment:
class my_env extends uvm_env;
`uvm_component_utils(my_env)
master_agent m_agent;
function new(string name = "", uvm_component parent);
super.new(name, parent);
endfunction
virtual function void build_phase(uvm_phase phase);
super.build_phase(phase);
m_agent = master_agent::type_id::create("m_agent", this);
endfunction
endclass
m_agent = master_agent::type_id::create(“m_agent”, this);
通过uvm的factory机制实例化对象。
testcase代码如下:
class my_test extends uvm_test;
`uvm_component_utils(my_test)
my_env m_env;
function new(string name = "", uvm_component parent);
super.new(name, parent);
endfunction
virtual function void build_phase(uvm_phase phase);
super.build_phase(phase);
m_env = my_env::type_id::create("m_env", this);
uvm_config_db#(uvm_object_wrapper)::set(
this, "*.m_seqr.run_phase",
"default_sequence", my_sequence::get_type());
endfunction
virtual function void start_of_simulation_phase(uvm_phase phase);
super.start_of_simulation_phase(phase);
uvm_top.print_topology(uvm_default_tree_printer);
endfunction
endclass
顶层
program automatic test;
import uvm_pkg::*;
`include "uvm_macros.svh"
`include "my_transaction.sv"
`include "my_sequence.sv"
`include "my_sequencer.sv"
`include "my_driver.sv"
`include "my_monitor.sv"
`include "master_agent.sv"
`include "my_env.sv"
`include "my_test.sv"
initial begin
run_test("my_test");
end
endprogram
仿真
Makefile如下:
SEED = 1
default: test
test: compile run
run:
./simv -l simv.log +ntb_ramdom_seed=$(SEED)
compile:
vcs -l vcs.log -sverilog -debug_all -full64 -ntb_opts uvm-1.1 -timescale=1ns/100ps test.sv
clean:
rm -rf simv* csrc* *.tmp *.vpd *.key *.log *hdrs.h
来到仿真目录下,输入make开始编译及仿真,可以看到打印出的测试测试平台hierarchy如下:
版权声明:本文为weixin_45704530原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。