1 package edu.berkeley.slipway;
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.*;
9 import java.awt.event.*;
10 import java.awt.color.*;
11 import org.ibex.util.*;
16 public class AsyncPaperDemo {
20 public AsyncPaperDemo() throws Exception {
21 fpslic = new FtdiBoard();
25 public void main(String[] s) throws Exception {
32 for(int i=0; i<255; i++)
36 for(int i=0; i<400; i+=2) {
39 //System.out.println("done");
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 });
49 Fpslic.Cell div = start.east();
52 if (div.south()==null || div.south().south()==null) break;
53 div = div.south().south();
55 div = div.south().east();
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));
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);
74 System.out.println("done.");
77 public void test(int count, int size, PrintWriter outfile) throws Exception {
86 long now = System.currentTimeMillis();
91 long then = System.currentTimeMillis();
93 int tokens = fpslic.readCount();
95 int clockrate = 24; // (in mhz)
96 double elapsed = (double)((((FtdiBoard)fpslic).timer)/clockrate);
98 double occupancy = ((double)(2*count))/((double)size);
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;
103 int clockdivisor = 64;
104 multiplier /= clockdivisor;
106 double result = (tokens*multiplier)/elapsed; // in millions
109 // result is transitions/sec => 633mcell/sec velocity! =)
110 outfile.println(occupancy + ", " + result);
111 System.out.println((2*count)+"/"+size+" "+occupancy + ", " + result/* + " @ " + elapsed*/);
115 private void drain(int size) {
117 topLeft().xlut(0x00);
118 for(int i=0; i<size*4; i++) {
119 topLeft().ylut(0xff);
120 topLeft().ylut(0x00);
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; }
130 for(int x=0; x<24; x++)
131 for(int y=0; y<24; y++)
132 fpslic.cell(x,y).wi(L0);
134 for(int x=0; x<24; x++)
135 for(int y=0; y<24; y++)
136 fpslic.cell(x,y).wi(NONE);
140 try { Thread.sleep(100); } catch (Exception e) { }
141 rc = fpslic.readCount();
142 if (rc!=0) { System.err.println("flush() failed => " + rc); continue; }
147 private void fill(int count, int size) {
148 //topLeft().ylut((count>0 && count<size/2-1) ? 0xff : 0x00);
150 topLeft().ylut(0x00);
153 topLeft().xlut(0x00);
156 for(int i=0; i<count-1; i++) {
158 topLeft().xlut(0xff);
160 topLeft().xlut(0x00);
164 //System.out.println("fill => " + yes);
165 //try { Thread.sleep(500); } catch (Exception _) { }
168 //System.out.println("done filling.");
169 //try { Thread.sleep(2000); } catch (Exception _) { }
171 //System.out.println("reconfigured.");
172 //try { System.in.read(); } catch (Exception _) { }
175 if (count>0 && count!=size/2-1) {
176 reconfigTopLeftPreserve(yes);
177 } else if (count>0) {
178 topLeft().xlut(0xff);
180 topLeft().ylut(0xff);
181 reconfigTopLeftPreserve(false);
184 //System.out.println("running.");
185 //try { System.in.read(); } catch (Exception _) { }
187 //try { Thread.sleep(2000); } catch (Exception _) { }
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();
199 c.ylut((LUT_SELF & ~LUT_OTHER) |
200 (LUT_Z & ~LUT_OTHER) |
208 private void reconfigTopLeftNice() {
209 Fpslic.Cell c = topLeft();
213 c.ylut((LUT_SELF & ~LUT_OTHER) |
214 (LUT_Z & ~LUT_OTHER) |
218 private void reconfigTopLeftPreserve(boolean on) {
219 Fpslic.Cell c = topLeft();
221 if (on) c.ylut(0x00);
226 c.ylut((LUT_SELF & ~LUT_OTHER) |
227 (LUT_Z & ~LUT_OTHER) |
231 private void reconfigTopRight() { micropipelineStage(topRight(), topRight().west(), topRight().sw()); }
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);
243 private int createPipeline(Fpslic.Cell c, boolean downward, int length, boolean start) {
244 boolean stop = false;
248 if (length < 8+4) { stop = true; break; }
250 c = pipe(c, c.north(), new int[] { SW, EAST, SW, WEST, NW, NORTH });
252 c = pipe(c, c.north(), new int[] { NE, NORTH });
256 if (length < 8+4) { stop = true; break; }
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());
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();
270 if (c.row > c.fpslic().getHeight()-7) {
271 if (length < 8+4) { stop = true; break; }
273 c = pipe(c, c.south(), new int[] { NW, SOUTH });
275 c = pipe(c, c.south(), new int[] { NE, EAST, SE, WEST, SE, SOUTH });
279 if (length < 8+4) { stop = true; break; }
281 Fpslic.Cell ret = c = pipe(c, c.south(), new int[] { NE, NORTH, NW, NORTH });
283 c = pipe(c, c.north(), new int[] { SW, SOUTH, SE, SOUTH });
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());
296 c = pipe(c, c.south(), new int[] { NW, EAST, SE, SOUTH });
300 return createPipeline(c, downward, length, false);
305 private void createPipeline(Fpslic.Cell c, boolean downward, int length) {
309 c = micropipelineStage(c, c.ne(), c.west());
310 c = micropipelineStage(c, c.east(), c.nw());
311 if (length > 0) createPipeline(c, false, length);
313 c = micropipelineStage(c, c.ne(), c.east());
314 c = micropipelineStage(c, c.west(), c.sw());
315 if (length > 0) createPipeline(c, true, length);
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);
323 c = micropipelineStage(c, c.se(), c.east());
324 c = micropipelineStage(c, c.west(), c.nw());
325 if (length > 0) createPipeline(c, false, length);
331 private Fpslic.Cell micropipelineStage(Fpslic.Cell c, Fpslic.Cell prev, Fpslic.Cell next) {
332 return micropipelineStage(c, prev, next, true);
334 private Fpslic.Cell micropipelineStage(Fpslic.Cell c, Fpslic.Cell prev, Fpslic.Cell next, boolean configDir) {
337 switch(c.dir(next)) {
338 case NORTH: case SOUTH: case EAST: case WEST:
339 switch (c.dir(prev)) {
340 case NORTH: case SOUTH: case EAST: case WEST: throw new Error("cannot have prev&next both use y");
355 c.ylut((LUT_SELF & ~LUT_OTHER) |
356 (LUT_Z & ~LUT_OTHER) |
363 case NW: case SE: case SW: case NE:
364 switch (c.dir(prev)) {
365 case NW: case SE: case SW: case NE: throw new Error("cannot have prev&next both use x");
380 c.xlut((LUT_SELF & ~LUT_OTHER) |
381 (LUT_Z & ~LUT_OTHER) |
388 default: throw new Error();
395 private void turnOnLeds() {
396 for(int i=0; i<24; i++) {
397 //fpslic.iob_bot(i, true).enableOutput(NORTH);
398 //fpslic.iob_bot(i, false).enableOutput(NW);
399 fpslic.cell(i, 0).xlut(0xff);
400 fpslic.cell(i, 0).ylut(0xff);
404 private void setupScanCell() {
405 fpslic.cell(23,15).h(3, true);
406 fpslic.cell(23,15).yi(L3);
407 fpslic.cell(23,15).ylut(0xAA);
408 fpslic.iob_right(15, true).enableOutput(WEST);
410 fpslic.cell(23,0).ylut(0x00);
411 fpslic.iob_right(0, true).enableOutput(WEST);
415 private void divider(Fpslic.Cell c) {
416 Fpslic.Cell detect1 = c;
417 Fpslic.Cell detect2 = c.east();
420 detect1.ylut(LUT_SELF);
421 detect1.xlut(LUT_OTHER & (~LUT_Z));
428 detect2.ylut(LUT_OTHER);
429 detect2.xlut((~LUT_SELF) & LUT_Z);
435 detect1.south().yi(EAST);
436 detect1.south().xi(NE);
437 detect1.south().c(YLUT);
438 detect1.south().t(TMUX_FB);
439 detect1.south().f(false);
440 detect1.south().b(false);
441 detect1.south().ylut( (LUT_OTHER & (~LUT_SELF)) |
442 ((~LUT_OTHER) & LUT_Z)
444 detect1.south().xlut( (LUT_SELF & (~LUT_OTHER)) |
445 ((~LUT_SELF) & LUT_Z)
448 detect2.south().yi(WEST);
449 detect2.south().xi(NW);
450 detect2.south().c(YLUT);
451 detect2.south().t(TMUX_FB);
452 detect2.south().f(false);
453 detect2.south().b(false);
454 detect2.south().ylut( (LUT_OTHER & (LUT_SELF)) |
455 ((~LUT_OTHER) & LUT_Z)
457 detect2.south().xlut( (LUT_SELF & (~LUT_OTHER)) |
458 ((~LUT_SELF) & LUT_Z)
463 private void runGui(int width, int height) throws Exception {
464 Gui vis = new Gui(fpslic, fpslic, width, height);
465 Frame fr = new Frame();
466 fr.addKeyListener(vis);
467 fr.setLayout(new BorderLayout());
468 fr.add(vis, BorderLayout.CENTER);
470 fr.setSize(900, 900);