继《IC设计中的DC综合学习记录——模板记录》之后,记录一下自己在综合过程中遇到的疑惑、问题及相应的解决方法。如有不正确或者更好的解决方法,欢迎广大网友批评指正、不吝赐教。
1 关于input/output port的部分问题与解
1.1复位信号的处理
由port复位信号在代码内部生成的复位信号作为工程中使用的复位信号,此时只需对Port的复位信号进行input_delay约束,内部生成的复位信号的约束由工具自动计算处理。
1.2 同一个信号在多个时钟域下
同一个输入信号被用在两个时钟域下,它的input_delay需要在两个时钟域下进行设置,在第二个时钟域下设置input_delay时需要用到-add_delay选项进行设置。
1.3输入信号from和to的时钟域不同
一个来自于时钟域clka的信号输入到需要综合的模块中并在clkb时钟域下工作,input_delay的参考时钟选择clkb。定义input_delay是为了保证在该综合模块中信号能正确被处理应用,因此只需要知道信号从上一级到该模块port的延时,从而知道该信号的留给该综合模块的时间裕量,该模块的时间裕量是相对于clkb的,所以参考时钟因该为该模块的clkb。
1.4 确认输入输出信号综合时的参考时钟域
确认输入输出信号的input_delay和output_delay的参考时钟。比如一个需要综合的模块存在多个时钟域,则需要确定除时钟信号外的其他输入输出信号的input_delay和output_delay的参考时钟。原因如下:
1.4.1关于input_delay
Input_delay定义为从前一个模块中最后一级寄存器输出端口到该综合模块输入端口的延时加上前一个模块中最后一级寄存器时钟端到Q端的延时。示意图可以参考链接(输入延时(Input Delay)与输出延时(Output Delay)_耐心的小黑的博客-CSDN博客_输入延时)中“输入延时的定义”中的示意图。
在这里,前一个模块的输出时钟和该综合模块的输入时钟为同一个时钟,因此可以在综合模块的约束设置中对input_delay的clk直接采用该综合模块相应的输入时钟作为参考时钟,延时也可用输入时钟周期的百分比表示。
但是如果前一个模块的输出数据的依赖时钟和该综合模块的输入时钟不是同一个时钟,在下一级的时序约束中,set_input_delay的参考时钟应该怎样设置?(参考时钟为在该综合模块中与输入数据相关的时钟,其延时可以不用采用输入时钟周期百分比的方式,可以直接采用延时数据。采用该级输入时钟作为参考时钟的原因是该级对输入数据的处理是按照该级的输入时钟来处理的,只有针对该时钟设置input_delay才有意义)
如果该综合模块的输入信号输入到该综合模块后先经过组合逻辑后再达到时序逻辑,则应追溯输入信号到达的时序逻辑的第一级时钟域,并以此时钟作为Input_delay的参考时钟。
如果该综合模块的输入信号到达的的第一级时钟域中有多个时钟,则input_delay的参考时钟需要设置多个,比如:
当一个需要被综合的模块中存在多个输入时钟域,每一个输入信号的input_delay参考时钟为该输入信号输入的第一级寄存器中的时钟信号,在第一级寄存器前即使有组合逻辑,也需要参考第一级寄存器的时钟。
如果一个输入信号的input_delay参考时钟为mux后的输出时钟,则将input_delay的参考时钟设置为Mux之前的时钟,用-add_delay选项设置多个参考时钟。
1.4.2 关于output_delay
output_delay的定义是指数据从该综合模块的输出端口到下一个模块的第一个寄存器的时钟端的延时,示意图可参考链接(输入延时(Input Delay)与输出延时(Output Delay)_耐心的小黑的博客-CSDN博客_输入延时)中的“output_delay”。参考时钟为该综合模块相应的时钟即可,如input_delay一样设置参考时钟。
如果在当前模块的输出信号先经过组合逻辑后再达到模块的输出端口或者pin,则应追溯输出信号最后一级时序逻辑的时钟域,并以此时钟作为output_delay的参考时钟。
如果该综合模块的输出信号来自于两个或者多个时钟域输出信号mux输出,则output_delay的参考时钟域应设置成两个或者多个,举例如下所示:
如果输出信号为多个时钟域信号的组合逻辑输出,Output_delay的参考时钟也应相应的设置为多个时钟。
如果输出为常数,则不用对常数输出进行设置。
如果综合模块的输出信号中有时钟信号,则不用对输出的时钟信号进行约束,直接设置为如下图所示:
编辑
如果综合模块有多个时钟域,对于复位信号,如果直接使用复位信号,则看复位信号与多少个时钟域相关,即看always敏感列表中与哪些时钟信号相关,所有的相关时钟都需要作为复位信号的input_delay的参考时钟;如果复位信号输入综合模块有经过特殊处理,则需要看处理部分的时钟,该时钟需要作为复位信号的input_delay的参考时钟。
关于input_delay和output_delay的参考链接还有一个:【 FPGA 】设置输入延迟(input delay)_李锐博恩的博客-CSDN博客_set_input_delay
1.5 不用对输入时钟设置input_delay
不需要对输入时钟设置input_delay,原因是时钟信号作为标准的处理信号,一切寄存器的打拍变化都是基于输入时钟的沿的,即使时钟存在延时也会将所有时钟上的延时做标准化归0化看待。
2 关于时钟clk的部分问题与解
2.1 clk不能穿透的模块定义时钟
2.1.1 时钟无毛刺切换模块
在时钟生成模块中存在一个clk_switch的子模块,clk_switch的结构如下图所示:
编辑
该clk_switch_u模块含有剔除切换时产生毛刺的功能,不能被时钟信号穿透的,因此需要对该子模块的时钟信号进行约束设置。具体做法有:在compile时需要加上-no_autoungroup选项使clk_switch_u在综合时不被打平,在设置约束时可以直接使用clk_switch_u的pin,约束设置如下:
create_generated_clock -name clk_out -source [get_pins clk_in1] [get_pins clk_switch_u/clk_out] -master clk_a]
create_generated_clock -name clk_out -source [get_pins clk_in2] [get_pins clk_switch_u/clk_out] -master clk_b -add
关于无毛刺时钟切换电路的讲解可参考如下网址,当然还有其他网址可供参考:
时钟切换电路(Glitch-free clock switching circuit)_glitch-circuit-CSDN博客
时钟切换处理(Verilog)_时钟切换电路 verilog-CSDN博客
2.1.2 reg输出Q端作为时钟生成点
在时钟分频电路中存在将寄存器的Q端输出作为时钟信号给到其他模块,此时对时钟的约束应该定义到寄存器的输出端口。
create_generated_clock -name clk_div2 -source [get_ports clk] [get_pins clk_div2_u/div2_reg_Q]
-master clk -add
2.2 check_timing的unconstrained end-points for maximum delay 的 warning
在DC的check_timing中能看到unconstrained end-points for maximum delay 的 warning,如下图所示。
A:出现这样的warning首先考虑的是与这些unconstrained end-points相关的时钟是否有被定义好。在DC_shell中使用report_clock或者report_clocks命令查看相关的是否被定义,如果没有被定义,则定义好;
B:如果相关时钟已经存在,则查看定义的时钟依托点是否正确合理;
C:查看unconstrained end-points与某个IP或者模块相关,该模块或者IP的端口信号中无时钟信号,如OTP ROM的端口信号,OTP ROM的读写时序完全靠设计者设计控制好。
2.3 时钟依托点的理解
时钟依托点的正确合理解释如下:在时钟生成模块中可能存在某一个生成时钟(比如上图中的clk_div2)直接连接到了模块pin上,但在模块内部有使用。而使用create_generated_clock时将生成时钟定义在了模块的pin上,这样在时钟生成模块后是存在时钟约束的,而在时钟生成模块内部使用到该生成时钟的寄存器就会出现没有时钟约束的情况。因此正确合理的时钟依托点应该是在时钟的真正生成点,这样才能完整约束上使用该生成时钟的寄存器。
2.4 某模块或者IP的端口信号中无时钟信号而产生了无约束的end-points(如otp mem和otp_ctrl模块之间的信号约束)
某模块或者IP的端口信号中无时钟信号而产生了无约束的end-points:这种情况下由于设计者在设计时已经完全考虑可能的端口时序,因此只要保证端口信号线的走线长度在一定范围内等长,即满足模块或者IP的时序要求就行。因此可以通过set_max_delay,set_min_delay或者set_input_delay,set_output_delay命令来设置端口走线等长(同等延时)的要求。如果这方法不可行,可以给PR特殊spec文件,满足那一组走线在一定范围内等长的要求。举例:比如对OTP ROM的控制信号有XCE、XREAD、XA、XDIN等信号线,均来自OTP_CTRL模块,信号的名称均为在OTP ROM和OTP_CTRL模块的端口名,则走线的设置的两个端点分别为OTP_ROM和OTP_CTRL模块的pins。
建议设计和综合时把otp mem单独分出来,原因如上。
2.5 时钟asynchoronous、logically_exclusive、phsycially_exclusive的设置
如果存在多个时钟信号,需要分清楚时钟之间的关系,是否为异步时钟,是否存在时钟的选择。如果存在异步时钟则需要设置asynchronous,如下
set_clock_groups -name asyn_clk1_clk2 -asynchronous \
-group {clk1} \
-group {clk2 clk_div2}
如果存在时钟信号选择的情况,则要弄清楚logically_exclusive和phsycially_exclusive的约束区别,可以通过man set_clock_groups来查找他们的用法和区别。
2.6 虚拟时钟设置
虚拟时钟主要用于作为电路中输入到输出的组合逻辑电路的时钟基准。定义虚拟时钟时不指定是中原(source或port),但必须指定时钟名,在实际的电路中没有对应的clock port or clock net。
create_clock -name clk_name -period cycle_value -waveform edge_list
2.7 set_clock_uncertainty
定义好clock之后,还需要指定实际时钟网络的clock_skew,用于模拟实际的时钟,需使用set_clock_uncertainty来指定始终网络的skew。
为了模拟实际时钟,还有其它设置命令;
set_clock_transition
set_clock_latency
set_clock_groups
set_max_transition
2.8 set_dont_touch_network
在综合时不需要考虑某些网络上的大负载,比如clock、reset、enable信号,因为前端工具不知道到实际连线的走线和长度,无法准确估计网络负载,且floorplan会影响实际的负载,因此在综合时不对网络负载做优化,需使用set_dont_touch_network。
set_dont_touch_network clk_name
注:set_dont_touch_network与set_dont_touch的区别,前者用于大负载网络,后者用于具体的cell\instance,在综合时忽略具体的cell或instance的约束条件,不做优化处理。
3 其他问题与解
3.1 compile_ultra命令
在compile_ultra命令中需要加上-no_atuoungroup选项,这样可以避免在综合过程中把层次结构打平,这样不仅能使约束时更好的找到相应层级结构上的Pin进行设置,也有助于布局布线阶段中对各个module的处理。
3.2同一个工程中涉及到多个operating_conditions
同一个工程中会使用到IO_pad和memory,以及大量的std cell,他们的operating_conditions不相同,如IO的工作电压高于std cell,memory的温度可能比std cell的高。而operating_condition会影响时序,因此要统一operating_condition。Std cell、memory、pad各个lib不一样,一般只需设置std cell的operating_condition就可以了,其他的在会在map时选取与std cell的operating_condition相近的operating_condition。不是所有lib里都能找到operating_condition。如果map的不对,就需要写具体的-library,-object_list来指明。
(这一点还需要实践)
参考网址有:关于operating condition的问题 - 后端讨论区 - EETOP 创芯网论坛 (原名:电子顶级开发网) -
3.3 DC中对DFT部分的处理
如果设计中存在DFT部分,常遇到的就scan chain的插入。在scan chain中主要是三种信号scan_in,scan_en,scan_out信号(有的可能是test_in,test_en,test_out信号名),在综合时用set_case_analysis只需设置scan_in和scan_en信号都为0。具体设置举例(针对scan信号在顶层port上的情况)如下:
set_case_analysis 0 [get_port scan_en]
set_case_analysis 0 [get_port scan_in]
对scan_mode的设置有的RTL设计是放在顶层的port上,但有的特殊设计是通过配置寄存器来设置scan_mode的。通过寄存器配置scan_mode则需要在综合中对scan_mode这条net设置为0。
在综合时是将RTL代码转成对应的逻辑门电路,对这三个信号是否处理、是在约束文件中处理还是在compile之后处理都不应该影响综合出来的电路,但目前在通过配置寄存器来控制scan_mode的情况下遇到了compile之前处理和在compile之后的处理的结果不一样。遇到的问题是在compile之前处理的情况下,在综合出来的网表中找不到与scan_mode这条net相连接的其它pin(寄存器配置的scan_mode的情况下,该寄存器的输出除控制scan_mode外还有着其它作用)。将该处的scan_mode的设置放在compile之后就正确了,也说明了在综合出来的网表中需要检查相应的设置是否正确。
附:关于DFT中scan chain的相应介绍的网址有
[DFT]Scan mode & ATPG_gsithxy的博客-CSDN博客
3.4 读取rtl.v文件使用到的一个命令——analyze
如果在RTL设计文件中存在用`ifdef/`ifndef和`endif定义的代码,在综合读取解析文件时需要告诉工具需要综合的代码是哪一部份,analyze的选项-define就具有该功能。analyze的语法如下,具体的使用可以在dc_shell中用man analyze查找。
analyze
[-format verilog | sverilog | vhdl]
[-define define_list]
[-library library_name | -work library_name]
[-uses design_libs_list]
[-vcs vcs_opts]
[-create_update]
[-recursive]
[-autoread]
[-rebuild]
[-output_script output_string]
[-exclude exclude_list]
[-verbose]
[-top top_design_name]
file_list
3.5 给特定的module指定特定的库
在综合时有时会需要给特定的module指定综合库,在综合中的命令为set_target_library_subset,使用的语法格式如下所示,具体的用法在dc_shell中用man set_target_library_subset查找。
set_target_library_subset
[-top | -object_list cells]
[-don't_use lib cells]
[-use lib_cells]
[-clock_path]
[-only_here lib_cells]
[-milkyway_reflibs milkyway_reflib_paths]
[library_file_name_list]
3.6 reset的时序check
在进行check时,当reset释放时也需要进行检查,原因是在某些standard cell由几个触发门组成,而触发门之间还存在组合逻辑,且reset会参与其间的组合逻辑,这样有可能在reset释放时出现时序不满足的情况。具体standard cell的组成可以参看standard cell的databook。
3.7 compile-once-dont-touch方法
如果几个模块的引用工作环境比较相似,可以将模块在周围环境最差的情况下综合后,使用set_dont_touch让DC在以后的优化时保留该子模块。举例如下(D0和D1都是D模块的具体例化):
current_design TOP
characterize U4
current_design D
compile
current_design TOP
set_dont_touch {U4 U3}
compile
这个方法的优点:运行时间短,所需存储空间小;缺点:不能针对各个子模块的具体环境优化。
常适用的场景:处理violation很大的子模块。在综合过程中发现路径延时都在某一个模块内,可以对该模块进行单独处理,以减少路径在该模块之内的延时。
4 链接推荐
超级推荐看的一个链接:
数字后端 FAQ (2/11更新到时序收敛) - 后端讨论区 - EETOP 创芯网论坛 (原名:电子顶级开发网) -
后续还会继续补充……