how to use script to run DRC?

Hi All,

I only know how to use GUI to run DRC, then save as the DRC report.
May I know how to use script to run DRC in terminal? for example, use for loop to check DRC for 10 GDS files and save the separate reports.
Then when finish, I can check one by one?
Another question is how to use script to check DRC for different CELL in one GDS, for example, one GDS contains 5 CELLs and I want to check them separately, and generate different report?

Thanks.

Shawn

Comments

  • Hi Shawn,

    the way I do it is to use KLayout in batch mode and configure DRC with variables taken from the command line.

    For example, in your DRC deck (e.g. "run.drc") you specify a source and report this way:

    source($input)
    report("DRC report", $output)
    ...
    

    Then you run KLayout with this deck in batch mode and pass "input" and "output" by defining script variables:

    klayout -b -r run.drc -rd input=input_file.gds -rd output=drc_for_input_file.lyrdb
    

    If you want to pick a specific cell from the input layout, you can use one more variable - i.e. "cellname":

    source($input, $cellname)
    report("DRC report", $output)
    ...
    

    Matthias

  • This looks like it should be paragraph 1, chapter 1 of the Klayout DRC Developer's Cookbook.

    If we had one.

  • Hi @Matthias ,

    Thank you very much!

    One more question.
    In the GUI, I can use

        cv = RBA::CellView::active
        cv.name
        cv.cell_name
    

    to get GDS file name without path, and the cell name in the GDS.

    When I
    source($input)
    How can I get the GDS file name without path, and the cell name in the GDS?

    Thank you very much!

    Shawn

  • Hi Shawn

    For the file without path use the Ruby toolbox:

    filename_without_path = File.basename($input)
    

    For the cell name use

    source.cell_name
    

    Matthias

  • Hi @Matthias ,

    Thank you very much!

    Shawn

  • Hi Matthias,
    Sorry , more question for this topic.
    As normally , we have many DRC command , such 1.lydrc / 2.lydrc
    Can we call another DRC command in DRC ?
    such as picture shown...

  • edited December 2020

    Hi,

    well, that's actually harder than it looks. There is a forum entry where I explain the topic: https://www.klayout.de/forum/discussion/comment/6738#Comment_6738

    The problem is basically that DRC is based on Ruby which (like Python) is a modern language. It incorporates concepts such as AST compilation and compile unit-local namespaces. Although this is nice and good it makes partitioning of big serial chunks of code difficult.

    In 0.27 I am proposing a pre-processor extension which adds a special feature to DRC scripts. This feature allows including other files through a simple pseudo-comment like this:

    # %include file_to_include.drc
    

    This will however only work for scripts executed within KLayout and debugging will be tedious outside KLayout because external debuggers will only see the expanded file.

    Matthias

  • Hi Matthias,
    firstly , I want to try to paste my code in the below , and change the format as a code ,
    hope it is workable to let you see what my code...

    # %include file_to_include.drc
    include_file = File.join(File.dirname(__FILE__), "DRC_width_loop.lydrc")
    instance_eval(File.read(include_file), include_file)
    

    second, as the attached file , I want to include (or "call" ) my DRC file .
    that file was named "DRC_width_loop.lydrc"
    but , I get a message as picture and didn't know what the issue happen
    Could you please help ?

  • Hi Matthias,
    please let me explain more detail for the request...
    this is our DRC command file for 1 of part.(the DRC named "psv1.lydrc)
    and I also shown "PKG-8.lydrc " which is the DRC command we have to "call " or "include"
    Cause we have to run "PGK-8.lydrc" in first ,to output layer 1000/1.... then go to check other rule in the first DRC command .(psv1.lydrc)
    we also need to call (include) other DRC command , that is why I asking for the function.
    and as the picture below , I got some error message , please help it...
    Thanks very much~

    # %include file_to_include.drc
    include_file = File.join(File.dirname(__FILE__), "PKG-8.lydrc")
    instance_eval(File.read(include_file), include_file)
    
        psv1=input(301,0)
        tiv=input(1,5)
        outline=input(0,7)
        outline1=input(1000,1)
        outline2=input(1000,2)
        psv1size=10.1.um
        psv1_pith=input(300,1)
        psv1_pith_space=20.um
        psv1_space=112.7.um
        tiv_enc_psv1_size=10.um
    

    this is what the DRC command in PKG-8.lydrc

    layer=input(73,1)
    layer.extent_refs(0.0,0.45,0.27,1.0).output(1000,1)
    layer.extent_refs(0.25,0.45,0.5,1.0).output(1000,2)
    layer.extent_refs(0.48,0.45,0.75,1.0).output(1000,3)
    layer.extent_refs(0.73,0.45,1.0,1.0).output(1000,4)
    

  • @jiunnweiyeh

    "lydrc", "lym" ... are XML formats which KLayout understands but not Ruby or Python. KLayout will use the XML attributes to store meta information such as where and how to show the script in the menu.

    In order to "load" a file, it needs to be in plain text (.drc).

    And please remove the "# %include ..." comment - it will confuse KLayout in the next release.

    Matthias

  • Hi Matthias
    Got it , it is work , Thanks very much for your help.

  • Hi Matthias,
    one more question , if the text file location at network , such as below.
    \obu3pie-nas01\OBU3PIE_Presonal_Databackup\Mask\sample
    how to make file.join to link it?

    include_file = File.join(File.dirname(__FILE__), "PKG-8.lydrc")

  • edited December 2020

    @jiunnweiyeh

    I usually don't see issues with "File.join" or "File.dirname" with proper paths, even on Windows network drives. The network path should be a valid UNC path however which is starting with a double backslash, like \\nas\Personal\....

    Matthias

  • Hi @Matthias ,

    May I know is it possible that we run drc check in windows system batch mode?
    currently in Windows CMD, I can use following command to run
    C:\Users\user1\Downloads>C:\Klayout\klayout-0.26.9-win64\klayout_app.exe -r C:\Users\user1\KLayout\drc\DRC.lydrc test.gds

    The KLayout GUI will start and check the GDS.
    However if I add -b option, it will not run. is it possible we add -b option to make it run at background?

    Thank you very much!

  • @TryAndTry In batch mode you cannot give a file as an argument because there is no GUI to load it into.

    You also need to specify where to write the report or output layout to.

    You can pass this information from the command line using variables. This is how I do it:

    In the DRC:

    if $input && $output
      source($input)
      report($output)   # or target($output) for writing layouts 
    end
    
    ... your DRC code ...
    

    This is how you call this script in batch mode:

    klayout -b -r your_drc.drc -rd input=input_file.gds -rd output=output_file
    

    Matthias

  • Do you have an example where the rules don't have the lyrdc xml header, but just simply a Ruby file? If so how would I import all the K-Layout DRC methods into such a Ruby runset?

    klayout -b -r your_drc.rb -rd input=input_file.gds -rd output=output_file

    ERROR: undefined method `input' for main:Object
    /home/you/drc/your_drc.rb

  • It's sufficient to use ".drc" suffix for the file. KLayout will automatically detect such files are using DRC notation.

    Matthias

  • Hi Jim,

    Here a complete xml file compatible with in-line execution :

    <?xml version="1.0" encoding="utf-8"?>
    <klayout-macro>
     <description/>
     <version/>
     <category>drc</category>
     <prolog/>
     <epilog/>
     <doc/>
     <autorun>false</autorun>
     <autorun-early>false</autorun-early>
     <priority>0</priority>
     <shortcut/>
     <show-in-menu>true</show-in-menu>
     <group-name>drc_scripts</group-name>
     <menu-path>tools_menu.drc.end</menu-path>
     <interpreter>dsl</interpreter>
     <dsl-interpreter-name>drc-dsl-xml</dsl-interpreter-name>
     <text>########################
    # 1000nm  DRC
    ########################
    
    tstart = Time.now
    
    # input / output files defnition
    #################################
    # optionnal for a batch launch :   klayout -b r this_exmple.lydrc -rd in_gds=my_layout.gds -rd topcell=your_topcell -rd report_file=tech1000nm_drc.lydrc
    if $in_gds
      if $topcell
        source($in_gds,$topcell)
      else
        source($in_gds)
      end
    end
    
    if $report_file
      report("1000nm 1P3M DRC runset", $report_file)
    else
      report("1000nm 1P3M DRC runset", File.join(File.dirname(RBA::CellView::active.filename), "tech1000nm_drc.lydrc"))
    end
    
    # options
    ########################
    DFM  = false
    
    # KLAYOUT setup
    ########################
    # Use a tile size of 1mm
    tiles(1000.um)
    # Use a tile border of 10 micron:
    tile_borders(10.um)
    #no_borders
    
    # hierarchical
    deep
    
    # Use 4 CPU cores
    threads(4)
    verbose(true)
    
    # layers definitions
    ########################
    info("Layers definitions")
    METAL1 = input(1,0)
    METAL2 = input(2,0)
    
    # DRC section
    ########################
    info("DRC section")
    
    ### Metal 1
    METAL1.ongrid(0.005).output("M1_offgrid", "Offgrid vertex on METAL1")
    if DFM
        METAL1.width(1.5,euclidian).output("DFM_M1_width", "Min. Metal1 width : 1.5um")
        M1.space(1.5,euclidian).output("DFM_M1_space", "Min. Metal1 spacing : 1.5um")
    else
        METAL1.width(1.0,euclidian).output("M1_width", "Min. Metal1 width : 1.0um")
        METAL1.space(1.0,euclidian).output("M1_space", "Min. Metal1 spacing : 1.0um")
    end
    
    ### Metal 2
    METAL2.ongrid(0.005).output("M2_offgrid", "Offgrid vertex on METAL2")
    if DFM
        METAL2.width(1.5,euclidian).output("DFM_M2_width", "Min. Metal2 width : 1.5um")
        METAL2.space(1.5,euclidian).output("DFM_M2_space", "Min. Metal2 spacing : 1.5um")
    else
        METAL2.width(1.0,euclidian).output("M2_width", "Min. Metal2 width : 1.0um")
        METAL2.space(1.0,euclidian).output("M2_space", "Min. Metal2 spacing : 1.0um")
    end
    
    # DRC time calculation
    ########################
    time = Time.now
    hours = ((time - tstart)/3600).to_i
    minutes = ((time - tstart)/60 - hours * 60).to_i
    seconds = ((time - tstart) - (minutes * 60 + hours * 3600)).to_i
    $stdout.write "DRC finished at : #{time.hour}:#{time.min}:#{time.sec}  -  DRC duration =  #{hours} hrs. #{minutes} min. #{seconds} sec.\n"
    </text>
    </klayout-macro>
    

    I prefer to use in_gds and report_file namings, because they are compatible with the names used in the OpenROAD flow scripts.

    I you use the klayout in gui, i.e. not in command mode, then you only have to copy the lines between and .

    I also included the constant DFM that you can also define as an in-line parameter if you prefer.

    BRgds,

    Laurent

Sign In or Register to comment.