d75c296c6e43199007b34102d6aded21d1b3d2ef
[fleet.git] / src / edu / berkeley / fleet / ir / New.java
1 package edu.berkeley.fleet.ir;
2 import edu.berkeley.fleet.api.*;
3 import edu.berkeley.fleet.api.Instruction.*;
4 import edu.berkeley.fleet.fpga.*;
5 import edu.berkeley.fleet.interpreter.*;
6 import edu.berkeley.fleet.api.Instruction.Set.FlagFunction;
7 import edu.berkeley.fleet.api.Instruction.Set;
8 import edu.berkeley.fleet.api.Instruction.Set.SetDest;
9 import edu.berkeley.fleet.api.Instruction.Set.FlagFunction;
10 import static edu.berkeley.fleet.api.Predicate.*;
11 import java.io.*;
12 import java.util.*;
13 import java.net.*;
14
15 // ScanRows+Fix: HARD!
16 /**
17  *  How do we know when a stream is done?  In the case of Equalize?
18  */
19
20 // Video-Out
21 // Loopback (fixpoint of a bundle)
22
23 public class New {
24
25     public final Fleet fleet;
26     public New(Fleet fleet) { this.fleet = fleet; }
27
28     private HashSet<Segment> segments = new HashSet<Segment>();
29
30     private HashSet<Ship> allocated = new HashSet<Ship>();
31     Ship allocate(String shipType) {
32         for(Ship ship : fleet)
33             if (shipType.equals(ship.getType()) && !allocated.contains(ship)) {
34                 allocated.add(ship);
35                 return ship;
36             }
37         throw new RuntimeException("no more ships of type " + shipType);
38     }
39
40     public void emit(ArrayList<Instruction> al) {
41         for(Segment s : segments) s.emitPrologue(al);
42         for(Segment s : segments) s.emitInstructions(al);
43         for(Segment s : segments) s.emitEpilogue(al);
44     }
45
46     public abstract class Segment {
47
48         public final int inputWidth;
49         public final int outputWidth;
50         protected Dock[] inputs;
51
52         public Segment(int inputWidth, int outputWidth) {
53             this.inputWidth = inputWidth;
54             this.outputWidth = outputWidth;
55             segments.add(this);
56         }
57
58         /** sets input docks, returns output docks */
59         public final Dock[] setInputs(Dock[] inputs) {
60             if (inputs.length != inputWidth) throw new RuntimeException();
61             this.inputs = inputs;
62             Dock[] ret = _setInputs();
63             if (ret.length != outputWidth) throw new RuntimeException();
64             return ret;
65         }
66
67         public abstract Dock[] _setInputs();
68         public void emitPrologue(ArrayList<Instruction> il) { }
69         public abstract void emitInstructions(ArrayList<Instruction> il);
70         public void emitEpilogue(ArrayList<Instruction> il) { }
71     }
72
73     public class Debug extends Segment {
74         Ship debugShip;
75         public Debug() {
76             super(1, 0);
77             debugShip = allocate("Debug");
78         }
79         public Dock[] _setInputs() { return new Dock[0]; }
80         public void emitPrologue(ArrayList<Instruction> il) { }
81         public void emitInstructions(ArrayList<Instruction> il) {
82             il.add(Util.sendto(inputs[0], true, debugShip.getDock("in")));
83             il.add(Util.wait(inputs[0], true));
84
85             il.add(Util.setILCInfinity(debugShip.getDock("in")));
86             il.add(Util.recvDeliverAck(debugShip.getDock("in"), inputs[0]));
87         }
88         public void emitEpilogue(ArrayList<Instruction> il) { }
89     }
90
91     public class Constant extends Segment {
92         Ship fifoShip = null;
93         public final long constant;
94         public Constant(long constant) {
95             super(0, 1);
96             this.constant = constant;
97         }
98         public Dock[] _setInputs() {
99             if (fifoShip == null) fifoShip = allocate("Fifo");
100             return new Dock[] { fifoShip.getDock("out") };
101         }
102         public void emitPrologue(ArrayList<Instruction> il) {
103             il.add(Util.setOLC(fifoShip.getDock("out"), 1));
104             il.add(Util.collect(fifoShip.getDock("out"), true));
105         }
106         public void emitInstructions(ArrayList<Instruction> il) {
107             Dock fifoIn = fifoShip.getDock("in");
108             Util.literal(fifoIn, constant, il);
109             il.add(Util.setILCInfinity(fifoIn));
110             il.add(Util.deliver(fifoIn));
111         }
112         public void emitEpilogue(ArrayList<Instruction> il) {
113             il.add(Util.tail(fifoShip.getDock("out")));
114         }
115     }
116
117     public class Alu extends Segment {
118         Ship alu = null;
119         public final int opcode;
120         public Alu(int opcode) {
121             super((opcode==-1) ? 3 : 2, 1);
122             this.opcode = opcode;
123         }
124         public Dock[] _setInputs() {
125             if (alu == null) alu = allocate("Alu2");
126             return new Dock[] { alu.getDock("out") };
127         }
128         public void emitPrologue(ArrayList<Instruction> il) {
129             il.add(Util.setOLC(alu.getDock("out"), 1));
130             il.add(Util.collect(alu.getDock("out"), true));
131         }
132         public void emitInstructions(ArrayList<Instruction> il) {
133             Dock inOp = alu.getDock("inOp");
134
135             if (opcode==-1) {
136                 il.add(Util.setILCInfinity(alu.getDock("inOp")));
137                 il.add(Util.recvDeliverAck(alu.getDock("inOp"), inputs[2]));
138                 il.add(Util.sendto(inputs[2], true, alu.getDock("inOp")));
139                 il.add(Util.wait(inputs[2], true));
140             } else {
141                 Util.literal(alu.getDock("inOp"), opcode, il);
142                 il.add(Util.setILCInfinity(alu.getDock("inOp")));
143                 il.add(Util.deliver(alu.getDock("inOp")));
144             }
145
146             il.add(Util.setILCInfinity(alu.getDock("in1")));
147             il.add(Util.recvDeliverAck(alu.getDock("in1"), inputs[0]));
148             il.add(Util.sendto(inputs[0], true, alu.getDock("in1")));
149             il.add(Util.wait(inputs[0], true));
150
151             il.add(Util.setILCInfinity(alu.getDock("in2")));
152             il.add(Util.recvDeliverAck(alu.getDock("in2"), inputs[1]));
153             il.add(Util.sendto(inputs[1], true, alu.getDock("in2")));
154             il.add(Util.wait(inputs[1], true));
155         }
156         public void emitEpilogue(ArrayList<Instruction> il) {
157             il.add(Util.tail(alu.getDock("out")));
158         }
159     }
160
161     public class Counter extends Segment {
162         Ship alu = null;
163         public final long start;
164         public final long incr;
165         public Counter(long start, long incr) {
166             super(0, 1);
167             this.start = start;
168             this.incr = incr;
169         }
170         public Dock[] _setInputs() {
171             if (alu == null) alu = allocate("Alu2");
172             return new Dock[] { alu.getDock("out") };
173         }
174         public void emitPrologue(ArrayList<Instruction> il) {
175             Util.literal(alu.getDock("out"), start, il);
176             il.add(Util.setOLC(alu.getDock("out"), 1));
177         }
178         public void emitInstructions(ArrayList<Instruction> il) {
179             Dock inOp = alu.getDock("inOp");
180             Util.literal(inOp, 2, il);
181             il.add(Util.setILCInfinity(inOp));
182             il.add(Util.deliver(inOp));
183
184             il.add(Util.setILCInfinity(alu.getDock("in1")));
185             il.add(Util.recvDeliver(alu.getDock("in1")));
186
187             Util.infiniteLiteral(alu.getDock("in2"), incr, il);
188         }
189         public void emitEpilogue(ArrayList<Instruction> il) {
190             il.add(Util.sendto(alu.getDock("out"), true, alu.getDock("in1")));
191             il.add(Util.collect(alu.getDock("out"), true));
192             il.add(Util.tail(alu.getDock("out")));
193         }
194     }
195
196     public class Between extends Segment {
197         Ship alu = null;
198         public final long min;
199         public final long max;
200         public Between(long min, long max) {
201             super(1, 1);
202             this.min = min;
203             this.max = max;
204         }
205         public Dock[] _setInputs() {
206             if (alu == null) alu = allocate("Alu2");
207             return new Dock[] { alu.getDock("out") };
208         }
209         public void emitPrologue(ArrayList<Instruction> il) {
210             il.add(Util.setOLC(alu.getDock("out"), 1));
211             il.add(Util.setOLC(alu.getDock("inOp"), 1));
212             il.add(Util.setOLC(alu.getDock("in1"), 1));
213             il.add(Util.setOLC(alu.getDock("in2"), 1));
214
215             il.add(Util.collect(alu.getDock("out"), true));
216             il.add(new Set(alu.getDock("out"), true, Predicate.Default, FlagFunction.ZERO.add(FlagC), FlagFunction.ZERO));
217             il.add(Util.collect(alu.getDock("out"), true));
218             il.add(new Set(alu.getDock("out"), true, Predicate.Default, FlagFunction.ZERO.add(FlagC).add(FlagA), FlagFunction.ZERO));
219             il.add(new Set(alu.getDock("out"), true, Predicate.NotFlagA, SetDest.DataLatch, 1));
220             il.add(new Set(alu.getDock("out"), true, Predicate.FlagA, SetDest.DataLatch, 0));
221         }
222
223         public void emitInstructions(ArrayList<Instruction> il) {
224             Util.literal(alu.getDock("inOp"), 4, il, true);   // MAX
225             il.add(Util.deliver(alu.getDock("inOp"), true));
226             Util.literal(alu.getDock("in1"), max, il, true);
227             il.add(Util.deliver(alu.getDock("in1"), true));
228             il.add(Util.recvDeliverAck(alu.getDock("in2"), inputs[0], true));
229
230             Util.literal(alu.getDock("inOp"), 4, il, true);   // MIN
231             il.add(Util.deliver(alu.getDock("inOp"), true));
232             Util.literal(alu.getDock("in2"), min, il, true);
233             il.add(Util.deliver(alu.getDock("in2"), true));
234             il.add(Util.recvDeliverAck(alu.getDock("in1"), inputs[0], true));
235
236             il.add(Util.sendto(inputs[0], true, alu.getDock("in2")));
237             il.add(Util.sendto(inputs[0], true, alu.getDock("in1")));
238             il.add(Util.wait(inputs[0], true));
239             il.add(Util.wait(inputs[0], true));
240         }
241
242         public void emitEpilogue(ArrayList<Instruction> il) {
243             il.add(Util.tail(alu.getDock("in1")));
244             il.add(Util.tail(alu.getDock("in2")));
245             il.add(Util.tail(alu.getDock("inOp")));
246             il.add(Util.tail(alu.getDock("out")));
247         }
248     }
249
250
251     public class FifoWithInit extends Segment {
252         Ship fifoShip = null;
253         public final long init;
254         public FifoWithInit(long init) {
255             super(1, 1);
256             this.init = init;
257         }
258         public Dock[] _setInputs() {
259             if (fifoShip == null) fifoShip = allocate("Fifo");
260             return new Dock[] { fifoShip.getDock("out") };
261         }
262         public void emitPrologue(ArrayList<Instruction> il) {
263             Util.literal(fifoShip.getDock("out"), init, il, false);
264             il.add(Util.setOLC(fifoShip.getDock("out"), 1));
265         }
266         public void emitInstructions(ArrayList<Instruction> il) {
267             il.add(Util.sendto(inputs[0], true, fifoShip.getDock("in")));
268             il.add(Util.wait(inputs[0], true));
269
270             il.add(Util.setILCInfinity(fifoShip.getDock("in")));
271             il.add(Util.recvDeliverAck(fifoShip.getDock("in"), inputs[0]));
272         }
273         public void emitEpilogue(ArrayList<Instruction> il) {
274             il.add(Util.collect(fifoShip.getDock("out"), true));
275             il.add(Util.tail(fifoShip.getDock("out")));
276         }
277     }
278
279     public class Video extends Segment {
280         Ship videoShip = null;
281         public Video() {
282             super(3, 0);
283         }
284         public Dock[] _setInputs() {
285             if (videoShip == null) videoShip = allocate("Video");
286             return new Dock[0];
287         }
288         public void emitPrologue(ArrayList<Instruction> il) { }
289         public void emitInstructions(ArrayList<Instruction> il) {
290             il.add(Util.setILCInfinity(videoShip.getDock("inX")));
291             il.add(Util.recvDeliverAck(videoShip.getDock("inX"), inputs[0]));
292             il.add(Util.sendto(inputs[0], true, videoShip.getDock("inX")));
293             il.add(Util.wait(inputs[0], true));
294
295             il.add(Util.setILCInfinity(videoShip.getDock("inY")));
296             il.add(Util.recvDeliverAck(videoShip.getDock("inY"), inputs[1]));
297             il.add(Util.sendto(inputs[1], true, videoShip.getDock("inY")));
298             il.add(Util.wait(inputs[1], true));
299
300             il.add(Util.setILCInfinity(videoShip.getDock("inData")));
301             il.add(Util.recvDeliverAck(videoShip.getDock("inData"), inputs[2]));
302             il.add(Util.sendto(inputs[2], true, videoShip.getDock("inData")));
303             il.add(Util.wait(inputs[2], true));
304         }
305         public void emitEpilogue(ArrayList<Instruction> il) { }
306     }
307
308     public static Dock bouncer(New n, int delt, int start, int min, int max) throws Exception {
309         Constant zeroes      = n.new Constant(0);
310         FifoWithInit pos     = n.new FifoWithInit(start);
311         FifoWithInit delta   = n.new FifoWithInit(delt);
312
313         Dock pos_i   = pos._setInputs()[0];
314         Dock delta_i = delta._setInputs()[0];
315
316         Alu negator = n.new Alu(3);
317         Dock zero_minus_delta_i = negator.setInputs(new Dock[] { zeroes.setInputs(new Dock[0])[0], delta_i })[0];
318
319         Between bet = n.new Between(min, max);
320         Dock selector_input = bet.setInputs(new Dock[] { pos_i })[0];
321
322         Alu selector = n.new Alu(-1);
323         Dock selected = selector.setInputs(new Dock[] { zero_minus_delta_i, delta_i, selector_input })[0];
324
325         Alu sum_alu = n.new Alu(2);
326         Dock sum = sum_alu.setInputs(new Dock[] { selected, pos_i })[0];
327
328         Dock pos_out = pos.setInputs(new Dock[] { sum })[0];
329         Dock delta_out = delta.setInputs(new Dock[] { selected })[0];
330         return pos_out;
331     }
332
333     public static void main(String[] s) throws Exception {
334
335
336         New n = null;
337
338         if (!s[0].equals("fpga")) n = new New(new Interpreter(new String[] {
339                     "Debug",
340                     "Fifo", "Fifo",
341                     "Fifo", "Fifo",
342                     "Fifo", "Fifo",
343                     "Fifo", "Fifo",
344                     "Fifo", "Fifo",
345                     "Fifo", "Fifo",
346                     "Alu2", "Alu2",
347                     "Alu2", "Alu2",
348                     "Alu2", "Alu2",
349                     "Alu2", "Alu2",
350                     "Alu2", "Alu2",
351                     "Alu2", "Alu2",
352                     "Video"
353                 }, false));
354
355
356         if (s[0].equals("fpga")) n = new New(new Fpga());
357
358
359         //Debug debug = n.new Debug();
360
361         /*
362         Constant con12 = n.new Constant(12);
363         debug.setInputs(con12.setInputs(new Dock[0]));
364         */
365
366         /*
367         Alu alu = n.new Alu(2);
368         Constant con12 = n.new Constant(12);
369         Constant con13 = n.new Constant(13);
370         debug.setInputs(alu.setInputs(new Dock[] { con12.setInputs(new Dock[0])[0], con13.setInputs(new Dock[0])[0] }));
371         */
372
373         /*
374         Constant con12 = n.new Constant(12);
375         Counter  con13 = n.new Counter(0, 2);
376         Alu alu = n.new Alu(2);
377         debug.setInputs(alu.setInputs(new Dock[] { con12.setInputs(new Dock[0])[0], con13.setInputs(new Dock[0])[0] }));
378         */
379
380         Dock x_pos = bouncer(n, 1, 6, 5, 634);
381         Dock y_pos = bouncer(n, 1, 6, 5, 474);
382         Dock color = n.new Constant(2).setInputs(new Dock[0])[0];
383         //Dock color = n.new Counter(0,1).setInputs(new Dock[0])[0];
384
385         //debug.setInputs(new Dock[] { x_pos });
386         Video vid = n.new Video();
387         vid.setInputs(new Dock[] { x_pos, y_pos, color });
388
389         ArrayList<Instruction> al = new ArrayList<Instruction>();
390         n.emit(al);
391
392
393         for(int i=0; i<al.size(); i++)
394             System.out.println(al.get(i));
395
396
397         FleetProcess fp = n.fleet.run((Instruction[])al.toArray(new Instruction[0]));
398         System.out.println("launching...");
399         while(true) {
400             System.out.println(fp.readWord().toLong());
401         }
402     }
403
404 }