ARTICLE DETAIL

资讯详情

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

复杂芯片模块的Floorplan与Powerplan设计实战解析

复杂芯片模块的Floorplan与Powerplan设计实战解析 1. 项目背景与整体设计思路拆解1.1 为什么是ICC为什么是floorplan与powerplan先交代一下这次项目的基本情况。这颗芯片是一个PCIe相关的SoC子系统里面同时集成了多个CPU簇、大量SRAM阵列、以及好几个高速SerDes PHY的模拟IP。我从RTL freeze之后介入负责整个子系统的数字后端实现。工具用的Synopsys ICC工艺是28nm HPC规模大概在800万门左右复杂度和密度都处于一个比较尴尬的区间——说大不大说小不小但恰恰是这种模块最考验floorplan和powerplan的功底。很多朋友在初学数字后端时有个误区觉得floorplan就是摆几个macro、给std cell画个边界就完事powerplan就是打几圈ring、拉几条strap。实际上在整个后端流程中floorplan和powerplan是唯一一个“做错一步、后面全崩”的环节。placement阶段发现问题你还能局部挪一挪CTS阶段发现问题还能用buffer修一修但如果floorplan阶段给macro留的channel太窄、给power strap分配的track不对、给关键IP的供电环宽度不足那后面route阶段无论怎么调都是戴着镣铐跳舞。我见过太多项目倒在这种“小事”上最后只能靠强行加宽die尺寸来救火代价是成本直接上升。这次选择ICC而不是Innovus倒不是说工具之间有什么绝对的优劣而是这个项目的后端环境沿用了一套成熟的ICC脚本框架包括分模块的legalize流程、与顶层APR的接口处理、以及基于ICC的IR drop signoff流程。更重要的是ICC在floorplan阶段有非常灵活的object handle机制配合Tcl可以做很多自动化操作这对我们这种macro数量多、分布不规则的模块来说效率反而更高。1.2 复杂模块的floorplan双重目标说回floorplan本身。复杂模块的floorplan从来不是单纯的“摆proxy”它要实现两个互相制约的目标。第一个目标是满足时序。具体来说是让所有高速路径的物理距离尽量短。以这颗芯片为例CPU簇之间的cache一致性互联跑在1.2GHz如果两个CPU cluster之间隔了半个die那不管是走顶层绕线还是后端绕线都很难收敛。第二个目标是满足物理实现的可布线性也就是congestion可控。macro之间的channel宽度、macro与block boundary之间的间距、pin access区域的预留这些都会直接影响后面routing stage的overflow。两者之间常常打架——把macro摆得太紧凑时序是好了但绕线资源被挤压DRC和short多到爆摆得太松散绕线是顺畅了但critical path拉长setup直接recover不了。我在项目里习惯把floorplan分成两个阶段来看第一个阶段是“满足时序约束的粗排”第二个阶段是“满足物理可实现性的细调”。粗排阶段只关心macro的相对位置、数据流方向、关键IP与IO port的关系细调阶段才去处理halo、channel、pin congestion这些细节。很多新手直接在第一步就把macro摆得满满当当结果到细调阶段根本没有回旋余地。我的经验是粗排阶段宁可稍微松散一些也要保证后面有调整空间。1.3 powerplan设计的芯片级视角powerplan这个环节很多教程都喜欢从“怎么画电源环、怎么拉电源条”这种操作层面讲但我在实际项目中更想强调的是powerplan本质上是芯片级供电网络设计在模块级的投影。你画出来的每一条ring、每一根strap不仅仅是给后端工具看的图形而是真实电流路径的物理载体。这个模块的功耗主要有三块CPU cluster的动态功耗、SRAM阵列的漏电与开关功耗、以及SerDes模拟IP的模拟供电需求。前两块是典型的高电流密度区域需要密集的power strap网络来保证IR drop在可接受范围第三块则更特殊模拟IP对电源噪声特别敏感通常需要单独隔离的power domain和相对独立的供电环避免数字开关噪声通过电源网络耦合进敏感电路。28nm工艺下电源网络的另外一个关键约束是electromigration。金属线越细允许通过的电流密度就越低。如果你powerplan阶段只想着“IR drop满足就行”那到了EM signoff阶段往往会发现某几根比较细的strap上电流密度超标。EM修起来比IR drop更麻烦因为它往往不是加宽局部金属能解决的而是需要重新调整整片供电网络的拓扑。所以我在这个项目里从一开始就把EM作为一个硬约束来参与strap宽度和间距的计算而不是事后去看报告。2. floorplan核心细节解析与实操要点2.1 数据准备与整体布局信息的整理在真正打开ICC之前有一堆数据准备工作必须要做得细致。我的经验是floorplan阶段花在“理解数据”上的时间应该和不花在“点击操作”上的时间至少一样多。如果数据理解不到位后面所有空间规划的决策都是盲人摸象。这个项目里我首先整理的是macro清单和它们之间的数据流关系。整颗芯片有32个SRAM macro、4个CPU cluster的hard macro、2个SerDes PHY的模拟IP还有大量的custom cell。对于每个macro我关心的不是它内部长什么样而是它的端口位置、尺寸、以及它与其他macro或IO之间是否存在高速数据交互。把这些信息整理成一张表比看十遍网表都管用。其次是IO port的分布情况。这个模块是一个子系统级的设计它的IO不是封装引脚而是与顶层其他模块对接的边界端口。这些端口的位置不是我能随便改的而是由顶层规划决定好的。所以floorplan的第一步就是把所有IO port的物理位置读进来作为整个布局的“锚点”。我在项目里对IO port做了进一步的分类哪些是高频时钟输入哪些是高速数据端口哪些是低速控制信号。高速数据端口的进出路径是我后续摆放macro时最优先考虑的因素。最后是die size和utilization的初始估算。当时我根据标准单元数量、macro占用的面积、加上预估的绕线资源余量初步把utilization定在68%左右。这里有个经验值大家可以参考对于这种带大量SRAM的复杂模块65%到70%的utilization是一个比较健康的区间。利用率低于60%说明die面积浪费严重高于75%后面的congestion大概率会非常难看。当然这个数字还要结合macro占用的面积比例来调整macro占比越高std cell的实际可用密度就越高utilization要相应下调。2.2 macro摆放的关键策略与数据流对齐macro摆放是floorplan的核心中的核心。我的策略很简单先梳理数据流的方向再按照数据流来定macro的宏观位置。以这个子系统为例数据流大致是这样SerDes PHY接收到高速串行数据经过deserializer转成并行数据进入一组接收FIFO然后通过AXI互联总线送达CPU cluster做处理处理完的结果再通过发送FIFO回到PHY。CPU cluster还挂着大容量的L2 SRAM作为缓存。如果按照数据流的自然方向来布局应该是PHY在左侧、接收FIFO和发送FIFO紧挨着PHY、AXI bus fabric居中、CPU cluster和L2 SRAM在右侧。这样走线的方向就非常规整几乎不会出现长距离的“回头路”。在实际摆放过程中有几个细节值得专门说。第一macro的channel宽度不能一看都是同一个值要区分场景区别对待。同一组数据流路径上相邻的两个macro之间channel至少要留出3到4根M4 track的宽度方便走线但对于没有数据交互的两个macrochannel可以压缩到1到2根track节省面积。我就见过有同事把所有macro之间的channel统一设成一样宽结果面积被白白浪费了一大块利用率凭空高了几个点。第二macro的orientation要统一。尽量让macro的数据端口朝向数据流的方向这个不只是美观问题更是为了减少信号线的绕路。如果两个macro的数据端口背对背信号线要么绕macro的边界走一圈要么在macro内部穿行——后者是绝对不允许的因为hard macro内部没有你的绕线资源。我在ICC里通过set_fp_macro_options和refine_macro_placement配合手动摆放基本能做到每个macro的端口都朝向正确方向。第三CPU cluster这种大尺寸hard macro的摆放要特别关注它与周边SRAM之间的距离。CPU通过密集的读写端口访问L2 SRAM这些端口的工作频率极高在布线层面必须保持保守的短距离。我的做法是让CPU cluster和L2 SRAM之间尽量贴近中间不留其他功能宏channel间距也压到最小。这样做虽然牺牲了一点可布线性但对时序的收益是决定性的。2.3 特殊模块与边界条件的处理除了普通SRAM macro复杂模块里总会遇到一些“刺头”模块处理得好不好往往是区分资深工程师和新手的标准。首先说模拟IP。这个项目里的SerDes PHY由于要接封装走线被放在了die的左侧边缘而且顶层明确要求它周围一定范围内不允许有任何标准单元和数字走线防止数字开关噪声耦合进模拟电路。这个要求在floorplan阶段落实起来就是在PHY四周建立placement blockage和routing blockageblockage的范围要比PHY本身的boundary再往外延伸至少50微米。同时PHY与其他数字逻辑之间要保留一条足够宽的隔离带隔离带里不摆任何std cell只走电源地straps。有人会问隔离带是不是太浪费面积但如果你在28nm节点做过模拟数字混合设计就会知道这个成本是必须付的。模拟IP被数字噪声干扰后眼图质量下降、jitter变差那可比浪费一两百微米的面积头疼多了。其次是多bit register和clock gating cell的摆放考虑。这类单元在floorplan阶段不需要单独摆但要为它们预留空间。现代综合工具会生成大量的ICG cell它们经常被约束在特定的区域以优化clock tree。我在floorplan阶段的做法是在每个功能模块的边界区域预留一块不放置普通std cell的空间专门留给ICG cell使用。这个预留比例大概是整个模块面积的2%到3%。不要小看这个比例如果floorplan阶段不留CTS阶段你会发现自己不得不在已经摆满std cell的区域里硬塞ICG cell造成局部congestion和timing detour。2.4 在ICC中执行floorplan的常用命令梳理我给出一套在这个项目中实际用过的ICC floorplan命令并简单注释了每个命令的作用。不同版本的ICC命令可能有细微差异但整体思路是一致的。# 1. 创建floorplan初始边界 # - core_utilization: 初始利用率 # - core_aspect_ratio: 宽高比 # - core_offset: core边界到die边界的距离 create_floorplan \ -core_utilization 0.65 \ -core_aspect_ratio 1.0 \ -core_offset {50 50 50 50} \ -left_io2core 60 \ -right_io2core 60 \ -bottom_io2core 60 \ -top_io2core 60 # 2. 设置macro摆放的halo # halo是macro周围禁止放置其他cell的区域 set_fp_macro_options \ -halo_x {5 5} \ -halo_y {5 5} \ [get_cells {u_sram_* u_cpu_cluster*}]上面这个create_floorplan里的io2core指的是IO port到core边缘的距离这个值不是随便拍的。IO port的物理位置是由顶层定的但core_halo这个参数决定了preroute之后的pin access区域宽度。如果太窄后面routing阶段会发现IO pin附近的congestion极其严重。我一般会把IO port到core boundary的距离至少留到50到60微米以上给pin access和电源strap都留出空间。# 3. 预摆放macro # 先用manual placement把关键CPU cluster固定再用refine自动排SRAM set_fp_placement_strategy -macro_strategy mf_auto # 用脚本计算出的坐标固定CPU cluster位置 set_cell_location \ -coordinates {400 800} \ -orientation N \ [get_cells u_cpu_cluster0] set_cell_location \ -coordinates {1000 800} \ -orientation N \ [get_cells u_cpu_cluster1] # 4. 对剩余SRAM做自动refine refine_macro_placement \ -num_strap_penalty 10 \ -macro_frequency_penalty 20这里要提醒一下不要完全相信refine_macro_placement的默认结果。自动placement算法擅长处理的是规则的、均匀分布的macro集合但对“数据流有明确方向”的设计算法往往不够智能。我的习惯是先把牵涉高速数据路径的几个关键macro手工定好剩下的、彼此之间交互不强的macro再交给自动工具去排。这样既保留了工程师对核心路径的控制又利用了工具在全局优化上的计算能力。3. powerplan设计与实现3.1 电源网络拓扑的整体思考floorplan做完接下来就是powerplan。powerplan的拓扑结构选择直接决定了整个芯片的供电质量和后端收敛难度。在28nm工艺下我见过的主流做法有三种只做ring的方案、ring加strap的方案、以及ring加strap加mesh的方案。只做ring也就是在core周围打一圈电源环这通常只适用于小尺寸模块或低功耗设计因为核心区域的中间部分离电源环太远IR drop往往会超标。ring加strap是大多数设计的标配strap从ring上引出横跨core区域上方把电源送到core内部的各个角落。ring加strap再加mesh则是重负载设计的做法在M6/M7上搭出纵横交错的电源网格把供电电阻压到极低。这个项目由于CPU cluster和SRAM的峰值电流密度很大我最终选择了M4/M5的strap加M6/M7的mesh混合方案。具体来说M4/M5作为局部的电源条负责给std cell区域供电M6/M7作为全局的电源网格负责把电流从外部电源IO传输到die各处。顶层再通过大量via把这两层网络连接起来。这样做的好处是M4/M5层离std cell更近via连接路径短局部IR drop小M6/M7层则能用更宽的金属铺出低电阻的电源干线承载更大的电流。3.2 电压域划分与隔离规则前面提到这颗芯片有不同电压域。这里的powerplan不能把所有模块一视同仁地接入同一个电源网络。我在项目里划分了三个电压域核心逻辑电压域VDD_CORE、IO电压域VDD_IO、以及模拟器件的模拟电压域VDDA_PLL。VDD_CORE是整个芯片的主供电工作电压0.9V覆盖了CPU cluster、SRAM阵列、AXI fabric和绝大部分逻辑电路。VDD_IO是1.8V只给IO buffer和level shifter的IO侧供电。VDDA_PLL是1.8V的模拟电源专门给PLL和SerDes的模拟电路供电。这三个电压域之间需要level shifter和isolation cell来做电平转换和信号隔离。这些cell的摆放位置其实在powerplan阶段就应该有所预留。我在每个电压域的边界上划出了一条专门的通道沿着通道摆放level shifter避免它们在placement阶段乱跑到电压域交叉区域以外。这样做还有个附带好处level shifter的电源连接更规范不太会出现connect电源的错误。在ICC里创建电压域比较直接用create_voltage_area命令指定domain的boundary和电源地网络名就行。但要注意domain的boundary最好和macro的boundary对齐不要把一个macro劈成两半。同时domain之间的间距要足够我这边设了10微米的gap既隔离了物理连接又给出了level shifter的摆放空间。3.3 电源环、电源条和Mesh的实现细节与参数计算下面讲参数计算。这部分内容我喜欢拿具体数字来讲没有数字的参数设计都是耍流氓。先估算整颗芯片的峰值电流。假设这个模块在最高负载下总功耗大致是18W电压0.9V那峰值电流就是20A左右。我一般习惯在功耗估计上再留20%的余量也就是按24A来设计电源网络。然后是电源环。电源环的作用不是承载大电流而是作为strap和供电IO之间的电流汇集层。我用的M7层宽度设置5微米间距设置1.5微米每组VDD/VSS各打3条总共6条金属线环。环的宽度要匹配后续strap的电流需求具体计算上有个简化公式电源环总宽度至少应该是所有strap总宽度的1.3倍以上以保证环上不会形成电流瓶颈。接着是strap。strap的间距主要取决于std cell区域的IR drop目标。对于0.9V的core电压我的target IR drop是3%也就是27mV。这27mV要分给从电源IO到core整个传输路径一般电源环上占30%、strap与mesh上占50%、std cell内部的Standard Cell Power rail上占20%。用简单的电阻估算公式可以反推出strap的间距需求。这个项目的计算结果是M4/M5层strap的间距设为7.2微米大约每两到三个std cell row就有一条VDD和VSS strap。最后是mesh网格。由于M6/M7层用了更宽的金属我设的间距是40.8微米方向和strap垂直形成大概5x5微米的供电网格。M3作为std cell连接层我通常不做完全铺满的grid而是靠synopsys的create_power_straps命令按规则自动生成M3的短strap。下面是我在实际项目中用的ICC powerplan命令序列略微简化过但关键参数保留着# 1. 创建电源环 add_rings \ -nets {VDD VSS} \ -type ring_blocks \ -around {core} \ -layers {top M7 bottom M7 left M6 right M6} \ -width {top 5 bottom 5 left 5 right 5} \ -spacing {top 1.5 bottom 1.5 left 1.5 right 1.5} \ -offset {top 2 bottom 2 left 2 right 2} \ -threshold 0 # 2. 创建水平和垂直的电源straps add_power_straps \ -nets {VDD VSS} \ -direction vertical \ -layer M4 \ -width 0.6 \ -num_placement_strap_groups 2 \ -step 7.2 \ -master_ring_net VDD \ -master_ring_width 3 add_power_straps \ -nets {VDD VSS} \ -direction horizontal \ -layer M5 \ -width 0.6 \ -step 7.2 \ -master_ring_net VDD # 3. 创建M6/M7全局mesh create_power_straps \ -nets {VDD VSS} \ -direction vertical \ -layer M6 \ -width 0.8 \ -step 40.8 \ -configure_step_and_direction center create_power_straps \ -nets {VDD VSS} \ -direction horizontal \ -layer M7 \ -width 0.8 \ -step 40.8 \ -configure_step_and_direction center # 4. M3层短strap连接std cell power rail create_power_straps \ -nets {VDD VSS} \ -direction vertical \ -layer M3 \ -width 0.1 \ -step 1.8 \ -configure_step_and_direction center \ -master_ring_net VDD这里有个关键参数值得单独拿出来说-configure_step_and_direction center。它表示每条新创建的strap尽量与前一层已经存在的strap中心对齐。这个设置能让上下层电源网络之间的via连接数量最大有效降低垂直方向的电源电阻。如果没有这个设置两层strap错位严重电流只能绕路等效电阻会高出一截IR drop直接变差。3.4 多层供电网络与macro区域的手工处理在自动创建完power network之后我还需要做一步手工处理macro区域的电源连接。SRAM macro和CPU cluster这类hard macro它们的电源引脚不是简单的M3 rail而是分布在macro边界上的特定位置。有的macro要求从M4或M5层直接供电有的macro则要求M6/M7层的strap必须经过它的power pin上方。ICC里有一组命令专门处理这种情况最常用的是derive_pg_connection它负责把macro的physical power pin和供电网络在逻辑上绑定。更精细的控制是用add_power_straps配合-ignore_soft_macro_constraints这类选项或者在对某个macro做局部电源规划时先用set_power_plan_options指定macro的power pin接入层再手动在该macro周围打一圈局部的电源环。我在这个项目里对两个CPU cluster和四个大的SRAM阵列都额外画了局部的M6/M7电源环确保这些高功耗模块从全局mesh取电时不会因为最顶层的strap距离太远而产生额外的IR drop。另外还有一个细节很多人容易忽略macro区域下方的电源strap是否要保留。如果一个SRAM macro的物理尺寸是100微米乘200微米而其所在位置下方的M4/M5 strap仍然像其他地方一样保留这些strap还是可以正常工作的它们的存在不会影响macro内部的布局因为macro是占用金属资源的其内部已有自己的金属层。正确做法是在macro正下方的电源strap要保持存在因为macro要接入这些strap取电。真正要避免的是在macro区域内部再额外创建仅服务于std cell的M3短strap这类短strap在macro内部没有任何意义还浪费资源和DRC检查时间。4. 实操过程与核心环节实现4.1 从数据导入到初步floorplan的完整执行流程上面讲过的是设计层面的思路这一节我按时间线把整个实操流程串起来。一个复杂模块的后端实现从打开ICC到完成floorplan与powerplan大概要经过下面这些环节。第一步是数据准备。我需要在ICC里读入网表、约束文件、物理库、电源定义文件这些基础数据。这是一个枯燥但容易出错的环节。特别是UPF文件如果电压域定义和网表里的电源引脚不一致后面所有步骤都会报错。我习惯在开始任何place操作之前先跑一遍link和check_mv_design把所有的电源域连接问题在源头堵死。第二步是create_floorplan。执行时我先把顶层约束的IO port位置写成一个Tcl脚本然后运行create_floorplan加一个很小的初始core面积。为什么要先用很小的面积跑因为后续macro手动摆放后core的实际大小会跟着调整我倾向于先在“略小”的core边界里排macro再通过expand_fp命令把边界往外推。这样做的好处是macro的相对位置密度更高能看到实际面积需求避免一开始就把面积开得太宽松、搞得后面所有路径都超长。第三步是macro摆放。先手动放CPU cluster等几个关键硬核再对SRAM做批量自动摆放最后用legalize_fp_placement检查是否有overlap。手动摆放时我习惯用ICC的GUI辅助查看数据流方向然后以Tcl命令固化下来。GUI只是观察工具最终一切以脚本为准。第四步是摆放std cell。这一步和floorplan关系密切。做完macro摆放后我会先跑一个快速placementplace_opt -skip_initial_placement或者直接compile_ultra -only_design_rule目的是看看congestion的大致分布。如果发现某个区域overflow过高回到floorplan阶段微调macro位置或加宽channel。我习惯把这个过程叫“floorplan的快速验证”它是保证floorplan质量的重要环节。第五步是powerplan实现。按照上一节的参数依次创建power ring、straps、mesh。每次执行完一组命令都要用verify_pg_nets检查电源网络的物理连接是否完整。常见的问题是某些macro的power pin没有连上、某个strap短路到了其他网络、或者电压域边界处的电源网络断裂。第六步是质量检查。我会用IC Compiler自带的power network分析命令主要是IR drop分析做一个初步的快速评估。虽然真正的IR signoff在后续流程中但这个阶段的趋势性结果能帮我判断电源网络是否有足够的冗余哪些区域可能需要加强strap密度。4.2 电源网络完整性的快速验证方法说到验证我想展开讲一下verify_pg_nets。这个命令在ICC里是检查电源网络物理连接性的一个关键工具。很多刚接触后端的同事觉得powerplan建完就行了直接进place阶段结果后面一堆DRC error源头就在这里。verify_pg_nets会检查每一层电源金属的连续性、via的连接、macro电源引脚的接入。如果发现开路或短路它会生成一个error报告包含具体坐标和涉及的网络。我在项目里的做法是在每次创建完一个电源网络组件后立刻跑一次verify而不是全部建完再检查。这样一旦出错能快速定位到是ring层的问题还是strap层的问题。还要强调一下IR drop的快速检查。ICC自带的IR drop分析perform_power_analysis或analyze_rail_voltage在floorplan阶段就能跑虽然精度比不上专门的RedHawk或Voltus但对于判断电源网络的整体趋势已经完全够用。我一般在powerplan完成后跑一次快速IR分析重点观察resistance热点、vdd/vss rail上的电压分布是否均匀、macro周围的供电是否出现明显凹陷。这些结果会直接反馈到strap密度和mesh参数的调整上。4.3 时序与拥塞的早期预警分析floorplan和powerplan阶段还有一个容易被忽略的产出就是时序和拥塞的早期预警。在完成快速placement之后我会从ICC导出congestion map和timing summary。这里的timing summary不要求准确因为时钟树还没综合工具只是用ideal clock做粗略估计但relative的趋势是可信的。如果发现某条path的estimated delay明显比其他同类路径长那大概率是floorplan阶段给它的物理距离留长了需要回头看macro摆放。congestion map是我更看重的指标。理论上floorplan阶段就要保证任何区域的overflow都不超过1%到2%。如果超过优先考虑的不是调整std cell placement而是回到floorplan调整macro或者加宽channel。另外要特别关注那些位于macro corner区域的拥挤点。macro corner是绕线资源的天然瓶颈信号线往往要在这里拐弯很容易成为congestion热点。如果发现某个macro corner的overflow过高可以在macro周围加一个小的routing blockage强制信号线绕道其他区域走虽然看起来多绕了一点路但整体congestion会显著改善。4.4 项目中的实践数据与效果评估这个项目最终的floorplan和powerplan效果我简单列一下数据。core面积最终定为1400微米乘1400微米利用率约66%。电源网络使用M4/M5 strap加M6/M7 mesh的方案strap间距7.2微米mesh间距40.8微米。完成powerplan后快速IR drop分析显示全chip最大静态IR drop约22毫伏占0.9V的2.4%低于3%的目标线。拥塞方面快速placement后的total overflow为0.5%局部热点控制在1%以内。后续的全局布线阶段没有因为floorplan或powerplan的问题产生大的返工。这些数据说明前面在floorplan和powerplan阶段做的细致的规划和验证是值得的。真正到了place_opt和route阶段你会发现前期多花一两天做精细的规划后面省下的调试时间是好几倍。5. 常见问题与排查技巧实录5.1 典型问题速查表我整理了在这个项目中踩过的坑和常见问题做成一张速查表供参考。每个问题后面附了排查思路方便大家在实际项目中快速定位。问题现象可能原因排查与解决思路macro之间存在overlap手动摆放坐标冲突检查set_cell_location坐标用legalize_fp_placement修正必要时先执行undochannel过窄导致congestionmacro间距不足在ICC中用report_congestion定位拥挤通道加宽channel或调整macro坐标IR drop在局部区域超标mesh/strap密度不足或macro取电路径过长在热点区域增加额外的power strap或添加局部电源环macro的power pin未连接derive_pg_connection未覆盖或UPF定义缺失检查UPF文件运行derive_pg_connection -help确认覆盖范围电源strap短路到其他网络strap参数设置错误或与已有网络重叠检查add_power_straps的net参数用verify_pg_nets定位短路坐标placement阶段发现macro之间无法摆放std cellhalo设置过大调整set_fp_macro_options中的halo_x/halo_y参数在保证绕线前提下缩小halo信号线必须穿越macro区域macro端口朝向与数据流不匹配回看macro orientation设置调整macro方向以减少绕路高速IO port附近pin access congestionio2core距离不足增加create_floorplan中的io2core参数或在IO区域设置routing blockage引导走线5.2 一个典型的IR drop热点排查案例这个项目里我遇到过一个挺有代表性的IR drop热点问题拿出来详细说说。问题是这样的快速IR drop分析完成后报告显示CPU cluster0的右上角有一个电压凹陷局部电压降到了0.87V左右超过了3%的目标线。从热力图上看这个凹陷的区域并不大大概就是几个macro pin的大小但数值很刺眼。第一反应是检查CPU cluster0周边的电源strap密度。结果发现那附近M6/M7的mesh间距几乎是均匀的strap宽度也没问题。接着查了CPU cluster0的power pin分布发现这个hard macro的右上角集中了大量的VDD pin而mesh的最近一条M7横向strap刚好没有覆盖到位导致这些pin要从较远的地方取电引入额外电阻。定位到原因后解决办法就很简单了在CPU cluster0的右上角增加一条局部的M7 strap专门服务这一小片高密度pin区域。具体做法我在ICC里用add_power_straps命令限定一个矩形区域在区域内额外加了几条M7 strap并确保它们与原有M7 mesh通过via正确连接。重新跑IR drop分析后这个热点的电压降恢复到了22毫伏之内问题解决。这个案例想说明的是powerplan的设计不能只看全局网格是否均匀还要结合具体hard macro的电源引脚分布来调整。很多试用版工具看全局IR drop热力图觉得很均匀就以为万事大吉实际局部的微观热点才是最影响芯片性能的地方。5.3 避坑指南与独家实操心得最后分享几条我在实践中总结出来的避坑经验。这些内容在常规流程文档里很少被写透但对实际项目很有价值。第一不要把utilization算得太满。很多项目为了追求die面积经济把utilization压到70%以上结果后面CTS和route阶段修改没有回旋余地只能反工。我的经验是复杂模块的utilization最好不要超过68%如果确实面积吃紧宁可稍微扩大die尺寸也不要牺牲后端的灵活性。芯片面积是成本但后端每多一轮ECO工程变更指令的成本同样不低。第二powerplan要在floorplan阶段就并行考虑不要等floorplan完全冻结了再做。尤其是在macro摆放阶段你要提前想好某个macro下方的strap怎么走、这个区域的电源环从哪接入、电压域边界上的level shifter摆哪里。如果floorplan完全定死了再做powerplan你可能会发现根本没有合适的金属层和位置来铺设电源网络。第三灵活使用blockage。在floorplan阶段placement blockage和routing blockage不是用来限制自己的而是用来引导工具行为、预防问题的。比如在高速数据路径两侧增加routing blockage可以强制信号走预期的通道在macro密集的角落增加placement blockage可以避免std cell挤进走线瓶颈区域。合理使用blockage是资深工程师握有的一种“大局观”工具。第四IR drop vs congestion本质是面积与性能的权衡。电源网络铺得越密集、metal宽度越大IR drop就越低但占用的绕线资源也越多congestion就会恶化。我在项目里的折中方法是整个die用中等密度的strap保证基本供电在高功耗、高温度的局部区域额外增加strap而不是全chip无差别加厚。这样既控制了IR drop又不会让congestion失控。第五不要忽视powerplan对CTS的影响。电源strap占用的金属层会直接影响CTS阶段时钟网络的绕线选择。如果M6/M7的strap布得太密CTS工具在M6/M7上找绕线路径时会遇到更多障碍。所以我一般会把clock net的preferred layer设定在M4/M5或更高层并检查它与power strap层是否冲突。如果有冲突要么调整power strap的间距要么给clock route留出专用的绕线通道。6. 一些更进阶的扩展思考6.1 从floorplan阶段就要考虑ECO需求这个项目在中途有一次比较大的ECO工程变更指令需要增加一小块逻辑来修复一个功能bug。如果在floorplan阶段没有预留任何空间这种ECO会非常难处理因为你会发现整个core区域已经被std cell和macro塞得满满当当根本没有多余空间来放置新加入的逻辑。我的经验是在floorplan阶段就刻意保留一些“空白区域”不要把所有地方都排满。这些空白区域不需要很大但分布要合理尽量靠近可能的逻辑更新点。比如CPU cluster和AXI fabric之间、SerDes PHY与数字逻辑之间、以及各个功能模块的交界处都是ECO的高发区域。在这些位置预留一些空间后面ECO时的改动成本会小很多。ICC里有几个命令可以辅助完成ECO space预留比如create_placement_blockage加一个区域或者用set_fp_macro_options -halo把macro周围的空间适当放大。我的习惯是让每个功能模块之间都保留一个宽度至少为2到3个标准单元高度的通道这个通道平时不摆cell关键时刻能放下几十个ECO cell。你可能觉得这样浪费了一点面积但在流片前遇到功能bug时这点空间能救你的命。6.2 IR drop与电压降分析工具的配合使用我们平时在ICC里做的快速IR drop分析本质上是一种简化。它只考虑了静态电流没有考虑动态电流变化和封装参数的影响。真正silicon signoff阶段项目组还会用RedHawk、Voltus等专门的功耗分析工具把封装模型、热效应、动态功耗都加进来做一个更加精确的EM与IR分析。但我还是要强调ICC自带的快速IR分析在这个阶段是有价值的。它最大的价值在于能帮你快速发现电源网络的物理拓扑问题——某段金属太窄、某个macro的取电路径太长、某层strap出现了意外的断裂。这类问题如果拖到RedHawk阶段才发现代价会大得多。我的做法是在ICC里做快速IR分析时至少要看以下几个指标最大IR drop的绝对值、热点位置是否与某类高功耗IP重合、每个电压域的IR drop分布是否均衡。如果这几个指标都在范围内再交给后端团队出详细的RedHawk报告。如果快速分析阶段就有问题我肯定不会急着往下走。6.3 多电压域与电源关断设计的floorplan协同前面提到这个项目有三个电压域。坦白说这三个电压域还是比较常规的它们都是常开电源域不存在电源关断。所以floorplan和powerplan的复杂度还不是最高的。如果遇到真正的power gating设计比如某个模块在低功耗模式下要被彻底关断电那floorplan和powerplan的复杂度会急剧上升。你需要在关断域周围加isolation cell和retention flip-flop需要处理power switch cell的摆放需要在关断域和常开域之间规划出专门的行。我做过的项目里对这种设计的经验是power switch cell绝对不能放在关断域内部而要放在关断域和常开域的边界上并且要保证开关cell的VDD来自常开域而它的输出VDD_GATED去往关断域。这个边界区域需要足够的宽度来容纳一排甚至两排的switch cell。同样isolation cell也有它的特殊要求它需要同时接受常开域和关断域的电源所以必须放在两个域交界处。在floorplan阶段这些特殊cell的摆放位置和区域宽度就要被规划进die面积预算中。如果你等place阶段再来考虑往往会发现边界区域没有预留空间导致这些cell被工具塞到奇怪的位置电源连接混乱后端的每一步都会变得极其痛苦。6.4 小芯片与模块级实现的差异提醒最后想提醒一点这套流程和方法针对的是模块级或中型规模芯片。如果你的项目是小芯片可能不需要这么复杂的powerplan如果是一个超大规模SoC模块级和顶层的floorplan策略又会不同。小芯片上total cell count可能在几十万门级电流也小得多一般一个简单的ring加几条strap就够用了。你在macro摆放上的自由度也更大因为芯片小所有路径的长度都在可控范围内。这时候还套用复杂模块的密集mesh方案反而会造成金属层的浪费和DRC负担。对于超大规模SoCfloorplan的核心就不再是单个模块内部的macro摆放了而是多个子模块之间的边界划分、电源域在顶层的分布、以及多个clock domain的物理隔离。这时候模块级的floorplan更多是服从顶层规划macro摆放的自由度反而更小。不过我在模块级练出来的那套“数据流驱动macro摆放”和“先全局后局部”的方法论放到顶层规划中依然适用。无论芯片规模怎么变底层逻辑是不变的所有的物理设计决策最终都是为了在合理的成本下让信号按时到达、让电源按需供应。
返回列表