ARTICLE DETAIL

资讯详情

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

从RTL到GDSII:Synopsys数字IC实现全流程与DSO.ai实战

从RTL到GDSII:Synopsys数字IC实现全流程与DSO.ai实战 1. 从RTL到GDSII一条完整的数字IC实现链路到底长什么样数字芯片设计这个行当外人看着神秘其实拆开来看就是一条流水线前端写RTL代码描述电路逻辑后端把逻辑变成实实在在的版图最后送去晶圆厂流片。这条流水线上Synopsys的工具链几乎是绕不开的存在。你可以不用它但很难绕开它——尤其是在先进工艺节点上Design Compiler、IC Compiler II、PrimeTime、VCS、Verdi、Formality、StarRC、PrimePower、DSO.ai这一整套工具基本覆盖了从综合、布局布线、时序签核、形式验证、功耗分析到参数提取的全流程。我做了十多年数字后端从28nm一路做到5nm中间换过几家公司但工具链始终是Synopsys这套。说实话这套工具的学习曲线不算平缓尤其是当你从学校实验室那种“跑通就行”的状态切换到工业级项目“PPAPower, Performance, Area必须同时达标”的要求时会发现之前学的那点东西根本不够用。网上关于Synopsys的教程不少但大多是零散的有人讲DC综合脚本怎么写有人讲ICC2的floorplan怎么摆但很少有人把整条链路串起来讲清楚——从RTL怎么一步步变成GDSII中间每个阶段该用什么工具、关键参数怎么设、常见坑在哪里。这篇内容就是干这个的。我会以Design Compiler为起点一路讲到DSO.ai这种基于强化学习的综合优化引擎把数字IC实现工作流的核心环节拆开揉碎讲一遍。适合谁看如果你是微电子专业的学生正在做EDA课程设计或者准备蓝桥杯EDA赛道这篇能帮你建立完整的流程认知如果你刚入行做数字后端正在被各种脚本和报告折磨这篇能帮你理清思路如果你已经有一定经验但对DSO.ai这类新工具还不太熟悉也可以看看我在实际项目中的使用体会。需要提前说明的是Synopsys工具链的版本迭代很快不同版本之间的命令和选项可能有差异。我下面讲的内容主要基于近几年主流版本DC 2022.03之后、ICC2 2022.03之后、PrimeTime 2022.03之后如果你用的是更早的版本部分命令可能需要调整。另外具体工艺库的参数和约束需要根据项目实际情况来定我给出的示例脚本是通用框架不能直接照搬到你的项目里——这一点务必注意。2. 综合阶段Design Compiler到底在做什么2.1 综合的本质从行为描述到门级网表Design Compiler简称DC做的事情说白了就是把RTL代码翻译成门级网表。你写的是always (posedge clk)这样的行为级描述DC要把它变成一堆与门、或门、触发器、多路选择器的连接关系并且这些连接关系要满足你给定的时序约束和面积目标。这个过程分三步走翻译Translation、逻辑优化Logic Optimization、映射Mapping。翻译阶段DC把RTL代码转成通用的布尔逻辑表达式这时候还不涉及具体工艺库逻辑优化阶段DC会对逻辑进行化简比如消除冗余项、合并等价逻辑映射阶段DC从目标工艺库中挑选具体的标准单元来实现这些逻辑同时做时序和面积的权衡。为什么要有这三步因为如果直接从RTL映射到门级搜索空间太大工具会跑得很慢甚至跑不出来。分步走的好处是每一步的搜索空间都可控而且逻辑优化阶段可以做与工艺无关的优化映射阶段再针对具体工艺做调整。这个思路在EDA工具里很常见本质上是用分层策略来降低问题复杂度。2.2 约束脚本怎么写SDC文件的核心结构DC的约束用SDCSynopsys Design Constraints格式描述本质上是一组Tcl命令。一个典型的SDC文件包含以下几类约束# 时钟定义 create_clock -name clk -period 2.0 -waveform {0 1.0} [get_ports clk] # 时钟不确定性 set_clock_uncertainty -setup 0.15 [get_clocks clk] set_clock_uncertainty -hold 0.05 [get_clocks clk] # 输入延迟 set_input_delay -clock clk -max 0.8 [get_ports data_in*] set_input_delay -clock clk -min 0.2 [get_ports data_in*] # 输出延迟 set_output_delay -clock clk -max 0.6 [get_ports data_out*] set_output_delay -clock clk -min 0.1 [get_ports data_out*] # 驱动能力 set_driving_cell -lib_cell BUFX4 -pin Y [get_ports data_in*] # 负载 set_load 0.05 [get_ports data_out*] # 虚假路径 set_false_path -from [get_ports rst_n] # 多周期路径 set_multicycle_path -setup 2 -from [get_clocks clk_slow] -to [get_clocks clk]这里面有几个参数需要重点解释。create_clock的-period是时钟周期单位默认是纳秒2.0ns对应500MHz。-waveform {0 1.0}定义上升沿在0ns、下降沿在1.0ns占空比50%。set_clock_uncertainty的setup值一般取时钟周期的5%到10%hold值取2%到5%具体要看时钟树的抖动和偏差预算。set_input_delay和set_output_delay是最容易设错的地方。这两个值不是随便填的它们取决于芯片外部电路的时序要求。举个例子如果上游器件在时钟上升沿后0.8ns才把数据稳定送到你的输入端口那-max就要设0.8如果上游器件在时钟上升沿后0.2ns就可能撤走数据那-min就要设0.2。设错了会导致综合结果要么过于乐观时序违例被掩盖要么过于悲观面积和功耗浪费。注意SDC文件里的时钟定义必须和RTL中的时钟端口名完全一致大小写敏感。我见过不少新手因为端口名写错导致时钟没约束上DC默认按无约束路径处理结果综合出来的网表时序一塌糊涂。2.3 综合脚本的完整框架一个可复用的DC综合脚本通常包含以下步骤# 设置搜索路径和目标库 set search_path [list . ./libs ./rtl] set target_library sc9_cln55_ss_0p72v_125c.db set link_library * $target_library dw_foundation.sldb set symbol_library sc9_cln55.sdb # 读取RTL analyze -format verilog {./rtl/top.v ./rtl/sub_module.v} elaborate top -architecture verilog -library WORK # 读取约束 source ./constraints/top.sdc # 设置综合选项 set_max_area 0 set_max_leakage_power 0 set_cost_priority {max_delay max_leakage_power max_area} # 编译 compile_ultra -gate_clock -retime -no_autoungroup # 输出结果 write -format verilog -hierarchy -output ./output/top_syn.v write_sdc ./output/top_syn.sdc write_sdf ./output/top_syn.sdf report_timing -max_paths 10 -nworst 10 ./reports/timing.rpt report_area -hierarchy ./reports/area.rpt report_power ./reports/power.rptcompile_ultra是DC的高强度综合命令比普通的compile多做了时序驱动优化和门控时钟插入。-gate_clock选项让DC自动插入时钟门控单元来降低动态功耗这个在低功耗项目里几乎是必选项。-retime允许DC在触发器之间重新分配组合逻辑用来改善时序但要注意retiming会改变寄存器的数量可能影响后续的形式验证。set_cost_priority定义了优化目标的优先级。我一般把max_delay放在第一位因为时序不满足的话面积和功耗再优也没意义。但如果项目对功耗有硬性要求比如可穿戴设备芯片那就把max_leakage_power提前。2.4 综合报告的解读与常见问题综合跑完之后report_timing会给出时序报告。重点看几个指标WNSWorst Negative Slack、TNSTotal Negative Slack、违例路径数量。WNS是最大负裕量如果WNS是-0.3ns说明最差路径差0.3ns才满足时序。TNS是所有违例路径负裕量的总和反映整体时序质量。常见问题一时钟没约束上。现象是报告里显示“no clock”或者路径没有起点终点。排查方法是检查SDC里的create_clock是否作用到了正确的端口可以用get_clocks和get_ports命令确认。常见问题二组合逻辑环。DC会报“combinational loop”错误。这通常是RTL代码里存在组合逻辑反馈比如assign a b a这种。解决办法是在RTL里打断环路或者用set_disable_timing命令临时禁用某条路径。常见问题三多驱动冲突。同一个信号被多个源驱动DC会报“multiple driver”错误。这通常是RTL代码里信号名重复定义或者模块例化时端口连接错误导致的。实操心得综合阶段不要一味追求零违例。有时候WNS差一点点比如-0.05ns可以通过后续的布局布线阶段修复。但如果WNS差得太多超过时钟周期的10%那就要回到RTL或者约束层面找问题硬扛到后端只会浪费时间。3. 布局布线IC Compiler II的物理实现3.1 从网表到版图物理设计的基本流程综合出来的门级网表只是逻辑连接关系没有物理位置信息。IC Compiler II简称ICC2要做的事情就是把这些标准单元摆到芯片的版图上然后用金属线把它们连起来同时满足时序、功耗、面积和可制造性要求。ICC2的流程大致分为数据准备Data Setup、布局规划Floorplan、布局Placement、时钟树综合CTS、布线Routing、签核Signoff。每个阶段都有对应的命令和检查点。数据准备阶段需要读入网表、工艺库、约束文件还要定义芯片的物理边界、电源网络、I/O位置等。这个阶段最容易出问题的是库文件版本不匹配——比如DC用的.db库和ICC2用的.ndm库不是同一个版本会导致单元参数不一致。3.2 Floorplan芯片的“城市规划”Floorplan是物理设计里最考验经验的一步。你可以把它理解为城市规划哪里放CPU核哪里放内存控制器哪里走电源线哪里留布线通道。Floorplan做得好后续布局布线会顺很多做得不好后面怎么修都修不回来。关键参数包括core利用率Core Utilization、纵横比Aspect Ratio、宏单元摆放Macro Placement、电源规划Power Plan。Core利用率一般设在60%到75%之间太低浪费面积太高布线拥塞。纵横比是芯片高度和宽度的比值通常接近1:1但也要考虑封装和引脚排布的限制。宏单元摆放有几个原则宏单元尽量靠边放不要挡在芯片中央宏单元之间留足布线通道一般不少于10个布线轨道时钟相关的宏单元要靠近时钟源减少时钟偏差。电源规划要先做IR drop分析确保电源网格的电阻足够小一般要求静态IR drop不超过电源电压的5%。# ICC2 Floorplan示例 initialize_floorplan -boundary {{0 0} {1000 0} {1000 800} {0 800}} \ -core_offset {10 10} -core_utilization 0.7 # 摆放宏单元 place_macro -macro_name SRAM_1024x32 -location {50 50} -orientation R0 place_macro -macro_name SRAM_512x64 -location {50 300} -orientation R0 # 电源规划 create_power_straps -direction vertical -width 2 -pitch 20 -layer M5 create_power_straps -direction horizontal -width 2 -pitch 20 -layer M63.3 Placement与CTS让单元各就各位Placement阶段ICC2会根据时序和拥塞情况自动把标准单元摆到合适的位置。这个阶段的核心是时序驱动布局工具会优先把关键路径上的单元摆得近一些减少线延迟。同时还要考虑拥塞如果某个区域单元太密集布线时会绕不开。CTS时钟树综合是物理设计里最精细的一步。时钟信号要驱动芯片上成千上万个触发器如果时钟到达不同触发器的时间不一致时钟偏差Clock Skew会导致时序问题。CTS的目标就是构建一棵平衡的时钟树让时钟偏差尽可能小同时控制时钟树的功耗和面积。# CTS示例 set_clock_tree_options -target_skew 0.05 -max_transition 0.15 clock_opt -from build_clock -to build_clock clock_opt -from route_clock -to route_clock-target_skew 0.05表示目标时钟偏差不超过50ps。这个值不是越小越好太小会导致时钟树面积和功耗急剧增加。一般根据时钟频率来定1GHz以上的时钟skew控制在30ps到50ps500MHz左右的时钟skew控制在80ps到100ps就够了。3.4 Routing把线连起来Routing阶段分两步全局布线Global Routing和详细布线Detail Routing。全局布线决定每条线大致走哪个区域详细布线决定每条线具体走哪个轨道、打哪个过孔。布线阶段最常见的问题是DRC违例Design Rule Check和LVS违例Layout Versus Schematic。DRC违例包括线宽不够、间距不够、过孔覆盖不够等LVS违例包括短路、开路、器件参数不匹配等。# Routing示例 route_global route_detail route_opt # 检查DRC verify_drc -limit 1000 ./reports/drc.rpt # 检查LVS verify_lvs ./reports/lvs.rpt注意布线完成后一定要做天线效应检查。天线效应是指长金属线在等离子刻蚀过程中积累电荷可能击穿栅氧化层。ICC2可以自动插入天线二极管来修复但会占用面积所以要在Floorplan阶段预留空间。4. 签核与验证PrimeTime、Formality与VCS4.1 PrimeTime时序签核的黄金标准PrimeTime简称PT是Synopsys的时序签核工具精度比DC和ICC2内置的时序分析引擎更高。签核阶段要用PT重新跑一遍时序确认没有违例。PT的输入包括门级网表、SDC约束、寄生参数文件SPEF、工艺库。SPEF文件由StarRC从版图提取包含每条线的电阻和电容信息。PT用这些信息做寄生参数反标Parasitic Back-Annotation得到接近实际的时序结果。# PT签核示例 read_verilog ./output/top_syn.v read_sdc ./output/top_syn.sdc read_parasitics ./output/top.spef read_liberty ./libs/sc9_cln55_ss_0p72v_125c.lib # 时序分析 update_timing report_timing -max_paths 20 -nworst 20 -delay max ./reports/pt_setup.rpt report_timing -max_paths 20 -nworst 20 -delay min ./reports/pt_hold.rpt # 功耗分析 report_power ./reports/pt_power.rptPT报告里要重点看Setup违例和Hold违例。Setup违例是数据到达太晚Hold违例是数据到达太早。Setup违例可以通过降低时钟频率、优化逻辑、调整布局来修复Hold违例通常通过插入延迟单元来修复。4.2 Formality形式验证确保网表功能一致综合和布局布线过程中工具会对逻辑做优化可能改变网表的结构。Formality简称FM用来验证优化后的网表功能和原始RTL是否一致。FM的流程是读入参考设计RTL和实现设计门级网表设置约束然后跑等价性检查。如果FM报“Pass”说明功能一致如果报“Fail”说明有逻辑错误需要排查。# Formality示例 read_verilog -container r -libname WORK ./rtl/top.v read_verilog -container i -libname WORK ./output/top_syn.v set_top top set_reference_design top set_implementation_design top match verifyFM报Fail的常见原因时钟门控插入导致寄存器数量变化、Retiming导致寄存器位置变化、约束不一致导致某些路径被优化掉。解决办法是在FM里设置对应的set_constant、set_dont_verify等命令告诉工具哪些差异是预期的。4.3 VCS仿真验证功能正确性VCS是Synopsys的仿真器用来验证RTL和门级网表的功能。前端工程师用VCS跑RTL仿真后端工程师用VCS跑门级仿真带SDF反标来确认时序修复没有引入功能错误。# VCS编译 vcs -full64 -sverilog -debug_accessall \ -f filelist.f \ -timescale1ns/1ps \ -o simv # 运行仿真 ./simv ntb_random_seed1 dumpwave门级仿真比RTL仿真慢很多因为要模拟每个标准单元的延迟。所以门级仿真通常只跑关键场景不会跑全量回归。跑门级仿真时要注意SDF文件的corner选择Setup检查用ss cornerHold检查用ff corner。实操心得VCS仿真时如果遇到“X”态传播先检查复位信号是否正常。很多X态问题都是因为复位没做好导致触发器初始状态不确定。另外门级仿真时如果SDF反标后出现时序违例仿真器会报“timing violation”但这不一定代表芯片会出错——要结合实际情况判断。5. DSO.ai当综合优化遇上强化学习5.1 DSO.ai解决了什么问题传统综合流程里工程师要手动调整几十个参数编译选项、约束优先级、优化策略、门控时钟阈值……每个参数组合跑一遍综合可能要几个小时工程师只能凭经验试几组很难找到全局最优解。DSO.aiDesign Space Optimization AI用强化学习来自动搜索这个参数空间目标是在给定约束下找到PPA最优的方案。DSO.ai的工作方式是你给它一个设计、一组约束、一个目标比如“在满足时序的前提下最小化面积”它会在后台启动多个综合任务每个任务用不同的参数组合然后根据结果反馈调整搜索策略。跑了几十轮之后它会给出一组推荐参数通常比人工调优的结果好5%到15%。5.2 DSO.ai的实操流程DSO.ai的使用分几个步骤准备设计环境、定义搜索空间、启动优化、分析结果。# DSO.ai启动示例 dsoai_start -design top -technology sc9_cln55 -flow dc # 定义搜索空间 dsoai_set_search_space -param compile_ultra_options \ -values {-gate_clock -retime -no_autoungroup} \ -values {-gate_clock -retime} \ -values {-gate_clock} dsoai_set_search_space -param max_area \ -range {0 1000} # 定义目标 dsoai_set_objective -metric timing_wns -weight 0.6 dsoai_set_objective -metric area_total -weight 0.3 dsoai_set_objective -metric power_total -weight 0.1 # 启动优化 dsoai_run -max_iterations 50 -parallel_jobs 8 # 查看结果 dsoai_report -best_designs 5-max_iterations 50表示最多跑50轮-parallel_jobs 8表示同时跑8个任务。并行数取决于你的服务器核数和License数量。一般来说8到16个并行任务比较合适太少收敛慢太多License不够用。5.3 DSO.ai的实际效果与局限我在一个55nm的MCU项目上用过DSO.ai目标是“时序优先面积次之”。跑了30轮之后DSO.ai推荐的参数组合比人工调优的结果WNS改善了0.12ns面积减少了8%功耗降低了5%。这个提升在成熟工艺上已经相当可观了。但DSO.ai不是万能的。它的搜索空间是你定义的如果你没把关键参数放进去它也找不到。另外DSO.ai需要大量的计算资源每个综合任务都要跑几十分钟到几个小时50轮下来可能要几天时间。所以它更适合在项目前期做探索不适合在项目后期赶进度时用。注意DSO.ai的License和普通DC License是分开的用之前确认公司有没有买。另外DSO.ai跑出来的结果还是要人工review不能直接拿去流片——它只是帮你缩小搜索范围最终决策还是靠工程师。6. 常见问题与排查技巧实录6.1 工具安装与环境配置问题Synopsys工具在Linux下安装时最常见的问题是Tcl/Tk版本不兼容。DC和ICC2依赖特定版本的Tcl/Tk如果系统自带的版本太新或太旧工具启动时会报错。解决办法是安装工具自带的Tcl/Tk或者用LD_LIBRARY_PATH指定库路径。另一个常见问题是License配置。Synopsys用FlexLM管理License需要设置SNPSLMD_LICENSE_FILE环境变量指向License服务器。如果License报错先检查网络是否通、端口是否开放、License是否过期。# 检查License状态 lmstat -a -c 27000license_server # 设置环境变量 export SNPSLMD_LICENSE_FILE27000license_server export PATH$PATH:/tools/synopsys/dc/bin export LM_LICENSE_FILE$SNPSLMD_LICENSE_FILE6.2 综合与布局布线的典型报错报错信息可能原因解决办法Cant find design xxx网表或库文件路径不对检查search_path和link_libraryTiming violation on clock gating check门控时钟单元时序不满足调整门控时钟单元的驱动能力或插入缓冲Congestion overflow布局太密布线资源不够降低core利用率调整宏单元位置Hold violation after CTS时钟偏差导致保持时间不够插入延迟单元调整CTS参数Antenna violation长金属线电荷积累插入天线二极管或调整布线层6.3 独家避坑技巧技巧一综合前先跑一遍check_design。这个命令能检查RTL里的常见问题比如未连接端口、多驱动、组合逻辑环等。提前发现比综合跑了一半再报错要省时间。技巧二ICC2的Floorplan不要一次做到位。先做一个粗略的Floorplan跑一遍Placement看拥塞情况再根据结果调整。一上来就精雕细琢后面发现方向错了要全部重来。技巧三PT签核时用set_propagated_clock。默认PT用理想时钟做分析和实际时钟树有差异。签核阶段要切换到传播时钟模式结果才准确。技巧四DSO.ai的搜索空间不要设太大。参数太多会导致搜索空间爆炸收敛慢。一般选3到5个关键参数就够了比如编译选项、优化目标权重、门控时钟阈值。技巧五门级仿真前先跑一遍zero_delay仿真。不带SDF反标跑一遍确认功能正确再带SDF跑时序仿真。这样能把功能错误和时序错误分开排查。7. 写在最后一些个人体会这套工作流我用了很多年从最初的手忙脚乱到现在的驾轻就熟中间踩过的坑不计其数。有几点体会比较深第一约束比代码重要。很多时序问题不是RTL写得不好而是约束设得不对。花时间把SDC写清楚比反复改RTL要有效得多。第二工具是死的人是活的。DC、ICC2、PT这些工具都有自动优化功能但自动优化的结果不一定是最优的。工程师的价值在于判断什么时候该信工具什么时候该手动干预。第三DSO.ai这类AI工具是辅助不是替代。它能帮你探索参数空间但最终的决策还是要靠工程师对设计的理解。不要指望扔给AI就能万事大吉。第四文档和脚本要版本管理。每个项目的约束、脚本、报告都要存档下次做类似项目时可以复用。我见过太多人每次做新项目都从头写脚本效率极低。最后分享一个小技巧如果你在跑综合或布局布线时遇到莫名其妙的报错先检查磁盘空间。Synopsys工具会产生大量临时文件和日志磁盘满了会导致各种奇怪的错误。这个坑我踩过不止一次每次都是排查半天才发现是磁盘满了。
返回列表