6 Replies Latest reply on Oct 12, 2016 6:38 AM by luciano.artuso

    COVER FREE AREA

    luciano.artuso

        Hi,

      I merged 5 different gds files into a unique layout like the image for example

       

      layout example.jpg

      I would like to know if it's possible to cover all free area around chips with a specific layer, using a command like "create polygon" or something like this on tcl script running calibredrv

       

      Many thanks in advance

       

         Best Regards

       

            Luciano

        • 1. Re: COVER FREE AREA
          vernon_greer

          Hi Luciano,

          That's very doable. I've drawn large chip-surrounding polygons required by foundries before in just such a fashion. Here's some code that will do the trick. This would be typed into the terminal from which you launched your CalibreDRV session at the DRV TCL prompt.

           

          set cwb [ find objects -class cwbWorkBench ]

          set L [ $cwb cget -_layout ]

          $L create polygon TOPCELL 0 0 0 2u 2u

           

          CalibreDRV uses object-oriented TCL, which you don't run into everywhere. Let's break the code down:

          1. The first line grabs the calibreWorkBench object from which all layout objects are born.
          2. The second line spawns a layout object from the cwbWorkBench object. Once we have that, we can start drawing. Oh, that last argument that looks so funny, that's "hyphen-underscore-'layout'" typed in there.
          3. The third line does the job, drawing a poly across a 2um X 2um area. The arguments are examples. More generally, the command looks like "$L create polygon <cellName> <layer> <x0 y0> <x1 y1> [x2 y2] [x3 y3] ...
            1. cellName := The name of the cell in which you want to draw the polygon.
            2. layer := The GDS layer number on which to draw the polygon. If your layer has a non-zero datatype, represent it like a float: layer 5 datatype 3 would be 5.3.
            3. x0 y0 := First polygon vertex.
            4. x1 y1 := Second polygon vertex. If you only provide 2, DRV will assume you are providing the lower left and upper right corners of a rectangle.
            5. xn yn := Additional vertices for more complicated polygons.
          • 2. Re: COVER FREE AREA
            luciano.artuso

              Hi Vernon,

             

            thanks for your explanation.

            I have tried this line

             

            $Lnew create layer 3

            $Lnew create polygon cellname 3 (6567500 8367500) (6567500 -8367500) (-6567500 8367500) (-6567500 -8367500) (-2347500 -2847500) (-2347500 -3717500) (-2535500 -4447500) (-2335500 -5317500) (-2699500 -1167500) (-2699500 -5565500) (-6017500 -5565500) (-6557500 -865500) (6557500 8352500) (-6557500 8352500) (-6557500 -865500) (-6557500 -2847500) (-6557500 -3717500) (-6557500 -4447500) (-6557500 -5317500)

             

            where I have put all vertex of the modules inserted into the layout but I received this errors message:

             

            Error: layout9 create polygon MPW_SL: found an unknown layer = '3' or invalid polygon specification

                while executing

            "$Lnew create polygon ......................................................................

             

            I have tried also the same line without open and close parenthesis, but the polygon generated is not what I need

             

            Can You help me to understand this point?

            Many thanks and regards

              Luciano

            • 3. Re: COVER FREE AREA
              matthew_grange

              Hi Luciano,

               

              It sounds like you want a layer that occupies all the space in your design not occupied by the current layers/cells in the design. I would do a NOT operation in this case ($L NOT). Here's an example script.

               

              #create new layout

              set ll [layout create]

               

              #create new topcell

              $ll create cell newCell

              #create layers in cell

              $ll create layer 3

              $ll create layer 4

              $ll create layer 50

               

              #create some random shapes on 1 layer (3)

              $ll create polygon newCell 3 10 10 100 100

              $ll create polygon newCell 3 120 200 200 100

              $ll create polygon newCell 3 140 50 300 10

               

              #get the bounding box of the entire cell

              set cellCoords [$ll bbox newCell]

               

              #create a new layer the same size as the bounding box

              eval $ll create polygon newCell 4 $cellCoords

               

              #Perform a NOT between the random shapes and the blanket layer to get the difference layer on 50

              $ll NOT 4 3 50

               

              #create the GDS

              $ll gdsout output.gds

               

              orig.png

              not.png

               

              matt

              • 4. Re: COVER FREE AREA
                luciano.artuso

                   Hi Matthew

                 

                thanks for your support

                Unfortunately doesn't work correctly how I need in my gds file:

                 

                2016-10-11_181858.jpg

                2016-10-11_182002.jpg

                 

                2016-10-11_182028.jpg

                In my hierarchy.

                Layer 997 is like your 3

                Layer 998 is like your 4

                Layer 999 is like your 50

                 

                In my example

                the layer 997 is present only on cell MPW_SL

                the layer 998 is present on both cells MPW and MPW_SL

                 

                After

                $Lnew NOT 998 997 999

                the layer 999 has been created WRONG on both cells MPW and MPW_SL

                 

                I need that correct layer 999 will be present only on cell MPW_SL

                Is possible do it?

                 

                   Many thanks

                    Luciano

                • 5. Re: COVER FREE AREA
                  matthew_grange

                  Hey Luciano,

                   

                  Without knowing exactly what you want, I tried to come up with something that demonstrates a number of options for you. Run this script in DESIGNrev to see the output. I think it will be more clear if you play around with turning on and off the layers. I put temporary and output layers on the same base layer but with different datatypes to help visualize the problem. The script does this:

                  1. Creates an example layout with two cells instantiated in a topcell.

                  1.png

                  The two cells have different geometry on layer 3.

                  2.png

                  2. Creates temporary layers (tmp1 and tmp2) in both cells that covers each cell entirely.

                  3.png

                  3. Creates a temporary layer (tmp3) that covers the entire top cell.

                  4.png

                  3. ORs the two cell layers onto a new temporary layer (tmp4) with the hier flag on so it propagates up to the top cell.

                  4. NOTs the combined tmp4 layer with the tmp3 layer to generate a layer (top_output_outlines) that entirely surrounds the cells.

                  5.png

                   

                  This green layer might be what you're looking for. If you're also looking to generate a layer that surrounds the geometry inside the cells, I've added a few more operations to the script that do that:

                   

                  5. Temporary layers in Step 2 are NOT'd with the design layer and OR'd together to get a layer (tmp5) that covers the empty space in each cell.

                  6.png

                  6. The new layer is NOT'd with the temporary layer (tmp3) that covers the entire top cell. This produces a layer that surrounds the design as if it was flat.

                  7.png

                  The cellC_output and cellB_output layers are just the NOT of the geometry in each cell.

                   

                  There are plenty of ways to do this, so I'm sure someone could come up with a different solution.

                   

                  Here's the script (just copy and paste it into a text file and call calibredrv myScript.tcl):

                   

                  ##############################################################################

                  # BEGIN

                  ##############################################################################

                  #create new layout

                  set ll [layout create]

                   

                  #====variables=======

                  #cell names

                  set topcell TOP_CELL

                  set cellA cell_A

                  set cellB cell_B

                   

                  set design_layer 3

                  #temp layers

                  set tmp_layer1 5.1

                  set tmp_layer2 5.2

                  set tmp_layer3 5.3

                  set tmp_layer4 5.4

                  set tmp_layer5 5.5

                  #generated overlay layer

                  set outlayer1 50.1

                  set outlayer2 50.2

                  set outlayer3 50.3

                  set outlayer4 50.4

                  #====/variables=======

                   

                  ##########################################################

                  # This part creates a layout with 2 cells for the example

                  ##########################################################

                  #create new topcell

                  $ll create cell $topcell

                   

                   

                  #create layers in layout

                  $ll create layer $design_layer

                  $ll create layer $tmp_layer1

                  $ll create layer $tmp_layer2

                  $ll create layer $tmp_layer3

                  $ll create layer $tmp_layer4

                  $ll create layer $tmp_layer5

                  $ll create layer $outlayer1

                  $ll create layer $outlayer2

                  $ll create layer $outlayer3

                  $ll create layer $outlayer4

                   

                  #create child cells

                  $ll create cell $cellA

                  $ll create cell $cellB

                   

                  #create some random shapes for cellA

                  $ll create polygon $cellA $design_layer 10 10 100 100

                  $ll create polygon $cellA $design_layer 120 200 200 100

                  $ll create polygon $cellA $design_layer 140 50 300 10

                   

                  #create some random shapes for cellB

                  $ll create polygon $cellB $design_layer 5 50 95 95

                  $ll create polygon $cellB $design_layer 0 0 100 10

                  $ll create polygon $cellB $design_layer 0 20 100 30

                   

                  #Place the cells as an instances in the topcell

                  set x 0

                  set y 0

                  set mirror 0

                  set angle 0

                  set mag 1

                  $ll create ref $topcell $cellA $x $y $mirror $angle $mag

                  set x 250

                  set y 250

                  set mag 2

                  $ll create ref $topcell $cellB $x $y $mirror $angle $mag

                   

                  ##########################################################

                  # Here's where the layer merging and NOTing takes place

                  ##########################################################

                  #get the bounding box of each cell instance and the top cell

                  set cellCoordsA [$ll bbox $cellA]

                  set cellCoordsB [$ll bbox $cellB]

                  set cellCoordsT [$ll bbox $topcell]

                   

                  #create a new layer the same size as the bounding box over each cell

                  eval $ll create polygon $cellA $tmp_layer1 $cellCoordsA

                  eval $ll create polygon $cellB $tmp_layer2 $cellCoordsB

                  eval $ll create polygon $topcell $tmp_layer3 $cellCoordsT

                   

                  #Perform a NOT between the random shapes and the blanket temporary layer to get the difference layer

                  $ll NOT $tmp_layer1 $design_layer $outlayer1

                  $ll NOT $tmp_layer2 $design_layer $outlayer2

                   

                  #process top layer (different ways to do this depending on what you want

                  $ll OR $tmp_layer1 $tmp_layer2 $tmp_layer4 -hier 1

                  $ll NOT $tmp_layer3 $tmp_layer4 $outlayer3

                   

                  #create combinedlayer that considers hierachy of CellA and B blockages

                  $ll OR $outlayer2 $outlayer1 $tmp_layer5 -hier 1

                  $ll OR $outlayer3 $tmp_layer5 $outlayer4 -hier 1

                   

                  #rename layers for readability in OASIS

                  $ll layernames $outlayer4 top_output_combined

                  $ll layernames $outlayer3 top_output_outlines

                  $ll layernames $outlayer2 cellB_output

                  $ll layernames $outlayer1 cellC_output

                  $ll layernames $design_layer design

                  $ll layernames $tmp_layer1 tmp1

                  $ll layernames $tmp_layer2 tmp2

                  $ll layernames $tmp_layer3 tmp3

                  $ll layernames $tmp_layer4 tmp4

                  $ll layernames $tmp_layer5 tmp5

                   

                  #create the OASIS file

                  $ll oasisout output.oas

                  • 6. Re: COVER FREE AREA
                    luciano.artuso

                    Hi Mattew,

                     

                    I'll try explain You better.

                     

                    This is my scrpt

                     

                    I need that on layer 999.1 will be present the NOT of layer 997 only on cell MPW_SL

                     

                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

                    #######

                     

                     

                    # Load file.gds

                     

                     

                    array set peekdata [layout peek file1.gds.gz -type -topcell -layers -units]

                    puts "TOPCELL: $peekdata(topcell)"

                     

                     

                    set format [string toupper $peekdata(type)]

                    puts $format

                     

                     

                    set Lone [layout create file1.gds.gz -dt_expand -preservePaths -preserveProperties -preserveTextAttributes]

                    set precision [expr int (1/([$Lone units]))]

                    $Lone units microns $precision

                    foreach mych [$Lone children $peekdata(topcell)] {

                        puts "STRUCT: $mych \n"

                        foreach pp [$Lone children $mych] {

                        puts "$pp \n"

                        }        

                        }

                       

                    puts $peekdata(layers)

                     

                     

                    set mychx1 [exec echo $peekdata(topcell) | sed {s/_TOP/ /g} | awk {{print $1}}]

                     

                    puts $mychx1

                     

                    set mychx2 [exec echo ${mychx1}_SL]

                    puts $mychx2

                     

                    set bboxlo [$Lone bbox $peekdata(topcell)]

                    puts $bboxlo

                     

                     

                    puts $peekdata(units)

                     

                    ################### rename cells on hierarchy #######################

                     

                    set suff   [clock seconds]

                     

                    set norename ""

                    foreach mytops [$Lone topcell all] {

                      set norename "$norename $mytops "

                      foreach mychild [$Lone children $mytops] {

                      set norename "$norename $mychild "

                      }

                      }

                     

                    foreach mycell [$Lone cells] {

                      if { [string first  $mycell $norename] == -1} {

                      set newcell  "${mycell}_${suff}"

                      puts "Renaming $mycell to $newcell"

                      $Lone cellname $mycell $newcell

                      } else {

                      puts "Cell name $mycell unchanged"

                      }

                     

                    }

                     

                    $Lone create layer 997

                    $Lone create layer 999.1

                    $Lone create polygon $mychx2 997 [lindex [$Lone bbox $peekdata(topcell)] 0] [lindex [$Lone bbox $peekdata(topcell)] 1] [lindex [$Lone bbox $peekdata(topcell)] 2] [lindex [$Lone bbox $peekdata(topcell)] 3]

                     

                    ################# create temporary gds file starting from both cells ###########################################

                     

                      if { $format == "GDS" } {

                     

                     

                    $Lone gdsout $mychx1.gds.gz $mychx1

                    set Lonet1 [layout create $mychx1.gds.gz -dt_expand -preservePaths -preserveProperties -preserveTextAttributes]

                     

                     

                    $Lone gdsout $mychx2.gds.gz $mychx2

                    set Lonet2 [layout create $mychx2.gds.gz -dt_expand -preservePaths -preserveProperties -preserveTextAttributes]

                     

                     

                           # $Lone gdsout file1.gds.gz

                       } else {

                          #  $Lone oasisout file1.oas -cBlocks -strictMode

                       }

                     

                       

                    # set mychx1 [lindex [$Lone children $peekdata(topcell)] 0]

                    # set mychx2 [lindex [$Lone children $peekdata(topcell)] 1]

                       

                     

                     

                    ##########################

                     

                    array set peekdata2 [layout peek file2.gds.gz -type -topcell -layers -units]

                    puts "TOPCELL: $peekdata2(topcell)"

                     

                     

                    set format2 [string toupper $peekdata2(type)]

                    puts $format2

                     

                     

                    set Ltwo [layout create file2.gds.gz -dt_expand -preservePaths -preserveProperties -preserveTextAttributes]

                    set precision2 [expr int (1/([$Ltwo units]))]

                    $Ltwo units microns $precision2

                    foreach mych2 [$Ltwo children $peekdata2(topcell)] {

                        puts "STRUCT: $mych2 \n"

                        foreach pp2 [$Ltwo children $mych2] {

                        puts "$pp2 \n"

                        }        

                        }

                       

                    puts $peekdata2(layers)

                     

                     

                    set mychy1 [exec echo $peekdata2(topcell) | sed {s/_TOP/ /g} | awk {{print $1}}]

                     

                    puts $mychy1

                     

                    set mychy2 [exec echo ${mychy1}_SL]

                    puts $mychy2

                     

                    set bboxlo2 [$Ltwo bbox $peekdata2(topcell)]

                    puts $bboxlo2

                     

                     

                    puts $peekdata2(units)

                     

                    ################### rename cells on hierarchy #######################

                     

                     

                    set suff2   [clock seconds]

                     

                    set norename2 ""

                    foreach mytops2 [$Ltwo topcell all] {

                      set norename2 "$norename2 $mytops2 "

                      foreach mychild2 [$Ltwo children $mytops2] {

                      set norename2 "$norename2 $mychild2 "

                      }

                      }

                     

                    foreach mycell2 [$Ltwo cells] {

                      if { [string first  $mycell2 $norename2] == -1} {

                      set newcell2  "${mycell2}_${suff2}"

                      puts "Renaming $mycell2 to $newcell2"

                      $Ltwo cellname $mycell2 $newcell2

                      } else {

                      puts "Cell name $mycell2 unchanged"

                      }

                     

                    }

                     

                     

                    $Ltwo create layer 997

                    $Ltwo create layer 999.1

                    $Ltwo create polygon $mychy2 997 [lindex [$Ltwo bbox $peekdata2(topcell)] 0] [lindex [$Ltwo bbox $peekdata2(topcell)] 1] [lindex [$Ltwo bbox $peekdata2(topcell)] 2] [lindex [$Ltwo bbox $peekdata2(topcell)] 3]

                     

                     

                    ################# create temporary gds file from bosth cells ###########################################

                     

                     

                    if { $format2 == "GDS" } {

                     

                     

                    $Ltwo gdsout $mychy1.gds.gz $mychy1

                    set Ltwot1 [layout create $mychy1.gds.gz -dt_expand -preservePaths -preserveProperties -preserveTextAttributes]

                     

                     

                    $Ltwo gdsout $mychy2.gds.gz $mychy2

                    set Ltwot2 [layout create $mychy2.gds.gz -dt_expand -preservePaths -preserveProperties -preserveTextAttributes]

                     

                     

                          #  $Ltwo gdsout file2.gds.gz

                            } else {

                          #  $Ltwo oasisout file3.oas -cBlocks -strictMode

                            }

                       

                    ##############################

                     

                     

                    array set peekdata3 [layout peek file3.gds.gz -type -topcell -layers -units]

                    puts "TOPCELL: $peekdata3(topcell)"

                     

                     

                    set format3 [string toupper $peekdata3(type)]

                    puts $format3

                     

                     

                    set Lthree [layout create file3.gds.gz -dt_expand -preservePaths -preserveProperties -preserveTextAttributes]

                    set precision3 [expr int (1/([$Lthree units]))]

                    $Lthree units microns $precision3

                    foreach mych3 [$Lthree children $peekdata3(topcell)] {

                        puts "STRUCT: $mych3 \n"

                        foreach pp3 [$Lthree children $mych3] {

                        puts "$pp3 \n"

                        }        

                        }

                       

                    puts $peekdata3(layers)

                     

                     

                    set mychz1 [exec echo $peekdata3(topcell) | sed {s/_TOP/ /g} | awk {{print $1}}]

                     

                    puts $mychz1

                     

                    set mychz2 [exec echo ${mychz1}_SL]

                    puts $mychz2

                     

                    set bboxlo3 [$Lthree bbox $peekdata3(topcell)]

                    puts $bboxlo3

                     

                     

                    puts $peekdata3(units)

                     

                    ################### rename cells on hierarchy #######################

                     

                     

                    set suff3   [clock seconds]

                     

                    set norename3 ""

                    foreach mytops3 [$Lthree topcell all] {

                      set norename3 "$norename3 $mytops3 "

                      foreach mychild3 [$Lthree children $mytops3] {

                      set norename3 "$norename3 $mychild3 "

                      }

                      }

                     

                    foreach mycell3 [$Lthree cells] {

                      if { [string first  $mycell3 $norename3] == -1} {

                      set newcell3  "${mycell3}_${suff3}"

                      puts "Renaming $mycell3 to $newcell3"

                      $Lthree cellname $mycell3 $newcell3

                      } else {

                      puts "Cell name $mycell3 unchanged"

                      }

                     

                    }

                     

                     

                    $Lthree create layer 997

                    $Lthree create layer 999.1

                    $Lthree create polygon $mychz2 997 [lindex [$Lthree bbox $peekdata3(topcell)] 0] [lindex [$Lthree bbox $peekdata3(topcell)] 1] [lindex [$Lthree bbox $peekdata3(topcell)] 2] [lindex [$Lthree bbox $peekdata3(topcell)] 3]

                     

                     

                    ################# create temporary cells for both cells ###########################################

                     

                     

                    if { $format3 == "GDS" } {

                     

                    $Lthree gdsout $mychz1.gds.gz $mychz1

                    set Lthreet1 [layout create $mychz1.gds.gz -dt_expand -preservePaths -preserveProperties -preserveTextAttributes]

                     

                     

                    $Lthree gdsout $mychz2.gds.gz $mychz2

                    set Lthreet2 [layout create $mychz2.gds.gz -dt_expand -preservePaths -preserveProperties -preserveTextAttributes]

                     

                     

                           # $Ltwo gdsout file3.gds.gz

                            } else {

                           # $Ltwo oasisout file3.oas -cBlocks -strictMode

                            }     

                       

                    ###########################################################################################################   

                     

                     

                    # Create empty cell

                    set Lnew [layout create]

                     

                     

                    # Create new topcell and children cells for new layout

                    $Lnew create cell MPW_TOP

                    $Lnew create cell MPW

                    $Lnew create cell MPW_SL

                     

                     

                    $Lnew create ref MPW_TOP MPW 0 0 0 0 1

                    $Lnew create ref MPW_TOP MPW_SL 0 0 0 0 1

                     

                     

                    # Copy patterns on new layout

                    $Lnew import layout $Lonet1 TRUE overwrite

                    $Lnew import layout $Lonet2 TRUE overwrite

                    $Lnew import layout $Ltwot1 TRUE overwrite

                    $Lnew import layout $Ltwot2 TRUE overwrite

                    $Lnew import layout $Lthreet1 TRUE overwrite

                    $Lnew import layout $Lthreet2 TRUE overwrite

                     

                     

                     

                     

                    $Lnew create ref MPW "${mychx1}" -4546500 -3282500 0 0 1

                    $Lnew create ref MPW_SL "${mychx2}" -4546500 -3282500 0 0 1

                     

                    $Lnew create ref MPW "${mychx1}" -4546500 -4882500 0 0 1

                    $Lnew create ref MPW_SL "${mychx2}" -4546500 -4882500 0 0 1

                     

                    $Lnew create ref MPW "${mychy1}" 0 3743500 0 0 1

                    $Lnew create ref MPW_SL "${mychy2}" 0 3743500 0 0 1

                     

                    $Lnew create ref MPW "${mychz1}" 4358500 -3366500 0 0 1

                    $Lnew create ref MPW_SL "${mychz2}" 4358500 -3366500 0 0 1

                     

                    $Lnew create layer 998.1

                    $Lnew create layer 998.2

                     

                    $Lnew create polygon MPW 998.1 [lindex -6567500] [lindex -8367500] [lindex 6567500] [lindex 8367500]

                    $Lnew create polygon MPW_SL 998.2 [lindex -6567500] [lindex -8367500] [lindex 6567500] [lindex 8367500]

                     

                     

                    $Lnew NOT 998.2 997 999.1

                     

                     

                    # Create final oasis file

                    $Lnew oasisout MPW_MULTI.oas

                     

                    array set peekdatao [layout peek MPW_MULTI.oas -type -precision -topcell -topcells -layers]

                    puts $peekdatao(layers)

                     

                    exec rm $mychx1.gds.gz $mychx2.gds.gz $mychy1.gds.gz $mychy2.gds.gz $mychz1.gds.gz $mychz2.gds.gz