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.
This commit is contained in:
Jean-Paul Chaput 2016-04-04 17:54:09 +02:00
parent d641f236a3
commit a4e46444e2
2 changed files with 49 additions and 17 deletions

View File

@ -472,6 +472,12 @@ namespace {
void Model::connectSubckts () 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 ) { for ( Subckt* subckt : _subckts ) {
if(not subckt->getModel()) if(not subckt->getModel())
throw Error( "No .model or cell named <%s> has been found.\n" throw Error( "No .model or cell named <%s> has been found.\n"
@ -524,20 +530,38 @@ namespace {
plugNet->addAlias( netName ); plugNet->addAlias( netName );
} }
else if (plugNet != net){ // Plus already connected to another net 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 ){ if (plugNet->isSupply() and not plug->getMasterNet()->isSupply()) {
ostringstream tmes; ostringstream message;
string powType = plugNet->getType() == Net::Type::POWER ? "power" : "ground"; message << "In " << instance << "\n "
string plugName = plugNet->getName()._getString(); // Name of the original net << "Terminal " << plug->getMasterNet()->getName()
tmes << "Connecting instance <" << subckt->getInstanceName() << "> " << " is connected to POWER/GROUND " << plugNet->getName()
<< "of <" << subckt->getModelName() << "> " << " through the alias " << netName
<< "to the " << powType << " net <" << plugName << "> "; << ".";
if(netName != plugName) cerr << Warning( message.str() ) << endl;
tmes << "with the alias <" << netName << ">. ";
tmes << "Maybe you should use tie cells?"; if (plugNet->isPower()) {
cerr << Warning(tmes.str()) << endl; 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 );
}
} }
} }
} }

View File

@ -630,10 +630,18 @@ void Net::merge(Net* net)
throw Error("Can't merge net : itself"); throw Error("Can't merge net : itself");
if (net->getCell() != _cell) 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()) 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_rubber(rubber, net->getRubbers()) rubber->_setNet(this); end_for;
for_each_component(component, net->getComponents()) component->_setNet(this); end_for; for_each_component(component, net->getComponents()) component->_setNet(this); end_for;