3. 编写UVM sequence产生随机激励
任务目标
编写一个UVM sequence,通过约束随机生成AHB-like总线事务(地址、数据、读写控制),并经sequencer发送至driver,最终在testbench中完成激励生成与驱动的闭环验证。
环境依赖
需要UVM-1.2库(或等效实现),仿真器支持+UVM_TESTNAME参数传递。以下代码基于标准UVM类库编写,不依赖额外IP。
核心实现
// 文件: ahb_transaction.svh
class ahb_transaction extends uvm_sequence_item;
rand bit [31:0] addr;
rand bit [31:0] data;
rand bit write;
rand bit [1:0] burst;
constraint c_addr_range { addr inside {[32'h0000_1000 : 32'h0000_2FFF]}; }
constraint c_burst_valid { burst != 2'b00; } // 禁止单次突发
`uvm_object_utils_begin(ahb_transaction)
`uvm_field_int(addr, UVM_ALL_ON)
`uvm_field_int(data, UVM_ALL_ON)
`uvm_field_int(write, UVM_ALL_ON)
`uvm_field_int(burst, UVM_ALL_ON)
`uvm_object_utils_end
function new(string name = "ahb_transaction");
super.new(name);
endfunction
endclass
// 文件: my_sequence.svh
class my_sequence extends uvm_sequence #(ahb_transaction);
`uvm_object_utils(my_sequence)
function new(string name = "my_sequence");
super.new(name);
endfunction
task body();
ahb_transaction tx;
repeat (10) begin
tx = ahb_transaction::type_id::create("tx");
start_item(tx);
assert(tx.randomize());
finish_item(tx);
end
endtask
endclass
// 文件: my_driver.svh
class my_driver extends uvm_driver #(ahb_transaction);
`uvm_component_utils(my_driver)
function new(string name = "my_driver", uvm_component parent = null);
super.new(name, parent);
endfunction
virtual task run_phase(uvm_phase phase);
ahb_transaction tx;
forever begin
seq_item_port.get_next_item(tx);
// 模拟驱动:打印事务内容(实际设计中此处驱动总线信号)
`uvm_info("DRV", $sformatf("Driving: %s", tx.convert2string()), UVM_MEDIUM)
seq_item_port.item_done();
end
endtask
endclass
// 文件: testbench_top.sv(最小验证环境)
module testbench_top;
import uvm_pkg::*;
// 简单连接:driver直接挂在sequencer上
class my_env extends uvm_env;
`uvm_component_utils(my_env)
my_driver drv;
uvm_sequencer #(ahb_transaction) seqr;
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction
function void build_phase(uvm_phase phase);
super.build_phase(phase);
drv = my_driver::type_id::create("drv", this);
seqr = uvm_sequencer#(ahb_transaction)::type_id::create("seqr", this);
endfunction
function void connect_phase(uvm_phase phase);
super.connect_phase(phase);
drv.seq_item_port.connect(seqr.seq_item_export);
endfunction
endclass
class my_test extends uvm_test;
`uvm_component_utils(my_test)
my_env env;
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction
function void build_phase(uvm_phase phase);
super.build_phase(phase);
env = my_env::type_id::create("env", this);
endfunction
task run_phase(uvm_phase phase);
my_sequence seq;
phase.raise_objection(phase);
seq = my_sequence::type_id::create("seq");
seq.start(env.seqr);
#100ns;
phase.drop_objection(phase);
endtask
endclass
initial begin
run_test("my_test");
end
endmodule
运行方式
# 使用支持UVM的仿真器(如VCS、Questa等)
vlog +incdir+$UVM_HOME/src $UVM_HOME/src/uvm.sv \
ahb_transaction.svh my_sequence.svh my_driver.svh testbench_top.sv
vsim -c -do "run -all; quit" testbench_top +UVM_TESTNAME=my_test
验证方法与判定标准
- 约束随机性验证:观察打印的10个事务,确认
addr始终在0x1000~0x2FFF范围内,且burst值不为0。 - 驱动闭环验证:仿真日志中应出现10条
UVM_INFO DRV记录,每条包含完整的地址、数据、读写和突发类型信息,表明sequence生成的每个事务均被driver成功接收并处理。 - 无UVM错误:仿真结束时UVM报告无
UVM_ERROR或UVM_FATAL,且objection机制正确平衡(无“Objection raised but not dropped”警告)。
若日志中事务数量不足10或地址越界,则说明随机约束或sequence-driver握手存在缺陷,需检查约束声明和start_item/finish_item调用时序。