项目寄存器与 RW1C

返回 项目总览。

通用寄存器 bank 适合所有寄存器行为一致的场景。真实 IP 往往同时包含软件可写控制位、硬件状态、只读版本号和写 1 清零的中断状态,因此项目又提供了 axi_lite_slave_project_regs 作为定制示例。

寄存器映射

地址名称类型行为
0x00CTRLRW软件读写,复位为 0
0x04STATUSRO读取外部 status_i
0x08INTR_ENRW中断使能,复位为 0
0x0CINTR_STATUSRW1C硬件置位,软件写 1 清零
0x10VERSIONRO返回参数 VERSION_VALUE

模块仍复用 AW/W 缓存、WSTRB、地址对齐和 B/R backpressure 结构,但写入时根据地址执行不同副作用。

RW、RO 和 RW1C 的区别

  • RW:软件写入什么,寄存器就保存什么;WSTRB 选择参与更新的字节。
  • RO:总线可以读取,但写操作不应改变值;值来自硬件输入或常量。
  • RW1C:读出当前状态;软件对某位写 1 清除,写 0 保留。它常用于中断状态,避免软件 read-modify-write 时误清除其他位。

RW1C 不是“写 1 后寄存器变成 1”。以当前值 4'b1011 为例:写 4'b0010 后得到 4'b1001,只有被写 1 的 bit 1 被清除。

外部置位与软件清零同时发生

中断状态每周期先有默认的硬件置位逻辑:

intr_status_reg <= intr_status_reg | intr_status_set_i;

若同一周期发生对 INTR_STATUS 的合法写,又会对选中的 byte lane 进行:

intr_status_reg[byte] <=
    (intr_status_reg[byte] | intr_status_set_i[byte]) &
    ~write_data[byte];

同一个 always 块中对同一变量的多次 nonblocking assignment 以最后执行的赋值为准。因此选中字节采用“先合入外部置位,再按写 1 清除”的表达式;未被 WSTRB 选中的字节仍执行默认硬件置位。

优先级必须来自规格

当前表达式意味着同一位在同一周期既被硬件置位、又被软件写 1 时,最终被清零。另一些项目会要求硬件事件优先,使该位保持 1。两种实现都可能合理,但必须由寄存器规格明确,并用定向测试覆盖冲突周期。

RO 地址写入时为什么仍返回 OKAY

STATUS 和 VERSION 被 is_valid_addr() 视为合法地址,因此写这些地址会进入 case 的 default,不修改任何状态,但返回 OKAY。这相当于“合法但忽略写入”。

如果系统规范要求对 RO 写返回 SLVERR,必须把“读地址合法性”和“写地址合法性”分开定义。验证计划也需要明确检查哪种策略,而不能只检查数值未改变。

应为这个模块补哪些验证

当前 51 次回归实例化的是通用 axi_lite_slave_regs,没有覆盖这个项目专用模块。针对它至少应增加:

  1. CTRL/INTR_EN 的全字与各 WSTRB 部分写。
  2. STATUS/VERSION 读值与写后不变。
  3. RW1C 的单 bit、多 bit、写 0、部分字节清除。
  4. 硬件置位、软件清零及二者同周期冲突。
  5. 未对齐地址、未映射地址和 RO 写响应策略。

不要混用证据范围

可以把专用寄存器模块作为项目设计亮点,但不能用通用 DUT 的 statement/branch/toggle coverage 证明它已被覆盖。现有报告明确排除了未实例化的 axi_lite_slave_project_regs.v。

自测

  1. intr_status=8'h0F、set=8'h10、software write=8'h03 时,选中该字节后的结果是什么?
  2. 为什么对 RW1C 寄存器使用普通 mirror = write_data 会得到错误参考值?
  3. 若产品要求硬件置位优先,组合表达式应如何调整?

答案要点:当前语义下结果为 (0F | 10) & ~03 = 1C;RW1C 写数据是清除掩码而非目标值;置位优先可在清零后再 OR 硬件事件。

上一篇:通用寄存器 RTL。下一篇:UVM 平台架构。