/*===================================================================*/ // // place_bin.c // // Aaron P. Hurst, 2007 // ahurst@eecs.berkeley.edu // /*===================================================================*/ #include #include #include #include #include //#define DEBUG #include "place_base.h" ABC_NAMESPACE_IMPL_START // -------------------------------------------------------------------- // Global variables // // -------------------------------------------------------------------- // -------------------------------------------------------------------- // Function prototypes and local data structures // // -------------------------------------------------------------------- void spreadDensityX(int numBins, float maxMovement); void spreadDensityY(int numBins, float maxMovement); // -------------------------------------------------------------------- // globalFixDensity() // /// Doesn't deal well with fixed cells in the core area. // -------------------------------------------------------------------- void globalFixDensity(int numBins, float maxMovement) { printf("QCLN-10 : \tbin-based density correction\n"); spreadDensityX(numBins, maxMovement); // spreadDensityY(numBins, maxMovement); } // -------------------------------------------------------------------- // spreadDensityX() // // -------------------------------------------------------------------- void spreadDensityX(int numBins, float maxMovement) { int c, c2, c3, x, y; float totalArea = 0; int moveableCells = 0; float yBinArea = 0, yCumArea = 0; int yBinStart = 0, yBinCount = 0; int xBinCount, xBinStart; float xBinArea, xCumArea; float lastOldEdge; float lastNewEdge; float curOldEdge, curNewEdge; float stretch, w; ConcreteCell *xCell, *yCell; ConcreteCell **binCells; ConcreteCell **allCells; binCells = (ConcreteCell **)malloc(sizeof(ConcreteCell*)*g_place_numCells); allCells = (ConcreteCell **)malloc(sizeof(ConcreteCell*)*g_place_numCells); for(c=0; cm_fixed && !cell->m_parent->m_pad) { allCells[moveableCells++] = cell; totalArea += getCellArea(cell); } } // spread X qsort(allCells, moveableCells, sizeof(ConcreteCell*), cellSortByY); y = 0; // for each y-bin... for(c=0; c= totalArea*(y+1)/numBins && yBinArea > 0) { memcpy(binCells, &(allCells[yBinStart]), sizeof(ConcreteCell*)*yBinCount); qsort(binCells, yBinCount, sizeof(ConcreteCell*), cellSortByX); #if defined(DEBUG) printf("y-bin %d count=%d area=%f\n",y,yBinCount, yBinArea); #endif x = 0; xBinCount = 0, xBinStart = 0; xBinArea = 0, xCumArea = 0; lastOldEdge = g_place_coreBounds.x; lastNewEdge = g_place_coreBounds.x; // for each x-bin... for(c2=0; c2m_x; printf("%.3f ", xCell->m_x); // have we filled up an x-bin? if (xCumArea >= yBinArea*(x+1)/numBins && xBinArea > 0) { curNewEdge = lastNewEdge + g_place_coreBounds.w*xBinArea/yBinArea; if (curNewEdge > g_place_coreBounds.x+g_place_coreBounds.w) curNewEdge = g_place_coreBounds.x+g_place_coreBounds.w; if ((curNewEdge-curOldEdge)>maxMovement) curNewEdge = curOldEdge + maxMovement; if ((curOldEdge-curNewEdge)>maxMovement) curNewEdge = curOldEdge - maxMovement; #if defined(DEBUG) printf("->\tx-bin %d count=%d area=%f (%f,%f)->(%f,%f)\n",x, xBinCount, xBinArea, curOldEdge, lastOldEdge, curNewEdge, lastNewEdge); #endif stretch = (curNewEdge-lastNewEdge)/(curOldEdge-lastOldEdge); // stretch! for(c3=xBinStart; c3m_x = lastNewEdge+(c3-xBinStart)*(curNewEdge-lastNewEdge); else binCells[c3]->m_x = lastNewEdge+(binCells[c3]->m_x-lastOldEdge)*stretch; // force within core w = binCells[c3]->m_parent->m_width*0.5; if (binCells[c3]->m_x-w < g_place_coreBounds.x) binCells[c3]->m_x = g_place_coreBounds.x+w; if (binCells[c3]->m_x+w > g_place_coreBounds.x+g_place_coreBounds.w) binCells[c3]->m_x = g_place_coreBounds.x+g_place_coreBounds.w-w; } lastOldEdge = curOldEdge; lastNewEdge = curNewEdge; x++; xBinCount = 0; xBinArea = 0; xBinStart = c2+1; } } y++; yBinCount = 0; yBinArea = 0; yBinStart = c+1; } } free(binCells); free(allCells); } // -------------------------------------------------------------------- // spreadDensityY() // // -------------------------------------------------------------------- void spreadDensityY(int numBins, float maxMovement) { int c, c2, c3, x, y; float totalArea = 0; int moveableCells = 0; float xBinArea = 0, xCumArea = 0; int xBinStart = 0, xBinCount = 0; int yBinCount, yBinStart; float yBinArea, yCumArea; float lastOldEdge; float lastNewEdge; float curOldEdge, curNewEdge; float stretch, h; ConcreteCell *xCell, *yCell; ConcreteCell **binCells; ConcreteCell **allCells; binCells = (ConcreteCell **)malloc(sizeof(ConcreteCell*)*g_place_numCells); allCells = (ConcreteCell **)malloc(sizeof(ConcreteCell*)*g_place_numCells); for(c=0; cm_fixed && !cell->m_parent->m_pad) { allCells[moveableCells++] = cell; totalArea += getCellArea(cell); } } // spread Y qsort(allCells, moveableCells, sizeof(ConcreteCell*), cellSortByX); x = 0; // for each x-bin... for(c=0; c= totalArea*(x+1)/numBins && xBinArea > 0) { memcpy(binCells, &(allCells[xBinStart]), sizeof(ConcreteCell*)*xBinCount); qsort(binCells, xBinCount, sizeof(ConcreteCell*), cellSortByY); // printf("x-bin %d count=%d area=%f\n",y,yBinCount, yBinArea); y = 0; yBinCount = 0, yBinStart = 0; yBinArea = 0, yCumArea = 0; lastOldEdge = g_place_coreBounds.y; lastNewEdge = g_place_coreBounds.y; // for each y-bin... for(c2=0; c2m_y; // have we filled up an x-bin? if (yCumArea >= xBinArea*(y+1)/numBins && yBinArea > 0) { curNewEdge = lastNewEdge + g_place_coreBounds.h*yBinArea/xBinArea; if (curNewEdge > g_place_coreBounds.y+g_place_coreBounds.h) curNewEdge = g_place_coreBounds.y+g_place_coreBounds.h; if ((curNewEdge-curOldEdge)>maxMovement) curNewEdge = curOldEdge + maxMovement; if ((curOldEdge-curNewEdge)>maxMovement) curNewEdge = curOldEdge - maxMovement; if (curOldEdge == lastOldEdge) continue; // hmmm stretch = (curNewEdge-lastNewEdge)/(curOldEdge-lastOldEdge); // stretch! for(c3=yBinStart; c3m_y = lastNewEdge+(binCells[c3]->m_y-lastOldEdge)*stretch; // force within core h = binCells[c3]->m_parent->m_height; if (binCells[c3]->m_y-h < g_place_coreBounds.y) binCells[c3]->m_y = g_place_coreBounds.y+h; if (binCells[c3]->m_y+h > g_place_coreBounds.y+g_place_coreBounds.h) binCells[c3]->m_y = g_place_coreBounds.y+g_place_coreBounds.h-h; } lastOldEdge = curOldEdge; lastNewEdge = curNewEdge; y++; yBinCount = 0; yBinArea = 0; yBinStart = c2+1; } } x++; xBinCount = 0; xBinArea = 0; xBinStart = c+1; } } free(binCells); free(allCells); } ABC_NAMESPACE_IMPL_END