From a4e46444e2572522ac5660522e8f9ea37709af24 Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Mon, 4 Apr 2016 17:54:09 +0200 Subject: [PATCH] Various problems in the BLIF parser. * In CRL Core, in BlifParser, when an input terminal of an instance is either connected to power or ground, insert a zero_x0 or one_x0 Cell to avoid direct connection to the supply (the router is not able to do it). The names and terminals of the intermediate cells are hard-wired for now (to SxLib). When merging Nets, always merge internal nets into external ones as the other way around is not always legal. --- crlcore/src/ccore/blif/BlifParser.cpp | 54 +++++++++++++++++++-------- hurricane/src/hurricane/Net.cpp | 12 +++++- 2 files changed, 49 insertions(+), 17 deletions(-) diff --git a/crlcore/src/ccore/blif/BlifParser.cpp b/crlcore/src/ccore/blif/BlifParser.cpp index 528b0fb2..0823b774 100644 --- a/crlcore/src/ccore/blif/BlifParser.cpp +++ b/crlcore/src/ccore/blif/BlifParser.cpp @@ -472,6 +472,12 @@ namespace { void Model::connectSubckts () { + auto framework = AllianceFramework::get(); + + unsigned int supplyCount = 0; + Cell* zero = framework->getCell( "zero_x0", Catalog::State::Views ); + Cell* one = framework->getCell( "one_x0" , Catalog::State::Views); + for ( Subckt* subckt : _subckts ) { if(not subckt->getModel()) throw Error( "No .model or cell named <%s> has been found.\n" @@ -489,8 +495,8 @@ namespace { // << "plug: <" << masterNetName << ">, " // << "external: <" << netName << ">." // << endl; - Net* net = _cell->getNet( netName ); - Net* masterNet = instance->getMasterCell()->getNet(masterNetName); + Net* net = _cell->getNet( netName ); + Net* masterNet = instance->getMasterCell()->getNet(masterNetName); if(not masterNet) { ostringstream tmes; tmes << "The master net <" << masterNetName << "> hasn't been found " @@ -501,7 +507,7 @@ namespace { throw Error(tmes.str()); } - Plug* plug = instance->getPlug( masterNet ); + Plug* plug = instance->getPlug( masterNet ); if(not plug) { ostringstream tmes; tmes << "The plug in net <" << netName << "> " @@ -524,20 +530,38 @@ namespace { plugNet->addAlias( netName ); } else if (plugNet != net){ // Plus already connected to another net - plugNet->merge( net ); + if (not plugNet->isExternal()) net->merge( plugNet ); + else plugNet->merge( net ); } - if ( plugNet->getType() == Net::Type::POWER or plugNet->getType() == Net::Type::GROUND ){ - ostringstream tmes; - string powType = plugNet->getType() == Net::Type::POWER ? "power" : "ground"; - string plugName = plugNet->getName()._getString(); // Name of the original net - tmes << "Connecting instance <" << subckt->getInstanceName() << "> " - << "of <" << subckt->getModelName() << "> " - << "to the " << powType << " net <" << plugName << "> "; - if(netName != plugName) - tmes << "with the alias <" << netName << ">. "; - tmes << "Maybe you should use tie cells?"; - cerr << Warning(tmes.str()) << endl; + if (plugNet->isSupply() and not plug->getMasterNet()->isSupply()) { + ostringstream message; + message << "In " << instance << "\n " + << "Terminal " << plug->getMasterNet()->getName() + << " is connected to POWER/GROUND " << plugNet->getName() + << " through the alias " << netName + << "."; + cerr << Warning( message.str() ) << endl; + + if (plugNet->isPower()) { + ostringstream insName; insName << "one_" << supplyCount++; + + Instance* insOne = Instance::create( _cell, insName.str(), one ); + Net* netOne = Net::create( _cell, insName.str() ); + + insOne->getPlug( one->getNet("q") )->setNet( netOne ); + plug->setNet( netOne ); + } + + if (plugNet->isGround()) { + ostringstream insName; insName << "zero_" << supplyCount++; + + Instance* insZero = Instance::create( _cell, insName.str(), zero ); + Net* netZero = Net::create( _cell, insName.str() ); + + insZero->getPlug( zero->getNet("nq") )->setNet( netZero ); + plug->setNet( netZero ); + } } } } diff --git a/hurricane/src/hurricane/Net.cpp b/hurricane/src/hurricane/Net.cpp index a1cfb773..71cbf180 100644 --- a/hurricane/src/hurricane/Net.cpp +++ b/hurricane/src/hurricane/Net.cpp @@ -630,10 +630,18 @@ void Net::merge(Net* net) throw Error("Can't merge net : itself"); if (net->getCell() != _cell) - throw Error("Can't merge net : incompatible net"); + throw Error( "Net::merge(): Cannot merge %s (%s) with %s (%s)." + , getString(getName()).c_str() + , getString(getCell()->getName()).c_str() + , getString(net->getName()).c_str() + , getString(net->getCell()->getName()).c_str() + ); if (!isExternal() && net->isExternal() && !net->getConnectedSlavePlugs().isEmpty()) - throw Error("Can't merge net : incompatible net"); + throw Error( "Net::merge(): Cannot merge external (%s) with an internal net (%s)." + , getString(net->getName()).c_str() + , getString(getName()).c_str() + ); for_each_rubber(rubber, net->getRubbers()) rubber->_setNet(this); end_for; for_each_component(component, net->getComponents()) component->_setNet(this); end_for;