remove instructionFifoSizeCheckDisabled
[fleet.git] / src / edu / berkeley / fleet / ir / Gadgets.java
1 package edu.berkeley.fleet.ir;
2 import edu.berkeley.fleet.loops.*;
3 import java.util.concurrent.Semaphore;
4 import java.util.*;
5 import java.net.*;
6 import edu.berkeley.fleet.two.*;
7 import edu.berkeley.fleet.fpga.*;
8 import edu.berkeley.fleet.api.*;
9 import edu.berkeley.fleet.api.Instruction.*;
10 import edu.berkeley.fleet.api.Instruction.Set;
11 import edu.berkeley.fleet.api.Instruction.Set.*;
12 import static edu.berkeley.fleet.util.BitManipulations.*;
13 import edu.berkeley.fleet.api.Instruction.Set.FlagFunction;
14 import edu.berkeley.fleet.api.Instruction.Set;
15 import edu.berkeley.fleet.api.Instruction.Set.SetDest;
16 import edu.berkeley.fleet.api.Instruction.Set.FlagFunction;
17 import static edu.berkeley.fleet.api.Predicate.*;
18
19 /*
20   - Change Alu behavior to "drain one"
21   - DROP1, DROP2
22   - secondary DDR chip
23   - facility for launching and Concluding a context
24   - implement the merge operation and test it
25   - test case for DRAM ship
26   - hideously ugly hacks in Verilog.java!
27   - dispatch ALWAYS needs to go via memory first, unless transmissions to
28     debugIn are flow-controlled properly
29   - current write-to-mem transformation screws up -- it can clog
30  */
31
32 public class Gadgets {
33
34     public static void readMem(FleetProcess fp, Ship memory, long offset, BitVector[] vals) throws RuntimeException {
35         doMem(true, fp, memory, offset, vals);
36     }
37     public static void writeMem(FleetProcess fp, Ship memory, long offset, BitVector[] vals) throws RuntimeException {
38         doMem(false, fp, memory, offset, vals);
39     }
40     public static void doMem(final boolean read, final FleetProcess fp, final Ship memory, final long offset, final BitVector[] vals) throws RuntimeException {
41         if (fp.getFleet() != memory.getFleet())
42             throw new RuntimeException("Fleet mismatch");
43
44         final Dock inAddrWrite = memory.getDock("inAddrWrite");
45         final Dock inDataWrite = memory.getDock("inDataWrite");
46         final Dock inAddrRead  = memory.getDock("inAddrRead");
47         final Dock out         = memory.getDock("out");
48         final Dock debugIn     = fp.getDebugInputDock();
49
50         final Semaphore sem = new Semaphore(12 /* FIXME */);
51
52         Context ctx = new Context(fp.getFleet());
53         LoopFactory lf;
54         if (read) {
55             lf = new LoopFactory(ctx, inAddrRead, 0);
56             lf.abortLoopIfTorpedoPresent();
57             lf.recvWord();
58             lf.deliver();
59         } else {
60             lf = new LoopFactory(ctx, inAddrWrite, 0);
61             lf.abortLoopIfTorpedoPresent();
62             lf.recvWord();
63             lf.deliver();
64             lf = new LoopFactory(ctx, inDataWrite, 0);
65             lf.abortLoopIfTorpedoPresent();
66             lf.recvWord();
67             lf.deliver();
68         }
69
70         lf = new LoopFactory(ctx, out, 0);
71         lf.abortLoopIfTorpedoPresent();
72         lf.collectWord();
73         lf.sendWord(debugIn.getDataDestination());
74
75         lf = new LoopFactory(ctx, debugIn, 0);
76         lf.abortLoopIfTorpedoPresent();
77         lf.recvWord();
78         lf.deliver();
79
80         ArrayList<Instruction> ai = new ArrayList<Instruction>();
81         ctx.emit(ai);
82         for(Instruction ins : ai)
83             fp.sendInstruction(ins);
84
85         new Thread() {
86             public void run() { try {
87                     for(int i=0; i<vals.length; i++) {
88                         if (!sem.tryAcquire()) {
89                             fp.flush();
90                             sem.acquire();
91                         }
92                         if (read) {
93                             fp.sendWord(inAddrRead.getDataDestination(), new BitVector(fp.getFleet().getWordWidth()).set(i+offset));
94                         } else {
95                             fp.sendWord(inAddrWrite.getDataDestination(), new BitVector(fp.getFleet().getWordWidth()).set(i+offset));
96                             fp.sendWord(inDataWrite.getDataDestination(), vals[i]);
97                         }
98                     }
99                     fp.flush();
100                 } catch (Exception e) { throw new RuntimeException(e); }
101                 }
102         }.start();
103
104         for(int i=0; i<vals.length; i++) {
105             BitVector outv = fp.recvWord();
106             if (read) vals[i] = outv;
107             if (read) System.out.print("\rread from address: " + i + ", got " + vals[i] + " = " + vals[i].toLong()+"           ");
108             else      System.out.print("\rwrote to address: " + i+"           ");
109             sem.release();
110         }
111
112         if (read) {
113             fp.sendToken(inAddrRead.getInstructionDestination());
114         } else {
115             fp.sendToken(inAddrWrite.getInstructionDestination());
116             fp.sendToken(inDataWrite.getInstructionDestination());
117         }
118         fp.sendToken(out.getInstructionDestination());
119         fp.sendToken(debugIn.getInstructionDestination());
120         System.out.println();
121     }
122
123     /** returns the output Dock at which the merged values may be collected */
124     public static Dock mergeSort(FleetProcess fp,
125                                  Context ctx,
126                                  Ship sourceMem,
127                                  Ship destMem,
128                                  long read_start,
129                                  long write_start,
130                                  int  stride_length,    /* per arity */
131                                  int  num_strides,
132                                  int  arity
133                                  )
134         throws RuntimeException {
135
136         if (arity != 2) throw new RuntimeException();
137         if (num_strides != 1) throw new RuntimeException();
138         LoopFactory lf;
139
140         Dock mem_inAddrData = sourceMem.getDock("inAddrData");
141         Dock mem_out        = sourceMem.getDock("out");
142
143         Ship merger = ctx.allocateShip("Alu");
144         Dock[] merger_inputs = new Dock[] { merger.getDock("in1"), merger.getDock("in2") };
145         Dock merger_inOp = merger.getDock("inOp");
146
147         // Address Generators (arity-many) /////////////////////////////////////////////////////////////////////
148
149         Ship[] address_generators = new Ship[arity];
150         for(int i=0; i<address_generators.length; i++) {
151             address_generators[i] = ctx.allocateShip("Alu");
152             long start = read_start + i*stride_length;
153             int  count = stride_length;
154
155             Dock ag_out = address_generators[i].getDock("out");
156             Dock ag_op  = address_generators[i].getDock("inOp");
157             Dock ag_in1 = address_generators[i].getDock("in1");
158             Dock ag_in2 = address_generators[i].getDock("in2");
159             BitVector signal = new BitVector(1/*FIXME*/).set(i/*FIXME*/);
160
161             lf = new LoopFactory(ctx, ag_in1, 0);
162             lf.literal(1);
163             lf = lf.makeNext(count);
164             
165
166             lf = new LoopFactory(ctx, ag_out, 1);
167             lf.literal(start);
168             lf = lf.makeNext(0);
169             lf.recvToken();
170             lf.sendWord(mem_inAddrData.getDataDestination(), signal);
171             //lf.sendWord(ag_in1);
172             // FIXME ...
173         }
174
175         // Memory Read ////////////////////////////////////////////////////////////////////////////////////////
176
177         lf = new LoopFactory(ctx, mem_inAddrData, 0);
178         lf.recvWord();
179         lf.setFlags(FlagFunction.ZERO.add(FlagC), FlagFunction.ZERO);
180         lf.setPredicate(Predicate.NotFlagA);
181         lf.sendToken(mem_out.getDataDestination(), new BitVector(1/*FIXME*/).set(0));   // note: arity-many tokens may pile up at mem_out...
182         lf.setPredicate(Predicate.FlagA);
183         lf.sendToken(mem_out.getDataDestination(), new BitVector(1/*FIXME*/).set(1));
184         lf.setPredicate(null);
185         lf.deliver();
186
187         lf = new LoopFactory(ctx, mem_out, 0);
188         lf.collectWord();
189         lf.recvToken();
190         lf.setFlags(FlagFunction.ZERO.add(FlagC), FlagFunction.ZERO);
191         lf.setPredicate(Predicate.NotFlagA);
192         lf.sendWord(merger_inputs[0].getDataDestination());
193         lf.setPredicate(Predicate.FlagA);
194         lf.sendWord(merger_inputs[1].getDataDestination());
195         lf.setPredicate(null);
196
197         // Merger /////////////////////////////////////////////////////////////////////////////////////////////
198
199         for(int i=0; i<merger_inputs.length; i++) {
200             lf = new LoopFactory(ctx, merger_inputs[i], stride_length);
201             lf.sendToken(address_generators[i].getDock("out").getDataDestination());
202             lf.recvWord();
203             lf.deliver();
204
205             lf = lf.makeNext(1);
206             lf.literal(-1);
207             lf.deliver();
208         }
209
210         lf = new LoopFactory(ctx, merger_inOp, 1);
211         lf.literal(5); // MIN
212         lf = lf.makeNext(stride_length * arity);
213         lf.deliver();
214         lf = lf.makeNext(1);
215         lf.literal(7); // DROP1
216         lf.deliver();
217         lf.literal(8); // DROP2
218         lf.deliver();
219
220         return merger.getDock("out");
221     }
222
223     public static void dispatch(FleetProcess fp, Context ctx) {
224         ArrayList<Instruction> ai;
225         ctx.emit(ai = new ArrayList<Instruction>());
226         for(Instruction ins : ai) {
227             fp.sendInstruction(ins);
228         }
229     }
230
231     public static void main(String[] s) throws Exception {
232         Random random = new Random(System.currentTimeMillis());
233         Fleet fleet = new Fpga();
234         FleetProcess fp = fleet.run(new Instruction[0]);
235         Ship memory = fleet.getShip("DDR2",0);
236         //Ship memory = fleet.getShip("Memory",0);
237         BitVector[] vals  = new BitVector[2 * 1024];
238         BitVector[] vals2 = new BitVector[2 * 1024];
239         for(int i=0; i<vals.length; i++)
240             vals[i] = new BitVector(fleet.getWordWidth()).set(random.nextLong());
241         writeMem(fp, memory, 0, vals);
242         readMem(fp, memory, 0, vals2);
243         for(int i=0; i<vals.length; i++)
244             if (!vals[i].equals(vals2[i]))
245                 System.out.println("disagreement!  on index " + i + "\n  "+vals[i]+"\n  "+vals2[i]);
246         System.out.println("done!");
247     }
248 }