def parse_net(self, args): """ Assembles a net from a list of junctions, segments, and labels. """ thisnet = Net(args) subdata = self.sub_nodes('J S A L Q B'.split()) # finish building thisnet for netpt in subdata['netpoint'][:]: # using a copy so that we can modify subdata['netpoint'] inside loop if netpt.point_id not in thisnet.points: thisnet.add_point(netpt) else: # oh yeah, a net can have a point more than once, because that # makes *great* sense. for point in netpt.connected_points: thisnet.points[netpt.point_id].add_connected_point(point) for comp in netpt.connected_components: thisnet.points[netpt.point_id].add_connected_component(comp) # update subdata['netpoint'] so that ref to netpt points to the # new combined point i = subdata['netpoint'].index(netpt) subdata['netpoint'][i] = thisnet.points[netpt.point_id] # yuck, passing in-band thisnet.ibpts = subdata['netpoint'] for pt_a, pt_b in subdata['segment']: thisnet.connect((subdata['netpoint'][pt_a - 1], subdata['netpoint'][pt_b - 1])) for annot in subdata['annot']: thisnet.add_annotation(annot) if '=' in annot.value: thisnet.add_attribute(*(annot.value.split('=', 1))) return ('net', thisnet)
def make_net(self, net): """ Construct an openjson net from an eagle net. """ points = {} # (x, y) -> NetPoint def get_point(x, y): """ Return a new or existing NetPoint for an (x,y) point """ if (x, y) not in points: points[x, y] = NetPoint('%da%d' % (x, y), x, y) out_net.add_point(points[x, y]) return points[x, y] out_net = Net(net.name) for segment in get_subattr(net, 'segment', ()): for wire in get_subattr(segment, 'wire', ()): out_net.connect((get_point(self.make_length(wire.x1), self.make_length(wire.y1)), get_point(self.make_length(wire.x2), self.make_length(wire.y2)))) for pinref in get_subattr(segment, 'pinref', ()): self.connect_pinref(pinref, get_point(*self.get_pinref_point(pinref))) return out_net
class NetTests(unittest.TestCase): """ The tests of the core module net feature """ def setUp(self): """ Setup the test case. """ self.net = Net('001') def tearDown(self): """ Teardown the test case. """ pass def test_create_new_net(self): """ Test the creation of a new empty net. """ assert self.net.net_id == '001' def test_bounds_simple(self): '''Make sure bounds() uses all the included NetPoints''' for (x, y) in ((1, 3), (3, 2), (4, 3), (3, 5)): net_pt = NetPoint(str((x, y)), x, y) self.net.add_point(net_pt) # NetPoints don't actually need to be connected to affect bounds() top_left, btm_right = self.net.bounds() self.assertEqual(top_left.x, 1) self.assertEqual(top_left.y, 2) self.assertEqual(btm_right.x, 4) self.assertEqual(btm_right.y, 5)
def calc_nets(self, design, segments): """ Return a set of Nets from segments """ coord2point = {} # (x, y) -> NetPoint def get_point(coord): """ Return a new or existing NetPoint for an (x,y) point """ coord = (int(coord[0]), int(coord[1])) if coord not in coord2point: coord2point[coord] = NetPoint('%da%d' % coord, coord[0], coord[1]) return coord2point[coord] # use this to track connected pins not yet added to a net self.make_pin_points(design, get_point) # set of points connected to pins pin_points = set(coord2point.itervalues()) # turn the (x, y) points into unique NetPoint objects segments = set((get_point(p1), get_point(p2)) for p1, p2 in segments) nets = [] # Iterate over the segments, removing segments when added to a net while segments: seg = segments.pop() # pick a point newnet = Net('') map(pin_points.discard, seg) # mark points as used newnet.connect(seg) found = True while found: found = set() for seg in segments: # iterate over segments if newnet.connected(seg): # segment touching the net map(pin_points.discard, seg) # mark points as used newnet.connect(seg) # add the segment found.add(seg) for seg in found: segments.remove(seg) nets.append(newnet) # add single-point nets for overlapping pins that are not # already in other nets for point in pin_points: if len(point.connected_components) > 1: net = Net('') net.add_point(point) nets.append(net) for net in nets: net.net_id = min(net.points) nets.sort(key=lambda net : net.net_id) return nets
def test_write_net(self): """ The write_net method creates the correct kicad wires from an openjson net. """ net = Net('') p1 = NetPoint('p1', 0, 0) p2 = NetPoint('p2', 1, 0) p3 = NetPoint('p3', 0, 1) net.add_point(p1) net.add_point(p2) net.add_point(p3) net.conn_point(p1, p2) net.conn_point(p1, p3) writer = KiCAD() buf = StringIO() writer.write_net(buf, net) self.assertEqual( buf.getvalue(), 'Wire Wire Line\n\t0 0 0 ' + str(int(-1 / MULT)) + '\nWire Wire Line\n\t0 0 ' + str(int(1 / MULT)) + ' 0\n')
def test_bounds_all_elts(self): '''bounds() with all the elements competing''' net = Net('foo') mkbounds(net, 3, 3, -1, -2) self.des.add_net(net) annot = Annotation('foo', 3, 3, 0, True) mkbounds(annot, 3, 3, 3, 5) self.des.design_attributes.add_annotation(annot) libcomp = Component('bar') libcomp.add_symbol(Symbol()) libcomp.symbols[0].add_body(Body()) mkbounds(libcomp.symbols[0].bodies[0], 0, 0, 3, 3) self.des.add_component('foo', libcomp) compinst = ComponentInstance('bar', 'foo', 0) compinst.add_symbol_attribute(SymbolAttribute(3, 0, 0, False)) self.des.add_component_instance(compinst) top_left, btm_right = self.des.bounds() self.assertEqual(top_left.x, -1) self.assertEqual(top_left.y, -2) self.assertEqual(btm_right.x, 6) self.assertEqual(btm_right.y, 5)
def _get_point(self, net_id, point_id, x, y): if net_id not in self.nets: n = Net(net_id) self.design.add_net(n) self.nets[n.net_id] = n else: n = self.nets[net_id] key = (x, y) if key not in self.net_points: if not point_id: point_id = str(self._id) self._id += 1 np = NetPoint(net_id + '-' + point_id, x, y) n.add_point(np) self.net_points[key] = np else: np = self.net_points[key] return np
def test_bounds_neg_coords(self): '''Test bounds() when the schematic is all negative coordinates''' net = Net('foo') mkbounds(net, -1, -2, -3, -4) self.des.add_net(net) top_left, btm_right = self.des.bounds() self.assertEqual(top_left.x, -3) self.assertEqual(top_left.y, -4) self.assertEqual(btm_right.x, -1) self.assertEqual(btm_right.y, -2)
def parse_net(self, args): """ Assembles a net from a list of junctions, segments, and labels. """ thisnet = Net(args) subdata = defaultdict(list) for phrase in self.stream: print phrase cmd, _sep, args = phrase.partition(' ') if cmd not in ('J', 'S', 'A', 'L', 'Q', 'B'): self.stream.push(phrase) break print args k, v = self.parsenode(cmd)(args) subdata[k].append(v) # finish building thisnet for netpt in subdata['netpoint'][:]: # using a copy so that we can modify subdata['netpoint'] inside loop if netpt.point_id not in thisnet.points: thisnet.add_point(netpt) else: # oh yeah, a net can have a point more than once, because that # makes *great* sense. for point in netpt.connected_points: thisnet.points[netpt.point_id].add_connected_point(point) for comp in netpt.connected_components: thisnet.points[netpt.point_id].add_connected_component(comp) # update subdata['netpoint'] so that ref to netpt points to the # new combined point i = subdata['netpoint'].index(netpt) subdata['netpoint'][i] = thisnet.points[netpt.point_id] # yuck, passing in-band thisnet.ibpts = subdata['netpoint'] for pt_a, pt_b in subdata['segment']: thisnet.connect((subdata['netpoint'][pt_a - 1], subdata['netpoint'][pt_b - 1])) for annot in subdata['annot']: thisnet.add_annotation(annot) if '=' in annot.value: thisnet.add_attribute(*(annot.value.split('=', 1))) return ('net', thisnet)
def test_bounds_nets(self): '''Test bounds() with just the design's nets''' leftnet = Net('foo1') topnet = Net('foo2') rightnet = Net('foo3') botnet = Net('foo4') # limits minx=2, miny=1, maxx=7, maxy=9 mkbounds(leftnet, 2, 3, 3, 3) mkbounds(topnet, 3, 1, 3, 3) mkbounds(rightnet, 3, 3, 7, 3) mkbounds(botnet, 3, 3, 3, 9) self.des.add_net(topnet) self.des.add_net(rightnet) self.des.add_net(leftnet) self.des.add_net(botnet) top_left, btm_right = self.des.bounds() self.assertEqual(top_left.x, 2) self.assertEqual(top_left.y, 1) self.assertEqual(btm_right.x, 7) self.assertEqual(btm_right.y, 9)
def parse_nets(self, nets): """ Extract nets. """ for net in nets: net_id = net.get('net_id') ret_net = Net(net_id) # Add Annotations for annotation in net.get('annotations'): anno = self.parse_annotation(annotation) ret_net.add_annotation(anno) # Get the Attributes for key, value in net.get('attributes').items(): ret_net.add_attribute(key, value) # Get the Points for net_point in net.get('points'): npnt = self.parse_net_point(net_point) ret_net.add_point(npnt) self.design.add_net(ret_net)
def build_nets(self): """ Build the nets from the connects, points, and instances """ todo = set(self.connects) # set([(index, cid)]) points = {} # (x, y) -> NetPoint nets = [] def get_point(point): """ Return a new or existing NetPoint for an (x,y) point """ if point not in points: points[point] = NetPoint('%da%d' % point, point[0], point[1]) return points[point] def update_net(net, main_key): """ Update a net with a new set of connects """ todo.discard(main_key) main_point = get_point(self.points[main_key]) net.add_point(main_point) remaining = [] for conn_key in self.connects[main_key]: if conn_key in todo: remaining.append(conn_key) if conn_key in self.points: connect(net, main_point, get_point(self.points[conn_key])) elif conn_key[0] in self.component_instances: inst = self.component_instances[conn_key[0]] cpt_parser = self.components[inst.library_id] cpt_parser.connect_point(conn_key[1], inst, main_point) return remaining while todo: net = Net(str(len(nets))) nets.append(net) remaining = [todo.pop()] while remaining: remaining.extend(update_net(net, remaining.pop(0))) return nets
def calc_nets(self, segments): """ Return a set of Nets from segments """ points = {} # (x, y) -> NetPoint def get_point(point): """ Return a new or existing NetPoint for an (x,y) point """ point = (make_length(point[0]), make_length(point[1])) if point not in points: points[point] = NetPoint('%da%d' % point, point[0], point[1]) return points[point] # turn the (x, y) points into unique NetPoint objects segments = set((get_point(p1), get_point(p2)) for p1, p2 in segments) nets = [] # Iterate over the segments, removing segments when added to a net while segments: seg = segments.pop() # pick a point newnet = Net('') newnet.connect(seg) found = True while found: found = set() for seg in segments: # iterate over segments if newnet.connected(seg): # segment touching the net newnet.connect(seg) # add the segment found.add(seg) for seg in found: segments.remove(seg) nets.append(newnet) for net in nets: net.net_id = min(net.points) nets.sort(key=lambda net: net.net_id) return nets
def calc_nets(self, segments): """ Return a set of Nets from segments """ points = {} # (x, y) -> NetPoint def get_point(point): """ Return a new or existing NetPoint for an (x,y) point """ point = (make_length(point[0]), make_length(point[1])) if point not in points: points[point] = NetPoint('%da%d' % point, point[0], point[1]) return points[point] # turn the (x, y) points into unique NetPoint objects segments = set((get_point(p1), get_point(p2)) for p1, p2 in segments) nets = [] # Iterate over the segments, removing segments when added to a net while segments: seg = segments.pop() # pick a point newnet = Net('') newnet.connect(seg) found = True while found: found = set() for seg in segments: # iterate over segments if newnet.connected(seg): # segment touching the net newnet.connect(seg) # add the segment found.add(seg) for seg in found: segments.remove(seg) nets.append(newnet) for net in nets: net.net_id = min(net.points) nets.sort(key=lambda net : net.net_id) return nets
def parse_net(self, args): """ Assembles a net from a list of junctions, segments, and labels. """ thisnet = Net(args) subdata = defaultdict(list) for phrase in self.stream: cmd, _sep, args = phrase.partition(' ') if cmd not in ('J', 'S', 'A', 'L', 'Q', 'B'): self.stream.push(phrase) break k, v = self.parsenode(cmd)(args) subdata[k].append(v) # finish building thisnet for netpt in subdata['netpoint'][:]: # using a copy so that we can modify subdata['netpoint'] inside loop if netpt.point_id not in thisnet.points: thisnet.add_point(netpt) else: # oh yeah, a net can have a point more than once, because that # makes *great* sense. for point in netpt.connected_points: thisnet.points[netpt.point_id].add_connected_point(point) for comp in netpt.connected_components: thisnet.points[netpt.point_id].add_connected_component(comp) # update subdata['netpoint'] so that ref to netpt points to the # new combined point i = subdata['netpoint'].index(netpt) subdata['netpoint'][i] = thisnet.points[netpt.point_id] # yuck, passing in-band thisnet.ibpts = subdata['netpoint'] for pt_a, pt_b in subdata['segment']: thisnet.connect((subdata['netpoint'][pt_a - 1], subdata['netpoint'][pt_b - 1])) for annot in subdata['annot']: thisnet.add_annotation(annot) if '=' in annot.value: thisnet.add_attribute(*(annot.value.split('=', 1))) return ('net', thisnet)
def get_net(point): """ Return a new or existing Net for a NetPoint. """ if point not in point2net: point2net[point] = Net(str(len(nets))) nets.add(point2net[point]) return point2net[point]
def parse_net(self, args): """ Assembles a net from a list of junctions, segments, and labels. """ thisnet = Net(args) subdata = self.sub_nodes('J S A L Q B'.split()) # finish building thisnet for netpt in subdata['netpoint'][:]: # using a copy so that we can modify subdata['netpoint'] inside loop if netpt.point_id not in thisnet.points: thisnet.add_point(netpt) else: # oh yeah, a net can have a point more than once, because that # makes *great* sense. for point in netpt.connected_points: thisnet.points[netpt.point_id].add_connected_point(point) for comp in netpt.connected_components: thisnet.points[netpt.point_id].add_connected_component( comp) # update subdata['netpoint'] so that ref to netpt points to the # new combined point i = subdata['netpoint'].index(netpt) subdata['netpoint'][i] = thisnet.points[netpt.point_id] # yuck, passing in-band thisnet.ibpts = subdata['netpoint'] for pt_a, pt_b in subdata['segment']: thisnet.connect( (subdata['netpoint'][pt_a - 1], subdata['netpoint'][pt_b - 1])) for annot in subdata['annot']: thisnet.add_annotation(annot) if '=' in annot.value: thisnet.add_attribute(*(annot.value.split('=', 1))) return ('net', thisnet)
def setUp(self): """ Setup the test case. """ self.net = Net('001')
def calc_nets(self, design, segments): """ Return a set of Nets from segments """ coord2point = {} # (x, y) -> NetPoint def get_point(coord): """ Return a new or existing NetPoint for an (x,y) point """ coord = (int(coord[0]), int(coord[1])) if coord not in coord2point: coord2point[coord] = NetPoint('%da%d' % coord, coord[0], coord[1]) return coord2point[coord] # use this to track connected pins not yet added to a net self.make_pin_points(design, get_point) # set of points connected to pins pin_points = set(coord2point.itervalues()) # turn the (x, y) points into unique NetPoint objects segments = set((get_point(p1), get_point(p2)) for p1, p2 in segments) nets = [] # Iterate over the segments, removing segments when added to a net while segments: seg = segments.pop() # pick a point newnet = Net('') map(pin_points.discard, seg) # mark points as used newnet.connect(seg) found = True while found: found = set() for seg in segments: # iterate over segments if newnet.connected(seg): # segment touching the net map(pin_points.discard, seg) # mark points as used newnet.connect(seg) # add the segment found.add(seg) for seg in found: segments.remove(seg) nets.append(newnet) # add single-point nets for overlapping pins that are not # already in other nets for point in pin_points: if len(point.connected_components) > 1: net = Net('') net.add_point(point) nets.append(net) for net in nets: net.net_id = min(net.points) nets.sort(key=lambda net: net.net_id) return nets