748145f9beff5e21100dcd4d6fd8d6baaa9a10fc
[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     private final Fpslic fpslic;
14         
15     public final int width;
16     public final int height;
17     private final PhysicalNet[][][][] sectorWires;
18     private final PhysicalFpslicCell[][] cells;
19
20     public PhysicalCell getCell(int col, int row) {
21         if (col<0) return null;
22         if (row<0) return null;
23         if (col>=width) return null;
24         if (row>=height) return null;
25         return cells[col][row];
26     }
27
28     public PhysicalFpslic(final Fpslic fpslic, int width, int height) {
29         this.fpslic = fpslic;
30         this.width = width;
31         this.height = height;
32         sectorWires = new PhysicalNet[width][height][5][2];
33         for(int x=0; x<width; x+=4)
34             for(int y=0; y<height; y+=4)
35                 for(int p=0; p<5; p++) {
36                     for(int xc=x; xc<x+4; xc++) {
37                         PhysicalNet vwire = new PhysicalNet("("+xc+","+y+"-"+(y+3)+")");
38                         for(int yc=y; yc<y+4; yc++)
39                             sectorWires[xc][yc][p][0] = vwire;
40                     }
41                     for(int yc=y; yc<y+4; yc++) {
42                         PhysicalNet hwire = new PhysicalNet("("+x+"-"+(x+3)+","+yc+")");
43                         for(int xc=x; xc<x+4; xc++)
44                             sectorWires[xc][yc][p][1] = hwire;
45                     }
46                 }
47
48         for(int x=4; x<width; x+=4) {
49             for(int y=0; y<height; y++) {
50                 for(int p=0; p<5; p++) {
51                     final int xc = x;
52                     final int yc = y;
53                     final int pc = p;
54                     new PhysicalPip("xxx",
55                                     sectorWires[x-1][y][p][1],
56                                     new PhysicalNet[] { sectorWires[x][y][p][1] },
57                                     5) {
58                         public void set(boolean connected) {
59                             fpslic.cell(xc-1, yc).hwire(pc).drives(fpslic.cell(xc, yc).hwire(pc), connected);
60                         }
61                     };
62                     new PhysicalPip("xxx",
63                                     sectorWires[x][y][p][1],
64                                     new PhysicalNet[] { sectorWires[x-1][y][p][1] },
65                                     5) {
66                         public void set(boolean connected) {
67                             fpslic.cell(xc, yc).hwire(pc).drives(fpslic.cell(xc-1, yc).hwire(pc), connected);
68                         }
69                     };
70                 }
71             }
72         }
73
74         for(int x=0; x<width; x++) {
75             for(int y=4; y<height; y+=4) {
76                 for(int p=0; p<5; p++) {
77                     final int xc = x;
78                     final int yc = y;
79                     final int pc = p;
80                     new PhysicalPip("xxx",
81                                     sectorWires[x][y-1][p][0],
82                                     new PhysicalNet[] { sectorWires[x][y][p][0] },
83                                     5) {
84                         public void set(boolean connected) {
85                             fpslic.cell(xc, yc-1).vwire(pc).drives(fpslic.cell(xc, yc).vwire(pc), connected);
86                         }
87                     };
88                     new PhysicalPip("xxx",
89                                     sectorWires[x][y][p][0],
90                                     new PhysicalNet[] { sectorWires[x][y-1][p][0] },
91                                     5) {
92                         public void set(boolean connected) {
93                             fpslic.cell(xc, yc).vwire(pc).drives(fpslic.cell(xc, yc-1).vwire(pc), connected);
94                         }
95                     };
96                 }
97             }
98         }
99
100         cells = new PhysicalFpslicCell[width][height];
101         for(int x=0; x<width; x++)
102             for(int y=0; y<height; y++) {
103                 cells[x][y] = new PhysicalFpslicCell(x, y);
104             }
105         for(int x=0; x<width; x++)
106             for(int y=0; y<height; y++)
107                 cells[x][y].link();
108     }
109
110     private PhysicalNet getSectorWire(int col, int row, int plane, boolean horizontal) {
111         return sectorWires[col][row][plane][horizontal ? 1 : 0];
112     }
113
114     public class PhysicalFpslicCell extends PhysicalCell {
115         private int col;
116         private int row;
117         private PhysicalNet   outputNet;
118         private PhysicalNet   xin;
119         private PhysicalNet   yin;
120         private PhysicalNet[] local = new PhysicalNet[5];
121
122         public void place(NetList.Node n) {
123             int x = col;
124             int y = row;
125             n.x = x;
126             n.y = y;
127             n.physicalCell = this;
128             Fpslic.Cell cell = fpslic.cell(x,y);
129             cell.c(XLUT);
130             cell.b(false);
131             cell.f(false);
132             cell.xi(NW);
133             cell.yi(EAST);
134             String type = n.getType();
135             if      (type.equals("and2"))    cell.xlut(LUT_SELF & LUT_OTHER);
136             else if (type.equals("or2"))     cell.xlut(LUT_SELF | LUT_OTHER);
137             else if (type.equals("xor2"))    cell.xlut(LUT_SELF ^ LUT_OTHER);
138             else if (type.equals("buf"))     cell.xlut(LUT_SELF);
139             else if (type.equals("inv"))     cell.xlut(~LUT_SELF);
140             else if (type.equals("cell0"))   return;
141         }
142
143         private Fpslic.Cell cell() { return fpslic.cell(col, row); }
144         public PhysicalNet getNet(String name) {
145             if (name.equals("out")) return outputNet;
146             if (name.equals("xi"))  return xin;
147             if (name.equals("yi"))  return yin;
148             throw new RuntimeException("unknown");
149         }
150
151         public void setFunction(String type) {
152             Fpslic.Cell cell = cell();
153             cell.c(XLUT);
154             cell.xo(false);
155             cell.b(false);
156             cell.f(false);
157             if      (type.equals("and2"))    cell.xlut(LUT_SELF & LUT_OTHER);
158             else if (type.equals("or2"))     cell.xlut(LUT_SELF | LUT_OTHER);
159             else if (type.equals("xor2"))    cell.xlut(LUT_SELF ^ LUT_OTHER);
160             else if (type.equals("buf"))     cell.xlut(LUT_SELF);
161             else if (type.equals("inv"))     cell.xlut(~LUT_SELF);
162         }
163
164         public void link() {
165             // FIXME wow, this is a horrendous hack!
166             if (getCell(col-1, row+1) != null)
167                 new PhysicalPip(this+".xiNW", getCell(col-1, row+1).getNet("out"), new PhysicalNet[] { xin }, 5) {
168                     public void set(boolean connected) { cell().xi(connected ? NW : NONE); }
169                 };
170             if (getCell(col-1, row-1) != null)
171                 new PhysicalPip(this+".xiSW", getCell(col-1, row-1).getNet("out"), new PhysicalNet[] { xin }, 5) {
172                     public void set(boolean connected) { cell().xi(connected ? SW : NONE); }
173                 };
174             if (getCell(col+1, row+1) != null)
175                 new PhysicalPip(this+".xiNE", getCell(col+1, row+1).getNet("out"), new PhysicalNet[] { xin }, 5) {
176                     public void set(boolean connected) { cell().xi(connected ? NE : NONE); }
177                 };
178             if (getCell(col+1, row-1) != null)
179                 new PhysicalPip(this+".xiSE", getCell(col+1, row-1).getNet("out"), new PhysicalNet[] { xin }, 5) {
180                     public void set(boolean connected) { cell().xi(connected ? SE : NONE); }
181                 };
182         }
183
184         private PhysicalFpslicCell(int col, int row) {
185             this.row = row;
186             this.col = col;
187             outputNet = new PhysicalNet(this.toString()+".out");
188             xin       = new PhysicalNet(this.toString()+".xi");
189             yin       = new PhysicalNet(this.toString()+".yi");
190             for(int j=0; j<5; j++) {
191
192                 // plane 3 is reserved for debugging
193                 if (j==3) continue;
194
195                 final int i = j;
196                 local[i] = new PhysicalNet(this.toString()+".L"+i);
197                 new PhysicalPip(this+".h"+i,  null,      new PhysicalNet[] { local[i], getSectorWire(col, row, i, true) }) {
198                     public void set(boolean connected) { cell().h(i, connected); }
199                 };
200                 new PhysicalPip(this+".v"+i,  null,      new PhysicalNet[] { local[i], getSectorWire(col, row, i, false) }) {
201                     public void set(boolean connected) { cell().v(i, connected); }
202                 };
203                 new PhysicalPip(this+".xi"+i, local[i],  new PhysicalNet[] { xin }) {
204                     public void set(boolean connected) { cell().xi(connected ? i : NONE); }
205                 };
206                 new PhysicalPip(this+".yi"+i, local[i],  new PhysicalNet[] { yin }) {
207                     public void set(boolean connected) { cell().yi(connected ? i : NONE); }
208                 };
209                 new PhysicalPip(this+".o"+i,  outputNet, new PhysicalNet[] { local[i] }) {
210                     public void set(boolean connected) { cell().out(i, connected); }
211                 };
212             }
213         }
214         public  String toString() { return "cell@("+col+","+row+")"; }
215     }
216
217 }