[CU]reg model构建篇-uvm_reg_field
资料来源
(1) 《UVM cookbook》
前言
(1) 按照单位由小到大依次罗列,分别为uvm_reg_field->uvm_reg,uvm_mem,uvm_reg_file,uvm_reg_map->uvm_reg_adapter,uvm_reg_block, uvm_reg_predictor;
1. uvm_reg_field概念
(1) uvm_reg_field是寄存器模型的最小单位,在uvm_reg的build函数内实例化,和DUT中每个register里的field对应;
2. uvm_reg_field源码
1 `ifndef UVM_REG_ADDR_WIDTH 2 //可以通过改变这个宏的值来改变register model所能表示的最大寄存器的值; 3 `define UVM_REG_ADDR_WIDTH 64 4 `endif 5 6 `ifndef UVM_REG_DATA_WIDTH 7 `define UVM_REG_DATA_WIDTH 64 8 `endif 9 10 typedef bit unsigned[`UVM_REG_DATA_WIDTH-1:0] uvm_reg_data_t; 11 12 class uvm_reg_field extends uvm_object; 13 14 //注意value的类型是rand,表示可以进行随机化; 15 rand uvm_reg_data_t value; // Mirrored after randomize() 16 17 local uvm_reg_data_t m_mirrored; // What we think is in the HW 18 local uvm_reg_data_t m_desired; // Mirrored after set() 19 20 //下面这组变量在调用uvm_reg_field的configure函数时,进行初始化操作; 21 local string m_access; //表示reg_field的存储特性,如RW,RO等; 22 local uvm_reg m_parent; //表示reg_field所在uvm_reg的指针; 23 local int unsigned m_lsb; //表示reg_field最低位在uvm_reg中的位置; 24 local int unsigned m_size; //表示reg_field占据了几个bit; 25 local bit m_volatile; //表示reg_field的volatile特性; 26 //表示reg_field复位后的值,m_reset是一个联合数组,表示reg_field可以有多个复位值,如硬复位,软复位等; 27 local uvm_reg_data_t m_reset[string]; 28 local bit m_written; 29 local bit m_read_in_progress; 30 local bit m_write_in_progress; 31 local string m_fname; 32 local int m_lineno; 33 local int m_cover_on; 34 local bit m_individually_accessible; 35 local uvm_check_e m_check; 36 ... 37 endclass
1 //示例 2 class my_fld_type extends uvm_reg_field; 3 `uvm_object_utils(my_fld_type) 4 5 function new(string name="my_fld_type"); 6 super.new(name); 7 endfunction 8 9 constraint valid { value inside {0,1,2,4,8,16,32};}; 10 endclass
3. uvm_reg_field的configure函数
(1) configure函数首先对一些成员变量进行赋值;
(2) 在调用m_parent(uvm_reg)的add_field函数时,函数内部会检测register是否已经被lock住了; 如果被lock住,该reg中就不能再加入任何field(一般的,当整个register model建立完成后,会在最顶层的uvm_reg_block调用lock相关函数,将整个模型锁起来);
(3)调用m_parent的add_field函数的效果是将该field加入到uvm_reg的m_fields数组中(这部分的源代码不错);
(4) uvm_reg_field的例化以及configure函数的调用均在uvm_reg的build函数内实现;
1 function void uvm_reg_field::configure(uvm_reg parent, 2 int unsigned size, 3 int unsigned lsb_pos, 4 string access, 5 bit volatile, 6 uvm_reg_data_t reset, 7 bit has_reset, 8 bit is_rand, 9 bit individually_accessible); 10 m_parent = parent; 11 if (size == 0) begin 12 `uvm_error("RegModel", 13 $sformatf("Field \"%s\" cannot have 0 bits", get_full_name())); 14 size = 1; 15 end 16 17 m_size = size; 18 m_volatile = volatile; 19 m_access = access.toupper(); 20 m_lsb = lsb_pos; 21 m_cover_on = UVM_NO_COVERAGE; 22 m_written = 0; 23 m_check = volatile ? UVM_NO_CHECK : UVM_CHECK; 24 m_individually_accessible = individually_accessible; 25 26 if (has_reset) 27 set_reset(reset); 28 else 29 uvm_resource_db#(bit)::set({"REG::", get_full_name()}, 30 "NO_REG_HW_RESET_TEST", 1); 31 32 m_parent.add_field(this); 33 34 if (!m_policy_names.exists(m_access)) begin 35 `uvm_error("RegModel", {"Access policy '",access, 36 "' for field '",get_full_name(),"' is not defined. Setting to RW"}) 37 m_access = "RW"; 38 end 39 40 if (size > m_max_size) 41 m_max_size = size; 42 43 // Ignore is_rand if the field is known not to be writeable 44 // i.e. not "RW", "WRC", "WRS", "WO", "W1", "WO1" 45 case (access) 46 "RO", "RC", "RS", "WC", "WS", 47 "W1C", "W1S", "W1T", "W0C", "W0S", "W0T", 48 "W1SRC", "W1CRS", "W0SRC", "W0CRS", "WSRC", "WCRS", 49 "WOC", "WOS": is_rand = 0; 50 endcase 51 52 if (!is_rand) 53 value.rand_mode(0); 54 55 m_field_registry[get_full_name()] = this; 56 endfunction: configure
关于uvm_reg_field configure函数输入参数的含义详见<<UVM实战>>参考资料;
参数1含义:该uvm_reg_field的父辈,即该域位于哪个寄存器中,传递为this;
参数2含义:该uvm_reg_field的宽度;
参数3含义:该uvm_reg_field最低位在该寄存器中的位置,从0开始计数;
参数4含义:该uvm_reg_field的存取方式,如RO,RW,RC,RS等25中存取方式,用户可自定义存取方式;
注1: RW的测试,先写后读,写全0,全1,全a,全5;
注2: RO的测试,先写一个非零值,再读,读出值是0,测不可写;
注3: WO的测试,先写一个非零值,再读,读出值是0;
注4: RC的测试,寄存器有一个非零值,读出,会返回非零值(???),再读,会返回0;
参数5含义:表明是否为易失的;
参数6含义:表明该uvm_reg_field上电复位后的默认值;
参数7含义:表明该uvm_reg_field是否有上电复位;
参数8含义:表明该域是否可以随机化;
参数9含义:表明该域是否可以单独存取;
4. uvm_reg_field的其他操作
(1) 当通过uvm_reg_field::read()或uvm_reg_field::write()进行register field的读写操作时,实际发生什么取决于多种因素,可能只是该register field被读写,也可能是包含该register field的整个register被读写;
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?