Files
lab-rv32i-freertos-c-queue/vendor/Hazard3/scripts/extract_ref_nets
T

80 lines
2.4 KiB
Python
Executable File

#!/usr/bin/env python3
# Turn KiCad netlist into a PCF file for icestorm
import argparse
import re
import shlex
from collections import OrderedDict
def sanitize_net_name(s):
s = s.replace("~", "")
s = re.sub(r"(\d+)$", r"[\1]", s)
return s
def natural_key(s):
return tuple(int(x) if x.isdigit() else x for x in re.split(r"(\d+)", s))
def extract_nets(fh, ref, filters):
nets = []
name = None
namevalid = False
for l in fh:
m = re.match(r"^\s*\(net \([^\)]*\) \(name ([^\)]+)\)", l)
if m:
name = m.group(1).strip().strip("/").lower()
namevalid = not any(name.startswith(s) for s in [
"\"net", "+", "-", "gnd", "vcc", "vdd", "vss", *filters
])
elif namevalid:
m = re.match(r"^\s*\(node \(ref ([^\)]+)\) \(pin ([^\)]+)\)", l)
if m and m.group(1) == ref:
nets.append((name, m.group(2)))
return nets
def align_buses(nets):
buses = OrderedDict()
onets = []
# First figure out what is/isn't a bus
for net in nets:
if "[" in net[0]:
busname = net[0].split("[")[0]
if busname not in buses:
buses[busname] = []
buses[busname].append(net)
else:
onets.append(net)
# Then right-justify the buses
for busname, bus in buses.items():
indices = list(int(net[0].split('[')[1].strip(']')) for net in bus)
lsb = min(indices)
for index, net in zip(indices, bus):
onets.append(("{}[{}]".format(busname, index - lsb), net[1]))
return onets
def write_pcf(fh, nets):
fh.write("# Generated with extract_ref_nets\n\n")
for name, loc in sorted(nets, key = lambda x: natural_key(x[0])):
fh.write("set_io {:<20} {}\n".format(name, loc))
def main():
parser = argparse.ArgumentParser(formatter_class=argparse.RawDescriptionHelpFormatter)
parser.add_argument("netfile", help="Path to KiCad .net file")
parser.add_argument("ref", help="Component reference whose named nets will be extracted")
parser.add_argument("--output", "-o", help="Output file name")
parser.add_argument("--filters", "-f", help="-f \"abc xyz\": filter out nets beginning with abc or xyz")
args = parser.parse_args()
opath = "chip.pcf" if args.output is None else args.output
filters = [] if args.filters is None else shlex.split(args.filters)
with open(args.netfile) as ifile:
nets = extract_nets(ifile, args.ref, filters)
nets = map(lambda n: (sanitize_net_name(n[0]), n[1]), nets)
nets = align_buses(nets)
with open(opath, "w") as ofile:
write_pcf(ofile, nets)
if __name__ == "__main__":
main()