OpenFPGA/abc/src/phys/place/place_gordian.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