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