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