Bug, uniquification of unique cells.

* In Hurricane: In Instance::slaveAbutmentBox() and Instance::uniquify()
    use isUnique() instead of isUniquified(). This way we do not clone
    masterCells that are unique in the design. This was the reason
    sometimes "holes" were appearing in the visualiser, as the AB were
    not merged. The uniqification policy may need some refinement.
This commit is contained in:
Jean-Paul Chaput 2016-03-27 17:13:30 +02:00
parent a78882fd5b
commit bbab2d14eb
3 changed files with 90 additions and 64 deletions

View File

@ -426,6 +426,10 @@ bool Cell::isNetAlias ( const Name& name ) const
bool Cell::isUnique() const bool Cell::isUnique() const
// ************************ // ************************
{ {
// ltrace(10) << "Cell::isUnique() " << this << endl;
// for ( Instance* instance : getSlaveInstances() ) {
// ltrace(10) << "| Slave instance:" << instance << endl;
// }
return getSlaveInstances().getSize() < 2; return getSlaveInstances().getSize() < 2;
} }
@ -784,7 +788,8 @@ Cell* Cell::getClone()
void Cell::uniquify(unsigned int depth) void Cell::uniquify(unsigned int depth)
// ************************************ // ************************************
{ {
//cerr << "Cell::uniquify() " << this << endl; ltrace(10) << "Cell::uniquify() " << this << endl;
ltracein(10);
vector<DeepNet*> deepNets; vector<DeepNet*> deepNets;
for ( DeepNet* deepNet : getNets().getSubSet<DeepNet*>() ) { for ( DeepNet* deepNet : getNets().getSubSet<DeepNet*>() ) {
@ -800,6 +805,7 @@ void Cell::uniquify(unsigned int depth)
for ( Instance* instance : getInstances() ) { for ( Instance* instance : getInstances() ) {
Cell* masterCell = instance->getMasterCell(); Cell* masterCell = instance->getMasterCell();
ltrace(10) << "| " << instance << endl;
if (masterCell->isTerminal()) continue; if (masterCell->isTerminal()) continue;
if (masterCells.find(masterCell) == masterCells.end()) { if (masterCells.find(masterCell) == masterCells.end()) {
@ -821,6 +827,9 @@ void Cell::uniquify(unsigned int depth)
for ( auto cell : masterCells ) for ( auto cell : masterCells )
cell->uniquify( depth-1 ); cell->uniquify( depth-1 );
} }
ltraceout(10);
ltrace(10) << "Cell::uniquify() END " << this << endl;
} }
void Cell::materialize() void Cell::materialize()

View File

@ -428,68 +428,80 @@ void Instance::setPlacementStatus(const PlacementStatus& placementStatus)
void Instance::setMasterCell(Cell* masterCell, bool secureFlag) void Instance::setMasterCell(Cell* masterCell, bool secureFlag)
// ************************************************************ // ************************************************************
{ {
if (masterCell != _masterCell) { ltrace(10) << "Instance::setMasterCell() on " << this << endl;
UpdateSession::open(); ltracein(10);
ltrace(10) << "NEW masterCell:" << masterCell << endl;
if (!masterCell) if (masterCell != _masterCell) {
throw Error("Can't set master : null master cell"); UpdateSession::open();
if (secureFlag && _cell->isCalledBy(masterCell)) if (!masterCell)
throw Error("Can't set master : cyclic construction"); throw Error("Can't set master : null master cell");
list<Plug*> connectedPlugList; if (secureFlag && _cell->isCalledBy(masterCell))
list<Net*> masterNetList; throw Error("Can't set master : cyclic construction");
for_each_plug(plug, getConnectedPlugs()) {
Net* masterNet = masterCell->getNet(plug->getMasterNet()->getName());
if (!masterNet || !masterNet->isExternal())
throw Error("Can't set master (bad master net matching)");
connectedPlugList.push_back(plug);
masterNetList.push_back(masterNet);
end_for;
}
for_each_shared_path(sharedPath, _getSharedPathes()) { list<Plug*> connectedPlugList;
if (!sharedPath->getTailSharedPath()) list<Net*> masterNetList;
// if the tail is empty the SharedPath isn't impacted by the change for_each_plug(plug, getConnectedPlugs()) {
delete sharedPath; Net* masterNet = masterCell->getNet(plug->getMasterNet()->getName());
end_for; if (!masterNet || !masterNet->isExternal())
} throw Error("Can't set master (bad master net matching)");
connectedPlugList.push_back(plug);
invalidate(true); masterNetList.push_back(masterNet);
end_for;
for_each_plug(plug, getUnconnectedPlugs()) {
plug->_destroy();
end_for;
}
while (!connectedPlugList.empty() && !masterNetList.empty()) {
Plug* plug = connectedPlugList.front();
Net* masterNet = masterNetList.front();
_plugMap._remove(plug);
plug->_setMasterNet(masterNet);
_plugMap._insert(plug);
connectedPlugList.pop_front();
masterNetList.pop_front();
}
_masterCell->_getSlaveInstanceSet()._remove(this);
_masterCell = masterCell;
_masterCell->_getSlaveInstanceSet()._insert(this);
for_each_net(externalNet, _masterCell->getExternalNets()) {
if (!getPlug(externalNet)) Plug::_create(this, externalNet);
end_for;
}
UpdateSession::close();
} }
for_each_shared_path(sharedPath, _getSharedPathes()) {
if (!sharedPath->getTailSharedPath())
// if the tail is empty the SharedPath isn't impacted by the change
delete sharedPath;
end_for;
}
invalidate(true);
for_each_plug(plug, getUnconnectedPlugs()) {
plug->_destroy();
end_for;
}
while (!connectedPlugList.empty() && !masterNetList.empty()) {
Plug* plug = connectedPlugList.front();
Net* masterNet = masterNetList.front();
_plugMap._remove(plug);
plug->_setMasterNet(masterNet);
_plugMap._insert(plug);
connectedPlugList.pop_front();
masterNetList.pop_front();
}
ltrace(10) << "Remove " << this << " from " << _masterCell << endl;
_masterCell->_getSlaveInstanceSet()._remove(this);
_masterCell = masterCell;
ltrace(10) << "Add (before) " << this << " to " << _masterCell << endl;
_masterCell->isUnique();
_masterCell->_getSlaveInstanceSet()._insert(this);
ltrace(10) << "Add (after) " << this << " to " << _masterCell << endl;
_masterCell->isUnique();
for_each_net(externalNet, _masterCell->getExternalNets()) {
if (!getPlug(externalNet)) Plug::_create(this, externalNet);
end_for;
}
UpdateSession::close();
}
ltraceout(10);
} }
void Instance::uniquify() void Instance::uniquify()
// ********************** // **********************
{ {
if (_masterCell->isUniquified()) { if (_masterCell->isUnique()) {
cerr << Warning( "Instance::uniquify(): Master Cell %s of %s is already uniquified, cancelled." cerr << Warning( "Instance::uniquify(): Master Cell %s of %s is unique or already uniquified, cancelled."
, getString(_masterCell->getName()).c_str() , getString(_masterCell->getName()).c_str()
, getString(getName()).c_str() , getString(getName()).c_str()
) << endl; ) << endl;
@ -511,7 +523,7 @@ void Instance::uniquify()
void Instance::slaveAbutmentBox() void Instance::slaveAbutmentBox()
// ****************************** // ******************************
{ {
if (not _masterCell->isUniquified()) uniquify(); if (not _masterCell->isUnique()) uniquify();
_masterCell->slaveAbutmentBox( getCell() ); _masterCell->slaveAbutmentBox( getCell() );
//_masterCell->_setShuntedPath( Path(getCell()->getShuntedPath(),this) ); //_masterCell->_setShuntedPath( Path(getCell()->getShuntedPath(),this) );
setTransformation( Transformation() ); setTransformation( Transformation() );

View File

@ -53,20 +53,25 @@ extern "C" {
trace << "PyDebugSession_open()" << endl; trace << "PyDebugSession_open()" << endl;
HTRY HTRY
PyObject* pySymbol = NULL; PyObject* arg0;
unsigned int traceLevel = 10000; PyObject* arg1;
if (PyArg_ParseTuple( args __cs.init ("DebugSession.open");
, "OI:DebugSession.open"
, &pySymbol if (not PyArg_ParseTuple(args,"|O&O&:DebugSession.open",
, &traceLevel Converter, &arg0,
)) { Converter, &arg1)) {
void* symbol = PyObject_AsHurricaneSymbol( pySymbol ); return NULL;
}
if (__cs.getObjectIds() == INT_ARG ) { DebugSession::open( PyAny_AsLong(arg0) ); }
else if (__cs.getObjectIds() == ":ent:int") {
void* symbol = PyObject_AsHurricaneSymbol( arg0 );
if (not symbol) { if (not symbol) {
Py_RETURN_NONE; Py_RETURN_NONE;
} }
DebugSession::open( symbol, traceLevel ); DebugSession::open( symbol, PyAny_AsLong(arg1) );
} else { } else {
PyErr_SetString( ConstructorError, "Bad parameters given to DebugSession.open()." ); PyErr_SetString(ConstructorError, "invalid number of parameters for DebugSession::open()." );
return NULL; return NULL;
} }
HCATCH HCATCH