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 ()
{
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 );
}
}
}
}

View File

@ -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;