1 package edu.berkeley.fleet.ir;
2 import edu.berkeley.fleet.loops.*;
3 import edu.berkeley.fleet.api.*;
4 import edu.berkeley.fleet.api.Instruction.*;
5 import edu.berkeley.fleet.fpga.*;
6 import edu.berkeley.fleet.interpreter.*;
7 import edu.berkeley.fleet.api.Instruction.Set.FlagFunction;
8 import edu.berkeley.fleet.api.Instruction.Set;
9 import edu.berkeley.fleet.api.Instruction.Set.SetDest;
10 import edu.berkeley.fleet.api.Instruction.Set.FlagFunction;
11 import static edu.berkeley.fleet.api.Predicate.*;
18 public final Fleet fleet;
19 private Context context;
20 public New(Fleet fleet) {
22 this.context = new Context(fleet);
25 private HashSet<Segment> segments = new HashSet<Segment>();
26 private HashSet<Ship> allocated = new HashSet<Ship>();
28 private HashMap<Dock,LoopFactory> loops = new HashMap<Dock,LoopFactory>();
29 private HashSet<LoopFactory> emitLoops = new HashSet<LoopFactory>();
31 public LoopFactory getLoopFactory(Dock d) { return getLoopFactory(d, 0); }
32 public LoopFactory getNextLoopFactory(Dock d, int count) {
33 LoopFactory lf = loops.get(d);
34 if (lf!=null) loops.put(d, lf = lf.makeNext(count, d+""));
35 return getLoopFactory(d, count);
37 public LoopFactory getLoopFactory(Dock d, int count) {
38 LoopFactory lf = loops.get(d);
40 loops.put(d, lf = new LoopFactory(context, d, count, d+""));
43 if (lf.count != count) throw new RuntimeException();
47 Ship allocate(String shipType) {
48 for(Ship ship : fleet)
49 if (shipType.equals(ship.getType()) && !allocated.contains(ship)) {
53 throw new RuntimeException("no more ships of type " + shipType);
56 public void emit(ArrayList<Instruction> al) {
57 for(Segment s : segments) s.emitPrologue(al);
58 for(Segment s : segments) s.emitInstructions(al);
59 for(LoopFactory lf : emitLoops) lf.emit(al);
62 public abstract class Segment {
64 public final int inputWidth;
65 public final int outputWidth;
66 protected Dock[] inputs;
68 public Segment(int inputWidth, int outputWidth) {
69 this.inputWidth = inputWidth;
70 this.outputWidth = outputWidth;
74 /** sets input docks, returns output docks */
75 public final Dock[] setInputs(Dock[] inputs) {
76 if (inputs.length != inputWidth) throw new RuntimeException();
78 Dock[] ret = _setInputs();
79 if (ret.length != outputWidth) throw new RuntimeException();
83 public abstract Dock[] _setInputs();
84 public void emitPrologue(ArrayList<Instruction> il) { }
85 public abstract void emitInstructions(ArrayList<Instruction> il);
88 public class Debug extends Segment {
92 debugShip = allocate("Debug");
94 public Dock[] _setInputs() { return new Dock[0]; }
95 public void emitPrologue(ArrayList<Instruction> il) { }
96 public void emitInstructions(ArrayList<Instruction> il) {
98 lf = new LoopFactory(context, debugShip.getDock("in"), 0, "debug.in");
104 public class Constant extends Segment {
105 Ship fifoShip = null;
106 public final long constant;
107 public Constant(long constant) {
109 this.constant = constant;
111 public Dock[] _setInputs() {
112 if (fifoShip == null) fifoShip = allocate("Fifo");
113 return new Dock[] { fifoShip.getDock("out") };
115 public void emitPrologue(ArrayList<Instruction> il) {
117 lf = getLoopFactory(fifoShip.getDock("out"), 0);
120 public void emitInstructions(ArrayList<Instruction> il) {
122 lf = getLoopFactory(fifoShip.getDock("in"), 1);
123 lf.literal(constant);
124 lf = getNextLoopFactory(fifoShip.getDock("in"), 0);
129 public class Alu extends Segment {
131 public final int opcode;
132 public Alu(int opcode) {
133 super((opcode==-1) ? 3 : 2, 1);
134 this.opcode = opcode;
136 public Dock[] _setInputs() {
137 if (alu == null) alu = allocate("Alu");
138 return new Dock[] { alu.getDock("out") };
140 public void emitPrologue(ArrayList<Instruction> il) {
142 lf = getLoopFactory(alu.getDock("out"), 0);
145 public void emitInstructions(ArrayList<Instruction> il) {
146 Dock inOp = alu.getDock("inOp");
149 recvSendTokenDeliver(alu.getDock("inOp"), inputs[2].getDataDestination());
151 lf = getLoopFactory(inputs[2], 0);
152 lf.sendWord(alu.getDock("inOp").getDataDestination());
156 lf = getLoopFactory(alu.getDock("inOp"), 1);
158 lf = getNextLoopFactory(alu.getDock("inOp"), 0);
162 recvSendTokenDeliver(alu.getDock("in1"), inputs[0].getDataDestination());
164 lf = getLoopFactory(inputs[0], 0);
165 lf.sendWord(alu.getDock("in1").getDataDestination());
168 recvSendTokenDeliver(alu.getDock("in2"), inputs[1].getDataDestination());
169 lf = getLoopFactory(inputs[1], 0);
170 lf.sendWord(alu.getDock("in2").getDataDestination());
175 public class Counter extends Segment {
177 public final long start;
178 public final long incr;
179 public Counter(long start, long incr) {
184 public Dock[] _setInputs() {
185 if (alu == null) alu = allocate("Alu");
186 return new Dock[] { alu.getDock("out") };
188 public void emitPrologue(ArrayList<Instruction> il) {
190 lf = getLoopFactory(alu.getDock("out"), 1);
192 getNextLoopFactory(alu.getDock("out"), 0);
194 public void emitInstructions(ArrayList<Instruction> il) {
196 lf = getLoopFactory(alu.getDock("inOp"), 1);
198 lf = getNextLoopFactory(alu.getDock("inOp"), 0);
201 lf = getLoopFactory(alu.getDock("in1"), 0);
205 lf = getLoopFactory(alu.getDock("in2"), 1);
207 lf = getNextLoopFactory(alu.getDock("in2"), 0);
210 lf = getLoopFactory(alu.getDock("out"), 0);
211 lf.sendWord(alu.getDock("in1").getDataDestination());
216 public class Between extends Segment {
218 public final long min;
219 public final long max;
220 public Between(long min, long max) {
225 public Dock[] _setInputs() {
226 if (alu == null) alu = allocate("Alu");
227 return new Dock[] { alu.getDock("out") };
229 public void emitPrologue(ArrayList<Instruction> il) {
230 getLoopFactory(alu.getDock("in1"), 0);
231 getLoopFactory(alu.getDock("in2"), 0);
234 lf = getLoopFactory(alu.getDock("out"), 0);
236 lf.setFlags(FlagFunction.ZERO.add(FlagC), FlagFunction.ZERO);
238 lf.setFlags(FlagFunction.ZERO.add(FlagC).add(FlagA), FlagFunction.ZERO);
239 lf.setPredicate(Predicate.NotFlagA);
241 lf.setPredicate(Predicate.FlagA);
243 lf.setPredicate(null);
246 public void emitInstructions(ArrayList<Instruction> il) {
248 lf = getLoopFactory(alu.getDock("inOp"), 1);
249 lf.literal(4); // MAX
250 lf = getNextLoopFactory(alu.getDock("inOp"), 0);
253 lf = getLoopFactory(alu.getDock("in1"), 0);
255 lf.sendToken(inputs[0].getDataDestination());
260 lf = getLoopFactory(alu.getDock("in2"), 0);
264 lf.sendToken(inputs[0].getDataDestination());
267 lf = getLoopFactory(inputs[0], 0);
268 lf.sendWord(alu.getDock("in2").getDataDestination());
269 lf.sendWord(alu.getDock("in1").getDataDestination());
275 public class FifoWithInit extends Segment {
276 Ship fifoShip = null;
277 public final long init;
278 public FifoWithInit(long init) {
282 public Dock[] _setInputs() {
283 if (fifoShip == null) fifoShip = allocate("Fifo");
284 return new Dock[] { fifoShip.getDock("out") };
286 public void emitPrologue(ArrayList<Instruction> il) {
288 lf = getLoopFactory(fifoShip.getDock("in"), 1);
291 lf = getNextLoopFactory(fifoShip.getDock("in"), 0);
293 lf = getLoopFactory(fifoShip.getDock("out"), 0);
296 public void emitInstructions(ArrayList<Instruction> il) {
298 lf = getLoopFactory(inputs[0], 0);
299 lf.sendWord(fifoShip.getDock("in").getDataDestination());
302 recvSendTokenDeliver(fifoShip.getDock("in"), inputs[0].getDataDestination());
306 public class Video extends Segment {
307 Ship videoShip = null;
311 public Dock[] _setInputs() {
312 if (videoShip == null) videoShip = allocate("Video");
315 public void emitPrologue(ArrayList<Instruction> il) { }
316 public void emitInstructions(ArrayList<Instruction> il) {
317 recvSendTokenDeliver(videoShip.getDock("inX"), inputs[0].getDataDestination());
318 recvSendTokenDeliver(videoShip.getDock("inY"), inputs[1].getDataDestination());
319 recvSendTokenDeliver(videoShip.getDock("inData"), inputs[2].getDataDestination());
322 lf = getLoopFactory(inputs[0]);
323 lf.sendWord(videoShip.getDock("inX").getDataDestination());
326 lf = getLoopFactory(inputs[1]);
327 lf.sendWord(videoShip.getDock("inY").getDataDestination());
330 lf = getLoopFactory(inputs[2]);
331 lf.sendWord(videoShip.getDock("inData").getDataDestination());
336 public static Dock bouncer(New n, int delt, int start, int min, int max) throws Exception {
337 Constant zeroes = n.new Constant(0);
338 FifoWithInit pos = n.new FifoWithInit(start);
339 FifoWithInit delta = n.new FifoWithInit(delt);
341 Dock pos_i = pos._setInputs()[0];
342 Dock delta_i = delta._setInputs()[0];
344 Alu negator = n.new Alu(3);
345 Dock zero_minus_delta_i = negator.setInputs(new Dock[] { zeroes.setInputs(new Dock[0])[0], delta_i })[0];
347 Between bet = n.new Between(min, max);
348 Dock selector_input = bet.setInputs(new Dock[] { pos_i })[0];
350 Alu selector = n.new Alu(-1);
351 Dock selected = selector.setInputs(new Dock[] { zero_minus_delta_i, delta_i, selector_input })[0];
353 Alu sum_alu = n.new Alu(2);
354 Dock sum = sum_alu.setInputs(new Dock[] { selected, pos_i })[0];
356 Dock pos_out = pos.setInputs(new Dock[] { sum })[0];
357 Dock delta_out = delta.setInputs(new Dock[] { selected })[0];
361 public static void main(String[] s) throws Exception {
362 New n = s[0].equals("fpga")
363 ? new New(new Fpga())
364 : new New(new Interpreter(new String[] {
381 Dock x_pos = bouncer(n, 1, 6, 5, 634);
382 Dock y_pos = bouncer(n, 1, 6, 5, 474);
383 Dock color = n.new Constant(2).setInputs(new Dock[0])[0];
384 //Dock color = n.new Counter(0,1).setInputs(new Dock[0])[0];
386 //debug.setInputs(new Dock[] { x_pos });
387 Video vid = n.new Video();
388 vid.setInputs(new Dock[] { x_pos, y_pos, color });
390 ArrayList<Instruction> al = new ArrayList<Instruction>();
392 for(int i=0; i<al.size(); i++) System.out.println(al.get(i));
394 FleetProcess fp = n.fleet.run((Instruction[])al.toArray(new Instruction[0]));
395 System.out.println("launching...");
396 while(true) System.out.println(fp.recvWord().toLong());
399 private void recvSendTokenDeliver(Dock dock, Destination dest) {
400 LoopFactory lf = getLoopFactory(dock);