Expand net finding to include Power Ports and Net Labels, Hijack find_connected_wires for this purpose

master
Aaron Goldstein 2020-05-22 17:20:23 -07:00
parent cbe42461b1
commit c39f4375cf
1 changed files with 46 additions and 28 deletions

View File

@ -3,8 +3,9 @@ import olefile
import re import re
import json import json
import copy import copy
import math
import logging as lg import logging as lg
lg.basicConfig(level=lg.INFO) lg.basicConfig(level=lg.DEBUG)
def parse(input, format, **kwargs): def parse(input, format, **kwargs):
fullPath = input fullPath = input
@ -77,29 +78,34 @@ def determine_parts_list(schematic):
return parts_list return parts_list
def determine_net_list(schematic): def determine_net_list(schematic):
wires = [ record for record in schematic["records"] if record["RECORD"] == "27" ] _, wires = find_record(schematic, key="RECORD", value="27")
pins = [ record for record in schematic["records"] if record["RECORD"] == 2 ] _, pins = find_record(schematic, key="RECORD", value="2")
_, labels = find_record(schematic, key="RECORD", value="25")
_, power_ports = find_record(schematic, key="RECORD", value="17")
devices = wires + pins + labels + power_ports
p = re.compile('^(?P<prefix>X)(?P<index>\d+)$') p = re.compile('^(?P<prefix>X)(?P<index>\d+)$')
for wire in wires: for device in devices:
coord_name_matches = [x for x in [p.match(key) for key in wire.keys()] if x] # if a Pin, do some fancy geometry math
wire['coords'] = [ ( int(wire['X' + match.group('index')]) , int(wire['Y' + match.group('index')]) ) if device["RECORD"] == "2":
rotation = (int(device["PINCONGLOMERATE"]) & 0x03) * 90
device['coords'] = [[
int(int(device['LOCATION.X']) + math.cos(rotation / 180 * math.pi) * int(device['PINLENGTH'])),
int(int(device['LOCATION.Y']) + math.sin(rotation / 180 * math.pi) * int(device['PINLENGTH']))
]]
# if a Wire, follow inconsistent location key names (X1 vs LOCATION.X, etc..)
elif device["RECORD"] == "27":
coord_name_matches = [x for x in [p.match(key) for key in device.keys()] if x]
device['coords'] = [ ( int(device['X' + match.group('index')]) , int(device['Y' + match.group('index')]) )
for match in coord_name_matches ] for match in coord_name_matches ]
# everything else, just convert the location values to ints
else:
device['coords'] = [(int(device['LOCATION.X']), int(device['LOCATION.Y']))]
nets = [] nets = []
for wire in wires: for device in devices:
if wire["index"] not in [id for net in nets for id in net]: if device["index"] not in [d['index'] for net in nets for d in net]:
nets.append(find_connected_wires(wire, [], schematic)) nets.append(find_connected_wires(device, devices, [], schematic))
_, pins = find_record(schematic, key="RECORD", value="2")
for net in nets:
for wire in net:
for vertex in wire['coords']:
for pin in pins:
if ( vertex[0] == int(pin['LOCATION.X'])
and vertex[1] == int(pin['LOCATION.Y']) ):
lg.debug('found pin {0} on net {1}'.format(pin, net))
schematic["nets"] = nets schematic["nets"] = nets
@ -129,8 +135,8 @@ def find_record(schematic, key, value, record=None, visited=None, found=None):
return visited, found return visited, found
def find_connected_wires(wire, visited, schematic): def find_connected_wires(wire, devices, visited, schematic):
neighbors = find_neighbors(wire, schematic) neighbors = find_neighbors(wire, devices, schematic)
lg.debug('entering: {0}'.format(wire['index'])) lg.debug('entering: {0}'.format(wire['index']))
if wire['index'] not in [w['index'] for w in visited]: if wire['index'] not in [w['index'] for w in visited]:
@ -139,7 +145,7 @@ def find_connected_wires(wire, visited, schematic):
for neighbor in neighbors: for neighbor in neighbors:
lg.debug('trying: {0} of {1}'.format(neighbor['index'], [x['index'] for x in neighbors])) lg.debug('trying: {0} of {1}'.format(neighbor['index'], [x['index'] for x in neighbors]))
visited = find_connected_wires(neighbor, visited, schematic) visited = find_connected_wires(neighbor, devices, visited, schematic)
lg.debug('visited = {0}'.format([w['index'] for w in visited])) lg.debug('visited = {0}'.format([w['index'] for w in visited]))
else: else:
lg.debug('skipping: {0} already in list {1}'.format(wire['index'], [w['index'] for w in visited])) lg.debug('skipping: {0} already in list {1}'.format(wire['index'], [w['index'] for w in visited]))
@ -147,8 +153,8 @@ def find_connected_wires(wire, visited, schematic):
lg.debug('returning: {0}'.format(wire['index'])) lg.debug('returning: {0}'.format(wire['index']))
return visited return visited
def find_neighbors(wire, schematic): def find_neighbors(wire, devices, schematic):
all_wires = [record for record in schematic["records"] if record["RECORD"] == "27"] all_wires = devices
other_wires = [record for record in all_wires if record != wire] other_wires = [record for record in all_wires if record != wire]
neighbors = [] neighbors = []
@ -159,10 +165,18 @@ def find_neighbors(wire, schematic):
return neighbors return neighbors
def is_connected(wire_a, wire_b): def is_connected(wire_a, wire_b):
if wire_a["RECORD"] == "27":
a_line_segments = [(wire_a['coords'][i], wire_a['coords'][i + 1]) for i in a_line_segments = [(wire_a['coords'][i], wire_a['coords'][i + 1]) for i in
range(len(wire_a['coords']) - 1)] range(len(wire_a['coords']) - 1)]
else:
a_line_segments = [(wire_a['coords'][0], wire_a['coords'][0])]
if wire_b["RECORD"] == "27":
b_line_segments = [(wire_b['coords'][i], wire_b['coords'][i + 1]) for i in b_line_segments = [(wire_b['coords'][i], wire_b['coords'][i + 1]) for i in
range(len(wire_b['coords']) - 1)] range(len(wire_b['coords']) - 1)]
else:
b_line_segments = [(wire_b['coords'][0], wire_b['coords'][0])]
# check if any vertices in wire_a lie on wire_b # check if any vertices in wire_a lie on wire_b
for vertex in [vx for line in a_line_segments for vx in line]: for vertex in [vx for line in a_line_segments for vx in line]:
@ -184,6 +198,10 @@ def is_connected(wire_a, wire_b):
and (min(a_ys) <= vertex[1] <= max(a_ys))): and (min(a_ys) <= vertex[1] <= max(a_ys))):
return True return True
# check if both items are Power Ports with the same TEXT value
if ( wire_a["RECORD"] == "17" ) and ( wire_b["RECORD"] == "17" ) and ( wire_a["TEXT"] == wire_b["TEXT"] ):
return True
return False return False
def main(args): def main(args):