Unsure why LVS is reporting mismatch

I'm trying to get LVS up and running for the first time, but I'm having some difficulty.

I'm using the LVS rule deck from here: https://github.com/laurentc2/FreePDK45_for_KLayout/tree/cb22893f1bf15cabcfe156182a055b4882874f99

The LVS deck is at lvs/lvs_freepdk45.lylvs. The unit test source GDS is at INV/INV.gds, and the reference schematic is at INV/INV.cir. I am running on the cell INV.

When I run the script, I get a mismatch:

It looks like all the pins are matching, but the transistors are not. I'm having trouble understanding why. Is it because the terminal names are in a different case ("gnd" vs. GND)? If so, where is "GND" coming from? "gnd" appears lowercase in both the reference schematic and the source GDS labels.

Version: KLayout 0.26.8
OS: CentOS 6

Thanks,
Austin

Comments

  • Hi Austin,

    first of all, the match is not case sensitive.

    There are two possibilities:

    • The transistor models are not matched
    • The W parameter is not matching (I don't see the one from the first column)

    In your case I assume the first, because - unless you tell LVS otherwise - models are matched by name. And "PMOS_VTG" is not the same name than "PMOS_GVT".

    Please try to consistently rename "PMOS_GVT" to "PMOS_VTG" and the same for "NMOS_.." (.cir and .lvsdb). I think this should make it match.

    Kind regards,

    Matthias

  • edited October 30

    🤦‍♂️
    I'm not sure how many times I've looked at that and didn't notice the typo. I fixed the reference circuit and everything matches, thanks!

    As a follow-up question, I have a different inverter INV_X1. The PDK provided the following schematic:

    .SUBCKT INV_X1 A ZN VDD VSS
    *.PININFO A:I ZN:O VDD:P VSS:G
    *.EQN ZN=!A
    M_i_0 ZN A VSS VSS NMOS_VTL W=0.415000U L=0.050000U
    M_i_1 ZN A VDD VDD PMOS_VTL W=0.630000U L=0.050000U
    .ENDS
    

    The devices are extracted with:

    active_in_nwell = active & nwell
    pactive    = active_in_nwell & pplus
    ntie       = active_in_nwell & nplus
    pgate      = pactive & poly
    psd        = pactive - pgate
    lv_pgate   = pgate - vtg - thkox
    
    active_in_pwell = active & pwell
    nactive    = active_in_pwell & nplus
    ptie       = active_in_pwell & pplus
    ngate      = nactive & poly
    nsd        = nactive - ngate
    lv_ngate   = ngate - vtg - thkox
    
    extract_devices(mos4("PMOS_VTL"), { "SD" => psd, "G" => lv_pgate, "tS" => psd, "tD" => psd, "tG" => poly, "W" => nwell, "tB" => nwell })
    extract_devices(mos4("NMOS_VTL"), { "SD" => nsd, "G" => lv_ngate, "tS" => nsd, "tD" => nsd, "tG" => poly, "W" => pwell, "tB" => pwell })
    

    However, LVS reports a mismatch, with S and D terminals flipped:

    I tried modifying the reference circuit to explicitly use substrate and well:

    .SUBCKT INV_X1 A ZN VDD VSS NWELL SUBSTRATE
    *.PININFO A:I ZN:O VDD:P VSS:G
    *.EQN ZN=!A
    M_i_0 ZN A VSS NWELL NMOS_VTL W=0.415000U L=0.050000U
    M_i_1 ZN A VDD SUBSTRATE PMOS_VTL W=0.630000U L=0.050000U
    .ENDS
    

    And LVS reports a match (although the terminals are still flipped):

    Is there a way to configure LVS to report a match using the unaltered PDK schematic? I am hoping that I don't have to modify the schematic for every cell :smile:. For reference, these cells do not have well ties in them (the well ties are in a separate cell). I have tried adding the connections using:

    connect_global(pwell, "VSS")
    connect_global(nwell, "VDD")
    connect_global(bulk, "VSS")
    

    Thanks!

  • edited October 30

    Austin, sorry for the error on Github, I also corrected it.

    To fix the substrate node, I am using 2 tricks :

    connect_global(pwell, "VSS")
    connect_global(nwell, "VDD")
    connect_global(bulk, "VSS")
    

    and

    connect_implicit("AND2_X1" , "VDD")
    connect_implicit("AND2_X1" , "VSS")
    connect_implicit("AND2_X2" , "VDD")
    connect_implicit("AND2_X2" , "VSS")
    connect_implicit("AND2_X4" , "VDD")
    . . .
    

    for all the cells of the library (see my repository on Github) to implicitly connect inside each cell VSS node to pwell, and VDD node to nwell.
    Then, you don't need to modify your netlist.

    BUT, it only works on KLayout 0.27 released after October 10th , from : http://www.klayout.org/downloads/master/

    BRgds,
    Laurent

  • Hi Laurent,

    You were right - the version number is important here. I didn't see version 0.27 on the downloads page (https://www.klayout.de/build.html) or GitHub Releases so I did not know it existed!

    I am seeing a full match with version 0.27. Thanks!

  • Hmm, there seems to be a new issue present in version 0.27, though. With the .lyt file for FreePDK45, it doesn't seem to remap layers from DEF correctly.

    In version 0.27, there is a giant box on via8 (26/0) placed over the entire design:

    In version 0.26.8, the layers are mapped correctly (no box):

    I think the OUTLINE (235/0) layer is getting mapped to via8 (26/0) improperly. The pin layers also look improperly mapped.

  • Please be careful ... 0.27 is just "master" and it's still under development.

    LEF/DEF has received a major rework (e.g. to support MASK). If you can point me to the .lyt file I'll take a look.

    Regards,

    Matthias

  • Matthias,
    I also got the problem with that .lyt file :
    https://github.com/laurentc2/FreePDK45_for_KLayout/blob/master/FreePDK45.lyt

    Laurent

  • Thanks :)

    @rovinski I do not fully understand why the 0.26 does it correctly in your case, but I can say that FreePDK45.lyt does not provide any layer mapping for DEF. 0.27 and 0.26 do layer mapping slightly differently, but without a proper LEF/DEF reader setup, neigther one will be correct.

    In order to properly set up LEF/DEF layer mapping, one needs to specify explicit GDS layer/datatypes. Otherwise KLayout will assign some by itself.

    Datatypes are managed by the purpose for the mask geometry layers (metal, etc.). In this case, a generic mapping is sufficient, like "M1 -> 11/0". Marker layers like "OUTLINE" need to be mapped explicit. The difference is that 0.27 will give OUTLINE a GDS layer while 0.26 doesn't. Maybe this creates the differences.

    Anyway, here is an example (Tools / Manage Technologies -> Reader Options, LEF/DEF page):

    This says, that OUTLINE will be mapped to 235/0 ("OUTLINE (235/0)"). In addition, M1 is basically mapped to 11/0 ("Selected layers or layer mapping": "M1 : 11/0"). V1, M2, ... are not shown here but should also be included. The datatypes for this mapping are provided by translating the purpose (routing and via geometry -> 0, pins -> 2 etc.).

    So please check your setup and maybe you wish to contribute a DEF/LEF enhanced .lyt version for Laurent's project :)

    Kind regards,

    Matthias

  • Hi Matthias,

    Thanks, and sorry for the confusion. I am using a slightly different .lyt file than Laurent, which does have the mappings in it:
    https://github.com/The-OpenROAD-Project/OpenROAD-flow-scripts/blob/872b051431ebb04f9def5b9b965b7469a81be387/flow/platforms/nangate45/FreePDK45.lyt#L24

    I can also provide an input file if you need it.

    Best,
    Austin

  • edited November 16

    Hi Austin,

    I see what's wrong .. or better: what can be improved in the new implementation.

    The LEF/DEF layer generation is actually pretty complex and that's why in 0.27 there can be mapping file which takes away this complexity but needs to specify all layers you wish to import.

    Anyway, the problem is the "OUTLINE" definition: actually, the LEF/DEF reader handles layers on two stages: first, it generates a layer - if you wish already with a layer / datatype specification. In the second stage, it runs the layers through the layer mapping. So if you enter a complete specification (including layer / datatype) as shown above ("OUTLINE (235/0)"), the layer mapping table will not need to specify anything for OUTLINE. This was the anticipated use model.

    In your case, you assign layer / datatype in the layer mapping. This isn't wrong and frankly it feels pretty natural. This path however doesn't work in the new implementation - if you want, you can call this a bug. But I think the original behaviour can be restored. Thanks for bringing up this use case.

    And yes, test cases are always welcome!

    Thanks and best regards,

    Matthias

Sign In or Register to comment.