文章目录
- 一、寄存器的访问方法汇总
- 二、以前门访问方式对方法进行说明
- 2.1. uvm_reg_field的属性成员介绍
- 2.2. configure()配置uvm_reg_field
- 2.3. 方法——reset()/get()/set()/randomize()—操作期望值
- 2.4. 方法——write()—写入DUT
- 2.5. 方法——read()—读出DUT
- 2.6. 方法——update()—写入DUT和更新镜像值
- 2.7. 方法——mirror()—读取DUT和更新镜像值
- 2.8. 方法——predict()—操作镜像值
一、寄存器的访问方法汇总
??寄存器模型相关类的访问方法:
??在此注意区分,uvm_reg所提供的四种方法
??寄存器序列提供的寄存器访问方法:
??上述方法由uvm_reg_sequence序列所提供,针对寄存器对象(Register)操作。
二、以前门访问方式对方法进行说明
2.1. uvm_reg_field的属性成员介绍
??在对寄存器访问方式进行介绍之前,先了解uvm_reg_field是如何存储寄存器的值。 uvm_reg_field使用四个属性来存储各种寄存器字段值。
- m_reset [“HARD”]——存储硬件复位值。 m_reset是一种带有重置键的关联数组。
- m_mirrored(
镜像值 )——存储DUT当前的已知状态值,镜像值往往有模型预测给出。 - m_desired(
期望值 )——存储我们想要设置给DUT的值,用以更新硬件(DUT)值。 - value(
真实值 )——存储硬件(DUT)真实值,该值会被采样并存储在功能覆盖率中,或者当该字段被随机化时该value值会被约束。
??在这些属性中,只有value值属性是
2.2. configure()配置uvm_reg_field
??在 创建uvm_reg_field后执行的第一件事是配置它。在寄存器抽象中,我们如下配置“rxtx0”域段。请注意,在Register Abstraction中,我们将“rxtx0”域段定义为“RW”(读/写),以使该字段更通用。知道各个参数的含义。
1 2 3 4 5 6 7 8 9 10 | rxtx0 = uvm_reg_field::type_id::create( "rxtx0" ); // rxtx0.configure( .parent ( this ), //此域的父辈,也就是此域位于哪个寄存器中,即是this; .size ( 3 ), //此域的宽度 .lsb_pos ( 0 ), //此域的最低位在整个寄存器的位置 .access ( "RW" ), //此域段的存取方式(属性); .volatile ( 0 ), //是否是易失的(volatile),这个参数一般不会使用; .reset ( 0 ), //此域上电复位后的默认值; .has_reset ( 1 ), //此域可复位 .is_rand ( 1 ), //是否可随机化 .individually_accessible( 0 ) ); //是否可以单独存取 |
??如果
2.3. 方法——reset()/get()/set()/randomize()—操作期望值
- reset()方法——只复位模型寄存器域段对象的复位值属性。
不会复位DUT中的寄存器 。注意,如果m_reset [kind]存在,reset()方法将重置寄存器域段的属性。默认类型是“HARD”。如果m_reset [kind]不存在,则reset()方法不执行任何操作。 - set()方法——设置(修改)模型寄存器域段的期望值。
set()方法不会修改DUT中的寄存器的值 。要真正将值设置为DUT中的寄存器,请使用write()或update()方法。
1 | regmodel.register.set(value); //设置本地寄存器的期望值 |
- get()方法——读取模型寄存器域段的期望值。
get()方法不会从DUT中的寄存器获取值 。它只获取m_desired属性的值。要实际从DUT获取值,请使用read()或mirror()方法。
1 2 3 4 5 6 | 还有两个get方法访问本地属性。 get_reset() ————检索m_reset [kind]属性的值, get_mirrored_value() ————方法检索m_mirrored属性的值。 使用方法: desired_value = regmodel.register.get(); //读取期望值 mirrored_value = regmodel.register.get_mirrored_value(); //读取镜像值 |
- randomize()方法——随机化一个模型寄存器域段对象期望值。
(随机化后,post_randomize()方法将value属性的值复制到m_desired属性。请注意,如果value属性的rand_mode为OFF,则pre_randomize()方法会将m_desired的值复制到value属性。)
1 | register.randomize(); //随机化创建期望值 |
2.4. 方法——write()—写入DUT
?? write()方法实际上向DUT写入一个值。语法见上一节。注意,
write()方法实现涉及多个步骤:见下图
1)、创建与写入操作对应的uvm_reg_item对象。
2)、uvm_reg_adapter将写入操作转换为相应的总线事务。
3)、uvm_driver执行到DUT的总线事务。
4)、uvm_monitor捕获总线事务。
5)、uvm_reg_predictor要求uvm_reg_adapter将总线事务转换为相应的寄存器操作。
6)、寄存器操作转换为uvm_reg_item。
7)、uvm_reg_item用于更新值,m_mirrored和m_desired属性。
2.5. 方法——read()—读出DUT
?? write()方法实际上从DUT读取一个寄存器值.语法见上一节。注意,
read()方法实现涉及多个步骤:见下图
1)、创建与读操作对应的uvm_reg_item对象。
2)、uvm_reg_adapter将读取操作转换为相应的总线事务。
3)、uvm_driver执行到DUT的总线事务。
4)、uvm_reg_apapter将读取数据的总线事务转换为寄存器操作。
5)、read()方法将读取值返回给调用者。
6)、同时,uvm_monitor捕获总线事务。
7)、uvm_reg_predictor要求uvm_reg_adapter将总线事务转换为相应的寄存器操作。
8)、寄存器操作转换为uvm_reg_item。
9)、uvm_reg_item用于更新值,m_mirrored和m_desired属性。
2.6. 方法——update()—写入DUT和更新镜像值
?? update()方法——实际上是向DUT写入一个寄存器值,同时更新镜像值。只有期望值与镜像值不一致,才向DUT写入期望值。 update()方法属于uvm_reg类。
1 2 | regmodel.register.update(status, [path], .parent(this)); //可以使用前门访问,也可以使用后门访问 update_reg(model, status, [path]); |
- write()方法将一个值作为其参数写入,而update()方法使用m_desired属性的值作为要写入的值。
- 只有当m_mirrored和m_desired不相等时,update()方法才向DUT写入该值。
2.7. 方法——mirror()—读取DUT和更新镜像值
?? mirror()方法——实际上是从DUT读取一个寄存器值,并将它们更新到寄存器模型中。
1 2 | regmodel.register.mirror(status, [check], [path], .parent(this)); //可以前门访问也可以后门访问 mirror_reg(regmodel.register, status, [check], [path]); |
- read()方法返回寄存器值给调用者,而mirror()方法不返回寄存器值。 mirror()方法只更新m_mirrored属性的值。
- 如果check参数的值默认为UVM_NO_CHECK,但若为为UVM_CHECK,则mirror()方法将读取值与镜像值进行比较。
2.8. 方法——predict()—操作镜像值
?? predict()方法——只用于设置模型寄存器镜像值 。人为的根据DUT来更新寄存器模型中的镜像值。但同时
1 2 | regmodel.register.predict(value); //设置镜像值 mirrored_value = regmodel.register.get_mirrored_value(); //读取镜像值 |
参考:http://cluelogic.com/2013/02/uvm-tutorial-for-candy-lovers-register-access-methods/