4. 模拟地址越界访问
任务目标
构造超出存储器映射地址范围的读写请求,驱动到DUT接口,验证地址保护机制能够正确识别越界访问并产生响应(如错误应答或总线异常),同时不影响合法地址空间的正常操作。
环境与依赖
基于UVM 1.2,需要标准UVM库。DUT为带地址保护的简单存储器模型,地址空间为0x0000_0000 ~ 0x0000_0FFF(4KB),越界地址定义为超出此范围。使用UVM寄存器模型或直接sequence驱动均可,本案例采用直接sequence方式以聚焦地址越界场景。
关键完整代码
// 文件: addr_overflow_seq.sv
class addr_overflow_seq extends uvm_sequence #(bus_transaction);
`uvm_object_utils(addr_overflow_seq)
function new(string name = "addr_overflow_seq");
super.new(name);
endfunction
virtual task body();
bus_transaction req;
// 合法边界地址(应正常响应)
req = bus_transaction::type_id::create("req");
start_item(req);
req.addr = 32'h0000_0FFC; // 合法空间最后一个word
req.kind = bus_transaction::READ;
finish_item(req);
// 越界地址:刚好超出4KB边界
req = bus_transaction::type_id::create("req");
start_item(req);
req.addr = 32'h0000_1000; // 越界首地址
req.kind = bus_transaction::READ;
finish_item(req);
// 越界地址:远高于地址空间
req = bus_transaction::type_id::create("req");
start_item(req);
req.addr = 32'hFFFF_0000;
req.kind = bus_transaction::WRITE;
req.data = 32'hDEAD_BEEF;
finish_item(req);
// 再次合法访问,验证保护机制不影响正常操作
req = bus_transaction::type_id::create("req");
start_item(req);
req.addr = 32'h0000_0000;
req.kind = bus_transaction::WRITE;
req.data = 32'h1234_5678;
finish_item(req);
endtask
endclass
// 文件: addr_overflow_test.sv
class addr_overflow_test extends uvm_test;
`uvm_component_utils(addr_overflow_test)
function new(string name = "addr_overflow_test", uvm_component parent = null);
super.new(name, parent);
endfunction
virtual function void build_phase(uvm_phase phase);
super.build_phase(phase);
// 假设env已在更高层构建,此处仅做简化示例
endfunction
virtual task run_phase(uvm_phase phase);
addr_overflow_seq seq;
phase.raise_objection(this);
seq = addr_overflow_seq::type_id::create("seq");
seq.start(uvm_top.find("*.env.agent.sqr"));
#100ns;
phase.drop_objection(this);
endtask
endclass
// 文件: bus_transaction.sv(最小定义)
class bus_transaction extends uvm_sequence_item;
`uvm_object_utils(bus_transaction)
rand bit [31:0] addr;
rand bit [31:0] data;
rand bit is_write;
typedef enum {READ, WRITE} kind_t;
rand kind_t kind;
bit error_flag; // DUT返回的越界标志
function new(string name = "bus_transaction");
super.new(name);
endfunction
`uvm_field_int(addr, UVM_ALL_ON)
`uvm_field_int(data, UVM_ALL_ON)
`uvm_field_enum(kind_t, kind, UVM_ALL_ON)
`uvm_field_int(error_flag, UVM_ALL_ON)
endclass
DUT地址保护行为约定
DUT对越界读返回data=32'hFFFF_FFFF并置error_flag=1;对越界写不产生存储效应,仅置error_flag=1。合法访问时error_flag=0且数据正常读写。
运行方式
# 在UVM环境中编译并运行
vlog +incdir+$UVM_HOME/src bus_transaction.sv addr_overflow_seq.sv addr_overflow_test.sv dut.sv top.sv
vsim -c -do "run -all; quit" work.top
验证方法与判定标准
- 在scoreboard中检查:对
0x1000和0xFFFF_0000的访问,monitor捕获到的error_flag必须为1; - 对
0x0FFC的读和0x0000的写,error_flag必须为0,且写后读回数据一致; - 仿真结束时打印
UVM_ERROR计数为0,表明所有越界访问均被正确标记,合法访问未受影响。
若DUT未置error_flag或合法访问被误判,则说明地址保护逻辑存在缺陷,测试失败。