尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

SRAM Compiler中Number of Banks详解:原理、PPA影响与配置实践

SRAM Compiler中Number of Banks详解:原理、PPA影响与配置实践 做 SoC 的同学应该都有这种经历内存编译器生成的 SRAM 宏时序不够或者面积比预想大一圈综合阶段怎么优化周围逻辑都救不回来结果最后定位到 memory compiler 里的 Number of banks 设置上。这个参数看起来只是下拉菜单里的一个数字实际上牵扯到 SRAM 的物理结构、位线负载、功耗分布和后端物理实现。我自己在 28nm 和更先进工艺的项目里都吃过这个参数的亏也花了不少时间把不同配置的 datasheet 翻了个遍。这篇文章就把 SRAM compiler 里 Number of banks 这个设置讲透包括它的底层原理、对 PPA 的具体影响、不同编译器产品里的差异以及实际项目里应该怎么定这个值。1. 先说清楚一件事SRAM 里的 bank 到底切的是什么1.1 从一条位线讲起理解为什么需要切 bank很多人第一次看到 Number of banks 选项时下意识把它当成芯片顶层的 memory bank 划分这是最常见的误解。实际上编译器里的 bank 切在 SRAM 宏内部是阵列物理结构的一种组织方式。SRAM 的基本存储单元是 6T cell每个 cell 靠两根位线bitline和一根字线wordline访问。位线本质上是给整列 cell 共用的字线则是给整行 cell 共用。当你访问某个地址时字线把这一行的所有 cell 打开然后位线上形成微小的电压差交给读出放大器去判断是 0 还是 1。问题就出在这里如果一列上挂了太多 cell位线的寄生电容就大读出放大器的输入端信号摆幅建立得慢访问时间自然拉长。同时字线从行解码器一路走到阵列最远端RC 延迟也会累积。这个现象和你在马路上越多的车排队越堵是一个道理位线就是那条马路cell 就是排队等待上车的乘客。切 bank 的本质就是把一整块阵列分成若干个子阵列每个子阵列独立完成本地的字线驱动、位线预充电和读出放大再通过第二级数据通路把选中 bank 的数据送出去。这样每条局部位线上挂的 cell 数量变少了位线电容减小访问速度得以提升。与此同时地址的高位作为 bank select决定本次访问开哪个 bank。1.2 编译器视角下的 bank 定义并非你在芯片顶层看到的东西在 SRAM compiler 的工具文档里bank 通常被定义为“可以由地址选择信号独立激活的存储子阵列”。每个 bank 内部有自己的一套局部控制电路、灵敏放大器和写入驱动但共享全局地址预解码、全局数据总线和输入输出控制逻辑。以总深度 8192、宽度 32 的 SRAM 为例如果设置 Number of banks 2那么地址最高 1 bit 作为 bank select每个 bank 内部是深度 4096 的阵列如果设置为 4则高位 2 bit 做 bank select每个 bank 内部是深度 2048 的阵列。也就是说增加 bank 数量等价于把横向的“行”规模拆小而不是把纵向的“列”宽度拆小。这里要特别留意一点部分编译器的 bank 机制和 column mux 是配合使用的有些编译器里的 bank 甚至可以直接改变位线方向和 IO 布局方式。所以在动手设置之前一定要先打开对应工艺库的 compiler user guide确认 bank 切的是字线方向还是位线方向。这个方向性直接决定了你到底是缩短了字线延迟还是位线延迟对最终时序的影响路径完全不同。我见过不少工程师只凭经验猜结果改完参数之后性能反而更差就是因为方向搞反了。1.3 一个 analog 视角局部位线和全局位线的两级结构现代大型 SRAM 宏基本都采用两级位线结构。局部位线连接一小段 cell配合局部读出放大器把一次小摆幅信号转成满摆幅全局位线再把各个局部读出放大器的结果汇合到最终的数据总线上。这种两级结构在编译器里往往不会直接画给你看但当你拉大 Number of banks 时局部位线长度会下降局部读出放大器数量却会增加。所以从电路设计者的角度Number of banks 绝对不是越大越好。每多一个 bank就多一份局部读出放大器、多一份 bank 选择逻辑、多一块隔离区。放大器的功耗和面积是实实在在的而位线变短节省下来的时间却可能不是线性增长的。这个权衡关系是这篇文章后面所有讨论的基础先把它记在心里。2. 调大 Number of banks 之后面积、时序和功耗各发生了什么2.1 面积省下来的位线电容又花在了哪些地方很多人第一反应是bank 越多每个 bank 的行数越少位线电容越小SRAM 应该更小。实际情况没那么理想。先说位线。位线电容来自整列的 cell 扩散区结电容和金属线本身减少每列挂的 cell 数量确实能减小电容也让读出放大器的输入更灵敏。但代价是你需要在每个 bank 边界加一圈 dummy cell 和隔离结构防止边缘 cell 受到工艺偏差影响。bank 数量越多这些边缘开销占的比例越大。更明显的是控制逻辑开销。全局地址预解码原来只要解出一根长字线分 4 个 bank 之后除了全局解码还要额外做 4 选 1 的 bank 选择、局部字线的二次驱动、局部读出放大器的动态使能信号对齐等。电路变复杂面积自然上去。还有全局数据总线每个 bank 的局部读出放大器输出都要汇集到一组全局线上如果编译器不主动做多级树形汇合布线资源也会跟着涨。实际项目里我做过的对比大致是在 64K×32、单端口 SRAM、标准 Vt 条件下从 1 bank 切到 2 bank面积大约增加 3~5%从 2 bank 切到 4 bank再增加 2~3%。这些数字不是绝对的每个工艺节点、每款编译器都不太一样但趋势很明确bank 数量增加大概率会带来面积惩罚只是大型阵列的惩罚比例相对更小。这也是为什么大容量 SRAM 用多 bank 很常见小容量 SRAM 用多 bank 就很不划算。2.2 时序位线变短但选择路径变长时序是选择 bank 数量时最敏感的部分。访问时间可以粗略拆成三段地址输入到内部预解码、预解码到字线/位线建立、读出放大器到数据输出。增加 bank 数量第一段时间会变长。因为 bank select 信号要在预解码阶段就生成然后和局部字线信号做类似“与”的逻辑等于在关键路径上多插入了一级选择逻辑。如果编译器把 bank select 放在地址路径后段这部分延迟会更明显。第二段也就是 row decoder 到 cell 的距离会缩短因为每个 bank 的行数少了。第三段会略微变长因为局部读出放大器的输出要经过多一级仲裁才能到达 IO。所以这就形成一个 U 形曲线bank 太少时位线/字线延迟占主导bank 太多时控制逻辑和选择逻辑延迟占主导中间存在一个最优区间。我曾经在 45nm 左右工艺下测试过 128K×32 的宏从 1 bank 到 4 bank 访问时间一路变好但到 8 bank 开始变差16 bank 时已经明显差于 4 bank。原因就是 U 形曲线的右半段。还有个容易被忽略的时序因素不同 bank 的读写时序偏差。多 bank 结构下如果某个 bank 离 IO 布局位置更远它的局部位线到全局数据通路的走线长度差异会变成额外 skew编译器通常会把时序模型做得更悲观导致.lib 里的 setup/hold 数值更差。你在仿真阶段看不出来但综合和后端会立刻体会到这种“惩罚”。2.3 功耗开关功耗、泄漏功耗和 bank 级 clock gating动态功耗方面bank 化之后明显会占便宜。因为每次访问只有一个 bank 的位线在翻转其他 bank 的位线保持预充电状态。位线翻转在 SRAM 访问功耗里是大头把这个大头砍掉一部分整块宏的动态功耗会显著下降。但泄漏功耗不一定降。泄漏功耗主要取决于 cell 数量和工艺电压阵列切分成多个 bank 并不会让 cell 的漏电消失。反倒是 bank 周边多出来的读出放大器、解码器、隔离管一直处于上电状态他们的泄漏是不可忽视的额外开销。特别是在低功耗项目里真正想靠 bank 省泄漏必须配合 bank 级 power gating也就是在不用时把一个 bank 完全关断。这就不是 compiler 单独能做主的需要后端在设计里加电源开关单元还要做 UPF 策略设计。功耗切换带来的另一个麻烦是电源完整性的局部热斑。多个 bank 同时切换时如果编译器没有做好的时序错开电流峰值会很集中。某些 compiler 在配置里会提供 bitline precharge 时序调节本质上就是在分散这种切换噪声。如果你把 bank 数量调的很大建议顺便看一下 compiler 生成的 peak current 报告这块在低功耗芯片里经常是后端的痛点。2.4 附带收益良率、冗余和抗干扰bank 切分还有一个隐藏的好处就是对工艺缺陷的容忍度提升。一个大阵列里如果某个 cell 坏了整个宏可能直接报废切成多个 bank 后配合行冗余和列冗余坏掉的 bank 可以用备用单元替换剩下正常的 bank 继续工作。很多编译器在开启 bank 之后会自动开启 redundancy 选项就是这个原因。对于容量特别大的 memory比如几百 Kbit 以上的 SRAM这种良率收益可能会超过面积代价。这也是为什么高密度 SRAM 编译器一般默认就会让你在几个 bank 数量之间做选择因为纯单 bank 的良率风险已经无法接受了。但从电路抗干扰角度bank 数量也不是越多越好。bank 间隔里的隔离区和电源走线如果密度过高会和相邻 bank 的字线形成耦合电容产生串扰噪声。这个问题在先进工艺的低电压 SRAM 里会放大有些后端同事反馈在 signoff 阶段补充噪声分析时多 bank 宏比单元件更容易报出问题基本就是这个原因。3. 在 Compiler 界面上找到这个选项只是第一步配置路径与常见工具差异3.1 典型 GUI 菜单里的位置与参数联动不同工艺库的 memory compiler 界面风格差异很大但基本逻辑是一致的。在 SRAM generator 或者 memory compiler 的主配置界面里你会先填 Depth、Width然后看到 Number of banks 或 Number of sub-arrays 之类的下拉选项。旁边几乎总伴随着另外两个参数Column mux也写成 Multiplexer/MUX factor和 Word-line partitioning。这三个参数经常是联动的。你改 Number of banks编译器会按照内部规则自动调整可选的 Column mux 范围反过来你手动改 Column mux某些 bank 数量选项会变灰或者调整上限。这是工具为了保证内布局合法避免出现位线长度和字线长度搭配失衡的情况。比如在某个 28nm 工艺的 compiler 上我见过这样的规则当 Depth 小于等于 4096 时Number of banks 只允许 1 或 2Depth 在 8192 以上才会开放 4Depth 到 16384 以上才有 8。这就是编译器自身的电路设计团队经过 PVT 仿真后限制出来的物理可行范围强行改成不支持的值工具也会在生成的网表中做不了电路连接直接报错。所以一个实用的建议是不要试图在 GUI 里乱填一个 bank 数量然后硬跑而是先把三个关键输入确定好——目标容量、目标频率、允许的功耗预算然后在 compiler 支持范围内挑选。GUI 里每个下拉选项背后其实是编译器预置的一组 floorplan 模板不同模板之间并不是连续可调的而是类似“套餐式”的跳变。3.2 命令行/配置脚本的等价写法项目到了后期没人愿意每次开 GUI 点点点都会把 compiler 的配置整理成脚本或配置文件。以常见商用工具为例一个典型的配置可能是这样set depth 16384 set width 32 set banks 4 set column_mux 4 set write_mask enable set power_gating enable不同编译器的语法有些差异有的叫-number_of_banks有的叫-split还有的直接用配置文件里的字典项。关键不在于背命令而在于掌握“配置项名称只是表象底层 floorplan 才是决定因素”这个原则。你完全可以在命令行里把每一种 bank 数量跑一遍比在 GUI 里一个个点快得多。我建议把编译器的配置文件和生成报告放到版本管理里和 RTL、约束一起存档。后面回看设计时能够轻易复盘“当时的 SRAM 为什么选 4 bank 而不是 2”对团队协作和问题回溯很有帮助。3.3 不同编译器产品之间的命名差异业内主流的 SRAM compiler 虽然都服务于同一个目的但术语并不完全统一。Synopsys 系 compiler 里常称为 Number of banks 或者 Number of subarrays层次结构为“global IO local subarray”。ARM Artisan memory compiler 里更多叫 Number of banks 或 SBsub-bank和 column mux 一起出现在 memory config 表格里。一些代工厂自研的编译器可能会直接叫 Bank split 或者 Row segment本质上都是同一件事。更需要注意的一点是某些 compiler 的 bank 选项其实是在做 “multiple instance”而不是“单个宏内部切分”。这两种做法的物理布局很像但外部接口和控制逻辑完全不同。跑生成之后你把弹出的 Symbol 和 Verilog model 拉出来看多实例方案的 bank select 信号会很清晰地出现在端口上单宏内切分方案则把这些信号收在宏内部外部只看到一个普通 SRAM 接口。搞混这两者的后果是你在做低功耗设计时可能为宏内部 bank 设计了一堆电源控制端口结果生成的网表根本没有这些端口整个 UPF 策略都要重做。3.4 配置好后生成的文件里哪里能看到 bank 的影子配置写完后compiler 会生成一大堆文件真值表、.lib 时序库、.sdc 约束、Verilog/VHDL 行为模型、LVS/DRC 用的 GDS 和 CDL还有 datasheet 和数据手册。想确认 bank 设置是否生效最直接的方法是在生成的 Verilog 模型里搜 bank select 相关信号。以 4 bank 为例你大概率能看到类似bank_sel[1:0]这样的内部信号并且地址最高两位会参与它的译码。如果采用的 compiler 支持 bank-level power gating还会有类似sleep_bank_0、iso_bank_0这样的电源控制端口出现在行为模型里。.datasheet 或者 summary report 里的信息同样关键。它会告诉你这个配置下最坏访问时间、面积、每个 bank 的功耗估计以及推荐的时钟周期。把这些数据和你在 GUI 里填的参数对应起来才能确认工具按照你的意图完成了编译。4. 到底选几个 bank按设计场景的决策流程4.1 先区分三种典型场景单端口、双端口、低功耗单端口 SRAM 只需要一个访问通道bank 数量的影响主要落在面积和延时曲线上。这类场景建议直接做参数扫描挑出访问时间和面积的 Pareto 最优组合然后再考虑良率因素。双端口或伪双端口 SRAM 情况要复杂一些因为两个端口可能同时访问同一个 bank也可以访问不同 bank。Compiler 通常会提供“同一 bank 冲突”的检测机制当两个端口选中同一 bank 时延迟增加选中不同 bank 时延迟较小。你可以根据实际应用里读写地址的分布倾向性选择让两个端口更容易落在不同 bank 上的配置。不过要注意如果两个端口地址经常访问同一个 bank多 bank 不但没有收益还会因为仲裁逻辑增加额外延迟。低功耗场景是最能体现 bank 价值的场景。智能手环、IoT 这类设备里SoC 常处于休眠状态只有少量 SRAM 在保持数据。如果 SRAM 支持 bank 级 power gating你可以把不需要保存数据的 bank 关掉保持电流大幅降低。此时 bank 数量不是一个简单的时序选择而是由“需要保持的现场数据量”决定的。比如你必须保存 8KB 上下文而单片 bank 是 4KB那至少得加到 4 bank 才能做到只唤醒 8KB、剩余全部关断的功耗目标。4.2 容量和宽深比是决定 bank 数量下限的硬条件听上去很绕但实际操作里 bank 数量先要看容量。容量太小比如 4Kb 甚至 2Kb 的 SRAM单 bank 就是最合理的硬加 bank 纯粹是给面积和功耗添负担。这种小型 FIFO、寄存器堆类的 SRAM编译器往往也默认只给 1 bank 的选项。容量到了 32Kb 以上就要开始认真考虑 2 bank 了。容量超过 128Kb一般来说至少需要 4 bank 才能让位线延迟和字线延迟处于均衡状态。容量超过 512Kb4 bank 起步是比较保险的做法部分激进的高性能设计甚至会用到 16 到 32 bank但此时 memory compiler 生成的不再是纯粹意义的 SRAM macro而更接近一个小型存储子系统的雏形。宽深比也要留意。宽而浅的 SRAM比如 512×128每个 bank 的行数很少位线本来就短这时加 bank 的收益有限反而面积惩罚明显窄而深的 SRAM比如 65536×8位线负载和字线延迟都很突出bank 化带来的收益就很可观。所以同样的存储容量配置可能是完全不同的。4.3 用一次 PPA 扫描代替拍脑袋我在实际项目中遇到最多的问题不是不知道该看哪些维度而是大家习惯拍脑袋定一个 bank 数量。比如默认 4 bank或者听供应商销售说“我们普遍推荐 2”这都谈不上严谨。我更推荐做一个简单的 PPA 扫描选定目标容量和宽度后在编译器支持范围内把 bank 数量从最小值到最大值依次跑一遍记录面积、读时间、写时间、泄漏功耗、动态功耗以及可选的冗余和良率信息。这些数据通常半小时内就能跑完得到的表格比任何经验都可靠。下面给一个我在某 28nm 工艺、64K×32 单端口 SRAM 上实测风格的示例结果具体数值因工艺库而异但曲线形状很有代表性Number of banks面积 (μm²)读时间 (ps)动态功耗 (mW)泄漏功耗 (mW)备注1152000182034.54.2位线负载极大2156800133022.14.6时序提升明显4162100108017.35.1平衡点8174600115016.86.2控制逻辑开始拖后腿16198300134017.67.5已经明显不划算这个例子里 4 bank 是比较理想的选择。如果你在项目里看到类似的表格判断规则也很简单读时间和功耗在某个 bank 数量后不再变好甚至开始反弹那么这个拐点附近就是最优区间。4.4 和编译器里的 column mux、wordline partition 一起看不要孤立调 bankNumber of banks 通常会释放物理收益而这个收益能不能被宏观设计实际接住很大程度取决于你怎么配合 column mux。column mux 表示的是每个 IO 对应的位线组比例。举例来说如果数据宽度是 32column mux 设为 4那么物理 bitcell 阵列的每 4 列位线共用 1 个读出放大器实际 IO 列数要乘 4。这会显著增加单个 word 的物理跨度同时减小每 bit 对应的位线数量。当 bank 数增多、column mux 也增大时两者叠加会让阵列的地图比例发生很大的变化。有些编译器允许的组合会让位线方向和读出放大器之间的走线出现拥挤生成报告里的 area 会虚高另一些组合则可能让局部字线驱动器的扇出失衡导致读路径半段超差。所以我习惯把 “深度 × 宽度 × 物理读端口数” 一起代入编译器然后同时对 Number of banks 和 Column mux 做二维扫描。有时候你会发现 bank2、column mux8 的组合比 bank4、column mux4 的面积和时序都好就是因为物理布局的布线资源占用不同。参数之间是联动的千万不要孤立地只调一个。5. 实际项目里因为 bank 设置踩过的坑5.1 案例一把 bank 从 1 调到 16时序反而崩了之前做一颗 MCU 芯片里边有个 512Kb 的 cache 数据存储 SRAM默认配置是 1 bank。综合时发现这条路径始终满足不了时钟频率于是有人想当然地把 Number of banks 调成了 16认为位线变短一定能提升速度。结果重新编译后访问时间不仅没有下降反而比原来多了 200ps 左右。打开 datasheet 一看bank select 逻辑出现在全局预解码到局部字线的关键路径上16 级选择逻辑的延迟超过了位线电容节省下来的时间。后来把 bank 降到 4访问时间才明显改善。这个案例让我彻底明白bank 数量的影响是 U 形曲线不是单调递减的。排查这类问题最快的方式是在生成 report 后对比不同 bank 数量下“地址到输出”和“片选到输出”两类时序弧的变化。如果片选到输出变差很多但地址到输出变好问题的根源就在 bank select 路径上。此时调 bank 数量没有意义需要从 RTL 侧考虑是否可以把片选信号提前或者用更快的局部译码结构。5.2 案例二低功耗模块的 bank 休眠控制逻辑被漏接另一个项目里我们看中多 bank 的休眠特性把 4 bank SRAM 的电源关断端口接到了电压域管理器上。RTL 仿真没问题但到了后端的 UPF 检查阶段工具报了 ERC 错误原因是 compiler 生成的 power gate 控制信号命名规则和我们预期的完全不一致。一开始以为 tool 配置错了后来翻 user guide 才发现这款 compiler 里 bank 级 power gating 默认是“内部自动控制”模式与外部 UPF 期望的开关控制端口并不是直接对应关系。需要在配置里显式打开某个external_power_switch选项才会把每个 bank 的 sleep 和 isolation 控制引脚暴露出来同时还要按照 compiler 要求的方法连接 UPF 里对应的 power switch cell。这个坑提醒我任何带电源管理需求的 SRAM 配置在确认 bank 数量时一定要同步确认 compiler 生成的 macro 端口列表和 datasheet 里的上电时序要求。如果内部 bank 电源开关的开启速度跟不上时钟唤醒时读取的第一个数据可能是非法的需要额外插入等待周期或者隔离逻辑。5.3 案例三DFT/BIST 只配了一个 bank 的入口结果漏覆盖还有一次踩坑是在 DFT 阶段。memory BIST 逻辑设计和 SRAM bank 配置没有对齐。我们选的 SRAM 是 4 bank但 BIST 控制器是按照单 bank 线性地址写的没有在算法里正确处理 bank select 的切换顺序导致测试时只完整扫了两个 bank另外两个 bank 的固定故障漏检。这个案例的教训不是让你别用多 bank而是提醒你在项目早期做 memory 测试计划时就要把 bank 数量告知 DFT 工程师。现在主流 EDA 工具的 memory BIST 生成器都能从编译器输出的 memory model 里解析出 bank 信息自动生成带 bank 遍历的算法。但如果你用的是自定义 BIST或者第三方 MBIST IP一定要核实地址解码逻辑是否能覆盖到所有 bank。5.4 我的经验清单拿到新工艺库先做的几件事换新工艺节点或者换新 compiler 版本时我会先花半天时间做以下事情把目标 SRAM 容量下支持的 bank 范围完整跑一遍记录 PPA 变化特别是读时间的 U 形曲线拐点。确认 compiler 的 bank 切分方向是切字线还是切位线并和 datasheet 的位置信息比对。检查生成的行为模型里是否有 bank 相关使能或电源控制端口以及它们是否影响 RTL 仿真模型。把不同 bank 配置下的面积、功耗、时序数据做成表格存进项目 wiki方便后端和项目经理随时查询。这套动作做完基本能避开大多数因为 bank 设置不合理导致的返工。6. 动手验证的思路让编译器数据替你作证6.1 从数据手册里找什么才能判断这个 bank 设置是否适合拿到 compiler 生成的 datasheet不要只看访问时间那一个数字。一般 datasheet 里包含 area、power、 pin capacitance、setup/hold time、min/max frequency 多个维度。判断 bank 设置是否合理建议先看 area 和 access time 的比例关系。如果 access time 比预期快很多但面积比预期大很多说明 bank 可能选多了。再看输入电容。编译器生成报告里每个 address 或 data 引脚的输入电容变化也能反映 bank 数量。bank 多时预解码逻辑重输入引脚电容明显上升。这会直接影响前端综合工具对输入链路的优化有时甚至会导致外部逻辑 buffer 变多。最后看功耗报告里的 peak average power。动态功耗下降但峰值功耗反而上升说明 bank 切换导致电流集中这种情况在低功耗和电源完整性检查里都要关注。6.2 用 .lib、.sdc 和 Verilog 模型交叉确认拿 .lib 里的时序弧是最直接的确认方式。翻开.lib查找timing()区块里的cell_rise、cell_fall能看到地址输入到输出、时钟到输出的延迟值。如果多 bank 配置下的时钟到输出延迟明显下降說明位线路径的收益确实被工具建模进去了。.sdc 文件里通常会给出 compiler 推荐的时钟约束和输入输出延迟。这部分很容易被忽略。有些 compiler 会根据 bank 数量生成不同的 recommended constraint你如果直接沿用默认约束可能在仿真阶段收益很小因为约束把 bank 延迟裕量吃掉了。建议对比修改 bank 前后的 .sdc 差异理解工具把哪些路径列为了关键路径。Verilog 模型层面除了确认 bank select 信号还建议跑一条简单的 RTL 仿真覆盖 bank 边界地址切换。比如 4 bank 配置下从 bank0 的最高地址跳到 bank1 的最低地址观察读出数据是否有多拍延时的额外风险。虽然.lib 里已经考虑了这个 transition但真实宏在边界 bank 的走线偏斜仍然可能存在早期 RTL 仿真时把边界地址用例加上能提前暴露一些模型层面的问题。6.3 迭代步骤建议从一个增量改变开始不要一次性把所有参数全改掉那样出了问题你根本不知道是哪个参数引起的。正确做法是保持深度和宽度不变先单独把 bank 从当前值改为相邻值比如从 2 改成 4跑一遍完整编译比较报告再把 column mux 改半档再比较一次。每次只有一个变量变化记录到的差异才能归因于这个变量。等找到一组偏好的配置后别忘了做 PVT 变化下的 robustness 检查。同一 bank 数量在 SS corner 和 FF corner 下时序曲线的拐点位置不一定相同。有些设计在典型条件下 4 bank 最优但在极慢工艺角下 8 bank 反而更抗延迟因为工艺变慢时位线延迟的增长比选择逻辑延迟更剧烈。所以如果项目分布跨多个电压和温度范围bank 数量的选择要在最差 corner 下验证而不是只看典型条件。迭代过程中也要保留中间产品就是每次编译生成的 .lib 和 datasheet。后面如果视图层或者布局规划有变化需要重新评估 SRAM 选型时这些历史数据能帮你快速定位“当时为什么选了 4 bank 而不是 2”。说到底Number of banks 没有一个放之四海而皆准的默认值。它和具体工艺、容量、宽深比、工作电压、功耗目标、甚至后端布局都有关系。与其到处问别人推荐值不如自己花半天时间把参数扫描跑一遍。我看过太多项目明明半小时的扫描实验就能解决的事最后硬是在综合阶段靠加班调逻辑拖了两周才解决。数据就摆在编译器生成报告里只要你愿意读它比任何人都诚实。
返回列表