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

[SKiDL BUG] tstamps/uuids not working correctly #238

Open
cyberhuman opened this issue Dec 30, 2024 · 1 comment
Open

[SKiDL BUG] tstamps/uuids not working correctly #238

cyberhuman opened this issue Dec 30, 2024 · 1 comment
Labels

Comments

@cyberhuman
Copy link

Describe the bug
When working on a bigger project with auto-assigned component references, I noticed that when re-importing the netlist into the KiCAD's PCB editor, it doesn't associate the existing symbols with the symbols in the netlist. I tried the Tags functionality but it didn't work (no change in behaviour), so I digged a bit and figured out it can't work in KiCAD8 (and maybe earlier versions) because it expects the following:

  1. in the (sheetpath .. (tstamps X)), the components of X must be UUIDs.
  2. there should be another (tstamps Y) as a sibling of the (sheetpath) node with the component UUID itself.

See the relevant source code here: https://gitlab.com/kicad/code/develop/-/blob/master/pcbnew/netlist_reader/kicad_netlist_reader.cpp#L442-473.
The sheetpath tstamps are KIID_PATH, which is a /-separated string of KIIDs, and the extra tstamps is a vector of KIIDs. A KIID is a wrapper for UUID which generates a random UUID if the constructor argument is not a valid UUID, which is what SKiDL currently writes.

To Reproduce
Steps to reproduce the behavior:

  1. use the code:
C = Part('Device', 'C', dest=TEMPLATE, footprint='Capacitor_SMD:C_0402_1005Metric')
C1 = C(value='10u', tag='C1')
C2 = C(value='4.7u', tag='C2')
  1. generate the netlist
  2. import the netlist into the KiCAD8's PCB editor
  3. change the code (swap lines with C1 and C2):
C = Part('Device', 'C', dest=TEMPLATE, footprint='Capacitor_SMD:C_0402_1005Metric')
C2 = C(value='4.7u', tag='C2')
C1 = C(value='10u', tag='C1')
  1. generate the netlist
  2. try to import the netlist into the KiCAD8's PCB editor and observe the behaviour:
    6.1. when the "Link footprints using reference designators" option is used, the footprints are swapped.
    6.2. when the "Link footprints using component tstamps (unique ids)" option is used, the existing footprints are removed and new footprints are added instead.

Expected behavior
When assigning a tag to a component, the component should get a valid stable UUID in the netlist.

Additional context
The following adhoc patch fixes the issue for me.
The namespace_uuid was generated using the genuuid command.
Note I don't really understand the semantics of the (sheetpath (tstamps ...)) and the (tstamps ...). The solution just generates stable UUIDs as expected by the PCB editor.

diff --git a/src/skidl/tools/kicad8/gen_netlist.py b/src/skidl/tools/kicad8/gen_netlist.py
index 7f878868..517c0754 100644
--- a/src/skidl/tools/kicad8/gen_netlist.py
+++ b/src/skidl/tools/kicad8/gen_netlist.py
@@ -8,12 +8,15 @@ Generate KiCad 5 netlist.
 
 import os.path
 import time
+import uuid
 
 from skidl.pckg_info import __version__
 from skidl.scriptinfo import scriptinfo
 from skidl.utilities import add_quotes, export_to_all
 
 
+namespace_uuid = uuid.UUID("7026fcc6-e1a0-409e-aaf4-6a17ea82654f")
+
 def gen_netlist_comp(part):
     """Generate the netlist text describing a component.
 
@@ -39,7 +42,11 @@ def gen_netlist_comp(part):
     # Embed the hierarchy along with a random integer into the sheetpath for each component.
     # This enables hierarchical selection in pcbnew.
     hierarchy = add_quotes("/" + part.hierarchical_name.replace(HIER_SEP, "/"))
-    tstamps = hierarchy
+    tstamps = "/".join([
+        str(uuid.uuid5(namespace_uuid, component))
+        for component in part.hierarchical_name.split(HIER_SEP)
+    ])
+    tstamps_uuid = uuid.uuid5(namespace_uuid, hierarchy)
 
     fields = ""
     for fld_name, fld_value in part.fields.items():
@@ -59,7 +66,7 @@ def gen_netlist_comp(part):
         + "      (footprint {footprint})\n"
         + "{fields}"
         + "      (libsource (lib {lib_filename}) (part {part_name}))\n"
-        + "      (sheetpath (names {hierarchy}) (tstamps {tstamps})))"
+        + "      (sheetpath (names {hierarchy}) (tstamps {tstamps})) (tstamps {tstamps_uuid}))"
     )
     txt = template.format(**locals())
     return txt
@cyberhuman cyberhuman added the bug label Dec 30, 2024
@devbisme
Copy link
Owner

devbisme commented Jan 4, 2025

Thanks for your bug report and your "adhoc" solution. I intend to incorporate it into the next release.

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