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:
parent
d641f236a3
commit
a4e46444e2
|
@ -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"
|
||||||
|
@ -489,8 +495,8 @@ namespace {
|
||||||
// << "plug: <" << masterNetName << ">, "
|
// << "plug: <" << masterNetName << ">, "
|
||||||
// << "external: <" << netName << ">."
|
// << "external: <" << netName << ">."
|
||||||
// << endl;
|
// << endl;
|
||||||
Net* net = _cell->getNet( netName );
|
Net* net = _cell->getNet( netName );
|
||||||
Net* masterNet = instance->getMasterCell()->getNet(masterNetName);
|
Net* masterNet = instance->getMasterCell()->getNet(masterNetName);
|
||||||
if(not masterNet) {
|
if(not masterNet) {
|
||||||
ostringstream tmes;
|
ostringstream tmes;
|
||||||
tmes << "The master net <" << masterNetName << "> hasn't been found "
|
tmes << "The master net <" << masterNetName << "> hasn't been found "
|
||||||
|
@ -501,7 +507,7 @@ namespace {
|
||||||
throw Error(tmes.str());
|
throw Error(tmes.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
Plug* plug = instance->getPlug( masterNet );
|
Plug* plug = instance->getPlug( masterNet );
|
||||||
if(not plug) {
|
if(not plug) {
|
||||||
ostringstream tmes;
|
ostringstream tmes;
|
||||||
tmes << "The plug in net <" << netName << "> "
|
tmes << "The plug in net <" << netName << "> "
|
||||||
|
@ -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 );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue