fpslic = new FtdiBoard();
}
- public void main() throws Exception {
+ Fpslic.Cell start;
+ public void main(String[] s) throws Exception {
turnOnLeds();
setupScanCell();
- Fpslic.Cell root = fpslic.cell(2, 2);
-
- root.yo(root.north());
- root.ylut(~LUT_SELF);
- root.c(YLUT);
- root = root.north();
-
- root.yo(root.east());
- root.ylut(~LUT_SELF);
- root.c(YLUT);
- root = root.east();
-
- root.yo(root.south());
- root.ylut(~LUT_SELF);
- root.c(YLUT);
- root = root.south();
-
- root.yo(root.west());
- root.c(YLUT);
- root = root.west();
-
- root = fpslic.cell(3, 7);
- root.h(1, true);
- root.h(2, true);
- root.wi(L1);
- root.zi(L2);
- root.c(YLUT);
- root.t(TMUX_W);
- root.b(false);
- root.f(false);
- root.ylut(LUT_SELF);
- root.yi(EAST);
- root.xlut(LUT_Z);
- root.xo(false);
-
- root.west().out(2, true);
- root.west().h(2, true);
- root.west().c(YLUT);
-
- root.west().west().out(1, true);
- root.west().west().h(1, true);
- root.west().west().c(YLUT);
-
- root.ne().xo(root);
-
- createPipeline(fpslic.cell(20, 22), true, 40, true);
+ //runGui(24, 24);
+
+ for(int i=0; i<255; i++)
+ fpslic.readCount();
+
+ //System.in.read();
+ for(int i=46; i<400; i+=2) {
+ go(i);
+ }
+ System.out.println("done");
+
+ }
+
+ public void go(int size) throws Exception {
+ start = fpslic.cell(20, 21);
+ int rsize = size-createPipeline(start, true, size, false);
+ System.out.println("actual size => " + rsize);
+ pipe(start.west().north(), start.west(), new int[] { NE, EAST, SW, SOUTH });
for(int i=1; i<22; i+=2)
divider(fpslic.cell(21, i));
fpslic.cell(21,22).yo(fpslic.cell(20,22));
fpslic.cell(21,22).xo(fpslic.cell(20,22));
- runGui(24, 24);
+ reconfigTopLeft();
+ reconfigTopRight();
+ fpslic.flush();
- Thread.sleep(5000);
+ Thread.sleep(2000);
- for(int i=0; i<20; i++) test(i);
- synchronized(Demo.class) { Demo.class.wait(); }
+ String sizes = rsize+"";
+ while(sizes.length()<3) sizes = "0"+sizes;
+ String fname = "data/size"+sizes+".csv";
+ if (!new File(fname).exists()) {
+ PrintWriter outfile = new PrintWriter(new OutputStreamWriter(new FileOutputStream(fname)));
+ for(int i=0; i<rsize/2+1; i++) test(i, rsize, outfile);
+ outfile.flush();
+ outfile.close();
+ }
+ System.out.println("done.");
}
- public void test(int count) throws Exception {
- flush();
- fill(count);
+ public void test(int count, int size, PrintWriter outfile) throws Exception {
+ fpslic.flush();
+ drain(count);
+ fpslic.flush();
+ fill(count, size);
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);
+ Thread.sleep(2000);
+ topLeft().ylut(0xff);
+ topLeft().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));
+ double elapsed = (double)((FtdiBoard)fpslic).timer;
+
+ double occupancy = ((double)(2*count))/((double)size);
+
+ //double elapsed = (then-now);
+ double result = (tokens*1000)/elapsed;
+
+ // eleven dividers...
+ //result *= 2*2*2*2*2*2*2*2*2*2*2;
+
+ // ...and the interrupt pin counts *pairs* of transitions
+ //result *= 2;
+
+ // result is transitions/sec => 633mcell/sec velocity! =)
+ outfile.println(occupancy + ", " + result);
+ System.out.println((2*count)+"/"+size+" "+occupancy + ", " + result + " @ " + elapsed);
+ outfile.flush();
}
- 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);
+ private void drain(int size) {
+ while(true){
+ topLeft().xlut(0x00);
+ for(int i=0; i<size*4; i++) {
+ topLeft().ylut(0xff);
+ fpslic.flush();
+ topLeft().ylut(0x00);
+ fpslic.flush();
}
- 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();
+ fpslic.readCount();
try { Thread.sleep(100); } catch (Exception e) { }
int rc = fpslic.readCount();
- if (rc!=0)
- throw new Error("flush() failed => " + rc);
+ if (rc!=0) {
+ System.err.println("flush() failed REALLY BADLY => " + rc);
+ //try { System.in.read(); } catch (Exception _) { }
+ continue;
+ }
+
+ reconfigTopLeft();
+
+ fpslic.flush();
+ fpslic.readCount();
+ fpslic.readCount();
+ try { Thread.sleep(100); } catch (Exception e) { }
+ rc = fpslic.readCount();
+ if (rc!=0) {
+ System.err.println("flush() failed => " + rc);
+ //try { System.in.read(); } catch (Exception _) { }
+ continue;
+ }
+ break;
+ }
}
- 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;
+ private void fill(int count, int size) {
+ //topLeft().ylut((count>0 && count<size/2-1) ? 0xff : 0x00);
+ topLeft().ylut(0x00);
+ boolean yes = false;
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);
- }
+ if (yes) {
+ topLeft().xlut(0xff);
+ } else {
+ topLeft().xlut(0x00);
+ }
+ fpslic.flush();
yes = !yes;
+ //System.out.println("fill => " + yes);
+ //try { Thread.sleep(500); } catch (Exception _) { }
}
- fpslic.cell(19,22).ylut(save1y);
- fpslic.cell(19,22).xlut(save1x);
- fpslic.cell(20,22).ylut(save2y);
- fpslic.cell(20,22).xlut(save2x);
+ //System.out.println("done filling.");
+ //try { Thread.sleep(2000); } catch (Exception _) { }
+
+ //System.out.println("reconfigured.");
+ //try { System.in.read(); } catch (Exception _) { }
+
+
+ if (count>0 && count<size/2-1) {
+ reconfigTopLeftPreserve(yes);
+ } else {
+ reconfigTopLeft();
+ }
+
+ //System.out.println("running.");
+ //try { System.in.read(); } catch (Exception _) { }
+
+ //try { Thread.sleep(2000); } catch (Exception _) { }
+ }
+
+ private Fpslic.Cell topLeft() { return start.north().north(); }
+ private Fpslic.Cell topRight() { return start.north().ne(); }
+ private void reconfigTopLeft() {
+ Fpslic.Cell c = topLeft();
+ c.c(YLUT);
+ c.ylut(0x00);
+ c.xlut(0x00);
+ c.wi(L0);
+ c.t(TMUX_W_AND_FB);
+ c.ylut((LUT_SELF & ~LUT_OTHER) |
+ (LUT_Z & ~LUT_OTHER) |
+ (LUT_Z & LUT_SELF));
+ fpslic.flush();
+ c.xlut(LUT_Z);
+ fpslic.flush();
+ c.wi(NONE);
+ fpslic.flush();
+ }
+ private void reconfigTopLeftNice() {
+ Fpslic.Cell c = topLeft();
+ c.c(YLUT);
+ c.xlut(LUT_Z);
+ fpslic.flush();
+ c.ylut((LUT_SELF & ~LUT_OTHER) |
+ (LUT_Z & ~LUT_OTHER) |
+ (LUT_Z & LUT_SELF));
fpslic.flush();
}
+ private void reconfigTopLeftPreserve(boolean on) {
+ Fpslic.Cell c = topLeft();
+ fpslic.flush();
+ if (on) c.ylut(0x00);
+ c.xlut(LUT_Z);
+ fpslic.flush();
+ c.ylut((LUT_SELF & ~LUT_OTHER) |
+ (LUT_Z & ~LUT_OTHER) |
+ (LUT_Z & LUT_SELF));
+ fpslic.flush();
+ }
+ private void reconfigTopRight() { micropipelineStage(topRight(), topRight().west(), topRight().sw()); }
private Fpslic.Cell pipe(Fpslic.Cell c, Fpslic.Cell prev, int[] dirs) {
for(int i=0; i<dirs.length; i++) {
return c;
}
- private void createPipeline(Fpslic.Cell c, boolean downward, int length, boolean start) {
- length -= 8;
+ private int createPipeline(Fpslic.Cell c, boolean downward, int length, boolean start) {
+ boolean stop = false;
+ do {
if (downward) {
if (c.row < 6) {
+ if (length < 10+4) { stop = true; break; }
+ length -= 10;
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());
+ if (length < 8+4) { stop = true; break; }
+ length -= 8;
+ c = micropipelineStage(c, 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 = 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());
+ micropipelineStage(c, c.se(), c.north());
c = c.south().south().south().south().east();
}
} else {
if (c.row > c.fpslic().getHeight()-7) {
+ if (length < 10+4) { stop = true; break; }
+ length -= 10;
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 {
+ if (length < 8+4) { stop = true; break; }
+ length -= 8;
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 {
+ } while(false);
+ if (stop) {
+ length -= 4;
if (downward) {
c = micropipelineStage(c, c.north(), c.sw());
c = micropipelineStage(c, c.ne(), c.west());
} else {
c = pipe(c, c.south(), new int[] { NW, EAST, SE, SOUTH });
}
+ return length;
+ } else {
+ return createPipeline(c, downward, length, false);
}
}
*/
private Fpslic.Cell micropipelineStage(Fpslic.Cell c, Fpslic.Cell prev, Fpslic.Cell next) {
+ return micropipelineStage(c, prev, next, true);
+ }
+ private Fpslic.Cell micropipelineStage(Fpslic.Cell c, Fpslic.Cell prev, Fpslic.Cell next, boolean configDir) {
+ c.b(false);
+ c.f(false);
+ c.yo(false);
+ c.xo(false);
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);
+ if (configDir) {
+ c.yi(next);
+ c.xi(prev);
+ }
+
c.c(YLUT);
- c.yi(next);
- c.xi(prev);
+ c.ylut(0x00);
+ c.xlut(0x00);
+ c.wi(L0);
+ c.t(TMUX_W_AND_FB);
+ c.ylut((LUT_SELF & ~LUT_OTHER) |
+ (LUT_Z & ~LUT_OTHER) |
+ (LUT_Z & LUT_SELF));
+ c.xlut(LUT_Z);
+ fpslic.flush();
+ c.wi(NONE);
+ fpslic.flush();
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);
+ if (configDir) {
+ c.xi(next);
+ c.yi(prev);
+ }
+
c.c(XLUT);
- c.xi(next);
- c.yi(prev);
+ c.xlut(0x00);
+ c.ylut(0x00);
+ c.wi(L0);
+ c.t(TMUX_W_AND_FB);
+ c.xlut((LUT_SELF & ~LUT_OTHER) |
+ (LUT_Z & ~LUT_OTHER) |
+ (LUT_Z & LUT_SELF));
+ c.ylut(LUT_Z);
+ fpslic.flush();
+ c.wi(NONE);
+ fpslic.flush();
break;
default: throw new Error();
}
- c.b(false);
- c.f(false);
- c.t(TMUX_FB);
- c.yo(false);
- c.xo(false);
+ //c.t(TMUX_FB);
return next;
}
private void turnOnLeds() {
for(int i=0; i<24; i++) {
- fpslic.iob_bot(i, true).enableOutput(NORTH);
- fpslic.iob_bot(i, false).enableOutput(NW);
+ //fpslic.iob_bot(i, true).enableOutput(NORTH);
+ //fpslic.iob_bot(i, false).enableOutput(NW);
fpslic.cell(i, 0).xlut(0xff);
fpslic.cell(i, 0).ylut(0xff);
}
fpslic.cell(23,0).ylut(0x00);
fpslic.iob_right(0, true).enableOutput(WEST);
+ fpslic.flush();
}
private void divider(Fpslic.Cell c) {
#include <avr/io.h>\r
#include <avr/interrupt.h>\r
\r
+volatile int32_t upper = 0;\r
+\r
int err = 0;\r
\r
void initUART0(unsigned int baudRate, unsigned int doubleRate) {\r
return (write_buf_tail-write_buf_head) > (BUFSIZE/2);\r
}\r
\r
+int32_t timer = 0;\r
+\r
inline char recv() {\r
int q;\r
char ret;\r
+\r
+ PORTE |= (1<<3);\r
while(read_empty()) cts(1);\r
+ PORTE &= ~(1<<3);\r
+\r
ret = read_buf[read_buf_head];\r
read_buf_head = inc(read_buf_head);\r
if (!read_nearlyFull()) cts(1);\r
- if (PORTE & (1<<3)) PORTE &= ~(1<<3);\r
- else PORTE |= (1<<3);\r
return ret;\r
}\r
\r
}\r
\r
void send(char c) {\r
+ PORTE |= (1<<2);\r
while (write_full());\r
+ PORTE &= ~(1<<2);\r
write_buf[write_buf_tail] = c;\r
write_buf_tail = inc(write_buf_tail);\r
- if (PORTE & (1<<2)) PORTE &= ~(1<<2);\r
- else PORTE |= (1<<2);\r
UCSR0B |= (1 << UDRIE0);\r
}\r
\r
sei();\r
}\r
\r
-void die() { cli(); PORTE|=(1<<5); _delay_ms(2000); while(1) { } }\r
+volatile int dead = 0;\r
+\r
+ISR(SIG_OVERFLOW1) { \r
+ upper = upper + 1;\r
+\r
+ if (!dead) {\r
+ if (PORTE & (1<<5)) PORTE &= ~(1<<5);\r
+ else PORTE |= (1<<5);\r
+ }\r
+\r
+ TCNT1 = 0;\r
+ sei();\r
+}\r
+\r
+//void die() { dead = 1; cli(); PORTE|=(1<<5); _delay_ms(2000); while(1) { } }\r
+\r
+void die(int two, int three, int five) {\r
+ dead = 1;\r
+ PORTE &~ ((1<<2) | (1<<3) | (1<<5));\r
+ if (two) PORTE |= (1<<2);\r
+ if (three) PORTE |= (1<<3);\r
+ if (five) PORTE |= (1<<5);\r
+ while(1) { }\r
+}\r
\r
ISR(SIG_UART0_RECV) {\r
- if (UCSR0A & (1 << FE0)) err = 201;//{ portd(2,0); portd(3,1); die(); } // framing error, lock up with LED=01\r
- if ((UCSR0A & (1 << OR0))) err = 202;//{ portd(2,1); portd(3,0); die(); } // overflow; lock up with LED=10\r
- if (read_full()) err = 203;//{ portd(2,1); portd(3,1); die(); } // buffer overrun\r
+ if (UCSR0A & (1 << FE0)) die(0, 0, 1);\r
+ if ((UCSR0A & (1 << OR0))) die(0, 1, 1);\r
+ if (read_full()) die(1, 0, 1);\r
\r
read_buf[read_buf_tail] = UDR0;\r
read_buf_tail = inc(read_buf_tail);\r
DDRE = (1<<7) | (1<<5) | (1<<3) | (1<<2);\r
PORTE = 0;\r
\r
+ PORTE |= (1<<5);\r
+\r
read_buf_head = 0;\r
read_buf_tail = 0;\r
write_buf_head = 0;\r
write_buf_tail = 0;\r
- initUART0(0, 0); //for slow board\r
+ initUART0(1, 0); //for slow board\r
\r
EIMF = 0xFF;\r
SREG = INT0;\r
sei();\r
\r
+ TCNT1 = 0;\r
+ TIFR&=~(1<<TOV1);\r
+ TIMSK|=(1<<TOIE1);\r
+ TCCR1B = 3;\r
+\r
cts(0);\r
cts(1);\r
\r
send('I');\r
send('T');\r
send('S');\r
- fpga_interrupts(0);\r
- if (flag) {PORTE |= (1<<5);}\r
+ fpga_interrupts(1);\r
+ if (flag) die(1, 1, 1);\r
break;\r
\r
case 1:\r
send((local_interrupt_count >> 16) & 0xff);\r
send((local_interrupt_count >> 8) & 0xff);\r
send((local_interrupt_count >> 0) & 0xff);\r
+ \r
+ int32_t local_timer = TCNT1;\r
+ int32_t local_upper = upper;\r
+ TCCR1B = 0;\r
+ TIFR&=~(1<<TOV1);\r
+ TIMSK|=(1<<TOIE1);\r
+ upper = 0;\r
+ TCNT1 = 0;\r
+ TCCR1B = 3;\r
+ send((local_upper >> 8) & 0xff);\r
+ send((local_upper >> 0) & 0xff);\r
+ send((local_timer >> 8) & 0xff);\r
+ send((local_timer >> 0) & 0xff);\r
break;\r
}\r
\r