+
+ Thread.sleep(5000);
+
+ for(int i=0; i<20; i++) test(i);
+ synchronized(Demo.class) { Demo.class.wait(); }
+ }
+
+ public void test(int count) throws Exception {
+ flush();
+ fill(count);
+
+ fpslic.flush();
+
+ fpslic.readCount();
+ long now = System.currentTimeMillis();
+ Thread.sleep(4000);
+ int save1y = fpslic.cell(19,22).ylut();
+ int save1x = fpslic.cell(19,22).xlut();
+ fpslic.cell(19,22).ylut(0xff);
+ fpslic.cell(19,22).xlut(0xff);
+ fpslic.flush();
+ long then = System.currentTimeMillis();
+ fpslic.cell(19,22).ylut(save1y);
+ fpslic.cell(19,22).xlut(save1x);
+
+ int tokens = fpslic.readCount();
+ System.out.println(count + ", " + (tokens*1000)/(then-now));
+ }
+
+ private void flush() {
+ int save1y = fpslic.cell(19,22).ylut();
+ int save1x = fpslic.cell(19,22).xlut();
+ int save2y = fpslic.cell(20,22).ylut();
+ int save2x = fpslic.cell(20,22).xlut();
+ fpslic.cell(19,22).ylut(0x00);
+ fpslic.cell(19,22).xlut(0x00);
+ for(int i=0; i<800; i++) {
+ fpslic.cell(20,22).ylut(0xff);
+ fpslic.cell(20,22).xlut(0xff);
+ fpslic.cell(20,22).ylut(0x00);
+ fpslic.cell(20,22).xlut(0x00);
+ }
+ fpslic.flush();
+ fpslic.cell(20,22).ylut(save2y);
+ fpslic.cell(20,22).xlut(save2x);
+ fpslic.cell(19,22).ylut(save2y);
+ fpslic.cell(19,22).xlut(save2x);
+ fpslic.flush();
+ fpslic.cell(19,22).ylut(save1y);
+ fpslic.cell(19,22).xlut(save1x);
+ fpslic.flush();
+ fpslic.readCount();
+ try { Thread.sleep(100); } catch (Exception e) { }
+ int rc = fpslic.readCount();
+ if (rc!=0)
+ throw new Error("flush() failed => " + rc);
+ }
+
+ private void fill(int count) {
+ int save1y = fpslic.cell(19,22).ylut();
+ int save1x = fpslic.cell(19,22).xlut();
+ int save2y = fpslic.cell(20,22).ylut();
+ int save2x = fpslic.cell(20,22).xlut();
+ fpslic.cell(19,22).ylut(0xff);
+ fpslic.cell(19,22).xlut(0xff);
+ fpslic.cell(20,22).ylut(0xff);
+ fpslic.cell(20,22).xlut(0xff);
+ boolean yes = true;
+ for(int i=0; i<count; i++) {
+ if (yes) {
+ fpslic.cell(19,22).ylut(0xff);
+ fpslic.cell(19,22).xlut(0xff);
+ } else {
+ fpslic.cell(19,22).ylut(0x00);
+ fpslic.cell(19,22).xlut(0x00);
+ }
+ yes = !yes;
+ }
+ fpslic.cell(19,22).ylut(save1y);
+ fpslic.cell(19,22).xlut(save1x);
+ fpslic.cell(20,22).ylut(save2y);
+ fpslic.cell(20,22).xlut(save2x);
+ fpslic.flush();
+ }
+
+ private Fpslic.Cell pipe(Fpslic.Cell c, Fpslic.Cell prev, int[] dirs) {
+ for(int i=0; i<dirs.length; i++) {
+ Fpslic.Cell next = c.dir(dirs[i]);
+ micropipelineStage(c, prev, next);
+ prev = c;
+ c = next;
+ }
+ return c;
+ }
+
+ private void createPipeline(Fpslic.Cell c, boolean downward, int length, boolean start) {
+ length -= 8;
+ if (downward) {
+ if (c.row < 6) {
+ c = pipe(c, c.north(), new int[] { SW, EAST, SW, WEST, NW, NORTH });
+ c = c.se();
+ c = pipe(c, c.north(), new int[] { NE, NORTH });
+ c = c.sw().west();
+ downward = false;
+ } else {
+ c = micropipelineStage(c, start ? c.west() : c.north(), c.sw());
+ c = micropipelineStage(c, c.ne(), c.south());
+ c = micropipelineStage(c, c.north(), c.se());
+ c = micropipelineStage(c, c.nw(), c.south());
+ c = c.nw();
+ c = micropipelineStage(c, c.south(), c.ne());
+ c = micropipelineStage(c, c.sw(), c.north());
+ c = micropipelineStage(c, c.south(), c.nw());
+ micropipelineStage(c, c.se(), start ? c.east() : c.north());
+ c = c.south().south().south().south().east();
+ }
+ } else {
+ if (c.row > c.fpslic().getHeight()-7) {
+ c = pipe(c, c.south(), new int[] { NW, SOUTH });
+ c = c.nw();
+ c = pipe(c, c.south(), new int[] { NE, EAST, SE, WEST, SE, SOUTH });
+ c = c.nw().west();
+ downward = true;
+ } else {
+ Fpslic.Cell ret = c = pipe(c, c.south(), new int[] { NE, NORTH, NW, NORTH });
+ c = c.se();
+ c = pipe(c, c.north(), new int[] { SW, SOUTH, SE, SOUTH });
+ c = ret;
+ }
+ }
+ if (length >= 8) createPipeline(c, downward, length, false);
+ else {
+ if (downward) {
+ c = micropipelineStage(c, c.north(), c.sw());
+ c = micropipelineStage(c, c.ne(), c.west());
+ c = micropipelineStage(c, c.east(), c.ne());
+ c = micropipelineStage(c, c.sw(), c.north());
+ } else {
+ c = pipe(c, c.south(), new int[] { NW, EAST, SE, SOUTH });
+ }
+ }
+ }
+
+ /*
+ private void createPipeline(Fpslic.Cell c, boolean downward, int length) {
+ length -= 2;
+ if (downward) {
+ if (c.row == 0) {
+ c = micropipelineStage(c, c.ne(), c.west());
+ c = micropipelineStage(c, c.east(), c.nw());
+ if (length > 0) createPipeline(c, false, length);
+ } else {
+ c = micropipelineStage(c, c.ne(), c.east());
+ c = micropipelineStage(c, c.west(), c.sw());
+ if (length > 0) createPipeline(c, true, length);
+ }
+ } else {
+ if (c.row == c.fpslic().getHeight()-1) {
+ c = micropipelineStage(c, c.se(), c.west());
+ c = micropipelineStage(c, c.east(), c.sw());
+ if (length > 0) createPipeline(c, true, length);
+ } else {
+ c = micropipelineStage(c, c.se(), c.east());
+ c = micropipelineStage(c, c.west(), c.nw());
+ if (length > 0) createPipeline(c, false, length);
+ }
+ }
+ }
+ */
+
+ private Fpslic.Cell micropipelineStage(Fpslic.Cell c, Fpslic.Cell prev, Fpslic.Cell next) {
+ switch(c.dir(next)) {
+ case NORTH: case SOUTH: case EAST: case WEST:
+ switch (c.dir(prev)) {
+ case NORTH: case SOUTH: case EAST: case WEST: throw new Error("cannot have prev&next both use y");
+ }
+ c.ylut((LUT_SELF & ~LUT_OTHER) | (LUT_Z & ~LUT_OTHER) | (LUT_Z & LUT_SELF & LUT_OTHER));
+ c.xlut(LUT_Z);
+ c.c(YLUT);
+ c.yi(next);
+ c.xi(prev);
+ break;
+ case NW: case SE: case SW: case NE:
+ switch (c.dir(prev)) {
+ case NW: case SE: case SW: case NE: throw new Error("cannot have prev&next both use x");
+ }
+ c.xlut((LUT_SELF & ~LUT_OTHER) | (LUT_Z & ~LUT_OTHER) | (LUT_Z & LUT_SELF & LUT_OTHER));
+ c.ylut(LUT_Z);
+ c.c(XLUT);
+ c.xi(next);
+ c.yi(prev);
+ break;
+ default: throw new Error();
+ }
+ c.b(false);
+ c.f(false);
+ c.t(TMUX_FB);
+ c.yo(false);
+ c.xo(false);
+ return next;