You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

FIRRTL中存储器部分更新的惯用实现及效率问题

FIRRTL中缓存部分写入的惯用实现与优化效率问题

在FIRRTL中编写寄存器文件的逻辑十分直观:创建以机器字为单元的存储器,对其执行读写操作即可。
但编写缓存时情况有所不同:缓存通常以缓存行作为存储单元,写入操作仅需要更新缓存行的部分内容,即缓存行中的单个元素。

请问FIRRTL中实现该操作的惯用方式是什么?(请勿指引参考Chisel编写的Rocket实现,Chisel代码可读性极差)

目前可想到至少两种实现方式:

  • 方式1:将存储器的存储元素定义为Vector或Bundle类型,写入时直接选中存储器元素的对应成员操作,示例代码如下:
cmem mem1 : {x:SInt<64>,y:SInt<64>}[4]
infer mport temp_x_mem1 = mem1[i].x, clock
temp_x_mem1 <= foo
  • 方式2:采用读-改-写流程实现,示例代码如下:
cmem mem1 : {x:SInt<64>,y:SInt<64>}[4]
infer mport temp_x_mem1 = mem1[i], clock
bar <= temp_x_mem1
bar.x <= foo
infer mport temp_x_mem1_B = mem1[i], clock
temp_x_mem1_B <= bar

当前场景为从其他格式生成FIRRTL代码,前期未针对该场景做规划,生成存储器逻辑时仅支持对整个存储器元素执行读写,不支持部分元素写入,因此方案1实现难度较高,方案2更易落地。核心疑问为:如果所有代码都在同一个模块内,FIRRTL优化器或后续的Verilog优化器能否将方案2优化至与方案1同等的运行效率?


回答

核心结论

同模块下结构合规的读-改-写实现,经过FIRRTL标准优化流程和下游Verilog综合工具处理后,完全可以达到和直接部分写入的方案1同等的运行效率,不存在额外的面积、时序开销。

具体说明

  1. FIRRTL优化器原生支持该模式的识别转换
    FIRRTL存储器编译阶段内置了部分写入识别逻辑:只要检测到同一时钟域下,对同一存储器同一地址的读操作后紧跟写操作,且写数据中未修改的字段完全直通读回的对应位、没有额外逻辑篡改,就会自动将这组读-改-写序列映射为存储器的字段掩码写端口,不会生成冗余的读通路、临时寄存器开销,最终生成的硬件结构和手动写部分字段选中的方案1完全等价。
    触发该优化仅需满足两个条件:
    • 读、写端口使用相同时钟
    • 写操作中不需要更新的字段,直接连接读回数据的对应位,不插入额外组合逻辑或时序逻辑
  2. 代码生成的注意事项
    给出的方案2示例存在一个语法问题:两个存储器端口不能使用相同命名,写端口需要单独定义标识符。另外要保证读回数据到写入数据的路径是纯组合逻辑,不要在中间插入寄存器,就能稳定触发优化。如果需要验证优化是否生效,可以检查FIRRTL编译导出的Verilog代码,只要对应存储器的写端口出现了按字段拆分的写使能信号,就说明转换已经完成。
  3. 实现选型建议
    手写FIRRTL时直接选中字段写入的方案1是更原生的写法,但对于自动代码生成场景,读-改-写的方案2落地成本更低,且没有效率损失,不需要为了支持部分字段写入重构已有的全元素读写生成逻辑。

内容的提问来源于stack exchange,提问作者Daniel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 06:39:18