📄 oaverilogcallbacksin.cpp
字号:
// *****************************************************************************// CallbacksIn::connectByName()//// Given an instance, a netName and an instTermName, this method establishes// connectivity to the instance by name.// *****************************************************************************voidCallbacksIn::connectByName(const oaName &instName, const oaName &netName, const oaName &instTermName){ if (isLeaf) { return; } oaModNet *net = getNet(netName, oacSignalSigType, NULL, NULL, false); oaModInst *inst = findInst(instName); oaName termName(instTermName); if (instTermName.getType() == oacScalarNameType) { expandITermScalarName(*instTermName.getScalar(), *net, *inst, termName); } if (inst->getNumBits() > 1) { expandCreateInstTerm((oaModVectorInst*) inst, net, termName); } else { createInstTerm(net, inst, termName); }}// *****************************************************************************// CallbacksIn::connectByOrder()//// Given an instance and a list of port connections this method establishes// connectivity to the instance by position. //// The "netName" is the name of the connecting net. It may be a scalar name// that represents the base name of a bus in which case the entire bus is// expected to be connected. It may also be a vector name representing a bus // or a bus subrange.//// The "termPosition" is the position of the terminal according to a Verilog// module declaration.//// The "bitPosition" is the bit within the given terminal position that is // being connected.// *****************************************************************************voidCallbacksIn::connectByOrder(const oaName &instName, const oaName &netName, oaUInt4 &termPosition, oaUInt4 bitPosition){ if (isLeaf) { return; } oaModNet *net = getNet(netName, oacSignalSigType, NULL, NULL, false); oaUInt4 netBits = net->getNumBits(); oaModInst *inst = findInst(instName); if (inst->getNumBits() > 1) { expandCreateInstTerm((oaModVectorInst*) inst, net, termPosition); } else { oaModInstTerm::create(net, inst, termPosition); }}// *****************************************************************************// CallbacksIn::createInstTerm()//// These functions wrap the creation of instTerms to allow narrow nets to// connect to wide terms.// *****************************************************************************voidCallbacksIn::createInstTerm(oaModNet *net, oaModInst *inst, const oaName &termName){ if (net->getNumBits() == inst->getNumBits() * termName.getNumBits()) { oaModInstTerm::create(net, inst, termName); return; } if (inst->getNumBits() > 1) { createInstTerm(net, (oaModVectorInst*) inst, termName); return; } if (termName.getNumBits() > net->getNumBits()) { oaUInt4 delta = termName.getNumBits() - net->getNumBits(); oaBitOrder order(oacDescendingBitOrder); if (termName.getVector()->getStart() < termName.getVector()->getStop()) { order = oacAscendingBitOrder; } oaModInstTerm::create(createPaddedNet(net, delta, order), inst, termName); widthWarning(net, termName); } else if (termName.getNumBits() < net->getNumBits()) { oaModInstTerm::create(createSubrange(net, termName.getNumBits()), inst, termName); widthWarning(net, termName); }}voidCallbacksIn::createInstTerm(oaModNet *net, oaModInst *inst, const oaUInt4 position){ oaModule *master = inst->getMasterModule(); if (!master) { oaModInstTerm::create(net, inst, position); return; } oaModTerm *term = oaModTerm::find(master, position); if (!term || net->getNumBits() == inst->getNumBits() * term->getNumBits()) { oaModInstTerm::create(net, inst, position); } else if (inst->getNumBits() > 1) { createInstTerm(net, (oaModVectorInst*) inst, term); } else if (term->getNumBits() > net->getNumBits()) { oaUInt4 delta = term->getNumBits() - net->getNumBits(); oaBitOrder order(oacDescendingBitOrder); if (((oaModBusTerm*) term)->getStart() < ((oaModBusTerm*) term)->getStop()) { order = oacAscendingBitOrder; } oaModInstTerm::create(createPaddedNet(net, delta, order), inst, position); widthWarning(net, term); } else if (term->getNumBits() < net->getNumBits()) { oaModInstTerm::create(createSubrange(net, term->getNumBits()), inst, position); widthWarning(net, term); }}voidCallbacksIn::createInstTerm(oaModNet *net, oaModVectorInst *inst, const oaName &termName){ if (net->getType() != oacModBundleNetType && net->getNumBits() == termName.getNumBits()) { oaString netNameStr; net->getName(vns, netNameStr); oaSimpleName netName(vns, netNameStr); oaBundleName bundleNetName; bundleNetName.append(netName, inst->getNumBits()); oaModInstTerm::create(getNet(bundleNetName, net->getSigType(), NULL, false), inst, termName); } else { oaString termNameStr; oaString netNameStr; oaName netName; net->getName(netName); Options::oaNameToString(termName, termNameStr); Options::oaNameToString(netName, netNameStr); throw Error(WidthMismatch, fileAndLine, (const char*) termNameStr, (const char*) netNameStr); }}voidCallbacksIn::createInstTerm(oaModNet *net, oaModVectorInst *inst, oaModTerm *term){ if (net->getType() != oacModBundleNetType && net->getNumBits() == term->getNumBits()) { oaString netNameStr; net->getName(vns, netNameStr); oaSimpleName netName(vns, netNameStr); oaBundleName bundleNetName; bundleNetName.append(netName, inst->getNumBits()); oaModInstTerm::create(getNet(bundleNetName, net->getSigType(), NULL, false), inst, term->getPosition()); } else { oaName termName; oaString termNameStr; oaString netNameStr; oaName netName; term->getName(termName); Options::oaNameToString(termName, termNameStr); net->getName(netName); Options::oaNameToString(netName, netNameStr); throw Error(WidthMismatch, fileAndLine, (const char*) termNameStr, (const char*) netNameStr); }}// *****************************************************************************// CallbacksIn::createPaddedNet()//// This function creates a bundle net that is padded with unconnected nets. The// padding nets will appear on the left of the bundle if the bit order is // descending and on the right if the bit order is ascending.// *****************************************************************************oaModBundleNet*CallbacksIn::createPaddedNet(oaModNet *net, const oaUInt4 padding, const oaBitOrder &order){ oaModule *module = net->getModule(); oaName paddingName; if (padding == 1) { options.makeUniqueNetName(module, oaName(), paddingName); } else { options.makeUniqueNetName(module, padding, paddingName); } oaModNet::create(module, paddingName); oaName netName; oaString netNameStr; oaString paddingNameStr; net->getName(netName); Options::oaNameToString(netName, netNameStr); Options::oaNameToString(paddingName, paddingNameStr); oaBundleName bundle; if (order == oacAscendingBitOrder) { appendToBundleName(netNameStr, bundle); appendToBundleName(paddingNameStr, bundle); } else { appendToBundleName(paddingNameStr, bundle); appendToBundleName(netNameStr, bundle); } return oaModBundleNet::create(module, bundle);}// *****************************************************************************// CallbacksIn::createSubrange()//// This function creates a net that consists of the lower numBits bits of the // input net. If the input net is a bus net then a bus net will be returned. If// the input net is a bundle net, then a bundle will be returned.// *****************************************************************************oaModNet*CallbacksIn::createSubrange(oaModNet *net, const oaUInt4 numBits){ oaModNet *subrange; if (net->getType() == oacModBundleNetType) { oaName netName; net->getName(netName); oaBundleName subRangeName; oaString bitNameStr; oaSimpleName bitName; for (oaUInt4 i = 0; i < numBits; i++) { netName.getBundle()->getBitName(vns, i, bitNameStr); bitName.init(vns, bitNameStr); subRangeName.append(bitName); } subrange = oaModNet::find(net->getModule(), subRangeName); if (!subrange) { subrange = oaModNet::create(net->getModule(), subRangeName, net->getSigType()); } } else { oaUInt4 start; oaUInt4 stop; oaInt4 step; getStartStopStep(*net, start, stop, step); if (start < stop) { stop = start + numBits - 1; } else { start = stop + numBits - 1; } oaName subRangeName; net->getName(subRangeName); subRangeName.getVector()->setStart(start); subRangeName.getVector()->setStop(stop); subrange = oaModNet::find(net->getModule(), subRangeName); if (!subrange) { subrange = oaModNet::create(net->getModule(), subRangeName, net->getSigType()); } } return subrange;}// *****************************************************************************// CallbacksIn::endModule()//// This function is called for each ENDMODULE token. Terminal order is // established (or in the case of leaf cells, validated). If the module is not// a leaf cell then it is saved.// *****************************************************************************voidCallbacksIn::endModule(const ParamList *ports, const ParamList *portParams){ if (ports) { ModuleTypeEnum leafType = currentModuleType; oaScalarName cellName; currentModule->getName(cellName); if (leafType == ModuleIncompleteLeafType || leafType == ModuleCellType) { establishPortOrder(*ports, portParams); if (leafType != ModuleCellType) { leafMgr.setType(currentModuleName, ModuleLeafType); currentModuleType = ModuleLeafType; } } else { validatePorts(*ports, portParams); } } if (isStub(currentModuleName)) { fixStubRefs(); } if (!isLeaf && currentDesign->isModified()) { currentDesign->save(); } currentDesign = NULL; currentModule = NULL; currentModuleType = ModuleUnknownType;}// *****************************************************************************// CallbacksIn::establishPortOrder()//// This function identifies the order of the terminals. Whatever the ordering// mechanism that is used, it must be consistent with the connectByOrder method// (of this class) so the order can be properly determined. If you override// this method to use a different mechanism for port order, then you must also// override the constructor for the callback class.//// The ports parameter array contains the terminal names in the order in which// they were specified in the Verilog netlist. Scalar names in the list may be// bus base names; in which case the entire bus is considered ported and the// terminal order of the bus bits should be based on the terminal order of the// connecting net. The name field of each parameter in the list is the name of// the terminal (port). If the value field is a string, then it is the name of// the connecting net. If the value field is not a string, then the terminal is// actually a place-holder that does not have any connectivity within the// module.//// This callback is invoked as one of the last actions of a module// declaration. We can safely assume that all nets, terms, and module// instantiations in the module declaration have already been processed.// *****************************************************************************voidCallbacksIn::establishPortOrder(const ParamList &ports, const ParamList *params){ oaUInt4 index = 0; oaName termName; oaString termNameStr; oaName netName; const oaName emptyName; oaUInt4 i = 0; for (ParamListIter portIter = ports.begin(); portIter != ports.end(); portIter++) { (*portIter)->getName(termNameStr); oaBoolean termNameNotEmpty = Options::oaStringToName(termNameStr, termName); oaModTerm *term = NULL; oaModNet *net = NULL; oaUInt4 termStart = 0; oaUInt4 termStop = 0; oaInt4 termStep = 0; // Get the terminal associated with the given port name (if one exists). // Do not create a terminal if the terminal already exists. if (termNameNotEmpty) { term = oaModTerm::find(currentModule, termName); if (term && term->isImplicit()) { term = getExplicitBit(term, 0); } if (!term && (termName.getType() == oacScalarNameType)) { oaScalarName *baseName = termName.getScalar(); oaModBusTermDef *tDf = oaModBusTermDef::find(currentModule, *baseName); if (tDf) { getStartStopStep(*tDf, termStart, termStop, termStep); if (termStart == termStop) { term = oaModBusTermBit::find(currentModule, *baseName, termStart); } else { term = oaModBusTerm::find(currentModule, *baseName, termStart, termStop, 1); } if (term) { term->getName(termName); } else { oaVectorName busName(*baseName, termStart, termStop, 1); termName = busName; } } } } // If the terminal was previously defined and if it already has an // index, then a new terminal with a unique name must be created and // connected to the same net. if (term && term->getPosition() != oacNullIndex && term->getPosition() != i) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -