asic设计流程
本文为《高级asic芯片综合》的阅读笔记
整体流程

主要流程为:
- RTL实现
- 动态仿真
- 约束、综合和扫描插入: 提供单元库和时序约束生成门级网表的过程。此外结合DFT还可以插入BIST、JTAG等测试部件
- 形式验证: 验证RTL与门级网表的等价性。
- 静态时序分析: 使用PrimeTime进行静态时序分析
- 布局、布线和验证: 通过布图规划(floorplan)根据时序约束放置单元,然后插入时钟树。这一阶段将反复迭代直至满足时序需求,并且在下单(tape-out)前还需要进行LVS(版图对原理图)和DRC(设计规则检查)
- 工程改变命令(ECO): 这是正常设计流程中的意外,当布局布线完成之后,如果此时测试发现错误,可以只将受影响的部分修改,它需要修改金属层的布线,因此这一过程称为金属掩模改变。
tcl基础
置换与赋值
赋值与输出命令: set、puts
置换:分为变量置换、命令置换、反斜杠置换
1 | |
在双引号与花括号中特殊字符不做处理
1 | |
数组
使用 花括号可以得到一个数组。此外还有一些内置函数处理数组
| 命令 | 功能 |
|---|---|
| concat | 合并数组 |
| lindex | 选取数组中的某一个元素 |
| llength | 数组长度 |
| lappend | 在尾端添加元素 |
| lsort | 排序 |
1 | |
控制流
分支
1 | |
循环
1 | |
函数
1 | |
synopsys tcl常用语句
获得实例
1 | |

属性获取
1 | |
综合
综合即将RTL代码转化为门级网表的过程,它包含转换(translate)、优化(optimization)、映射(mapping)三个过程。其中转换为RTL转换为GTECH网表,映射将GTECTH网表转换为门级网表。
综合通常使用Design Compiler或Physical Compiler,PhyC除了包含DC的所有功能外,还提供了根据设计的时序和面积约束优化放置单元的能力。
库
当运行DC时,首先将执行.synopsys_dc.setup文件。这个文件中通常包含以下命令
1 | |
- search_path: 库文件及include文件的搜索路径
- target_library: 工艺库,映射时所需的库
- link_library: 链接库,包含工艺库及一些其他的宏单元(RAM、ROM等)
- physical_library: 物理库,后端使用
- symbol_library: 符号库,单元的图形化显示,在图形化界面中使用
库的结构
库分为逻辑库和物理库,逻辑库中包含引脚到引脚的时序、面积、引脚类型和功耗等信息。逻辑库是一个文本文件(.lib),通过Library Compiler编译后生成”.db”文件供DC使用。
逻辑库包含如下信息:
- 库类
- 库级属性
- 环境描述
- 单元描述
库类
库类指定库名,里面包含库的描述
1 | |
库级属性
库级属性包含了库的特征信息
1 | |
环境描述
对温度、电压、工艺的偏差建模。还包括用于估算连线延迟的线载模型。
1 | |
tree_type定义了环境互联模型,DC在计算互联延迟时会使用合适的公式。worst_case_tree是负载引脚在距离驱动最远的连线端的极端情况进行建模。这种情况下负载引脚承受整个连线的电容和电阻。base_case_tree中负载引脚只承受连线电容而没有电阻。电阻会减慢速度。
单元描述
单元包括功能、面积、端口、时序等信息。
1 | |
被驱动单元的每个输入引脚的所有fanout_load值的总和不能超出驱动器引脚输出的max_fanout。例如一个BUFFD0(max_fanout=4)最多驱动两个同类单元(fanout_load=2)
max_transition通常用于输入引脚。他指定任何转换时间大于max_transition的连线不能连接到该引脚。max_capacitance通常用于输出引脚。他指定任何总电容大于max_capacitance的连线不能连接该引脚。
延时计算
Synopsys支持一些延迟模型,包括CMOS通用延迟模型,CMOS分段线性延迟模型和CMOS非线性查表模型(NLDM)。前两种不能有效表示VDSM几何尺寸引起的真实延迟,目前通常使用NLDM模型。
NLDM模型使用转换时间和输出负载电容来决定一个单元的延时。
进行延时计算需要用到输入转换时间和输出电容负载。输入转换时间要以前一单元转换延迟为基础,并且需要用最坏转换时间进行估算。
一般在最大延迟环境检查建立时间,在最小延迟环境检查保持时间
如图所示U2的输入转换时间将使用reset的转换时间(2ns)。如果不想用reset的转换时间,可以使用set_disable_timing U1 -from A -to Z排除。
输入
可以使用两类命令读取RTL文件
- read
- analyze/elaborate
Synopsys最初使用read命令,他无法传递参数也无法保存中间结果。analyze将分析文件并将中间结果存储于work目录下。elaborate利用中间文件生成对应的模块。
如果想要在综合时屏蔽某些代码,可以使用//synopsys translate_off关闭转换,然后再使用//synopsys translate_on开启。
约束
通过对面积、时序等信息进行约束,DC可以利用这些信息进行优化使其符合设计规范。
- set_min_library: 用于指定最坏和最佳情况的库
- set_operating_conditions: 描述设计的PVT,通常使用WORST,TYPICAL,BEST描述。例如
set_opearting_conditions -min BEST -max WORST - set_wire_load_model: 设置线载模型,在工艺库中通常有许多线载模型,例如
set_wire_load_model -name MEDIUM - set_drive: 指定输入端口的驱动强度。例如
set_drive 0 {CLK RST} - set_load: 设置电容负载。
set_load 1.5 [all_outputs]。
时序相关命令:
- create_clock: 定义时钟.
create_clock -period 40 -waveform [list 0 20] CLK - create_generated_clcok: 分频时钟.
create_generated_clock -name CLK_DIV2 -source CLK -divide_by 2 - set_dont_touch_network: 用于时钟网络或复位,在进行优化时,不会对原有器件替换
- set_ideal_network: 0转换时间,0延时,所有cell和net都有dont_touch属性
- set_input_delay: 指定输入信号的延时,例如一个30ns周期的时钟,使用
set_input_delay -max 23 -min 2 -clock CLK {datain}。那么在[2,23]内数据是不稳定的。因此保持时间最多为2,建立时间最多为7 - set_output_delay: 输出端口定义在时钟边沿到来之前数据有效所需时间。
set_output_delay -max 19.0 -clock CLK {dataout}.
- set_clock_latency: 时钟网络插入延迟.
set_clock latency 3.0 [get_clocks CLK] - set_clock_uncertainty: 时钟抖动偏移等信息.
set_clock_uncertainty -setup 0.5 -hold 0.25 [get_clocks CLK] - set_false_path: 忽略某一路径的时序。例如一些异步路径
- set_multicycle_path: 设定多周期路径
- group_path: 用于将时序关键路径绑定到一起计算,使得该组合路径优先于其他路径。
优化
优化的目标是使得面积最小并最大化速度,默认的优化优先级为时序>面积。
编译命令:
1 | |
map_effort表示在构建和映射上所消耗的时间。默认为medium, 如果约束无法满足可以调为high。scan表示添加可测性测试。gate_clock表示添加门控时钟
展平和构造
展平可以减少组合逻辑的层次,主要用于优化算数电路,并不是减少模块层次的含义。
这一选项默认未开启,可以使用set_flatten true开启展平,这种方式会增加面积。
构造是根据指定的规则优化,他通过分解中间变量使得逻辑共享,从而减少面积。例如
1 | |
然而通过构造会使得扇出增加,并可能增加线延迟,从而影响时序。构造分为两种: 时序(默认开启)和布尔优化,布尔优化可以有效减小面积,但会对时序造成更大影响。布尔优化适用于非关键时序,开启命令为set_structure -boolean true
消除层次
在默认情况下,DC综合时保持原有层次,也就是有许多模块。层次实际上是一个逻辑边界,它防止DC跨边界优化。因此可以将所有模块进行合并,从而使得DC可以更好的进行优化。优化命令为ungroup -flatten -all。
在消除层次之后,变量名称发生改变,这会给时序检查带来麻烦。
命名优化
为了在布图时进行时钟树综合,必须唯一化DC中的网表。因此需要对设计中多次例化的子模块生成唯一的模块定义。使用uniquify命令可以完成这一操作。
而verilog网表中可能存在一些特殊名称的线网。例如,DC中会产生以”*cell*“或”-return”结尾的信号名。因此需要规范化命名。
1 | |
移除未连接的端口
1 | |
特殊线网
DC为inout生成tri连线,为了避免生成tri,可以使用set verilog_no_tri true。当该设置为真时,tri被定义为wire
如果模块包含直接连接到同一模块输出端口的输入端口,穿通就会出现。或者输出端口接地,或者由常量驱动,这些都会生成assign语句。
为了避免穿通,可以使用set_fix_multiple_port_nets -feedthroughs。这将会在输入输出之间插入缓冲器
而为了处理常量驱动的端口,可以使用set_fix_multiple_port_nets -all -buffer_constants。
如果进行上述步骤之后仍会生成assign,可能是由于dont_touch导致的,可以使用remove_attribute [get_nets <net_name>] dont_touch移除dont_touch属性。
静态时序分析
SDF生成
SDF文件包含所有单元的时序信息。基本的时序数据由以下部分组成:
- IOPATH延迟: 单元延迟,依据输出连线负载和输入信号转换时间
- INTERCONNECT延迟: 驱动单元的输出到被驱动单元的输入之间的连线延迟
- SETUP时序检查
- HOLD时序检查
SDF生成命令
1 | |
Prime Time
虽然DC也可以进行静态时序分析,但是PT可以提供更多功能。它的命令和DC类型,使用transcript dc_script pt_script可以将DC的命令转换为PT的命令。
PT不能读取RTL文件,他只能读取网表文件。可以使用read_verilog命令进行读取。
时序分析命令:
- set_input_transition: 它设置不依赖于连线负载的固定转换时间。例如
set_input_transition 0.2 [all_inputs] - set_timing_derate: 用于减免时序报告中的延迟值。在生成时序报告前需要和这个数相乘。例如
set_timing_derate -min 0.2 -max 1.2 - set_propagated_clock: 设置传播时钟。在读取反标注文件之后,可以使用真实的网络延迟进行计算。
set_propagated_clock [get_clocks clk] - set_case_analysis: 用于给端口设定固定值。例如
set_case_analysis 0 scan_mode。此时与scan_mode相关的时序弧将失效。 - remove_case_analysis
- report_timing: 生成时序报告。
report_timing -from [all_inputs] -to [all_registers -data_pins] - report_constraint: 报告相关违例。例如
report_constraint -all_violators。 - report-bottleneck: 确定对设计中多个违例有贡献的叶单元。

静态时序分析中通常需要对四类路径进行分析
- 输入到触发器:
report_timing -from [all_inputs] -to [all_registers -data_pins] - 触发器到触发器:
report_timing -from [all_registers -clock_pins] -to [all_registers -data_pins] - 触发器到输出:
report_timing -from [all_register -clock_pins] -to [all_outputs] - 输入到输出:
report_timing -from [all_inputs] -to [all_outputs]