1 package edu.berkeley.fleet.ir;
2 import edu.berkeley.fleet.loops.*;
5 import edu.berkeley.fleet.two.*;
6 import edu.berkeley.fleet.api.*;
7 import edu.berkeley.fleet.fpga.*;
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 static edu.berkeley.fleet.api.Predicate.*;
12 import static edu.berkeley.fleet.util.BitManipulations.*;
17 public class RepeatModule extends Module {
18 private final Ship alu;
19 public final InPort count = new InPort("count") {
20 public void recvToken(Context.LoopFactory lf) { lf.recvToken(); }
21 public void sendWord(Context.LoopFactory lf) { lf.sendWord(alu.getDock("in1").getDataDestination(), new BitVector(1).set(0)); }
22 public Context.LoopFactory build() {
23 Context.LoopFactory lf = ctx.new LoopFactory(alu.getDock("in1"), 0);
24 lf.abortLoopIfTorpedoPresent();
26 lf.setFlags(FlagFunction.ZERO.add(FlagC), FlagFunction.ZERO);
27 lf.setPredicate(Predicate.FlagA);
29 lf.abortLoopIfTorpedoPresent();
31 lf.setPredicate(null);
32 lf.abortLoopIfTorpedoPresent();
34 // RECV_AFTER_TORPEDO == 1
38 public final InPort val = new InPort("val") {
39 public void recvToken(Context.LoopFactory lf) { lf.recvToken(); }
40 public void sendWord(Context.LoopFactory lf) { lf.sendWord(alu.getDock("in2").getDataDestination(), new BitVector(1).set(0)); }
41 public Context.LoopFactory build() {
42 Context.LoopFactory lf = ctx.new LoopFactory(alu.getDock("in2"), 1);
47 lf.setFlags(FlagFunction.ONE, FlagFunction.ZERO);
50 lf.setPredicate(Predicate.FlagA);
51 lf.abortLoopIfTorpedoPresent();
53 lf.setPredicate(null);
54 lf.abortLoopIfTorpedoPresent();
57 lf.abortLoopIfTorpedoPresent();
60 lf.setFlags(FlagFunction.ZERO.add(FlagC), FlagFunction.ZERO);
61 lf.setPredicate(Predicate.FlagA);
66 public final OutPort out = new OutPort("out") {
67 public void sendToken(Context.LoopFactory lf) { lf.sendToken(alu.getDock("out").getDataDestination()); }
68 public void recvWord(Context.LoopFactory lf) { lf.recvWord(); }
69 public Context.LoopFactory build() {
70 Context.LoopFactory lf = ctx.new LoopFactory(alu.getDock("out"), 1);
71 lf.sendToken(alu.getDock("in1").getDataDestination(), new BitVector(1).set(1));
74 lf.abortLoopIfTorpedoPresent();
76 lf.setFlags(FlagFunction.ZERO.add(FlagC), FlagFunction.ZERO);
77 lf.setPredicate(Predicate.FlagA);
78 lf.sendToken(alu.getDock("in1").getDataDestination(), new BitVector(1).set(1));
79 lf.setPredicate(null);
80 lf.setPredicate(Predicate.NotFlagA);
81 lf.sendWord(alu.getDock("in1").getDataDestination(), new BitVector(1).set(0));
82 lf.setPredicate(null);
83 lf.abortLoopIfTorpedoPresent();
85 lf.setPredicate(Predicate.FlagA);
86 lf.sendToken(alu.getDock("in2").getDataDestination(), new BitVector(1).set(1));
87 lf.setPredicate(null);
88 lf.setPredicate(Predicate.NotFlagA);
89 lf.sendWord(alu.getDock("in2").getDataDestination(), new BitVector(1).set(0));
92 lf.setPredicate(null);
96 public RepeatModule() {
97 this.alu = ctx.allocateShip("Alu");
101 Context.LoopFactory lf = ctx.new LoopFactory(alu.getDock("inOp"), 0);
102 lf.literal(3); // SUB
103 lf.abortLoopIfTorpedoPresent();
105 lf.literal(1); // IN2
106 lf.abortLoopIfTorpedoPresent();
113 public class PunctuatorModule extends Module {
114 private final Ship alu;
115 private final long punctuator;
116 private final boolean unpunctuate;
117 public final InPort count = new InPort("count") {
118 public void recvToken(Context.LoopFactory lf) { lf.recvToken(); }
119 public void sendWord(Context.LoopFactory lf) { lf.sendWord(alu.getDock("in1").getDataDestination(), new BitVector(1).set(0)); }
120 public Context.LoopFactory build() {
121 Context.LoopFactory lf = ctx.new LoopFactory(alu.getDock("in1"), 0);
123 lf.setFlags(FlagFunction.ZERO.add(FlagC), FlagFunction.ZERO);
124 lf.setPredicate(Predicate.FlagA);
126 //lf.abortLoopIfTorpedoPresent(); FIXME
128 lf.setPredicate(null);
129 lf.abortLoopIfTorpedoPresent();
131 lf.abortLoopIfTorpedoPresent();
136 public final InPort val = new InPort("val") {
137 public void recvToken(Context.LoopFactory lf) { lf.recvToken(); }
138 public void sendWord(Context.LoopFactory lf) { lf.sendWord(alu.getDock("in2").getDataDestination(), new BitVector(1).set(0)); }
139 public Context.LoopFactory build() {
140 Context.LoopFactory lf = ctx.new LoopFactory(alu.getDock("in2"), 0);
145 lf.abortLoopIfTorpedoPresent();
147 lf.setFlags(FlagFunction.ZERO.add(FlagC), FlagFunction.ZERO);
148 lf.setPredicate(Predicate.FlagA);
150 lf.abortLoopIfTorpedoPresent();
152 lf.setPredicate(null);
157 public final OutPort out = new OutPort("out") {
158 public void sendToken(Context.LoopFactory lf) { lf.sendToken(alu.getDock("out").getDataDestination()); }
159 public void recvWord(Context.LoopFactory lf) { lf.recvWord(); }
160 public Context.LoopFactory build() {
161 Context.LoopFactory lf = ctx.new LoopFactory(alu.getDock("out"), 1);
162 lf.sendToken(alu.getDock("in1").getDataDestination(), new BitVector(1).set(1));
166 lf.abortLoopIfTorpedoPresent();
168 lf.setFlags(FlagFunction.ZERO.add(FlagC), FlagFunction.ZERO);
169 lf.abortLoopIfTorpedoPresent();
173 lf.setPredicate(Predicate.FlagA);
174 lf.sendWord(alu.getDock("in1").getDataDestination(), new BitVector(1).set(1));
175 lf.setPredicate(Predicate.NotFlagA);
176 lf.sendWord(alu.getDock("in1").getDataDestination(), new BitVector(1).set(0));
177 lf.setPredicate(null);
178 lf.sendToken(alu.getDock("in2").getDataDestination(), new BitVector(1).set(1));
180 // if count==0, issue punctuation and tell in1 to get a new count
181 lf.setPredicate(Predicate.FlagA);
182 lf.literal(punctuator);
183 lf.abortLoopIfTorpedoPresent();
186 lf.sendToken(alu.getDock("in1").getDataDestination(), new BitVector(1).set(1));
187 lf.sendToken(alu.getDock("in2").getDataDestination(), new BitVector(1).set(0));
188 lf.setPredicate(null);
190 // if count!=0, cycle around the decremented count and pass a value through
191 lf.setPredicate(Predicate.NotFlagA);
192 lf.sendWord(alu.getDock("in1").getDataDestination(), new BitVector(1).set(0));
193 lf.sendToken(alu.getDock("in2").getDataDestination(), new BitVector(1).set(1));
194 lf.setPredicate(null);
197 lf.abortLoopIfTorpedoPresent();
201 lf.setPredicate(Predicate.NotFlagA);
202 lf.abortLoopIfTorpedoPresent();
205 lf.setPredicate(null);
207 lf.setPredicate(Predicate.NotFlagA);
208 lf.abortLoopIfTorpedoPresent();
211 lf.setPredicate(null);
217 public PunctuatorModule(long punctuator, boolean unpunctuate) {
218 this.alu = ctx.allocateShip("Alu");
219 this.punctuator = punctuator;
220 this.unpunctuate = unpunctuate;
222 public void build() {
224 Context.LoopFactory lf = ctx.new LoopFactory(alu.getDock("inOp"), 0);
225 lf.literal(6); // CMP
226 lf.abortLoopIfTorpedoPresent();
228 lf.literal(3); // SUB
229 lf.abortLoopIfTorpedoPresent();
231 lf.literal(1); // IN2
232 lf.abortLoopIfTorpedoPresent();
238 public class DownCounterModule extends Module {
239 private final int internal_inflight;
240 private final boolean incr_is_already_negative;
241 private final Ship alu;
242 public final InPort start = new InPort("start") {
243 public void recvToken(Context.LoopFactory lf) { lf.recvToken(); }
244 public void sendWord(Context.LoopFactory lf) { lf.sendWord(alu.getDock("in1").getDataDestination(), new BitVector(1).set(0)); }
245 public Context.LoopFactory build() {
246 Context.LoopFactory lf = ctx.new LoopFactory(alu.getDock("in1"), 0);
248 lf.setFlags(FlagFunction.ZERO.add(FlagC), FlagFunction.ZERO);
249 lf.setPredicate(Predicate.FlagA);
251 lf.abortLoopIfTorpedoPresent();
253 lf.setPredicate(null);
258 public final InPort incr = new InPort("incr") {
259 public void recvToken(Context.LoopFactory lf) { lf.recvToken(); }
260 public void sendWord(Context.LoopFactory lf) { lf.sendWord(alu.getDock("in2").getDataDestination(), new BitVector(1).set(0)); }
261 public Context.LoopFactory build() {
262 Context.LoopFactory lf = ctx.new LoopFactory(alu.getDock("in2"), 0);
264 lf.setFlags(FlagFunction.ZERO.add(FlagC), FlagFunction.ZERO);
265 lf.setPredicate(Predicate.FlagA);
267 lf.abortLoopIfTorpedoPresent();
270 lf.setPredicate(Predicate.NotFlagA);
271 lf.abortLoopIfTorpedoPresent();
276 public final OutPort out = new OutPort("out") {
277 public void sendToken(Context.LoopFactory lf) { lf.sendToken(alu.getDock("out").getDataDestination()); }
278 public void recvWord(Context.LoopFactory lf) { lf.recvWord(); }
279 public Context.LoopFactory build() {
280 Context.LoopFactory lf = ctx.new LoopFactory(alu.getDock("out"), 1);
281 lf.setFlags(FlagFunction.ONE, FlagFunction.ZERO);
284 lf.setPredicate(Predicate.FlagA);
285 lf.sendToken(alu.getDock("in1").getDataDestination(), new BitVector(1).set(1));
286 lf.sendToken(alu.getDock("in2").getDataDestination(), new BitVector(1).set(1));
287 lf.setPredicate(Predicate.NotFlagA);
288 lf.sendWord(alu.getDock("in1").getDataDestination(), new BitVector(1).set(0));
289 lf.sendToken(alu.getDock("in2").getDataDestination(), new BitVector(1).set(0));
290 lf.setPredicate(null);
291 lf.abortLoopIfTorpedoPresent();
293 lf.setFlags(FlagFunction.ZERO.add(FlagC), FlagFunction.ZERO);
294 lf.setPredicate(Predicate.NotFlagA);
295 lf.abortLoopIfTorpedoPresent();
298 lf.setPredicate(null);
302 public DownCounterModule(boolean incr_is_already_negative, int internal_inflight) {
303 this.alu = ctx.allocateShip("Alu");
304 this.incr_is_already_negative = incr_is_already_negative;
305 this.internal_inflight = internal_inflight;
306 if (internal_inflight != 0) throw new RuntimeException("not yet supported");
308 public void build() {
310 Context.LoopFactory lf = ctx.new LoopFactory(alu.getDock("inOp"), 1);
311 // Phase 2 (FIXME: tokens for flow control here)
312 lf.literal(incr_is_already_negative
317 lf.abortLoopIfTorpedoPresent();
323 * A "vector register" which is initialized holding zero or more
324 * elements and which will expect to receive count-many elements
328 DOES NOT HANDLE TORPEDOES
329 public class VectorRegisterModule extends Module {
330 public final InPort in;
331 public final OutPort out;
332 public final int count;
333 private final Ship ship;
334 public VectorRegisterModule(final long[] initialValues, final int count) {
335 this(longsToBitVectors(initialValues), count);
337 public VectorRegisterModule(final BitVector[] initialValues, final int count) {
339 ship = ctx.allocateShip("Fifo");
340 in = new PlainInPort("in", ship.getDock("in"), count) {
341 public Context.LoopFactory build(Context.LoopFactory lf) {
342 lf.disableInstructionFifoOverflowCheck();
343 for(int i=0; i<initialValues.length; i++) {
344 lf.literal(initialValues[i]);
347 return super.build(lf.makeNext(1));
350 out = new PlainOutPort("out", ship.getDock("out"), initialValues.length);
356 public class DownCounterModule extends Module {
357 private final int internal_inflight;
358 private final boolean incr_is_already_negative;
359 private final Ship alu;
360 public final InPort incr = new InPort("incr") {
361 public void recvToken(Context.LoopFactory lf) { lf.recvToken(); }
362 public void sendWord(Context.LoopFactory lf) { lf.sendWord(alu.getDock("in1").getDataDestination()); }
363 public Context.LoopFactory build() {
364 Context.LoopFactory lf = ctx.new LoopFactory(alu.getDock("in1"), 1);
369 for(int i=0; i<internal_inflight; i++) lf.deliver();
372 for(int i=0; i<internal_inflight*2; i++) {
377 // Phase 3 (FIXME: tokens for flow control here)
385 public final InPort start = new InPort("start") {
386 public void recvToken(Context.LoopFactory lf) { lf.recvToken(); }
387 public void sendWord(Context.LoopFactory lf) { lf.sendWord(alu.getDock("in2").getDataDestination()); }
388 public Context.LoopFactory build() {
389 Context.LoopFactory lf = ctx.new LoopFactory(alu.getDock("in2"), 1);
394 for(int i=0; i<internal_inflight; i++) lf.deliver();
398 for(int i=0; i<internal_inflight; i++) {
404 // Phase 3 (FIXME: tokens for flow control here)
411 public final OutPort out = new OutPort("out") {
412 public void sendToken(Context.LoopFactory lf) { lf.sendToken(alu.getDock("out").getDataDestination()); }
413 public void recvWord(Context.LoopFactory lf) { lf.recvWord(); }
414 public Context.LoopFactory build() {
415 Context.LoopFactory lf = ctx.new LoopFactory(alu.getDock("out"), 1);
418 for(int i=0; i<internal_inflight*2; i++) {
420 lf.sendWord(alu.getDock("in1").getDataDestination());
424 for(int i=0; i<internal_inflight; i++) {
426 lf.sendWord(alu.getDock("in2").getDataDestination());
430 //lf.setFlags(FlagFunction.ZERO.add(FlagC), FlagFunction.ZERO);
431 //lf.setPredicate(Predicate.FlagA);
433 //lf.setPredicate(null);
435 lf.sendWord(alu.getDock("in1").getDataDestination());
444 lf.setFlags(FlagFunction.ZERO.add(FlagC), FlagFunction.ZERO);
445 lf.setPredicate(Predicate.FlagA);
447 lf.setPredicate(null);
448 lf.sendWord(alu.getDock("in1").getDataDestination());
455 public DownCounterModule(boolean incr_is_already_negative, int internal_inflight) {
456 this.alu = ctx.allocateShip("Alu");
457 this.incr_is_already_negative = incr_is_already_negative;
458 this.internal_inflight = internal_inflight;
459 if (!incr_is_already_negative) throw new RuntimeException("this is broken right now");
461 public void build() {
464 Context.LoopFactory lf = ctx.new LoopFactory(alu.getDock("inOp"), 1);
467 for(int i=0; i<internal_inflight; i++) {
468 lf.literal(0); // IN1
470 lf.literal(1); // IN2
474 // Phase 2 (FIXME: tokens for flow control here)
475 lf.literal(incr_is_already_negative
486 VectorRegisterModule cm1 = proc.new VectorRegisterModule(new long[] { 12, 14, 18, 15 }, 0);
487 VectorRegisterModule cm2 = proc.new VectorRegisterModule(new long[] { 13, 17, 1, 3 }, 0);
488 VectorRegisterModule cm3 = proc.new VectorRegisterModule(new long[] { 2, 2, 2, 2 }, 0);
490 AluModule alu = proc.new AluModule();
492 ForeverModule fmm = proc.new ForeverModule(2);
493 fmm.in.connect(cm2.out);
494 fmm.out.connect(alu.in2);
495 fmm.out_const.connect(alu.inOp);
496 alu.in1.connect(cm1.out);
497 alu.out.connect(dm.in);
501 VectorRegisterModule cm1 = proc.new VectorRegisterModule(new long[] { 43, 10, 5, 5, 5 }, 0);
502 VectorRegisterModule cm2 = proc.new VectorRegisterModule(new long[] { 2, 1, 1, 2, 3 }, 0);
503 DownCounterModule dcm = proc.new DownCounterModule(false, 0);
504 dcm.start.connect(cm1.out);
505 dcm.incr.connect(cm2.out);
506 dcm.out.connect(dm.in);
510 VectorRegisterModule cm1 = proc.new VectorRegisterModule(new long[] { 43, 10, 5, 8, 5 }, 0);
511 VectorRegisterModule cm2 = proc.new VectorRegisterModule(new long[] { 7, 1, 1, 2, 3 }, 0);
512 RepeatModule rm = proc.new RepeatModule();
513 rm.val.connect(cm1.out);
514 rm.count.connect(cm2.out);
515 rm.out.connect(dm.in);