def main(): # load command-line arguments parser = argparse.ArgumentParser() parser.add_argument('--json') parser.add_argument('--pcb') args = parser.parse_args() # read board placement from SMT-PCB print "Reading output from SMT engine." with open(args.json, 'r') as f: json_dict = json.load(f) # load board print 'Loading PCB file.' pcb = Board.load(args.pcb) # move parts to specified locations print 'Placing all components.' place_parts(json_dict, pcb) # draw board edge print 'Drawing board edge.' draw_board_edge(json_dict, pcb) # save board print 'Saving PCB file.' pcb.save() # add net and net class information print 'Adding nets and net classes to the PCB design.' BoardTools.add_nets( json_dict['design_dict'], json_dict['net_class_list'], args.pcb, args.pcb)
def main(): # load command-line arguments parser = argparse.ArgumentParser() parser.add_argument('--json') parser.add_argument('--units', default='inch') args = parser.parse_args() # read board placement from SMT-PCB with open(args.json, 'r') as f: json_dict = json.load(f) board_edge = json_dict['board_edge'] width, height = BoardTools.get_board_dims(board_edge) # define unit conversion if args.units.lower() in ['in', 'inch', 'inches']: conv = lambda x: 0.0393701 * x area_str = 'in^2' if args.units.lower() in ['mm', 'mms', 'millimeters']: conv = lambda x: x area_str = 'mm^2' if args.units.lower() in ['mil', 'mils']: conv = lambda x: 39.3701 * x area_str = 'mil^2' area = conv(width) * conv(height) # print summary print '############' print 'Summary' print 'Board area: %0.3f %s' % (area, area_str) print '############'
def draw_board_edge(json_dict, pcb): # compute upper left corner of board board_ul = Point(*BoardTools.get_board_ul(json_dict['board_edge'])) # draw edge edge = [Point(x, y) + board_ul for x, y in json_dict['board_edge']] pcb.add_polyline(edge, layer='Edge.Cuts')
def place_parts(json_dict, pcb): # compute upper left corner of board board_ul = Point(*BoardTools.get_board_ul(json_dict['board_edge'])) # place all components for name, module in json_dict['module_dict'].items(): if module['type'] == 'comp': # set rotation rot = module['rotation'] pcb.modules[name].rotation = rot # make the buffer vector if round(degrees(rot)) in [0, 180]: buf_space = Point(module['bufx'], module['bufy']) elif round(degrees(rot)) in [90, 270]: buf_space = Point(module['bufy'], module['bufx']) else: raise Exception("Can't determine rotation.") # set position pcb.modules[name].position = \ pcb.modules[name].position \ + Point(module['x'], module['y']) \ + buf_space \ + board_ul \ - pcb.modules[name].boundingBox.ul elif module['type'] == 'keepout': pass else: raise Exception('Unimplemented component type: ' + str(module['type']))
def place_rects(args): # read in SMT input with open(args.json, 'r') as f: json_dict = json.load(f) # create the placer grid width, height = BoardTools.get_board_dims(json_dict['board_edge']) grid = PlaceGrid(width=width, height=height, dx=args.dx, dy=args.dy) fab = design.Fabric(grid.place_dims) # Create the design comps_list = grid.make_comps_list(json_dict['module_dict']) routing_list = grid.make_routing_list(json_dict['routing_list']) d = design.Design(comps_list, routing_list, fab, position.RotIntXY) # Add constraints d.add_constraint_generator('no_overlap', constraints.no_overlap) d.add_pad_cg('max_dist', constraints.pad_max_dists) # create the solver if args.optimize: d.add_pad_opt('min_total_dist', constraints.pad_dists) s = z3.Optimize() else: s = z3.Solver() # add the constraints to the solver s.add(d.constraints) # set up the optimization, if desired if args.optimize: for func in d.r_opt_param: s.minimize(func) with open('freeduino.smt', 'w') as f: f.write(s.to_smt2()) # run the placement start = time.time() result = s.check() end = time.time() place_time = end - start print('Placement took', place_time, 'seconds.') if args.dout: with open(args.dout, 'a+') as f: f.write(str(place_time) + '\n') if result == z3.unsat: raise Exception('Problem is unsat.') return d, s.model()
def boundary(edge): ul = Point(*BoardTools.get_board_ul(edge)) edge = [ul + Point(x, y) for x, y in edge] # repeat the last point edge = edge + [edge[-1]] # add points to the edge path = ['path', 'pcb', '0'] for point in edge: # convert points from mm to um # and negate y coordinate x = '%d' % dsnx(point.x) y = '%d' % dsny(point.y) path = path[:] + [x, y] return ['boundary', path]
def main(): # load command-line arguments parser = argparse.ArgumentParser() parser.add_argument('--json') parser.add_argument('--pcb') parser.add_argument('--fill_top', default='GND') parser.add_argument('--fill_bot', default='GND') parser.add_argument('--bufx', type=float, default=0.5) parser.add_argument('--bufy', type=float, default=0.5) args = parser.parse_args() # read board placement from SMT-PCB with open(args.json, 'r') as f: json_dict = json.load(f) # get the board edge board_edge = json_dict['board_edge'] board_ul = Point(*BoardTools.get_board_ul(board_edge)) # compute board center cx, cy = BoardTools.get_board_center(board_edge) edge = [] for idx, (x, y) in enumerate(board_edge): if x < cx: px = x - args.bufx else: px = x + args.bufx if y < cy: py = y - args.bufy else: py = y + args.bufy board_edge[idx] = (px, py) # write board edge back with open(args.json, 'w') as f: json.dump(json_dict, f, indent=2, sort_keys=True) # create the new board edge edge = [Point(x, y) + board_ul for x, y in board_edge] # create zone outline for copper pours minx = min([p.x for p in edge]) maxx = max([p.x for p in edge]) miny = min([p.y for p in edge]) maxy = max([p.y for p in edge]) ul = Point(minx, miny) ur = Point(maxx, miny) lr = Point(maxx, maxy) ll = Point(minx, maxy) outline = [ul, ur, lr, ll] # write changes to board pcb = Board.load(args.pcb) # write edge pcb.clearLayer('Edge.Cuts') pcb.add_polyline(edge, layer='Edge.Cuts') # write zones #clearance = max(args.bufx, args.bufy) #pcb.add_zone(outline, args.fill_top, 'F.Cu', clearance) #pcb.add_zone(outline, args.fill_bot, 'B.Cu', clearance) pcb.save()