#ifndef GRID_H #define GRID_H #include "parser.h" struct routed_net { int net_id; struct routed_net *next; }; struct grid_element { routed_net *rn; }; struct grid_cost { // this is multiplexed as well, cells with x&0x01==1 have their // cost in the low nybble, other cells have it in the high nybble unsigned char cost; }; struct grid_prev_visited { // 3 bits for previous direction // 4th bit for visited // two grid spaces per element unsigned char stuff; }; class grid { private: // this array holds the grid structure grid_element ***ge; grid_prev_visited ***gpv; grid_cost ***gc; float cost_quantizer; int max_cost; // here we store how much each net costs to cross for // a given run, it is indexed by net id public: vector<int> net_costs; int quantized_costs[256]; int width; int height; void resetCost(cell c); int quantizeCosts(); int countNets(cell c); int isPin(cell c); int makeGrid(vector<pin> &vp, int width, int height, int max_net); int clearVisitedAndPrev(); inline void setVisited(cell c){ if (c.x&0x01) { gpv[c.l][c.y][c.x/2].stuff|=0x08; } else { gpv[c.l][c.y][c.x/2].stuff|=0x80; } } inline bool getVisited(cell c){ if (c.x&0x01) { if (gpv[c.l][c.y][c.x/2].stuff&0x08) return true; return false; } else { if (gpv[c.l][c.y][c.x/2].stuff&0x80) return true; return false; } } inline int cellCost(cell c) { int l; if (c.x&0x1) { l=gc[c.l][c.y][c.x/2].cost&0x0f; } else { l=(gc[c.l][c.y][c.x/2].cost&0xf0)>>4; } return quantized_costs[l]; } int cellCostAccurate(cell c); /* inline int getNet(cell c){ return ge[c.l][c.y][c.x].net; } */ inline char getPrevDir(cell c) { if (c.x&0x01) { return (gpv[c.l][c.y][c.x/2].stuff&0x07); } else { return (gpv[c.l][c.y][c.x/2].stuff&0x70)>>4; } } inline void setPrev(cell c, cell prev, int dir) { if (c.x&0x01) { gpv[c.l][c.y][c.x/2].stuff&=0xF8; gpv[c.l][c.y][c.x/2].stuff|=dir; } else { gpv[c.l][c.y][c.x/2].stuff&=0x8F; gpv[c.l][c.y][c.x/2].stuff|=(dir<<4); } } cell getPrev(cell c); void addCellToPath(cell &lc, int net); int addNetToPath(list<cell> &lc, int net); int removeNetFromPath(list<cell> &lc, int net); int getNeighbor(cell c, int dir, cell &nc){ int nx,ny,nz; switch (dir) { case 0: // north nx=c.x; ny=c.y-1; nz=c.l; break; case 1: // east nx=c.x+1; ny=c.y; nz=c.l; break; case 2: // south nx=c.x; ny=c.y+1; nz=c.l; break; case 3: // west nx=c.x-1; ny=c.y; nz=c.l; break; case 4: // up nx=c.x; ny=c.y; nz=c.l+1; break; case 5: // down nx=c.x; ny=c.y; nz=c.l-1; break; } if (nx<0 || nx>=width) return 0; if (ny<0 || ny>=height) return 0; if (nz<0 || nz>3) return 0; nc.x=nx; nc.y=ny; nc.l=nz; return 1; } }; #endif