如何在UVM的post_write/post_read回调中访问寄存器字段值
寄存器post_write/post_read回调中获取字段值的实现方法
完全可以通过寄存器的post_write/post_read回调实现需求,不用局限于字段的post_predict。以下是具体实现思路和代码示例:
核心思路
在寄存器的读写回调中,直接通过寄存器对象遍历其下属的所有字段,要么从寄存器镜像中读取字段当前值,要么从rw对象的原始值中解析出字段值,之后统一打印并写入文件。
代码示例(以UVM环境为例)
virtual function void post_write(uvm_reg_item rw); uvm_reg_field fields[$]; string log_content; int file_desc; // 获取当前寄存器的所有字段列表 this.get_fields(fields); // 拼接寄存器级日志 log_content = $sformatf("=== Register Access Log ===\nRegister Name: %s\nTotal Value: 0x%0h", this.get_full_name(), rw.value[0]); // 遍历每个字段,拼接字段信息 foreach(fields[idx]) begin uvm_reg_field curr_field = fields[idx]; // 方式1:从寄存器镜像中获取字段值(读写后镜像已更新) bit [31:0] fld_val = curr_field.get(); // 方式2:直接从rw.value中解析字段值(不依赖镜像) // bit [31:0] fld_val = (rw.value[0] >> curr_field.get_lsb()) & ((1 << curr_field.get_width()) - 1); log_content = $sformatf("%s\n Field: %s | Value: 0x%0h | Bit Range: [%0d:%0d]", log_content, curr_field.get_name(), fld_val, curr_field.get_msb(), curr_field.get_lsb()); end // 打印到控制台 $display("\n%s\n", log_content); // 写入日志文件(追加模式) file_desc = $fopen("register_access_log.txt", "a"); if(file_desc != 0) begin $fdisplay(file_desc, "%s\n", log_content); $fclose(file_desc); end endfunction
关键说明
get_fields()方法可以获取当前寄存器下的所有字段,返回一个动态数组- 两种获取字段值的方式任选:
- 方式1依赖寄存器镜像,适合需要确认镜像同步状态的场景
- 方式2直接从读写操作的原始值解析,不依赖寄存器内部状态,更轻量化
- 回调函数中的
rw对象包含了本次读写的完整信息,包括操作类型、地址、原始值等
post_read回调的适配
把上述代码复制到post_read回调中即可,逻辑完全通用,因为读操作完成后寄存器镜像同样会更新,字段值的获取方式一致。
内容的提问来源于stack exchange,提问作者pakooran
相关产品推荐
相关产品推荐

