updates that were lying around but never got checked in; includes reorg of gui
[slipway.git] / src / edu / berkeley / slipway / mpar / PhysicalFpslic.java
1 package edu.berkeley.slipway.mpar;
2 import com.atmel.fpslic.*;
3 import byucc.edif.tools.merge.*;
4 import byucc.edif.*;
5 import java.io.*;
6 import java.util.*;
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.*;
11
12 public class PhysicalFpslic extends PhysicalDevice {
13     public static int CELLSEP  = 40;
14     public static int PLANESEP = 3;
15
16     private final FpslicDevice fpslic;
17         
18     public final int width;
19     public final int height;
20     private final PhysicalNet[][][][] sectorWires;
21     private final PhysicalFpslicCell[][] cells;
22
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];
29     }
30
31     public PhysicalFpslic(final FpslicDevice fpslic, int width, int height) {
32         this.fpslic = fpslic;
33         this.width = width;
34         this.height = 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;
44                     }
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;
50                     }
51                 }
52
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++) {
56                     final int xc = x;
57                     final int yc = y;
58                     final int pc = p;
59                     new PhysicalFpslicPip(x,
60                                           y,
61                                           -1 * (4-p) * PLANESEP,
62                                           -1 * (0+p) * PLANESEP,
63                                           "xxx",
64                                           sectorWires[x-1][y][p][1],
65                                           new PhysicalNet[] { sectorWires[x][y][p][1] },
66                                           5) {
67                         public void set(boolean connected) {
68                             fpslic.cell(xc-1, yc).hwire(pc).drives(fpslic.cell(xc, yc).hwire(pc), connected);
69                         }
70                     };
71                     new PhysicalFpslicPip(x,
72                                           y,
73                                           -1 * (4-p) * PLANESEP,
74                                           -1 * (0+p) * PLANESEP,
75                                           "xxx",
76                                           sectorWires[x][y][p][1],
77                                           new PhysicalNet[] { sectorWires[x-1][y][p][1] },
78                                           5) {
79                         public void set(boolean connected) {
80                             fpslic.cell(xc, yc).hwire(pc).drives(fpslic.cell(xc-1, yc).hwire(pc), connected);
81                         }
82                     };
83                 }
84             }
85         }
86
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++) {
90                     final int xc = x;
91                     final int yc = y;
92                     final int pc = p;
93                     new PhysicalFpslicPip(x,
94                                           y,
95                                           -1 * (4-p) * PLANESEP,
96                                           -1 * (0+p) * PLANESEP,
97                                           "xxx",
98                                           sectorWires[x][y-1][p][0],
99                                           new PhysicalNet[] { sectorWires[x][y][p][0] },
100                                           5) {
101                         public void set(boolean connected) {
102                             fpslic.cell(xc, yc-1).vwire(pc).drives(fpslic.cell(xc, yc).vwire(pc), connected);
103                         }
104                     };
105                     new PhysicalFpslicPip(x,
106                                           y,
107                                           -1 * (4-p) * PLANESEP,
108                                           -1 * (0+p) * PLANESEP,
109                                           "xxx",
110                                           sectorWires[x][y][p][0],
111                                           new PhysicalNet[] { sectorWires[x][y-1][p][0] },
112                                           5) {
113                         public void set(boolean connected) {
114                             fpslic.cell(xc, yc).vwire(pc).drives(fpslic.cell(xc, yc-1).vwire(pc), connected);
115                         }
116                     };
117                 }
118             }
119         }
120
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);
125             }
126         for(int x=0; x<width; x++)
127             for(int y=0; y<height; y++)
128                 cells[x][y].link();
129     }
130
131     private PhysicalNet getSectorWire(int col, int row, int plane, boolean horizontal) {
132         return sectorWires[col][row][plane][horizontal ? 1 : 0];
133     }
134
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);
139     }
140
141     public class PhysicalFpslicCell extends PhysicalCell {
142         private int x;
143         private int y;
144         private int col;
145         private int row;
146         private PhysicalNet   outputNet;
147         private PhysicalNet   xin;
148         private PhysicalNet   yin;
149         private PhysicalNet[] local = new PhysicalNet[5];
150
151         public PhysicalCell randomCellWithin(Random rand, double percentOfDevice) {
152             int distance = (int)(percentOfDevice * Math.max(width, height));
153             if (distance < 4) distance = 4;
154             // FIXME ugly
155             while(true) {
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;
160             }
161         }
162         public void place(NetList.Node n) {
163             this.x = col;
164             this.y = row;
165             FpslicDevice.Cell cell = fpslic.cell(x,y);
166             cell.c(XLUT);
167             cell.b(false);
168             cell.f(false);
169             cell.xi(NW);
170             cell.yi(EAST);
171             //cell.xo(true);
172             //cell.yo(true);
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;
180         }
181
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");
188         }
189
190         public void setFunction(String type) {
191             FpslicDevice.Cell cell = cell();
192             cell.c(XLUT);
193             cell.xo(false);
194             cell.b(false);
195             cell.f(false);
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);
201         }
202
203         public void link() {
204             // FIXME wow, this is a horrendous hack!
205
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); }
210                 };
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); }
215                 };
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); }
220                 };
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); }
225                 };
226
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); }
231                 };
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); }
236                 };
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); }
241                 };
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); }
246                 };
247
248         }
249
250         private PhysicalFpslicCell(int col, int row) {
251             this.row = row;
252             this.col = col;
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++) {
257
258                 // plane 3 is reserved for debugging
259                 if (j==3) continue;
260
261                 final int i = j;
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); }
267                 };
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); }
272                 };
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); }
276                 };
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); }
280                 };
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); }
284                 };
285             }
286         }
287         public  String toString() { return "cell@("+col+","+row+")"; }
288     }
289
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);
293         }
294         public PhysicalFpslicPip(int x, int y, int ox, int oy, String name, PhysicalNet driver, PhysicalNet[] driven) {
295             super(name, driver, driven);
296             this.x = x;
297             this.y = y;
298             this.ox = ox;
299             this.oy = oy;
300         }
301         private int ox;
302         private int oy;
303         private int x;
304         private int y;
305         public boolean prohibited() {
306             return Math.abs(x-badx) <= badr && Math.abs(y-bady) <= badr;
307         }
308         public int getX() {
309             return x * CELLSEP + ox;
310         }
311         public int getY() {
312             return ((height * CELLSEP) - (y * CELLSEP)) + oy;
313         }
314         public double        getCost(PhysicalNet in, PhysicalNet out) {
315             if (prohibited()) return 100 * ((2*badr)-(Math.abs(badx-x) + Math.abs(bady-y)));
316             return defaultCost;
317         }
318         public double        getDelay(PhysicalNet in, PhysicalNet out) {
319             if (prohibited()) return 10000 * defaultDelay;
320             return defaultDelay;
321         }
322     }
323
324     static int badx = 5;
325     static int bady = 5;
326     static int badr = 3;
327 }