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.*;
15 // ScanRows+Fix: HARD!
17 * How do we know when a stream is done? In the case of Equalize?
21 // Loopback (fixpoint of a bundle)
25 public final Fleet fleet;
26 public New(Fleet fleet) { this.fleet = fleet; }
28 private HashSet<Segment> segments = new HashSet<Segment>();
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)) {
37 throw new RuntimeException("no more ships of type " + shipType);
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);
46 public abstract class Segment {
48 public final int inputWidth;
49 public final int outputWidth;
50 protected Dock[] inputs;
52 public Segment(int inputWidth, int outputWidth) {
53 this.inputWidth = inputWidth;
54 this.outputWidth = outputWidth;
58 /** sets input docks, returns output docks */
59 public final Dock[] setInputs(Dock[] inputs) {
60 if (inputs.length != inputWidth) throw new RuntimeException();
62 Dock[] ret = _setInputs();
63 if (ret.length != outputWidth) throw new RuntimeException();
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) { }
73 public class Debug extends Segment {
77 debugShip = allocate("Debug");
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));
85 il.add(Util.setILCInfinity(debugShip.getDock("in")));
86 il.add(Util.recvDeliverAck(debugShip.getDock("in"), inputs[0]));
88 public void emitEpilogue(ArrayList<Instruction> il) { }
91 public class Constant extends Segment {
93 public final long constant;
94 public Constant(long constant) {
96 this.constant = constant;
98 public Dock[] _setInputs() {
99 if (fifoShip == null) fifoShip = allocate("Fifo");
100 return new Dock[] { fifoShip.getDock("out") };
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));
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));
112 public void emitEpilogue(ArrayList<Instruction> il) {
113 il.add(Util.tail(fifoShip.getDock("out")));
117 public class Alu extends Segment {
119 public final int opcode;
120 public Alu(int opcode) {
121 super((opcode==-1) ? 3 : 2, 1);
122 this.opcode = opcode;
124 public Dock[] _setInputs() {
125 if (alu == null) alu = allocate("alu2");
126 return new Dock[] { alu.getDock("out") };
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));
132 public void emitInstructions(ArrayList<Instruction> il) {
133 Dock inOp = alu.getDock("inOp");
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));
141 Util.literal(alu.getDock("inOp"), opcode, il);
142 il.add(Util.setILCInfinity(alu.getDock("inOp")));
143 il.add(Util.deliver(alu.getDock("inOp")));
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));
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));
156 public void emitEpilogue(ArrayList<Instruction> il) {
157 il.add(Util.tail(alu.getDock("out")));
161 public class Counter extends Segment {
163 public final long start;
164 public final long incr;
165 public Counter(long start, long incr) {
170 public Dock[] _setInputs() {
171 if (alu == null) alu = allocate("alu2");
172 return new Dock[] { alu.getDock("out") };
174 public void emitPrologue(ArrayList<Instruction> il) {
175 Util.literal(alu.getDock("out"), start, il);
176 il.add(Util.setOLC(alu.getDock("out"), 1));
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));
184 il.add(Util.setILCInfinity(alu.getDock("in1")));
185 il.add(Util.recvDeliver(alu.getDock("in1")));
187 Util.infiniteLiteral(alu.getDock("in2"), incr, il);
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")));
196 public class Between extends Segment {
198 public final long min;
199 public final long max;
200 public Between(long min, long max) {
205 public Dock[] _setInputs() {
206 if (alu == null) alu = allocate("alu2");
207 return new Dock[] { alu.getDock("out") };
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));
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));
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));
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));
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));
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")));
251 public class FifoWithInit extends Segment {
252 Ship fifoShip = null;
253 public final long init;
254 public FifoWithInit(long init) {
258 public Dock[] _setInputs() {
259 if (fifoShip == null) fifoShip = allocate("Fifo");
260 return new Dock[] { fifoShip.getDock("out") };
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));
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));
270 il.add(Util.setILCInfinity(fifoShip.getDock("in")));
271 il.add(Util.recvDeliverAck(fifoShip.getDock("in"), inputs[0]));
273 public void emitEpilogue(ArrayList<Instruction> il) {
274 il.add(Util.collect(fifoShip.getDock("out"), true));
275 il.add(Util.tail(fifoShip.getDock("out")));
279 public class Video extends Segment {
280 Ship videoShip = null;
284 public Dock[] _setInputs() {
285 if (videoShip == null) videoShip = allocate("Video");
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));
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));
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));
305 public void emitEpilogue(ArrayList<Instruction> il) { }
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);
313 Dock pos_i = pos._setInputs()[0];
314 Dock delta_i = delta._setInputs()[0];
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];
319 Between bet = n.new Between(min, max);
320 Dock selector_input = bet.setInputs(new Dock[] { pos_i })[0];
322 Alu selector = n.new Alu(-1);
323 Dock selected = selector.setInputs(new Dock[] { zero_minus_delta_i, delta_i, selector_input })[0];
325 Alu sum_alu = n.new Alu(2);
326 Dock sum = sum_alu.setInputs(new Dock[] { selected, pos_i })[0];
328 Dock pos_out = pos.setInputs(new Dock[] { sum })[0];
329 Dock delta_out = delta.setInputs(new Dock[] { selected })[0];
333 public static void main(String[] s) throws Exception {
338 if (!s[0].equals("fpga")) n = new New(new Interpreter(new String[] {
356 if (s[0].equals("fpga")) n = new New(new Fpga());
359 //Debug debug = n.new Debug();
362 Constant con12 = n.new Constant(12);
363 debug.setInputs(con12.setInputs(new Dock[0]));
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] }));
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] }));
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];
385 //debug.setInputs(new Dock[] { x_pos });
386 Video vid = n.new Video();
387 vid.setInputs(new Dock[] { x_pos, y_pos, color });
389 ArrayList<Instruction> al = new ArrayList<Instruction>();
393 for(int i=0; i<al.size(); i++)
394 System.out.println(al.get(i));
397 FleetProcess fp = n.fleet.run((Instruction[])al.toArray(new Instruction[0]));
398 System.out.println("launching...");
400 System.out.println(fp.readWord().toLong());