28nm工藝下,自動生成管腳排列文件,給設計加PAD,並在PAD上面打Label的流程(含Tcl腳本)


本文轉自:自己的微信公眾號《數字集成電路設計及EDA教程》

里面主要講解數字IC前端、后端、DFT、低功耗設計以及驗證等相關知識,並且講解了其中用到的各種EDA工具的教程。

考慮到微信公眾平台上面發布的很多推文百度搜索不到,所以以后的推文也會在這里進行轉載。

 

圖:

黑洞:卡岡都亞

 

28nm工藝下,自動生成管腳排列文件,給設計加PAD,並在PAD上面打Label的流程(含Tcl腳本)

 

在后端設計中編寫管腳排列文件(.tdf文件)是一個非常繁瑣的過程,其實只要SPEC寫好,完全可以用腳本的方式來自動生成該文件,從而減少工作量並防止產生語法問題;且如果要在.tdf文件中指定IO的坐標,當坐標位置有一定的規律時,也可以用Tcl腳本來計算得到,不用靠手工計算來完成。當IO數目上百之后,可想該工作量該有多大,所以能用腳本就盡量用腳本來完成。

此外,在一些IO多的設計中經常用到一些Stagger擺放的PAD,他們的擺放也不容易,在PAD數目非常少的情況下手工擺放還有可能,但是數目增多之后難道非常大。尤其是一些特殊的庫中IO和PAD的FRAM View的寬度還不一樣。

另外,在ICC中給Port或者PAD打Label也是一個比較繁瑣的過程,不像之前的Astro直接用一個命令就搞定了,這里也需要用腳本來批量執行。

這里給出一個自己開發的流程,只要按照這個流程來做就能完美解決上述問題,且設計出錯的概率也會非常小。

 

放置PAD可以在Floorplan之后也可以在布線、DFM等完成之后。不過根據28 nm后端設計時的一些經驗,因為PAD是Stagger放置的,所以在內側PAD的金屬和芯片Core內部金屬連線存在一些金屬間距的違反,所以有兩種選擇:1、PAD在Floorplan結束之后馬上放置;2、PAD在布局布線、DFM之后放置,放置完畢后再檢查一下是否有DRC的違反,如果有,修復一下。

 

之后開始介紹詳細的生成.tdf文件以及放置PAD並為其打Label的流程:

1、首先要按照下面的格式寫一個SPEC文件來說明IO的名稱(這個也是將來打Label要用的),IO例化調用的cell,IO的放置方向(左、右、上、下)、順序(ORDER)、輸入輸出屬性(INOUT,這個不是必須的,不過為了使得整個設計更加清晰,所以加上了這一項),也可以加上坐標等信息。

 

2、之后編寫一個Tcl文件,內容如下,然后用Tcl執行即可生成Floorplan的管腳排列文件(.tdf):

set fida [open ../../data/io_spec.csv r]

set fidb [open ../../data/create_io.tdf w]

 

gets $fida

 

while {[gets $fida data_in]>0} {

set side_sym [lindex $data_in 4]

 

switch $side_sym {

       LEFT   {set side_num 1}

       TOP    {set side_num 2}

       RIGHT  {set side_num 3}

       BOTTOM {set side_num 4}

       default {}

}

 

puts $fidb "set_pad_physical_constraints -pad_name [lindex$data_in 2] -side $side_num -order [lindex $data_in 5]"

}

puts $fidb "set_pad_physical_constraints -pad_name CORNER1-side 1 -offset 0"

puts $fidb "set_pad_physical_constraints -pad_name CORNER2-side 2 -offset 0"

puts $fidb "set_pad_physical_constraints -pad_name CORNER3-side 3 -offset 0"

puts $fidb "set_pad_physical_constraints -pad_name CORNER4-side 4 -offset 0"

 

close $fida

close $fidb

 

生成的tdf文件如下:

 

3、之后根據SPEC來查找IO所在位置,分內側和外側用Stagger方式插入PAD,並在PAD中心打相應的Label。其實SMIC 28 nm工藝和40 nm工藝的IO和PAD有一個非常大的不同之處是,它的IO不是等寬的,有細微的差距,有的是30 μm,有的是33 μm,可是PAD寬度是固定的30。本想擺放PAD的時候讓PAD和IO中心對齊,但是計算太麻煩了,感覺沒有必要,就讓所有的PAD都擺放在IO的一邊而非中心,因為這樣也能接觸良好,且不存在DRC、LVS的違反。另外,其實Label也沒有必要打在中心,打在左下角也是可以的,不過為了美觀,這里放在了中心。接下來是腳本:

 

#設定IO的長度和寬度:

set io_length 155

#IO的寬度有兩種,一種是33,一種是30,沒有必要將PAD放置在IO的中心,所以指定一個小的寬度:

set io_width  30;#33

 

set padio_width 30

#Stagger的PAD有兩種,一種是內側的PADI,一種是外側的PADO,

#指定PADI和PADO的長度:

set padi_length 155 

set pado_length 67.07

 

#指定Label的偏移量:

set txt_x_org 15

set txt_y1_org 30

set txt_y2_org 114

 

#對PAD進行計數,同時對PAD進行命名,PAD0、PAD1…:

set num 0

 

#用out來指定PAD是擺放在內側還是外側,out=1則創建PADO,將其放在外側;否則的話創建PADI,並將其放在內側。Out交替變換實現Stagger。

set out 1

 

set fid [open ../../data/io_spec.csv r]

set data_in [gets $fid]

 

while {[gets $fid data_in]>0} {

 

global out

 

if {$out == 0} {

       create_cell"PADI$num" PADI30RN ;#cannot use {PAD$num}

       set padname"PADI$num"

} else {

       create_cell"PADO$num" PADO30RN

       set padname"PADO$num"

}

 

set io_location [get_location [lindex $data_in 2]]

set io_x_location [lindex $io_location 0]

set io_y_location [lindex $io_location 1]

 

#如果IO位於Bottom,那么坐標計算非常方便,直接讓PAD的左下角坐標和IO完全一樣就行了:

if {[lindex $data_in 4] == "BOTTOM"} {

 

       set_attribute [get_cells-all $padname] orientation {N}

      

       set pad_x_location$io_x_location

      

       set pad_y_location$io_y_location

 

       set txt_x_location [expr$pad_x_location+$txt_x_org]

 

       if {$out == 0} {

              settxt_y_location [expr $pad_y_location+$txt_y2_org]

       } else {

              settxt_y_location [expr $pad_y_location+$txt_y1_org]

       }

 

#如果IO位於Right,那么計算會稍微復雜一點,PADO要貼近右側邊緣放置,而get_location只能得到IO左下角的坐標,所以坐標需要加上IO的長度再減去PAD的長度,如下圖所示,從圖中還能看出PAD的寬度和IO不一樣,因為沒有必要將PAD擺放到IO中心,所以也就沒有這樣做。

 

在Virtuoso中擺放出來是這樣的:

 

} elseif {[lindex $data_in 4] == "RIGHT"} {

 

       set_attribute [get_cells-all $padname] orientation {W}

 

       if {$out == 0} {

              setpad_x_location [expr $io_x_location+$io_length-$padi_length]

       } else {

              setpad_x_location [expr $io_x_location+$io_length-$pado_length]

       }

 

       set pad_y_location$io_y_location

 

       set txt_y_location [expr$pad_y_location+$txt_x_org]

 

       set txt_x_location [expr$pad_x_location+$txt_y1_org]

 

 

} elseif {[lindex $data_in 4] == "TOP"} {

 

       set_attribute [get_cells-all $padname] orientation {S}

 

       set pad_x_location$io_x_location

 

       if {$out == 0} {    

              setpad_y_location [expr $io_y_location+$io_length-$padi_length]

       } else {

              setpad_y_location [expr $io_y_location+$io_length-$pado_length]

       }

 

       set txt_x_location [expr$pad_x_location+$txt_x_org]

      

       set txt_y_location [expr$pad_y_location+$txt_y1_org]

 

 

} elseif {[lindex $data_in 4] == "LEFT"} {

 

       set_attribute [get_cells-all $padname] orientation {E}

 

       set pad_x_location$io_x_location

      

       set pad_y_location$io_y_location

 

       set txt_y_location [expr$pad_y_location+$txt_x_org]

 

       if {$out == 0} {

              settxt_x_location [expr $pad_x_location+$txt_y2_org]

       } else {

              settxt_x_location [expr $pad_x_location+$txt_y1_org]

       }

 

}

 

set_cell_location -coordinates "$pad_x_location$pad_y_location" $padname

 

create_text -origin [list [expr $txt_x_location] [expr$txt_y_location]] \

       -height 1 \

       -layer 83 \

       -orient N [lindex$data_in 1]

 

 

if {$out == 0} {

set out 1

} else {

set out 0

}

 

incr num

}

 

close $fid

 

給出插入PAD之后的效果,注:IO在PAD下邊(DUP)

 

Label所在位置如下:

 

如果喜歡本公眾號也請多多分享喲,謝謝您的關注

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM