ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

SRAM Number of Banks配置:功耗、时序与面积权衡的工程实践

SRAM Number of Banks配置:功耗、时序与面积权衡的工程实践 芯片前端工程师应该都有过这种经历Memory Compiler生成的SRAM明明看起来“够大”综合布线之后却发现时序收敛不了功耗也压不下去最后把目光投向GUI里那个默认是1的Number of banks选项情况才有了转机。这个选项写在很多compiler界面上都只是一行下拉框背后却牵涉SRAM的结构划分、访问功耗、时序路径、物理布局甚至DFT策略。简单说它决定了你一整块memory是作为一个大阵列访问还是切成多个相对独立的小阵列、由外部地址高位来选择激活哪一个。这个“切”与“不切”在实际项目里常被忽视但它的影响范围和调试难度远比字面上一个数字要大得多。这篇就围绕SRAM compiler里Number of banks的设置把原理、实操、取舍和踩坑经验一次说清楚。1. Number of banks到底在配置什么1.1 从compiler生成的实例结构看起用SRAM compiler不管你是用Arm Artisan还是各foundry自带的compiler生成一个memory实例时输出结果里通常包括.lib、.v、.gds和一份datasheet。datasheet里除了功耗时序还会有一个结构示意图上面会标注instance总的容量、word count、bit width以及划分出来的bank信息。所谓bank本质上是把一大块存储阵列拆成若干子阵列每个子阵列拥有相对独立的译码、读出放大、写入驱动和控制时序电路但它们共享同一组地址总线、数据总线和控制信号。从外部看你访问的还是一个深度×宽度的memory但内部真正“干活”的只是某个特定bank。compiler界面里最常见的banks选项是1、2、4、8这几个级别有些编译器最高支持到16。选1就是最原始的整块单阵列选2以上输入地址的高位会额外用于bank选择低位的地址用于bank内部的wordline译码。这个划分是所有后续功耗、面积、时序差异的根源。1.2 bank数量选项背后的结构差异单bank结构下整块memory在一个时钟周期内完成全局译码、字线驱动和位线放电。优势是控制逻辑简单面积利用率高不需要额外的bank选择转移电路劣势是容量一大字线和位线都被拉得很长RC延迟增长非常明显动态功耗也集中爆发。多bank结构下每个bank的wordline覆盖的行数变少位线长度也随列数分配而缩短内部node电容减小读写路径上的RC自然下降。代价是每个bank都要复制一套外围电路row decoder、column mux、sense amplifier、write driver、时序控制逻辑都得各自配一份面积开销会上升。我在一个ISP图像处理项目里对比过同一颗16nm工艺、容量512K×32的SRAM单bank频率大概只能跑到450MHz时序还很紧张拆成4 banks之后最高跑到了700MHz以上代价是面积增加了接近两成。当时工程组里争论很多但后端反馈的物理实现难度反而比预想低因为每个bank本身更小布局更整齐。2. 配置bank数量时真正在权衡什么2.1 功耗只唤醒你需要的部分SRAM的动态功耗来源主要是位线充放电、字线驱动和sense amplifier的启动。单bank大阵列里每次读写访问都会让整片阵列的字线、位线参与预充电和放电电流集中在周边功耗自然大。拆成多个bank后每次只有被选中那个bank的字线和位线在翻转其他bank保持静止有效电容一下子缩小到原来的bank分之一。这里有一个容易被忽略的点未激活的bank不是完全零功耗。它的存储单元本身还有静态漏电外围预充电晶体管如果没做输入隔离位线电压也可能持续跳变。不少编译器在多bank模式下会增加一种“bitline floating”或“bitline keep”的行为把未选中的位线置为保持态降低无谓的动态翻转。你如果发现拆bank之后功耗下降没有预想那么多多半是需要去datasheet里看“Standby/Active bank current”的明细确认未选中的bank是否真正处于低功耗状态。不过纯粹为了省动态功耗去拆分bank需要看总容量。我做过一个4KB的小SRAM单bank功耗本来就不高硬拆成2 banks后面积多了8%功耗只省了不到10%性价比很差。一般128Kbit以上容量的memory拆banks的收益才明显。2.2 时序更短的字线和位线SRAM关键路径通常从地址输入到sense amplifier输出里面包含地址译码、字线驱动、存储单元访问、位线放电、读出放大这几段。字线长度和位线长度直接决定RC大小RC大了单元电流建立速度变慢位线压差要更久才能达到sense amplifier的触发点。拆banks本质上是把一条宽而长的路径切成几条小而短的路。举个例子同一个64K×32的实例单bank下每个wordline要驱动整行32个单元还有跨越整行长度的RC拆成2 banks后每边16列字线负载直接减半同一工艺下访问时间可以改善约20%到30%具体数值取决于工艺节点和compiler优化。我要提醒的是拆banks不是万能的时序解药。地址输入到bank选择路径上的多路选择器、以及bank间数据总线合并逻辑都会额外增加延迟。当bank数量从4翻到8时这部分Select路径的延迟增长可能盖过位线变短带来的收益出现时序反而变差的拐点。所以不能一上来就追求最多的bank数量具体拐点最好用compiler跑2、4、8三组对比看数据。2.3 面积和成本的账每个bank都有独立的外围电路这些电路占用的面积不会因为阵列变小而大幅缩小其中上一级译码器、时序控制电路和读写出放大器的面积相对固定。一个4-bank的64K×32 memory总面积一般会比单bank版增多15%到25%这个数据在不同工艺和compiler上会有差异但大方向一致。多bank还会影响供电网络和物理布局。每个bank都要求独立的位线预充电电压和sense amplifier参考电压后端需要更细致的电源环设计否则IR drop在不同bank之间不一致会造成访问时间波动。实际floorplan的时候要是没给memory区域预留足够的电源走线空间后端可能被迫插大量decap单元又反过来吃掉面积。从成本角度讲area increase就是die cost increase。尤其soc里memory占比极高一片128Mbit的总memory量面积增加10%对整体芯片成本的影响相当可观。所以每次设banks数量之前都要先算清楚这笔账。3. 实际操作一个SRAM实例的bank配置流程3.1 在compiler里怎么选这部分操作本身不复杂。Arm Artisan的SRAM compiler GUI里选择memory类型之后会有一栏Memory Configuration里面有Number of banks下拉框选好后点Generate就能生成完整的库里文件命令行模式通常有对应的选项比如在配置脚本里加-banks 4。不过光是在GUI里选数字远远不够。配置bank时至少要同步确认以下参数Address orderingbanks是按高位地址选择还是低位地址选择。高位选择适合连续地址访问顺序落入同一个bank的场景可以减少bank切换低位选择则适合每次访问都在不同bank间交错的场景。多数compiler默认高位选择除非你有明确的低功耗交错访问需求否则不用改。Data width per bank总宽度不变的前提下bank数越多单bank的数据宽度相对越窄。如果你外部数据总线是128bit却选了8 banks部分compiler可能会要求每个bank宽度是16bit这个比值会影响列mux配置最好提前确认datasheet的可配范围。Test mode / Redundancy多bank配合memory BIST时要确认BIST控制器能否独立寻址每个bank并覆盖bank交叉区域。有些compiler支持bank-level redundancy repair坏行修复时选哪个bank可以单独映射这会直接影响良率策略设计阶段就要和DFT工程师对齐。3.2 拿到datasheet后怎么判读生成完实例datasheet里的几个关键表要仔细看。首先是Timing Data重点关注address access time、read cycle time和write cycle time随bank数量的变化曲线。如果curves里依然存在较大的斜率下降但后段趋缓说明bank拆分带来的收益正在递减。然后是Power Data看active power和standby power。有些datasheet会把total power分成decoder、memory array、sense amplifier三部分拆bank之后decoder部分通常反而增大因为多了bank select路径但array部分下降幅度更大power总和是下降的。要是发现decoder占比异常高说明bank数可能选多了。最后是Area Data所有列出的尺寸数据要结合你的floorplan实际使用不是光看总面积。memory形状长宽比也很重要多bank模式下compiler会把banks排成一行或两行长宽比变化明显。一个超高瘦的memory在物理实现时不见得比一个矮胖的更好布线我吃过这个亏后面章节详说。3.3 与后端流程的衔接综合阶段多bank memory体现在.lib里就是多了一个bank select相关的setup/hold检查时序约束通常不会太复杂。但你需要在SDC里对memory的所有输入端口设置合理的input delay不要只约束了地址和数据却把CSchip select或BWSbyte write select忘掉否则综合器容易把bank select路径优化歪。布局布线阶段麻烦一点的是电源完整性。每个bank的瞬态电流峰值集中在局部电源网格设计要保证所有bank在同时切换时局部IR drop不超过库文件里的限定值。这个检查手段一般是跑动态压降模拟或者利用compiler给到的peak current数据做简化评估。我见过有项目为了省模拟时间默认整片memory都算作一个功耗源结果流片回来后高负载场景下sense amplifier失调增大读数据出错率上升最后定位到是电源网格设计不足。DFT阶段多bank memory的BIST测试向量要覆盖bank间串扰和竞争问题。单bank下你不需要考虑两个bank同时被选中会怎样多bank模式下如果bank select逻辑存在毛刺两个bank的字线可能同时短暂打开造成数据竞争。所以DFT工程师安排测试pattern时要加一个针对“同时选中”的检测环节或者依赖compiler内部提供的自检测脚本来覆盖这个场景。4. 踩坑实录多bank配置中的常见问题4.1 小容量SRAM盲目拆分得不偿失我接手过一个无线通信SoC模块内部有个16K×16的小缓冲为了优化读延迟设计工程师把Number of banks从1改成4。综合报告里memory本身面积大了不少但模块总频率反而没提升后来用PT分析发现关键路径根本不在memory内部而在数据输出之后的一级组合逻辑。这类问题很常见bank拆分只能优化memory本身的速度但如果你系统的瓶颈在周边逻辑拆分只会徒增面积和功耗读延迟还因为多级bank选择多了一点点。改回去之后项目功耗反而更好。遇到类似场景我建议先用Profiler分析片上memory的访问热点和时序余量再决定要不要动bank数而不是先拆了再说。4.2 多bank和物理布局容易互相拖后腿多bank memory的自身布局比单bank更不灵活。单bank可以切成不同长宽比来适应floorplan多bank则更像是一排整齐小房子宽度和高度都受bank数量限制。曾经某个项目里2-bank实例是纵向排列的但模块剩余空间是横向的硬塞进去之后四周留下大量碎片面积整体利用率反而比单bank差。解决办法是做floorplan之前先把目标bank数对应的几份datasheet长宽数据拉出来对比一下不同排列下的白空间white space大小。compiler一般提供bank间的spacing选项让banks之间的间距可调也能在一定程度上缓解形状不匹配的问题。我在另一个项目里就是靠调大bank间spacing让2个bank横向展开才把碎片面积降到可控。4.3 边界条件读改写时序和测试模式多bank对于读改写read-modify-write操作不太友好。如果外部系统在同一个时钟周期内需要读一个地址、写另一个相邻地址而这两个地址落在不同bank时bank select信号需要额外时间发散和收敛可能会导致读写竞争。更麻烦的是如果编译器生成的多bank memory支持byte write不同bank的byte write使能信号时序一致性要保持好否则窄位宽写操作会在部分bank里变成全写或者不写。测试模式方面有些compiler默认在test mode下把所有bank同时选中方便并行测试降低测试时间但这也意味着测试模式的动态功耗是完整memory全开的常温下跑可能没问题到了高温可靠性测试阶段局部热点温度会明显偏高。这块虽然一般不需要设计工程师去改但评估芯片热设计功耗时要把这个场景算进去。否则你封装厂报告的热阻数据会偏乐观。4.4 功耗数据容易算错回到功耗很多工程师看datasheet里active energy那一栏是per access的值就直接用最高频率去乘。但多bank模式下实际功耗和地址访问模式强相关连续在同一bank内读写时动态功耗较低如果地址频繁在bank间跳变bank select路径和复用总线翻转增多功耗反而上升。数据手册上给出的往往是一个平均模型偏向“每个bank轮流访问”的前提。如果你的系统在某个时间段内集中访问某一个bank对应bank的自热会显著高于其他bank平均功耗看起来没问题局部温度却可能超限。这个现象在可靠性分析时要关注评估EM电迁移寿命时也要用最坏的bank访问分布而不是平均分布。5. 一个值得参考的选型思路5.1 我给不同容量memory的建议根据做过的项目我一般按总bit数给一个粗略的bank数参考区间总容量建议bank范围主要考虑≤64Kbit1~2面积优先时序通常不是瓶颈64Kbit~512Kbit1~4根据时序余量和功耗目标折中512Kbit~4Mbit2~8功耗收益显著注意物理布局匹配≥4Mbit4~16优先考虑局部热点和DFT策略这个表格不是硬性规定。比如你做的AI加速器有大量并行数据访问即使单bank容量不大bank间访问模式也经常跳变那选低位数bank可能更合适避免select路径开销太大。相反如果你的memory访问高度集中且带宽要求高用更高bank数配合interleaving策略可以有效降低bank冲突概率。5.2 实际项目复盘与经验总结以我之前负责的一个ISP scaler模块为例原始设计里有一块192KB的line buffer单bank结构综合后频率只有520MHz不满足600MHz的目标。没有直接上8 banks我先在compiler里跑了2 banks和4 banks两组配置对比面积和时序数据。结果2 banks只把频率提到了560MHz还是不够4 banks能到650MHz但面积涨了18%。后来我调整了bank选择方式从高位选择改成低位交错选择因为scaler读数据是连续扫描模式交错的bank访问可以让每行缓存命中率更高等效latency明显下降最后用4 banks加交错方式频率跑到680MHz面积开销也控制在了14%左右。这个案例里有个更重要的经验Number of banks的设置不是孤立存在的它需要和memory的输出寄存器、后端时钟树、DFT策略一起评估。单独调一个数字往往只是把时序瓶颈从memory内部搬到memory周边问题没有真正消失。5.3 后续还可以这样扩展如果你的项目已经定了bank数后面想继续压功耗或提升性能还有几个方向值得提前研究最小位宽模式不少compiler支持把memory切分成更小位宽实例并联相当于软bank可以在不改动硬bank数的情况下让部分数据通路进入低功耗休眠模式。时钟门控粒度结合bank select信号做时钟门控让未访问bank的时钟边沿不翻转能进一步降低动态功耗但维护时钟树收敛要更小心。嵌入式ECC与redundancy联动多bank能提供更大的redundancy修复粒度把ECC的纠错粒度设计为小于bank大小可以更灵活地处理多bit翻转对车规和服务器级可靠性设计非常有用。这些方向不一定每个项目都适用但想清楚能用在哪会让你的bank配置更有前瞻性而不是等PPA问题暴露再来回头调。我个人这些年在多bank配置上踩过不少坑最深的一点体会是不要只盯着compiler下拉框里的数字要把bank设置放到整个芯片的物理实现和测试策略里去审视它本质上是一次功耗、速度和面积的系统级权衡。下次打开SRAM compiler配置页时多花十分钟对比一下不同bank数下的datasheet数据往往能省下后面好几轮post-simulation和后端迭代的功夫。
返回列表