b7901063c354ec87de9ebb1fdee9b09cbca85795
[slipway.git] / src / edu / berkeley / slipway / AsyncPaperDemo.java
1 package edu.berkeley.slipway;
2
3 import edu.berkeley.slipway.*;
4 import com.atmel.fpslic.*;
5 import static com.atmel.fpslic.FpslicConstants.*;
6 import static com.atmel.fpslic.FpslicUtil.*;
7 import edu.berkeley.slipway.gui.*;
8 import java.awt.*;
9 import java.awt.event.*;
10 import java.awt.color.*;
11 import org.ibex.util.*;
12 import java.io.*;
13 import java.util.*;
14 import gnu.io.*;
15
16 public class AsyncPaperDemo {
17
18     FtdiBoard fpslic;
19
20     public AsyncPaperDemo() throws Exception {
21         fpslic = new FtdiBoard();
22     }
23
24     public void main() throws Exception {
25
26         turnOnLeds();
27         setupScanCell();
28
29         Fpslic.Cell root = fpslic.cell(2, 2);
30             
31         root.yo(root.north());
32         root.ylut(~LUT_SELF);
33         root.c(YLUT);
34         root = root.north();
35
36         root.yo(root.east());
37         root.ylut(~LUT_SELF);
38         root.c(YLUT);
39         root = root.east();
40
41         root.yo(root.south());
42         root.ylut(~LUT_SELF);
43         root.c(YLUT);
44         root = root.south();
45
46         root.yo(root.west());
47         root.c(YLUT);
48         root = root.west();
49
50         root = fpslic.cell(3, 7);
51         root.h(1, true);
52         root.h(2, true);
53         root.wi(L1);
54         root.zi(L2);
55         root.c(YLUT);
56         root.t(TMUX_W);
57         root.b(false);
58         root.f(false);
59         root.ylut(LUT_SELF);
60         root.yi(EAST);
61         root.xlut(LUT_Z);
62         root.xo(false);
63
64         root.west().out(2, true);
65         root.west().h(2, true);
66         root.west().c(YLUT);
67
68         root.west().west().out(1, true);
69         root.west().west().h(1, true);
70         root.west().west().c(YLUT);
71
72         root.ne().xo(root);
73
74         createPipeline(fpslic.cell(20, 22), true, 40, true);
75
76         for(int i=1; i<22; i+=2)
77             divider(fpslic.cell(21, i));
78         fpslic.cell(23,0).yo(fpslic.cell(22,0));
79         fpslic.cell(21,22).yo(fpslic.cell(20,22));
80         fpslic.cell(21,22).xo(fpslic.cell(20,22));
81
82         runGui(24, 24);
83
84         Thread.sleep(5000);
85
86         for(int i=0; i<20; i++) test(i);
87         synchronized(Demo.class) { Demo.class.wait(); }
88     }
89
90     public void test(int count) throws Exception {
91         flush();
92         fill(count);
93
94         fpslic.flush();
95
96         fpslic.readCount();
97         long now = System.currentTimeMillis();
98         Thread.sleep(4000);
99         int save1y = fpslic.cell(19,22).ylut();
100         int save1x = fpslic.cell(19,22).xlut();
101         fpslic.cell(19,22).ylut(0xff);
102         fpslic.cell(19,22).xlut(0xff);
103         fpslic.flush();
104         long then = System.currentTimeMillis();
105         fpslic.cell(19,22).ylut(save1y);
106         fpslic.cell(19,22).xlut(save1x);
107
108         int tokens = fpslic.readCount();
109         System.out.println(count + ", " + (tokens*1000)/(then-now));
110     }
111
112     private void flush() {
113         int save1y = fpslic.cell(19,22).ylut();
114         int save1x = fpslic.cell(19,22).xlut();
115         int save2y = fpslic.cell(20,22).ylut();
116         int save2x = fpslic.cell(20,22).xlut();
117         fpslic.cell(19,22).ylut(0x00);
118         fpslic.cell(19,22).xlut(0x00);
119         for(int i=0; i<800; i++) {
120             fpslic.cell(20,22).ylut(0xff);
121             fpslic.cell(20,22).xlut(0xff);
122             fpslic.cell(20,22).ylut(0x00);
123             fpslic.cell(20,22).xlut(0x00);
124         }
125         fpslic.flush();
126         fpslic.cell(20,22).ylut(save2y);
127         fpslic.cell(20,22).xlut(save2x);
128         fpslic.cell(19,22).ylut(save2y);
129         fpslic.cell(19,22).xlut(save2x);
130         fpslic.flush();
131         fpslic.cell(19,22).ylut(save1y);
132         fpslic.cell(19,22).xlut(save1x);
133         fpslic.flush();
134         fpslic.readCount();
135         try { Thread.sleep(100); } catch (Exception e) { }
136         int rc = fpslic.readCount();
137         if (rc!=0)
138             throw new Error("flush() failed => " + rc);
139     }
140
141     private void fill(int count) {
142         int save1y = fpslic.cell(19,22).ylut();
143         int save1x = fpslic.cell(19,22).xlut();
144         int save2y = fpslic.cell(20,22).ylut();
145         int save2x = fpslic.cell(20,22).xlut();
146         fpslic.cell(19,22).ylut(0xff);
147         fpslic.cell(19,22).xlut(0xff);
148         fpslic.cell(20,22).ylut(0xff);
149         fpslic.cell(20,22).xlut(0xff);
150         boolean yes = true;
151         for(int i=0; i<count; i++) {
152             if (yes) {
153                 fpslic.cell(19,22).ylut(0xff);
154                 fpslic.cell(19,22).xlut(0xff);
155             } else {
156                 fpslic.cell(19,22).ylut(0x00);
157                 fpslic.cell(19,22).xlut(0x00);
158             }
159             yes = !yes;
160         }
161         fpslic.cell(19,22).ylut(save1y);
162         fpslic.cell(19,22).xlut(save1x);
163         fpslic.cell(20,22).ylut(save2y);
164         fpslic.cell(20,22).xlut(save2x);
165         fpslic.flush();
166     }
167
168     private Fpslic.Cell pipe(Fpslic.Cell c, Fpslic.Cell prev, int[] dirs) {
169         for(int i=0; i<dirs.length; i++) {
170             Fpslic.Cell next = c.dir(dirs[i]);
171             micropipelineStage(c, prev, next);
172             prev = c;
173             c = next;
174         }
175         return c;
176     }
177
178     private void createPipeline(Fpslic.Cell c, boolean downward, int length, boolean start) {
179         length -= 8;
180         if (downward) {
181             if (c.row < 6) {
182                 c = pipe(c, c.north(), new int[] { SW, EAST, SW, WEST, NW, NORTH });
183                 c = c.se();
184                 c = pipe(c, c.north(), new int[] { NE, NORTH });
185                 c = c.sw().west();
186                 downward = false;
187             } else {
188                 c = micropipelineStage(c, start ? c.west() : c.north(), c.sw());
189                 c = micropipelineStage(c, c.ne(),    c.south());
190                 c = micropipelineStage(c, c.north(), c.se());
191                 c = micropipelineStage(c, c.nw(),    c.south());
192                 c = c.nw();
193                 c = micropipelineStage(c, c.south(), c.ne());
194                 c = micropipelineStage(c, c.sw(),    c.north());
195                 c = micropipelineStage(c, c.south(), c.nw());
196                 micropipelineStage(c, c.se(),    start ? c.east() : c.north());
197                 c = c.south().south().south().south().east();
198             }
199         } else {
200             if (c.row > c.fpslic().getHeight()-7) {
201                 c = pipe(c, c.south(), new int[] { NW, SOUTH });
202                 c = c.nw();
203                 c = pipe(c, c.south(), new int[] { NE, EAST, SE, WEST, SE, SOUTH });
204                 c = c.nw().west();
205                 downward = true;
206             } else {
207                 Fpslic.Cell ret = c = pipe(c, c.south(), new int[] { NE, NORTH, NW, NORTH });
208                 c = c.se();
209                 c = pipe(c, c.north(), new int[] { SW, SOUTH, SE, SOUTH });
210                 c = ret;
211             }
212         }
213         if (length >= 8) createPipeline(c, downward, length, false);
214         else {
215             if (downward) {
216                 c = micropipelineStage(c, c.north(), c.sw());
217                 c = micropipelineStage(c, c.ne(), c.west());
218                 c = micropipelineStage(c, c.east(), c.ne());
219                 c = micropipelineStage(c, c.sw(), c.north());
220             } else {
221                 c = pipe(c, c.south(), new int[] { NW, EAST, SE, SOUTH });
222             }
223         }
224     }
225
226     /*
227     private void createPipeline(Fpslic.Cell c, boolean downward, int length) {
228         length -= 2;
229         if (downward) {
230             if (c.row == 0) {
231                 c = micropipelineStage(c, c.ne(),   c.west());
232                 c = micropipelineStage(c, c.east(), c.nw());
233                 if (length > 0) createPipeline(c, false, length);
234             } else {
235                 c = micropipelineStage(c, c.ne(),   c.east());
236                 c = micropipelineStage(c, c.west(), c.sw());
237                 if (length > 0) createPipeline(c, true, length);
238             }
239         } else {
240             if (c.row == c.fpslic().getHeight()-1) {
241                 c = micropipelineStage(c, c.se(),   c.west());
242                 c = micropipelineStage(c, c.east(), c.sw());
243                 if (length > 0) createPipeline(c, true, length);
244             } else {
245                 c = micropipelineStage(c, c.se(),   c.east());
246                 c = micropipelineStage(c, c.west(), c.nw());
247                 if (length > 0) createPipeline(c, false, length);
248             }
249         }
250     }
251     */
252
253     private Fpslic.Cell micropipelineStage(Fpslic.Cell c, Fpslic.Cell prev, Fpslic.Cell next) {
254         switch(c.dir(next)) {
255             case NORTH: case SOUTH: case EAST: case WEST:
256                 switch (c.dir(prev)) {
257                     case NORTH: case SOUTH: case EAST: case WEST: throw new Error("cannot have prev&next both use y");
258                 }
259                 c.ylut((LUT_SELF & ~LUT_OTHER) | (LUT_Z & ~LUT_OTHER) | (LUT_Z & LUT_SELF & LUT_OTHER));
260                 c.xlut(LUT_Z);
261                 c.c(YLUT);
262                 c.yi(next);
263                 c.xi(prev);
264                 break;
265             case NW: case SE: case SW: case NE:
266                 switch (c.dir(prev)) {
267                     case NW: case SE: case SW: case NE: throw new Error("cannot have prev&next both use x");
268                 }
269                 c.xlut((LUT_SELF & ~LUT_OTHER) | (LUT_Z & ~LUT_OTHER) | (LUT_Z & LUT_SELF & LUT_OTHER));
270                 c.ylut(LUT_Z);
271                 c.c(XLUT);
272                 c.xi(next);
273                 c.yi(prev);
274                 break;
275             default: throw new Error();
276         }
277         c.b(false);
278         c.f(false);
279         c.t(TMUX_FB);
280         c.yo(false);
281         c.xo(false);
282         return next;
283     }
284
285     private void turnOnLeds() {
286         for(int i=0; i<24; i++) {
287             fpslic.iob_bot(i, true).enableOutput(NORTH);
288             fpslic.iob_bot(i, false).enableOutput(NW);
289             fpslic.cell(i, 0).xlut(0xff);
290             fpslic.cell(i, 0).ylut(0xff);
291         }
292     }
293
294     private void setupScanCell() {
295         fpslic.cell(23,15).h(3, true);
296         fpslic.cell(23,15).yi(L3);
297         fpslic.cell(23,15).ylut(0xAA);
298         fpslic.iob_right(15, true).enableOutput(WEST);
299
300         fpslic.cell(23,0).ylut(0x00);
301         fpslic.iob_right(0, true).enableOutput(WEST);
302     }
303
304     private void divider(Fpslic.Cell c) {
305         Fpslic.Cell detect1 = c;
306         Fpslic.Cell detect2 = c.east();
307
308         detect1.yi(NORTH);
309         detect1.ylut(LUT_SELF);
310         detect1.xlut(LUT_OTHER & (~LUT_Z));
311         detect1.c(YLUT);
312         detect1.t(TMUX_FB);
313         detect1.f(false);
314         detect1.b(false);
315
316         detect2.xi(NW);
317         detect2.ylut(LUT_OTHER);
318         detect2.xlut((~LUT_SELF) & LUT_Z);
319         detect2.c(YLUT);
320         detect2.t(TMUX_FB);
321         detect2.f(false);
322         detect2.b(false);
323
324         detect1.south().yi(EAST);
325         detect1.south().xi(NE);
326         detect1.south().c(YLUT);
327         detect1.south().t(TMUX_FB);
328         detect1.south().f(false);
329         detect1.south().b(false);
330         detect1.south().ylut( (LUT_OTHER    & (~LUT_SELF)) |
331                               ((~LUT_OTHER) &   LUT_Z)
332                               );
333         detect1.south().xlut( (LUT_SELF    & (~LUT_OTHER)) |
334                               ((~LUT_SELF) &   LUT_Z)
335                               );
336
337         detect2.south().yi(WEST);
338         detect2.south().xi(NW);
339         detect2.south().c(YLUT);
340         detect2.south().t(TMUX_FB);
341         detect2.south().f(false);
342         detect2.south().b(false);
343         detect2.south().ylut( (LUT_OTHER    & (LUT_SELF)) |
344                               ((~LUT_OTHER) &   LUT_Z)
345                               );
346         detect2.south().xlut( (LUT_SELF    & (~LUT_OTHER)) |
347                               ((~LUT_SELF) &   LUT_Z)
348                               );
349
350     }
351
352     private void runGui(int width, int height) throws Exception {
353         Gui vis = new Gui(fpslic, fpslic, width, height);
354         Frame fr = new Frame();
355         fr.addKeyListener(vis);
356         fr.setLayout(new BorderLayout());
357         fr.add(vis, BorderLayout.CENTER);
358         fr.pack();
359         fr.setSize(900, 900);
360         vis.repaint();
361         fr.repaint();
362         fr.show();
363     }
364 }
365
366