zoukankan      html  css  js  c++  java
  • 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所在位置如下:

    如果喜欢本公众号也请多多分享哟,谢谢您的关注

  • 相关阅读:
    fetch API 和 ajax
    java 通过数据库名获得 该数据所有的表名以及字段名、字段类型
    自定义注解,通过反射获得注解中的值(详细自定义注解解释)
    main方法中sleep
    eclipse中设置JVM内存
    命令java 找不到或无法加载主类
    windows下的命令
    mac terminal基本命令
    ThreadLocal 源码剖析
    SQL中的函数用法
  • 原文地址:https://www.cnblogs.com/ASIC-Horizon/p/8072084.html
Copyright © 2011-2022 走看看