def editIcon(self, actComp=None): '''edit svg file''' if self.type == 'symbolView': block = actComp libname = actComp.libname blockname = actComp.blockname else: libname = self.libraries.currentItem().text() blockname = self.cells.currentItem().text() block = getBlock(libname, blockname) svgiconname = block.icon # = svgfilepath if svgiconname is None: svgiconname = libraries.blockpath(libname, blockname).rstrip('.py') + '.svg' # temp file fo = tempfile.NamedTemporaryFile(suffix='.svg', delete=False) svgtempfilename = fo.name if os.path.isfile(svgiconname): with open(svgiconname) as fi: t = fi.read() #copy to a tempfile fo.write(t) fo.close() updateSvg(block, svgtempfilename) timestamp0 = os.stat(svgtempfilename).st_mtime try: subprocess.call('inkscape {}'.format(svgtempfilename).split()) timestamp1 = os.stat(svgtempfilename).st_mtime if timestamp0 and timestamp0 < timestamp1: # newer => copy and update print('scrubbing', svgtempfilename) updateSvg(block, svgtempfilename, makeports=False) if not svgiconname.lower().endswith('.svg'): # old-style icon svgiconname = libraries.blockpath( block.libname, block.blockname).rstrip('.py') + '.svg' shutil.move(svgtempfilename, svgiconname) print('mv to', svgiconname) block.setIcon(svgiconname) # register niew view blockdir = os.path.dirname( libraries.blockpath(block.libname, block.blockname)) relpath = os.path.relpath(svgiconname, blockdir) block.setView('icon', relpath) # creanup tempfile if os.path.exists(svgtempfilename): os.remove(svgtempfilename) except OSError: raise Exception('Inkscape is not installed')
def updateOnDisk(libname, blockname, dd=dict(), writeback=True): '''replace assignments with new values for variable names in dd and write back to disk''' fname = libraries.blockpath(libname, blockname) src = [] with open(fname) as f: lines = f.readlines() ix = 0 while ix < len(lines): line = lines[ix] s = line.replace('=', ' = ').split() if len(s) > 2 and line.startswith( s[0]) and s[0] in dd and s[1] == '=': # assignment without leading whitespace key = s[0] while line.endswith('\\\n') or line.strip().endswith(','): ix += 1 line = lines[ix] # get comment if present line, _, cmt = line.partition('#') if cmt: cmt = ' # ' + cmt.strip() line = '{} = {}\n'.format(key, dd[key], cmt) src.append(line) ix += 1 src = ''.join(src) if writeback: with open(fname, 'wb') as f: f.write(src) getBlockModule(libname, blockname) # update module return src
def getBlockModule(libname, blockname, errors=[]): '''read python module of block from disk''' fpath = libraries.blockpath(libname, blockname) blk = import_module_from_source_file(fpath, errors) if errors: print(errors) block_modules[libname + '/' + blockname] = blk if blk: _addBlockModuleDefaults(libname, blockname) return blk
def instToMyhdl(inst): '''returns tuple (text, isimport''' libname, blkname = inst['libname'], inst['blockname'] name = inst['label']['text'] # instance name in diagram args = inst['conn'] # store properties if 'properties' in inst: args.update(inst['properties']) parameters = inst['parameters'] if 'parameters' in inst else dict( ) # pcell instance_netlist = '' # find inst module k = libname + '/' + blkname try: blkMod = blkModuleCache[k] except KeyError: fname = libraries.blockpath(libname, blkname) blkMod = import_module_from_source_file(fname) blkModuleCache[k] = blkMod # try module.toMyhdlInstance() try: instance_netlist = blkMod.toMyhdlInstance(name, args, parameters) return instance_netlist, False except AttributeError: if parameters: # parametrized cell should have netlist function message = 'error while netlisting parametrized block {}.{}\n'.format(libname, blkname) + \ 'function toMyhdlInstance is not present.' raise Exception(message) if not instance_netlist: # normal cell netlist #instance_netlist = defaultMyHdlInstance(name, libname, blkname, args) conns = [] for pinname, netname in list(args.items()): if isinstance(netname, (list, tuple)): netname = netname[0] conns.append('{} = {}'.format(pinname, netname)) jj = ',\n' + ' ' * 12 c = jj.join(conns) return ' u_{} = {}{}.{}({})\n'.format(name, libraries.libprefix, libname, blkname, c), True
def _addBlockModuleDefaults(libname, blockname): '''add default settings to a loaded block_module''' blk = block_modules[libname + '/' + blockname] blk.name = blockname blk.libname = libname blk.textSource = libraries.blockpath(libname, blockname) try: if not 'icon' in blk.views: blk.views['icon'] = None if not hasattr(blk, 'bbox'): blk.bbox = None for pp in ['properties', 'parameters']: if not hasattr(blk, pp): setattr(blk, pp, dict()) except Exception as e: raise Exception('Block {}.{} raised error {}'.format( libname, blockname, str(e))) p = libraries.libpath(libname) for viewname, (ed, ext) in viewTypes.items(): fn = os.path.join(p, blockname + ext) if os.path.isfile(fn): blk.views[viewname] = fn
def convertSymAct(self): selection = self.scene.items(self.scene.selectionArea()) if selection and self.scene.selectedItems(): # blocks, connections, nodes, comments blocks = [] connections = [] nodes = [] comments = [] inp = [] outp = [] inout = [] for item in selection: if isinstance(item, Block): blocks.append(str(item.toData())) elif isConnection(item): connections.append(str(item.toData())) elif isNode(item): nodes.append(str(item.toData())) elif isPort(item, 'pin'): item.pinToPort(inp, outp, inout) elif isComment(item): comments.append(str(item.toData())) dialog = convertSymDialog() ret = dialog.getRet() if ret: name = ret['name'] icon = ret['icon'] if self.library.type == 'symbolView': libname = self.library.tabs.tabText( self.library.tabs.currentIndex()) else: libname = self.library.libraries.currentItem().text() ed, ext = viewTypes['diagram'] views = dict( diagram=os.path.join(libraries.libprefix + libname, name + ext)) if icon: views['icon'] = icon parameters = dict() properties = ret['properties'] data = templates['block'].format(name=name, libname=libname, inp=inp, outp=outp, io=inout, bbox=None, properties=properties, parameters=parameters, views=views) # save block fname = libraries.blockpath(libname, name) with open(fname, 'w+') as f: f.write(str(data)) # save diagram ed, ext = viewTypes['diagram'] fname = strip_ext(fname, '.py') + ext self.saveDiagramAs(fname, selection) for item in self.scene.selectedItems(): try: item.remove() except: pass # with open(self.path + '/libraries/library_' + libname + '/' + name + '_diagram.py','w+') as f: # f.write("blocks = [" + ",\n ".join(blocks) + "]\n\n" + # "connections = [" + ",\n ".join(connections) + "]\n\n" + # "nodes = [" + ",\n ".join(nodes) + "]\n\n" + # "comments = [" + ",\n ".join(comments) + "]") center = self.scene.getCenter() item = getBlock(libname, name, None, self.scene) item.setPos(center[0], center[1]) if self.library.type == 'symbolView': ix = self.library.tabs.currentIndex() self.library.symbolView() self.library.tabs.setCurrentIndex(ix) else: self.library.listView() self.library.libraries.setCurrentItem( self.library.libraries.findItems( 'symbols', QtCore.Qt.MatchExactly)[0]) else: error('Select what you want to convert')
def resolve_connectivity(filename, properties=dict()): #import file dgm = import_module_from_source_file(filename) #============================================================================== # read blocks #============================================================================== blocks = dict() for inst in dgm.blocks: inst_name = inst['label']['text'] blocks[inst_name] = inst blockname, libname = inst['blockname'], inst['libname'] fname = libraries.blockpath(libname, blockname) k = blockname + '/' + libname if not k in blkModuleCache: blkModuleCache[k] = import_module_from_source_file(fname) blkMod = blkModuleCache[k] if 'parameters' in inst: param = inst['parameters'] if hasattr(blkMod, 'ports'): inp, outp, inout = blkMod.ports(param) else: inp = param['inp'] if 'inp' in param else [] outp = param['outp'] if 'outp' in param else [] inout = param['inout'] if 'inout' in param else [] else: inp, outp, inout = blkMod.inp, blkMod.outp, [] # first initialize the connection to each pin to None inst['conn'] = OrderedDict() # inst['signalType'] = OrderedDict() if isinstance(inp, int): for ix in range(inp): inst['conn']['.i_{}'.format(ix)] = None else: for pname, px, py in inp: inst['conn'][pname] = None inst['outp'] = set( ) # used to set unnamed nets that are connected to an output if isinstance(outp, int): for ix in range(outp): pname = '.o_{}'.format(ix) inst['conn'][pname] = None inst['outp'].add(pname) else: for pname, px, py in outp: inst['conn'][pname] = None inst['outp'].add(pname) if isinstance(inout, int): for ix in range(inout): inst['conn']['.io_{}'.format(ix)] = None else: for pname, px, py in inout: inst['conn'][pname] = None # copy keys, to signalTypes # inst['signalType'].update(inst['conn']) # find pins because they are external nets pinnames = set() nodes = dict() for n in dgm.nodes: xy = n['x'], n['y'] nodes[xy] = NetObj(n) if 'label' in n and n['porttype'] != 'node': pinnames.add(n['label']['text']) resolved = dict( ) # resolved connections resolved[netname] == set(connections and nodes) unresolved = set() # unresolved connections for c in dgm.connections: conn = NetObj(c) for xy in [(c['x0'], c['y0']), (c['x1'], c['y1'])]: if xy in nodes: conn.stamp(nodes[xy]) nodes[xy].stamp(conn) if conn.netname: if conn.netname not in resolved: resolved[conn.netname] = set() resolved[conn.netname].add(conn) else: unresolved.add(conn) #============================================================================== # propagate names nets #============================================================================== for netname in resolved.keys(): for conn in set(resolved[netname]): propagateNets(conn, unresolved, resolved) #============================================================================== # propagate anonymous nets #============================================================================== # build a set of driven nets driven_connections = set() for conn in unresolved: if 'p0' in conn.d: driven_connections.add(conn) n_nets = 0 # used to number anonymous nets while unresolved: # check if there are driven conncetions if driven_connections: # name after driving instance conn = driven_connections.pop() unresolved.discard(conn) instname, portname = conn.d['p0'] inst = blocks[instname] netname = 'w_{}'.format(instname.lower()) #instance_name if portname in inst['outp']: netname = 'w_{}'.format(instname.lower()) #instance_name if len(inst['outp']) > 1: # not the only output netname += '_{}'.format( portname.lstrip('.').lower()) # + port_name else: print(inst) raise Exception( '{}: connection to {} pin {} is not an output of {}.{}'. format(filename, instname, portname, inst['libname'], inst['blockname'])) else: # choose arbitrary name conn = unresolved.pop() if debug: print('anonymous net in ', filename) print(' p0 = {}, {}'.format(conn.d['x0'], conn.d['y0'])) print(' p1 = {}, {}'.format(conn.d['x1'], conn.d['y1'])) n_nets += 1 netname = 'net{}'.format(n_nets) conn.netname = netname if conn.netname not in resolved: resolved[conn.netname] = set() resolved[conn.netname].add(conn) propagateNets(conn, unresolved, resolved) #============================================================================== # resolve connection to blocks #============================================================================== for netname, conns in resolved.items(): for conn in conns: for p in ['p0', 'p1']: if p in conn.d: blkname, pname = conn.d[p] inst = blocks[blkname] inst['conn'][pname] = (conn.netname, conn.type) # check that all block ports are connected for instname, inst in blocks.items(): for pin, net in inst['conn'].items(): if net is None: if debug: print('debug', inst['conn']) raise Exception( 'file {}: instance {}, pin {} is not Connected'.format( filename, instname, pin)) # print('file {}: instance {}, pin {} is not Connected'.format(filename, instname, pin)) internal_nets = dict() external_nets = dict() for netname in resolved: # signal_type st = None for item in resolved[netname]: if item.type: if st is None: st = item.type elif st != item.type: raise Exception('Type conflict: {}, {}\non {}'.format(\ st, item.type, item)) prop = dict(signalType=st) for c in resolved[netname]: if 'properties' in c.d: prop.update(c.d['properties']) if netname in pinnames: external_nets[netname] = prop else: internal_nets[netname] = prop return blocks, internal_nets, external_nets
def resolve_dgm_connectivity(filename, properties=dict()): '''work out the connections in a diagram''' #import file dgm = import_module_from_source_file(filename) #============================================================================== # read blocks #============================================================================== blocks = dict() for inst in dgm.blocks: inst_name = inst['label']['text'] blocks[inst_name] = inst blockname, libname = inst['blockname'], inst['libname'] fname = libraries.blockpath(libname, blockname) k = blockname + '/' + libname if not k in blkModuleCache: blkModuleCache[k] = import_module_from_source_file(fname) blkMod = blkModuleCache[k] if 'parameters' in inst: param = inst['parameters'] if hasattr(blkMod, 'ports'): inp, outp, inout = blkMod.ports(param) else: inp = param['inp'] if 'inp' in param else [] outp = param['outp'] if 'outp' in param else [] inout = param['inout'] if 'inout' in param else [] else: inp, outp, inout = blkMod.inp, blkMod.outp, [] # first initialize the connection to each pin to None inst['conn'] = OrderedDict() # inst['signalType'] = OrderedDict() if isinstance(inp, int): for ix in range(inp): inst['conn']['.i_{}'.format(ix)] = None else: for pname, px, py in inp: inst['conn'][pname] = None # inst['outp'] = set() # used to set unnamed nets that are connected to an output if isinstance(outp, int): for ix in range(outp): pname = '.o_{}'.format(ix) inst['conn'][pname] = None # inst['outp'].add(pname) else: for pname, px, py in outp: inst['conn'][pname] = None # inst['outp'].add(pname) if isinstance(inout, int): for ix in range(inout): inst['conn']['.io_{}'.format(ix)] = None else: for pname, px, py in inout: inst['conn'][pname] = None # copy keys, to signalTypes # inst['signalType'].update(inst['conn']) #============================================================================== # Build connectivity network #============================================================================== dgm_nets = Nets() # dgm_nets hold all different nets for node in dgm.nodes: dgm_nets.addNode(node) for conn in dgm.connections: dgm_nets.addConnection(conn) dgm_nets.name_all_nets(blocks) #============================================================================== # check that all block ports are connected #============================================================================== for instname, inst in list(blocks.items()): for pin, net in list(inst['conn'].items()): if net is None: if debug: print('debug', inst['conn']) raise Exception( 'file {}: instance {}, pin {} is floating'.format( filename, instname, pin)) #============================================================================== # spit internal and external nets #============================================================================== internal_nets, external_nets = dgm_nets.split_nets() if debug: for netname, net in list(dgm_nets.named.items()): print('Net:', netname) net.pprint() return blocks, internal_nets, external_nets