166 lines
4.9 KiB
C
166 lines
4.9 KiB
C
/*===================================================================*/
|
|
//
|
|
// place_gordian.c
|
|
//
|
|
// Aaron P. Hurst, 2003-2007
|
|
// ahurst@eecs.berkeley.edu
|
|
//
|
|
/*===================================================================*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <math.h>
|
|
#include <assert.h>
|
|
#include <limits.h>
|
|
|
|
#include "place_gordian.h"
|
|
#include "place_base.h"
|
|
|
|
ABC_NAMESPACE_IMPL_START
|
|
|
|
|
|
|
|
// --------------------------------------------------------------------
|
|
// Global variables
|
|
//
|
|
// --------------------------------------------------------------------
|
|
|
|
int g_place_numPartitions;
|
|
|
|
|
|
// --------------------------------------------------------------------
|
|
// globalPlace()
|
|
//
|
|
/// \brief Performs analytic placement using a GORDIAN-like algorithm.
|
|
//
|
|
/// Updates the positions of all non-fixed non-pad cells.
|
|
///
|
|
// --------------------------------------------------------------------
|
|
void globalPlace() {
|
|
bool completionFlag = false;
|
|
int iteration = 0;
|
|
|
|
printf("PLAC-10 : Global placement (wirelength-driven Gordian)\n");
|
|
|
|
initPartitioning();
|
|
|
|
// build matrices representing interconnections
|
|
printf("QMAN-00 : \tconstructing initial quadratic problem...\n");
|
|
constructQuadraticProblem();
|
|
|
|
// iterate placement until termination condition is met
|
|
while(!completionFlag) {
|
|
printf("QMAN-01 : \titeration %d numPartitions = %d\n",iteration,g_place_numPartitions);
|
|
|
|
// do the global optimization in each direction
|
|
printf("QMAN-01 : \t\tglobal optimization\n");
|
|
solveQuadraticProblem(!IGNORE_COG);
|
|
|
|
// -------- PARTITIONING BASED CELL SPREADING ------
|
|
|
|
// bisection
|
|
printf("QMAN-01 : \t\tpartition refinement\n");
|
|
if (REALLOCATE_PARTITIONS) reallocPartitions();
|
|
completionFlag |= refinePartitions();
|
|
|
|
printf("QMAN-01 : \t\twirelength = %e\n", getTotalWirelength());
|
|
|
|
iteration++;
|
|
}
|
|
|
|
// final global optimization
|
|
printf("QMAN-02 : \t\tfinal pass\n");
|
|
if (FINAL_REALLOCATE_PARTITIONS) reallocPartitions();
|
|
solveQuadraticProblem(!IGNORE_COG);
|
|
printf("QMAN-01 : \t\twirelength = %e\n", getTotalWirelength());
|
|
|
|
// clean up
|
|
sanitizePlacement();
|
|
printf("QMAN-01 : \t\twirelength = %e\n", getTotalWirelength());
|
|
globalFixDensity(25, g_place_rowHeight*5);
|
|
printf("QMAN-01 : \t\twirelength = %e\n", getTotalWirelength());
|
|
}
|
|
|
|
|
|
// --------------------------------------------------------------------
|
|
// globalIncremental()
|
|
//
|
|
/// \brief Performs analytic placement using a GORDIAN-like algorithm.
|
|
//
|
|
/// Requires a valid set of partitions.
|
|
///
|
|
// --------------------------------------------------------------------
|
|
|
|
void globalIncremental() {
|
|
if (!g_place_rootPartition) {
|
|
printf("WARNING: Can not perform incremental placement\n");
|
|
globalPlace();
|
|
return;
|
|
}
|
|
|
|
printf("PLAC-10 : Incremental global placement\n");
|
|
|
|
incrementalPartition();
|
|
|
|
printf("QMAN-00 : \tconstructing initial quadratic problem...\n");
|
|
constructQuadraticProblem();
|
|
|
|
solveQuadraticProblem(!IGNORE_COG);
|
|
printf("QMAN-01 : \t\twirelength = %e\n", getTotalWirelength());
|
|
|
|
// clean up
|
|
sanitizePlacement();
|
|
printf("QMAN-01 : \t\twirelength = %e\n", getTotalWirelength());
|
|
globalFixDensity(25, g_place_rowHeight*5);
|
|
printf("QMAN-01 : \t\twirelength = %e\n", getTotalWirelength());
|
|
}
|
|
|
|
|
|
// --------------------------------------------------------------------
|
|
// sanitizePlacement()
|
|
//
|
|
/// \brief Moves any cells that are outside of the core bounds to the nearest location within.
|
|
//
|
|
// --------------------------------------------------------------------
|
|
void sanitizePlacement() {
|
|
int c;
|
|
float order_width = g_place_rowHeight;
|
|
float x, y, edge, w, h;
|
|
|
|
printf("QCLN-10 : \tsanitizing placement\n");
|
|
|
|
for(c=0; c<g_place_numCells; c++) if (g_place_concreteCells[c]) {
|
|
ConcreteCell *cell = g_place_concreteCells[c];
|
|
if (cell->m_fixed || cell->m_parent->m_pad) {
|
|
continue;
|
|
}
|
|
// the new locations of the cells will be distributed within
|
|
// a small margin inside the border so that ordering is preserved
|
|
order_width = g_place_rowHeight;
|
|
|
|
x = cell->m_x, y = cell->m_y,
|
|
w = cell->m_parent->m_width, h = cell->m_parent->m_height;
|
|
|
|
if ((edge=x-w*0.5) < g_place_coreBounds.x) {
|
|
x = g_place_coreBounds.x+w*0.5 +
|
|
order_width/(1.0+g_place_coreBounds.x-edge);
|
|
}
|
|
else if ((edge=x+w*0.5) > g_place_coreBounds.x+g_place_coreBounds.w) {
|
|
x = g_place_coreBounds.x+g_place_coreBounds.w-w*0.5 -
|
|
order_width/(1.0+edge-g_place_coreBounds.x-g_place_coreBounds.w);
|
|
}
|
|
if ((edge=y-h*0.5) < g_place_coreBounds.y) {
|
|
y = g_place_coreBounds.y+h*0.5 +
|
|
order_width/(1.0+g_place_coreBounds.y-edge);
|
|
}
|
|
else if ((edge=y+h*0.5) > g_place_coreBounds.y+g_place_coreBounds.h) {
|
|
y = g_place_coreBounds.y+g_place_coreBounds.h-h*0.5 -
|
|
order_width/(1.0+edge-g_place_coreBounds.x-g_place_coreBounds.w);
|
|
}
|
|
cell->m_x = x;
|
|
cell->m_y = y;
|
|
}
|
|
}
|
|
ABC_NAMESPACE_IMPL_END
|
|
|