1 package edu.berkeley.slipway.mpar;
2 import com.atmel.fpslic.*;
3 import byucc.edif.tools.merge.*;
7 import edu.berkeley.slipway.*;
8 import com.atmel.fpslic.*;
9 import static com.atmel.fpslic.FpslicConstants.*;
10 import static edu.berkeley.slipway.mpar.MPARDemo.*;
12 public class PhysicalFpslic extends PhysicalDevice {
13 public static int CELLSEP = 40;
14 public static int PLANESEP = 3;
16 private final FpslicDevice fpslic;
18 public final int width;
19 public final int height;
20 private final PhysicalNet[][][][] sectorWires;
21 private final PhysicalFpslicCell[][] cells;
23 public PhysicalCell getCell(int col, int row) {
24 if (col<0) return null;
25 if (row<0) return null;
26 if (col>=width) return null;
27 if (row>=height) return null;
28 return cells[col][row];
31 public PhysicalFpslic(final FpslicDevice fpslic, int width, int height) {
35 sectorWires = new PhysicalNet[width][height][5][2];
36 for(int x=0; x<width; x+=4)
37 for(int y=0; y<height; y+=4)
38 for(int p=0; p<5; p++) {
39 for(int xc=x; xc<x+4; xc++) {
40 PhysicalNet vwire = new PhysicalNet("("+xc+","+y+"-"+(y+3)+")");
41 for(int yc=y; yc<y+4; yc++)
42 if (xc < sectorWires.length && yc < sectorWires[xc].length)
43 sectorWires[xc][yc][p][0] = vwire;
45 for(int yc=y; yc<y+4; yc++) {
46 PhysicalNet hwire = new PhysicalNet("("+x+"-"+(x+3)+","+yc+")");
47 for(int xc=x; xc<x+4; xc++)
48 if (xc < sectorWires.length && yc < sectorWires[xc].length)
49 sectorWires[xc][yc][p][1] = hwire;
53 for(int x=4; x<width; x+=4) {
54 for(int y=0; y<height; y++) {
55 for(int p=0; p<5; p++) {
59 new PhysicalFpslicPip(x,
61 -1 * (4-p) * PLANESEP,
62 -1 * (0+p) * PLANESEP,
64 sectorWires[x-1][y][p][1],
65 new PhysicalNet[] { sectorWires[x][y][p][1] },
67 public void set(boolean connected) {
68 fpslic.cell(xc-1, yc).hwire(pc).drives(fpslic.cell(xc, yc).hwire(pc), connected);
71 new PhysicalFpslicPip(x,
73 -1 * (4-p) * PLANESEP,
74 -1 * (0+p) * PLANESEP,
76 sectorWires[x][y][p][1],
77 new PhysicalNet[] { sectorWires[x-1][y][p][1] },
79 public void set(boolean connected) {
80 fpslic.cell(xc, yc).hwire(pc).drives(fpslic.cell(xc-1, yc).hwire(pc), connected);
87 for(int x=0; x<width; x++) {
88 for(int y=4; y<height; y+=4) {
89 for(int p=0; p<5; p++) {
93 new PhysicalFpslicPip(x,
95 -1 * (4-p) * PLANESEP,
96 -1 * (0+p) * PLANESEP,
98 sectorWires[x][y-1][p][0],
99 new PhysicalNet[] { sectorWires[x][y][p][0] },
101 public void set(boolean connected) {
102 fpslic.cell(xc, yc-1).vwire(pc).drives(fpslic.cell(xc, yc).vwire(pc), connected);
105 new PhysicalFpslicPip(x,
107 -1 * (4-p) * PLANESEP,
108 -1 * (0+p) * PLANESEP,
110 sectorWires[x][y][p][0],
111 new PhysicalNet[] { sectorWires[x][y-1][p][0] },
113 public void set(boolean connected) {
114 fpslic.cell(xc, yc).vwire(pc).drives(fpslic.cell(xc, yc-1).vwire(pc), connected);
121 cells = new PhysicalFpslicCell[width][height];
122 for(int x=0; x<width; x++)
123 for(int y=0; y<height; y++) {
124 cells[x][y] = new PhysicalFpslicCell(x, y);
126 for(int x=0; x<width; x++)
127 for(int y=0; y<height; y++)
131 private PhysicalNet getSectorWire(int col, int row, int plane, boolean horizontal) {
132 return sectorWires[col][row][plane][horizontal ? 1 : 0];
135 public PhysicalCell randomCell(Random rand) {
136 int x = (Math.abs(rand.nextInt()) % width);
137 int y = (Math.abs(rand.nextInt()) % height);
138 return getCell(x, y);
141 public class PhysicalFpslicCell extends PhysicalCell {
146 private PhysicalNet outputNet;
147 private PhysicalNet xin;
148 private PhysicalNet yin;
149 private PhysicalNet[] local = new PhysicalNet[5];
151 public PhysicalCell randomCellWithin(Random rand, double percentOfDevice) {
152 int distance = (int)(percentOfDevice * Math.max(width, height));
153 if (distance < 4) distance = 4;
156 int dx = (Math.abs(rand.nextInt()) % (distance*2+1));
157 int dy = (Math.abs(rand.nextInt()) % (distance*2+1));
158 PhysicalCell pc = getCell(col+dx-distance, row+dy-distance);
159 if (pc != null) return pc;
162 public void place(NetList.Node n) {
165 FpslicDevice.Cell cell = fpslic.cell(x,y);
173 String type = n.getType();
174 if (type.equals("and2")) cell.xlut(LUT_SELF & LUT_OTHER);
175 else if (type.equals("or2")) cell.xlut(LUT_SELF | LUT_OTHER);
176 else if (type.equals("xor2")) cell.xlut(LUT_SELF ^ LUT_OTHER);
177 else if (type.equals("buf")) cell.xlut(LUT_SELF);
178 else if (type.equals("inv")) cell.xlut(~LUT_SELF);
179 else if (type.equals("cell0")) return;
182 public FpslicDevice.Cell cell() { return fpslic.cell(col, row); }
183 public PhysicalNet getNet(String name) {
184 if (name.equals("out")) return outputNet;
185 if (name.equals("xi")) return xin;
186 if (name.equals("yi")) return yin;
187 throw new RuntimeException("unknown");
190 public void setFunction(String type) {
191 FpslicDevice.Cell cell = cell();
196 if (type.equals("and2")) cell.xlut(LUT_SELF & LUT_OTHER);
197 else if (type.equals("or2")) cell.xlut(LUT_SELF | LUT_OTHER);
198 else if (type.equals("xor2")) cell.xlut(LUT_SELF ^ LUT_OTHER);
199 else if (type.equals("buf")) cell.xlut(LUT_SELF);
200 else if (type.equals("inv")) cell.xlut(~LUT_SELF);
204 // FIXME wow, this is a horrendous hack!
206 if (getCell(col-1, row+1) != null)
207 new PhysicalFpslicPip(col, row, 0, 0,
208 this+".xiNW", getCell(col-1, row+1).getNet("out"), new PhysicalNet[] { xin }, 5) {
209 public void set(boolean connected) { cell().xi(connected ? NW : NONE); }
211 if (getCell(col-1, row-1) != null)
212 new PhysicalFpslicPip(col, row, 0, 0,
213 this+".xiSW", getCell(col-1, row-1).getNet("out"), new PhysicalNet[] { xin }, 5) {
214 public void set(boolean connected) { cell().xi(connected ? SW : NONE); }
216 if (getCell(col+1, row+1) != null)
217 new PhysicalFpslicPip(col, row, 0, 0,
218 this+".xiNE", getCell(col+1, row+1).getNet("out"), new PhysicalNet[] { xin }, 5) {
219 public void set(boolean connected) { cell().xi(connected ? NE : NONE); }
221 if (getCell(col+1, row-1) != null)
222 new PhysicalFpslicPip(col, row, 0, 0,
223 this+".xiSE", getCell(col+1, row-1).getNet("out"), new PhysicalNet[] { xin }, 5) {
224 public void set(boolean connected) { cell().xi(connected ? SE : NONE); }
227 if (getCell(col-1, row) != null)
228 new PhysicalFpslicPip(col, row, 0, 0,
229 this+".yiW", getCell(col-1, row).getNet("out"), new PhysicalNet[] { yin }, 5) {
230 public void set(boolean connected) { cell().yi(connected ? WEST : NONE); }
232 if (getCell(col, row-1) != null)
233 new PhysicalFpslicPip(col, row, 0, 0,
234 this+".yiN", getCell(col, row-1).getNet("out"), new PhysicalNet[] { yin }, 5) {
235 public void set(boolean connected) { cell().yi(connected ? NORTH : NONE); }
237 if (getCell(col+1, row) != null)
238 new PhysicalFpslicPip(col, row, 0, 0,
239 this+".yiE", getCell(col+1, row).getNet("out"), new PhysicalNet[] { yin }, 5) {
240 public void set(boolean connected) { cell().yi(connected ? EAST : NONE); }
242 if (getCell(col, row+1) != null)
243 new PhysicalFpslicPip(col, row, 0, 0,
244 this+".yiS", getCell(col, row+1).getNet("out"), new PhysicalNet[] { yin }, 5) {
245 public void set(boolean connected) { cell().yi(connected ? SOUTH : NONE); }
250 private PhysicalFpslicCell(int col, int row) {
253 outputNet = new PhysicalNet(this.toString()+".out");
254 xin = new PhysicalNet(this.toString()+".xi");
255 yin = new PhysicalNet(this.toString()+".yi");
256 for(int j=0; j<5; j++) {
258 // plane 3 is reserved for debugging
262 local[i] = new PhysicalNet(this.toString()+".L"+i);
263 new PhysicalFpslicPip(col, row, -1 * (4-j) * PLANESEP, -1 * j * PLANESEP,
264 this+".h"+i, null, new PhysicalNet[] {
265 local[i], getSectorWire(col, row, i, true) }) {
266 public void set(boolean connected) { cell().h(i, connected); }
268 new PhysicalFpslicPip(col, row, -1 * (4-j) * PLANESEP, -1 * j * PLANESEP,
269 this+".v"+i, null, new PhysicalNet[] {
270 local[i], getSectorWire(col, row, i, false) }) {
271 public void set(boolean connected) { cell().v(i, connected); }
273 new PhysicalFpslicPip(col, row, -1 * (4-j) * PLANESEP + 15, -1 * j * PLANESEP + 15,
274 this+".xi"+i, local[i], new PhysicalNet[] { xin }) {
275 public void set(boolean connected) { cell().xi(connected ? i : NONE); }
277 new PhysicalFpslicPip(col, row, -1 * (4-j) * PLANESEP + 15, -1 * j * PLANESEP + 15,
278 this+".yi"+i, local[i], new PhysicalNet[] { yin }) {
279 public void set(boolean connected) { cell().yi(connected ? i : NONE); }
281 new PhysicalFpslicPip(col, row, -1 * (4-j) * PLANESEP + 15, -1 * j * PLANESEP + 15,
282 this+".o"+i, outputNet, new PhysicalNet[] { local[i] }) {
283 public void set(boolean connected) { cell().out(i, connected); }
287 public String toString() { return "cell@("+col+","+row+")"; }
290 public abstract class PhysicalFpslicPip extends PhysicalPip {
291 public PhysicalFpslicPip(int x, int y, int ox, int oy, String name, PhysicalNet driver, PhysicalNet[] driven, int q) {
292 this(x, y, ox, oy, name, driver, driven);
294 public PhysicalFpslicPip(int x, int y, int ox, int oy, String name, PhysicalNet driver, PhysicalNet[] driven) {
295 super(name, driver, driven);
305 public boolean prohibited() {
306 return Math.abs(x-badx) <= badr && Math.abs(y-bady) <= badr;
309 return x * CELLSEP + ox;
312 return ((height * CELLSEP) - (y * CELLSEP)) + oy;
314 public double getCost(PhysicalNet in, PhysicalNet out) {
315 if (prohibited()) return 100 * ((2*badr)-(Math.abs(badx-x) + Math.abs(bady-y)));
318 public double getDelay(PhysicalNet in, PhysicalNet out) {
319 if (prohibited()) return 10000 * defaultDelay;