679 lines
22 KiB
Plaintext
679 lines
22 KiB
Plaintext
|
|
// This file is part of the Coriolis Project.
|
|
// Copyright (C) Laboratoire LIP6 - Departement ASIM
|
|
// Universite Pierre et Marie Curie
|
|
//
|
|
// Main contributors :
|
|
// Christophe Alexandre <Christophe.Alexandre@lip6.fr>
|
|
// Sophie Belloeil <Sophie.Belloeil@lip6.fr>
|
|
// Hugo Clément <Hugo.Clement@lip6.fr>
|
|
// Jean-Paul Chaput <Jean-Paul.Chaput@lip6.fr>
|
|
// Damien Dupuis <Damien.Dupuis@lip6.fr>
|
|
// Christian Masson <Christian.Masson@lip6.fr>
|
|
// Marek Sroka <Marek.Sroka@lip6.fr>
|
|
//
|
|
// The Coriolis Project is free software; you can redistribute it and/or
|
|
// modify it under the terms of the GNU General Public License as
|
|
// published by the Free Software Foundation; either version 2 of the
|
|
// License, or (at your option) any later version.
|
|
//
|
|
// The Coriolis Project is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
// General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with the Coriolis Project; if not, write to the Free Software
|
|
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
//
|
|
//
|
|
// License-Tag
|
|
//
|
|
// Date : 29/01/2004
|
|
// Author : Christophe Alexandre <Christophe.Alexandre@lip6.fr>
|
|
//
|
|
// Authors-Tag
|
|
|
|
#include "Cell.h"
|
|
#include "HyperNet.h"
|
|
USING_NAMESPACE_HURRICANE
|
|
|
|
#include "CTimer.h"
|
|
#include "CDataBase.h"
|
|
#include "CCellGauge.h"
|
|
using namespace CRL;
|
|
|
|
#include "Nimbus.h"
|
|
using namespace NIMBUS;
|
|
|
|
#include "Surface.h"
|
|
#include "Row.h"
|
|
#include "SimAnnealingPlacer.h"
|
|
#include "BBPlacer.h"
|
|
#include "Mauka.h"
|
|
|
|
namespace MAUKA {
|
|
|
|
namespace {
|
|
|
|
Name MaukaName("Mauka");
|
|
|
|
}
|
|
|
|
|
|
Mauka::Mauka(Cell* cell)
|
|
// *************************
|
|
: Inherit(cell)
|
|
, _params()
|
|
, _displaySlot(NULL)
|
|
, _instanceOccurrencesVector()
|
|
, _instanceOccurrencesMap()
|
|
, _instanceWidths()
|
|
, _instanceNets()
|
|
, _nets()
|
|
, _netInstances()
|
|
, _netInitX()
|
|
, _netInitY()
|
|
, _hasInitX()
|
|
, _hasInitY()
|
|
, _surface(NULL)
|
|
, _simAnnealingPlacer(NULL)
|
|
, _bbPlacer(NULL)
|
|
{}
|
|
|
|
Mauka* Mauka::Create(Cell* cell, double searchratio, Box placementbox)
|
|
// *******************************************************************
|
|
{
|
|
Mauka* mauka = new Mauka(cell);
|
|
|
|
mauka->_PostCreate(placementbox, searchratio);
|
|
|
|
return mauka;
|
|
}
|
|
|
|
void Mauka::_PostCreate(Box& placementbox, double searchratio)
|
|
// ***********************************************************
|
|
{
|
|
Inherit::_PostCreate();
|
|
|
|
Construct();
|
|
|
|
//_simAnnealingPlacer = new SimAnnealingPlacer(this, 1, 0.0, 0.0);
|
|
_simAnnealingPlacer = new SimAnnealingPlacer(this, 0.9, 0.05, 0.05);
|
|
|
|
_displaySlot = DisplaySlot::Create(GetCell(),MaukaName,139,0,139);
|
|
|
|
_surface = Surface::Create(this, placementbox, searchratio);
|
|
|
|
|
|
_simAnnealingPlacer->Init();
|
|
|
|
//Plot();
|
|
}
|
|
|
|
#if 0
|
|
void Mauka::ReInit()
|
|
// *******************
|
|
{
|
|
Box placementBox = _surface->GetBox();
|
|
_surface->Delete();
|
|
_simAnnealingPlacer->Delete();
|
|
_surface = Surface::Create(this, placementBox);
|
|
_simAnnealingPlacer = SimAnnealingPlacer::Create(this);
|
|
}
|
|
#endif
|
|
|
|
void Mauka::Run()
|
|
{
|
|
|
|
CTimer timer;
|
|
timer.Start();
|
|
while (_simAnnealingPlacer->Iterate())
|
|
;
|
|
timer.Stop();
|
|
if (_verbosity.MajorStatsIsOn())
|
|
{
|
|
_simAnnealingPlacer->DisplayResults();
|
|
}
|
|
if (_params.plotBins)
|
|
{
|
|
//PlotBinsStats();
|
|
}
|
|
if (_verbosity.SystemResourcesIsOn())
|
|
{
|
|
cout << endl << " o Simulated Annealing run took " << timer.GetUserTime() << " s ..." << endl;
|
|
}
|
|
//Plot();
|
|
_bbPlacer = new BBPlacer(this);
|
|
_bbPlacer->Run();
|
|
_bbPlacer->Save();
|
|
//Plot();
|
|
}
|
|
|
|
namespace {
|
|
void VerifyPathCellBox(const Occurrence& occurrence)
|
|
//On occurrence Path set all cells Abox to (0,0,0,0) if Box is empty
|
|
//This avoids bad Transfos on Path
|
|
{
|
|
Path path = occurrence.GetPath();
|
|
while (!path.IsEmpty())
|
|
{
|
|
Instance* instance = path.GetHeadInstance();
|
|
Cell* model = instance->GetMasterCell();
|
|
if (model->GetAbutmentBox().IsEmpty())
|
|
{
|
|
model->SetAbutmentBox(Box(Point(0,0), Point(0,0)));
|
|
}
|
|
path = path.GetTailPath();
|
|
}
|
|
}
|
|
}
|
|
|
|
void Mauka::Construct()
|
|
// **********************
|
|
{
|
|
typedef map<Occurrence, unsigned> InstanceOccurrenceMap;
|
|
typedef set<Instance*> InstanceSet;
|
|
typedef map<Net*, unsigned> NetMap;
|
|
InstanceSet instanceSet;
|
|
NetMap netMap;
|
|
unsigned instanceId = 0;
|
|
unsigned netId = 0;
|
|
|
|
Unit standardCellHeight = 0;
|
|
|
|
for_each_occurrence(occurrence, GetCell()->GetLeafInstanceOccurrences())
|
|
{
|
|
Instance* instance = static_cast<Instance*>(occurrence.GetEntity());
|
|
if (!instance->IsFixed())
|
|
{
|
|
//cerr << "unplaced " << occurrence << occurrence.GetBoundingBox() << endl;
|
|
Cell* model = instance->GetMasterCell();
|
|
Unit insWidth = model->GetAbutmentBox().GetWidth();
|
|
Unit insHeight = model->GetAbutmentBox().GetHeight();
|
|
if (standardCellHeight == 0)
|
|
standardCellHeight = insHeight;
|
|
else if (insHeight != standardCellHeight)
|
|
{
|
|
throw Error("All non-standard instances : "
|
|
+ GetString(instance->GetName())
|
|
+ " must be placed");
|
|
}
|
|
_instanceOccurrencesVector.push_back(occurrence);
|
|
//VerifyPathCellBox(occurrence);
|
|
_instanceWidths.push_back(insWidth);
|
|
InstanceSet::iterator isit = instanceSet.find(instance);
|
|
if (isit != instanceSet.end())
|
|
{
|
|
cerr << "Unplaced Instance : " << *isit << endl;
|
|
cerr << "Unplaced Occurrence : " << occurrence << endl;
|
|
cerr << (*isit)->GetPlacementStatus() << endl;
|
|
throw Error("Each unplaced instance must have one occurrence only");
|
|
}
|
|
_instanceOccurrencesMap[occurrence] = instanceId++;
|
|
instanceSet.insert(instance);
|
|
_instanceNets.push_back(UVector());
|
|
}
|
|
end_for;
|
|
}
|
|
|
|
if (_instanceOccurrencesVector.size() == 0)
|
|
throw Error("No Instance to place...");
|
|
|
|
typedef set<Net*> NetSet;
|
|
NetSet treatedNets;
|
|
|
|
for (InstanceOccurrencesVector::const_iterator iovit = _instanceOccurrencesVector.begin();
|
|
iovit != _instanceOccurrencesVector.end();
|
|
iovit++)
|
|
{
|
|
Instance* instance = static_cast<Instance*>(iovit->GetEntity());
|
|
for_each_plug(plug, instance->GetConnectedPlugs())
|
|
{
|
|
Net* net = plug->GetNet();
|
|
if (net->IsGlobal())
|
|
continue;
|
|
typedef list<Occurrence> InstanceOccurrenceList;
|
|
InstanceOccurrenceList instanceOccurrenceList;
|
|
Occurrence rootNetOccurrence = GetHyperNetRootNetOccurrence(Occurrence(net, iovit->GetPath()));
|
|
Net* rootNet = static_cast<Net*>(rootNetOccurrence.GetEntity());
|
|
NetSet::iterator snit = treatedNets.find(rootNet);
|
|
if (snit != treatedNets.end())
|
|
continue;
|
|
treatedNets.insert(rootNet);
|
|
HyperNet hyperNet(rootNetOccurrence);
|
|
typedef list<Point> PointList;
|
|
PointList pointList;
|
|
for_each_occurrence(occurrence, hyperNet.GetNetOccurrences())
|
|
{
|
|
Instance* instance = occurrence.GetPath().GetTailInstance();
|
|
if (instance && instance->IsLeaf())
|
|
{
|
|
Occurrence instanceOccurrence = Occurrence(instance, occurrence.GetPath().GetHeadPath());
|
|
if (instance->IsFixed())
|
|
pointList.push_back(instanceOccurrence.GetBoundingBox().GetCenter());
|
|
else
|
|
instanceOccurrenceList.push_back(instanceOccurrence);
|
|
}
|
|
end_for;
|
|
}
|
|
unsigned pointListSize = pointList.size();
|
|
Point fixedPoint(0,0);
|
|
if (pointListSize > 0)
|
|
{
|
|
for (PointList::iterator plit = pointList.begin();
|
|
plit != pointList.end();
|
|
plit++)
|
|
{
|
|
fixedPoint.SetX(fixedPoint.GetX() + plit->GetX() / pointListSize);
|
|
fixedPoint.SetY(fixedPoint.GetY() + plit->GetY() / pointListSize);
|
|
}
|
|
}
|
|
if ((instanceOccurrenceList.size() < 2) && pointListSize == 0)
|
|
continue;
|
|
_netInstances.push_back(UVector());
|
|
_nets.push_back(net);
|
|
if (pointListSize > 0)
|
|
{
|
|
_netInitX.push_back(fixedPoint.GetX());
|
|
_netInitY.push_back(fixedPoint.GetY());
|
|
_hasInitX.push_back(true);
|
|
_hasInitY.push_back(true);
|
|
}
|
|
else
|
|
{
|
|
_netInitX.push_back(0);
|
|
_netInitY.push_back(0);
|
|
_hasInitX.push_back(false);
|
|
_hasInitY.push_back(false);
|
|
}
|
|
|
|
netMap[net] = netId;
|
|
for (InstanceOccurrenceList::iterator iolit = instanceOccurrenceList.begin();
|
|
iolit != instanceOccurrenceList.end();
|
|
iolit++)
|
|
{
|
|
InstanceOccurrenceMap::const_iterator iomit = _instanceOccurrencesMap.find(*iolit);
|
|
if (iomit == _instanceOccurrencesMap.end())
|
|
{
|
|
cerr << "cannot find " << iomit->first << endl;
|
|
throw Error("Error in netsInstances construction in SimAnnealingPlacer");
|
|
}
|
|
_netInstances.back().push_back(iomit->second);
|
|
_instanceNets[iomit->second].push_back(netId);
|
|
}
|
|
++netId;
|
|
end_for;
|
|
}
|
|
|
|
}
|
|
|
|
#if DEBUG
|
|
|
|
//debug ... display netlist
|
|
for (unsigned instanceId = 0; instanceId < _instanceOccurrencesVector.size(); instanceId++)
|
|
{
|
|
cerr << "instance " << _instanceOccurrencesVector[instanceId] << endl;
|
|
cerr << "is connected to " << endl;
|
|
for (UVector::const_iterator uvit = _instanceNets[instanceId].begin();
|
|
uvit != _instanceNets[instanceId].end();
|
|
uvit++)
|
|
{
|
|
unsigned netid = *uvit;
|
|
cerr << _nets[netid] << endl;
|
|
for (UVector::const_iterator nuvit = _netInstances[netid].begin();
|
|
nuvit != _netInstances[netid].end();
|
|
nuvit++)
|
|
{
|
|
cerr << _instanceOccurrencesVector[*nuvit] << endl;
|
|
}
|
|
cerr << endl;
|
|
}
|
|
cerr << endl;
|
|
}
|
|
#endif
|
|
|
|
|
|
}
|
|
|
|
bool Mauka::Iterate()
|
|
// ******************
|
|
{
|
|
bool canContinue = _simAnnealingPlacer->Iterate();
|
|
Save();
|
|
return canContinue;
|
|
}
|
|
|
|
void Mauka::_PreDelete()
|
|
// *********************
|
|
{
|
|
_surface->Delete();
|
|
if (_simAnnealingPlacer)
|
|
delete _simAnnealingPlacer;
|
|
if (_bbPlacer)
|
|
delete _bbPlacer;
|
|
_displaySlot->Delete();
|
|
Inherit::_PreDelete();
|
|
}
|
|
|
|
Record* Mauka::_GetRecord() const
|
|
// ************************
|
|
{
|
|
Record* record = Inherit::_GetRecord();
|
|
if (record) {
|
|
record->Add(GetSlot("Surface", _surface));
|
|
}
|
|
return record;
|
|
}
|
|
|
|
const Name& Mauka::GetName() const
|
|
// *******************************
|
|
{
|
|
return MaukaName;
|
|
}
|
|
|
|
void Mauka::Save() const
|
|
// *********************
|
|
{
|
|
if (_bbPlacer)
|
|
_bbPlacer->Save();
|
|
else if (_simAnnealingPlacer)
|
|
_simAnnealingPlacer->Save();
|
|
}
|
|
|
|
Mauka* GetMauka(const Cell* cell)
|
|
// ******************************
|
|
{
|
|
return static_cast<Mauka*>(GetCEngine(cell, MaukaName));
|
|
}
|
|
|
|
namespace {
|
|
class TestSubRow : public Box {
|
|
public: Unit _size; // sum of the contained instances width
|
|
public: TestSubRow(const Box& box): Box(box), _size(0) {}
|
|
};
|
|
|
|
typedef list<TestSubRow*> TestSubRowsList;
|
|
typedef vector<Occurrence> InstanceOccurrencesVector;
|
|
typedef list<Occurrence> InstanceOccurrencesList;
|
|
|
|
void DestroyTestSubRows(TestSubRowsList& testsubrowslist)
|
|
{
|
|
for (TestSubRowsList::iterator tsrlit = testsubrowslist.begin();
|
|
tsrlit != testsubrowslist.end();
|
|
tsrlit++)
|
|
{
|
|
delete *tsrlit;
|
|
}
|
|
testsubrowslist.clear();
|
|
}
|
|
|
|
struct SortInstanceOccurrencesByWidth
|
|
{
|
|
bool operator()(Occurrence occurrence1, Occurrence occurrence2)
|
|
{
|
|
Instance* instance1 = static_cast<Instance*>(occurrence1.GetEntity());
|
|
Instance* instance2 = static_cast<Instance*>(occurrence2.GetEntity());
|
|
return instance1->GetAbutmentBox().GetWidth() > instance2->GetAbutmentBox().GetWidth();
|
|
}
|
|
};
|
|
|
|
bool TryDisplayInstancesInSubRows(
|
|
InstanceOccurrencesVector& instanceoccurrencesvector, TestSubRowsList& testsubrowslist)
|
|
{
|
|
// Try Insert instances in subrows
|
|
sort(instanceoccurrencesvector.begin(), instanceoccurrencesvector.end(), SortInstanceOccurrencesByWidth());
|
|
|
|
TestSubRowsList::iterator tsrlit = testsubrowslist.begin();
|
|
InstanceOccurrencesVector::const_iterator insIterator = instanceoccurrencesvector.begin();
|
|
InstanceOccurrencesVector::const_iterator lastLoopInsertedInsIterator = insIterator;
|
|
|
|
while(insIterator != instanceoccurrencesvector.end())
|
|
{
|
|
if (tsrlit == testsubrowslist.end())
|
|
{
|
|
tsrlit = testsubrowslist.begin();
|
|
if (lastLoopInsertedInsIterator != insIterator)
|
|
lastLoopInsertedInsIterator = insIterator;
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
TestSubRow* testSubRow = *tsrlit;
|
|
Instance* instance = static_cast<Instance*>(insIterator->GetEntity());
|
|
Cell* model = instance->GetMasterCell();
|
|
Unit insWidth = model->GetAbutmentBox().GetWidth();
|
|
if (insWidth <= testSubRow->GetWidth() - testSubRow->_size)
|
|
{
|
|
testSubRow->_size += insWidth;
|
|
++insIterator;
|
|
}
|
|
++tsrlit;
|
|
}
|
|
return true;
|
|
}
|
|
}
|
|
|
|
bool TestMaukaConstruction(Cell* cell, GCell* gcell)
|
|
// *************************************************
|
|
{
|
|
Unit pitch = GetCDataBase()->GetDefaultCGPitch();
|
|
Unit sliceHeight = GetCDataBase()->GetDefaultCGSliceHeight();
|
|
|
|
const Box& box = gcell->GetBox();
|
|
|
|
if (box.IsEmpty() || box.IsPonctual() ||box.IsFlat())
|
|
throw Error("Wrong Box for GCell");
|
|
if (box.GetHeight() % sliceHeight)
|
|
throw Error("Box Height must be a multiple of Slice Height");
|
|
|
|
InstanceOccurrencesList fixedInstanceOccurrenceList;
|
|
InstanceOccurrencesVector toPlaceInstanceOccurrencesVector;
|
|
//search for preplaced leaf instances
|
|
Unit instanceToPlaceWidthMax = 0;
|
|
for_each_occurrence(occurrence, cell->GetLeafInstanceOccurrencesUnder(gcell->GetBox()))
|
|
{
|
|
Instance* instance = static_cast<Instance*>(occurrence.GetEntity());
|
|
if (instance->IsFixed())
|
|
fixedInstanceOccurrenceList.push_back(occurrence);
|
|
else
|
|
{
|
|
Cell* model = instance->GetMasterCell();
|
|
Unit insWidth = model->GetAbutmentBox().GetWidth();
|
|
toPlaceInstanceOccurrencesVector.push_back(occurrence);
|
|
if (instanceToPlaceWidthMax > insWidth)
|
|
instanceToPlaceWidthMax = insWidth;
|
|
}
|
|
end_for;
|
|
}
|
|
|
|
Unit binWidthMax = GetUnit((unsigned)(
|
|
2.0 * GetValue(instanceToPlaceWidthMax) / GetValue(pitch)) * GetValue(pitch));
|
|
Unit binWidthMin = GetUnit((unsigned)(
|
|
GetValue(binWidthMax) / (GetValue(pitch) * 2)) * GetValue(pitch));
|
|
|
|
TestSubRowsList testSubRowsList;
|
|
|
|
if (fixedInstanceOccurrenceList.size() != 0)
|
|
{
|
|
int width = (unsigned)(gcell->GetWidth() / pitch); //number of x pitch
|
|
int height = (unsigned)(gcell->GetHeight() / sliceHeight); //number of y slices
|
|
|
|
|
|
Mauka::PrePlaceTab prePlaceTab(height, Mauka::PrePlaceRow(width, false));
|
|
|
|
for (InstanceOccurrencesList::iterator iolit = fixedInstanceOccurrenceList.begin();
|
|
iolit != fixedInstanceOccurrenceList.end();
|
|
iolit++)
|
|
{
|
|
Instance* instance = static_cast<Instance*>(iolit->GetEntity());
|
|
Box instanceAbutmentBox = instance->GetAbutmentBox();
|
|
iolit->GetPath().GetTransformation().ApplyOn(instanceAbutmentBox);
|
|
|
|
Box preplacedBox = gcell->GetIntersection(instanceAbutmentBox);
|
|
|
|
Unit insWidth = preplacedBox.GetWidth();
|
|
Unit insHeight = preplacedBox.GetHeight();
|
|
|
|
int insPitchWidth = (int)(insWidth / pitch); // largeur ramene au pitch
|
|
int insSliceHeight = (int)(insHeight / sliceHeight); // hauteur ramene a la hauteur du slice
|
|
|
|
int ypos = (int)((preplacedBox.GetYMin() - gcell->GetYMin()) / sliceHeight); // position en y ramene au slice
|
|
int xpos = (int)((preplacedBox.GetXMin() - gcell->GetXMin()) / pitch); // position en x ramene au pitch
|
|
for (int yit = ypos; yit < ypos + insSliceHeight; yit++)
|
|
{
|
|
for (int xit = xpos; xit < xpos + insPitchWidth; xit++)
|
|
{
|
|
if ( (xit > width - 1) || (yit > height - 1)
|
|
|| (xit < 0 ) || (yit < 0 ) )
|
|
{
|
|
cerr << " o ERROR : " << *iolit
|
|
<< " out of the abutment box" << endl;
|
|
exit(1);
|
|
}
|
|
if (prePlaceTab[yit][xit] == false)
|
|
{
|
|
prePlaceTab[yit][xit] = true;
|
|
}
|
|
else
|
|
{
|
|
cerr << " o ERROR : " << *iolit
|
|
<< " badly placed .... There is already an instance at its position ...."
|
|
<< endl;
|
|
exit (1);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
for (int y = 0; y < (int)prePlaceTab.size(); y++)
|
|
{
|
|
int x = 0;
|
|
while (x < (int)prePlaceTab[y].size())
|
|
{
|
|
while ((x < (int)prePlaceTab[y].size()) && (prePlaceTab[y][x] == true))
|
|
++x;
|
|
Unit subRowXMin = gcell->GetXMin() + x * pitch;
|
|
|
|
if (x >= (int)prePlaceTab[y].size())
|
|
break;
|
|
|
|
while ((x < (int)prePlaceTab[y].size()) && (prePlaceTab[y][x] == false))
|
|
++x;
|
|
Unit subRowXMax = gcell->GetXMin() + x * pitch;
|
|
if (subRowXMax - subRowXMin > binWidthMin)
|
|
{
|
|
testSubRowsList.push_back(new TestSubRow(
|
|
Box(subRowXMin, gcell->GetYMin() + y * sliceHeight
|
|
, subRowXMax, gcell->GetYMin() + (y+1) * sliceHeight)
|
|
));
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (Unit ymin = gcell->GetYMin(); ymin <= gcell->GetYMax() - sliceHeight; ymin += sliceHeight)
|
|
{
|
|
testSubRowsList.push_back(new TestSubRow(
|
|
Box(gcell->GetXMin(), ymin, gcell->GetXMax(), ymin + sliceHeight)
|
|
));
|
|
}
|
|
}
|
|
|
|
bool tryInstanceInsertion = TryDisplayInstancesInSubRows(toPlaceInstanceOccurrencesVector, testSubRowsList);
|
|
DestroyTestSubRows(testSubRowsList);
|
|
return tryInstanceInsertion;
|
|
}
|
|
|
|
|
|
void Mauka::PlotBinsStats() const
|
|
// ******************************
|
|
{
|
|
ofstream out("binsstats.gpl");
|
|
|
|
out << "set noxtics" << endl << "set noytics" << endl
|
|
<< "set noborder" << endl << "set nokey" << endl
|
|
<< "set title '" << GetCell()->GetName() << "'" << endl
|
|
<< "#set terminal postscript eps color solid" << endl
|
|
<< "#set output 'binsstats.ps'" << endl;
|
|
|
|
_surface->PlotBinsStats(out);
|
|
}
|
|
|
|
void Mauka::Plot() const
|
|
// *********************
|
|
{
|
|
static unsigned count = 0;
|
|
string cellNameString = GetString(GetCell()->GetName())
|
|
+ "_" + GetString(count) + ".gpl";
|
|
++count;
|
|
ofstream out(cellNameString.c_str());
|
|
|
|
out << "set noxtics" << endl << "set noytics" << endl
|
|
<< "set noborder" << endl << "set nokey" << endl
|
|
<< "set title '" << cellNameString << "'" << endl
|
|
<< "#set terminal postscript eps color solid" << endl << "#set output '"
|
|
<< cellNameString << ".ps'" << endl;
|
|
|
|
Box boundingBox = _surface->GetBox();
|
|
boundingBox.Merge(PlotFixedPointsLabels(out));
|
|
|
|
out << "set xrange[" << boundingBox.GetXMin()
|
|
<< ":" << boundingBox.GetXMax() << "]" << endl
|
|
<< "set yrange[" << boundingBox.GetYMin()
|
|
<< ":" << boundingBox.GetYMax() << "]" << endl;
|
|
|
|
out << "plot [:][:][:][:] '-' w l, '-' w l 2, '-' w l 3, '-' w l 4" << endl;
|
|
// << "plot [:][:][:][:] '-' w l, '-' w l 2, '-' w l 3, '-' w l 4" << endl;
|
|
|
|
_surface->Plot(out);
|
|
if (_bbPlacer)
|
|
_bbPlacer->Plot(out);
|
|
else
|
|
_simAnnealingPlacer->Plot(out);
|
|
|
|
out << "pause -1 'press any key'" << endl;
|
|
}
|
|
|
|
Box Mauka::PlotFixedPointsLabels(ofstream& out) const
|
|
// ****************************************************
|
|
{
|
|
Box boundingBox;
|
|
|
|
out << "#FixedPoints" << endl;
|
|
for (unsigned i = 0; i < _netInstances.size(); i++)
|
|
{
|
|
if (_hasInitX[i])
|
|
{
|
|
|
|
out << "set label \""
|
|
<< GetString(_nets[i]->GetName()) << "\" at "
|
|
<< _netInitX[i] << "," << _netInitY[i] << " center"
|
|
<< endl;
|
|
}
|
|
boundingBox.Merge(_netInitX[i], _netInitY[i]);
|
|
}
|
|
return boundingBox;
|
|
}
|
|
|
|
void Mauka::Hide() {
|
|
if (_displaySlot != NULL) {
|
|
_displaySlot->Hide();
|
|
}
|
|
}
|
|
|
|
void Mauka::Show() {
|
|
if (_displaySlot != NULL) {
|
|
_displaySlot->Show();
|
|
}
|
|
}
|
|
|
|
unsigned Mauka::GetRandomInstanceId() const {
|
|
unsigned instanceId = (unsigned)((double)_instanceOccurrencesVector.size() * rand() / (RAND_MAX + 1.0));
|
|
return instanceId;
|
|
}
|
|
|
|
}
|