Create a new layer and set its properties

edited November 2017 in Ruby Scripting

Hi,

I want to create a new layer and set its GDS layer/datatype, name, set its color, filling color, shape, width :

###  create a layer view for the wafer
linfo1 = RBA::LayerInfo.new(1,0)
linfo1.name = "wafer"
layer_id = layout.insert_layer( linfo1 )
ln1 = RBA::LayerPropertiesNode::new
ln1.source_layer_index = layer_id
ln1.dither_pattern = 1
ln.fill_color = 0xFF0000
ln1.frame_color = 0xFF0000
ln1.name = "wafer"
ln1.width = 3
layout_view.insert_layer( layout_view.end_layers, ln1 )

Unfortunatly, it creates 2 layers : where is my mistake ?

Thank you,

Laurent

Comments

  • edited November -1

    Hi Laurent,

    This is not the full code. Without the missing part, I am not able to really answer this question. I guess there is a "add_missing_layers" or something like this later on.

    Without this and there should be one layer only.

    Matthias

  • edited November 2017

    Matthias,

    Here is the full code, the 3 layers I need are set between the lines 389 and 430.

    Thanks, Best regards,

    Laurent

    #
    # This program is free software; you can redistribute it and/or modify
    # it under the terms of the GNU General Public License as published by
    # the Free Software Foundation; either version 2 of the License, or
    # (at your option) any later version.
    #
    # This program is distributed in the hope that it will be useful,
    # but WITHOUT ANY WARRANTY; without even the implied warranty of
    # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    # GNU General Public License for more details.
    #
    # DESCRIPTION: dice count : gross die , yield estimation and wafermap
    #
    # Run the script with
    #   klayout -rm gross_die.rbm ...
    # or put the script as "gross_die.rbm" into the installation path (on Unix for version <=0.21:
    # set $KLAYOUTPATH to the installation folder).
    #
    # def wafermap(layout_name, layout_X, layout_Y, scribe_X, scribe_Y, waf_diam, waf_typ, PEE, defectsE, alphaE, l)
    
    include RBA
    
    $gross_die2 = MenuAction.new( "Gross die / Yield 2", "" ) do 
    
        dialog = QDialog.new(Application.instance.main_window)
        dialog.windowTitle = "WAFER & DIE characteritics"
        layout = QVBoxLayout::new(dialog)
        dialog.setLayout(layout)
    
    ### Die name
        label = QLabel.new(dialog)
        layout.addWidget(label)
        label.text = "Enter the die or project name :"
        layout_name = QLineEdit.new(dialog)
        layout.addWidget(layout_name)
        label = QLabel.new(dialog)
        layout.addWidget(label)
        label.text = "\n"
    
    ### Layout width : X
        label = QLabel.new(dialog)
        layout.addWidget(label)
        label.text = "Enter the layout width X (mm) :"
        layout_X = QLineEdit.new(dialog)
        layout.addWidget(layout_X)
    
    ### Layout heigth : Y
        label = QLabel.new(dialog)
        layout.addWidget(label)
        label.text = "Enter the layout heigth Y (mm) :"
        layout_Y = QLineEdit.new(dialog)
        layout.addWidget(layout_Y)
    
    ### Scribe width : X
        label = QLabel.new(dialog)
        layout.addWidget(label)
        label.text = "Enter the scribe width X (mm) :"
        scribe_X = QLineEdit.new(dialog)
        layout.addWidget(scribe_X)
        scribe_X.text = "0.1"
    
    ### Scribe heigth : Y
        label = QLabel.new(dialog)
        layout.addWidget(label)
        label.text = "Enter the scribe heigth Y (mm) :"
        scribe_Y = QLineEdit.new(dialog)
        layout.addWidget(scribe_Y)
        scribe_Y.text = "0.1"
    
    ### Wafer diameter
        label = QLabel.new(dialog)
        layout.addWidget(label)
        label.text = "Enter the wafer diameter (mm) / (inches)"
        waf_diam = QComboBox.new(dialog)
        waf_diam.addItem("50 mm / 2 \" ")
        waf_diam.addItem("75 mm / 3 \" ")
        waf_diam.addItem("100 mm / 4 \" ")
        waf_diam.addItem("125 mm / 5 \" ")
        waf_diam.addItem("150 mm / 6 \" ")
        waf_diam.addItem("200 mm / 8 \" ")
        waf_diam.addItem("300 mm / 12 \" ")
        waf_diam.addItem("450 mm / 18 \" ")
        # waf_diam.setSizeAdjustPolicy(QComboBox::AdjustToContents)
        waf_diam.setCurrentIndex(5)  # default wafer size = 200mm
        layout.addWidget(waf_diam)
    
    ### Wafer type : P-100
        label = QLabel.new(dialog)
        layout.addWidget(label)
        label.text = "Enter the wafer type"
        waf_typ = QComboBox.new(dialog)
        waf_typ.addItem("N-100")
        waf_typ.addItem("N-111")
        waf_typ.addItem("P-100")
        waf_typ.addItem("P-111")
        layout.addWidget(waf_typ)
        # waf_typ.setSizeAdjustPolicy(QComboBox::AdjustToContents)
    
    ### Edging loss of the wafer
        label = QLabel.new(dialog)
        layout.addWidget(label)
        label.text = "Enter the edging loss (mm) :"
        PEE = QLineEdit.new(dialog)
        layout.addWidget(PEE)
        PEE.text = "3"
    
    ### defects / cm^2
        label = QLabel.new(dialog)
        layout.addWidget(label)
        label.text = "Enter the defects density D0 (/cm^2) :"
        defectsE = QLineEdit.new(dialog)
        layout.addWidget(defectsE)
        defectsE.text = "0.12"
    
    ### measure of manufacturing process complexity
        label = QLabel.new(dialog)
        layout.addWidget(label)
        label.text = "Enter the manufacturing process complexity :"
        alphaE = QLineEdit.new(dialog)
        layout.addWidget(alphaE)
        alphaE.text = "2.5"
    
    # OK button
            buttonOK = QPushButton.new(dialog)
            layout.addWidget(buttonOK)
            buttonOK.text = " OK "
            buttonOK.clicked do
                if (layout_X.text.to_f == 0.0)
                    confirm = RBA::MessageBox.info("WRONG INPUTS !!!","Set the layout width X", RBA::MessageBox.b_ok + RBA::MessageBox.b_cancel)
                    if confirm == RBA::MessageBox.b_cancel
                        raise "Operation aborted"
                    end
                elsif (layout_Y.text.to_f == 0.0)
                    confirm = RBA::MessageBox.info("WRONG INPUTS !!!","Set the layout heigth Y", RBA::MessageBox.b_ok + RBA::MessageBox.b_cancel)
                    if confirm == RBA::MessageBox.b_cancel
                        raise "Operation aborted"
                    end
                else
                    dialog.accept()
                end
            end
    
        dialog.exec  # input data
    
        app = RBA::Application.instance
        for l in (1 .. 16) do
    
        ### Input data from string to float
            xlayout = layout_X.text.to_f  
            ylayout = layout_Y.text.to_f
            xscribe = scribe_X.text.to_f
            yscribe = scribe_Y.text.to_f
            PE = PEE.text.to_f
            defects = defectsE.text.to_f
            alpha = alphaE.text.to_f
    
            if (waf_diam.currentText() == "50 mm / 2 \" ")
                diameter = 50.8
                OFL = 15.88         ## Wafer primary slice length
                CFL = 8.0           ## Length of the secondary side of the wafer
                RE  = 2.0           ## Resist damage on the side of the wafer
                thick = 279
            end
            if (waf_diam.currentText() == "75 mm / 3 \" ")
                diameter = 76.2
                OFL = 22.22
                CFL = 11.18
                RE  = 2.0
                thick = 381
            end
            if (waf_diam.currentText() == "100 mm / 4 \" ")
                diameter = 100.0
                OFL = 32.5
                CFL = 18.0
                RE  = 2.0
                thick = "525 or 625"
            end
            if (waf_diam.currentText() == "125 mm / 5 \" ")
                diameter = 125.0
                OFL = 42.5
                CFL = 27.5
                RE  = 2.0
                thick = 625
            end
            if (waf_diam.currentText() == "150 mm / 6 \" ")
                diameter = 150.0
                OFL = 57.5
                CFL = 37.5
                RE  = 2.0
                thick = 675
            end
            if (waf_diam.currentText() == "200 mm / 8 \" ")
                diameter = 200.0
                OFL = 0.0
                CFL = 0.0
                RE  = 0.1
                thick = 725
            end
            if (waf_diam.currentText() == "300 mm / 12 \" ")
                diameter = 300.0
                OFL = 0.0
                CFL = 0.0
                RE  = 0.1
                thick = 775
            end
            if (waf_diam.currentText() == "450 mm / 18 \" ")
                diameter = 450.0
                OFL = 0.0
                CFL = 0.0
                RE  = 0.1
                thick = 925
            end
    
    ### Define common constants
        PI = 3.14159
        sqrt2 = Math::sqrt(2)
        lne = 2.7183
        inchtomm = 25.4
        radius = diameter / 2.0
    
        height = xlayout + xscribe
        width  = ylayout + yscribe
    
    ### Formula One round in the die landed calculated the number of ways to calculate the diagonal
    ### Formula1 refer to Anderson School at UCLA
        DieCount1 = 0
        h = height
        w = width
        if (h > w)
            h = width
            w = height
        end
        diam_eff = diameter - 2*PE - RE
    
        if (w < diameter)
            rowmax = (Math::sqrt(diam_eff ** 2 - w ** 2) / h).to_i - 2
            columax = (Math::sqrt(diam_eff ** 2 - h ** 2) / w).to_i
    
            for row in (1..rowmax) do
                columns = (Math::sqrt((diam_eff ** 2) - (row * h) ** 2) / w).to_i
                DieCount1 = DieCount1 + columns
            end
        end
    
    ### Formula 2 is calculated in terms of area and remove the edge of the die number
    ### Formula 2 refers to www.cse.psu.edu/~mji 
        diearea = height * width
        PreCount = PI * (diameter - 2*PE - RE) ** 2 / diearea / 4.0
        Margin = PI * (diameter - 2*PE - RE) / Math::sqrt(2 * diearea)
        DieCount2 = (PreCount - Margin).round
    
    ### Formula 3 is Wikipedia calculation method
        DieCount3 = (PreCount * Math::exp( -2 * Math::sqrt(diearea) / diearea)).round
    
    ### Formula 4 is Wikipedia calculation method
        DieCount4 = (PreCount * (1 - 2 * Math::sqrt(diearea) / diearea) ** 2).round
    
    ### Formula 5 is Wikipedia calculation method
        DieCount5 = (PreCount - 0.58 * sqrt2 * Margin).round
    
    ### Formula 6 is Wikipedia calculation method
        DieCount6 = (PreCount * Math::exp( -2.32 * Math::sqrt(diearea) / diearea)).round
    
    ### Formula 7 is Wikipedia calculation method
        DieCount7 = (PreCount * (1 - 1.16 * Math::sqrt(diearea) / diearea) ** 2).round
    
    ### Formula 8 is TSMC calculation method
        DieCount8 = (PI * (diameter / 2.0 - 0.24 * (h + w) - PE - RE) ** 2 / diearea).round
    
    ### Four yield models formula
        NegBinYield  = 100.0 *(1.0 +(defects * diearea * 1e-2) / alpha) **(alpha * -1.0)
        PoissonYield = 100.0 * 1.0 /(lne **(diearea * 1e-2 * defects))
        MurphyYield  = 100.0 *((1.0 -(lne **(-1.0 * diearea * 1e-2 * defects))) /(diearea * 1e-2 * defects)) ** 2
        SeedYield    = 100.0 * 1.0 /(lne ** Math::sqrt(diearea * 1e-2 * defects))
    
            if (waf_typ.currentText() == "N-100")
                OFR = radius - Math::sqrt(radius ** 2.0 -(OFL/2.0) ** 2)
                CFR = radius - Math::sqrt(radius ** 2.0 -(CFL/2.0) ** 2)
                cutOFR = (OFR / h + 1.0).round
                cutCFR45 = 0.0
                cutCFR90 = 0.0
                cutCFR180 = (CFR / w +1).round
            end
            if (waf_typ.currentText() == "N-111")
                OFR = radius - Math::sqrt(radius ** 2.0 -(OFL/2.0) ** 2)
                CFR = radius - Math::sqrt(radius ** 2.0 -(CFL/2.0) ** 2)
                cutOFR = (OFR / h + 1.0).round
                cutCFR45 = 1.0
                cutCFR90 = 0.0
                cutCFR180 = 0.0
            end
            if (waf_typ.currentText() == "P-100")
                OFR = radius - Math::sqrt(radius ** 2.0 -(OFL/2.0) ** 2)
                CFR = radius - Math::sqrt(radius ** 2.0 -(CFL/2.0) ** 2)
                cutOFR = (OFR / h + 1.0).round
                cutCFR45 = 0.0
                cutCFR90 = (CFR / w + 1.0).round
                cutCFR180 = 0.0
            end
            if (waf_typ.currentText() == "P-111")
                OFR = radius - Math::sqrt(radius ** 2.0 -(OFL/2.0) ** 2)
                cutOFR = (OFR / h +1.0).round
                cutCFR45 = 0.0
                cutCFR90 = 0.0
                cutCFR180 = 0.0
            end
    
    
            if (l == 1)
                dx = 0.0
                dy = 0.0
            end
            if (l == 2)
                dx = 0.0
                dy = 0.25
            end
            if (l == 3)
                dx = 0.0
                dy = 0.5
            end
            if (l == 4)
                dx = 0.0
                dy = 0.75
            end
            if (l == 5)
                dx = 0.25
                dy = 0.0
            end
            if (l == 6)
                dx = 0.25
                dy = 0.25
            end
            if (l == 7)
                dx = 0.25
                dy = 0.5
            end
            if (l == 8)
                dx = 0.25
                dy = 0.75
            end
            if (l == 9)
                dx = 0.5
                dy = 0.0
            end
            if (l == 10)
                dx = 0.5
                dy = 0.25
            end
            if (l == 11)
                dx = 0.5
                dy = 0.5
            end
            if (l == 12)
                dx = 0.5
                dy = 0.75
            end
            if (l == 13)
                dx = 0.75
                dy = 0.0
            end
            if (l == 14)
                dx = 0.75
                dy = 0.25
            end
            if (l == 15)
                dx = 0.75
                dy = 0.5
            end
            if (l == 16)
                dx = 0.75
                dy = 0.75
            end
    
    ### Draw the wafer
        mw = app.main_window
    
    #  create a new layout 
        # layout_view = mw.create_layout( (l).to_i )
        mw.create_layout( 1 )
        layout_view = mw.current_view
    
    ###  create a new layer in that layout
        # cv = layout_view.cellview(0).create
        # layout = cv.layout 
        layout = layout_view.active_cellview.layout 
        layout1 = layout_view.active_cellview.layout 
        layout_view.set_config("background-color", "0xFFFFFF")
    
    ###  create a layer view for the wafer
        linfo1 = RBA::LayerInfo.new(1,0)
        linfo1.name = "wafer"
        layer_id = layout.insert_layer( linfo1 )
        ln1 = RBA::LayerPropertiesNode::new
        ln1.source_layer_index = layer_id
        ln1.dither_pattern = 1
        # ln.fill_color = 0xFFFFFF
        ln1.frame_color = 0x000000
        ln1.name = "wafer"
        ln1.width = 3
        layout_view.insert_layer( layout_view.end_layers, ln1 )
    
    ###  create a layer view for the safe area
        linfo2 = RBA::LayerInfo.new(2,0)
        linfo2.name = "safe_area"
        # linfo2.layer = 2
        # linfo2.datatype = 0
        layer_id2 = layout.insert_layer( linfo2 )
        ln2 = RBA::LayerPropertiesNode::new
        ln2.source_layer_index = layer_id2
        ln2.dither_pattern = 1
        # ln2.fill_color = 0xFFFFFF
        ln2.frame_color = 0x00FF00
        ln2.name = "safe_area"
        ln2.width = 1
        layout_view.insert_layer( layout_view.end_layers, ln2 )
    
    ###  create a layer view for the die
        linfo3 = RBA::LayerInfo.new(3,0)
        linfo3.name = "die"
        # linfo3.layer = 3
        # linfo3.datatype = 0
        layer_id3 = layout.insert_layer( linfo3 )
        ln3 = RBA::LayerPropertiesNode::new
        ln3.source_layer_index = layer_id3
        ln3.dither_pattern = 1
        # ln3.fill_color = 0xFFFFFF
        ln3.frame_color = 0xFF0000
        ln3.name = "die"
        ln3.width = 2
        layout_view.insert_layer( layout_view.end_layers, ln3 )
    
    ###  create a top cell
        wafer = layout.add_cell( "wafer_#{l}" )
        dbu = 1.0/layout.dbu
        RPE = radius - (RE + PE)
    
    ### convert to micron
        radius  *= 1000.0 * dbu
        RPE     *= 1000.0 * dbu
        xlayout *= 1000.0 * dbu
        ylayout *= 1000.0 * dbu
        xscribe *= 1000.0 * dbu
        yscribe *= 1000.0 * dbu
    
    ### draw wafers
        pts = []
        n = 128
        da = Math::PI * 2 / n
        if ((waf_diam.currentText() == "200 mm / 8 \" ") || (waf_diam.currentText() == "300 mm / 12 \" ") || (waf_diam.currentText() == "450 mm / 18 \" "))
            n.times do |i|
                if (i==0)
                    pts.push(Point.from_dpoint(DPoint.new(radius * Math::sin(i * da) + 1000*dbu, - radius * Math::cos(i * da))))
                else
                    pts.push(Point.from_dpoint(DPoint.new(radius * Math::sin(i * da), - radius * Math::cos(i * da))))
                end
            end
            pts.push(Point.from_dpoint(DPoint.new(- 1000*dbu, - radius)))  # draw the wafer notch
            pts.push(Point.from_dpoint(DPoint.new(- 1000*dbu, - radius + 1000*dbu)))
            pts.push(Point.from_dpoint(DPoint.new(0, - radius + 1500*dbu)))
            pts.push(Point.from_dpoint(DPoint.new(+ 1000*dbu, - radius + 1000*dbu)))
        else
            flat = 0
            n.times do |i|
                if ((- Math::cos(i * da) > 0) || (radius * Math::sin(i * da) > OFL*500*dbu) || (radius * Math::sin(i * da) < -OFL*500*dbu))
                    if ((waf_typ.currentText() == "N-111") && ((i * da) < (Math::asin((OFL*500*dbu) / radius) + 2 * Math::asin((CFL*500*dbu) / radius))))
                        if (flat==0)
                            theta = Math::asin((OFL*500*dbu) / radius) + 2 * Math::asin((CFL*500*dbu) / radius)
                            pts.push(Point.from_dpoint(DPoint.new( radius * Math::sin(theta), - radius * Math::cos(theta))))
                        end
                        flat = 1
                    elsif ((waf_typ.currentText() == "P-100") && (Math::sin(i * da) > 0) && (radius * Math::cos(i * da) < CFL*500*dbu) && (radius * Math::cos(i * da) > -CFL*500*dbu))
                        flat = 1
                    elsif ((waf_typ.currentText() == "P-111") && (- Math::cos(i * da) > 0) && (radius * Math::sin(i * da) < CFL*500*dbu) && (radius * Math::sin(i * da) > -CFL*500*dbu))
                        flat = 1
                    else
                        pts.push(Point.from_dpoint(DPoint.new(radius * Math::sin(i * da), - radius * Math::cos(i * da))))
                    end
            end
        end
            pts.push(Point.from_dpoint(DPoint.new(-OFL*500*dbu, - Math::sqrt(radius**2 - (OFL*500*dbu)**2 ))))
            pts.push(Point.from_dpoint(DPoint.new( OFL*500*dbu, - Math::sqrt(radius**2 - (OFL*500*dbu)**2 ))))
        end
        layout.cell(wafer).shapes(layer_id).insert(Polygon.new(pts))
    
    ### draw the safe circle
        RPE = radius - PE * 1000.0 * dbu
        pts = []
        n.times do |i|
            pts.push(Point.from_dpoint(DPoint.new(RPE * Math::cos(i * da), RPE * Math::sin(i * da))))
        end
        layout.cell(wafer).shapes(layer_id2).insert(Polygon.new(pts))
    
    ### line function   Calculating an angle of 45 N-111 Cutaway
        linem = 1
        lineb1 = - radius * sqrt2
        lineb2 = sqrt2 * (radius - Math::sqrt(radius**2 - (CFL/2.0)**2))
        lineb = lineb1 + lineb2
        R0x = 0.0
        R0y = linem * R0x + lineb
        R1y = 0.0
        R1x = (R1y - lineb) / linem
    
        P2 = -1
        DieCount = 0
        row_min = cutOFR.to_i
        row_max = (rowmax - cutCFR180 + 2).to_i
        col_max = (columax - cutCFR90 + 1).to_i
    
        for j in (-row_max..row_max) do
            for i in (-col_max..col_max) do
                gBLx = (i + dx) * (xlayout + xscribe) + (xscribe/2.0)
                gBLy = (j + dy) * (ylayout + yscribe) + (yscribe/2.0)
                gTRx = (i + dx + 1) * (xlayout + xscribe) - (xscribe/2.0)
                gTRy = (j + dy + 1) * (ylayout + yscribe) - (yscribe/2.0)
    
    ### point inside wafer  Calculation falls in the circle die
                ptdisc1 = Math::sqrt(gBLx**2 + gBLy**2)
                ptdisc2 = Math::sqrt(gTRx**2 + gTRy**2)
                ptdisc3 = Math::sqrt(gBLx**2 + gTRy**2)
                ptdisc4 = Math::sqrt(gTRx**2 + gBLy**2)
    
    ### in angle 45     45 Ø cutting angle calculation die within
                if (cutCFR45 == 1)
                    Rnx = gBLx
                    Rny = gBLy
                    P0 = (R1x-Rnx) * (R0y-Rny)
                    P1 = (R0x-Rnx) * (R1y-Rny)
                    P2 = P0-P1
                end
    
    ### create die rectangle - Create die in the cellview
                if (ptdisc1<RPE && ptdisc2<RPE && ptdisc3<RPE && ptdisc4<RPE && P2<0)
                    layout.cell(wafer).shapes(layer_id3).insert(Box.new(gBLx,gBLy,gTRx,gTRy))
                    DieCount += 1
                end
            end     # for i
        end         # for j
    
    ### Add text on the layout
        txt_size = (radius / 50 / dbu).round.to_s  # set the text display size proportional to the wafer radius
        layout_view.set_config("default-text-size", txt_size)
    
        string = "Die / project name :  #{layout_name.text}"
        layout.cell(wafer).shapes(layer_id3).insert(RBA::Text::new(string, RBA::Trans::new(radius * 1.1, radius * 0.95)))
        layout_size = xlayout * ylayout / 1000000 / dbu / dbu
        string = "Layout size : #{layout_X.text} x #{layout_Y.text} = #{'%.2f' %layout_size} mm2"
        layout.cell(wafer).shapes(layer_id).insert(RBA::Text::new(string, RBA::Trans::new(radius * 1.1, radius * 0.84)))
        string = "Scribe size :  X = #{scribe_X.text} :  Y #{scribe_Y.text}  mm"
        layout.cell(wafer).shapes(layer_id).insert(RBA::Text::new(string, RBA::Trans::new(radius * 1.1, radius * 0.76)))
        die_size = (xlayout+xscribe) * (ylayout+yscribe) / 1000000 / dbu / dbu
        string = "Die size : #{'%.3f' %(layout_X.text.to_f+scribe_X.text.to_f)} x #{'%.3f' %(layout_Y.text.to_f+scribe_Y.text.to_f)} = #{'%.2f' %die_size} mm2"
        layout.cell(wafer).shapes(layer_id3).insert(RBA::Text::new(string, RBA::Trans::new(radius * 1.1, radius * 0.68)))
        if (l==1)
            string = "Shift en X: center , en Y : center"
        end
        if (l==2)
            string = "Shift en X: 1/4width , en Y : center"
        end
        if (l==3)
            string = "Shift en X: 1/2width , en Y : center"
        end
        if (l==4)
            string = "Shift en X: 3/4width , en Y : center"
        end
        if (l==5)
            string = "Shift en X: center , en Y : 1/4height"
        end
        if (l==6)
            string = "Shift en X: 1/4width , en Y : 1/4height"
        end
        if (l==7)
            string = "Shift en X: 1/2width , en Y : 1/4height"
        end
        if (l==8)
            string = "Shift en X: 3/4width , en Y : 1/4height"
        end
        if (l==9)
            string = "Shift en X: center , en Y : 1/2height"
        end
        if (l==10)
            string = "Shift en X: 1/4width , en Y : 1/2hieght"
        end
        if (l==11)
            string = "Shift en X: 1/2width , en Y : 1/2height"
        end
        if (l==12)
            string = "Shift en X: 3/4width , en Y : 1/2height"
        end
        if (l==13)
            string = "Shift en X: center , en Y : 3/4height"
        end
        if (l==14)
            string = "Shift en X: 1/4width , en Y : 3/4height"
        end
        if (l==15)
            string = "Shift en X: 1/2width , en Y : 3/4height"
        end
        if (l==16)
            string = "Shift en X: 3/4width , en Y : 3/4hieght"
        end
        # string = "Die count : (method 1) =  #{DieCount1}"
        layout.cell(wafer).shapes(layer_id3).insert(RBA::Text::new(string, RBA::Trans::new(radius * 1.1, radius * 0.60)))
        string = "Die count : (method 2) =  #{DieCount2}"
        layout.cell(wafer).shapes(layer_id).insert(RBA::Text::new(string, RBA::Trans::new(radius * 1.1, radius * 0.54)))
        string = "Die count : (method 3) =  #{DieCount3}"
        layout.cell(wafer).shapes(layer_id).insert(RBA::Text::new(string, RBA::Trans::new(radius * 1.1, radius * 0.48)))
        string = "Die count : (method 4) =  #{DieCount4}"
        layout.cell(wafer).shapes(layer_id).insert(RBA::Text::new(string, RBA::Trans::new(radius * 1.1, radius * 0.42)))
        string = "Die count : (method 5) =  #{DieCount5}"
        layout.cell(wafer).shapes(layer_id).insert(RBA::Text::new(string, RBA::Trans::new(radius * 1.1, radius * 0.36)))
        string = "Die count : (method 6) =  #{DieCount6}"
        layout.cell(wafer).shapes(layer_id).insert(RBA::Text::new(string, RBA::Trans::new(radius * 1.1, radius * 0.30)))
        string = "Die count : (method 7) =  #{DieCount7}"
        layout.cell(wafer).shapes(layer_id).insert(RBA::Text::new(string, RBA::Trans::new(radius * 1.1, radius * 0.24)))
        string = "Die count : (method 8) =  #{DieCount8}"
        layout.cell(wafer).shapes(layer_id3).insert(RBA::Text::new(string, RBA::Trans::new(radius * 1.1, radius * 0.18)))
        string = "Die count : (counted) =  #{DieCount}  \nBest method: counted from the wafer map"
        layout.cell(wafer).shapes(layer_id2).insert(RBA::Text::new(string, RBA::Trans::new(radius * 1.1, radius * 0.08)))
        string = " NegBin Yield =  #{'%.2f' %NegBinYield} %"
        layout.cell(wafer).shapes(layer_id).insert(RBA::Text::new(string, RBA::Trans::new(radius * 1.1, radius * 0.00)))
        string = "Poisson Yield =  #{'%.2f' %PoissonYield} %"
        layout.cell(wafer).shapes(layer_id).insert(RBA::Text::new(string, RBA::Trans::new(radius * 1.1, radius * -0.07)))
        string = " Murphy Yield =  #{'%.2f' %MurphyYield} %"
        layout.cell(wafer).shapes(layer_id).insert(RBA::Text::new(string, RBA::Trans::new(radius * 1.1, radius * -0.14)))
        string = "   Seed Yield =  #{'%.2f' %SeedYield} %"
        layout.cell(wafer).shapes(layer_id).insert(RBA::Text::new(string, RBA::Trans::new(radius * 1.1, radius * -0.21)))
        good_die = ((NegBinYield+PoissonYield+MurphyYield)*(DieCount1+DieCount2+DieCount3+DieCount4+DieCount5+DieCount6+DieCount7+DieCount8+2*DieCount)/3000).round
        string = "Expected good die / wafer = #{good_die}\n\nDepending on design, layout and test margins,\nfoundry defects density D0 and process complexity"
        layout.cell(wafer).shapes(layer_id3).insert(RBA::Text::new(string, RBA::Trans::new(radius * 1.1, radius * -0.43)))
        string = "Foundry defects density =  #{defectsE.text} /cm^2\nProcess complexity assumed : #{alphaE.text}"
        layout.cell(wafer).shapes(layer_id).insert(RBA::Text::new(string, RBA::Trans::new(radius * 1.1, radius * -0.55)))
        string = "Wafer size =  #{waf_diam.currentText()}"
        layout.cell(wafer).shapes(layer_id).insert(RBA::Text::new(string, RBA::Trans::new(radius * 1.1, radius * -0.65)))
        string = "Wafer type =  #{waf_typ.currentText()}"
        layout.cell(wafer).shapes(layer_id).insert(RBA::Text::new(string, RBA::Trans::new(radius * 1.1, radius * -0.75)))
        string = "Wafer safety edge =  #{'%.2f' %(RE + PE)} mm"
        layout.cell(wafer).shapes(layer_id2).insert(RBA::Text::new(string, RBA::Trans::new(radius * 1.1, radius * -0.85)))
        string = "Wafer thickness =  #{thick} um-typ"
        layout.cell(wafer).shapes(layer_id).insert(RBA::Text::new(string, RBA::Trans::new(radius * 1.1, radius * -0.95)))
      ### Text box : the third parameter : radius*2.2 need to be adjusted depending on your screen resolution : it adjust the box width
        layout.cell(wafer).shapes(layer_id).insert(Box.new(radius*1.05 , -radius*1.0 , radius*1.9 , radius*1.00))
    
    ### adjust layout view to fit the drawings
        layout_view.select_cell(wafer, 0)
        layout_view.update_content
        layout_view.add_missing_layers
        layout_view.zoom_fit
        layout_view.max_hier_levels=(2)
    
    ### Die count and Yield message
      # RBA::MessageBox::info("Die count and Yield", "Gross die (count1) = #{DieCount1}\nGross die (count2) = #{DieCount2}\nBest one from drawing: \nGross die (counted) = #{DieCount}\n\nNegBin  Yield #{'%.2f' %NegBinYield}%\nPoisson Yield #{'%.2f' %PoissonYield}%\nMurphy Yield #{'%.2f' %MurphyYield}%\nSeed     Yield #{'%.2f' %SeedYield}%", RBA::MessageBox::b_ok)
        end
    end
    
    ### add the command in the tools menu
    app = RBA::Application.instance
    mw = app.main_window
    
    menu = mw.menu
    #menu.insert_separator("tools_menu.end", "name")
    menu.insert_item("tools_menu.end", "gross_die2", $gross_die2)
    
  • edited November -1

    Hi Laurent,

    I do see the issue:

    layout_view.add_missing_layers
    

    Please omit this line and it should be fine.

    Here is the explanation:

    A layer view can be linked to a data layer by different ways. You picked "source_layer_index". This is fine for now, but it's not applicable in the general case. If the link way always like this, one could not do a "reload" because then the layer indexes may change. Hence the layer views usually use "semantic linking" which is through "source_layer" and "source_datatype". In this case, the views are linked to the data layers by means of invariant layer descriptions.

    "add_missing_layers" considers "semantic links" only. If you only have "source_layer_index" links, they are not considered for this update and new semantic links are created. That's what you observe.

    Matthias

Sign In or Register to comment.