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