2. 实现矩阵加法模块的参考模型
任务目标
编写一个UVM参考模型(reference model),模拟矩阵加法运算,将激励驱动后得到的预期结果传递给后续比较器(scoreboard),用于与DUT输出进行比对。
实现方案
参考模型通过uvm_analysis_port接收从driver发送的输入事务(两个输入矩阵),在内部执行矩阵加法,并将计算结果封装为输出事务,通过另一个analysis port发送给scoreboard。参考模型本身不关心时序,只负责纯组合逻辑运算。
关键完整代码
<code>// 文件: ref_model.sv
class ref_model extends uvm_component;
`uvm_component_utils(ref_model)
uvm_analysis_imp #(matrix_txn, ref_model) in_port; // 接收输入激励
uvm_analysis_port #(matrix_txn) out_port; // 发送预期结果
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction
function void build_phase(uvm_phase phase);
super.build_phase(phase);
in_port = new("in_port", this);
out_port = new("out_port", this);
endfunction
// 由analysis imp自动回调,每收到一个输入事务执行一次
function void write(matrix_txn txn);
matrix_txn exp_txn = matrix_txn::type_id::create("exp_txn");
exp_txn.copy(txn); // 复制维度、ID等公共字段
exp_txn.data = new[txn.data.size()];
// 矩阵加法:A + B(数据按行主序存储)
foreach (txn.data[i]) begin
exp_txn.data[i] = txn.data[i] + txn.data_b[i];
end
out_port.write(exp_txn);
endfunction
endclass
事务定义(依赖说明)
// 文件: matrix_txn.sv(已在前序环境定义,此处仅列出关键字段)
class matrix_txn extends uvm_sequence_item;
rand int rows, cols;
rand byte data[]; // 矩阵A
rand byte data_b[]; // 矩阵B
// ... 约束与copy/compare等标准方法
endclass
集成方式
在env中实例化参考模型并完成连接:
// 在env的connect_phase中
ref_mdl.in_port.connect(driver.analysis_port); // driver发送激励给参考模型
ref_mdl.out_port.connect(scoreboard.exp_imp); // 参考模型输出预期结果
运行与验证
- 编译:确保UVM库已链接,编译命令示例:
vlog +incdir+$UVM_HOME/src ref_model.sv matrix_txn.sv - 运行:在测试用例中启动sequence,驱动发送矩阵A和B后,参考模型自动计算A+B并发送给scoreboard。
- 通过条件:scoreboard收到参考模型输出与DUT输出,逐元素比较;若所有元素相等且比较次数与激励次数一致,则测试通过。可在scoreboard中打印比较结果,观察是否出现“MATCH”或“MISMATCH”提示。
常见问题
- 若数据位宽超过byte范围,请根据实际DUT位宽修改data类型(如改为shortint或int)。
- 确保driver发送的txn中data和data_b长度一致且等于rows*cols,否则foreach会越界。
- 参考模型为组合逻辑,不处理复位或时钟;若DUT有时序延迟,需在scoreboard中做对齐处理。