It looks like you're new here. If you want to get involved, click one of these buttons!
I'm debugging a issue with LVS results where I am seeing an undesired behavior in the LVS compare when the topology matches, but the pin names are incorrect or swapped. I want to detect this case where pins are incorrectly labeled, either as a LVS compare failure, or as some other property that can be accessed during the LVS script execution. I'm at a loss as to where to look for this information and I haven't intentionally enabled swapping in my LVS deck. My KLayout version is a self-built 0.27.11 in case that matters. I can recreate this issue using the Github LVS sample on the NAND gate "ND2X1" layout by taking the following steps:
The LVS result clearly shows the pins as swapped. How can I make this case fail, or detect swapped pins in the result?
Comments
Hi @barlow,
The LVS is basically name agnostic and does a topological match. It finds - correctly - that the topology matches. What it also finds is, that what is called "A" in the schematic is called "B" in the layout and vice versa.
By default, LVS does not require name identity of the pins. It will only use names for hints in case of ambiguities (symmetry).
You can require net names to match using "same_nets!", i.e.
or for all (named) nets:
You can also request name matching on all circuits and all (named) nets by using
Matthias
Thank you for your response!
I understand topologically everything is correct, but the problem that I run into is when I'm integrating these cells as subcells in a larger schematic/layout. In those cases, my "A" and "B" pins being swapped on a NAND gate will result in an error at the higher level, as then the topology will be wrong. While I haven't tried troubleshooting this type of error in KLayout, I would prefer to be proactive and ensure that the pin names in the layout match the pin names in the schematic.
I didn't realize the "same_nets!" command could operate on wildcards, that's great to know. However, when I insert the "same_nets!" command on line 113 of the si4all.lvs script I get an error:
I get the exact same error no matter where in the script I place the command, or if I use the actual cell and pin names. I've included where it is in my version below copied directly. Do you have any ideas on what I might have done wrong?
Two problems (or more) I think.
First the NAND gate needs to be botom-up correct
all by itself. Seems that's not the case (initially at least).
Then if higher level assemblies mis-follow the
connectivity and call a pin-swap, that must then be
another class of problem. But NAND has a topological
difference between A and B legs that should be clean
to follow.
I might suggest that LVS debug could always use
some "assistance". In this case I believe that terminal
mismatch should be clearly presented in the "top level
error summary report" along with other classes of
mismatch and with whatever clues can be delivered
about what's the nature of the beef.
To be clear, the provided design on GitHub is correct as provided. I am changing the labels in the layout to help demonstrate the issue that I'm having, where a bottom-up verification scheme "fails" because the labels aren't treated as a rigid constraint.
From a verification perspective, I would be happy if I got an error whenever the number of pins in SPICE don't match the labels in GDS, if the pin names aren't identical, and if the circuit topology (independent of labeling) matches but the labels don't match.
Curious whether the klayout LVS understands pin-permute
and has support for permute rules for pins (which ones
can swap - like regular MOS would always have
permuteParallel rule for S and D, but an asymmetric
(drain-extended / annular / LDMOS) would not allow S/D
swapping).
In the NAND2 (and other flat combo logic) case, differences
in path delay & threshold might be considered "trivial" per
the library developers and allowed to swap those specific pins.
Might look to that, in the ND2X1 contexts (instance and
rules) to see if the swap is flagged for hookup at the low
level (by actual layout false swapping) but then "blessed"
by this kind of "overlay" rule that "fixes" legit swaps.
Hi @barlow,
I am afraid 0.27.11 is far too old. Do you have a chance to try on a later version?
Matthias
And regarding the the question of @dick_freebird:
As you say, a CMOS gate is not symmetric, but if you wire the pins correctly on upper levels, the topology matches and the labels do not matter.
But it is possible to treat the inputs symmetric and enable swapping to allow more freedom in the wiring. To do you, you have to declare pins equivalent for specific gates where you want to allow this.
The feature is described here: https://www.klayout.de/doc-qt5/manual/lvs_compare.html#h2-255. The keyword is "equivalent_pins".
Matthias
@Matthias I did some playing around with versions to see if it might have been something we did with our build process, and I tested several versions. I think I already tested more than I needed, and I'd probably be better served at this point to dig into the source repository if it was really necessary.
I think (for me) upgrading is probably the simplest path for getting this to work. Thanks for your help.
@Matthias So in trying out the
same_nets!("*", "*")
function, I have run into a new issue - now all nets must have names matching in both the schematic and layout. I suppose that result is not too surprising considering the wildcards. The desired behavior is to allow any unnamed layout net to match any net in the schematic, while requiring the (named) ports to match.The NAND2 gate still works as an example, as there is an unnamed node in the series NFET chain. In the SPICE netlist, this is given as node 1. I added the well/substrate tie to the layout to prevent spurious warnings to the layout:
The match fails on comparing layout net $I3 to schematic net 1 presumably due to the net name issue. For reference, without the
same_nets!("*", "*")
function I get a passing result.I tried
same_nets!("*", "$*", "*", "*")
in the hopes that I could form a wildcard net filter that matches all nets that are unlabeled, but this no longer catches incorrect pins. I think either the automatic layout nets that start with a "$" always can be addressed by that name, or I can't run the command after labels have been applied. I'm trying to make this generic to any circuit, but I don't see how to grab the top-level pin names from either the schematic or layout to make the "*" more specific. Any advice on how to proceed?I'm running version 0.29.1 now for reference.
A brief addendum, I tried seeing if I could iterate through the schematic nets to mark which nets can match "anything" and those that can't. Using the
nets_by_name("*")
andNet.is_internal?
I can iterate through the netlist and differentiate between internal and external nodes. I think I've got a lead on the matching with the following code blurb:I have yet to try this on a hierarchal design, but this works on my NAND2 example
Hi @barlow,
Yes, your solution makes sense.
However, I just checked my code. I though that
*
would match named nets only, but that is not strictly the case. It matches the "given" name which is empty in case of unnamed nets. As*
also matches empty strings, it will also apply to unnamed nets.So I think the solution is simply to use
Then, the match requirement should apply to named nets only.
I think I can change the behavior internally. Selecting unnamed nets by name does not really make sense.
Matthias
I stand corrected. The solution above isn't working right now as it will either select schematic nets or layout nets - the schematic nets are always named, hence "?*" will still select all nets.
I have opened a ticket (https://github.com/KLayout/klayout/issues/1719) to fix the behavior of
same_nets!("*", "*")
together with other topics.Thanks for bringing up this issue.
Matthias
That is an insidious edge case for the wildcards.
I tried out the
same_nets!("*", "?*")
bit. I found out that this works roughly as expected, but fails when the schematic net name has only 1 character. In practice, this might not be a big deal but false positives are such a pain to work through that I think I won't use that right now.I need to amend my previous segment, I found that the
Nets.is_internal?
query returns true only if there are no connected pins and the number of terminals is exactly two, which I didn't notice. Going back through the iterate method, I've adjusted the "Check if internal" query to be simplyNets.pin_count == 0
.@barlow,
yes, you're right .. "internal" means it is connecting two device terminals and nothing else. If you wonder what this is good for: internal nets connect devices in a serial fashion, so they can be combined (i.e. two resistors).
I hope, the fix for https://github.com/KLayout/klayout/issues/1719 will provide a more reasonable and intuitive behavior more compatible with other (and non-agnostic) tools.
Matthias