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=256; ; 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; }
133 try { Thread.sleep(100); } catch (Exception e) { }
134 rc = fpslic.readCount();
135 if (rc!=0) { System.err.println("flush() failed => " + rc); continue; }
140 private void fill(int count, int size) {
141 //topLeft().ylut((count>0 && count<size/2-1) ? 0xff : 0x00);
143 topLeft().ylut(0x00);
146 topLeft().xlut(0x00);
149 for(int i=0; i<count-1; i++) {
151 topLeft().xlut(0xff);
153 topLeft().xlut(0x00);
157 //System.out.println("fill => " + yes);
158 //try { Thread.sleep(500); } catch (Exception _) { }
161 //System.out.println("done filling.");
162 //try { Thread.sleep(2000); } catch (Exception _) { }
164 //System.out.println("reconfigured.");
165 //try { System.in.read(); } catch (Exception _) { }
168 if (count>0 && count!=size/2-1) {
169 reconfigTopLeftPreserve(yes);
170 } else if (count>0) {
171 topLeft().xlut(0xff);
173 topLeft().ylut(0xff);
174 reconfigTopLeftPreserve(false);
177 //System.out.println("running.");
178 //try { System.in.read(); } catch (Exception _) { }
180 //try { Thread.sleep(2000); } catch (Exception _) { }
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();
192 c.ylut((LUT_SELF & ~LUT_OTHER) |
193 (LUT_Z & ~LUT_OTHER) |
201 private void reconfigTopLeftNice() {
202 Fpslic.Cell c = topLeft();
206 c.ylut((LUT_SELF & ~LUT_OTHER) |
207 (LUT_Z & ~LUT_OTHER) |
211 private void reconfigTopLeftPreserve(boolean on) {
212 Fpslic.Cell c = topLeft();
214 if (on) c.ylut(0x00);
219 c.ylut((LUT_SELF & ~LUT_OTHER) |
220 (LUT_Z & ~LUT_OTHER) |
224 private void reconfigTopRight() { micropipelineStage(topRight(), topRight().west(), topRight().sw()); }
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);
236 private int createPipeline(Fpslic.Cell c, boolean downward, int length, boolean start) {
237 boolean stop = false;
241 if (length < 8+4) { stop = true; break; }
243 c = pipe(c, c.north(), new int[] { SW, EAST, SW, WEST, NW, NORTH });
245 c = pipe(c, c.north(), new int[] { NE, NORTH });
249 if (length < 8+4) { stop = true; break; }
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());
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();
263 if (c.row > c.fpslic().getHeight()-7) {
264 if (length < 8+4) { stop = true; break; }
266 c = pipe(c, c.south(), new int[] { NW, SOUTH });
268 c = pipe(c, c.south(), new int[] { NE, EAST, SE, WEST, SE, SOUTH });
272 if (length < 8+4) { stop = true; break; }
274 Fpslic.Cell ret = c = pipe(c, c.south(), new int[] { NE, NORTH, NW, NORTH });
276 c = pipe(c, c.north(), new int[] { SW, SOUTH, SE, SOUTH });
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());
289 c = pipe(c, c.south(), new int[] { NW, EAST, SE, SOUTH });
293 return createPipeline(c, downward, length, false);
298 private void createPipeline(Fpslic.Cell c, boolean downward, int length) {
302 c = micropipelineStage(c, c.ne(), c.west());
303 c = micropipelineStage(c, c.east(), c.nw());
304 if (length > 0) createPipeline(c, false, length);
306 c = micropipelineStage(c, c.ne(), c.east());
307 c = micropipelineStage(c, c.west(), c.sw());
308 if (length > 0) createPipeline(c, true, length);
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);
316 c = micropipelineStage(c, c.se(), c.east());
317 c = micropipelineStage(c, c.west(), c.nw());
318 if (length > 0) createPipeline(c, false, length);
324 private Fpslic.Cell micropipelineStage(Fpslic.Cell c, Fpslic.Cell prev, Fpslic.Cell next) {
325 return micropipelineStage(c, prev, next, true);
327 private Fpslic.Cell micropipelineStage(Fpslic.Cell c, Fpslic.Cell prev, Fpslic.Cell next, boolean configDir) {
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");
347 c.ylut((LUT_SELF & ~LUT_OTHER) |
348 (LUT_Z & ~LUT_OTHER) |
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");
369 c.xlut((LUT_SELF & ~LUT_OTHER) |
370 (LUT_Z & ~LUT_OTHER) |
377 default: throw new Error();
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);
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);
399 fpslic.cell(23,0).ylut(0x00);
400 fpslic.iob_right(0, true).enableOutput(WEST);
404 private void divider(Fpslic.Cell c) {
405 Fpslic.Cell detect1 = c;
406 Fpslic.Cell detect2 = c.east();
409 detect1.ylut(LUT_SELF);
410 detect1.xlut(LUT_OTHER & (~LUT_Z));
417 detect2.ylut(LUT_OTHER);
418 detect2.xlut((~LUT_SELF) & LUT_Z);
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)
433 detect1.south().xlut( (LUT_SELF & (~LUT_OTHER)) |
434 ((~LUT_SELF) & LUT_Z)
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)
446 detect2.south().xlut( (LUT_SELF & (~LUT_OTHER)) |
447 ((~LUT_SELF) & LUT_Z)
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);
459 fr.setSize(900, 900);