寄存器(RAL)模型中的write方法

本文详细介绍了在UVM寄存器模型中执行write操作的步骤,包括原子操作、do_write方法、前门和后门访问的判断及执行过程,以及自定义front_door和backdoor的使用。重点讲解了check_access函数、local_map的do_write方法以及前后门访问的转换和执行机制。

在使用UVM寄存器模型时,当对寄存器进行写操作时,有很多种方法,这里介绍最常用的方法:
假设已经生成了一个uvm_reg_block模型,名字时reg_blk,在模型中有一个寄存器名字叫reg1。并且reg1添加到了名字是map1的uvm_reg_map中
![在这里插入图片描述](https://img-blog.csdnimg.cn/20191213153743991.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2xpdXdlaTg0OA==,size_16,color_FFFFFF,t_70
下面来讲解一下寄存器模型时如何完成write操作的

   extern virtual task write(output uvm_status_e      status,
                             input  uvm_reg_data_t    value,
                             input  uvm_door_e        path = UVM_DEFAULT_DOOR,
                             input  uvm_reg_map       map = null,
                             input  uvm_sequence_base parent = null,
                             input  int               prior = -1,
                             input  uvm_object        extension = null,
                             input  string            fname = "",
                             input  int               lineno = 0);

status: 表示操作状态,OK or NOT OK
value: 表示要写的值(初始值)
path: 表示是前门访问还是后门访问
map: 表示 如果是前门访问时用哪个map。
parent:表示哪个sequence来发送RAL item
prior:表示item的优先级
extension:表示一些扩展信息,这个后续介绍
fname和lineno没有什么用,暂时不用去care

   // create an abstract transaction for this operation
   uvm_reg_item rw;

   XatomicX(1);

   set(value);

   rw = uvm_reg_item::type_id::create("write_item",,get_full_name());
   rw.element      = this;
   rw.element_kind = UVM_REG;
   rw.kind         = UVM_WRITE;
   rw.value[0]     = value;
   rw.path         = path;
   rw.map          = map;
   rw.parent       = parent;
   rw.prior        = prior;
   rw.extension    = extension;
   rw.fname        = fname;
   rw.lineno       = lineno;

   do_write(rw);

   status = rw.status;

   XatomicX(0);

1:

首先会调用task XatomicX(1),这个task是让这个操作进程拿到semaphore,XatomicX(0),进程释放semaphore,供别的进程使用。uvm_reg在new的时候会默认分配一个semaphore,这样的话假如有如下代码

fork
       reg1.write(*)
       reg1.write(*)
join

同一时刻两个进程同时要进行write操作,但是只有一个semaphore,这样就可以避免多个进程同时对reg进行write操作。

但是UVM的寄存器访问不支持原子操作,所以使用的过程中如果可能有多个线程同时访问reg,必须访问,uvm_reg中提供了变量m_is_busy,m_write_in_process以及m_read_in_process来做判断使用

<think>嗯,用户问的是寄存器模型write和update的区别。首先,我得回忆一下自己在验证和寄存器模型方面的知识。寄存器模型通常用在硬件验证中,特别是在UVM(通用验证方法学)里。用户可能是做验证的工程师,或者正在学习相关的内容,所以需要明确这两个操作的不同应用场景。 首先,write操作应该是直接写入寄存器的当前值,而update可能涉及到将期望值同步到硬件。不过具体细节可能容易混淆,需要仔细区分。比如,write可能只是更新寄存器模型的镜像值,而update则是将模型的值写入实际的硬件寄存器? 然后,想到UVM中的寄存器抽象层(RAL)。在RAL里,write方法通常用于发起一个写事务到硬件,同时更新寄存器的镜像值。而update方法可能是在配置寄存器时,当镜像值和期望值不一致时,将期望值写入硬件,确保两者一致。比如,当使用predict方法改变了镜像值,但实际硬件没有变化时,需要用update来同步? 可能需要进一步确认两者的具体行为。比如,write会触发一个前门或后门的访问,直接修改硬件寄存器的值,并更新镜像值。而update则检查镜像值和期望值是否一致,如果不一致,就调用write操作来同步。比如,在初始化的时候,可能需要先设置寄存器的期望值,然后调用update来确保硬件和模型一致。 再想想例子。比如,当测试用例中修改了某个寄存器的配置,使用write会立即写入硬件,并更新镜像。而如果在模型中使用set方法修改了期望值,但没有立即写入硬件,这时候调用update会检测到差异,并执行写入操作。这样可以分两步:先设置值,再统一更新,适用于批量配置寄存器的情况。 用户可能在实际使用中遇到问题,比如为什么有时候直接write可以,有时候需要用update。或者镜像值和硬件值不同步导致测试错误。这时候明确两者的区别就很重要了。 另外,需要注意后门访问和前门访问的区别。write方法可能支持两种方式,而update可能也是基于write的实现。但update更关注于同步镜像值和硬件值,确保两者一致,而不只是单次写入。 总结的话,write是主动发起一次写入操作,影响硬件并更新镜像;update是被动检查差异,并在需要时执行写入,保证镜像和硬件一致。可能update内部会调用write来完成这个动作。</think>在寄存器模型(如UVM中的RAL)中,`write`和`update`是两个关键操作,它们的区别主要体现在行为目的和触发机制上。以下是逐步解析: --- ### **1. write操作** #### **行为特点** - **直接性**:通过总线协议(前门访问)或直接修改寄存器(后门访问)将数据写入硬件寄存器。 - **镜像更新**:执行后,寄存器模型的镜像值(mirrored value)会立即更新为写入的值。 - **单次触发**:每次调用`write()`都会生成一次实际的寄存器写入事务。 #### **典型场景** ```systemverilog // 示例:将0xFF写入地址0x10的寄存器 reg_model.reg_block.reg_a.write(status, 8'hFF, .path(UVM_FRONTDOOR)); ``` 此时: 1. 硬件寄存器值被修改为`0xFF` 2. 寄存器模型的镜像值同步为`0xFF` --- ### **2. update操作** #### **行为特点** - **条件性**:仅当寄存器的镜像值(mirrored value)与期望值(desired value)不一致时,才会触发写入操作。 - **延迟触发**:通过对比镜像值和期望值决定是否执行写入,本质是“按需同步”。 - **批量同步**:常用于初始化阶段,一次性同步所有寄存器的期望值到硬件。 #### **典型场景** ```systemverilog // 步骤1:设置期望值(不立即写入硬件) reg_model.reg_block.reg_a.set(8'hFF); // 步骤2:检查差异并同步 reg_model.reg_block.reg_a.update(status, UVM_FRONTDOOR); ``` 此时: 1. 若镜像值 ≠ 期望值(`8'hFF`),触发`write()`操作。 2. 硬件和镜像值最终同步为`8'hFF`。 --- ### **3. 核心区别总结** | 特性 | `write` | `update` | |---------------|----------------------------|------------------------------| | **触发条件** | 无条件执行 | 仅当镜像值 ≠ 期望值时执行 | | **数据来源** | 直接使用传入值 | 使用寄存器内部保存的期望值 | | **典型用途** | 单次寄存器写入 | 批量同步或修复寄存器不一致 | | **镜像更新** | 立即更新为传入值 | 更新为期望值(若执行写入) | --- ### **4. 实际应用建议** - **初始化阶段**:用`reset()` + `update()`批量同步寄存器配置。 - **动态修改值**:先`set()`期望值,再`update()`按需同步。 - **调试异常**:若怀疑镜像值与硬件不一致,可调用`mirror()`读取硬件值并更新镜像。 通过区分`write`和`update`,可更精准地控制寄存器行为,避免冗余操作或状态不一致问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值