Rewrite of the Etesian engine to run the new placer
This commit is contained in:
parent
3830a90482
commit
1e71b5fb08
|
@ -1 +1 @@
|
||||||
Subproject commit 068689b3eea8d2a5b47ada054fba828209897515
|
Subproject commit ea12145d338238d3c92c6863a164d3069560c42e
|
|
@ -18,9 +18,6 @@
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include "coloquinte/circuit.hxx"
|
|
||||||
#include "coloquinte/circuit_helper.hxx"
|
|
||||||
#include "coloquinte/legalizer.hxx"
|
|
||||||
#include "hurricane/configuration/Configuration.h"
|
#include "hurricane/configuration/Configuration.h"
|
||||||
#include "hurricane/utilities/Dots.h"
|
#include "hurricane/utilities/Dots.h"
|
||||||
#include "hurricane/DebugSession.h"
|
#include "hurricane/DebugSession.h"
|
||||||
|
@ -55,10 +52,8 @@ namespace {
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace Hurricane;
|
using namespace Hurricane;
|
||||||
using coloquinte::int_t;
|
|
||||||
using coloquinte::float_t;
|
|
||||||
using coloquinte::point;
|
|
||||||
using Etesian::EtesianEngine;
|
using Etesian::EtesianEngine;
|
||||||
|
using coloquinte::CellOrientation;
|
||||||
|
|
||||||
// Options for both placers
|
// Options for both placers
|
||||||
unsigned const SteinerModel = 0x0001;
|
unsigned const SteinerModel = 0x0001;
|
||||||
|
@ -156,8 +151,8 @@ namespace {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Transformation toTransformation ( point<int_t> position
|
Transformation toTransformation ( coloquinte::Point position
|
||||||
, point<bool> orientation
|
, coloquinte::CellOrientation orientation
|
||||||
, Cell* model
|
, Cell* model
|
||||||
, DbU::Unit hpitch
|
, DbU::Unit hpitch
|
||||||
, DbU::Unit vpitch
|
, DbU::Unit vpitch
|
||||||
|
@ -169,18 +164,44 @@ namespace {
|
||||||
Box cellBox = model->getAbutmentBox();
|
Box cellBox = model->getAbutmentBox();
|
||||||
Transformation::Orientation orient = Transformation::Orientation::ID;
|
Transformation::Orientation orient = Transformation::Orientation::ID;
|
||||||
|
|
||||||
if ( not orientation.x and orientation.y) {
|
switch (orientation) {
|
||||||
tx += cellBox.getWidth();
|
case CellOrientation::N:
|
||||||
orient = Transformation::Orientation::MX;
|
orient = Transformation::Orientation::ID;
|
||||||
} else if ( orientation.x and not orientation.y) {
|
break;
|
||||||
|
case CellOrientation::R180:
|
||||||
ty += cellBox.getHeight();
|
ty += cellBox.getHeight();
|
||||||
orient = Transformation::Orientation::MY;
|
|
||||||
} else if ( not orientation.x and not orientation.y) {
|
|
||||||
tx += cellBox.getWidth();
|
tx += cellBox.getWidth();
|
||||||
ty += cellBox.getHeight();
|
|
||||||
orient = Transformation::Orientation::R2;
|
orient = Transformation::Orientation::R2;
|
||||||
|
break;
|
||||||
|
case CellOrientation::MY:
|
||||||
|
orient = Transformation::Orientation::MY;
|
||||||
|
ty += cellBox.getHeight();
|
||||||
|
break;
|
||||||
|
case CellOrientation::MX:
|
||||||
|
orient = Transformation::Orientation::MX;
|
||||||
|
ty += cellBox.getWidth();
|
||||||
|
break;
|
||||||
|
/*
|
||||||
|
case CellOrientation::R90:
|
||||||
|
orient = Transformation::Orientation::R1;
|
||||||
|
// TODO
|
||||||
|
break;
|
||||||
|
case CellOrientation::R270:
|
||||||
|
orient = Transformation::Orientation::R3;
|
||||||
|
// TODO
|
||||||
|
break;
|
||||||
|
case CellOrientation::MX90:
|
||||||
|
orient = Transformation::Orientation::XR;
|
||||||
|
// TODO
|
||||||
|
break;
|
||||||
|
case CellOrientation::MY90:
|
||||||
|
orient = Transformation::Orientation::YR;
|
||||||
|
// TODO
|
||||||
|
break;
|
||||||
|
*/
|
||||||
|
default:
|
||||||
|
throw Error("Unsupported orientation");
|
||||||
}
|
}
|
||||||
|
|
||||||
return Transformation( tx, ty, orient );
|
return Transformation( tx, ty, orient );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -264,18 +285,6 @@ namespace Etesian {
|
||||||
using CRL::Measures;
|
using CRL::Measures;
|
||||||
using CRL::MeasuresSet;
|
using CRL::MeasuresSet;
|
||||||
using CRL::CatalogExtension;
|
using CRL::CatalogExtension;
|
||||||
using coloquinte::index_t;
|
|
||||||
using coloquinte::capacity_t;
|
|
||||||
using coloquinte::int_t;
|
|
||||||
using coloquinte::float_t;
|
|
||||||
using coloquinte::point;
|
|
||||||
using coloquinte::box;
|
|
||||||
using coloquinte::Movability;
|
|
||||||
using coloquinte::temporary_cell;
|
|
||||||
using coloquinte::temporary_net;
|
|
||||||
using coloquinte::temporary_pin;
|
|
||||||
using coloquinte::netlist;
|
|
||||||
using coloquinte::placement_t;
|
|
||||||
|
|
||||||
const char* missingEtesian =
|
const char* missingEtesian =
|
||||||
"%s :\n\n"
|
"%s :\n\n"
|
||||||
|
@ -308,7 +317,7 @@ namespace Etesian {
|
||||||
, _circuit (NULL)
|
, _circuit (NULL)
|
||||||
, _placementLB (NULL)
|
, _placementLB (NULL)
|
||||||
, _placementUB (NULL)
|
, _placementUB (NULL)
|
||||||
, _densityLimits(NULL)
|
//, _densityLimits(NULL)
|
||||||
, _netsToIds ()
|
, _netsToIds ()
|
||||||
, _instsToIds ()
|
, _instsToIds ()
|
||||||
, _idsToInsts ()
|
, _idsToInsts ()
|
||||||
|
@ -447,7 +456,7 @@ namespace Etesian {
|
||||||
delete _circuit;
|
delete _circuit;
|
||||||
delete _placementLB;
|
delete _placementLB;
|
||||||
delete _placementUB;
|
delete _placementUB;
|
||||||
delete _densityLimits;
|
//delete _densityLimits;
|
||||||
|
|
||||||
NetsToIds emptyNetsToIds;
|
NetsToIds emptyNetsToIds;
|
||||||
_netsToIds.swap( emptyNetsToIds );
|
_netsToIds.swap( emptyNetsToIds );
|
||||||
|
@ -465,7 +474,7 @@ namespace Etesian {
|
||||||
_circuit = NULL;
|
_circuit = NULL;
|
||||||
_placementLB = NULL;
|
_placementLB = NULL;
|
||||||
_placementUB = NULL;
|
_placementUB = NULL;
|
||||||
_densityLimits = NULL;
|
//_densityLimits = NULL;
|
||||||
_diodeCount = 0;
|
_diodeCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -811,10 +820,15 @@ namespace Etesian {
|
||||||
|
|
||||||
// Coloquinte circuit description data-structures.
|
// Coloquinte circuit description data-structures.
|
||||||
// One dummy fixed instance at the end
|
// One dummy fixed instance at the end
|
||||||
vector<Transformation> idsToTransf ( instancesNb+1 );
|
|
||||||
vector<temporary_cell> instances ( instancesNb+1 );
|
_circuit = new coloquinte::Circuit( instancesNb+1 );
|
||||||
vector< point<int_t> > positions ( instancesNb+1 );
|
vector<int> cellX( instancesNb+1 );
|
||||||
vector< point<bool> > orientations( instancesNb+1, point<bool>(true, true) );
|
vector<int> cellY( instancesNb+1 );
|
||||||
|
vector<coloquinte::CellOrientation> orient( instancesNb+1 );
|
||||||
|
vector<int> cellWidth( instancesNb+1 );
|
||||||
|
vector<int> cellHeight( instancesNb+1 );
|
||||||
|
vector<bool> cellIsFixed( instancesNb+1 );
|
||||||
|
vector<bool> cellIsObstruction( instancesNb+1 );
|
||||||
|
|
||||||
cmess1 << ::Dots::asUInt( " - Number of instances ", instancesNb ) << endl;
|
cmess1 << ::Dots::asUInt( " - Number of instances ", instancesNb ) << endl;
|
||||||
if (instancesNb) {
|
if (instancesNb) {
|
||||||
|
@ -837,7 +851,7 @@ namespace Etesian {
|
||||||
getCell()->flattenNets( NULL, _excludedNets, Cell::Flags::NoClockFlatten );
|
getCell()->flattenNets( NULL, _excludedNets, Cell::Flags::NoClockFlatten );
|
||||||
|
|
||||||
bool tooManyInstances = false;
|
bool tooManyInstances = false;
|
||||||
index_t instanceId = 0;
|
int instanceId = 0;
|
||||||
if (getBlockInstance()) {
|
if (getBlockInstance()) {
|
||||||
for ( Instance* instance : getCell()->getInstances() ) {
|
for ( Instance* instance : getCell()->getInstances() ) {
|
||||||
if (instance == getBlockInstance()) continue;
|
if (instance == getBlockInstance()) continue;
|
||||||
|
@ -845,17 +859,18 @@ namespace Etesian {
|
||||||
Box overlapAb = topAb.getIntersection( instance->getAbutmentBox() );
|
Box overlapAb = topAb.getIntersection( instance->getAbutmentBox() );
|
||||||
if (not overlapAb.isEmpty()) {
|
if (not overlapAb.isEmpty()) {
|
||||||
// Upper rounded
|
// Upper rounded
|
||||||
int_t xsize = (overlapAb.getWidth () + vpitch - 1) / vpitch;
|
int xsize = (overlapAb.getWidth () + vpitch - 1) / vpitch;
|
||||||
int_t ysize = (overlapAb.getHeight() + hpitch - 1) / hpitch;
|
int ysize = (overlapAb.getHeight() + hpitch - 1) / hpitch;
|
||||||
// Lower rounded
|
// Lower rounded
|
||||||
int_t xpos = overlapAb.getXMin() / vpitch;
|
int xpos = overlapAb.getXMin() / vpitch;
|
||||||
int_t ypos = overlapAb.getYMin() / hpitch;
|
int ypos = overlapAb.getYMin() / hpitch;
|
||||||
|
|
||||||
instances[instanceId].size = point<int_t>( xsize, ysize );
|
cellX[instanceId] = xpos;
|
||||||
instances[instanceId].list_index = instanceId;
|
cellY[instanceId] = ypos;
|
||||||
instances[instanceId].area = static_cast<capacity_t>(xsize) * static_cast<capacity_t>(ysize);
|
cellWidth[instanceId] = xsize;
|
||||||
positions[instanceId] = point<int_t>( xpos, ypos );
|
cellHeight[instanceId] = ysize;
|
||||||
instances[instanceId].attributes = 0;
|
cellIsFixed[instanceId] = true;
|
||||||
|
cellIsObstruction[instanceId] = true;
|
||||||
|
|
||||||
_instsToIds.insert( make_pair(instance,instanceId) );
|
_instsToIds.insert( make_pair(instance,instanceId) );
|
||||||
_idsToInsts.push_back( make_tuple(instance,vector<RoutingPad*>()) );
|
_idsToInsts.push_back( make_tuple(instance,vector<RoutingPad*>()) );
|
||||||
|
@ -904,11 +919,11 @@ namespace Etesian {
|
||||||
instanceTransf.applyOn( instanceAb );
|
instanceTransf.applyOn( instanceAb );
|
||||||
|
|
||||||
// Upper rounded
|
// Upper rounded
|
||||||
int_t xsize = (instanceAb.getWidth () + vpitch - 1) / vpitch;
|
int xsize = (instanceAb.getWidth () + vpitch - 1) / vpitch;
|
||||||
int_t ysize = (instanceAb.getHeight() + hpitch - 1) / hpitch;
|
int ysize = (instanceAb.getHeight() + hpitch - 1) / hpitch;
|
||||||
// Lower rounded
|
// Lower rounded
|
||||||
int_t xpos = instanceAb.getXMin() / vpitch;
|
int xpos = instanceAb.getXMin() / vpitch;
|
||||||
int_t ypos = instanceAb.getYMin() / hpitch;
|
int ypos = instanceAb.getYMin() / hpitch;
|
||||||
|
|
||||||
//if (xsize < 6) xsize += 2;
|
//if (xsize < 6) xsize += 2;
|
||||||
|
|
||||||
|
@ -926,18 +941,17 @@ namespace Etesian {
|
||||||
if (isFlexLib and not instance->isFixed() and (masterName == "buf_x8"))
|
if (isFlexLib and not instance->isFixed() and (masterName == "buf_x8"))
|
||||||
++xsize;
|
++xsize;
|
||||||
|
|
||||||
instances[instanceId].size = point<int_t>( xsize, ysize );
|
cellX[instanceId] = xpos;
|
||||||
instances[instanceId].list_index = instanceId;
|
cellY[instanceId] = ypos;
|
||||||
instances[instanceId].area = static_cast<capacity_t>(xsize) * static_cast<capacity_t>(ysize);
|
cellWidth[instanceId] = xsize;
|
||||||
positions[instanceId] = point<int_t>( xpos, ypos );
|
cellHeight[instanceId] = ysize;
|
||||||
|
|
||||||
if ( not instance->isFixed() and instance->isTerminalNetlist() ) {
|
if ( not instance->isFixed() and instance->isTerminalNetlist() ) {
|
||||||
instances[instanceId].attributes = coloquinte::XMovable
|
cellIsFixed[instanceId] = false;
|
||||||
|coloquinte::YMovable
|
cellIsObstruction[instanceId] = false;
|
||||||
|coloquinte::XFlippable
|
|
||||||
|coloquinte::YFlippable;
|
|
||||||
} else {
|
} else {
|
||||||
instances[instanceId].attributes = 0;
|
cellIsFixed[instanceId] = true;
|
||||||
|
cellIsObstruction[instanceId] = true;
|
||||||
// cerr << endl;
|
// cerr << endl;
|
||||||
// cerr << "FIXED " << instance << endl;
|
// cerr << "FIXED " << instance << endl;
|
||||||
// cerr << " id=" << instanceId
|
// cerr << " id=" << instanceId
|
||||||
|
@ -965,11 +979,12 @@ namespace Etesian {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dummy fixed instance at the end
|
// Dummy fixed instance at the end
|
||||||
instances[instanceId].size = point<int_t>( 0, 0 );
|
cellX[instanceId] = 0;
|
||||||
instances[instanceId].list_index = instanceId;
|
cellY[instanceId] = 0;
|
||||||
instances[instanceId].area = 0;
|
cellWidth[instanceId] = 0;
|
||||||
positions[instanceId] = point<int_t>( 0, 0 );
|
cellHeight[instanceId] = 0;
|
||||||
instances[instanceId].attributes = 0;
|
cellIsFixed[instanceId] = true;
|
||||||
|
cellIsObstruction[instanceId] = true;
|
||||||
|
|
||||||
dots.finish( Dots::Reset|Dots::FirstDot );
|
dots.finish( Dots::Reset|Dots::FirstDot );
|
||||||
|
|
||||||
|
@ -993,8 +1008,6 @@ namespace Etesian {
|
||||||
|
|
||||||
cmess1 << " - Converting " << netsNb << " nets" << endl;
|
cmess1 << " - Converting " << netsNb << " nets" << endl;
|
||||||
|
|
||||||
vector<temporary_net> nets ( netsNb );
|
|
||||||
vector<temporary_pin> pins;
|
|
||||||
_idsToNets.resize( netsNb );
|
_idsToNets.resize( netsNb );
|
||||||
|
|
||||||
unsigned int netId = 0;
|
unsigned int netId = 0;
|
||||||
|
@ -1012,11 +1025,9 @@ namespace Etesian {
|
||||||
|
|
||||||
_netsToIds.insert( make_pair(net,netId) );
|
_netsToIds.insert( make_pair(net,netId) );
|
||||||
_idsToNets[netId] = make_tuple( net, _instsToIds.size(), 0 );
|
_idsToNets[netId] = make_tuple( net, _instsToIds.size(), 0 );
|
||||||
nets[netId] = temporary_net( netId, 1 );
|
|
||||||
|
|
||||||
//cerr << "+ " << net << endl;
|
|
||||||
|
|
||||||
string topCellInstancePin = getString(getCell()->getName()) + ":C";
|
string topCellInstancePin = getString(getCell()->getName()) + ":C";
|
||||||
|
vector<int> netCells, pinX, pinY;
|
||||||
|
|
||||||
for ( RoutingPad* rp : net->getRoutingPads() ) {
|
for ( RoutingPad* rp : net->getRoutingPads() ) {
|
||||||
Path path = rp->getOccurrence().getPath();
|
Path path = rp->getOccurrence().getPath();
|
||||||
|
@ -1024,10 +1035,12 @@ namespace Etesian {
|
||||||
if (pin) {
|
if (pin) {
|
||||||
if (path.isEmpty()) {
|
if (path.isEmpty()) {
|
||||||
Point pt = rp->getCenter();
|
Point pt = rp->getCenter();
|
||||||
int_t xpin = pt.getX() / vpitch;
|
int xpin = pt.getX() / vpitch;
|
||||||
int_t ypin = pt.getY() / hpitch;
|
int ypin = pt.getY() / hpitch;
|
||||||
// Dummy last instance
|
// Dummy last instance
|
||||||
pins.push_back( temporary_pin( point<int_t>(xpin,ypin), instanceId, netId ) );
|
pinX.push_back(xpin);
|
||||||
|
pinY.push_back(ypin);
|
||||||
|
netCells.push_back(instanceId);
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -1054,8 +1067,8 @@ namespace Etesian {
|
||||||
string insName = extractInstanceName( rp );
|
string insName = extractInstanceName( rp );
|
||||||
Point offset = extractRpOffset ( rp );
|
Point offset = extractRpOffset ( rp );
|
||||||
|
|
||||||
int_t xpin = offset.getX() / vpitch;
|
int xpin = offset.getX() / vpitch;
|
||||||
int_t ypin = offset.getY() / hpitch;
|
int ypin = offset.getY() / hpitch;
|
||||||
|
|
||||||
auto iid = _instsToIds.find( instance );
|
auto iid = _instsToIds.find( instance );
|
||||||
if (iid == _instsToIds.end()) {
|
if (iid == _instsToIds.end()) {
|
||||||
|
@ -1063,7 +1076,9 @@ namespace Etesian {
|
||||||
cerr << Error( "Unable to lookup instance \"%s\".", insName.c_str() ) << endl;
|
cerr << Error( "Unable to lookup instance \"%s\".", insName.c_str() ) << endl;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
pins.push_back( temporary_pin( point<int_t>(xpin,ypin), (*iid).second, netId ) );
|
pinX.push_back(xpin);
|
||||||
|
pinY.push_back(ypin);
|
||||||
|
netCells.push_back((*iid).second);
|
||||||
Net* rpNet = NULL;
|
Net* rpNet = NULL;
|
||||||
Plug* plug = dynamic_cast<Plug*>( rp->getPlugOccurrence().getEntity() );
|
Plug* plug = dynamic_cast<Plug*>( rp->getPlugOccurrence().getEntity() );
|
||||||
if (plug) {
|
if (plug) {
|
||||||
|
@ -1074,6 +1089,7 @@ namespace Etesian {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
_circuit->addNet(netCells, pinX, pinY);
|
||||||
|
|
||||||
netId++;
|
netId++;
|
||||||
}
|
}
|
||||||
|
@ -1084,18 +1100,16 @@ namespace Etesian {
|
||||||
if (_bloatCells.getSelected()->getName() != "disabled")
|
if (_bloatCells.getSelected()->getName() != "disabled")
|
||||||
cmess2 << stdCellSizes.toString(1) << endl;
|
cmess2 << stdCellSizes.toString(1) << endl;
|
||||||
|
|
||||||
_densityLimits = new coloquinte::density_restrictions ();
|
//_densityLimits = new coloquinte::density_restrictions ();
|
||||||
_surface = new box<int_t>( (int_t)(topAb.getXMin() / vpitch)
|
_surface = new coloquinte::Rectangle( (int)(topAb.getXMin() / vpitch)
|
||||||
, (int_t)(topAb.getXMax() / vpitch)
|
, (int)(topAb.getXMax() / vpitch)
|
||||||
, (int_t)(topAb.getYMin() / hpitch)
|
, (int)(topAb.getYMin() / hpitch)
|
||||||
, (int_t)(topAb.getYMax() / hpitch)
|
, (int)(topAb.getYMax() / hpitch)
|
||||||
);
|
);
|
||||||
_circuit = new netlist( instances, nets, pins );
|
_circuit->check();
|
||||||
_circuit->selfcheck();
|
// TODO: define the rows
|
||||||
_placementLB = new coloquinte::placement_t ();
|
_placementLB = new coloquinte::PlacementSolution ();
|
||||||
_placementLB->positions_ = positions;
|
_placementUB = new coloquinte::PlacementSolution ( *_placementLB );
|
||||||
_placementLB->orientations_ = orientations;
|
|
||||||
_placementUB = new coloquinte::placement_t ( *_placementLB );
|
|
||||||
|
|
||||||
return instancesNb-fixedNb;
|
return instancesNb-fixedNb;
|
||||||
}
|
}
|
||||||
|
@ -1139,216 +1153,38 @@ namespace Etesian {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void EtesianEngine::preplace ()
|
void EtesianEngine::globalPlace ( unsigned options )
|
||||||
{
|
{
|
||||||
using namespace coloquinte::gp;
|
_circuit->placeGlobal(getPlaceEffort());
|
||||||
|
// TODO: add callback for placement update + antenna effect
|
||||||
// Perform a very quick legalization pass
|
*_placementUB = _circuit->solution();
|
||||||
cmess2 << " o Simple legalization." << endl;
|
_updatePlacement(_placementUB);
|
||||||
auto first_legalizer = region_distribution::uniform_density_distribution(*_surface, *_circuit, *_placementLB);
|
|
||||||
first_legalizer.selfcheck();
|
|
||||||
get_rough_legalization( *_circuit, *_placementUB, first_legalizer);
|
|
||||||
|
|
||||||
*_placementLB = *_placementUB;
|
|
||||||
|
|
||||||
// Early topology-independent solution with a star model + negligible pulling forces to avoid dumb solutions
|
|
||||||
// Spreads well to help subsequent optimization passes
|
|
||||||
cmess2 << " o Star (*) Optimization." << endl;
|
|
||||||
auto solv = get_star_linear_system( *_circuit, *_placementLB, 1.0, 0, 10) // Limit the number of pins: don't want big awful nets with high weight
|
|
||||||
+ get_pulling_forces( *_circuit, *_placementUB, 1000000.0);
|
|
||||||
solve_linear_system( *_circuit, *_placementLB, solv, 200 );
|
|
||||||
_progressReport2(" [---]" );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void EtesianEngine::roughLegalize ( float minDisruption, unsigned options )
|
void EtesianEngine::detailedPlace ( unsigned options )
|
||||||
{
|
{
|
||||||
using namespace coloquinte::gp;
|
_circuit->placeDetailed(getPlaceEffort());
|
||||||
// Create a legalizer and bipartition it until we have sufficient precision
|
*_placementUB = _circuit->solution();
|
||||||
auto legalizer = (options & ForceUniformDensity) != 0 ?
|
// TODO: add callback for placement update + antenna effect
|
||||||
region_distribution::uniform_density_distribution (*_surface, *_circuit, *_placementLB, *_densityLimits)
|
|
||||||
: region_distribution::full_density_distribution (*_surface, *_circuit, *_placementLB, *_densityLimits);
|
|
||||||
while(legalizer.region_dimensions().x > 2*legalizer.region_dimensions().y)
|
|
||||||
legalizer.x_bipartition();
|
|
||||||
while(2*legalizer.region_dimensions().x < legalizer.region_dimensions().y)
|
|
||||||
legalizer.y_bipartition();
|
|
||||||
while( std::max(legalizer.region_dimensions().x, legalizer.region_dimensions().y)*4 > minDisruption ) {
|
|
||||||
legalizer.x_bipartition();
|
|
||||||
legalizer.y_bipartition();
|
|
||||||
legalizer.redo_line_partitions();
|
|
||||||
legalizer.redo_diagonal_bipartitions();
|
|
||||||
legalizer.redo_line_partitions();
|
|
||||||
legalizer.redo_diagonal_bipartitions();
|
|
||||||
legalizer.selfcheck();
|
|
||||||
}
|
|
||||||
// Keep the orientation between LB and UB
|
|
||||||
*_placementUB = *_placementLB;
|
|
||||||
// Update UB
|
|
||||||
get_rough_legalization( *_circuit, *_placementUB, legalizer );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void EtesianEngine::globalPlace ( float initPenalty
|
|
||||||
, float minDisruption
|
|
||||||
, float targetImprovement
|
|
||||||
, float minInc
|
|
||||||
, float maxInc
|
|
||||||
, unsigned options )
|
|
||||||
{
|
|
||||||
using namespace coloquinte::gp;
|
|
||||||
|
|
||||||
bool antennaDone = false;
|
|
||||||
float_t penaltyIncrease = minInc;
|
|
||||||
float_t linearDisruption = get_mean_linear_disruption(*_circuit, *_placementLB, *_placementUB);
|
|
||||||
float_t pullingForce = initPenalty;
|
|
||||||
float_t upperWL = static_cast<float_t>(get_HPWL_wirelength(*_circuit, *_placementUB)),
|
|
||||||
lowerWL = static_cast<float_t>(get_HPWL_wirelength(*_circuit, *_placementLB));
|
|
||||||
float_t prevOptRatio = lowerWL / upperWL;
|
|
||||||
|
|
||||||
index_t i=0;
|
|
||||||
do{
|
|
||||||
roughLegalize(minDisruption, options);
|
|
||||||
if(options & UpdateUB)
|
|
||||||
_updatePlacement( _placementUB );
|
|
||||||
|
|
||||||
ostringstream label;
|
|
||||||
label.str("");
|
|
||||||
label << " [" << setw(3) << setfill('0') << i << setfill(' ') << "] "
|
|
||||||
<< setw(7) << fixed << setprecision(1) << linearDisruption << "% Bipart.";
|
|
||||||
_progressReport1(label.str() );
|
|
||||||
|
|
||||||
upperWL = static_cast<float_t>(get_HPWL_wirelength(*_circuit, *_placementUB));
|
|
||||||
//float_t legRatio = lowerWL / upperWL;
|
|
||||||
|
|
||||||
// Get the system to optimize (tolerance, maximum and minimum pin counts)
|
|
||||||
// and the pulling forces (threshold distance)
|
|
||||||
auto opt_problem = (options & SteinerModel) ?
|
|
||||||
get_RSMT_linear_system ( *_circuit, *_placementLB, minDisruption, 2, 100000 )
|
|
||||||
: get_HPWLF_linear_system ( *_circuit, *_placementLB, minDisruption, 2, 100000 );
|
|
||||||
auto solv = opt_problem
|
|
||||||
+ get_linear_pulling_forces( *_circuit
|
|
||||||
, *_placementUB
|
|
||||||
, *_placementLB
|
|
||||||
, pullingForce
|
|
||||||
, 2.0f * linearDisruption);
|
|
||||||
solve_linear_system( *_circuit, *_placementLB, solv, 200 ); // 200 iterations
|
|
||||||
_progressReport2(" Linear." );
|
|
||||||
|
|
||||||
if(options & UpdateLB)
|
|
||||||
_updatePlacement( _placementUB );
|
|
||||||
|
|
||||||
// Optimize orientation sometimes
|
|
||||||
if (i%5 == 0) {
|
|
||||||
optimize_exact_orientations( *_circuit, *_placementLB );
|
|
||||||
_progressReport2(" Orient." );
|
|
||||||
}
|
|
||||||
|
|
||||||
lowerWL = static_cast<float_t>(get_HPWL_wirelength(*_circuit, *_placementLB));
|
|
||||||
float_t optRatio = lowerWL / upperWL;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Schedule the penalty during global placement to achieve uniform improvement
|
|
||||||
*
|
|
||||||
* Currently, the metric considered is the ratio optimized HPWL/legalized HPWL
|
|
||||||
* Other ones, like the disruption itself, may be considered
|
|
||||||
*/
|
|
||||||
penaltyIncrease = std::min(maxInc, std::max(minInc,
|
|
||||||
penaltyIncrease * std::sqrt( targetImprovement / (optRatio - prevOptRatio) )
|
|
||||||
) );
|
|
||||||
cparanoid << " L/U ratio: " << 100*optRatio << "% (previous: " << 100*prevOptRatio << "%)\n"
|
|
||||||
<< " Pulling force: " << pullingForce << " Increase: " << penaltyIncrease << endl;
|
|
||||||
|
|
||||||
pullingForce += penaltyIncrease;
|
|
||||||
prevOptRatio = optRatio;
|
|
||||||
|
|
||||||
linearDisruption = get_mean_linear_disruption(*_circuit, *_placementLB, *_placementUB);
|
|
||||||
++i;
|
|
||||||
|
|
||||||
if ((linearDisruption < getAntennaInsertThreshold()*100.0) and not antennaDone) {
|
|
||||||
//antennaProtect();
|
|
||||||
antennaDone = true;
|
|
||||||
}
|
|
||||||
// First way to exit the loop: UB and LB difference is <10%
|
|
||||||
// Second way to exit the loop: the legalization is close enough to the previous result
|
|
||||||
} while (linearDisruption > minDisruption and prevOptRatio <= 0.9);
|
|
||||||
_updatePlacement( _placementUB );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void EtesianEngine::detailedPlace ( int iterations, int effort, unsigned options )
|
|
||||||
{
|
|
||||||
using namespace coloquinte::gp;
|
|
||||||
using namespace coloquinte::dp;
|
|
||||||
|
|
||||||
int_t sliceHeight = getSliceHeight() / getSliceStep();
|
|
||||||
roughLegalize(sliceHeight, options);
|
|
||||||
// TODO: for uniform density distribution, add some margin to the cell sizes so we don't disrupt it during detailed placement
|
|
||||||
|
|
||||||
for ( int i=0; i<iterations; ++i ){
|
|
||||||
ostringstream label;
|
|
||||||
label.str("");
|
|
||||||
label << " [" << setw(3) << setfill('0') << i << setfill(' ') << "]";
|
|
||||||
|
|
||||||
optimize_x_orientations( *_circuit, *_placementUB ); // Don't disrupt VDD/VSS connections in a row
|
|
||||||
_progressReport1(label.str() + " Oriented ......." );
|
|
||||||
if(options & UpdateDetailed)
|
|
||||||
_updatePlacement( _placementUB );
|
|
||||||
|
|
||||||
auto legalizer = legalize( *_circuit, *_placementUB, *_surface, sliceHeight );
|
|
||||||
coloquinte::dp::get_result( *_circuit, legalizer, *_placementUB );
|
|
||||||
_progressReport1(" Legalized ......" );
|
|
||||||
if(options & UpdateDetailed)
|
|
||||||
_updatePlacement( _placementUB );
|
|
||||||
|
|
||||||
row_compatible_orientation( *_circuit, legalizer, true );
|
|
||||||
swaps_global_HPWL( *_circuit, legalizer, 3, 4 );
|
|
||||||
coloquinte::dp::get_result( *_circuit, legalizer, *_placementUB );
|
|
||||||
_progressReport1(" Global Swaps ..." );
|
|
||||||
if(options & UpdateDetailed)
|
|
||||||
_updatePlacement( _placementUB );
|
|
||||||
|
|
||||||
if(options & SteinerModel)
|
|
||||||
OSRP_noncvx_RSMT( *_circuit, legalizer );
|
|
||||||
else
|
|
||||||
OSRP_convex_HPWL( *_circuit, legalizer );
|
|
||||||
coloquinte::dp::get_result( *_circuit, legalizer, *_placementUB );
|
|
||||||
_progressReport1(" Row Optimization" );
|
|
||||||
if(options & UpdateDetailed)
|
|
||||||
_updatePlacement( _placementUB );
|
|
||||||
|
|
||||||
if(options & SteinerModel)
|
|
||||||
swaps_row_noncvx_RSMT( *_circuit, legalizer, effort+2 );
|
|
||||||
else
|
|
||||||
swaps_row_convex_HPWL( *_circuit, legalizer, effort+2 );
|
|
||||||
coloquinte::dp::get_result( *_circuit, legalizer, *_placementUB );
|
|
||||||
_progressReport1(" Local Swaps ...." );
|
|
||||||
if(options & UpdateDetailed)
|
|
||||||
_updatePlacement( _placementUB );
|
|
||||||
|
|
||||||
if (i == iterations-1) {
|
|
||||||
//swaps_row_convex_RSMT( *_circuit, legalizer, 4 );
|
|
||||||
row_compatible_orientation( *_circuit, legalizer, true );
|
|
||||||
coloquinte::dp::get_result( *_circuit, legalizer, *_placementUB );
|
|
||||||
verify_placement_legality( *_circuit, *_placementUB, *_surface );
|
|
||||||
_progressReport1(" Final Legalize ." );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*_placementLB = *_placementUB; // In case we run other passes
|
*_placementLB = *_placementUB; // In case we run other passes
|
||||||
_updatePlacement( _placementUB, FinalStage );
|
_updatePlacement(_placementUB);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void EtesianEngine::antennaProtect ()
|
void EtesianEngine::antennaProtect ()
|
||||||
{
|
{
|
||||||
|
// TODO
|
||||||
|
/*
|
||||||
DbU::Unit maxWL = getAntennaGateMaxWL();
|
DbU::Unit maxWL = getAntennaGateMaxWL();
|
||||||
if (not maxWL) return;
|
if (not maxWL) return;
|
||||||
|
|
||||||
cmess1 << " o Inserting antenna effect protection." << endl;
|
cmess1 << " o Inserting antenna effect protection." << endl;
|
||||||
uint32_t count = 0;
|
uint32_t count = 0;
|
||||||
int_t diodeWidth = _diodeCell->getAbutmentBox().getWidth() / getSliceStep();
|
int diodeWidth = _diodeCell->getAbutmentBox().getWidth() / getSliceStep();
|
||||||
cdebug_log(122,0) << "diodeWidth=" << diodeWidth << "p" << endl;
|
cdebug_log(122,0) << "diodeWidth=" << diodeWidth << "p" << endl;
|
||||||
|
|
||||||
for ( coloquinte::index_t inet=0 ; inet < _circuit->net_cnt() ; ++inet ) {
|
for ( coloquinte::int inet=0 ; inet < _circuit->nbNets() ; ++inet ) {
|
||||||
DbU::Unit rsmt = toDbU( coloquinte::get_RSMT_length( *_circuit, *_placementUB, inet ) );
|
DbU::Unit rsmt = toDbU( coloquinte::get_RSMT_length( *_circuit, *_placementUB, inet ) );
|
||||||
Net* net = std::get<0>( _idsToNets[inet] );
|
Net* net = std::get<0>( _idsToNets[inet] );
|
||||||
|
|
||||||
|
@ -1371,7 +1207,7 @@ namespace Etesian {
|
||||||
if (iinst == _instsToIds.end()) continue;
|
if (iinst == _instsToIds.end()) continue;
|
||||||
|
|
||||||
std::get<1>( _idsToInsts[ (*iinst).second ] ).push_back( rp );
|
std::get<1>( _idsToInsts[ (*iinst).second ] ).push_back( rp );
|
||||||
coloquinte::point<int_t> cell_size = _circuit->get_cell_size( (*iinst).second );
|
coloquinte::point<int> cell_size = _circuit->get_cell_size( (*iinst).second );
|
||||||
cell_size.x += 2*diodeWidth;
|
cell_size.x += 2*diodeWidth;
|
||||||
_circuit->set_cell_size( (*iinst).second, cell_size );
|
_circuit->set_cell_size( (*iinst).second, cell_size );
|
||||||
++count;
|
++count;
|
||||||
|
@ -1379,6 +1215,7 @@ namespace Etesian {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cmess1 << ::Dots::asInt( " - Inserted diodes", count ) << endl;
|
cmess1 << ::Dots::asInt( " - Inserted diodes", count ) << endl;
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1414,20 +1251,11 @@ namespace Etesian {
|
||||||
//findYSpin();
|
//findYSpin();
|
||||||
if (not toColoquinte()) return;
|
if (not toColoquinte()) return;
|
||||||
|
|
||||||
Effort placementEffort = getPlaceEffort();
|
|
||||||
GraphicUpdate placementUpdate = getUpdateConf();
|
GraphicUpdate placementUpdate = getUpdateConf();
|
||||||
Density densityConf = getSpreadingConf();
|
Density densityConf = getSpreadingConf();
|
||||||
double sliceHeight = getSliceHeight() / getSliceStep();
|
|
||||||
|
|
||||||
cmess1 << " o Running Coloquinte." << endl;
|
cmess1 << " o Running Coloquinte." << endl;
|
||||||
cmess2 << " - Computing initial placement..." << endl;
|
|
||||||
cmess2 << right;
|
|
||||||
startMeasures();
|
|
||||||
|
|
||||||
preplace();
|
|
||||||
|
|
||||||
float_t minPenaltyIncrease, maxPenaltyIncrease, targetImprovement;
|
|
||||||
int detailedIterations, detailedEffort;
|
|
||||||
unsigned globalOptions=0, detailedOptions=0;
|
unsigned globalOptions=0, detailedOptions=0;
|
||||||
|
|
||||||
if (placementUpdate == UpdateAll) {
|
if (placementUpdate == UpdateAll) {
|
||||||
|
@ -1441,37 +1269,11 @@ namespace Etesian {
|
||||||
if (densityConf == ForceUniform)
|
if (densityConf == ForceUniform)
|
||||||
globalOptions |= ForceUniformDensity;
|
globalOptions |= ForceUniformDensity;
|
||||||
|
|
||||||
if (placementEffort == Fast) {
|
|
||||||
minPenaltyIncrease = 0.005f;
|
|
||||||
maxPenaltyIncrease = 0.08f;
|
|
||||||
targetImprovement = 0.05f; // 5/100 per iteration
|
|
||||||
detailedIterations = 1;
|
|
||||||
detailedEffort = 0;
|
|
||||||
} else if (placementEffort == Standard) {
|
|
||||||
minPenaltyIncrease = 0.001f;
|
|
||||||
maxPenaltyIncrease = 0.04f;
|
|
||||||
targetImprovement = 0.02f; // 2/100 per iteration
|
|
||||||
detailedIterations = 2;
|
|
||||||
detailedEffort = 1;
|
|
||||||
} else if (placementEffort == High) {
|
|
||||||
minPenaltyIncrease = 0.0005f;
|
|
||||||
maxPenaltyIncrease = 0.02f;
|
|
||||||
targetImprovement = 0.01f; // 1/100 per iteration
|
|
||||||
detailedIterations = 4;
|
|
||||||
detailedEffort = 2;
|
|
||||||
} else {
|
|
||||||
minPenaltyIncrease = 0.0002f;
|
|
||||||
maxPenaltyIncrease = 0.01f;
|
|
||||||
targetImprovement = 0.005f; // 5/1000 per iteration
|
|
||||||
detailedIterations = 7;
|
|
||||||
detailedEffort = 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
cmess1 << " o Global placement." << endl;
|
cmess1 << " o Global placement." << endl;
|
||||||
globalPlace(minPenaltyIncrease, sliceHeight, targetImprovement, minPenaltyIncrease, maxPenaltyIncrease, globalOptions);
|
globalPlace(globalOptions);
|
||||||
|
|
||||||
cmess1 << " o Detailed Placement." << endl;
|
cmess1 << " o Detailed Placement." << endl;
|
||||||
detailedPlace(detailedIterations, detailedEffort, detailedOptions);
|
detailedPlace(detailedOptions);
|
||||||
|
|
||||||
//toHurricane();
|
//toHurricane();
|
||||||
//addFeeds();
|
//addFeeds();
|
||||||
|
@ -1479,10 +1281,6 @@ namespace Etesian {
|
||||||
cmess1 << " o Placement finished." << endl;
|
cmess1 << " o Placement finished." << endl;
|
||||||
stopMeasures();
|
stopMeasures();
|
||||||
printMeasures();
|
printMeasures();
|
||||||
cmess1 << ::Dots::asString
|
|
||||||
( " - HPWL", DbU::getValueString( (DbU::Unit)coloquinte::gp::get_HPWL_wirelength(*_circuit,*_placementUB )*getSliceStep() ) ) << endl;
|
|
||||||
cmess1 << ::Dots::asString
|
|
||||||
( " - RMST", DbU::getValueString( (DbU::Unit)coloquinte::gp::get_RSMT_wirelength(*_circuit,*_placementUB )*getSliceStep() ) ) << endl;
|
|
||||||
addMeasure<double>( "placeT", getTimer().getCombTime() );
|
addMeasure<double>( "placeT", getTimer().getCombTime() );
|
||||||
|
|
||||||
UpdateSession::open();
|
UpdateSession::open();
|
||||||
|
@ -1501,44 +1299,7 @@ namespace Etesian {
|
||||||
UpdateSession::close();
|
UpdateSession::close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EtesianEngine::_updatePlacement ( const coloquinte::PlacementSolution* placement, uint32_t flags )
|
||||||
void EtesianEngine::_progressReport1 ( string label ) const
|
|
||||||
{
|
|
||||||
size_t w = label.size();
|
|
||||||
string indent ( w, ' ' );
|
|
||||||
if (not w) {
|
|
||||||
label = string( 5, ' ' );
|
|
||||||
indent = label;
|
|
||||||
}
|
|
||||||
|
|
||||||
cmess2 << label
|
|
||||||
<< " HPWL=" << setw(14) << DbU::getValueString(toDbU(coloquinte::gp::get_HPWL_wirelength( *_circuit, *_placementUB )))
|
|
||||||
<< " RMST=" << setw(14) << DbU::getValueString(toDbU(coloquinte::gp::get_RSMT_wirelength( *_circuit, *_placementUB )))
|
|
||||||
<< endl;
|
|
||||||
cparanoid << indent
|
|
||||||
<< " L-Dsrpt=" << setw(8) << coloquinte::gp::get_mean_linear_disruption ( *_circuit, *_placementLB, *_placementUB )
|
|
||||||
<< " Q-Dsrpt=" << setw(8) << coloquinte::gp::get_mean_quadratic_disruption( *_circuit, *_placementLB, *_placementUB )
|
|
||||||
<< endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void EtesianEngine::_progressReport2 ( string label ) const
|
|
||||||
{
|
|
||||||
size_t w = label.size();
|
|
||||||
string indent ( w, ' ' );
|
|
||||||
if (not w) {
|
|
||||||
label = string( 5, ' ' );
|
|
||||||
indent = label;
|
|
||||||
}
|
|
||||||
|
|
||||||
cmess2 << label
|
|
||||||
<< " HPWL=" << setw(14) << DbU::getValueString(toDbU(coloquinte::gp::get_HPWL_wirelength( *_circuit, *_placementLB )))
|
|
||||||
<< " RMST=" << setw(14) << DbU::getValueString(toDbU(coloquinte::gp::get_RSMT_wirelength( *_circuit, *_placementLB )))
|
|
||||||
<< endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void EtesianEngine::_updatePlacement ( const coloquinte::placement_t* placement, uint32_t flags )
|
|
||||||
{
|
{
|
||||||
UpdateSession::open();
|
UpdateSession::open();
|
||||||
|
|
||||||
|
@ -1568,9 +1329,9 @@ namespace Etesian {
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
//uint32_t outputSide = getOutputSide( instance->getMasterCell() );
|
//uint32_t outputSide = getOutputSide( instance->getMasterCell() );
|
||||||
point<int_t> position = placement->positions_[(*iid).second];
|
auto place = (*placement)[(*iid).second];
|
||||||
Transformation cellTrans = toTransformation( position
|
Transformation cellTrans = toTransformation( place.position
|
||||||
, placement->orientations_[(*iid).second]
|
, place.orientation
|
||||||
, instance->getMasterCell()
|
, instance->getMasterCell()
|
||||||
, hpitch
|
, hpitch
|
||||||
, vpitch
|
, vpitch
|
||||||
|
|
|
@ -40,9 +40,9 @@ namespace Etesian {
|
||||||
// Class : "Etesian::Configuration".
|
// Class : "Etesian::Configuration".
|
||||||
|
|
||||||
enum Effort { Fast =1
|
enum Effort { Fast =1
|
||||||
, Standard=2
|
, Standard=3
|
||||||
, High =3
|
, High =6
|
||||||
, Extreme =4
|
, Extreme =9
|
||||||
};
|
};
|
||||||
enum GraphicUpdate { UpdateAll =1
|
enum GraphicUpdate { UpdateAll =1
|
||||||
, LowerBound=2
|
, LowerBound=2
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include "coloquinte/circuit.hxx"
|
#include "coloquinte2/coloquinte.hpp"
|
||||||
|
|
||||||
#include "hurricane/Timer.h"
|
#include "hurricane/Timer.h"
|
||||||
#include "hurricane/Name.h"
|
#include "hurricane/Name.h"
|
||||||
|
@ -131,10 +131,8 @@ namespace Etesian {
|
||||||
inline Transformation toBlock ( const Transformation& ) const;
|
inline Transformation toBlock ( const Transformation& ) const;
|
||||||
void setPlaceArea ( const Box& );
|
void setPlaceArea ( const Box& );
|
||||||
size_t toColoquinte ();
|
size_t toColoquinte ();
|
||||||
void preplace ();
|
void globalPlace ( unsigned options=0 );
|
||||||
void roughLegalize ( float minDisruption, unsigned options );
|
void detailedPlace ( unsigned options=0 );
|
||||||
void globalPlace ( float initPenalty, float minDisruption, float targetImprovement, float minInc, float maxInc, unsigned options=0 );
|
|
||||||
void detailedPlace ( int iterations, int effort, unsigned options=0 );
|
|
||||||
void antennaProtect ();
|
void antennaProtect ();
|
||||||
void place ();
|
void place ();
|
||||||
uint32_t doHFNS ();
|
uint32_t doHFNS ();
|
||||||
|
@ -160,11 +158,12 @@ namespace Etesian {
|
||||||
bool _flatDesign;
|
bool _flatDesign;
|
||||||
Box _placeArea;
|
Box _placeArea;
|
||||||
std::vector<Box> _trackAvoids;
|
std::vector<Box> _trackAvoids;
|
||||||
coloquinte::box<coloquinte::int_t>* _surface;
|
coloquinte::Rectangle* _surface;
|
||||||
coloquinte::netlist* _circuit;
|
coloquinte::Circuit* _circuit;
|
||||||
coloquinte::placement_t* _placementLB;
|
coloquinte::PlacementSolution* _placementLB;
|
||||||
coloquinte::placement_t* _placementUB;
|
coloquinte::PlacementSolution* _placementUB;
|
||||||
coloquinte::density_restrictions* _densityLimits;
|
// TODO
|
||||||
|
// coloquinte::density_restrictions* _densityLimits;
|
||||||
NetsToIds _netsToIds;
|
NetsToIds _netsToIds;
|
||||||
InstancesToIds _instsToIds;
|
InstancesToIds _instsToIds;
|
||||||
std::vector<InstanceInfos> _idsToInsts;
|
std::vector<InstanceInfos> _idsToInsts;
|
||||||
|
@ -195,7 +194,7 @@ namespace Etesian {
|
||||||
private:
|
private:
|
||||||
inline uint32_t _getNewDiodeId ();
|
inline uint32_t _getNewDiodeId ();
|
||||||
Instance* _createDiode ( Cell* );
|
Instance* _createDiode ( Cell* );
|
||||||
void _updatePlacement ( const coloquinte::placement_t*, uint32_t flags=0 );
|
void _updatePlacement ( const coloquinte::PlacementSolution*, uint32_t flags=0 );
|
||||||
void _progressReport1 ( string label ) const;
|
void _progressReport1 ( string label ) const;
|
||||||
void _progressReport2 ( string label ) const;
|
void _progressReport2 ( string label ) const;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue