Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Flat LVS OK and deep failing #1813

Closed
FatsieFS opened this issue Aug 1, 2024 · 4 comments
Closed

Flat LVS OK and deep failing #1813

FatsieFS opened this issue Aug 1, 2024 · 4 comments
Labels

Comments

@FatsieFS
Copy link

FatsieFS commented Aug 1, 2024

Need some help to change a LVS deck to be compatible with hierarchical LVS checking.
In testcase_deep.zip you can find the testcase I made for this case.
When I run lvs_Sky130 in the directory I get the following:

~/eda/Chips4Makers/test/testcase_deep$ ./lvs_Sky130 
Running flat LVS
Flat LVS OK
Running deep LVS
Deep LVS Failed!

I zipped the directory with the output files of the runs included.
This is a LVS deck automatically generated. Similar LVS decks are generated for all PDKs I support in project Arrakeen (see FSiC2024) and thus complementary to the upstream PDK ones.

@FatsieFS FatsieFS changed the title Flat LVS and deep failing Flat LVS OK and deep failing Aug 1, 2024
@klayoutmatthias
Copy link
Collaborator

Hi Staf,

that is a classic one.

The following happens:

The substrate is created as a large layer through "extent":

substrate__Sky130 = (extent.sized(0.34)-nwm)

later, the body connections for the NMOS devices are made to this layer through the "W" target (which is essentially a "connect" of the device pin shapes to the substrate__Sky130 layer):

extract_devices(mos4("sky130_fd_pr__nfet_01v8__model"), {
    "SD" => difftap__conn, "G" => gate__mosfet__nfet_01v8, "tG" => poly__conn, "W" => substrate__Sky130,
})

Now, when you extract in deep mode, the substrate layer is flat, because

  1. "extent" is a flat layer
  2. the golden rule of "first layer determines hierarchy" in "substrate - nwell"

So eventually you make a connection of devices inside the hierarchy (NMOS) to a flat layer upwards in the hierarchy.

This creates pins as one can see here:

image

With these pins, the buf_x1 subcircuits do not match the schematic which does not have these pins.

About the solutions

The first solution is to use a local "extent" for every cell - this creates a local boundary in every cell. However, the "sized" operation will spoil that again, because it merges. I do not really see the need for the size as it only participates in connect statements and everything relevant is included in "extent" already - even without "sized":

substrate__Sky130 = (extent("*")-nwm)

A better solution IMHO however is to use a global net. This reflects the physical nature of a (non-SOI) substrate which is "below everything" - i.e. also connecting islands inside nwell rings with the outside. To implement this, you need to substitute "substrate__Sky130" by a global net. Here is my patch for deep mode LVS:

  1. substrate__Sky130 becomes an empty layer
63c63
< substrate__Sky130 = polygons # empty layer, we will do a connect_global later
---
> substrate__Sky130 = (extent.sized(0.34)-nwm)
  1. As difftap__conn__psdm also contains the NMOS source/drains we need to extract the taps:
68d67
< difftap__conn__psub = difftap__conn__psdm-nwm
  1. We connect substrate__Sky130 to a new global "PSUB" net:
98c97
< connect_global(substrate__Sky130, "PSUB")
---
> connect(substrate__Sky130, extent.sized(0.34))
  1. We replace difftap__conn__psdm by difftap__conn__psub:
108c107
< connect(difftap__conn, difftap__conn__psub)
---
> connect(difftap__conn, difftap__conn__psdm)
  1. Finally difftap__conn__psub is also connected to the global "PSUB" net:
110c109
< connect_global(difftap__conn__psub, "PSUB")
---
> connect(difftap__conn__psdm, substrate__Sky130)

With this patch, the LVS also passes in deep mode.

Matthias

@FatsieFS
Copy link
Author

FatsieFS commented Aug 2, 2024

Thanks @klayoutmatthias for prompt and good support.
I assumed the name used in global net needed to be a net used in the layout indicated with labels and I didn't want restrict my deck to force use of specific name for the ground net.
I'll see if more questions pop up when I implement this, otherwise I'll close this issue when I've updated my LVS deck generation script.

@klayoutmatthias
Copy link
Collaborator

klayoutmatthias commented Aug 2, 2024

Hi Staf,

Of course, please feel free to raise questions :)

Actually, the name of the global net is just an identifier. You can basically create multiple global nets, and the identifier tells which one to use. You could even use "VSS", but I'd not advise to do so. KLayout does not consider nets with the same name connected by default, so you may get two nets with the same name. "PSUB" or anything like that is a better choice for the global net.

As you connect "VSS" physically to the "PSUB" substrate (ties included, very good :) ), the net names will be joined and the result is a new name like "VSS,PSUB". KLayout LVS (mostly) does not care about net names, so it will happily match this net to "VSS" from the schematic.

Best regards,

Matthias

@FatsieFS
Copy link
Author

I do think it is clear now how to fix this so closing this issue.
New #1935 has been created though that still seems to be failing for deep LVS even when following guidelines from this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants