revamp demos
[slipway.git] / src / edu / berkeley / slipway / demos / ExperimentUtils.java
1 package edu.berkeley.slipway.demos;
2
3 import java.io.*;
4 import java.util.*;
5 import java.awt.*;
6 import com.atmel.fpslic.*;
7 import edu.berkeley.slipway.*;
8 import edu.berkeley.slipway.gui.*;
9 import static com.atmel.fpslic.FpslicConstants.*;
10
11 /** useful test structures */
12 public class ExperimentUtils {
13
14     /** 
15      *  Creates a 2x2 cell frequency divider with top left corner at
16      *  c, taking input from c.north() and providing output on the
17      *  orthogonal axis at c.south().  Returns c.south().south() for
18      *  easy daisy-chaining.
19      */
20     public static FpslicDevice.Cell divider(FpslicDevice.Cell c) {
21         FpslicDevice.Cell detect1 = c;
22         FpslicDevice.Cell detect2 = c.east();
23
24         detect1.yi(NORTH);
25         detect1.ylut(LUT_SELF);
26         detect1.xlut(LUT_OTHER & (~LUT_Z));
27         detect1.c(YLUT);
28         detect1.t(TMUX_FB);
29         detect1.f(false);
30         detect1.b(false);
31
32         detect2.xi(NW);
33         detect2.ylut(LUT_OTHER);
34         detect2.xlut((~LUT_SELF) & LUT_Z);
35         detect2.c(YLUT);
36         detect2.t(TMUX_FB);
37         detect2.f(false);
38         detect2.b(false);
39
40         detect1.south().yi(EAST);
41         detect1.south().xi(NE);
42         detect1.south().c(YLUT);
43         detect1.south().t(TMUX_FB);
44         detect1.south().f(false);
45         detect1.south().b(false);
46         detect1.south().ylut( (LUT_OTHER    & (~LUT_SELF)) |
47                               ((~LUT_OTHER) &   LUT_Z)
48                               );
49         detect1.south().xlut( (LUT_SELF    & (~LUT_OTHER)) |
50                               ((~LUT_SELF) &   LUT_Z)
51                               );
52
53         detect2.south().yi(WEST);
54         detect2.south().xi(NW);
55         detect2.south().c(YLUT);
56         detect2.south().t(TMUX_FB);
57         detect2.south().f(false);
58         detect2.south().b(false);
59         detect2.south().ylut( (LUT_OTHER    & (LUT_SELF)) |
60                               ((~LUT_OTHER) &   LUT_Z)
61                               );
62         detect2.south().xlut( (LUT_SELF    & (~LUT_OTHER)) |
63                               ((~LUT_SELF) &   LUT_Z)
64                               );
65
66         if (c.south().south()==null) return null;
67         if (c.south().south().south()==null) return null;
68         return c.south().south();
69     }
70
71     /** set up the scan cell */
72     public static void setupScanCell(FpslicDevice fpslic) { setupScanCell(fpslic, L3); }
73     public static void setupScanCell(FpslicDevice fpslic, int debug_plane) {
74         fpslic.cell(23,15).h(3, true);
75         fpslic.cell(23,15).yi(debug_plane);
76         fpslic.cell(23,15).ylut(0xAA);
77         fpslic.iob_right(15, true).enableOutput(WEST);
78
79         fpslic.cell(23,0).ylut(0x00);
80         fpslic.iob_right(0, true).enableOutput(WEST);
81         fpslic.flush();
82     }
83
84     public static void scan(FpslicDevice.Cell cell, int source, boolean setup) { scan(cell, source, setup, L3); }
85     public static void scan(FpslicDevice.Cell cell, int source, boolean setup, int debug_plane) {
86         FpslicDevice dev = cell.fpslic();
87         if (setup) {
88             if (source != NONE && cell.c()!=source) cell.c(source);
89             if (cell.b()) cell.b(false);
90             if (cell.f()) cell.f(false);
91         }
92         if (cell.out(debug_plane)!=setup) cell.out(debug_plane, setup);
93         if (cell.vx(debug_plane)!=setup) cell.v(debug_plane, setup);
94
95         FpslicDevice.SectorWire sw = cell.vwire(debug_plane);
96
97         if (sw.row > (12 & ~0x3) && sw.north()!=null && sw.north().drives(sw))
98             sw.north().drives(sw, false);
99         while(sw.row > (12 & ~0x3) && sw.south() != null) {
100             //System.out.println(sw + " -> " + sw.south());
101             if (sw.drives(sw.south())!=setup) sw.drives(sw.south(), setup);
102             sw = sw.south();
103         }
104         if (sw.row < (12 & ~0x3) && sw.south() != null && sw.south().drives(sw))
105             sw.north().drives(sw, false);
106         while(sw.row < (12 & ~0x3) && sw.north() != null) {
107             //System.out.println(sw + " -> " + sw.north());
108             if (sw.drives(sw.north())!=setup) sw.drives(sw.north(), setup);
109             sw = sw.north();
110         }
111
112         cell = dev.cell(cell.col, 15);
113
114         if (cell.hx(debug_plane) != setup) cell.h(debug_plane, setup);
115         if (cell.vx(debug_plane) != setup) cell.v(debug_plane, setup);
116         sw = cell.hwire(debug_plane);
117
118         if (sw.west()!=null && sw.west().drives(sw)) { sw.west().drives(sw, false); }
119         while(sw.east() != null) {
120             //System.out.println(sw + " -> " + sw.east());
121             if (sw.drives(sw.east())!=setup) sw.drives(sw.east(), setup);
122             sw = sw.east();
123         }
124
125     }
126
127     /** watches for a pulse on Xin, copies value of Yin */
128     public static void pulse_copy(FpslicDevice.Cell cell, int xi, int yi, boolean invert) {
129         loopback(cell, YLUT);
130         if (!invert) cell.ylut(0xB8);                        /* yo = x ?  yi : z => 1011 1000 */
131         else         cell.ylut(0x74);                        /* yo = x ? !yi : z => 0111 0100 */
132         if (!invert) cell.xlut(FpslicUtil.lutSwap(0xB8));   /* yo = x ?  yi : z => 1011 1000 */
133         else         cell.xlut(FpslicUtil.lutSwap(0x74));   /* yo = x ? !yi : z => 0111 0100 */
134         cell.xi(xi);
135         cell.yi(yi);
136     }
137
138     /** watches for a rising/falling edge on Yin, emits a pulse on Xout */
139     public static void pulse_detect(FpslicDevice.Cell c, int in, boolean falling) {
140         c.ylut(0x00);
141         c.xlut(0x00);
142         switch(in) {
143             case NW: case NE: case SW: case SE: {
144                 c.xi(in);
145                 loopback(c, XLUT);
146                 if (!falling) c.ylut(FpslicUtil.lutSwap(0x0C)); /* x & !z */
147                 else          c.ylut(FpslicUtil.lutSwap(0x30)); /* !x & z */
148                 c.xlut(LUT_SELF);
149                 break;
150             }
151             case NORTH: case SOUTH: case EAST: case WEST: {
152                 c.yi(in);
153                 loopback(c, YLUT);
154                 if (!falling) c.xlut(0x0C); /* y & !z */
155                 else          c.xlut(0x30); /* !y & z */
156                 c.ylut(LUT_SELF);
157                 break;
158             }
159             default: throw new Error();
160         }
161     }
162
163     public static void loopback(FpslicDevice.Cell cell, int cin) {
164         cell.f(false);
165         cell.b(false);
166         cell.t(false, false, true);
167         cell.yo(false);
168         cell.xo(false);
169         cell.c(cin);
170     }
171
172     /** copies an x/y-direction input to a y/x-direction output */
173     public static void copy(FpslicDevice.Cell c, int xdir, int ydir) {
174         switch(xdir) {
175             case NW: case NE: case SW: case SE: {
176                 c.xi(xdir);
177                 c.xlut(LUT_SELF);
178                 break;
179             }
180             case NORTH: case SOUTH: case EAST: case WEST: {
181                 c.yi(xdir);
182                 c.xlut(LUT_OTHER);
183                 break;
184             }
185             case NONE: break;
186             default: throw new Error();
187         }
188         switch(ydir) {
189             case NW: case NE: case SW: case SE: {
190                 c.xi(ydir);
191                 c.ylut(LUT_OTHER);
192                 break;
193             }
194             case NORTH: case SOUTH: case EAST: case WEST: {
195                 c.yi(ydir);
196                 c.ylut(LUT_SELF);
197                 break;
198             }
199             case NONE: break;
200             default: throw new Error();
201         }
202         c.xo(false);
203         c.yo(false);
204     }
205
206 }