5 # Created PADS-PCB netlist file, for FreePCB at http://www.freepcb.com/ ,
6 # or any other PCB layout program that supports the PADS-PCB format.
10 PROGRAM_NAME
= "pads.py"
15 "R": "RC07", # 1/4 resistor
17 "sp3t": "SS14MDP2", # NKK switch
18 #"1N4148": "DO-35", # Diode
19 "D": "DO-35", # All diodes (note: should really be specific!)
22 # If enabled, RX$Xflipflop$XX<n>$Xinv$R{P,N} will be mapped to ${P,N}<n>.
23 # Useful for laying out a single dtflop-ms_test, but may cause serious
25 SHORT_DTFLOP_RP_RN
= False
27 # TODO: remove these limitations on FreePCB, so that
28 # USE_SHORT_NAMES and BREAK_LONG_LINES can be turned off!
30 # If true, reference designators and node names will be assigned
31 # sequentially, instead of using their hierarchical name
32 # from the net2 file. Some PCB programs have length limits
33 # on reference designators (FreePCB).
34 USE_SHORT_NAMES
= True
36 # Split long nets over multiple lines.
37 BREAK_LONG_LINES
= True
39 # If not false, nodes with only one connection will have a
40 # testpoint attached, using the given footprint.
41 #NAKED_NODE_FOOTPRINT = "HOLE_100_RND_200"
42 NAKED_NODE_FOOTPRINT
= None
46 print """usage: %s input-filename [output-filename]
48 input-filename A chip-level SPICE netlist (.net2)
49 output-filename PADS-PCB layout netlist (.pads)
51 If output-filename is omitted, input-filename is used but
52 with a .pads extension instead of .net2, or .pads appended.
54 Either filenames can be "-" for stdin or stdout, respectively.
55 """ % (PROGRAM_NAME
, )
58 # MAX_NET_NAME_SIZE and FMAX_PIN_NAME_SIZE from
59 # svn://svn.berlios.de/freepcb/trunk/Shape.h and Netlist.h
60 # (TODO: remove these arbitrary limits in FreePCB)
64 # Names to preserve, if USE_SHORT_NAMES is True.
65 # Would be nice to preserve all/more net names, but
66 # some are just too long and hierarchical.
76 def shorten(long, is_netname
):
77 if not USE_SHORT_NAMES
:
80 if SHORT_DTFLOP_RP_RN
and long.startswith("RX$Xflipflop$XX"):
81 short
= long[len("RX$Xflipflop$XX"):][0]
82 if long.endswith("RP"):
84 elif long.endswith("RN"):
87 sys
.stderr
.write("dtflop RP/RN mapping enabled, but not RP/RN!")
91 if len(long) <= MAX_SIZE
:
92 # We got away with it this time.
95 # Resistors are what you have to watch our for
96 if long2short
.has_key(long):
97 short
= long2short
[long]
99 # id = first letter, 'R', etc.
100 # Net names get a prefix of "NX" (for node extended;
101 # the name was too long so it was shortened)
108 #sys.stderr.write("%s\n" % (long,))
109 short
= "%s%d" % (id, next_serial
[id])
110 long2short
[long] = short
115 if len(sys
.argv
) < 2:
117 filename
= sys
.argv
[1]
119 # Redirect stdout to output file
120 if len(sys
.argv
) > 2:
121 output_filename
= sys
.argv
[2]
123 output_filename
= filename
.replace(".net2", ".pads")
124 if output_filename
== filename
:
125 output_filename
= filename
+ ".pads"
126 if output_filename
!= "-":
127 sys
.stdout
= file(output_filename
, "wt")
130 print "*%s*" % (filename
, )
137 infile
= file(filename
, "rt")
138 for line
in infile
.readlines():
147 long_refdesg
= words
[0]
149 refdesg
= shorten(long_refdesg
, is_netname
=False)
152 if refdesg
[0] == 'V':
153 # Voltage sources only have two pins, other arguments
154 # may be PWL or other values (really one argument, but
155 # separated by spaces, so we'll see it as more than one).
156 args
= [args
[0], args
[1]]
159 for i
, long_arg
in enumerate(args
):
160 if long_arg
.startswith("NC_"):
166 #sys.stderr.write("-> %s" % (line,))
167 arg
= shorten(long_arg
, is_netname
=True)
169 if arg
not in nets
.keys():
172 nets
[arg
].append("%s.%s" % (refdesg
, i
+ 1))
177 parts
.append((refdesg
, model
))
179 # Map models to footprints
182 refdesg
, model
= part
183 if footprint_map
.has_key(model
):
184 package
= footprint_map
[model
]
185 elif footprint_map
.has_key(refdesg
[0]):
186 package
= footprint_map
[refdesg
[0]]
188 raise "Part name %s, model %s unknown, couldn't find in map: %s" % (refdesg
, model
, footprint_map
)
189 print "%s %s" % (refdesg
, package
)
191 # Nets with only one node get testpoints for free (also appends to parts list)
192 if NAKED_NODE_FOOTPRINT
:
193 for signal_name
, nodes
in nets
.iteritems():
195 testpoint
= "%s_tp" % (signal_name
,)
196 print "%s %s" % (testpoint
, NAKED_NODE_FOOTPRINT
)
197 nets
[signal_name
].append(testpoint
)
202 for signal
, pins
in nets
.iteritems():
203 print "*SIGNAL* %s" % (signal
,)
208 # Break lines every so many pins
209 # (would be nice if didn't have to do this)
217 # Print a newline at the end for picky layout programs (ExpressPCB)