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             //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         for(int i=0; i<count; i++) {
153                 if (yes) {
154                     topLeft().xlut(0xff);
155                 } else {
156                     topLeft().xlut(0x00);
157                 }
158                 fpslic.flush();
159             yes = !yes;
160             //System.out.println("fill => " + yes);
161             //try { Thread.sleep(500); } catch (Exception _) { }
162         }
163         //System.out.println("done filling.");
164         //try { Thread.sleep(2000); } catch (Exception _) { }
165
166         //System.out.println("reconfigured.");
167         //try { System.in.read(); }  catch (Exception _) { }
168
169
170         if (count>0 && count<size/2-1) {
171             reconfigTopLeftPreserve(yes);
172         } else if (count>0) {
173             topLeft().xlut(0xff);
174             fpslic.flush();
175             topLeft().ylut(0xff);
176             reconfigTopLeftPreserve(false);
177         } 
178
179         //System.out.println("running.");
180         //try { System.in.read(); }  catch (Exception _) { }
181
182         //try { Thread.sleep(2000); } catch (Exception _) { }
183     }
184
185     private Fpslic.Cell topLeft() { return start.north().north(); }
186     private Fpslic.Cell topRight() { return start.north().ne(); }
187     private void reconfigTopLeft() {
188         Fpslic.Cell c = topLeft();
189                 c.c(YLUT);
190                 c.ylut(0x00);
191                 c.xlut(0x00);
192                 c.wi(L0);
193                 c.t(TMUX_W_AND_FB);
194                 c.ylut((LUT_SELF & ~LUT_OTHER) |
195                        (LUT_Z & ~LUT_OTHER) |
196                        (LUT_Z & LUT_SELF));
197             fpslic.flush();
198                 c.xlut(LUT_Z);
199             fpslic.flush();
200                 c.wi(NONE);
201             fpslic.flush();
202     }
203     private void reconfigTopLeftNice() {
204         Fpslic.Cell c = topLeft();
205         c.c(YLUT);
206         c.xlut(LUT_Z);
207         fpslic.flush();
208         c.ylut((LUT_SELF & ~LUT_OTHER) |
209                (LUT_Z & ~LUT_OTHER) |
210                (LUT_Z & LUT_SELF));
211         fpslic.flush();
212     }
213     private void reconfigTopLeftPreserve(boolean on) {
214         Fpslic.Cell c = topLeft();
215         fpslic.flush();
216         if (on) c.ylut(0x00);
217         //else    c.ylut(0xff);
218         //fpslic.flush();
219         c.xlut(LUT_Z);
220         fpslic.flush();
221         c.ylut((LUT_SELF & ~LUT_OTHER) |
222                (LUT_Z & ~LUT_OTHER) |
223                (LUT_Z & LUT_SELF));
224         fpslic.flush();
225     }
226     private void reconfigTopRight() { micropipelineStage(topRight(), topRight().west(), topRight().sw()); }
227
228     private Fpslic.Cell pipe(Fpslic.Cell c, Fpslic.Cell prev, int[] dirs) {
229         for(int i=0; i<dirs.length; i++) {
230             Fpslic.Cell next = c.dir(dirs[i]);
231             micropipelineStage(c, prev, next);
232             prev = c;
233             c = next;
234         }
235         return c;
236     }
237
238     private int createPipeline(Fpslic.Cell c, boolean downward, int length, boolean start) {
239         boolean stop = false;
240         do {
241         if (downward) {
242             if (c.row < 6) {
243                 if (length < 10+4) { stop = true; break; }
244                 length -= 10;
245                 c = pipe(c, c.north(), new int[] { SW, EAST, SW, WEST, NW, NORTH });
246                 c = c.se();
247                 c = pipe(c, c.north(), new int[] { NE, NORTH });
248                 c = c.sw().west();
249                 downward = false;
250             } else {
251                 if (length < 8+4) { stop = true; break; }
252                 length -= 8;
253                 c = micropipelineStage(c, c.north(), c.sw());
254                 c = micropipelineStage(c, c.ne(),    c.south());
255                 c = micropipelineStage(c, c.north(), c.se());
256                 c = micropipelineStage(c, c.nw(),    c.south());
257                 c = c.nw();
258                 c = micropipelineStage(c, c.south(), c.ne());
259                 c = micropipelineStage(c, c.sw(),    c.north());
260                 c = micropipelineStage(c, c.south(), c.nw());
261                 micropipelineStage(c, c.se(),    c.north());
262                 c = c.south().south().south().south().east();
263             }
264         } else {
265             if (c.row > c.fpslic().getHeight()-7) {
266                 if (length < 10+4) { stop = true; break; }
267                 length -= 10;
268                 c = pipe(c, c.south(), new int[] { NW, SOUTH });
269                 c = c.nw();
270                 c = pipe(c, c.south(), new int[] { NE, EAST, SE, WEST, SE, SOUTH });
271                 c = c.nw().west();
272                 downward = true;
273             } else {
274                 if (length < 8+4) { stop = true; break; }
275                 length -= 8;
276                 Fpslic.Cell ret = c = pipe(c, c.south(), new int[] { NE, NORTH, NW, NORTH });
277                 c = c.se();
278                 c = pipe(c, c.north(), new int[] { SW, SOUTH, SE, SOUTH });
279                 c = ret;
280             }
281         }
282         } while(false);
283         if (stop) {
284             length -= 4;
285             if (downward) {
286                 c = micropipelineStage(c, c.north(), c.sw());
287                 c = micropipelineStage(c, c.ne(), c.west());
288                 c = micropipelineStage(c, c.east(), c.ne());
289                 c = micropipelineStage(c, c.sw(), c.north());
290             } else {
291                 c = pipe(c, c.south(), new int[] { NW, EAST, SE, SOUTH });
292             }
293             return length;
294         } else {
295             return createPipeline(c, downward, length, false);
296         }
297     }
298
299     /*
300     private void createPipeline(Fpslic.Cell c, boolean downward, int length) {
301         length -= 2;
302         if (downward) {
303             if (c.row == 0) {
304                 c = micropipelineStage(c, c.ne(),   c.west());
305                 c = micropipelineStage(c, c.east(), c.nw());
306                 if (length > 0) createPipeline(c, false, length);
307             } else {
308                 c = micropipelineStage(c, c.ne(),   c.east());
309                 c = micropipelineStage(c, c.west(), c.sw());
310                 if (length > 0) createPipeline(c, true, length);
311             }
312         } else {
313             if (c.row == c.fpslic().getHeight()-1) {
314                 c = micropipelineStage(c, c.se(),   c.west());
315                 c = micropipelineStage(c, c.east(), c.sw());
316                 if (length > 0) createPipeline(c, true, length);
317             } else {
318                 c = micropipelineStage(c, c.se(),   c.east());
319                 c = micropipelineStage(c, c.west(), c.nw());
320                 if (length > 0) createPipeline(c, false, length);
321             }
322         }
323     }
324     */
325
326     private Fpslic.Cell micropipelineStage(Fpslic.Cell c, Fpslic.Cell prev, Fpslic.Cell next) {
327         return micropipelineStage(c, prev, next, true);
328     }
329     private Fpslic.Cell micropipelineStage(Fpslic.Cell c, Fpslic.Cell prev, Fpslic.Cell next, boolean configDir) {
330         c.b(false);
331         c.f(false);
332         c.yo(false);
333         c.xo(false);
334         switch(c.dir(next)) {
335             case NORTH: case SOUTH: case EAST: case WEST:
336                 switch (c.dir(prev)) {
337                     case NORTH: case SOUTH: case EAST: case WEST: throw new Error("cannot have prev&next both use y");
338                 }
339                 if (configDir) {
340                     c.yi(next);
341                     c.xi(prev);
342                 }
343
344                 c.c(YLUT);
345                 c.ylut(0x00);
346                 c.xlut(0x00);
347                 c.wi(L0);
348                 c.t(TMUX_W_AND_FB);
349                 c.ylut((LUT_SELF & ~LUT_OTHER) |
350                        (LUT_Z & ~LUT_OTHER) |
351                        (LUT_Z & LUT_SELF));
352                 c.xlut(LUT_Z);
353             fpslic.flush();
354                 c.wi(NONE);
355             fpslic.flush();
356                 break;
357             case NW: case SE: case SW: case NE:
358                 switch (c.dir(prev)) {
359                     case NW: case SE: case SW: case NE: throw new Error("cannot have prev&next both use x");
360                 }
361                 if (configDir) {
362                     c.xi(next);
363                     c.yi(prev);
364                 }
365
366                 c.c(XLUT);
367                 c.xlut(0x00);
368                 c.ylut(0x00);
369                 c.wi(L0);
370                 c.t(TMUX_W_AND_FB);
371                 c.xlut((LUT_SELF & ~LUT_OTHER) |
372                        (LUT_Z & ~LUT_OTHER) |
373                        (LUT_Z & LUT_SELF));
374                 c.ylut(LUT_Z);
375             fpslic.flush();
376                 c.wi(NONE);
377             fpslic.flush();
378                 break;
379             default: throw new Error();
380         }
381         //c.t(TMUX_FB);
382         return next;
383     }
384
385     private void turnOnLeds() {
386         for(int i=0; i<24; i++) {
387             //fpslic.iob_bot(i, true).enableOutput(NORTH);
388             //fpslic.iob_bot(i, false).enableOutput(NW);
389             fpslic.cell(i, 0).xlut(0xff);
390             fpslic.cell(i, 0).ylut(0xff);
391         }
392     }
393
394     private void setupScanCell() {
395         fpslic.cell(23,15).h(3, true);
396         fpslic.cell(23,15).yi(L3);
397         fpslic.cell(23,15).ylut(0xAA);
398         fpslic.iob_right(15, true).enableOutput(WEST);
399
400         fpslic.cell(23,0).ylut(0x00);
401         fpslic.iob_right(0, true).enableOutput(WEST);
402         fpslic.flush();
403     }
404
405     private void divider(Fpslic.Cell c) {
406         Fpslic.Cell detect1 = c;
407         Fpslic.Cell detect2 = c.east();
408
409         detect1.yi(NORTH);
410         detect1.ylut(LUT_SELF);
411         detect1.xlut(LUT_OTHER & (~LUT_Z));
412         detect1.c(YLUT);
413         detect1.t(TMUX_FB);
414         detect1.f(false);
415         detect1.b(false);
416
417         detect2.xi(NW);
418         detect2.ylut(LUT_OTHER);
419         detect2.xlut((~LUT_SELF) & LUT_Z);
420         detect2.c(YLUT);
421         detect2.t(TMUX_FB);
422         detect2.f(false);
423         detect2.b(false);
424
425         detect1.south().yi(EAST);
426         detect1.south().xi(NE);
427         detect1.south().c(YLUT);
428         detect1.south().t(TMUX_FB);
429         detect1.south().f(false);
430         detect1.south().b(false);
431         detect1.south().ylut( (LUT_OTHER    & (~LUT_SELF)) |
432                               ((~LUT_OTHER) &   LUT_Z)
433                               );
434         detect1.south().xlut( (LUT_SELF    & (~LUT_OTHER)) |
435                               ((~LUT_SELF) &   LUT_Z)
436                               );
437
438         detect2.south().yi(WEST);
439         detect2.south().xi(NW);
440         detect2.south().c(YLUT);
441         detect2.south().t(TMUX_FB);
442         detect2.south().f(false);
443         detect2.south().b(false);
444         detect2.south().ylut( (LUT_OTHER    & (LUT_SELF)) |
445                               ((~LUT_OTHER) &   LUT_Z)
446                               );
447         detect2.south().xlut( (LUT_SELF    & (~LUT_OTHER)) |
448                               ((~LUT_SELF) &   LUT_Z)
449                               );
450
451     }
452
453     private void runGui(int width, int height) throws Exception {
454         Gui vis = new Gui(fpslic, fpslic, width, height);
455         Frame fr = new Frame();
456         fr.addKeyListener(vis);
457         fr.setLayout(new BorderLayout());
458         fr.add(vis, BorderLayout.CENTER);
459         fr.pack();
460         fr.setSize(900, 900);
461         vis.repaint();
462         fr.repaint();
463         fr.show();
464     }
465 }
466
467