Etesian manage top level obstacles when placing a sub-block.
Note: To implement this in a more flexible way we should introduce a concept of Instance/Cell "placeholder" to reserve space transhierarchically. * Change: In EtesianEngine::toColoquinte(), when placing only one block in a cell, the cell itself can contains other fixed instances that are over the placement area. Create dummy fixed instances to reserve the taken space. In EtesianEngine::AddFeeds(), do not put feed cells over the cell area occuped by the sibling instances cells. * Cleanup: In KatanaEngine::setupPowerRails(): small cleanup.
This commit is contained in:
parent
0217ca1f26
commit
e6e667c6c7
|
@ -370,6 +370,22 @@ namespace Etesian {
|
||||||
|
|
||||||
sliceHoles.setSpinSlice0( _yspinSlice0 );
|
sliceHoles.setSpinSlice0( _yspinSlice0 );
|
||||||
|
|
||||||
|
if (getBlockInstance()) {
|
||||||
|
Transformation toBlockTransf = getBlockInstance()->getTransformation();
|
||||||
|
toBlockTransf.invert();
|
||||||
|
for ( Instance* instance : getCell()->getInstances() ) {
|
||||||
|
if (instance == getBlockInstance()) continue;
|
||||||
|
if (instance->getPlacementStatus() == Instance::PlacementStatus::FIXED) {
|
||||||
|
Box overlapAb = instance->getAbutmentBox();
|
||||||
|
toBlockTransf.applyOn( overlapAb );
|
||||||
|
overlapAb = topCellAb.getIntersection( overlapAb );
|
||||||
|
if (not overlapAb.isEmpty()) {
|
||||||
|
sliceHoles.merge( overlapAb );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for ( Occurrence occurrence : getBlockCell()->getTerminalNetlistInstanceOccurrences() )
|
for ( Occurrence occurrence : getBlockCell()->getTerminalNetlistInstanceOccurrences() )
|
||||||
{
|
{
|
||||||
Instance* instance = static_cast<Instance*>(occurrence.getEntity());
|
Instance* instance = static_cast<Instance*>(occurrence.getEntity());
|
||||||
|
|
|
@ -577,13 +577,24 @@ namespace Etesian {
|
||||||
Dots dots ( cmess2, " ", 80, 1000 );
|
Dots dots ( cmess2, " ", 80, 1000 );
|
||||||
if (not cmess2.enabled()) dots.disable();
|
if (not cmess2.enabled()) dots.disable();
|
||||||
|
|
||||||
Box topAb = getBlockCell()->getAbutmentBox();
|
|
||||||
Transformation topTransformation;
|
|
||||||
if (getBlockInstance()) topTransformation = getBlockInstance()->getTransformation();
|
|
||||||
topTransformation.applyOn( topAb );
|
|
||||||
|
|
||||||
size_t instancesNb = 0;
|
size_t instancesNb = 0;
|
||||||
size_t fixedNb = 0;
|
size_t fixedNb = 0;
|
||||||
|
Box topAb = getBlockCell()->getAbutmentBox();
|
||||||
|
Transformation topTransformation;
|
||||||
|
if (getBlockInstance()) {
|
||||||
|
topTransformation = getBlockInstance()->getTransformation();
|
||||||
|
topTransformation.applyOn( topAb );
|
||||||
|
for ( Instance* instance : getCell()->getInstances() ) {
|
||||||
|
if (instance == getBlockInstance()) continue;
|
||||||
|
if (instance->getPlacementStatus() == Instance::PlacementStatus::FIXED) {
|
||||||
|
if (topAb.intersect(instance->getAbutmentBox())) {
|
||||||
|
++instancesNb;
|
||||||
|
++fixedNb;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for ( Occurrence occurrence : getCell()->getTerminalNetlistInstanceOccurrences(getBlockInstance()) ) {
|
for ( Occurrence occurrence : getCell()->getTerminalNetlistInstanceOccurrences(getBlockInstance()) ) {
|
||||||
++instancesNb;
|
++instancesNb;
|
||||||
Instance* instance = static_cast<Instance*>(occurrence.getEntity());
|
Instance* instance = static_cast<Instance*>(occurrence.getEntity());
|
||||||
|
@ -611,8 +622,37 @@ namespace Etesian {
|
||||||
//getCell()->flattenNets( Cell::Flags::BuildRings|Cell::Flags::NoClockFlatten );
|
//getCell()->flattenNets( Cell::Flags::BuildRings|Cell::Flags::NoClockFlatten );
|
||||||
getCell()->flattenNets( getBlockInstance(), Cell::Flags::NoClockFlatten );
|
getCell()->flattenNets( getBlockInstance(), Cell::Flags::NoClockFlatten );
|
||||||
|
|
||||||
|
|
||||||
bool tooManyInstances = false;
|
bool tooManyInstances = false;
|
||||||
index_t instanceId = 0;
|
index_t instanceId = 0;
|
||||||
|
if (getBlockInstance()) {
|
||||||
|
for ( Instance* instance : getCell()->getInstances() ) {
|
||||||
|
if (instance == getBlockInstance()) continue;
|
||||||
|
if (instance->getPlacementStatus() == Instance::PlacementStatus::FIXED) {
|
||||||
|
Box overlapAb = topAb.getIntersection( instance->getAbutmentBox() );
|
||||||
|
if (not overlapAb.isEmpty()) {
|
||||||
|
// Upper rounded
|
||||||
|
int_t xsize = (overlapAb.getWidth () + vpitch - 1) / vpitch;
|
||||||
|
int_t ysize = (overlapAb.getHeight() + hpitch - 1) / hpitch;
|
||||||
|
// Lower rounded
|
||||||
|
int_t xpos = overlapAb.getXMin() / vpitch;
|
||||||
|
int_t ypos = overlapAb.getYMin() / hpitch;
|
||||||
|
|
||||||
|
instances[instanceId].size = point<int_t>( xsize, ysize );
|
||||||
|
instances[instanceId].list_index = instanceId;
|
||||||
|
instances[instanceId].area = static_cast<capacity_t>(xsize) * static_cast<capacity_t>(ysize);
|
||||||
|
positions[instanceId] = point<int_t>( xpos, ypos );
|
||||||
|
instances[instanceId].attributes = 0;
|
||||||
|
|
||||||
|
_cellsToIds.insert( make_pair(getString(instance->getName()),instanceId) );
|
||||||
|
_idsToInsts.push_back( instance );
|
||||||
|
++instanceId;
|
||||||
|
dots.dot();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for ( Occurrence occurrence : getCell()->getTerminalNetlistInstanceOccurrences(getBlockInstance()) )
|
for ( Occurrence occurrence : getCell()->getTerminalNetlistInstanceOccurrences(getBlockInstance()) )
|
||||||
{
|
{
|
||||||
if (tooManyInstances or (instanceId == instancesNb)) {
|
if (tooManyInstances or (instanceId == instancesNb)) {
|
||||||
|
|
|
@ -251,17 +251,15 @@ namespace {
|
||||||
cdebug_log(159,0) << " getRootNet:" << path << ":" << net << endl;
|
cdebug_log(159,0) << " getRootNet:" << path << ":" << net << endl;
|
||||||
|
|
||||||
if (net == _blockage) return _blockage;
|
if (net == _blockage) return _blockage;
|
||||||
|
|
||||||
if (net->getType() == Net::Type::POWER ) return _vdd;
|
if (net->getType() == Net::Type::POWER ) return _vdd;
|
||||||
if (net->getType() == Net::Type::GROUND) return _vss;
|
if (net->getType() == Net::Type::GROUND) return _vss;
|
||||||
if (net->getType() != Net::Type::CLOCK ) {
|
if (net->getType() != Net::Type::CLOCK ) return NULL;
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Track up, *only* for clocks.
|
// Track up, *only* for clocks.
|
||||||
const Net* upNet = net;
|
const Net* upNet = net;
|
||||||
|
|
||||||
if (not path.isEmpty()) {
|
if (not path.isEmpty()) {
|
||||||
|
cdebug_log(159,0) << " Path is *not* empty:" << path << endl;
|
||||||
DeepNet* deepClockNet = getTopCell()->getDeepNet( path, net );
|
DeepNet* deepClockNet = getTopCell()->getDeepNet( path, net );
|
||||||
if (deepClockNet) {
|
if (deepClockNet) {
|
||||||
cdebug_log(159,0) << " Deep Clock Net:" << deepClockNet
|
cdebug_log(159,0) << " Deep Clock Net:" << deepClockNet
|
||||||
|
@ -292,15 +290,17 @@ namespace {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cdebug_log(159,0) << " Check againts top clocks ck:"
|
cdebug_log(159,0) << " Check against top clocks ck:"
|
||||||
<< ((_ck) ? _ck->getName() : "NULL") << endl;
|
<< ((_ck) ? _ck->getName() : "NULL") << endl;
|
||||||
|
|
||||||
if (_ck) {
|
if (_ck) {
|
||||||
if (upNet->getName() == _ck->getName()) {
|
if (upNet->getName() == _ck->getName()) {
|
||||||
|
cdebug_log(159,0) << " Clock name matches upNet." << endl;
|
||||||
if (isCoreClockNetRouted(upNet)) return _ck;
|
if (isCoreClockNetRouted(upNet)) return _ck;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cdebug_log(159,0) << " upNet fixed:" << NetRoutingExtension::isFixed(upNet) << endl;
|
||||||
return NetRoutingExtension::isFixed(upNet) ? _blockage : NULL;
|
return NetRoutingExtension::isFixed(upNet) ? _blockage : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue