1、芯片后仿的意義:
既然前仿保證了邏輯功能,STA 保證了時序,PT對各個corner進行了時序窮舉計算並確保時序收斂,那么作為數字IC設計流程的最后一環后仿真的意義是什么呢?
原因有若干:
1、 多時鍾域的timing確認(跨時鍾域信號的同步處理)。
2、由於異步處理部分在SDC約束文件中做的是fath_path處理,所以這部分時序是否滿足,PT並不會檢查也不會報出violation。
3、異步的處理方式在PD處理后有問題: example:dmux結構,data signal latnecy過大;導致后仿出現ctrl信號先 data stable后的case。
4、一些test pattern需要做后仿,調整合適的timing margin,太緊的話,片子容易fail。
5、時鍾切換電路?
6、DFT邏輯的插入是否導致功能出現問題。
2、芯片后仿違例類型:
1、Setup/hold違背(posedge D -> posedge CK , negedge D -> posedge CK)
2、Recovary/Removal違背 (posedge CDN -> posedge CK ,posedge SDN -> posedge CK)??
3、Width違背 (CK,CDN,SDN)
4、IP接口時序不符合datasheet?外設器件是否也需要帶延時的model?
3、后仿全面介紹:http://www.chipsbank.com/news_detail/newsId=121.html
1.后仿是否必要
隨着芯片規模的增大,關於IC設計流程中的后仿是否必要,有多種聲音。
認為不必要的理由是:布局布線后的網表,已經可以通過STA保證時序,后仿只不過是確認一遍電路的時序。而且隨着電路規模不斷增大,仿真工具的仿真速度的提升仍不明顯,后仿必然是一個很耗時的步驟,時間代價大而收益不明顯。
認為有必要的理由是,從公司以往多個項目的經驗來看,后仿中也發現了一些問題。而對於有些設計,STA並不能完全覆蓋所有的路徑。后仿的工作是對后端實現最后的check。
本文認為,以公司現階段的研發力量,后仿還是必須的。
2.前后仿的區別
前仿:RTL的仿真
后仿:門級仿真。又分為綜合后仿真和布局布線后仿真
a.關注點不同;
前仿:關注RTL在功能上是否正確(符合設計)
后仿:關注電路在各種工作條件下,插入了延時后,功能是否依然正確。
b.仿真對象不同;
前仿:仿真的對象是RTL
后仿:仿真的對象是門級網表+sdf文件(可能包括一些IP的sdf)
綜合后仿真用的是綜合后的網表+PreSTA產生的sdf(無net延時,cell延時不准確,時鍾樹不准確)
布局布線后仿真用的是PR后的網表+PostSTA產生的sdf
c.外部激勵與響應檢查;
所用的激勵和響應檢查應一致
后仿可能讓時鍾漂移以模擬極端的情況
3.后仿的各種組合情況
如果考慮OSC漂移以及三種Corner,可以組合以下六種情況
Fast OSC + Fast SDF
Slow OSC + Fast SDF
Fast OSC + Typ SDF
Slow OSC + Typ SDF
Fast OSC + Slow SDF
Slow OSC + Slow SDF
說明:對於普通的設計,實際只需考慮3中sdf即可。對於osc偏移可能帶來的影響(如,flash編程),則后仿需要考慮更多Osc偏移帶來的影響(時序不滿足)
4. 認識sdf文件
sdf = 標准延時文件
請參考附錄1中對於sdf文件的注釋
5. Sdf反標
反標:vcs將sdf文件中的延時信息添加到門級網表中對應的地方
$sdf_annotate
例:$sdf_annotate("/home/chengp/project/zi2201/trunk/Digital/FrontEnd/sta/sdf/zi2201.20100726_v0.26_post_min_case1.eco.sdf",U_zi2201e_digital);
6.后仿違背的類型
a.時序器件
Setup/hold違背(posedge D -> posedge CK , negedge D -> posedge CK)
Recovary/Removal違背 (posedge CDN -> posedge CK ,posedge SDN -> posedge CK)
Width違背 (CK,CDN,SDN)
b.IP時序違背
IP接口時序不符合datasheet
7.針對違背采取的措施
a.同步處理第一級寄存器的違背(注:這一級的X態主要是由於同步復位的寄存器導致的)
i.方法一
1,建立文件Sync.v,格式如下:
initial begin
force Top.uXX.uYY.uZZ_reg.notifier = 1'b0;
…………
end
2,在SimTop中的include此文件;
解決了寄存器輸出為x的情況,但仿真會報很多warning
ii.方法二
1,建立文件Sync.v,格式如下
instance {
Top.uXX.uYY.uZZ_reg,
……
} {noTiming}
2,在runsim文件中加入 +optconfigfile+./Sync.v
b.其他
i.時序約束是否存在問題
ii.時鍾樹是否合理
iii.電路設計是否有潛在風險
iv.接口設計是否遵循datasheet
8.后仿腳本
1,+neg_tchk
寄存器可能出現負的setup limit和hold limit。??
如果sdf中存在負的setup limit或hold limit,則使用特定的規則檢查
實際仿真結果:
仿真加 +neg_tchk
仿真調用的sdf如下圖所示:
a,正的setup + 負的hold
Posedge D 發生在時鍾沿前 (-2.6ns , -1.8ns)會出現setuphold違背
b,負的setup + 正的hold
Negedge D發生在時鍾沿后 ( 1.7ns , 2.9ns )會出現setuphold違背
2,+sdfverbose
反標過程中打印詳細的信息
9.后仿注意的問題
1,對於一些IP的仿真模型,定義了一些延時量,但一般不針對某個corner。因此最好定義各個corner下的延時量。
10. 后仿遺留問題
1,反標負延時?
vcs手冊中說用-negdelay可以允許sdf中的cell和net使用負延時。
備注:負延時的一種情形:
實際仿真時,修改了某個cell的延時為負,仿真不加-negdelay,仿真提示:
Warning-[SDFCOM_NDI] Negative Delay Ignored
/home/chengp/project/zi2201/trunk/Digital/FrontEnd/sta/sdf/zi2201.20100726_v0.26_post_max_case1.eco.sdf, 34671
module: inv0d0, "instance: zi2201eTest.U_zi2201e_digital.U3827"
SDF Warning: Negative delay is ignored and replaced by 0.
Please use -negdelay to support it.
如果加-negdelay仿真,仿真提示如下:
Warning-[SDFCOM_NIOD] Negative IOPATH Delay encountered
/home/chengp/project/zi2201/trunk/Digital/FrontEnd/sta/sdf/zi2201.20100726_v0.26_post_max_case1.eco.sdf, 34671
SDF Warning: Negative IOPATH Delay I to ZN is replaced by 0.
This negative value cannot be handled with switch -negdelay. Please check SDF files.
2,+overlap作用
3,sdf中的mindelays ,maxdelays
pt在使用bc_wc測例做sta分析時,生成的sdf可能mindelays和maxdelays可能不一樣。如:(IOPATH I ZN (0.540::0.642) (0.302::0.362))。反標sdf時,vcs腳本中加+mindelays則反標的是0.540和0.302,加+maxdelays則反標的是0.642和0.362。
附錄1 sdf文件
(DELAYFILE
(SDFVERSION "OVI 2.1")
(DESIGN "zi2201_digital_virage") // top name
(DATE "Mon Jul 26 11:06:27 2010")
(VENDOR "tsl18fs020_max") // 生成sdf所使用的庫
(PROGRAM "Synopsys PrimeTime")
(VERSION "B-2008.06-SP2")
(DIVIDER /)
// OPERATING CONDITION "tsl18fs020_max::tsl18fs020_max"
(VOLTAGE 0.90::0.90) // corner參數
(PROCESS "1.200::1.200")
(TEMPERATURE 125.00::125.00)
(TIMESCALE 1ns) //延時單位
(CELL
(CELLTYPE "zi2201_digital_virage")
(INSTANCE)
(DELAY
(ABSOLUTE
(INTERCONNECT U4384/ZN U3558/I (0.001::0.001)) // 兩個cell的pin之間連線的delay
)
)
)
(CELL // 網表中的每個單元的信息都是由 (CELL .. )包括
(CELLTYPE "inv0d0")
(INSTANCE U3558) // 網表中的單元
(DELAY
(ABSOLUTE
(IOPATH I ZN (0.540::0.642) (0.302::0.362)) // 延時數據
// 0.540= min delay from I(1->0) to Z (0->1)
// 0.642= max delay from I(1->0) to Z (0->1)
// 0.302= min delay from I(0->1) to Z (1->0)
// 0.362= max delay from I(0->1) to Z (1->0)
)
)
)
(CELL
(CELLTYPE "dfcrn1")
(INSTANCE U_Decoder_TRCalCntH_reg_0_)
(DELAY
(ABSOLUTE
(IOPATH CP QN (1.546::1.721) (1.551::1.727))
(IOPATH CDN QN (1.907::1.907) ())
)
)
(TIMINGCHECK // timing check 參數
(WIDTH (posedge CP) (0.532::0.532))
(WIDTH (negedge CP) (0.972::0.972))
(HOLD (posedge CDN) (posedge CP) (1.216::1.216))
(RECOVERY (posedge CDN) (posedge CP) (-0.653::-0.653))
(WIDTH (negedge CDN) (0.412::0.412))
(SETUP (posedge D) (posedge CP) (0.219::0.219))
(SETUP (negedge D) (posedge CP) (0.193::0.193))
(HOLD (posedge D) (posedge CP) (-0.202::-0.202))
(HOLD (negedge D) (posedge CP) (0.057::0.057))
)
)
附錄2 仿真模型
module inv0d0 (I,ZN);
output ZN;
input I;
not #1 (ZN,I);
`ifdef functional
`else
specify
// Parameter declarations
specparam i_lh_zn_hl=-1,i_hl_zn_lh=-1;
// Delays
( I -=> ZN) = (i_hl_zn_lh,i_lh_zn_hl);
endspecify
`endif
endmodule
module dfcrn1 (D,CP,CDN,QN);
output QN;
input D,CP,CDN;
`ifdef neg_tchk
wire d_D,d_CP,d_CDN;
`endif
`ifdef functional
U_FD_P_RB #1 (QN_not,D,CP,CDN);
`else
reg notifier;
`ifdef neg_tchk
U_FD_P_RB_NO #1 (QN_not,d_D,d_CP,d_CDN,notifier);
`else
U_FD_P_RB_NO #1 (QN_not,D,CP,CDN,notifier);
`endif
`endif
not (QN,QN_not);
`ifdef functional
`else
specify
// Parameter declarations
specparam tsu_d_h_cp=0.12,tsu_d_l_cp=0.22,tsu_cdn_h_cp=0.00,th_cp_d_h=0.00,
th_cp_d_l=0.00,th_cp_cdn_l=0.33,tpw_cp_h=0.26,tpw_cp_l=0.43,tpw_cdn_l=0.23,
cp_lh_qn_hl=0,cp_lh_qn_lh=0,cdn_hl_qn_lh_1=0;
// Violation constraints
`ifdef neg_tchk
$setuphold (posedge CP &&& (CDN==1'b1),posedge D &&& (CDN==1'b1),tsu_d_h_cp,th_cp_d_l,notifier,,,d_CP,d_D);
$setuphold (posedge CP &&& (CDN==1'b1),negedge D &&& (CDN==1'b1),tsu_d_l_cp,th_cp_d_h,notifier,,,d_CP,d_D);
$recrem (posedge CDN,posedge CP,tsu_cdn_h_cp,th_cp_cdn_l,notifier,,,d_CDN,d_CP);
`else
$setup (posedge D &&& (CDN==1'b1),posedge CP &&& (CDN==1'b1),tsu_d_h_cp,notifier);
$setup (negedge D &&& (CDN==1'b1),posedge CP &&& (CDN==1'b1),tsu_d_l_cp,notifier);
$recovery (posedge CDN,posedge CP,tsu_cdn_h_cp,notifier);
$hold (posedge CP &&& (CDN==1'b1),negedge D &&& (CDN==1'b1),th_cp_d_h,notifier);
$hold (posedge CP &&& (CDN==1'b1),posedge D &&& (CDN==1'b1),th_cp_d_l,notifier);
$hold (posedge CP,posedge CDN,th_cp_cdn_l,notifier);
`endif
$width (posedge CP &&& (CDN==1'b1),tpw_cp_h,0,notifier);
$width (negedge CP &&& (CDN==1'b1),tpw_cp_l,0,notifier);
$width (negedge CDN,tpw_cdn_l,0,notifier);
// Delays
if (CDN==1'b1)
(posedge CP => (QN -: D )) = (cp_lh_qn_lh,cp_lh_qn_hl);
(negedge CDN => (QN +: 1'b1)) = (cdn_hl_qn_lh_1,0);
endspecify
`endif
endmodule