def openView(self, viewtype, actComp=None): if actComp: blockname = actComp.blockname libname = actComp.libname else: libname = self.libraries.currentItem().text() blockname = self.cells.currentItem().text() try: source = getViews(libname, blockname)[viewtype] except: error('view not found') cmd = None for tp, (editor, extension) in viewTypes.items(): if source.endswith(extension): cmd = editor break if cmd: os.system(cmd + " " + source) else: error( "{} is unkown type\nplease see viewTypes in menu Settings -> Edit settings" .format(source)) return #reset library self.refresh([(libname, blockname)])
def openDiagram(self, filename=None): if filename in [None, False]: filename = QtWidgets.QFileDialog.getOpenFileName( self, 'Open', self.path + '/saves/', filter='Diagram (*.py *.diagram);;All (*.*)') if isinstance(filename, tuple): filename = filename[0] if filename: path, ffname = os.path.split(filename) # path, full filename bname, ext = os.path.splitext(ffname) # basename, extension('.py') ed, dgmext = viewTypes['diagram'] if ext not in ['.py', dgmext]: error(filename + ' is not a diagram') return self.path = path self.filename = bname self.newTab(self.filename) ix = self.centralWidget.currentIndex() self.centralWidget.widget(ix).fname = filename # store name dgm = import_module_from_source_file(os.path.abspath(filename)) blocks = dgm.blocks nodes = dgm.nodes connections = dgm.connections comments = dgm.comments self.dataToDiagram(blocks, connections, nodes, comments)
def setType(self, porttype=None): pp, cc = None, None # polygon/circle coordinates if porttype: self.porttype = porttype if self.porttype is None: # not set return if self.porttype == 'input': # block input pp = ((PW/2,0), (-PW/2,PW/2), (-PW/2,-PW/2)) self.label_side = 'right' elif self.porttype == 'output': # block output pp = ((-PW/2,-PW/2), (PW/2,-PW/2), (PW/2,PW/2), (-PW/2,PW/2)) self.label_side = 'left' elif self.porttype == 'inout': # block inout pp = ((-PW/2,0), (0,PW/2), (PW/2,0), (0,-PW/2)) self.label_side = 'left' elif self.porttype == 'ipin': # input terminal pp = ((PW/2,0), (0,PW/2), (-PW,PW/2), (-PW,-PW/2), (0,-PW/2)) self.label_side = 'left' elif self.porttype == 'opin': # output terminal pp = ((PW/2,0), (0,PW/2), (-PW,PW/2), (-PW/2,0), (-PW,-PW/2), (0,-PW/2)) self.label_side = 'right' elif self.porttype == 'iopin': # inout terminal pp = ((-PW,0), (-PW/2,PW/2), (PW/2,PW/2), (PW,0), (PW/2,-PW/2), (-PW/2,-PW/2)) self.label_side = 'right' elif self.porttype == 'node': # node cc = (-NW/2, -NW/2, NW, NW) self.label_side = 'top' for k in [self.porttype, 'port_'+self.porttype]: if k in colors: self.lineColor, self.fillColor = colors[k] pen = QtGui.QPen(self.lineColor) pen.setWidth(1) self.setPen(pen) self.setBrush(self.fillColor) break self.p.swap(QtGui.QPainterPath()) # new painterpath if pp: polygon = QtGui.QPolygonF() for (x, y) in pp: polygon.append(QtCore.QPointF(x, y)) polygon.append(QtCore.QPointF(pp[0][0], pp[0][1])) # close polygon self.p.addPolygon(polygon) elif cc: bb = QtCore.QRectF(*cc) self.p.addEllipse(bb) else: error('unknown Port type: {}'.format(self.porttype))
def addView(self, viewtype, fname): if viewtype not in viewTypes: error('viewtype {} is not defined in const.py'.format(viewtype)) return views = self.getViews() # if viewtype in views: # error('viewtype {} is already present'.format(viewtype)) # return views[viewtype] = fname self.updateOnDisk(views)
def editBbox(self, actComp=None): if actComp: blockname = actComp.blockname libname = actComp.libname blk = actComp cx, cy, w, h = blk.center.x(), blk.center.y(), blk.w, blk.h bbox = (int(cx - w / 2), int(cy - h / 2), int(w), int(h)) else: error() libname = self.libraries.currentItem().text() blockname = self.cells.currentItem().text() blk = getBlockModule(libname, blockname) bbox = getattr(blk, 'bbox', None) if bbox is None: bbox = calcBboxFromPins(blk.inp, blk.outp) if hasattr(blk, 'getSymbol'): error( "you have to change the getSymbol function to change this block's bbox" ) return x0, y0, w, h = bbox x1, y1 = x0 + w, y0 + h lines = [('left', int(x0)), ('top', int(y0)), ('right', int(x1)), ('bottom', int(y1))] dialog = txtDialog() ret = dialog.editList(lines) if ret: d = dict(ret) x0, y0, x1, y1 = d['left'], d['top'], d['right'], d['bottom'] bbox = (x0, y0, x1 - x0, y1 - y0) libname, blockname, fname, blk = self.getnames(blk) dd = dict() dd['bbox'] = bbox src = updateOnDisk(libname, blockname, dd) if 'bbox' not in src: lines = src.splitlines() for ix, line in enumerate(lines): if line.startswith('outp'): line[ix] = line[ix] + 'bbox = {}\n'.format(bbox) break src = ''.join(lines) with open(fname, 'wb') as f: f.write(src) reload('libraries.library_{}.{}'.format(libname, blockname)) self.refresh([(libname, blockname)])
def addLibrary(self): dialog = textLineDialog('Name: ', 'Add library') ret = dialog.getLabel() if ret: try: # create path fp = libraries.libpath(ret) os.mkdir(fp) # create __init__.py f = open(os.path.join(fp, '__init__.py'), 'wb') f.close() self.refresh() except Exception as e: error('Library error' + str(e))
def portAddType(self, event): item = self.scene.item if not isPort(item): error('use on nodes/pins') return if item.signalType: dialog = textLineDialog('Signal type: ', 'Signal type', item.signalType.text()) else: dialog = textLineDialog('Signal type: ', 'Signal type') ret = dialog.getLabel() if ret: item.signalType = textItem(ret, anchor=8, parent=item) item.signalType.setBrush(colors['signalType']) font = item.signalType.font() font.setItalic(True) item.signalType.setFont(font)
def netlistMyhdlAct(self): ix = self.centralWidget.currentIndex() fname = self.centralWidget.widget(ix).fname dirname, basename = os.path.split(fname) dgmname, ext = os.path.splitext(basename) netlist_dir = os.path.join(os.curdir, 'netlist_myhdl', dgmname) #actual netlisting try: netlist(fname, lang='myhdl', netlist_dir=netlist_dir) except Exception as e: error('netlist of {} produced error {}'.format(fname, str(e))) # print message b = QtWidgets.QMessageBox() b.setWindowModality(QtCore.Qt.ApplicationModal) b.setText('netlist written in ' + netlist_dir) b.exec_()
def mouseDoubleClicked(self, obj, event): pos = gridPos(event.scenePos()) item = self.itemAt(pos, exclude=[isConnection]) if isBlock(item): if 'diagram' in item.getViews(): self.scene.mainw.descend(item) else: views = item.getViews() fname = None if len(views) == 1: viewtype, fname = views.items()[0] elif len(views) > 1: d = selectionDialog(views.keys(), title='Select view') ret = d.getRet() if ret: fname = views[ret] if fname: for tp, (editor, extension) in viewTypes.items(): if fname.endswith(extension): cmd = editor break if cmd: os.system(cmd + " " + fname) else: error( "{} is unkown type\nplease see viewTypes in menu Settings -> Edit settings" .format(source)) return elif isPort(item, tp='ipin opin iopin node'.split()): self.scene.item = item self.portEdit() if self.conn: self.conn.remove() self.conn = None self.scene.mainw.view.setCursor(QtCore.Qt.ArrowCursor) elif isTextItem(item): font, ok = QtWidgets.QFontDialog.getFont(item.font()) if ok: item.setFont(font)
def portEdit(self): item = self.scene.item if not isPort(item): error('not a pin') dd = OrderedDict() dd['Pin_label'] = item.label.text() if item.label else '' options = 'ipin opin iopin node'.split() dd['Pin_type'] = (item.porttype, options) properties = item.properties title = 'Edit Node' if isNode(item) else 'Edit Pin' dialog = propertiesDialog(self.scene.mainw, dd, properties, title=title) dd = dialog.getRet() if dd: item.setType(dd.pop('Pin_type')[0]) item.setLabel(dd.pop('Pin_label')) if dd: item.properties = dd item.setup()
def addViewAction(self, actComp=None): libname, blockname, fname, blk = self.getnames(actComp) dialog = addViewDialog(libname, blockname) ret = dialog.getRet() if ret: view, path = ret[0], ret[1] if view in templates: txt = templates[view].format(name=blockname) else: txt = '' try: path = os.getcwd() f = open(path + "/" + ret[1], 'w+') f.write(txt) f.close() except: error('File source not correct') return actComp.addView(view, path) self.openView(ret[0], actComp)
def editPins(self, actComp=None): libname, blockname, fname, blk = self.getnames(actComp) param = getattr(blk, 'parameters', None) if param: error( 'cannot edit pins of parametrized cell, the pins should be set in getSymbol' ) if hasattr(blk, 'getSymbol'): error('Cannot edit pins block containing getSymbol() function') return inp = actComp.inp outp = actComp.outp dialog = editPinsDialog(inp, outp) ret = dialog.getRet() if ret: dd = dict() dd['inp'] = ret[0] dd['outp'] = ret[1] actComp.updateOnDisk(dd) self.refresh([(libname, blockname)])
def netList(self, type): try: item = self.scene.item fname = 'libraries.library_{}.{}'.format(item.libname, item.blockname) exec('import ' + fname) func = eval(fname + '.netlist' + type) func(item) except: if type == 'myhdl': item = self.scene.item if item.hasDiagram(): views = libraries.getViews(item.blockname, item.libname) fname = 'libraries/library_{}/{}_myhdl.py'.format( item.libname, item.blockname) overwrite = True if 'myhdl' in views: dialog = overWriteNetlist() ret = dialog.exec_() if ret == 0: fname = views['myhdl'] else: overwrite = False if overwrite: import supsisim.netlist content = supsisim.netlist.netlistMyHdl( item.blockname, item.libname, item.properties) if content == False: error('More than 1 label on signal') return f = open(fname, 'w+') f.write(content) f.close() if not 'myhdl' in views: self.addView(item.blockname, item.libname, 'myhdl') self.parent().library.openView('myhdl', item) else: error("file doesn't have a diagram") else: error('netlist not found')
def getBlock(libname, blockname, parent=None, scene=None, param=dict(), properties=dict(), name=None, flip=False, errors=[]): '''create a Block''' blk = getBlockModule(libname, blockname, errors=errors) if blk is None: return if blk.parameters: # start from default parameters param = dict(blk.parameters.items() + param.items()) if blk.properties: # start from default properties properties = dict(blk.properties.items() + properties.items()) try: b = blk.getSymbol(param, properties, parent, scene) except AttributeError: b = None if b: # pcell b.libname = libname if isinstance(b, Block): if name: if scene: scene.blocks.discard(b) b.name = name scene.blocks.add(b) else: b.name = name b.label.setText(name) b.flip = flip b.setFlip() if hasattr(blk, 'tooltip'): b.setToolTip(blk.tooltip) return b else: error('getSymbol returned no block') return False # except Exception as e: # error('libary_{}/{}.py contains error:\n{}'.format(libname, blockname, str(e))) # return False else: # std block if param: error('pcell {}.{}.getSymbol did not return block'.format( libname, blockname)) else: parameters = blk.parameters properties = blk.properties attributes = dict() attributes['name'] = name if name else blockname attributes['libname'] = libname attributes['input'] = blk.inp attributes['output'] = blk.outp attributes['icon'] = blk.views['icon'] attributes['bbox'] = blk.bbox attributes['flip'] = flip b = Block(attributes, parameters, properties, blockname, libname, parent, scene) if hasattr(blk, 'tooltip'): b.setToolTip(blk.tooltip) return b
def dataToDiagram(self, blocks, connections, nodes, comments, center=True, undo=False): errors = [] for data in blocks: prop = data['properties'] if 'properties' in data else dict() if 'parameters' in data: #getBlock(libname, blockname, parent=None, scene=None, param=dict(), name=None, flip=False) b = getBlock(data['libname'], data['blockname'], scene=self.scene, param=data['parameters'], properties=prop, errors=errors) else: b = getBlock(data['libname'], data['blockname'], scene=self.scene, properties=prop, errors=errors) if b: b.fromData(data) for item in nodes: pos = QtCore.QPointF(item['x'], item['y']) if self.scene.find_itemAt(pos): print('discarding overlapping node at x={}, y={}'.format( item['x'], item['y'])) else: p = Port(None, self.scene) p.fromData(item) for data in connections: pos = [QtCore.QPointF(data['x0'], data['y0'])] pos.append(QtCore.QPointF(data['x1'], data['y1'])) if pos[0] == pos[1]: print('discarding zero length segment x={}, y={}'.format( data['x0'], data['y0'])) else: conn = Connection(None, self.scene) for ix in [0, 1]: port = self.scene.find_itemAt(pos[ix], exclude=(Block, Connection, textItem)) if isPort(port): conn.attach(ix, port) else: conn.pos[ix] = pos[ix] print('no port at ', pos[ix]) conn.update_path() if 'label' in data: conn.label = textItem(data['label'], anchor=3, parent=conn) conn.label.setPos(conn.pos2.x(), conn.pos2.y()) if 'signalType' in data: conn.signalType = textItem(data['signalType'], anchor=3, parent=conn) conn.signalType.setPos(conn.pos2.x(), conn.pos2.y()) for data in comments: comment = Comment('') comment.fromData(data) self.scene.addItem(comment) if center: self.scene.mainw.view.centerOn(self.scene.getCenter()[0], self.scene.getCenter()[1]) if errors: error('\n'.join(errors))
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.saveDiagram(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')