37f940f500164711ac57753ca962fe3156732927
[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     Fpslic.Cell start;
25     public void main(String[] s) throws Exception {
26
27         turnOnLeds();
28         setupScanCell();
29
30         runGui(24, 24);
31
32         for(int i=0; i<255; i++)
33             fpslic.readCount();
34
35         //System.in.read();
36         for(int i=90; i<400; i+=2) {
37             go(i);
38         }
39         System.out.println("done");
40
41     }
42
43     public void go(int size) throws Exception {
44         start = fpslic.cell(20, 21);
45         int rsize = size-createPipeline(start, true, size, false)+2;
46         System.out.println("actual size => " + rsize);
47         pipe(start.west().north(), start.west(), new int[] { NE, EAST, SW, SOUTH });
48
49         for(int i=1; i<22; i+=2)
50             divider(fpslic.cell(21, i));
51         fpslic.cell(23,0).yo(fpslic.cell(22,0));
52         fpslic.cell(21,22).yo(fpslic.cell(20,22));
53         fpslic.cell(21,22).xo(fpslic.cell(20,22));
54
55         reconfigTopLeft();
56         reconfigTopRight();
57         fpslic.flush();
58
59         Thread.sleep(2000);
60
61         String sizes = rsize+"";
62         while(sizes.length()<3) sizes = "0"+sizes;
63         String fname = "data/size"+sizes+".csv";
64         if (!new File(fname).exists()) {
65             PrintWriter outfile = new PrintWriter(new OutputStreamWriter(new FileOutputStream(fname)));
66             //for(int i=0; i<rsize/2+1; i++) test(i, rsize, outfile);
67             for(int i=rsize/2; i>=0; i--) test(i, rsize, outfile);
68             outfile.flush();
69             outfile.close();
70         }
71         System.out.println("done.");
72     }
73
74     public void test(int count, int size, PrintWriter outfile) throws Exception {
75         fpslic.flush();
76         drain(count);
77         fpslic.flush();
78         fill(count, size);
79
80         fpslic.flush();
81
82         fpslic.readCount();
83         long now = System.currentTimeMillis();
84         Thread.sleep(2000);
85         topLeft().ylut(0xff);
86         topLeft().xlut(0xff);
87         fpslic.flush();
88         long then = System.currentTimeMillis();
89
90         int tokens = fpslic.readCount();
91         double elapsed = (double)((FtdiBoard)fpslic).timer;
92         
93         double occupancy = ((double)(2*count))/((double)size);
94
95         //double elapsed = (then-now);
96         double result = (tokens*1000)/elapsed;
97
98         // eleven dividers...
99         //result *= 2*2*2*2*2*2*2*2*2*2*2;
100
101         // ...and the interrupt pin counts *pairs* of transitions
102         //result *= 2;
103
104         // result is transitions/sec => 633mcell/sec velocity! =)
105         outfile.println(occupancy + ", " + result);
106         System.out.println((2*count)+"/"+size+"  "+occupancy + ", " + result + " @ " + elapsed);
107         outfile.flush();
108     }
109
110     private void drain(int size) {
111         while(true){
112         topLeft().xlut(0x00);
113         for(int i=0; i<size*4; i++) {
114             topLeft().ylut(0xff);
115             fpslic.flush();
116             topLeft().ylut(0x00);
117             fpslic.flush();
118         }
119
120         fpslic.flush();
121         fpslic.readCount();
122         fpslic.readCount();
123         try { Thread.sleep(100); } catch (Exception e) { }
124         int rc = fpslic.readCount();
125         if (rc!=0) {
126             System.err.println("flush() failed REALLY BADLY => " + rc);
127             //try { System.in.read(); }  catch (Exception _) { }
128             continue;
129         }
130
131         reconfigTopLeft();
132
133         fpslic.flush();
134         fpslic.readCount();
135         fpslic.readCount();
136         try { Thread.sleep(100); } catch (Exception e) { }
137         rc = fpslic.readCount();
138         if (rc!=0) {
139             System.err.println("flush() failed => " + rc);
140             //try { System.in.read(); }  catch (Exception _) { }
141             continue;
142         }
143         break;
144         }
145     }
146
147     private void fill(int count, int size) {
148         //topLeft().ylut((count>0 && count<size/2-1) ? 0xff : 0x00);
149         if (count>0)
150             topLeft().ylut(0x00);
151         boolean yes = true;
152         if (count==1) {
153             topLeft().xlut(0x00);
154             yes = true;
155         } else {
156             for(int i=0; i<count-1; i++) {
157                 if (yes) {
158                     topLeft().xlut(0xff);
159                 } else {
160                     topLeft().xlut(0x00);
161                 }
162                 fpslic.flush();
163                 yes = !yes;
164             //System.out.println("fill => " + yes);
165             //try { Thread.sleep(500); } catch (Exception _) { }
166             }
167         }
168         //System.out.println("done filling.");
169         //try { Thread.sleep(2000); } catch (Exception _) { }
170
171         //System.out.println("reconfigured.");
172         //try { System.in.read(); }  catch (Exception _) { }
173
174
175         if (count>0 && count!=size/2-1) {
176             reconfigTopLeftPreserve(yes);
177         } else if (count>0) {
178             topLeft().xlut(0xff);
179             fpslic.flush();
180             topLeft().ylut(0xff);
181             reconfigTopLeftPreserve(false);
182         } 
183
184         //System.out.println("running.");
185         //try { System.in.read(); }  catch (Exception _) { }
186
187         //try { Thread.sleep(2000); } catch (Exception _) { }
188     }
189
190     private Fpslic.Cell topLeft() { return start.north().north(); }
191     private Fpslic.Cell topRight() { return start.north().ne(); }
192     private void reconfigTopLeft() {
193         Fpslic.Cell c = topLeft();
194                 c.c(YLUT);
195                 c.ylut(0x00);
196                 c.xlut(0x00);
197                 c.wi(L0);
198                 c.t(TMUX_W_AND_FB);
199                 c.ylut((LUT_SELF & ~LUT_OTHER) |
200                        (LUT_Z & ~LUT_OTHER) |
201                        (LUT_Z & LUT_SELF));
202             fpslic.flush();
203                 c.xlut(LUT_Z);
204             fpslic.flush();
205                 c.wi(NONE);
206             fpslic.flush();
207     }
208     private void reconfigTopLeftNice() {
209         Fpslic.Cell c = topLeft();
210         c.c(YLUT);
211         c.xlut(LUT_Z);
212         fpslic.flush();
213         c.ylut((LUT_SELF & ~LUT_OTHER) |
214                (LUT_Z & ~LUT_OTHER) |
215                (LUT_Z & LUT_SELF));
216         fpslic.flush();
217     }
218     private void reconfigTopLeftPreserve(boolean on) {
219         Fpslic.Cell c = topLeft();
220         fpslic.flush();
221         if (on) c.ylut(0x00);
222         //else    c.ylut(0xff);
223         //fpslic.flush();
224         c.xlut(LUT_Z);
225         fpslic.flush();
226         c.ylut((LUT_SELF & ~LUT_OTHER) |
227                (LUT_Z & ~LUT_OTHER) |
228                (LUT_Z & LUT_SELF));
229         fpslic.flush();
230     }
231     private void reconfigTopRight() { micropipelineStage(topRight(), topRight().west(), topRight().sw()); }
232
233     private Fpslic.Cell pipe(Fpslic.Cell c, Fpslic.Cell prev, int[] dirs) {
234         for(int i=0; i<dirs.length; i++) {
235             Fpslic.Cell next = c.dir(dirs[i]);
236             micropipelineStage(c, prev, next);
237             prev = c;
238             c = next;
239         }
240         return c;
241     }
242
243     private int createPipeline(Fpslic.Cell c, boolean downward, int length, boolean start) {
244         boolean stop = false;
245         do {
246         if (downward) {
247             if (c.row < 6) {
248                 if (length < 10+4) { stop = true; break; }
249                 length -= 10;
250                 c = pipe(c, c.north(), new int[] { SW, EAST, SW, WEST, NW, NORTH });
251                 c = c.se();
252                 c = pipe(c, c.north(), new int[] { NE, NORTH });
253                 c = c.sw().west();
254                 downward = false;
255             } else {
256                 if (length < 8+4) { stop = true; break; }
257                 length -= 8;
258                 c = micropipelineStage(c, c.north(), c.sw());
259                 c = micropipelineStage(c, c.ne(),    c.south());
260                 c = micropipelineStage(c, c.north(), c.se());
261                 c = micropipelineStage(c, c.nw(),    c.south());
262                 c = c.nw();
263                 c = micropipelineStage(c, c.south(), c.ne());
264                 c = micropipelineStage(c, c.sw(),    c.north());
265                 c = micropipelineStage(c, c.south(), c.nw());
266                 micropipelineStage(c, c.se(),    c.north());
267                 c = c.south().south().south().south().east();
268             }
269         } else {
270             if (c.row > c.fpslic().getHeight()-7) {
271                 if (length < 10+4) { stop = true; break; }
272                 length -= 10;
273                 c = pipe(c, c.south(), new int[] { NW, SOUTH });
274                 c = c.nw();
275                 c = pipe(c, c.south(), new int[] { NE, EAST, SE, WEST, SE, SOUTH });
276                 c = c.nw().west();
277                 downward = true;
278             } else {
279                 if (length < 8+4) { stop = true; break; }
280                 length -= 8;
281                 Fpslic.Cell ret = c = pipe(c, c.south(), new int[] { NE, NORTH, NW, NORTH });
282                 c = c.se();
283                 c = pipe(c, c.north(), new int[] { SW, SOUTH, SE, SOUTH });
284                 c = ret;
285             }
286         }
287         } while(false);
288         if (stop) {
289             length -= 4;
290             if (downward) {
291                 c = micropipelineStage(c, c.north(), c.sw());
292                 c = micropipelineStage(c, c.ne(), c.west());
293                 c = micropipelineStage(c, c.east(), c.ne());
294                 c = micropipelineStage(c, c.sw(), c.north());
295             } else {
296                 c = pipe(c, c.south(), new int[] { NW, EAST, SE, SOUTH });
297             }
298             return length;
299         } else {
300             return createPipeline(c, downward, length, false);
301         }
302     }
303
304     /*
305     private void createPipeline(Fpslic.Cell c, boolean downward, int length) {
306         length -= 2;
307         if (downward) {
308             if (c.row == 0) {
309                 c = micropipelineStage(c, c.ne(),   c.west());
310                 c = micropipelineStage(c, c.east(), c.nw());
311                 if (length > 0) createPipeline(c, false, length);
312             } else {
313                 c = micropipelineStage(c, c.ne(),   c.east());
314                 c = micropipelineStage(c, c.west(), c.sw());
315                 if (length > 0) createPipeline(c, true, length);
316             }
317         } else {
318             if (c.row == c.fpslic().getHeight()-1) {
319                 c = micropipelineStage(c, c.se(),   c.west());
320                 c = micropipelineStage(c, c.east(), c.sw());
321                 if (length > 0) createPipeline(c, true, length);
322             } else {
323                 c = micropipelineStage(c, c.se(),   c.east());
324                 c = micropipelineStage(c, c.west(), c.nw());
325                 if (length > 0) createPipeline(c, false, length);
326             }
327         }
328     }
329     */
330
331     private Fpslic.Cell micropipelineStage(Fpslic.Cell c, Fpslic.Cell prev, Fpslic.Cell next) {
332         return micropipelineStage(c, prev, next, true);
333     }
334     private Fpslic.Cell micropipelineStage(Fpslic.Cell c, Fpslic.Cell prev, Fpslic.Cell next, boolean configDir) {
335         c.b(false);
336         c.f(false);
337         c.yo(false);
338         c.xo(false);
339         switch(c.dir(next)) {
340             case NORTH: case SOUTH: case EAST: case WEST:
341                 switch (c.dir(prev)) {
342                     case NORTH: case SOUTH: case EAST: case WEST: throw new Error("cannot have prev&next both use y");
343                 }
344                 if (configDir) {
345                     c.yi(next);
346                     c.xi(prev);
347                 }
348
349                 c.c(YLUT);
350                 c.ylut(0x00);
351                 c.xlut(0x00);
352                 c.wi(L0);
353                 c.t(TMUX_W_AND_FB);
354                 c.ylut((LUT_SELF & ~LUT_OTHER) |
355                        (LUT_Z & ~LUT_OTHER) |
356                        (LUT_Z & LUT_SELF));
357                 c.xlut(LUT_Z);
358             fpslic.flush();
359                 c.wi(NONE);
360             fpslic.flush();
361                 break;
362             case NW: case SE: case SW: case NE:
363                 switch (c.dir(prev)) {
364                     case NW: case SE: case SW: case NE: throw new Error("cannot have prev&next both use x");
365                 }
366                 if (configDir) {
367                     c.xi(next);
368                     c.yi(prev);
369                 }
370
371                 c.c(XLUT);
372                 c.xlut(0x00);
373                 c.ylut(0x00);
374                 c.wi(L0);
375                 c.t(TMUX_W_AND_FB);
376                 c.xlut((LUT_SELF & ~LUT_OTHER) |
377                        (LUT_Z & ~LUT_OTHER) |
378                        (LUT_Z & LUT_SELF));
379                 c.ylut(LUT_Z);
380             fpslic.flush();
381                 c.wi(NONE);
382             fpslic.flush();
383                 break;
384             default: throw new Error();
385         }
386         //c.t(TMUX_FB);
387         return next;
388     }
389
390     private void turnOnLeds() {
391         for(int i=0; i<24; i++) {
392             //fpslic.iob_bot(i, true).enableOutput(NORTH);
393             //fpslic.iob_bot(i, false).enableOutput(NW);
394             fpslic.cell(i, 0).xlut(0xff);
395             fpslic.cell(i, 0).ylut(0xff);
396         }
397     }
398
399     private void setupScanCell() {
400         fpslic.cell(23,15).h(3, true);
401         fpslic.cell(23,15).yi(L3);
402         fpslic.cell(23,15).ylut(0xAA);
403         fpslic.iob_right(15, true).enableOutput(WEST);
404
405         fpslic.cell(23,0).ylut(0x00);
406         fpslic.iob_right(0, true).enableOutput(WEST);
407         fpslic.flush();
408     }
409
410     private void divider(Fpslic.Cell c) {
411         Fpslic.Cell detect1 = c;
412         Fpslic.Cell detect2 = c.east();
413
414         detect1.yi(NORTH);
415         detect1.ylut(LUT_SELF);
416         detect1.xlut(LUT_OTHER & (~LUT_Z));
417         detect1.c(YLUT);
418         detect1.t(TMUX_FB);
419         detect1.f(false);
420         detect1.b(false);
421
422         detect2.xi(NW);
423         detect2.ylut(LUT_OTHER);
424         detect2.xlut((~LUT_SELF) & LUT_Z);
425         detect2.c(YLUT);
426         detect2.t(TMUX_FB);
427         detect2.f(false);
428         detect2.b(false);
429
430         detect1.south().yi(EAST);
431         detect1.south().xi(NE);
432         detect1.south().c(YLUT);
433         detect1.south().t(TMUX_FB);
434         detect1.south().f(false);
435         detect1.south().b(false);
436         detect1.south().ylut( (LUT_OTHER    & (~LUT_SELF)) |
437                               ((~LUT_OTHER) &   LUT_Z)
438                               );
439         detect1.south().xlut( (LUT_SELF    & (~LUT_OTHER)) |
440                               ((~LUT_SELF) &   LUT_Z)
441                               );
442
443         detect2.south().yi(WEST);
444         detect2.south().xi(NW);
445         detect2.south().c(YLUT);
446         detect2.south().t(TMUX_FB);
447         detect2.south().f(false);
448         detect2.south().b(false);
449         detect2.south().ylut( (LUT_OTHER    & (LUT_SELF)) |
450                               ((~LUT_OTHER) &   LUT_Z)
451                               );
452         detect2.south().xlut( (LUT_SELF    & (~LUT_OTHER)) |
453                               ((~LUT_SELF) &   LUT_Z)
454                               );
455
456     }
457
458     private void runGui(int width, int height) throws Exception {
459         Gui vis = new Gui(fpslic, fpslic, width, height);
460         Frame fr = new Frame();
461         fr.addKeyListener(vis);
462         fr.setLayout(new BorderLayout());
463         fr.add(vis, BorderLayout.CENTER);
464         fr.pack();
465         fr.setSize(900, 900);
466         vis.repaint();
467         fr.repaint();
468         fr.show();
469     }
470 }
471
472