summaryrefslogtreecommitdiffstats
path: root/src/phys/place/place_base.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/phys/place/place_base.c')
-rw-r--r--src/phys/place/place_base.c345
1 files changed, 345 insertions, 0 deletions
diff --git a/src/phys/place/place_base.c b/src/phys/place/place_base.c
new file mode 100644
index 00000000..4e38f1d1
--- /dev/null
+++ b/src/phys/place/place_base.c
@@ -0,0 +1,345 @@
+/*===================================================================*/
+//
+// place_base.c
+//
+// Aaron P. Hurst, 2003-2007
+// ahurst@eecs.berkeley.edu
+//
+/*===================================================================*/
+
+#include <stdlib.h>
+#include <limits.h>
+#include <assert.h>
+#include <string.h>
+
+#include "place_base.h"
+#include "place_gordian.h"
+
+// --------------------------------------------------------------------
+// Global variables
+//
+// --------------------------------------------------------------------
+
+int g_place_numCells = 0;
+int g_place_numNets = 0;
+float g_place_rowHeight = 1.0;
+
+Rect g_place_coreBounds;
+Rect g_place_padBounds;
+
+ConcreteCell **g_place_concreteCells = NULL;
+int g_place_concreteCellsSize = 0;
+ConcreteNet **g_place_concreteNets = NULL;
+int g_place_concreteNetsSize = 0;
+
+
+// --------------------------------------------------------------------
+// getNetBBox()
+//
+/// \brief Returns the bounding box of a net.
+//
+// --------------------------------------------------------------------
+Rect getNetBBox(const ConcreteNet *net) {
+ int t;
+ Rect r;
+
+ assert(net);
+
+ r.x = r.y = INT_MAX;
+ r.w = r.h = -INT_MAX;
+ for(t=0; t<net->m_numTerms; t++) {
+ r.x = net->m_terms[t]->m_x < r.x ? net->m_terms[t]->m_x : r.x;
+ r.y = net->m_terms[t]->m_y < r.y ? net->m_terms[t]->m_y : r.y;
+ r.w = net->m_terms[t]->m_x > r.w ? net->m_terms[t]->m_x : r.w;
+ r.h = net->m_terms[t]->m_y > r.h ? net->m_terms[t]->m_y : r.h;
+ }
+ r.w -= r.x; r.h -= r.y;
+ return r;
+}
+
+
+// --------------------------------------------------------------------
+// getNetWirelength()
+//
+/// \brief Returns the half-perimeter wirelength of a net.
+//
+// --------------------------------------------------------------------
+float getNetWirelength(const ConcreteNet *net) {
+ Rect r;
+
+ assert(net);
+
+ r = getNetBBox(net);
+ return r.w+r.h;
+}
+
+
+// --------------------------------------------------------------------
+// getTotalWirelength()
+//
+/// \brief Returns the total HPWL of all nets.
+//
+// --------------------------------------------------------------------
+float getTotalWirelength() {
+ float r = 0;
+ int n;
+ for(n=0; n<g_place_numNets; n++) if (g_place_concreteNets[n])
+ r += getNetWirelength(g_place_concreteNets[n]);
+ return r;
+}
+
+
+// --------------------------------------------------------------------
+// getCellArea()
+//
+// --------------------------------------------------------------------
+float getCellArea(const ConcreteCell *cell) {
+ assert(cell);
+ return cell->m_parent->m_width*cell->m_parent->m_height;
+}
+
+
+// --------------------------------------------------------------------
+// addConcreteNet()
+//
+/// \brief Adds a net to the placement database.
+///
+/// The net object must already be allocated and the ID must be set
+/// appropriately.
+//
+// --------------------------------------------------------------------
+void addConcreteNet(ConcreteNet *net) {
+ assert(net);
+ assert(net->m_id >= 0);
+ if (net->m_id >= g_place_concreteNetsSize) {
+ g_place_concreteNetsSize = (net->m_id > g_place_concreteNetsSize ?
+ net->m_id : g_place_concreteNetsSize);
+ g_place_concreteNetsSize *= 1.5;
+ g_place_concreteNetsSize += 20;
+ g_place_concreteNets = (ConcreteNet**)realloc(g_place_concreteNets,
+ sizeof(ConcreteNet*)*g_place_concreteNetsSize);
+ assert(g_place_concreteNets);
+ }
+ if (net->m_id >= g_place_numNets) {
+ memset(&(g_place_concreteNets[g_place_numNets]), 0,
+ sizeof(ConcreteNet*)*(net->m_id+1-g_place_numNets));
+ g_place_numNets = net->m_id+1;
+ assert(g_place_numNets <= g_place_concreteNetsSize);
+ }
+ g_place_concreteNets[net->m_id] = net;
+}
+
+
+// --------------------------------------------------------------------
+// delConcreteNet()
+//
+/// Does not deallocate memory.
+// --------------------------------------------------------------------
+void delConcreteNet(ConcreteNet *net) {
+ assert(net);
+ g_place_concreteNets[net->m_id] = 0;
+ while(!g_place_concreteNets[g_place_numNets-1]) g_place_numNets--;
+}
+
+
+// --------------------------------------------------------------------
+// addConcreteCell()
+//
+/// The cell object must already be allocated and the ID must be set
+/// appropriately.
+//
+// --------------------------------------------------------------------
+void addConcreteCell(ConcreteCell *cell) {
+ assert(cell);
+ assert(cell->m_id >= 0);
+ if (cell->m_id >= g_place_concreteCellsSize) {
+ g_place_concreteCellsSize = (cell->m_id > g_place_concreteCellsSize ?
+ cell->m_id : g_place_concreteCellsSize);
+ g_place_concreteCellsSize *= 1.5;
+ g_place_concreteCellsSize += 20;
+ g_place_concreteCells = (ConcreteCell**)realloc(g_place_concreteCells,
+ sizeof(ConcreteCell*)*g_place_concreteCellsSize);
+ assert(g_place_concreteCells);
+ }
+ if (cell->m_id >= g_place_numCells) {
+ memset(&(g_place_concreteCells[g_place_numCells]), 0,
+ sizeof(ConcreteCell*)*(cell->m_id+1-g_place_numCells));
+ g_place_numCells = cell->m_id+1;
+ }
+ g_place_concreteCells[cell->m_id] = cell;
+}
+
+
+// --------------------------------------------------------------------
+// delCellFromPartition()
+//
+// --------------------------------------------------------------------
+void delCellFromPartition(ConcreteCell *cell, Partition *p) {
+ int c;
+ bool found = false;
+
+ assert(cell);
+ assert(p);
+
+ for(c=0; c<p->m_numMembers; c++)
+ if (p->m_members[c] == cell) {
+ p->m_members[c] = 0;
+ p->m_area -= getCellArea(cell);
+ found = true;
+ break;
+ }
+
+ if (!found) return;
+
+ if (!p->m_leaf) {
+ delCellFromPartition(cell, p->m_sub1);
+ delCellFromPartition(cell, p->m_sub2);
+ }
+}
+
+
+// --------------------------------------------------------------------
+// delConcreteCell()
+//
+/// \brief Removes a cell from the placement database.
+///
+/// Does not deallocate memory.
+///
+/// Important: does not modify nets that may point to this
+/// cell. If these are connections are not removed, segmentation faults
+/// and other nasty errors will occur.
+//
+// --------------------------------------------------------------------
+void delConcreteCell(ConcreteCell *cell) {
+ assert(cell);
+ g_place_concreteCells[cell->m_id] = 0;
+ while(!g_place_concreteCells[g_place_numCells-1]) g_place_numCells--;
+
+ if (g_place_rootPartition) delCellFromPartition(cell, g_place_rootPartition);
+}
+
+
+// --------------------------------------------------------------------
+// netSortByX...
+//
+/// \brief Sorts nets by position of one of its corners.
+//
+/// These are for use with qsort().
+///
+/// Can tolerate pointers to NULL objects.
+///
+// --------------------------------------------------------------------
+int netSortByL(const void *a, const void *b) {
+ const ConcreteNet *pa = *(const ConcreteNet **)a;
+ const ConcreteNet *pb = *(const ConcreteNet **)b;
+ Rect ba, bb;
+
+ if (!pa && !pb) return 0;
+ else if (!pa) return -1;
+ else if (!pb) return 1;
+ ba = getNetBBox(pa), bb = getNetBBox(pb);
+ if (ba.x < bb.x) return -1;
+ if (ba.x > bb.x) return 1;
+ return 0;
+}
+
+int netSortByR(const void *a, const void *b) {
+ const ConcreteNet *pa = *(const ConcreteNet **)a;
+ const ConcreteNet *pb = *(const ConcreteNet **)b;
+ Rect ba, bb;
+
+ if (!pa && !pb) return 0;
+ else if (!pa) return -1;
+ else if (!pb) return 1;
+ ba = getNetBBox(pa), bb = getNetBBox(pb);
+ if (ba.x + ba.w < bb.x + bb.w) return -1;
+ if (ba.x + ba.w > bb.x + bb.w) return 1;
+ return 0;
+}
+
+int netSortByB(const void *a, const void *b) {
+ const ConcreteNet *pa = *(const ConcreteNet **)a;
+ const ConcreteNet *pb = *(const ConcreteNet **)b;
+ Rect ba, bb;
+
+ if (!pa && !pb) return 0;
+ else if (!pa) return -1;
+ else if (!pb) return 1;
+ ba = getNetBBox(pa), bb = getNetBBox(pb);
+ if (ba.y + ba.h < bb.y + bb.h) return -1;
+ if (ba.y + ba.h > bb.y + bb.h) return 1;
+ return 0;
+}
+
+int netSortByT(const void *a, const void *b) {
+ const ConcreteNet *pa = *(const ConcreteNet **)a;
+ const ConcreteNet *pb = *(const ConcreteNet **)b;
+ Rect ba, bb;
+
+ if (!pa && !pb) return 0;
+ else if (!pa) return -1;
+ else if (!pb) return 1;
+ ba = getNetBBox(pa), bb = getNetBBox(pb);
+ if (ba.y < bb.y) return -1;
+ if (ba.y > bb.y) return 1;
+ return 0;
+}
+
+int netSortByID(const void *a, const void *b) {
+ const ConcreteNet *pa = *(const ConcreteNet **)a;
+ const ConcreteNet *pb = *(const ConcreteNet **)b;
+
+ if (!pa && !pb) return 0;
+ else if (!pa) return -1;
+ else if (!pb) return 1;
+ if (pa->m_id < pb->m_id) return -1;
+ if (pa->m_id > pb->m_id) return 1;
+ return 0;
+}
+
+
+// --------------------------------------------------------------------
+// cellSortByX...
+//
+/// \brief Sorts cells by either position coordinate.
+//
+/// These are for use with qsort().
+///
+/// Can tolerate pointers to NULL objects.
+//
+// --------------------------------------------------------------------
+int cellSortByX(const void *a, const void *b) {
+ const ConcreteCell *pa = *(const ConcreteCell **)a;
+ const ConcreteCell *pb = *(const ConcreteCell **)b;
+
+ if (!pa && !pb) return 0;
+ else if (!pa) return -1;
+ else if (!pb) return 1;
+ if (pa->m_x < pb->m_x) return -1;
+ if (pa->m_x > pb->m_x) return 1;
+ return 0;
+}
+
+int cellSortByY(const void *a, const void *b) {
+ const ConcreteCell *pa = *(const ConcreteCell **)a;
+ const ConcreteCell *pb = *(const ConcreteCell **)b;
+
+ if (!pa && !pb) return 0;
+ else if (!pa) return -1;
+ else if (!pb) return 1;
+ if (pa->m_y < pb->m_y) return -1;
+ if (pa->m_y > pb->m_y) return 1;
+ return 0;
+}
+
+int cellSortByID(const void *a, const void *b) {
+ const ConcreteCell *pa = *(const ConcreteCell **)a;
+ const ConcreteCell *pb = *(const ConcreteCell **)b;
+
+ if (!pa && !pb) return 0;
+ else if (!pa) return -1;
+ else if (!pb) return 1;
+ if (pa->m_id < pb->m_id) return -1;
+ if (pa->m_id > pb->m_id) return 1;
+ return 0;
+}