00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "torc/packer/Unpacker.hpp"
00017 #include "torc/packer/PrimitiveStructure.hpp"
00018 #include "torc/packer/Virtex5PrimitiveStructure.hpp"
00019 #include "torc/common/DeviceDesignator.hpp"
00020 #include "torc/architecture/DDB.hpp"
00021 #include "torc/architecture/Sites.hpp"
00022 #include "torc/architecture/XdlImporter.hpp"
00023 #include "torc/common/DirectoryTree.hpp"
00024 #include "torc/physical/Design.hpp"
00025 #include "torc/common/DirectoryTree.hpp"
00026 #include "torc/physical/ConfigMap.hpp"
00027 #include "torc/physical/Circuit.hpp"
00028 #include "torc/physical/Factory.hpp"
00029 #include "torc/physical/Instance.hpp"
00030 #include <fstream>
00031 #include <vector>
00032 #include <string>
00033 #include <iostream>
00034 #include <map>
00035
00036 namespace torc {
00037 namespace packer {
00038
00039 using namespace torc::architecture;
00040
00041 void Unpacker::initialize(void) {
00042
00043
00044 torc::common::DeviceDesignator deviceDesignator(mDesignPtr->getDevice() +
00045 mDesignPtr->getPackage()
00046 + mDesignPtr->getSpeedGrade());
00047 mDDBPtr = new DDB(deviceDesignator);
00048 const Sites& sites = mDDBPtr->getSites();
00049
00050
00051 typedef const Array<const PrimitiveDef> PrimitiveDefArray;
00052 PrimitiveDefArray& primitiveDefs = sites.getSiteTypes();
00053 PrimitiveDefArray::const_iterator p = primitiveDefs.begin();
00054 PrimitiveDefArray::const_iterator e = primitiveDefs.end();
00055 while(p < e) {
00056
00057 PrimitiveStructureSharedPtr primitiveStructurePtr
00058 (new Virtex5PrimitiveStructure(&*p++));
00059 const torc::architecture::PrimitiveDef* primitiveDefPtr
00060 = primitiveStructurePtr->getPrimitiveDefPtr();
00061 const std::string& primitiveDefName = primitiveDefPtr->getName();
00062
00063 if(primitiveDefName != "IOB" && primitiveDefName != "IOBM"
00064 && primitiveDefName != "IOBS")
00065 mPrimitiveStructures[primitiveDefName] = primitiveStructurePtr;
00066 }
00067 }
00068
00069
00070 bool Unpacker::findNextElement(const PrimitiveStructure& inPrimitiveStructure,
00071 const torc::architecture::PrimitiveElement& element,
00072 torc::physical::InstanceSharedPtr& inInstancePtr,
00073 NameToElementPtrMap& inUsedElements,
00074 std::vector<std::string> inInstanceInputPins,
00075 CandidateNet& inElementPinsForNet,
00076 const torc::architecture::PrimitiveElementPin*
00077 &outNetSourcePin,
00078 std::vector<torc::physical::InstanceSharedPtr>
00079 &outNewInstances,
00080 ElementPtrToInstancePtrMap &elementToInstanceMap) {
00081
00082
00083 if(inUsedElements.find(element.getName()) != inUsedElements.end()) return true;
00084
00085 const PrimitiveElement* elementPtr = &element;
00086 std::string elementName = element.getName();
00087
00088 const PrimitiveElementPinArray& fetchNextElementPins = element.getPins();
00089 PrimitiveElementPinArray::const_iterator fpp = fetchNextElementPins.begin();
00090 PrimitiveElementPinArray::const_iterator fpe = fetchNextElementPins.end();
00091 std::vector<std::string>::const_iterator instanceInputit;
00092 bool result = false;
00093 bool found = false;
00094 bool isInverter = false;
00095 bool isInputTerminal = false;
00096 bool isOutputTerminal = false;
00097
00098 if(inPrimitiveStructure.mTerminals.find(elementName)
00099 != inPrimitiveStructure.mTerminals.end()) {
00100 const PrimitivePinArray& primitivePins
00101 = inPrimitiveStructure.mPrimitiveDefPtr->getPins();
00102 int primitivePinIndex
00103 = inPrimitiveStructure.mPrimitiveDefPtr->findPinIndexByName
00104 (elementName);
00105 const PrimitivePin& primitivePin = primitivePins[primitivePinIndex];
00106
00107 isInputTerminal = (!primitivePin.isOutput());
00108 isOutputTerminal = (primitivePin.isOutput());
00109 }
00110
00111 if(isInputTerminal){
00112 instanceInputit = find(inInstanceInputPins.begin(),
00113 inInstanceInputPins.end(), elementName);
00114 if(instanceInputit != inInstanceInputPins.end()) {
00115 inUsedElements[elementName]
00116 = inPrimitiveStructure.mElements.find(elementName)->second;
00117 return true;
00118 } else {
00119 return false;
00120 }
00121 }
00122
00123 std::string cfgName;
00124 std::string cfgSetting;
00125 bool hasConfig = inInstancePtr->getConfig(elementName, cfgName, cfgSetting);
00126
00127
00128
00129 int pinIndex;
00130 const PrimitiveElementPin* invPtr;
00131
00132 if(inPrimitiveStructure.mMuxes.find(elementName)
00133 != inPrimitiveStructure.mMuxes.end()){
00134
00135 if(hasConfig){
00136
00137 pinIndex = element.findPinIndexByName(cfgSetting);
00138 const PrimitiveElementPin* muxPtr
00139 = fetchNextElementPins[pinIndex].getPrimitiveConn()
00140 ->getSourcePtr();
00141 invPtr = &fetchNextElementPins[pinIndex];
00142
00143
00144 std::set<const PrimitiveElementPin*>::const_iterator it
00145 = inPrimitiveStructure.mInvertedInputs.find(invPtr);
00146 if(it != inPrimitiveStructure.mInvertedInputs.end()) {
00147 outNetSourcePin = invPtr;
00148 isInverter = true;
00149 } else {
00150 outNetSourcePin = muxPtr;
00151 const PrimitiveElement* nextElementPtr2
00152 = fetchNextElementPins[pinIndex].getPrimitiveConn()
00153 ->getSourcePtr()->getElementPtr();
00154 const PrimitiveElement& nextElement2 = *nextElementPtr2;
00155 return findNextElement(inPrimitiveStructure, nextElement2,
00156 inInstancePtr, inUsedElements,
00157 inInstanceInputPins,
00158 inElementPinsForNet,
00159 outNetSourcePin, outNewInstances,
00160 elementToInstanceMap);
00161 }
00162
00163
00164 } else {
00165 return false;
00166 }
00167 }
00168
00169 if(inPrimitiveStructure.mPower.find(elementName)
00170 != inPrimitiveStructure.mPower.end()){
00171 result = true;
00172 } else if(inPrimitiveStructure.mGround.find(elementName)
00173 != inPrimitiveStructure.mGround.end()){
00174 result = true;
00175 }
00176
00177
00178 if(hasConfig) result = true;
00179
00180
00181 const PrimitiveElementPin* newNetSourcePin;
00182
00183 while(fpp < fpe) {
00184
00185 const PrimitiveElementPin& fetchNextElementPin = *fpp++;
00186 const PrimitiveElementPin* fetchNextElementPinPtr = &fetchNextElementPin;
00187 if(!fetchNextElementPin.isInput()) continue;
00188
00189 if(isInverter && (invPtr != fetchNextElementPinPtr)) continue;
00190
00191 const PrimitiveElement* nextElementPtr
00192 = fetchNextElementPin.getPrimitiveConn()->getSourcePtr()
00193 ->getElementPtr();
00194 const PrimitiveElementPin* sourcePtr
00195 = fetchNextElementPin.getPrimitiveConn()->getSourcePtr();
00196 const PrimitiveElement& nextElement = *nextElementPtr;
00197 std::string nextElementName = fetchNextElementPin.getPrimitiveConn()
00198 ->getSourcePtr()->getElementPtr()->getName();
00199
00200
00201
00202
00203 bool isPower = false;
00204 if(inPrimitiveStructure.mPower.find(nextElementName)
00205 != inPrimitiveStructure.mPower.end()){
00206 isPower = true;
00207 } else if(inPrimitiveStructure.mGround.find(nextElementName)
00208 != inPrimitiveStructure.mGround.end()){
00209 isPower = true;
00210 }
00211 newNetSourcePin = sourcePtr;
00212 found = findNextElement(inPrimitiveStructure, nextElement, inInstancePtr,
00213 inUsedElements, inInstanceInputPins,
00214 inElementPinsForNet, newNetSourcePin,
00215 outNewInstances, elementToInstanceMap);
00216
00217 if(found) {
00218
00219
00220 inElementPinsForNet[newNetSourcePin]
00221 .push_back(fetchNextElementPinPtr);
00222 }
00223 result |= found && !isPower;
00224 }
00225
00226 if (result && !isOutputTerminal){
00227
00228 inUsedElements[elementName] = inPrimitiveStructure.mElements.find
00229 (elementName)->second;
00230 string newName = inInstancePtr->getName();
00231 newName = newName + ":" + elementName + ":" + cfgName;
00232
00233 string typeName = isInverter ? "INV" : elementName;
00234 torc::physical::InstanceSharedPtr newInstancePtr
00235 = torc::physical::Factory::newInstancePtr(newName, typeName,
00236 "", "");
00237
00238 outNewInstances.push_back(newInstancePtr);
00239
00240
00241 newInstancePtr->setConfig(elementName, cfgName, cfgSetting);
00242 std::map<std::string,
00243 std::vector<const PrimitiveElement*> >::const_iterator it;
00244
00245
00246 if(inPrimitiveStructure.mFlops.find(elementName)
00247 != inPrimitiveStructure.mFlops.end()
00248 || inPrimitiveStructure.mLUTs.find(elementName)
00249 != inPrimitiveStructure.mLUTs.end()){
00250
00251 for(it = inPrimitiveStructure.mPrincipalstoOrphans.begin();
00252 it != inPrimitiveStructure.mPrincipalstoOrphans.end(); it++){
00253 if(it->first != elementName) continue;
00254 for(std::vector<const PrimitiveElement*>
00255 ::const_iterator iter = it->second.begin();
00256 iter != it->second.end(); iter++){
00257 const PrimitiveElement* orphanPtr = *iter;
00258 const PrimitiveElement& orphan
00259 = *orphanPtr;
00260 std::string orphanName = orphan.getName();
00261 std::string orphanCfgName,
00262 orphanCfgSetting;
00263 bool configForOrphan = inInstancePtr
00264 ->getConfig(orphanName,
00265 orphanCfgName,
00266 orphanCfgSetting);
00267 if(configForOrphan)
00268 newInstancePtr->setConfig(
00269 orphanName, orphanCfgName,
00270 orphanCfgSetting);
00271 }
00272 }
00273 }
00274 elementToInstanceMap[elementPtr] = newInstancePtr;
00275 return true;
00276 }
00277 return false;
00278 }
00279
00280
00281 void Unpacker::unpack(void) {
00282 torc::physical::Circuit::InstanceSharedPtrConstIterator ip
00283 = mDesignPtr->instancesBegin();
00284 torc::physical::Circuit::InstanceSharedPtrConstIterator ie
00285 = mDesignPtr->instancesEnd();
00286 unpack(ip, ie);
00287 }
00288
00289
00290 void Unpacker::unpack(torc::physical::Circuit::InstanceSharedPtrConstIterator ip,
00291 torc::physical::Circuit::InstanceSharedPtrConstIterator ie) {
00292 std::vector<torc::physical::InstanceSharedPtr> oldInstances;
00293 std::vector<torc::physical::InstanceSharedPtr> newInstances;
00294 std::vector<torc::physical::InstanceSharedPtr>::iterator instIt;
00295
00296 while(ip < ie){
00297
00298 torc::physical::InstanceSharedPtr instancePtr = *ip++;
00299 torc::physical::Instance& instance = *instancePtr;
00300 std::string instanceType = instance.getType();
00301 std::string instanceName = instance.getName();
00302 CandidateNet elementPinsForNet;
00303 CandidateNet::const_iterator it1;
00304
00305 NameToElementPtrMap usedElements;
00306 NameToElementPtrMap::const_iterator it;
00307 ElementPtrToInstancePtrMap elementToInstanceMap;
00308 ElementPtrToInstancePtrMap::const_iterator elementToInstanceMapit;
00309 std::vector<std::string> instanceInputPins;
00310 std::vector<std::string> instanceOutputPins;
00311 std::vector<std::string> usedPower;
00312 std::vector<std::string> usedGround;
00313 const PrimitiveElementPin* outNetSourcePin = 0;
00314
00315
00316 PrimitiveStructuresSharedPtrMap::const_iterator pos;
00317
00318 pos = mPrimitiveStructures.find(instanceType);
00319 if(pos != mPrimitiveStructures.end()){
00320
00321 const PrimitiveStructure& primitiveStructure = *(pos->second);
00322 const PrimitiveDef* primitiveDefPtr
00323 = primitiveStructure.getPrimitiveDefPtr();
00324
00325 if(primitiveDefPtr == 0) return;
00326 const PrimitivePinArray& primitivePins
00327 = primitiveDefPtr->getPins();
00328
00329 using torc::physical::InstancePinSharedPtr;
00330 using torc::physical::InstancePinSharedPtrVector;
00331 using torc::physical::Instance;
00332 using torc::physical::NetSharedPtr;
00333 using torc::architecture::xilinx::PinIndex;
00334
00335
00336 InstancePinSharedPtrVector inputPins;
00337 InstancePinSharedPtrVector outputPins;
00338 Instance::InstancePinSharedPtrConstIterator ipp
00339 = instancePtr->pinsBegin();
00340 Instance::InstancePinSharedPtrConstIterator ipe
00341 = instancePtr->pinsEnd();
00342 InstancePinSharedPtr instancePinPtr;
00343 NetSharedPtr netPtr;
00344 while(ipp != ipe) {
00345
00346 InstancePinSharedPtr instancePinPtr = ipp++->second;
00347 const std::string& pinName = instancePinPtr->getPinName();
00348 netPtr = instancePinPtr->getParentWeakPtr().lock();
00349
00350
00351 PinIndex pinIndex
00352 = primitiveDefPtr->findPinIndexByName(pinName);
00353
00354 if(static_cast<boost::int32_t>(pinIndex) < 0) continue;
00355 const PrimitivePin& primitivePin = primitivePins[pinIndex];
00356 if(primitivePin.isInput())
00357 inputPins.push_back(instancePinPtr);
00358 if(primitivePin.isOutput())
00359 outputPins.push_back(instancePinPtr);
00360
00361
00362 }
00363
00364 InstancePinSharedPtrVector::const_iterator ipp2;
00365 InstancePinSharedPtrVector::const_iterator ipe2;
00366
00367 ipp2 = inputPins.begin();
00368 ipe2 = inputPins.end();
00369 while(ipp2 != ipe2) {
00370 InstancePinSharedPtr instancePinPtr = *ipp2++;
00371 instanceInputPins.push_back(instancePinPtr->getPinName());
00372
00373 }
00374
00375 ipp2 = outputPins.begin();
00376 ipe2 = outputPins.end();
00377 while(ipp2 != ipe2) {
00378 InstancePinSharedPtr instancePinPtr = *ipp2++;
00379 instanceOutputPins.push_back(instancePinPtr->getPinName());
00380 std::cout << " found OUTPUT " << instancePinPtr
00381 ->getPinName() << std::endl;
00382 std::string outPinName = instancePinPtr->getPinName();
00383
00384 const PrimitiveElement* elementPtr
00385 = primitiveStructure.mTerminals.find(outPinName)
00386 ->second;
00387 const PrimitiveElement& element = *elementPtr;
00388 findNextElement(primitiveStructure, element, instancePtr,
00389 usedElements, instanceInputPins,
00390 elementPinsForNet, outNetSourcePin,
00391 newInstances, elementToInstanceMap);
00392 }
00393
00394 for(it1 = elementPinsForNet.begin();
00395 it1 != elementPinsForNet.end(); it1++){
00396 torc::physical::NetSharedPtr net;
00397 PrimitiveElementPinPtrVector terminals;
00398 const PrimitiveElementPin* sourcePinPtr = it1->first;
00399 std::string drivingElementName = sourcePinPtr
00400 ->getElementPtr()->getName();
00401 std::string sourcePinName = sourcePinPtr->getName();
00402
00403
00404 if(primitiveStructure.mTerminals
00405 .find(sourcePinPtr->getElementPtr()->getName())
00406 != primitiveStructure.mTerminals.end()) {
00407
00408 terminals.push_back(sourcePinPtr);
00409 }
00410
00411 for(PrimitiveElementPinPtrVector::const_iterator iter
00412 = it1->second.begin(); iter
00413 != it1->second.end(); iter++){
00414 const PrimitiveElementPin* sinkPinPtr
00415 = *iter;
00416
00417
00418
00419 if(primitiveStructure.mTerminals.find(sinkPinPtr
00420 ->getElementPtr()->getName())
00421 != primitiveStructure.mTerminals.end()){
00422 terminals.push_back(sinkPinPtr);
00423 std::string sinkPinName
00424 = sinkPinPtr->getName();
00425
00426
00427 }
00428 }
00429
00430
00431
00432 if(terminals.size() > 1){
00433 std::string netName = instancePtr->getName()
00434 + ":" + drivingElementName + ":"
00435 + sourcePinName;
00436 net = torc::physical::Factory::newNetPtr(netName);
00437 for(std::vector<const PrimitiveElementPin*>
00438 ::const_iterator iter
00439 = terminals.begin();
00440 iter != terminals.end(); iter++){
00441 Instance::InstancePinSharedPtrConstIterator
00442 pin = instancePtr
00443 ->findPin(torc::physical
00444 ::PinName(sourcePinPtr
00445 ->getName()));
00446 InstancePinSharedPtr pinPtr = pin->second;
00447 torc::physical::NetSharedPtr net2
00448 = pinPtr
00449 ->getParentWeakPtr().lock();
00450 for(torc::physical::Net
00451 ::InstancePinSharedPtrIterator
00452 netSourceIter = net2
00453 ->sourcesBegin();
00454 netSourceIter != net2->sourcesEnd();
00455 netSourceIter++ ){
00456 net->addSource(*netSourceIter);
00457 }
00458 for(torc::physical::Net
00459 ::InstancePinSharedPtrIterator
00460 netSinkIter = net2
00461 ->sourcesBegin();
00462 netSinkIter != net2->sourcesEnd();
00463 netSinkIter++ ){
00464 net->addSink(*netSinkIter);
00465 }
00466 mDesignPtr->removeNet(net2);
00467 }
00468
00469
00470
00471 } else if(terminals.size() == 1){
00472 Instance::InstancePinSharedPtrConstIterator pin
00473 = instancePtr
00474 ->findPin(torc::physical::PinName
00475 (terminals.front()->getName()));
00476 InstancePinSharedPtr pinPtr = pin->second;
00477 net = pinPtr->getParentWeakPtr().lock();
00478 net->unroute();
00479
00480
00481 } else {
00482
00483 std::cout << "Adding a new net" << std::endl;
00484 std::string netName = instancePtr->getName()
00485 + ":" + drivingElementName + ":"
00486 + sourcePinName;
00487 net = torc::physical::Factory::newNetPtr(netName);
00488 mDesignPtr->addNet(net);
00489 }
00490
00491
00492 if(primitiveStructure.mTerminals.find(sourcePinPtr
00493 ->getElementPtr()
00494 ->getName())
00495 != primitiveStructure.mTerminals.end()) {
00496 Instance::InstancePinSharedPtrConstIterator pin1
00497 = instancePtr
00498 ->findPin(torc::physical::PinName
00499 (sourcePinPtr->getName()));
00500 InstancePinSharedPtr pin1Ptr = pin1->second;
00501
00502
00503 net->removeSink(pin1Ptr);
00504 }else{
00505 torc::physical::InstanceSharedPtr instanceSourcePtr
00506 = elementToInstanceMap.find(sourcePinPtr
00507 ->getElementPtr())->second;
00508 InstancePinSharedPtr instanceSourcePin
00509 = torc::physical::Factory
00510 ::newInstancePinPtr(instanceSourcePtr,
00511 sourcePinName);
00512
00513 net->addSource(instanceSourcePin);
00514 }
00515 const PrimitiveElementPinPtrVector& sinkVector
00516 = it1->second;
00517
00518 for(PrimitiveElementPinPtrVector
00519 ::const_iterator iter = sinkVector.begin();
00520 iter != sinkVector.end(); iter++){
00521 if(primitiveStructure.mTerminals.find((*iter)
00522 ->getElementPtr()->getName())
00523 != primitiveStructure.mTerminals.end()) {
00524 Instance::InstancePinSharedPtrConstIterator
00525 pin2 = instancePtr
00526 ->findPin(torc::physical::PinName
00527 ((*iter)->getName()));
00528 InstancePinSharedPtr pin2Ptr
00529 = pin2->second;
00530 net->removeSource(pin2Ptr);
00531
00532
00533 }else{
00534 torc::physical::InstanceSharedPtr
00535 instanceSinkPtr
00536 = elementToInstanceMap.find((*iter)
00537 ->getElementPtr())->second;
00538 InstancePinSharedPtr instanceSinkPin
00539 = torc::physical::Factory
00540 ::newInstancePinPtr
00541 (instanceSinkPtr,
00542 (*iter)->getName());
00543
00544 net->addSink(instanceSinkPin);
00545 }
00546 }
00547 terminals.clear();
00548 }
00549
00550 oldInstances.push_back(instancePtr);
00551 }
00552
00553
00554
00555
00556 }
00557 std::cout << "-------------------- NEW INSTANCES -------------------" << std::endl;
00558 for(instIt = newInstances.begin(); instIt != newInstances.end(); instIt++){
00559 torc::physical::InstanceSharedPtr newInstancePtr = *instIt;
00560 torc::physical::Instance newInstance = *newInstancePtr;
00561 std::cout << " " << newInstance.getName() << std::endl;
00562 mDesignPtr->addInstance(newInstancePtr);
00563 }
00564 std::cout << "-------------------- OLD INSTANCES -------------------" << std::endl;
00565 for(instIt = oldInstances.begin(); instIt != oldInstances.end(); instIt++){
00566 torc::physical::InstanceSharedPtr oldInstancePtr = *instIt;
00567 torc::physical::Instance oldInstance = *oldInstancePtr;
00568 std::cout << " " << oldInstance.getName() << std::endl;
00569 mDesignPtr->removeInstance(oldInstancePtr);
00570 }
00571
00572 }
00573 }
00574 }