checkpoint
[slipway.git] / src / edu / berkeley / slipway / Demo.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 Demo {
17
18     public static boolean mullers = true;
19     public static int masterx = 1;
20
21     public static int PIPELEN=20;
22     public static void main(String[] s) throws Exception {
23         FtdiBoard device = new FtdiBoard();
24         Fpslic at40k = device;
25         try {
26             long begin = System.currentTimeMillis();
27             FpslicUtil.readMode4(new ProgressInputStream("configuring fabric", System.in, 111740), device);
28             long end = System.currentTimeMillis();
29             Log.info(Demo.class, "finished in " + ((end-begin)/1000) + "s");
30             Thread.sleep(1000);
31             Log.info(Demo.class, "issuing command");
32
33             //at40k.iob_top(2, true).oe(false);
34             //at40k.iob_top(2, false).oe(false);
35             //at40k.iob_top(1, true).oe(false);
36
37             // this command confirmed to turn *on* led0
38             //at40k.iob_top(1, false).output(0);
39             /*
40             for(int i=0; i<20; i++) {
41                 at40k.iob_bot(i, false).output(0);
42                 at40k.iob_bot(i, true).output(0);
43             }
44             */
45
46             //System.out.println("tick");
47                 //Thread.sleep(3000);
48                 //System.out.println("tick");
49                 //at40k.cell(0x01, 0x17).xlut((byte)0x);
50
51             /*
52             System.out.println(Integer.toString(0xff & at40k.cell(0x01, 0x17).xlut(), 16));
53             System.out.println(Integer.toString(0xff & at40k.cell(0x01, 0x17).ylut(), 16));
54             at40k.cell(0x01, 0x17).ylut((byte)0xff);
55             */
56
57             //at40k.cell(0x01, 0x17).wi(L1);
58             /*
59             System.out.println("a: " + at40k.new SectorWire(true, 0, 4, 0x17).driverRight());
60             System.out.println("b: " + at40k.new SectorWire(true, 1, 4, 0x17).driverRight());
61             Fpslic.SectorWire h0p0 = at40k.new SectorWire(true, 0, 0, 0x17);
62             Fpslic.SectorWire h0p1 = at40k.new SectorWire(true, 1, 0, 0x17);
63             Fpslic.SectorWire h0p2 = at40k.new SectorWire(true, 2, 0, 0x17);
64             Fpslic.SectorWire h4p0 = at40k.new SectorWire(true, 0, 4, 0x17);
65             Fpslic.SectorWire h4p1 = at40k.new SectorWire(true, 1, 4, 0x17);
66             Fpslic.SectorWire h4p2 = at40k.new SectorWire(true, 2, 4, 0x17);
67
68             //h4p1.drives(h0p1, false);
69             //at40k.cell(0x04, 0x17).out(L1, false);
70             //at40k.cell(0x04, 0x17).h(L0, false);
71
72             for(int plane=0; plane<5; plane++) {
73                 at40k.new SectorWire(true, plane,     4, 0x17).drives(at40k.new SectorWire(true, plane,     0, 0x17), false);
74                 at40k.cell(0x04, 0x17).out(plane, false);
75                 at40k.cell(0x04, 0x17).h(plane, false);
76                 at40k.cell(0x01, 0x17).h(plane, false);
77             }
78             try { Thread.sleep(2000); } catch (Exception e) { }
79
80             int plane=0;
81             at40k.new SectorWire(true, plane, 4, 0x17).drives(at40k.new SectorWire(true, plane, 0, 0x17), true);
82             at40k.cell(0x04, 0x17).out(plane, true);
83             at40k.cell(0x04, 0x17).h(plane, true);
84             at40k.cell(0x01, 0x17).h(plane, true);
85             at40k.cell(0x01, 0x17).wi(plane);
86
87             */
88
89             /*
90             System.out.println("xlut is " + hex(at40k.cell(0x04, 0x17).xlut()));
91             System.out.println("ylut is " + hex(at40k.cell(0x04, 0x17).ylut()));
92             Fpslic.Cell cell = at40k.cell(0x04, 0x17);
93             //cell.xlut(0xff);
94             //cell.f(false);
95             System.out.println(cell.c());
96             cell.c(YLUT);
97             cell.ylut(0x4D);
98             cell.xlut(0x00);
99
100             cell.b(false);
101             cell.f(false);
102             //cell.t(false, false, true);
103             cell.t(false, true, false);
104             cell.out(L3, true);
105             cell.wi(L3);
106
107             cell.yo(false);
108             cell.h(L0, false);
109             cell.h(L1, false);
110             cell.h(L2, false);
111             cell.h(L3, false);
112             cell.h(L4, false);
113
114             for(int i=3; i>=1; i--) {
115                 at40k.cell(i, 0x17).yi(EAST);
116                 at40k.cell(i, 0x17).ylut(0x55);
117                 at40k.cell(i, 0x17).yo(false);
118             }
119             */
120
121             //System.out.println("reading port status: " + Integer.toString(device.readBus() & 0xff, 16));
122
123
124             // blank these out
125             /*
126             at40k.cell(23, 8).ylut(0xff);
127             at40k.cell(23, 11).ylut(0xff);
128             at40k.iob_right(8, true).enableOutput();
129             at40k.iob_right(11, true).enableOutput();
130             */
131             //for(int x=4;  x<=22; x++) swap(at40k.cell(x, 22), NW, NORTH);
132
133
134             // entry cell: just copy X->X Y->Y
135             //at40k.cell(4,23).b(false);
136             //at40k.cell(4,23).yo(false);
137             //at40k.cell(4,23).ylut(at40k.cell(4,23).xlut());
138             //at40k.cell(4,23).xo(false);
139             /*
140             at40k.cell(4,23).xlut(0x55);
141             at40k.cell(4,23).ylut(0x55);
142             */
143             /*
144             at40k.cell(4,23).xlut(0x71);
145             at40k.cell(4,23).ylut(0x44);
146             at40k.cell(4,23).c(YLUT);
147             at40k.cell(4,23).f(false);
148             at40k.cell(4,23).t(false, false, true);
149             */
150
151             //for(int x=6;  x<=23; x++) copy(at40k.cell(x, 23), NW, WEST);  // top row copies to the right
152             /*
153             copy(at40k.cell(5, 22), NW, NORTH);
154             for(int x=6;  x<=22; x++) copy(at40k.cell(x, 22), NW, WEST);  // second top row copies to the right
155             //for(int y=22; y>=10; y--) copy(at40k.cell(23, y), NW, NORTH); // right edge copies down
156             for(int y=21; y>=9;  y--) copy(at40k.cell(22, y), NW, NORTH); // second right edge copies down
157             copy(at40k.cell(23, 9), NW, WEST);                            // second output
158             */
159             /*
160             handshaker(at40k.cell(4,23));
161             at40k.cell(4,23).xi(NW);
162             at40k.cell(4,23).yi(SOUTH);
163
164             //handshaker(at40k.cell(5,23));
165             //at40k.cell(5,23).yi(NORTH);
166
167             at40k.cell(5,23).yi(NORTH);
168             at40k.cell(5,23).xlut(0x55);
169             at40k.cell(5,23).xi(SW);
170             at40k.cell(5,23).ylut(0x55);
171             at40k.cell(5,22).yi(NORTH);
172             at40k.cell(5,22).xlut(0x55);
173
174             bounce(at40k.cell(4,22));
175
176             // cell southeast of entry cell
177             at40k.cell(3,22).xi(NE);      // NW->xin
178             at40k.cell(3,22).ylut(0x33);  // xin->y
179             at40k.cell(3,22).yo(false);   // y->yout
180             copy(at40k.cell(3, 21), NW, NORTH);  // second top row copies to the right
181             copy(at40k.cell(4, 21), NW, EAST);  // second top row copies to the right
182             copy(at40k.cell(5, 21), NW, EAST);  // second top row copies to the right
183             copy(at40k.cell(6, 21), NW, EAST);  // second top row copies to the right
184             copy(at40k.cell(6, 22), NW, SOUTH);  // second top row copies to the right
185             */
186             /*
187             at40k.cell(05,22).xlut(0xff);
188             at40k.cell(05,22).ylut(0xff);
189             at40k.cell(05,22).c(XLUT);
190             at40k.cell(05,22).f(false);
191             at40k.cell(05,22).b(false);
192             at40k.cell(05,22).oe(NONE);
193             at40k.cell(05,22).v(L3, true);
194             at40k.cell(05,22).out(L3, true);
195             */
196             /*
197             at40k.cell(4,23).ylut(~0xCC);
198             at40k.cell(4,23).xlut(~0xAA);
199             at40k.cell(5,23).ylut(~0xAA);
200             at40k.cell(5,23).xlut(~0xAA);
201             for(int i=6; i<PIPELEN+2; i++) {
202                 at40k.cell(i, 23).ylut(0xAA);
203                 at40k.cell(i, 23).xlut(0xCC);
204                 at40k.cell(i, 23).yi(WEST);
205             }
206             */
207
208             /* LAST
209             System.out.println("doit");
210             if (mullers) doitx(at40k, device);
211             //System.out.println("counter");
212             //counter(at40k, device);
213
214             at40k.cell(21,15).yi(WEST);
215             at40k.cell(21,15).ylut(0xAA);
216
217             at40k.cell(22,15).yi(WEST);
218             at40k.cell(22,15).ylut(0xAA);
219             */
220             at40k.cell(23,15).h(3, true);
221             at40k.cell(23,15).yi(L3);
222             at40k.cell(23,15).ylut(0xAA);
223             at40k.iob_right(15, true).enableOutput(WEST);
224
225
226             Fpslic.Cell c = at40k.cell(10,10);
227             c.ylut(~LUT_SELF);
228             c.xlut(LUT_Z);
229             c.yi(WEST);
230             c.c(YLUT);
231             c.f(false);
232             c.t(TMUX_FB);
233             copy(c.west(), EAST, NW);
234             copy(c.west().north().west(), SE, SE);
235
236             c = c.east();
237             c.ylut(~LUT_SELF);
238             c.xlut(LUT_Z);
239             c.yi(EAST);
240             c.c(YLUT);
241             c.f(false);
242             c.t(TMUX_FB);
243             copy(c.east(), WEST, SE);
244             copy(c.east().south().east(), NW, NW);
245
246             c = c.north();
247             copy(c.north(), SOUTH, SOUTH);
248             c.xlut((LUT_SELF & ~LUT_OTHER) | LUT_Z);
249             c.ylut(LUT_Z);
250             c.yi(SOUTH);
251             c.c(XLUT);
252             c.xi(SW);
253             c.wi(L4);
254             c.f(false);
255             c.t(TMUX_W_AND_FB);
256             c.v(L4, false);
257             c.h(L4, true);
258             c.v(L2, false);
259             c.h(L2, true);
260
261             c = c.west();
262             copy(c.north(), SOUTH, SOUTH);
263             c.xlut((LUT_SELF & ~LUT_OTHER) | LUT_Z);
264             c.ylut(~LUT_Z);
265             c.yi(SOUTH);
266             c.xi(SE);
267             c.c(XLUT);
268             c.wi(L4);
269             c.f(false);
270             c.t(TMUX_W_AND_FB);
271             c.v(L4, false);
272             c.h(L4, true);
273             c.v(L2, false);
274             c.h(L2, true);
275
276             c = c.west();
277             c.v(L4, false);
278             c.h(L4, true);
279             c.out(L4, true);
280             c.f(false);
281             c.b(false);
282             c.oe(NONE);
283             c.c(YLUT);
284             c.hwire(L4).west().drives(c.hwire(L4), false);
285             c.hwire(L4).east().drives(c.hwire(L4), false);
286
287             c = c.south();
288             c = c.south();
289             c.v(L4, false);
290             c.h(L4, true);
291             c.out(L4, true);
292             c.f(false);
293             c.b(false);
294             c.oe(NONE);
295             c.c(YLUT);
296             c.hwire(L4).west().drives(c.hwire(L4), false);
297             c.hwire(L4).east().drives(c.hwire(L4), false);
298
299             c = c.east();
300             c = c.east();
301             copy(c.south(), NORTH, NORTH);
302             c.xlut(((~LUT_SELF) & (~LUT_OTHER)) | LUT_Z);
303             c.ylut(LUT_Z);
304             c.yi(NORTH);
305             c.c(XLUT);
306             c.xi(NW);
307             c.wi(L4);
308             c.f(false);
309             c.t(TMUX_W_AND_FB);
310             c.v(L4, false);
311             c.h(L4, true);
312             c.v(L2, false);
313             c.h(L2, true);
314
315             c = c.west();
316             copy(c.south(), NORTH, NORTH);
317             c.xlut((LUT_SELF & LUT_OTHER) | LUT_Z);
318             c.ylut(LUT_Z);
319             c.yi(NORTH);
320             c.xi(NE);
321             c.c(XLUT);
322             c.wi(L4);
323             c.f(false);
324             c.t(TMUX_W_AND_FB);
325             c.v(L4, false);
326             c.h(L4, true);
327             c.v(L2, false);
328             c.h(L2, true);
329
330
331             // catch a rising transition
332             /*
333             c = c.west();
334             c.v(L2, false);
335             c.h(L2, true);
336             c.out(L2, true);
337             c.f(false);
338             c.b(false);
339             c.oe(NONE);
340             c.c(YLUT);
341             */
342             c.hwire(L2).west().drives(c.hwire(L2), false);
343             c.hwire(L2).east().drives(c.hwire(L2), false);
344
345
346
347             //////
348
349             c = at40k.cell(20,20);
350             c.yi(WEST);
351             c.ylut(LUT_SELF);
352             c.c(YLUT);
353             c.oe(H4);
354             c.h(L4, true);
355             c.b(false);
356             c.f(false);
357             c.out(L4);
358
359             c = at40k.cell(21,20);
360             c.c(YLUT);
361             c.oe(NONE);
362             c.h(L4, true);
363             c.b(false);
364             c.f(false);
365
366
367             c = at40k.cell(8,8);
368             c.f(true);
369             c.b(true);
370             c.xo(true);
371             c.xi(NE);
372             c.zi(L3);
373             c.wi(L0);
374             c.yi(NORTH);
375             c.oe(H4);
376             c.h(L0, true);
377             c.h(L2, true);
378             c.h(L4, true);
379             c.v(L1, true);
380             c.v(L3, true);
381             c.out(L0, true);
382             c.out(L1, true);
383             c.out(L2, true);
384             c.out(L3, true);
385             c.out(L4, true);
386             c.xo(true);
387             c.yo(true);
388             c.c(ZMUX);
389
390             at40k.cell(9,10).xo(true);
391             at40k.cell(9,10).yo(true);
392             at40k.cell(9,10).c(YLUT);
393             at40k.cell(9,10).b(false);
394
395             //for(int x=5; x<PIPELEN; x++) {
396             //at40k.cell(x,23).hwire(L0).drives(at40k.cell(x,23).hwire(L0).east());
397             //}
398
399             /*
400             at40k.cell(22,11).ylut(0xff);
401             at40k.cell(23,11).yi(L3);
402             //at40k.cell(23,11).yi(WEST);
403             //at40k.cell(23,11).xi(L1);
404             at40k.cell(23,11).ylut(0xAA);
405             at40k.iob_right(11, true).enableOutput(WEST);
406             at40k.cell(23,11).v(L3, true);
407             at40k.cell(23,11).yo(false);
408             //at40k.flush();
409             */
410             int vx=04;
411             int vv=23;
412             /*
413             System.out.println("correct: " + at40k.cell(19,15).hwire(L3) + " drives " + at40k.cell(20,15).hwire(L3));
414             System.out.println("correct: " + at40k.cell(15,15).hwire(L3) + " drives " + at40k.cell(19,15).hwire(L3));
415             System.out.println("correct: " + at40k.cell(11,15).hwire(L3) + " drives " + at40k.cell(15,15).hwire(L3));
416             System.out.println("correct: " + at40k.cell(07,15).hwire(L3) + " drives " + at40k.cell(11,15).hwire(L3));
417
418             at40k.cell(19,15).hwire(L3).drives(at40k.cell(20,15).hwire(L3), true);
419             at40k.cell(15,15).hwire(L3).drives(at40k.cell(19,15).hwire(L3), true);
420             at40k.cell(11,15).hwire(L3).drives(at40k.cell(15,15).hwire(L3), true);
421             at40k.cell(07,15).hwire(L3).drives(at40k.cell(11,15).hwire(L3), true);
422             */
423             //at40k.cell(05,vv).xlut(0xff);
424             //at40k.cell(05,vv).ylut(0xff);
425             /*
426             at40k.cell(vx,vv).c(YLUT);
427             at40k.cell(vx,vv).f(false);
428             at40k.cell(vx,vv).b(false);
429             at40k.cell(vx,vv).oe(NONE);
430             at40k.cell(vx,vv).v(L3, true);
431             at40k.cell(vx,vv).out(L3, true);
432             */
433             /*
434             at40k.cell(vx,15).v(L3, true);
435             at40k.cell(vx,15).h(L3, true);
436             at40k.cell(vx,19).vwire(L3).drives(at40k.cell(vx,15).vwire(L3), true);
437             at40k.cell(vx,23).vwire(L3).drives(at40k.cell(vx,19).vwire(L3), true);
438             */
439
440             //at40k.cell(5,23).ylut(0x00);
441             //at40k.cell(6,22).ylut(0xff);
442             //at40k.cell(22,11).ylut(0xff);
443             /*
444             Fpslic.Cell cell = at40k.cell(4, 16);
445             cell.xlut(0xff);
446             cell.ylut(0xff);
447             cell.b(false);
448             cell.f(false);
449             cell.c(XLUT);
450             cell.h(L3, true);
451             cell.v(L3, true);
452             cell.out(L3, true);
453             cell.oe(NONE);
454             */
455             //scan(at40k, cell, YLUT, true);
456             //scan(at40k, cell, YLUT, false);
457
458             //device.scanFPGA(true);
459
460             at40k.cell(10,10).f(true);
461             at40k.cell(10,10).c(ZMUX);
462
463             at40k.cell(8,7).xlut(LUT_SELF);
464             at40k.cell(8,7).xi(NW);
465
466             at40k.cell(7,8).xlut(LUT_SELF & LUT_Z);
467             at40k.cell(7,8).xi(SE);
468             at40k.cell(7,8).c(XLUT);
469             at40k.cell(7,8).f(false);
470             at40k.cell(7,8).b(false);
471             at40k.cell(7,8).t(TMUX_FB);
472             at40k.cell(7,8).xo(false);
473             System.out.println(at40k.cell(7,8).fb_relevant());
474
475             at40k.cell(6,13).xi(SE);
476             at40k.cell(6,13).c(ZMUX);
477             at40k.cell(6,13).xlut(LUT_SELF);
478             at40k.cell(6,13).ylut(LUT_OTHER);
479             at40k.cell(6,13).xo(false);
480             at40k.cell(6,13).yo(false);
481             at40k.cell(7,12).xi(SE);
482
483             for(int i=0; i<24; i++) {
484                 at40k.iob_bot(i, true).enableOutput(NORTH);
485                 at40k.iob_bot(i, false).enableOutput(NW);
486                 at40k.cell(i, 0).xlut(0xff);
487                 at40k.cell(i, 0).ylut(0xff);
488             }
489
490             device.flush();
491
492             Gui vis = new Gui(at40k, device);
493             Frame fr = new Frame();
494             fr.addKeyListener(vis);
495             fr.setLayout(new BorderLayout());
496             fr.add(vis, BorderLayout.CENTER);
497             fr.pack();
498             fr.setSize(900, 900);
499             vis.repaint();
500             fr.repaint();
501             fr.show();
502             synchronized(Demo.class) { Demo.class.wait(); }
503
504
505
506             /*
507             Visualizer v = new Visualizer(at40k, device);
508             v.show();
509             v.setSize(1380, 1080);
510             Fpslic.Cell cell = at40k.cell(4, 23);
511             */
512             //Image img = v.createImage(v.getWidth(), v.getHeight());
513             /*
514             int x = 1;
515             int y = 14;
516             cell = at40k.cell(x,y);
517             scan(at40k, cell, YLUT, true);
518             cell.c(YLUT);
519             cell.b(false);
520             cell.f(false);
521             cell.oe(NONE);
522             cell.ylut(0xff);
523             */
524             //int x = 5;
525             //int y = 11;
526
527             //selfTest(device, at40k, v);
528             //System.out.println("save: " + FtdiBoard.save + " of " + (FtdiBoard.saveof*5));
529
530             at40k.iob_top(0, true).enableInput();
531             copy(at40k.cell(0, 23), NORTH, NORTH);
532             at40k.iob_bot(0, true).enableOutput(NORTH);
533
534             for(int i=0; i<10000; i++) {
535                 //v.refresh();
536                 try { Thread.sleep(100); } catch (Exception e) { }
537             }
538             //cell.ylut(0x09);
539
540             //at40k.cell(0x01, 0x17).h(0, false);
541             //at40k.cell(0x01, 0x17).xi(NE);
542             //at40k.cell(0x01, 0x17).ylut((byte)0x55);
543
544             //at40k.cell(0x04, 0x17).xlut((byte)0x10);
545             //at40k.cell(0x04, 0x17).ylut((byte)0x10);
546             //at40k.cell(0x04, 0x17).yo(false);
547             //at40k.cell(0x04, 0x17).xo();
548
549             /*
550             at40k.cell(0x01, 0x17).xi(L0);
551             at40k.cell(0x01, 0x17).h(L0, true);
552             */
553             /*
554             at40k.cell(0x03, 0x17).xlut((byte)0x55);
555             at40k.cell(0x03, 0x17).ylut((byte)0x55);
556             at40k.cell(0x03, 0x17).yi(EAST);
557             at40k.cell(0x03, 0x17).ylut((byte)0x55);
558             at40k.cell(0x03, 0x17).yo(true);
559
560             at40k.cell(0x03, 0x17).f(false);
561             at40k.cell(0x03, 0x17).c(XLUT);
562             at40k.cell(0x03, 0x17).oe(NONE);
563             at40k.cell(0x03, 0x17).out(L0, true);
564
565             at40k.cell(0x02, 0x17).yi(EAST);
566             at40k.cell(0x02, 0x17).ylut((byte)0x55);
567             at40k.cell(0x02, 0x17).yo(false);
568
569             at40k.cell(0x01, 0x17).yi(EAST);
570             at40k.cell(0x01, 0x17).ylut((byte)0x55);
571             at40k.cell(0x01, 0x17).yo(false);
572
573             at40k.cell(0x01, 0x17).h(L0, true);
574             at40k.cell(0x01, 0x17).v(L0, false);
575             */
576             //at40k.cell(0x01, 0x17).yi(L0);
577             //at40k.cell(0x01, 0x17).xi(L0);
578             //at40k.cell(0x01, 0x17).ylut((byte)0x33);
579
580             /*
581             at40k.cell(0x03, 0x17).h(L0, true);
582             at40k.cell(0x03, 0x17).out(L0, true);
583             at40k.cell(0x03, 0x17).c(XLUT);
584             at40k.cell(0x03, 0x17).f(false);
585             */
586             /*
587             at40k.cell(0x01, 0x17).xin(4);
588             at40k.cell(0x01, 0x17).yin(4);
589             at40k.cell(0x01, 0x16).ylut((byte)0x00);
590             device.mode4(2, 0x17, 0x01, 0);
591
592             for(int i=0; i<10; i++) {
593                 Thread.sleep(3000);
594                 System.out.println("tick");
595                 //at40k.cell(0x01, 0x17).xlut((byte)0xFF);
596                 at40k.cell(0x00, 0x17).ylut((byte)0x00);
597                 device.flush();
598                 Thread.sleep(3000);
599                 System.out.println("tick");
600                 //at40k.cell(0x01, 0x17).xlut((byte)0x00);
601                 at40k.cell(0x00, 0x17).ylut((byte)0xFF);
602                 device.flush();
603             }
604             */
605
606
607             /*
608             at40k.iob_top(0, true).output(0);
609             at40k.iob_top(0, true).oe(false);
610             at40k.iob_top(0, true).pullup();
611             device.flush();
612             Thread.sleep(3000);
613
614             Log.info(Demo.class, "issuing command");
615             at40k.iob_top(1, true).pulldown();
616             device.flush();
617             */
618             Log.info(Demo.class, "done");
619             System.exit(0);
620         } catch (Exception e) { e.printStackTrace(); }
621     }
622
623     public static void scan(Fpslic dev, Fpslic.Cell cell, int source, boolean setup) {
624         if (setup) {
625             if (source != NONE) cell.c(source);
626             if (cell.b()) cell.b(false);
627             if (cell.f()) cell.f(false);
628         }
629         if (cell.out(L3)!=setup) cell.out(L3, setup);
630         if (cell.vx(L3)!=setup) cell.v(L3, setup);
631
632         Fpslic.SectorWire sw = cell.vwire(L3);
633         //System.out.println("wire is: " + sw);
634
635         if (sw.row > (12 & ~0x3) && sw.north()!=null && sw.north().drives(sw))
636             sw.north().drives(sw, false);
637         while(sw.row > (12 & ~0x3) && sw.south() != null) {
638             //System.out.println(sw + " -> " + sw.south());
639             if (sw.drives(sw.south())!=setup) sw.drives(sw.south(), setup);
640             sw = sw.south();
641         }
642         if (sw.row < (12 & ~0x3) && sw.south() != null && sw.south().drives(sw))
643             sw.north().drives(sw, false);
644         while(sw.row < (12 & ~0x3) && sw.north() != null) {
645             //System.out.println(sw + " -> " + sw.north());
646             if (sw.drives(sw.north())!=setup) sw.drives(sw.north(), setup);
647             sw = sw.north();
648         }
649
650         //cell = dev.cell(19, 15);
651         cell = dev.cell(cell.col, 15);
652         /*
653         System.out.println("cell is " + cell);
654         cell.xlut(0xff);
655         cell.ylut(0xff);
656         cell.b(false);
657         cell.f(false);
658         cell.c(XLUT);
659         cell.out(L3, true);
660         cell.oe(NONE);
661         */
662         if (cell.hx(L3) != setup) cell.h(L3, setup);
663         if (cell.vx(L3) != setup) cell.v(L3, setup);
664         sw = cell.hwire(L3);
665
666         if (sw.west()!=null && sw.west().drives(sw)) { sw.west().drives(sw, false); }
667         while(sw.east() != null) {
668             //System.out.println(sw + " -> " + sw.east());
669             if (sw.drives(sw.east())!=setup) sw.drives(sw.east(), setup);
670             sw = sw.east();
671         }
672
673     }
674
675     public static void copy(Fpslic.Cell c, int xdir, int ydir) {
676         switch(xdir) {
677             case NW: case NE: case SW: case SE: {
678                 c.xi(xdir);
679                 c.xlut(LUT_SELF);
680                 break;
681             }
682             case NORTH: case SOUTH: case EAST: case WEST: {
683                 c.yi(xdir);
684                 c.xlut(LUT_OTHER);
685                 break;
686             }
687             case NONE: break;
688             default: throw new Error();
689         }
690         switch(ydir) {
691             case NW: case NE: case SW: case SE: {
692                 c.xi(ydir);
693                 c.ylut(LUT_OTHER);
694                 break;
695             }
696             case NORTH: case SOUTH: case EAST: case WEST: {
697                 c.yi(ydir);
698                 c.ylut(LUT_SELF);
699                 break;
700             }
701             case NONE: break;
702             default: throw new Error();
703         }
704         c.xo(false);
705         c.yo(false);
706     }
707     public static String hex(int x) {
708         return Long.toString(x & 0xffffffffL, 16);
709     }
710
711     public static void handshaker(Fpslic.Cell cell) {
712         cell.xlut(0x22);
713         cell.ylut(0x71);
714         cell.c(XLUT);
715         cell.f(false);
716         cell.t(false, false, true);
717     }
718
719
720     private static String pad(int i, String s) { if (s.length()>i) return s; return "0"+pad((i-1),s); }
721     public static String bin8(byte b) {
722         int n = b & 0xff;
723         String ret = "";
724         for(int i=7; i>=0; i--)
725             ret += (n & (1<<i))==0 ? "0" : "1";
726         return ret;
727     }
728
729     public static void bounce(Fpslic.Cell cell, int xi, int yi) {
730         cell.xlut((byte)0xCC);
731         cell.ylut((byte)0xCC);
732         cell.xi(xi);
733         cell.yi(yi);
734         cell.xo(false);
735         cell.yo(false);
736     }
737     public static void muller(Fpslic.Cell cell, int xi, int yi) {
738         cell.ylut(0xB2);
739         cell.c(YLUT);
740         cell.f(false);
741         cell.t(false, false, true);
742         cell.xi(xi);
743         cell.yi(yi);
744         cell.yo(false);
745         cell.xo(false);
746     }
747
748     /** watches for a rising/falling edge on Yin, emits a pulse on Xout */
749     public static void pulse_detect(Fpslic.Cell c, int in, boolean falling) {
750         c.ylut(0x00);
751         c.xlut(0x00);
752         switch(in) {
753             case NW: case NE: case SW: case SE: {
754                 c.xi(in);
755                 loopback(c, XLUT);
756                 if (!falling) c.ylut(FpslicUtil.lutSwap(0x0C)); /* x & !z */
757                 else          c.ylut(FpslicUtil.lutSwap(0x30)); /* !x & z */
758                 c.xlut(LUT_SELF);
759                 break;
760             }
761             case NORTH: case SOUTH: case EAST: case WEST: {
762                 c.yi(in);
763                 loopback(c, YLUT);
764                 if (!falling) c.xlut(0x0C); /* y & !z */
765                 else          c.xlut(0x30); /* !y & z */
766                 c.ylut(LUT_SELF);
767                 break;
768             }
769             default: throw new Error();
770         }
771     }
772
773     /** watches for a pulse on Xin, copies value of Yin */
774     public static void pulse_copy(Fpslic.Cell cell, int xi, int yi, boolean invert) {
775         loopback(cell, YLUT);
776         if (!invert) cell.ylut(0xB8);   /* yo = x ?  yi : z => 1011 1000 */
777         else         cell.ylut(0x74);   /* yo = x ? !yi : z => 0111 0100 */
778         if (!invert) cell.xlut(FpslicUtil.lutSwap(0xB8));   /* yo = x ?  yi : z => 1011 1000 */
779         else         cell.xlut(FpslicUtil.lutSwap(0x74));   /* yo = x ? !yi : z => 0111 0100 */
780         cell.xi(xi);
781         cell.yi(yi);
782     }
783
784     public static void loopback(Fpslic.Cell cell, int cin) {
785         cell.f(false);
786         cell.b(false);
787         cell.t(false, false, true);
788         cell.yo(false);
789         cell.xo(false);
790         cell.c(cin);
791     }
792
793     public static void doit(Fpslic at40k, FtdiBoard device) throws Exception {
794
795         Fpslic.Cell led = at40k.cell(1, 23);
796         led.v(L2, true);
797         led.h(L2, false);
798         led.yi(L2);
799         led.ylut(~LUT_SELF);
800         led.xlut(LUT_SELF);
801         led.yo(false);
802
803         Fpslic.Cell c = at40k.cell(1, 22);
804         c.out(L1, true);
805         c.out(L0, true);
806         c.oe(V4);
807         c.ylut(0xff);
808         c.h(L1, true);
809         c.h(L0, false);
810
811         c.v(L0, /*false*/true);
812
813         c.v(L1, true);
814         c.f(false);
815         c.b(false);
816         c.c(YLUT);
817
818         for(int i=0; i<4; i++) at40k.cell(i, 20).h(L0, false);
819         Fpslic.Cell z = at40k.cell(1, 20);
820         z.out(L0, true);
821         z.xlut(0xff);
822         z.c(XLUT);
823         z.yi(L0);
824         z.ylut(~LUT_SELF);
825         z.v(L0, true);
826         //z.h(L0, true);
827         z.h(L0, false);
828         z.f(false);
829         z.b(false);
830         z.hwire(L0).east().drives(z.hwire(L0), false);
831         z.hwire(L1).east().drives(z.hwire(L1), false);
832         z.vwire(L0).south().drives(z.vwire(L0), false);
833         z.vwire(L1).south().drives(z.vwire(L1), false);
834         z.oe(H4);
835
836         z = at40k.cell(0, 20);
837         z.oe(NONE);
838         z.out(L0, true);
839         z.out(L1, true);
840         z.out(L2, true);
841         //z.out(L3, true);
842         z.out(L4, true);
843         z.h(L0, true);
844         z.h(L1, true);
845         z.h(L2, true);
846         //z.h(L3, true);
847         z.h(L4, true);
848         z.f(false);
849         z.b(false);
850         z.yi(EAST);
851         z.ylut(LUT_SELF);
852         z.c(YLUT);
853
854         for(int y=20; y<=22; y++)
855             for(int x=2; x<=5; x++) {
856                 c = at40k.cell(x, y);
857                 copy(c, NW, WEST);
858             }
859
860         //c = at40k.cell(2, 22);
861         //c.h(L0, true);
862         //c.yi(L0);
863
864         c = at40k.cell(1, 21);
865         c.v(L0, true);
866         c.v(L2, true);
867         c.yi(L0);
868         c.out(L2, true);
869         c.ylut(LUT_SELF);
870         c.c(YLUT);
871         c.b(false);
872         c.f(false);
873         c.oe(NONE);
874         c.yo(false);
875
876         
877
878         c = at40k.cell(13, 22);
879         c.xlut(LUT_OTHER | 0xF0);
880         c.c(XLUT);
881         c.t(false, false, true);
882         c.b(false);
883         c.f(false);
884         c.ylut(0xF0);
885         c.yi(EAST);
886         c.yo(false);
887         /*
888         // this gate detects a rising edge on its Xin (delayed copy on Yin); when viewed, it inverts its state
889         c = at40k.cell(14, 22);
890         c.ylut(0x00);
891         c.c(XLUT);
892         c.f(false);
893         c.b(false);
894         c.t(false, false, true);
895         c.xi(SE);
896         c.yi(SOUTH);
897         c.yo(false);
898         c.xo(false);
899         c.ylut(0xA6); // (x & !z) ? ~y : y
900         c.xlut(LUT_SELF); 
901
902         c = at40k.cell(14, 20);
903         c.ylut(LUT_OTHER);
904         c.xi(NE);
905         c = at40k.cell(14, 21);
906         c.ylut(LUT_SELF);
907         c.xi(SOUTH);
908
909         c = at40k.cell(13, 22);
910         c.xlut(0x00);
911         c.xlut(LUT_OTHER);// | 0xF0);
912 */
913         //c = at40k.cell(13, 22);
914         //copy(c, NW, EAST);
915         /*
916         c.ylut(0x00);
917         c.c(YLUT);
918         c.f(false);
919         c.b(false);
920         c.t(false, false, true);
921         c.xi(SE);
922         c.yi(NORTH);
923         c.yo(false);
924         c.xo(false);
925         c.ylut(0x54);  // (x || z) & !y
926         */
927
928         /*        
929         c = at40k.cell(2, 21);
930         c.ylut(0x00);
931         c.c(YLUT);
932         c.f(false);
933         c.b(false);
934         c.t(false, false, true);
935         c.xi(SE);
936         c.yi(WEST);
937         c.yo(false);
938         c.xo(false);
939         c.ylut(0xE8);
940  
941        //at40k.cell(2, 21).xlut(0xF0);
942
943         at40k.cell(3, 22).ylut(LUT_OTHER);
944         at40k.cell(3, 22).xi(SW);
945         */
946         //at40k.iob_top(5, true).enableOutput(SOUTH);
947         //at40k.iob_top(5, false).enableOutput(SE);
948     }
949
950     public static int yofs = mullers ? 19 : 22;
951     public static void counter(Fpslic at40k, FtdiBoard device) throws Exception {
952         // watch for rising edge from south, emit pulse on Xout (to NE)
953         //copy(at40k.cell(16,23), SW, WEST);
954         
955         for(int x=22; x>=1; x-=2) {
956             pulse_detect(at40k.cell(x, yofs), SE,      false);
957             pulse_detect(at40k.cell(x, yofs-1), EAST,    true);
958             pulse_copy(at40k.cell(x-1, yofs), SE, SOUTH, false);
959             pulse_copy(at40k.cell(x-1, yofs-1), NE, NORTH, true);
960
961             //pulse_detect(at40k.cell(15, 22), NORTH, false);
962             //pulse_detect(at40k.cell(16, 22), NW,    true);
963             //pulse_copy(at40k.cell(16, 21), NW, WEST, false);
964             //pulse_copy(at40k.cell(15, 21), NE, EAST, true);
965         }
966         for(int x=23; x>1; x-=2) {
967             pulse_detect(at40k.cell(x-1, yofs-2), SW,    false);
968             pulse_detect(at40k.cell(x-1, yofs-3), WEST,  true);
969             pulse_copy(at40k.cell(x, yofs-2), SW, SOUTH, false);
970             pulse_copy(at40k.cell(x, yofs-3), NW, NORTH, true);
971
972             //pulse_detect(at40k.cell(15, 22), NORTH, false);
973             //pulse_detect(at40k.cell(16, 22), NW,    true);
974             //pulse_copy(at40k.cell(16, 21), NW, WEST, false);
975             //pulse_copy(at40k.cell(15, 21), NE, EAST, true);
976         }
977         copy(at40k.cell(1, yofs-2), SOUTH, SOUTH);
978         copy(at40k.cell(1, yofs-3), NORTH, NORTH);
979         at40k.cell(1, yofs-3).ylut(~at40k.cell(1, yofs-3).ylut());
980         at40k.cell(1, yofs-3).xlut(~at40k.cell(1, yofs-3).xlut());
981
982         copy(at40k.cell(23, yofs), SOUTH, SOUTH);
983         copy(at40k.cell(23, yofs-1), SOUTH, SOUTH);
984
985         for(int i=23; i>yofs; i--) copy(at40k.cell(1, i), SOUTH, SOUTH);
986
987         //at40k.iob_top(1, true).slew(SLOW);
988         //at40k.iob_top(1, false).slew(SLOW);
989
990     }
991
992     public static void fill(Fpslic at40k, FtdiBoard device, int num) throws Exception {
993         //muller(at40k.cell(PIPELEN,22), NE, WEST);
994         Fpslic.Cell a = at40k.cell(10,22);
995         Fpslic.Cell b = at40k.cell(11,22);
996         a.ylut(0x00);
997         for(int i=0; i<num; i++) {
998             //System.out.println(i);
999             b.lut(0xff, 0xff);
1000             device.flush();
1001             try { Thread.sleep(1); } catch (Exception e) { }
1002             b.lut(0x00, 0x00);
1003             device.flush();
1004             try { Thread.sleep(1); } catch (Exception e) { }
1005         }
1006         b.ylut(0xB2);
1007         a.ylut(0xB2);
1008     }
1009
1010     public static void drain(Fpslic at40k, FtdiBoard device) throws Exception {
1011         Fpslic.Cell a = at40k.cell(10,22);
1012         Fpslic.Cell b = at40k.cell(11,22);
1013         a.lut(0x00, 0x00);
1014         b.lut(0x00, 0x00);
1015         for(int i=0; i<30; i++) {
1016             //System.out.println(i);
1017             a.lut(0xff, 0xff);
1018             device.flush();
1019             try { Thread.sleep(1); } catch (Exception e) { }
1020             a.lut(0x00, 0x00);
1021             device.flush();
1022             try { Thread.sleep(1); } catch (Exception e) { }
1023         }
1024         b.ylut(0xB2);
1025         a.ylut(0xB2);
1026     }
1027
1028     public static void doitx(Fpslic at40k, FtdiBoard device) throws Exception {
1029         for(int i=5; i<PIPELEN+1; i++) bounce(at40k.cell(i, 23), SE,                     SOUTH);
1030         for(int x=5; x<PIPELEN;   x++) muller(at40k.cell(x, 22), x==PIPELEN-1 ? SE : NE, WEST);
1031         
1032         bounce(at40k.cell(PIPELEN,  21), NW, WEST);
1033         
1034         for(int x=5; x<PIPELEN;   x++) muller(at40k.cell(x, 21), SW,                     x==PIPELEN-1 ? NORTH : EAST);
1035         for(int x=4; x<PIPELEN+1; x++) bounce(at40k.cell(x, 20), NW,                     NORTH);
1036         
1037         bounce(at40k.cell(4, 22), SE, EAST);
1038         //muller(at40k.cell(4PIPELEN-1,21), SW, NORTH);
1039         
1040         //muller(at40k.cell(4,22), NE, WEST);
1041         //at40k.cell(4,22).ylut(0xEE);
1042         muller(at40k.cell(5, 22), NE, SOUTH);
1043         muller(at40k.cell(5, 21), NW, EAST);
1044         /*
1045         for(int x=4; x>=0; x--) {
1046             at40k.cell(x, 21).ylut(0xAA);
1047             at40k.cell(x, 21).yi(EAST);
1048             at40k.cell(x, 21).yo(false);
1049         }
1050
1051         at40k.cell(0, 22).ylut(0xAA);
1052         at40k.cell(0, 22).yi(SOUTH);
1053         at40k.cell(0, 22).yo(false);
1054
1055         at40k.cell(0, 23).ylut(~0xAA);
1056         at40k.cell(0, 23).xlut(~0xcc);
1057         at40k.cell(0, 23).yi(SOUTH);
1058         at40k.cell(0, 23).yo(false);
1059         */
1060         for(int x=3; x<=23; x+=2) {
1061             pulse_detect(at40k.cell(x-1, 19), SW,    false);
1062             pulse_detect(at40k.cell(x-1, 18), WEST,  true);
1063             pulse_copy(at40k.cell(x, 19), SW, SOUTH, false);
1064             pulse_copy(at40k.cell(x, 18), NW, NORTH, true);
1065
1066             if (x<17) {
1067                 pulse_detect(at40k.cell(x-1, 16), SW,    false);
1068                 pulse_detect(at40k.cell(x-1, 15), WEST,  true);
1069                 pulse_copy(at40k.cell(x, 16), SW, SOUTH, false);
1070                 pulse_copy(at40k.cell(x, 15), NW, NORTH, true);
1071             }
1072             //pulse_detect(at40k.cell(15, 22), NORTH, false);
1073             //pulse_detect(at40k.cell(16, 22), NW,    true);
1074             //pulse_copy(at40k.cell(16, 21), NW, WEST, false);
1075             //pulse_copy(at40k.cell(15, 21), NE, EAST, true);
1076         }
1077         for(int x=14; x>=1; x--)
1078             copy(at40k.cell(x, 17), EAST, EAST);
1079         for(int x=4; x>=0; x--)
1080             copy(at40k.cell(x, 21), EAST, EAST);
1081         copy(at40k.cell(13, 17), SOUTH, SOUTH);
1082
1083         copy(at40k.cell(0, 20), NORTH, NORTH);
1084         copy(at40k.cell(0, 19), NORTH, NORTH);
1085         copy(at40k.cell(0, 18), NORTH, NORTH);
1086         copy(at40k.cell(0, 17), NORTH, NORTH);
1087         copy(at40k.cell(0, 16), NORTH, NORTH);
1088         copy(at40k.cell(1, 16), WEST, WEST);
1089         copy(at40k.cell(1, 15), NORTH, NORTH);
1090
1091         copy(at40k.cell(1, 20), SOUTH, SOUTH);
1092         copy(at40k.cell(1, 19), SOUTH, SOUTH);
1093         copy(at40k.cell(1, 18), SOUTH, SOUTH);
1094
1095         for(int y=20; y<=23; y++)
1096             copy(at40k.cell(23, y), SOUTH, SOUTH);
1097
1098
1099         //for(int x=19; x<=23; x++)
1100         //copy(at40k.cell(x, 0), WEST, WEST);
1101         //copy(at40k.cell(18, 19), NW, NW);
1102         //at40k.iob_top(5, true).enableOutput(SOUTH);
1103         //at40k.iob_top(5, false).enableOutput(SOUTH);
1104     }
1105 }