#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