def setup(self, cktIdx): ckt = self.dDB.subCkt(cktIdx) for nodeIdx in range(ckt.numNodes()): flipCell = False cktNode = ckt.node(nodeIdx) # Flip cell if is in the "right" half device of symmetry if cktNode.name in self.symDict.values(): flipCell = True if cktNode.isLeaf(): continue subCktIdx = self.dDB.subCkt(cktIdx).node(nodeIdx).graphIdx devGen = Device_generator.Device_generator(self.mDB) if magicalFlow.isImplTypeDevice( self.dDB.subCkt(subCktIdx).implType): if flipCell: devGen.generateDevice( subCktIdx, self.resultName + '/gds/', True) #FIXME: directly add to the database else: devGen.generateDevice(subCktIdx, self.resultName + '/gds/', False) devGen.readGDS(subCktIdx, self.resultName + '/gds/') else: if flipCell: cktNode.flipVertFlag = True
def generateConstraints(self): for cktIdx in range(self.dDB.numCkts()): ckt = self.dDB.subCkt(cktIdx) #magicalFlow.CktGraph if magicalFlow.isImplTypeDevice(ckt.implType): continue if self.isCktStdCells(cktIdx): continue self.symDict = self.constraint.genConstraint( cktIdx, self.resultName)
def primaryCell(self, cktIdx): """ @brief Checking if cell is primary """ ckt = self.dDB.subCkt(cktIdx) print("ckt name", ckt.name) for nodeIdx in range(ckt.numNodes()): instNode = ckt.node(nodeIdx) print("node name", instNode.name) subckt = self.dDB.subCkt(instNode.graphIdx) if not magicalFlow.isImplTypeDevice(subckt.implType): return False return True
def writeInitObj(self, cktIdx, dirName): """ @brief write .initObj file """ ckt = self.dDB.subCkt(cktIdx) phyDB = self.dDB.phyPropDB() filename = dirName + ckt.name + '.initObj' fout = open(filename, "w") instId = 0 for nodeIdx in range(ckt.numNodes()): instNode = ckt.node(nodeIdx) assert not magicalFlow.isImplTypeDevice( instNode.implType), "Circuit %s contains non instance %s" % ( ckt.name + instNode.name) cirNode = self.dDB.subCkt(instNode.graphIdx) instPIdx = cirNode.implIdx fout.write("Inst\n%d\n" % instId) if cirNode.implType == magicalFlow.ImplTypePCELL_Nch: fout.write("NMOS\n%s\n" % instNode.name) nch = phyDB.nch(instPIdx) fout.write("%de-12 %de-12 %d\n" % (nch.width, nch.length, nch.numFingers)) elif cirNode.implType == magicalFlow.ImplTypePCELL_Pch: fout.write("PMOS\n%s\n" % instNode.name) pch = phyDB.pch(instPIdx) fout.write("%de-12 %de-12 %d\n" % (pch.width, pch.length, pch.numFingers)) elif cirNode.implType == magicalFlow.ImplTypePCELL_Res: fout.write("RES\n%s\n" % instNode.name) res = phyDB.resistor(instPIdx) fout.write("%de-12 %de-12\n" % (res.wr, res.lr)) elif cirNode.implType == magicalFlow.ImplTypePCELL_Cap: fout.write("CAP\n%s\n" % instNode.name) cap = phyDB.capacitor(instPIdx) fout.write("%de-12 %de-12\n" % (cap.w, cap.lr)) else: fout.write("OTHER\n%s\n" % instNode.name) for pin_idx in range(instNode.numPins()): pinIdx = instNode.pinIdx(pin_idx) netIdx = ckt.pin(pinIdx).netIdx fout.write("%d\n" % netIdx) #fout.write("%d %s\n" %(netIdx,ckt.net(netIdx).name)) instId += 1 for net in range(ckt.numNets()): fout.write("NET\n%d\n%s\n" % (net, ckt.net(net).name))
def primarySym(self, cktIdx, dirName): constGen = ConstGenPy.ConstGen() ckt = self.dDB.subCkt(cktIdx) phyDB = self.dDB.phyPropDB() mosPinType = [ConstGenPy.D, ConstGenPy.G, ConstGenPy.S, ConstGenPy.B] capPinType = [ConstGenPy.THIS, ConstGenPy.THAT, ConstGenPy.OTHER] for net in range(ckt.numNets()): idx = constGen.addNet(ckt.net(net).name, net) assert net == idx, "Net index not matched!" for nodeIdx in range(ckt.numNodes()): instNode = ckt.node(nodeIdx) assert not magicalFlow.isImplTypeDevice( instNode.implType), "Circuit %s contains non instance %s" % ( ckt.name + instNode.name) cirNode = self.dDB.subCkt(instNode.graphIdx) instPIdx = cirNode.implIdx if cirNode.implType == magicalFlow.ImplTypePCELL_Nch: nch = phyDB.nch(instPIdx) idx = constGen.addInst(instNode.name, ConstGenPy.Nch, nch.width, nch.length, nch.numFingers) pinTypeArray = mosPinType elif cirNode.implType == magicalFlow.ImplTypePCELL_Pch: pch = phyDB.pch(instPIdx) idx = constGen.addInst(instNode.name, ConstGenPy.Pch, pch.width, pch.length, pch.numFingers) pinTypeArray = mosPinType elif cirNode.implType == magicalFlow.ImplTypePCELL_Res: res = phyDB.resistor(instPIdx) idx = constGen.addInst(instNode.name, ConstGenPy.Res, res.wr, res.lr, res.segNum) pinTypeArray = capPinType elif cirNode.implType == magicalFlow.ImplTypePCELL_Cap: cap = phyDB.capacitor(instPIdx) idx = constGen.addInst(instNode.name, ConstGenPy.Cap, cap.w, cap.lr, cap.numFingers) pinTypeArray = capPinType else: assert False, "Device not supported %s" % instNode.name for pin_idx in range(instNode.numPins()): pinIdx = instNode.pinIdx(pin_idx) netIdx = ckt.pin(pinIdx).netIdx constGen.addInstPin(idx, netIdx, pinTypeArray[pin_idx]) assert nodeIdx == idx constGen.dumpResult(dirName + ckt.name)
def constructSubgraph(self, cktIdx, topIoNodeIdx): ckt = self.dDB.subCkt(cktIdx) self.circuitNodes[cktIdx] = dict() netNodeIdx = dict() nodeList = [] for net in range(ckt.numNets()): if ckt.net(net).isIo(): netNodeIdx[net] = topIoNodeIdx[ckt.net(net).ioPos] else: netName = ckt.net(net).name netIdx = self.addNet(netName) netNodeIdx[net] = netIdx for nodeIdx in range(ckt.numNodes()): cktNode = ckt.node(nodeIdx) subCkt = self.dDB.subCkt(cktNode.graphIdx) cktType = subCkt.implType ioNodeIdx = dict() for pin in range(cktNode.numPins()): pinIdx = cktNode.pinIdx(pin) netIdx = ckt.pin(pinIdx).netIdx ioNodeIdx[pin] = netNodeIdx[netIdx] if not magicalFlow.isImplTypeDevice(cktType): subNodes = self.constructSubgraph(cktNode.graphIdx, ioNodeIdx) elif cktType in [ magicalFlow.ImplTypePCELL_Nch, magicalFlow.ImplTypePCELL_Pch ]: subNodes = self.addInst(subCkt, 3, ioNodeIdx) elif cktType in [ magicalFlow.ImplTypePCELL_Res, magicalFlow.ImplTypePCELL_Cap ]: subNodes = self.addInst(subCkt, 2, ioNodeIdx) else: raise Exception('Device type of %s not supported' % subCkt.name) self.circuitNodes[cktIdx][nodeIdx] = subNodes nodeList.extend(subNodes) return nodeList
def implCktLayout(self, cktIdx): """ @brief implement the circuit layout """ dDB = self.mDB.designDB.db #c++ database ckt = dDB.subCkt(cktIdx) #magicalFlow.CktGraph # If the ckt is a device, generation will be added in setup() if magicalFlow.isImplTypeDevice(ckt.implType): Device_generator.Device_generator(self.mDB).generateDevice( cktIdx, self.resultName + '/gds/') #FIXME: directly add to the database return # If the ckt is a standard cell # This version only support DFCNQD2BWP and NR2D8BWP, hard-encoded # TODO: This should be parsed from the json file if self.isCktStdCells(cktIdx): StdCell.StdCell(self.mDB).setup(cktIdx, self.resultName) return # If the ckt is actually a circuit instead of a device for nodeIdx in range(ckt.numNodes()): cktNode = ckt.node(nodeIdx) # magicalFlow.CktNode if cktNode.isLeaf(): # Do not go deeper for leaf node continue subCkt = dDB.subCkt(cktNode.graphIdx) if (subCkt.isImpl): # Do not duplicately implement the layout continue self.implCktLayout( cktNode.graphIdx) # Recursively implement all the children ckt = dDB.subCkt( cktIdx) # just to make sure the reference is not messed up # After all the children being implemented. P&R at this circuit ckt = dDB.subCkt(cktIdx) #magicalFlow.CktGraph self.symDict = self.constraint.genConstraint(cktIdx, self.resultName) self.setup(cktIdx) pnr = PnR.PnR(self.mDB) pnr.placeOnly(cktIdx, self.resultName) self.runtime += pnr.runtime self.pnrs.append(pnr)
def plotGraph(self, cktIdx=None, recursive=True): if cktIdx == None: labels = dict( (n, d['name']) for n, d in self.graph.nodes(data=True)) pos = nx.spring_layout(self.graph) nx.draw(self.graph, labels=labels, pos=pos) plt.show() if recursive: self.plotGraph(self.mDB.topCktIdx()) else: ckt = self.dDB.subCkt(cktIdx) if magicalFlow.isImplTypeDevice(ckt.implType): return for nodes in range(ckt.numNodes()): subgraph = self.subgraph(cktIdx, nodes) labels = dict( (n, d['name']) for n, d in subgraph.nodes(data=True)) pos = nx.spring_layout(subgraph) if len(subgraph.nodes) > 4: nx.draw(subgraph, labels=labels, pos=pos) plt.show() if recursive: self.plotGraph(ckt.node(nodes).graphIdx)
def constructGraph(self, topCktIdx=None): # Added option for local graph generation if not topCktIdx: topCktIdx = self.mDB.topCktIdx() self.circuitNodes[topCktIdx] = dict() ckt = self.dDB.subCkt(topCktIdx) netNodeIdx = dict() # dict of net name to graph node idx for net in range(ckt.numNets()): netName = ckt.net(net).name nodeIdx = self.addNet(netName) netNodeIdx[net] = nodeIdx for nodeIdx in range(ckt.numNodes()): cktNode = ckt.node(nodeIdx) ioNodeIdx = dict() subCkt = self.dDB.subCkt(cktNode.graphIdx) cktType = subCkt.implType for pin in range(cktNode.numPins()): pinIdx = cktNode.pinIdx(pin) netIdx = ckt.pin(pinIdx).netIdx ioNodeIdx[pin] = netNodeIdx[netIdx] if not magicalFlow.isImplTypeDevice(cktType): subNodes = self.constructSubgraph(cktNode.graphIdx, ioNodeIdx) elif cktType in [ magicalFlow.ImplTypePCELL_Nch, magicalFlow.ImplTypePCELL_Pch ]: subNodes = self.addInst(subCkt, 3, ioNodeIdx) elif cktType in [ magicalFlow.ImplTypePCELL_Res, magicalFlow.ImplTypePCELL_Cap ]: subNodes = self.addInst(subCkt, 2, ioNodeIdx) else: raise Exception('Device type of %s not supported' % subCkt.name) self.circuitNodes[topCktIdx][nodeIdx] = subNodes self.removeNetNodes()