http://bb2hh.blogbus.com/logs/20818986.html
在阅读本篇之前,请先阅读http://bb2hh.blogbus.com/logs/20563101.html,了解一下fanout的影响。
dc在综合高扇出的网络的时候,约束优先级是:
1.功能正确
2.DRC(max_transition ,max_fanout,max_capacitance )
3.Setup time (max_delay)
4.Hold time (min_delay)
5. Other...
为了符合drc要求,dc通常花费很多时间来编译和修正这些DRC violators。
路径上的cell延迟由input_transition 和output_load(包括扇出pin上的load)决定,这个由查抄表可以得到。
而net延迟是由net上的R,C决定的。在没有布局布线之前,我们不知道实际的R,C是多少,dc根据互联线模型(set_wire_load_model)来计算出R,C。然后根据得到的R,C计算出net上的延迟:
Net_delay=R*C*OC
其中系数OC是根据操作环境(set_opearting_conditions)中设置的rc树模型得到。
一般的工艺库的操作环境有三种,WORST,TYPICAL,BEST,分别是最差,典型,最坏。
在ic中出现high fanout的情况基本有三种:
1.时钟clock
2.复位reset
3.一般信号
<!--[if !supportLineBreakNewLine]-->
<!--[endif]-->
dc中对于高扇出net的处理,基本就是加buffer(前提,如果没有对这条net设置一些约束,比如set_ideal_network,set_dont_touch,后面会讲到),以此来减少cell输出端的负载,从而减少transition time 和delay time,以及max_capacitance。而事实上我们是不希望dc这么处理的,我们希望的是可以在后端版图的时候让后端工具自己加buffer,因为我们不知道真实的high fanout net上的RC,所以不知道应该加怎么样的buffer,dc只是根据互联线模型来计算RC,接着加入buffer,不是真实的,只有布线以后我们才可以得到几乎真实的rc。
所以在dc综合过程中我们要阻止dc最high fanout net进行insert buffer处理。因此这些没被处理的高扇出net就会引起一些drc或者timing错误,在dc中,dc用价值函数(cost function)来判断这些约束对设计的影响。价值函数=DRC violator和+ timing violator 和。一般的,dc会根据所有drc和timing错误,通过使价值函数趋近等于0来修正这些违规。为了达到效果,dc会每次修正一个路径,然后重新计算价值函数,如果价值函数变小,说明设计被改进了。
在介绍如何处理 high fanout net之前,先介绍3个命令。
Set_ideal_net (已经被set_ideal_network -no_propagate代替) 忽略port,pin,net上的时序优化(timing optimization),以及drc修正(drc fixxing)。network具有传输型。
Set_dont_touch (已经被set_dont_touch_network -no_propagate代替)忽略,port,cell,design,pin上的优化(timing optimization),但是不会忽略DRC。network具有传输型
这样我们在综合的时候就要对high fanout net做一定的约束,让dc不对这些net做优化以及加入buffer。下面分三种情况来说明。
1.Clock,对于clock,当我们用create_clock,or creat_generated_clock创建clock的时候,这些clock已经有了ideal_network的属性。Dc已经不会在clock tree上加入buffer,同时也不会计算drc violation,但是delay timing 仍然会被计算。不计算drc不是说没有负载。
2.Reset,对于复位高扇出信号,因为没有那些属性,所以要手动设置,set_ideal_network
3.一般信号。同样需要手动set_ideal_network
下面看例子:
下面看一个高扇出实例,有时钟,有复位还有一般信号
module test(clk,clk_G, d_in ,s_r1, s_r2, rst_N1, rst_N2,dout);
parameter size =1100;
input d_in, rst_N1,rst_N2, s_r1, s_r2,clk_G,clk;
output dout;
reg dout;
reg [size-1:1] tmp;
wire G_clk, rst_N, s_r;
integer i;
assign G_clk = clk & clk_G;
assign rst_N = rst_N1 & rst_N2;
assign s_r = s_r1 & s_r2;
always@(posedge G_clk or negedge rst_N) begin
if(!rst_N) begin
dout <= 0;
tmp <= 0;
end
else begin
dout <= tmp[size-1] | s_r;
for(i=size-1 ; i>1; i="i-1")
tmp <= tmp[i-1] | s_r;
tmp[1] <= d_in | s_r;
end
end
endmodule
综合脚本:
set lib $env(DC_LIB)
set target_library "slow.db fast.db"
set link_library "* $target_library"
set search_path ". ../src ../scripts $lib"
set hdlin_while_loop_iterations 5000
analyze -format verilog test.v
elaborate test
uniquify
link
check_design
create_clock -period 100 [get_ports clk]
set_operating_conditions -max slow -min fast
set_wire_load_mode top
set_min_library slow.db -min_version fast.db
set input_exp_clk [remove_from_collection [all_inputs] [get_ports clk]]
set_input_delay 60 -clock [get_clocks clk] $input_exp_clk
set_output_delay 30 -clock [get_clocks clk] [all_outputs ]
compile
电路图:
下面是生成的网表的关键几个地方。
AND2X4 U1106 ( .A(clk_G), .B(clk), .Y(G_clk) );
AND2X2 U1340 ( .A(s_r2), .B(s_r1), .Y(n2) );
AND2X2 U2441 ( .A(rst_N2), .B(rst_N1), .Y(n3) );
在没有分析时序前,根据我们已经有的知识,基本上可以知道这几个net上可能存在的问题。
1.较大的延迟,因为每个net上都有1100个负载。
2.drc错误,max_transition,max_capacitance,max_fanout
3.较大的输出转换时间output_transition,尤其是U1340的output_transition作为下一级的input_transition,经过下一级的cell时候会造成更大的延迟。
时序分析
<!--[if !supportLists]-->1. <!--[endif]-->clock
可以看到clock tree上没有插入buffer,但是 cell的延迟却很大
2.reset
Dc自动插入了buffer。
3一般信号
Dc同样自动插入了buffer。
下面我们修改一下脚本,如下;
set lib $env(DC_LIB)
set target_library "slow.db fast.db"
set link_library "* $target_library"
set search_path ". ../src ../scripts $lib"
set hdlin_while_loop_iterations 5000
analyze -format verilog test.v
elaborate test
uniquify
link
check_design
create_clock -period 100 [get_ports clk]
set input_exp_clk [remove_from_collection [all_inputs] [get_ports clk]]
set_input_delay 60 -clock [get_clocks clk] $input_exp_clk
set_output_delay 30 -clock [get_clocks clk] [all_outputs ]
set_ideal_network -no_propagate [get_nets s_r]
set_ideal_network -no_propagate [get_nets rst_N]
compile
重新分析timing
<!--[if !supportLists]-->1. <!--[endif]-->clock
基本和原来一样,cell上仍然有很大延迟。
<!--[if !supportLists]-->1. <!--[endif]-->reset
原来插入的buffer现在没有了。不过令我不明白的是cell上竟然没有大延迟。等知道的朋友解答。
<!--[if !supportLists]-->1. <!--[endif]-->一般信号
同样dc也没有插入延迟,和希望的一样。不过也没有出现大延迟,不是很明白
问题:
虽然设置了set_ideal_net(network),set_dont_touch(network)但是clock上仍然有大延迟。
为了解决这个问题,我们还要继续设置高扇出的选项。
<!--[if !supportLists]-->1. <!--[endif]-->high_fanout_net_threshold,这个变量是用来指出,如果net的扇出个数超过指定值,那么他就是高扇出,同时drc检查,还有延迟计算都是这个数值计算,但是时间上net上的扇出是没有变的。
<!--[if !supportLists]-->2. <!--[endif]-->high_fanout_net_pin_capacitance,结合high_fanout_net_threshold使用的,当net的扇出超过threshold,那么net上的负载等于这2个数值的乘积。
进一步:修改脚本:
set lib $env(DC_LIB)
set target_library "slow.db fast.db"
set link_library "* $target_library"
set search_path ". ../src ../scripts $lib"
set hdlin_while_loop_iterations 5000
analyze -format verilog test.v
elaborate test
uniquify
link
check_design
create_clock -period 100 [get_ports clk]
set input_exp_clk [remove_from_collection [all_inputs] [get_ports clk]]
set_input_delay 60 -clock [get_clocks clk] $input_exp_clk
set_output_delay 30 -clock [get_clocks clk] [all_outputs ]
set_ideal_network -no_propagate [get_nets s_r]
set_ideal_network -no_propagate [get_nets rst_N]
set high_fanout_net_threshold 60
set high_fanout_net_pin_capacitance 0.01
compile
时序分析:
<!--[if !supportLists]-->1. <!--[endif]-->clock
可以发现cell的延迟已经很合理。
<!--[if !supportLists]-->1. <!--[endif]-->reset
Cell上的延迟和原来一样
<!--[if !supportLists]-->1. <!--[endif]-->一般信号
发现和原来一样。
Apr之后
导出网标,修改约束文件成初始状态,继续分析时序:
可以看出apr工具自动加入了buffer,同时优化了net上的fanout
总结:
为了让dc在综合高扇出的net时候不插入buffer tree和buffer chain,需要使用set_idea_network使这些搞扇出net避免时序优化(timing optimization),时序更新(timing update),drc修正(drc fixxing)。但是这样设置之后,net上的高负载并没有消除,我们需要额外的参数进行设置. high_fanout_net_threshold high_fanout_net_pin_capacitance .以减少dc综合时间,以及减少timing violators report
文章评论(0条评论)
登录后参与讨论