1. 注入随机位错误到数据总线
任务目标
在UVM测试平台中构建一个可注入随机位错误的sequence,向DUT数据总线施加含单比特翻转的激励,用于验证DUT的检错(如ECC或奇偶校验)机制能否正确触发错误标志。
实现方案
通过自定义sequence随机选择待翻转的比特位,在数据从driver发送前完成异或翻转。核心在于:错误注入点位于sequence层,保证driver与interface无需感知错误注入逻辑,仅需传递原始数据与错误标志。
关键完整代码
// 错误注入sequence:随机翻转数据总线上的单个比特
class err_inject_seq extends uvm_sequence #(bus_transaction);
`uvm_object_utils(err_inject_seq)
function new(string name = "err_inject_seq");
super.new(name);
endfunction
virtual task body();
bus_transaction tx;
bit [31:0] data_with_err;
int err_bit;
// 创建正常事务
tx = bus_transaction::type_id::create("tx");
start_item(tx);
if (!tx.randomize() with { tx.data inside {[32'h0000_0001 : 32'hFFFF_FFFF]}; })
`uvm_fatal(get_type_name(), "Randomize failed")
// 随机选择要翻转的比特位(0~31)
err_bit = $urandom_range(0, 31);
// 注入单比特错误:异或翻转
data_with_err = tx.data ^ (1 << err_bit);
// 更新事务数据并标记错误注入
tx.data = data_with_err;
tx.err_injected = 1;
tx.err_position = err_bit;
finish_item(tx);
endtask
endclass
事务定义与接口连接
// 事务类:包含数据与错误注入元数据
class bus_transaction extends uvm_sequence_item;
`uvm_object_utils(bus_transaction)
rand bit [31:0] data;
bit err_injected; // 是否注入了错误
int err_position; // 错误比特位置
function new(string name = "bus_transaction");
super.new(name);
endfunction
`uvm_field_int(data, UVM_ALL_ON)
`uvm_field_int(err_injected, UVM_ALL_ON)
`uvm_field_int(err_position, UVM_ALL_ON)
endclass
运行与验证
- 集成方式:在测试类(test)的main_phase中,通过
seq.start(sequencer)启动上述sequence。 - DUT检错验证:在scoreboard中比较DUT输出的错误标志(如
err_flag)与tx.err_injected是否一致。若DUT检错机制有效,则当err_injected=1时,DUT应拉高错误标志。 - 运行命令(示例,具体取决于仿真器):
vsim +UVM_TESTNAME=base_test work.tb_top - 通过条件:仿真结束无UVM_ERROR,且scoreboard中比对计数器显示:注入错误的100个事务全部被DUT检错标志捕获(匹配率100%)。
验证要点
- 本sequence每次仅翻转1个比特,覆盖单比特错误场景。若需多比特翻转,可修改
err_bit为随机数组。 - 错误注入位置
err_position用于scoreboard精确比对,确保DUT报错对应的数据周期正确。 - 若DUT采用ECC机制,可额外检查DUT是否输出纠正后数据;本案例仅验证检错标志触发。