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