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