skidl icon indicating copy to clipboard operation
skidl copied to clipboard

Regex on Part pins causes confusion

Open jamesbowman opened this issue 7 years ago • 12 comments
trafficstars

When referring to pins by name, the regex interpretation causes confusion. I find it much clearer to refer to pins by name, rather than number. Is there a way of getting an exact match?

For example trying this part:

from skidl import *

j1 = Part('conn', 'USB_OTG')
print j1
print
print j1['D+']

As you can see, "D+" actually matches 5 pins!

 USB_OTG (): USB mini/micro connector
    Pin J1/1/VBUS/POWER-IN
    Pin J1/2/D-/PASSIVE
    Pin J1/3/D+/PASSIVE
    Pin J1/4/ID/PASSIVE
    Pin J1/5/GND/POWER-IN
    Pin J1/6/Shield/PASSIVE

[Pin J1/2/D-/PASSIVE, Pin J1/3/D+/PASSIVE, Pin J1/4/ID/PASSIVE, Pin J1/5/GND/POWER-IN, Pin J1/6/Shield/PASSIVE]

Yeah, I know I can write:

j1['^D\+$']

But that loses a lot of the clarity that I'm hoping to get from using SKiDL

jamesbowman avatar Feb 17 '18 17:02 jamesbowman

I'll try to implement some non-intrusive method of enabling/disabling the regex.

xesscorp avatar Feb 19 '18 19:02 xesscorp

IMO, the change should be intrusive - i.e. regexp matching should only be used through dedicated "search" APIs, and name lookups should be implemented using simple string comparison or even dictionary lookups.

I only use name matching interactively from a repl when initially searching for stuff. From my code, I only ever want to look up a pin/part by it's exact known name.

Implementing search and name-based getters separately also yields big performance gains when actually doing library searches, because the library loading code constantly checks if a part is already known by name... I experimented with this when initially checking out skidl, because searching the KiCAD library would take several minutes with python2 (with python3, it was quite a bit faster, but still too slow for interactive use). With string comparions, even with linear search it was then orders of magnitude faster (runtime was then bound by the shlex tokenizer).

chenz avatar Feb 19 '18 22:02 chenz

100% in agreement - was really surprising to get regex matching on signal names. To quote PEP 20:

explicit is better than implicit

jamesbowman avatar Feb 19 '18 23:02 jamesbowman

James, I changed the pin search to look for an exact, non-regex match first. If that fails, it will do a regex search. That should allow you to use the clearer pin names. It's checked into the master branch, but not on PyPi until I get conditional installs on PySpice working.

xesscorp avatar Feb 20 '18 04:02 xesscorp

Regex matching is helpful for certain chips like microcontrollers that have long pin names listing every possible function of a pin.

xesscorp avatar Feb 20 '18 04:02 xesscorp

Updated code to cure REGEX problem, however I have DIN connector with pin numbers A1 to A32 and B1 to B32. This connector has pin names SMA0 to SMA23, of which SMA19 to 23 are connected to NC. However ERC fails with "ERC ERROR: Pin conflict on net ADDR1: BIDIRECTIONAL pin 11/A1 of XC9572XL-W65/U1_1 <==> NO-CONNECT pin A3/SMA1 of W65Bus/CON1" and other similar messages. Netlist seems fine. Great piece of code by the way.

paulbonnett avatar Feb 27 '18 09:02 paulbonnett

Apologies ignore above, entirely my fault. Don't you just feel stupid sometimes!

paulbonnett avatar Feb 27 '18 10:02 paulbonnett

I also think it would be nice to be able to explicitly specify regex or non-regex, pin number or pin name. For example trying to match address pins on a DDR3 part will conflict with the first row of BGA balls.

mng2 avatar Nov 25 '19 03:11 mng2

This problem has been on my list for a long time! Thanks for bringing it back to my attention.

As a short-term solution, you can reference a pin by it's number through an attribute named "p" + pin number. For example:

ice40 = Part(lib='FPGA_Lattice.lib', name='ICE40HX8K-BG121')
pin_A1 = ice40.pA1

In the long term, maybe SKiDL could support attributes on each part that are restricted to pin numbers and names in both regex and non-regex versions so you could do things like this:

pin_A1 = ice40.p['A1']   # Matches pin number A1.
pin_A1 = ice40.rxp['A1']   # Matches any pin number containing 'A1'.
pin_A1 = ice40.n['A1']   # Matches any pin with the name A1.
pin_A1 = ice40.rxn['A1']   # Matches any pin with a name containing 'A1'.

Let me know if that would be an acceptable solution for the problem, or if you can think of a better solution.

xesscorp avatar Dec 02 '19 14:12 xesscorp

For my project I ended up renaming my DDR pins as ADDRx, so I was able to work around it. I do like your long-term idea though. Thanks for creating some really cool software!

mng2 avatar Dec 03 '19 06:12 mng2

Sorry you had to change pin names. But thanks for raising the issue and forcing me to think about it again!

xesscorp avatar Dec 03 '19 13:12 xesscorp

I posted something about this issue on the forum.

xesscorp avatar Jun 05 '20 17:06 xesscorp