--- /dev/null
+package edu.berkeley.fleet.dataflow;
+import edu.berkeley.fleet.loops.*;
+import edu.berkeley.fleet.api.*;
+
+public class AluNode extends Node {
+ public final Ship ship = dfg.pool.allocateShip("Alu");
+ public final InPort in1 = new DockInPort("in1", ship.getDock("in1"));
+ public final InPort in2 = new DockInPort("in2", ship.getDock("in2"));
+ public final InPort inOp = new DockInPort("inOp", ship.getDock("inOp"));
+ public final OutPort out = new DockOutPort("out", ship.getDock("out"));
+ public AluNode(DataFlowGraph dfg) { super(dfg); }
+}
this.pool = pool;
}
+ public void addNode(Node node) {
+ this.nodes.add(node);
+ }
+
public static int reset_count = 0;
public static HashSet<Dock> torpedoes = new HashSet<Dock>();
mod.reset(ctx, phase, ackDestination);
}
- public static class Node {
-
- void doReset(Context ctx, int phase, Dock dock, Port peer, Destination ackDestination, boolean peerUsed) {
- if (dock.getShip().getType().equals("Debug")) return;
-
- switch(phase) {
-
- // Phase 0: torpedo every output dock, put it in
- // collecting mode. Cannot combine with phase 1,
- // because until output docks are in vacuum mode we
- // cannot be sure that the tokens to the input docks
- // will eventually succeed. This may cause the
- // instructions sent after the tokens to back up into
- // the switch fabric.
- case 0: {
- if (!dock.isInputDock()) {
- torpedoes.add(dock);
- LoopFactory lf = new LoopFactory(ctx, dock, 1);
- lf.sendToken(ackDestination);
- lf = lf.makeNext(0);
- lf.abortLoopIfTorpedoPresent();
- lf.collectWord();
- reset_count++;
- }
- break;
- }
-
- // Phase 1: torpedo every input dock, put it in loopback mode
- case 1: {
- if (dock.isInputDock()) {
- torpedoes.add(dock);
- LoopFactory lf = new LoopFactory(ctx, dock, 1);
- lf.sendToken(ackDestination);
-
- // FIXME: this won't work right for ports that
- // get "shared" by two senders (for example,
- // inAddrRead1/2)
-
- if (peerUsed && peer!=null) {
- lf = lf.makeNext(0);
- lf.abortLoopIfTorpedoPresent();
- ((OutPort)peer).recvWord(lf);
- ((OutPort)peer).sendToken(lf);
- }
- reset_count++;
- }
- break;
- }
-
- // Phase 2: torpedo every output dock, have it absorb tokens
- case 2: {
- if (!dock.isInputDock()) {
- torpedoes.add(dock);
- LoopFactory lf = new LoopFactory(ctx, dock, 1);
- if (peer != null)
- for(int i=0; i<((InPort)peer).getTokensToAbsorb(); i++)
- lf.recvToken();
- lf.sendToken(ackDestination);
- reset_count++;
- }
- break;
- }
-
- // Phase 3: torpedo every input dock, and we're done
- case 3: {
- if (dock.isInputDock()) {
- if (peerUsed && peer!=null) {
- torpedoes.add(dock);
- }
- LoopFactory lf = new LoopFactory(ctx, dock, 1);
- lf.sendToken(ackDestination);
- reset_count++;
- }
- break;
- }
-
-
- }
- }
-
- public final DataFlowGraph dfg;
- public Node(DataFlowGraph dfg) {
- this.dfg = dfg;
- dfg.nodes.add(this);
- }
-
- private HashMap<String,Port> ports = new HashMap<String,Port>();
-
- public InPort getInPort(String name) { return (InPort)ports.get(name); }
- public OutPort getOutPort(String name) { return (OutPort)ports.get(name); }
-
- public void build(Context ctx) { for(Port p : ports.values()) p.build(ctx); }
- public void reset(Context ctx, int phase, Destination ackDestination) {
- for(Port p : ports.values()) p.reset(ctx, phase, ackDestination);
- }
-
- public abstract class Port {
- public final String name;
- public Port(String name) {
- this.name = name;
- if (Node.this.ports.get(name)!=null) throw new RuntimeException();
- Node.this.ports.put(name,this);
- }
- public abstract void build(Context ctx);
- public abstract void reset(Context ctx, int phase, Destination ackDestination);
- }
-
- public abstract class InPort extends Port {
- OutPort peer;
- public InPort(String name) { super(name); }
- public void connect(OutPort peer) {
- this.setPeer(peer);
- peer.setPeer(this);
- }
- public void setPeer(OutPort peer) {
- if (this.peer!=null) throw new RuntimeException("cannot call setPeer() twice");
- this.peer = peer;
- }
-
- /** this port's peer (an OutPort) invokes this to have "recvToken" or equivalent inserted */
- public abstract void recvToken(LoopFactory loopfactory_at_output_dock);
- /** this port's peer (an OutPort) invokes this to have "sendWord" or equivalent inserted */
- public abstract void sendWord(LoopFactory loopfactory_at_output_dock);
-
- public int getTokensToAbsorb() { return 0; }
- }
-
- public abstract class OutPort extends Port {
- InPort peer;
- public OutPort(String name) { super(name); }
- public void connect(InPort peer) {
- this.setPeer(peer);
- peer.setPeer(this);
- }
- public void setPeer(InPort peer) {
- if (this.peer!=null) throw new RuntimeException("cannot call setPeer() twice");
- this.peer = peer;
- }
-
- /** this port's peer (an InPort) invokes this to have "sendToken" or equivalent inserted */
- public abstract void sendToken(LoopFactory loopfactory_at_input_dock);
- /** this port's peer (an InPort) invokes this to have "recvWord" or equivalent inserted */
- public abstract void recvWord(LoopFactory loopfactory_at_input_dock);
- }
-
- public final class DockInPort extends InPort {
- final Dock dock;
- int count;
- BitVector[] pattern;
- public DockInPort(String name, Dock dock) { this(name, dock, 0); }
- public DockInPort(String name, Dock dock, int count) { this(name, dock, count, new BitVector[] { null }); }
- public DockInPort(String name, Dock dock, int count, BitVector[] pattern) {
- super(name);
- this.dock = dock;
- this.count = count;
- this.pattern = pattern;
- }
- public void recvToken(LoopFactory lf) { lf.recvToken(); }
- public void sendWord(LoopFactory lf) { lf.sendWord(dock.getDataDestination()); }
- public void build(Context ctx) { build(ctx, new LoopFactory(ctx, dock, 1)); }
- // number-in-flight is considered a property of the input dock in a pair
- public int getInflight() { return 4; }
- //public int getInflight() { return 1; }
- public int getTokensToAbsorb() { return getInflight(); }
- private boolean peerUsed() {
- if (peer==null) return false;
- for(int i=0; i<pattern.length; i++) if (pattern[i]==null) return true;
- return false;
- }
- public void reset(Context ctx, int phase, Destination ackDestination) {
- doReset(ctx, phase, dock, peer, ackDestination, peerUsed());
- }
- protected void build(Context ctx, LoopFactory lf) {
- int inflight = (count != 0 && count < getInflight()) ? count : getInflight();
-
- if (peer!=null)
- for(int i=0; i<inflight; i++) peer.sendToken(lf);
-
- lf = lf.makeNext(count, true);
- for(int i=0; i<pattern.length; i++) {
- if (pattern[i]==null) {
- if (peer!=null) {
- lf.abortLoopIfTorpedoPresent();
- peer.recvWord(lf);
- peer.sendToken(lf);
- lf.deliver();
- } else {
- lf.interruptibleNop();
- }
- } else {
- lf.literal(pattern[i]);
- lf.abortLoopIfTorpedoPresent();
- lf.deliver();
- }
- }
-
- if (count!=0) {
- // "torpedoable nop" to keep the dock in a receptive state
- lf.abortLoopIfTorpedoPresent();
- lf.recvToken();
- }
- }
- public BitVector getConstant(String constantName) {
- return dock.getConstant(constantName);
- }
- }
-
- public /*final*/ class DockOutPort extends OutPort {
- public final Dock dock;
- public final int count;
- public DockOutPort(String name, Dock dock) { this(name, dock, 0); }
- public DockOutPort(String name, Dock dock, int count) { super(name); this.dock = dock; this.count = count; }
- public void sendToken(LoopFactory lf) { lf.sendToken(dock.getDataDestination()); }
- public void recvWord(LoopFactory lf) { lf.recvWord(); }
- public void build(Context ctx) { build(ctx, new LoopFactory(ctx, dock, 1)); }
- protected void build(Context ctx, LoopFactory lf) {
- if (peer==null) return;
- lf = lf.makeNext(count);
- lf.abortLoopIfTorpedoPresent();
- peer.recvToken(lf);
- lf.collectWord();
- peer.sendWord(lf);
- }
- public void reset(Context ctx, int phase, Destination ackDestination) {
- doReset(ctx, phase, dock, peer, ackDestination, true);
- }
- }
- }
-
- private BitVector bv(long l) { return new BitVector(fleet.getWordWidth()).set(l); }
- private BitVector[] bv(long[] l) {
+ BitVector bv(long l) { return new BitVector(fleet.getWordWidth()).set(l); }
+ BitVector[] bv(long[] l) {
BitVector[] ret = new BitVector[l.length];
for(int i=0; i<ret.length; i++) ret[i] = bv(l[i]);
return ret;
}
- /**
- * Deliver the constant at out forever. Flow control in<->out is
- * maintained, but out is not flow-controlled, so be sure
- * that every datum sent there is consumed synchronously wiht
- * data items sent to out.
- */
- public static class ForeverNode extends Node {
- private BitVector bv;
- public final OutPort out = new OutPort("out") {
- public void sendToken(LoopFactory lf) { }
- public void recvWord(LoopFactory lf) { }
- public void build(Context ctx) { }
- public void reset(Context ctx, int phase, Destination ackDestination) { }
- public void setPeer(InPort peer) {
- this.peer = peer;
- DockInPort pip = ((DockInPort)peer);
- for(int i=0; i<pip.pattern.length; i++) {
- if (pip.pattern[i]==null)
- pip.pattern[i] = bv;
- }
- }
- };
- public ForeverNode(DataFlowGraph dfg, long l) { this(dfg, new BitVector(dfg.fleet.getWordWidth()).set(l)); }
- public ForeverNode(DataFlowGraph dfg, final BitVector bv) { super(dfg); this.bv = bv; }
- }
-
- public static class OnceNode extends Node {
- private BitVector bv;
- public final OutPort out = new OutPort("out") {
- public void sendToken(LoopFactory lf) { }
- public void recvWord(LoopFactory lf) { }
- public void build(Context ctx) { }
- public void reset(Context ctx, int phase, Destination ackDestination) { }
- public void setPeer(InPort peer) {
- this.peer = peer;
- DockInPort pip = ((DockInPort)peer);
- BitVector[] pip_pattern = pip.pattern;
- BitVector[] temp = new BitVector[pip_pattern.length * 2];
- int j = 0;
- int i = 0;
- boolean done = false;
- // FIXME: if peer.count is already 1, this gets simpler and different
- for(i=0; i<temp.length; i++) {
- if (pip_pattern[j] != null) {
- temp[i] = pip_pattern[j];
- } else {
- if (done) break;
- done = true;
- temp[i] = bv;
- }
- j++;
- if (j >= pip_pattern.length) j = 0;
- }
- pip.pattern = new BitVector[i];
- System.arraycopy(temp, 0, pip.pattern, 0, i);
- pip.count = 1;
- }
- };
- public OnceNode(DataFlowGraph dfg, long l) { this(dfg, new BitVector(dfg.fleet.getWordWidth()).set(l)); }
- public OnceNode(DataFlowGraph dfg, final BitVector bv) { super(dfg); this.bv = bv; }
- }
-
- public static class DebugNode extends Node {
- public final Ship ship = dfg.pool.allocateShip("Debug");
- public final InPort in = new DockInPort("in", ship.getDock("in"));
- // NOTE: shutdown needs to treat this specially
- public DebugNode(DataFlowGraph dfg) { super(dfg); }
- }
-
- public static class UnPunctuatorNode extends Node {
- private final Ship ship = dfg.pool.allocateShip("Counter");
- public final OutPort out = new DockOutPort("out", ship.getDock("out"));
- public final InPort val = new DockInPort("in1", ship.getDock("in1"));
- public final InPort count = new DockInPort("in2", ship.getDock("in2"), 0, new BitVector[] { null, dfg.bv(1) });
- public final InPort op = new DockInPort("inOp", ship.getDock("inOp"), 0, new BitVector[] {
- ship.getDock("inOp").getConstant("PASS_C2_V1"),
- ship.getDock("inOp").getConstant("DROP_C2_V1") } );
- public UnPunctuatorNode(DataFlowGraph dfg) { super(dfg); }
- }
-
- public static class PunctuatorNode extends Node {
- private final long punc;
- private final Ship ship = dfg.pool.allocateShip("Counter");
- public final OutPort out = new DockOutPort("out", ship.getDock("out"));
- public final InPort val = new DockInPort("in1", ship.getDock("in1"));
- public final InPort op = new DockInPort("inOp", ship.getDock("inOp"), 0, new BitVector[] {
- ship.getDock("inOp").getConstant("PASS_C2_V1"),
- ship.getDock("inOp").getConstant("PASS_C2_V2") } );
- public final InPort count;
- public PunctuatorNode(DataFlowGraph dfg, long punc) {
- super(dfg);
- this.punc = punc;
- this.count = new DockInPort("in2", ship.getDock("in2"), 0, new BitVector[] { null, dfg.bv(1), dfg.bv(punc) });
- }
- }
-
- public static class AluNode extends Node {
- public final Ship ship = dfg.pool.allocateShip("Alu");
- public final InPort in1 = new DockInPort("in1", ship.getDock("in1"));
- public final InPort in2 = new DockInPort("in2", ship.getDock("in2"));
- public final InPort inOp = new DockInPort("inOp", ship.getDock("inOp"));
- public final OutPort out = new DockOutPort("out", ship.getDock("out"));
- public AluNode(DataFlowGraph dfg) { super(dfg); }
- }
-
- public static class DownCounterNode extends Node {
- public final Ship ship = dfg.pool.allocateShip("Counter");
- public final InPort start = new DockInPort("in1", ship.getDock("in1"));
- public final InPort incr = new DockInPort("in2", ship.getDock("in2"));
- public final InPort inOp = new DockInPort("inOp", ship.getDock("inOp"), 0, new BitVector[] {
- ship.getDock("inOp").getConstant("COUNT") });
- public final OutPort out = new DockOutPort("out", ship.getDock("out"));
- public DownCounterNode(DataFlowGraph dfg) { super(dfg); }
- }
-
- public static class RepeatNode extends Node {
- public final Ship ship = dfg.pool.allocateShip("Counter");
- public final InPort count = new DockInPort("in1", ship.getDock("in1"));
- public final InPort val = new DockInPort("in2", ship.getDock("in2"));
- public final InPort inOP = new DockInPort("inOp", ship.getDock("inOp"), 0, new BitVector[] {
- ship.getDock("inOp").getConstant("REPEAT_C1_V2") });
- public final OutPort out = new DockOutPort("out", ship.getDock("out"));
- public RepeatNode(DataFlowGraph dfg) { super(dfg); }
- }
-
- public static class SortedMergeNode extends Node {
- public final Ship ship = dfg.pool.allocateShip("Alu");
- public final InPort in1 = new DockInPort("in1", ship.getDock("in1"));
- public final InPort in2 = new DockInPort("in2", ship.getDock("in2"));
- public final InPort inOp = new DockInPort("inOp", ship.getDock("inOp"), 0, new BitVector[] {
- ship.getDock("inOp").getConstant("MAXMERGE") });
- public final OutPort out = new DockOutPort("out", ship.getDock("out"));
- public SortedMergeNode(DataFlowGraph dfg) { super(dfg); }
- }
-
- public static class MemoryNode extends Node {
- public final Ship ship;
- public final InPort inCBD;
- public final InPort inAddrRead1;
- public final InPort inAddrRead2;
- public final InPort inAddrWrite;
- public final InPort inDataWrite;
- public final OutPort outRead1;
- public final OutPort outRead2;
- public final OutPort outWrite;
- public MemoryNode(DataFlowGraph dfg, Ship memoryShip) {
- super(dfg);
- this.ship = memoryShip;
- this.inCBD = ship.getType().equals("Memory") ? new DockInPort("inCBD", ship.getDock("inCBD")) : null;
- this.inAddrWrite = new DockInPort("inAddrWrite", ship.getDock("inAddrWrite"));
- this.inDataWrite = new DockInPort("inDataWrite", ship.getDock("inDataWrite"));
- this.inAddrRead1 = new InPort("inAddrRead1") {
- public void recvToken(LoopFactory lf) { lf.recvToken(); }
- public void sendWord(LoopFactory lf) { lf.sendWord(ship.getDock("inAddrRead").getDataDestination(), new BitVector(1).set(0)); }
- public void build(Context ctx) { }
- public int getTokensToAbsorb() { return outRead1.peer.getTokensToAbsorb(); }
- public void reset(Context ctx, int phase, Destination ackDestination) {
- doReset(ctx, phase, ship.getDock("inAddrRead"), null, ackDestination, false);
- }
- };
- this.inAddrRead2 = new InPort("inAddrRead2") {
- public void recvToken(LoopFactory lf) { lf.recvToken(); }
- public void sendWord(LoopFactory lf) { lf.sendWord(ship.getDock("inAddrRead").getDataDestination(), new BitVector(1).set(1)); }
- public void build(Context ctx) { }
- public int getTokensToAbsorb() { return outRead2.peer.getTokensToAbsorb(); }
- public void reset(Context ctx, int phase, Destination ackDestination) { }
- };
- this.outRead1 = new OutPort("outRead1") {
- public void sendToken(LoopFactory lf) { inAddrRead1.peer.sendToken(lf); }
- public void recvWord(LoopFactory lf) { lf.recvWord(); }
- public void build(Context ctx) { }
- public void reset(Context ctx, int phase, Destination ackDestination) { }
- };
- this.outRead2 = new OutPort("outRead2") {
- public void sendToken(LoopFactory lf) { inAddrRead2.peer.sendToken(lf); }
- public void recvWord(LoopFactory lf) { lf.recvWord(); }
- public void build(Context ctx) { }
- public void reset(Context ctx, int phase, Destination ackDestination) { }
- };
- this.outWrite = new DockOutPort("out", ship.getDock("out")) {
- protected void build(Context ctx, LoopFactory lf) {
- lf = lf.makeNext(0);
- lf.abortLoopIfTorpedoPresent();
- lf.collectWord();
-
- lf.setFlags(FlagFunction.ZERO, FlagFunction.ZERO.add(FlagC));
- if (this.peer != null) {
- lf.setPredicate(Predicate.FlagB);
- lf.literal(77);
- lf.abortLoopIfTorpedoPresent();
- this.peer.recvToken(lf);
- this.peer.sendWord(lf);
- }
-
- lf.setPredicate(Predicate.NotFlagB);
- lf.abortLoopIfTorpedoPresent();
- lf.recvToken();
- lf.setFlags(FlagFunction.ZERO.add(NotFlagC).add(FlagB), FlagFunction.ZERO.add(FlagC).add(FlagB));
- if (outRead1.peer != null) {
- lf.setPredicate(Predicate.NotFlagB);
- outRead1.peer.sendWord(lf);
- }
- if (outRead2.peer != null) {
- lf.setPredicate(Predicate.NotFlagA);
- outRead2.peer.sendWord(lf);
- }
- lf.setPredicate(null);
- }
- };
- }
- public void build(Context ctx) {
- super.build(ctx);
- LoopFactory lf;
-
- lf = new LoopFactory(ctx, ship.getDock("inAddrRead"), 0);
- lf.abortLoopIfTorpedoPresent();
- lf.recvWord();
- lf.setFlags(FlagFunction.ZERO.add(FlagC), FlagFunction.ZERO);
- lf.setPredicate(Predicate.NotFlagA);
- lf.sendToken(ship.getDock("out").getDataDestination(), new BitVector(1).set(0));
- lf.setPredicate(Predicate.FlagA);
- lf.sendToken(ship.getDock("out").getDataDestination(), new BitVector(1).set(1));
- lf.setPredicate(null);
- lf.deliver();
- }
- }
-
public static void main(String[] s) throws Exception {
Fleet fleet = new Fpga();
//Fleet fleet = new Interpreter(false);
if (fp==null) fp = fleet.run(new Instruction[0]);
// do the mergeSort
- vals = mergeSort(fp, fleet, vals, vals_length, stride, mem1, mem2);
+ vals = MergeSort.mergeSort(fp, fleet, vals, vals_length, stride, mem1, mem2);
// verify the cleanup
//CleanupUtils.verifyClean(fp);
}
- public static long[] mergeSort(FleetProcess fp, Fleet fleet,
- long[] vals, int vals_length, int stride_length,
- Ship memoryShip1, Ship memoryShip2) throws Exception {
-
- if (vals != null) {
- BitVector[] mem = new BitVector[vals_length];
- for(int i=0; i<mem.length; i++) mem[i] = new BitVector(fleet.getWordWidth()).set(vals[i]);
- MemoryUtils.writeMem(fp, memoryShip1, 0, mem);
- }
-
- //////////////////////////////////////////////////////////////////////////////
-
- DataFlowGraph proc = new DataFlowGraph(fleet);
- DebugNode dm = new DebugNode(proc);
-
- int end_of_data = vals_length;
- int num_strides = end_of_data / (stride_length * 2);
-
- MemoryNode mm = new MemoryNode(proc, memoryShip1);
- SortedMergeNode sm = new SortedMergeNode(proc);
-
- // So far: we have four spare Counter ships; one can be used for resetting
- for(int i=0; i<2; i++) {
-
- DownCounterNode c0 = new DownCounterNode(proc);
- DownCounterNode c1 = new DownCounterNode(proc);
-
- c0.start.connect(new ForeverNode(proc, stride_length).out);
- c0.incr.connect(new ForeverNode(proc, 1).out);
-
- c1.start.connect(new OnceNode(proc, end_of_data + i*stride_length).out);
- c1.incr.connect(new OnceNode(proc, stride_length*2).out);
-
- RepeatNode r1 = new RepeatNode(proc);
- r1.val.connect(c1.out);
- r1.count.connect(new ForeverNode(proc, stride_length).out);
-
- AluNode alu = new AluNode(proc);
- alu.in1.connect(r1.out);
- alu.in2.connect(c0.out);
- alu.inOp.connect(new ForeverNode(proc, ((Node.DockInPort)alu.inOp).getConstant("ADD")).out);
- alu.out.connect(i==0 ? mm.inAddrRead1 : mm.inAddrRead2);
-
- PunctuatorNode punc = new PunctuatorNode(proc, -1);
- punc.count.connect(new ForeverNode(proc, stride_length).out);
- punc.val.connect(i==0 ? mm.outRead1 : mm.outRead2);
- punc.out.connect(i==0 ? sm.in1 : sm.in2);
- }
-
- UnPunctuatorNode unpunc = new UnPunctuatorNode(proc);
- unpunc.val.connect(sm.out);
- unpunc.count.connect(new ForeverNode(proc, 2*stride_length).out);
-
- DownCounterNode cw = new DownCounterNode(proc);
- cw.start.connect(new OnceNode(proc, end_of_data).out);
- cw.incr.connect(new OnceNode(proc, 1).out);
-
- MemoryNode mm2 = new MemoryNode(proc, memoryShip2);
- mm2.inAddrWrite.connect(cw.out);
- mm2.inDataWrite.connect(unpunc.out);
- mm2.outWrite.connect(dm.in);
-
- //////////////////////////////////////////////////////////////////////////////
-
- Context ctx = new Context(fp.getFleet());
- ctx.setAutoflush(true);
-
- ArrayList<Instruction> ai = new ArrayList<Instruction>();
- proc.build(ctx);
- ctx.emit(ai);
- for(Instruction ins : ai) {
- //System.out.println(ins);
- fp.sendInstruction(ins);
- }
- fp.flush();
-
- for(int i=0; i<vals_length; i++) {
- System.out.print("\rreading back... " + i+"/"+vals_length+" ");
- BitVector rec = fp.recvWord();
- System.out.print(" (prev result: " + rec + " = " + rec.toLong() + ")");
- }
- System.out.println("\rdone. ");
-
- //if (true) return ret;
-
- Context ctx2 = new Context(fp.getFleet());
- Dock debugIn = fleet.getShip("Debug",0).getDock("in");
- Dock fred = debugIn;
- fp.sendToken(debugIn.getInstructionDestination());
- fp.flush();
-
- LoopFactory lf = new LoopFactory(ctx2, debugIn, 0);
- lf.literal(0);
- lf.abortLoopIfTorpedoPresent();
- lf.recvToken();
- lf.deliver();
-
- ctx2.dispatch(fp);
- fp.flush();
-
- int count = 0;
-
- Ship counter = proc.pool.allocateShip("Counter");
-
- for(int phase=0; phase<=3; phase++) {
- System.out.println("== phase "+phase+" ==================================================================");
- ctx2 = new Context(fp.getFleet());
-
- Destination ackDestination = counter.getDock("in2").getDataDestination();
- proc.reset(ctx2, phase, ackDestination);
-
- Context ctx3 = new Context(fp.getFleet());
- lf = new LoopFactory(ctx3, counter.getDock("inOp"), 1);
- lf.literal("DROP_C1_V2");
- lf.deliver();
- lf.literal(5);
- lf.deliver();
- lf = new LoopFactory(ctx3, counter.getDock("in1"), 1);
- lf.literal(reset_count-1);
- lf.deliver();
- lf.literal(1);
- lf.deliver();
- lf = new LoopFactory(ctx3, counter.getDock("in2"), 0);
- lf.abortLoopIfTorpedoPresent();
- lf.recvWord();
- lf.deliver();
- lf = new LoopFactory(ctx3, counter.getDock("out"), 1);
- lf.collectWord();
- lf.sendToken(counter.getDock("in2").getInstructionDestination()); // HACK: we don't check to make sure this hits
- lf.sendToken(debugIn.getDataDestination());
- ctx3.dispatch(fp); // HACK: we don't check to make sure that this is "firmly in place"
-
- for(Dock dock : torpedoes) fp.sendToken(dock.getInstructionDestination());
- ctx2.dispatch(fp);
- fp.flush();
- System.out.println("flushed");
-
- fp.recvWord();
- System.out.println("phase done");
-
- System.out.println();
- }
-
- fp.sendToken(debugIn.getInstructionDestination());
- fp.flush();
-
- //System.out.println("verifying cleanup:");
- //CleanupUtils.verifyClean(fp);
-
- System.out.println("reading back:");
- long[] ret = null;
- if (vals != null) {
- ret = new long[vals_length];
- BitVector[] mem = new BitVector[vals_length];
- MemoryUtils.readMem(fp, memoryShip2, 0, mem);
- for(int i=0; i<ret.length; i++) ret[i] = mem[i].toLong();
- }
- return ret;
- }
private BitVector[] longsToBitVectors(long[] initialValues) {
BitVector[] bv = new BitVector[initialValues.length];
--- /dev/null
+package edu.berkeley.fleet.dataflow;
+import edu.berkeley.fleet.loops.*;
+import edu.berkeley.fleet.api.*;
+
+public class DebugNode extends Node {
+ public final Ship ship = dfg.pool.allocateShip("Debug");
+ public final InPort in = new DockInPort("in", ship.getDock("in"));
+ // NOTE: shutdown needs to treat this specially
+ public DebugNode(DataFlowGraph dfg) { super(dfg); }
+}
--- /dev/null
+package edu.berkeley.fleet.dataflow;
+import edu.berkeley.fleet.loops.*;
+import edu.berkeley.fleet.api.*;
+
+public class DownCounterNode extends Node {
+ public final Ship ship = dfg.pool.allocateShip("Counter");
+ public final InPort start = new DockInPort("in1", ship.getDock("in1"));
+ public final InPort incr = new DockInPort("in2", ship.getDock("in2"));
+ public final InPort inOp = new DockInPort("inOp", ship.getDock("inOp"), 0, new BitVector[] {
+ ship.getDock("inOp").getConstant("COUNT") });
+ public final OutPort out = new DockOutPort("out", ship.getDock("out"));
+ public DownCounterNode(DataFlowGraph dfg) { super(dfg); }
+}
--- /dev/null
+package edu.berkeley.fleet.dataflow;
+import edu.berkeley.fleet.loops.*;
+import edu.berkeley.fleet.api.*;
+
+/**
+ * Deliver the constant at out forever. Flow control in<->out is
+ * maintained, but out is not flow-controlled, so be sure
+ * that every datum sent there is consumed synchronously wiht
+ * data items sent to out.
+ */
+public class ForeverNode extends Node {
+ private BitVector bv;
+ public final OutPort out = new OutPort("out") {
+ public void sendToken(LoopFactory lf) { }
+ public void recvWord(LoopFactory lf) { }
+ public void build(Context ctx) { }
+ public void reset(Context ctx, int phase, Destination ackDestination) { }
+ public void setPeer(InPort peer) {
+ this.peer = peer;
+ DockInPort pip = ((DockInPort)peer);
+ for(int i=0; i<pip.pattern.length; i++) {
+ if (pip.pattern[i]==null)
+ pip.pattern[i] = bv;
+ }
+ }
+ };
+ public ForeverNode(DataFlowGraph dfg, long l) { this(dfg, new BitVector(dfg.fleet.getWordWidth()).set(l)); }
+ public ForeverNode(DataFlowGraph dfg, final BitVector bv) { super(dfg); this.bv = bv; }
+}
--- /dev/null
+package edu.berkeley.fleet.dataflow;
+import edu.berkeley.fleet.loops.*;
+import edu.berkeley.fleet.api.*;
+import edu.berkeley.fleet.api.Instruction.*;
+import edu.berkeley.fleet.api.Instruction.Set;
+import edu.berkeley.fleet.api.Instruction.Set.*;
+import static edu.berkeley.fleet.api.Predicate.*;
+
+
+public class MemoryNode extends Node {
+ public final Ship ship;
+ public final InPort inCBD;
+ public final InPort inAddrRead1;
+ public final InPort inAddrRead2;
+ public final InPort inAddrWrite;
+ public final InPort inDataWrite;
+ public final OutPort outRead1;
+ public final OutPort outRead2;
+ public final OutPort outWrite;
+ public MemoryNode(DataFlowGraph dfg, Ship memoryShip) {
+ super(dfg);
+ this.ship = memoryShip;
+ this.inCBD = ship.getType().equals("Memory") ? new DockInPort("inCBD", ship.getDock("inCBD")) : null;
+ this.inAddrWrite = new DockInPort("inAddrWrite", ship.getDock("inAddrWrite"));
+ this.inDataWrite = new DockInPort("inDataWrite", ship.getDock("inDataWrite"));
+ this.inAddrRead1 = new InPort("inAddrRead1") {
+ public void recvToken(LoopFactory lf) { lf.recvToken(); }
+ public void sendWord(LoopFactory lf) { lf.sendWord(ship.getDock("inAddrRead").getDataDestination(), new BitVector(1).set(0)); }
+ public void build(Context ctx) { }
+ public int getTokensToAbsorb() { return outRead1.peer.getTokensToAbsorb(); }
+ public void reset(Context ctx, int phase, Destination ackDestination) {
+ doReset(ctx, phase, ship.getDock("inAddrRead"), null, ackDestination, false);
+ }
+ };
+ this.inAddrRead2 = new InPort("inAddrRead2") {
+ public void recvToken(LoopFactory lf) { lf.recvToken(); }
+ public void sendWord(LoopFactory lf) { lf.sendWord(ship.getDock("inAddrRead").getDataDestination(), new BitVector(1).set(1)); }
+ public void build(Context ctx) { }
+ public int getTokensToAbsorb() { return outRead2.peer.getTokensToAbsorb(); }
+ public void reset(Context ctx, int phase, Destination ackDestination) { }
+ };
+ this.outRead1 = new OutPort("outRead1") {
+ public void sendToken(LoopFactory lf) { inAddrRead1.peer.sendToken(lf); }
+ public void recvWord(LoopFactory lf) { lf.recvWord(); }
+ public void build(Context ctx) { }
+ public void reset(Context ctx, int phase, Destination ackDestination) { }
+ };
+ this.outRead2 = new OutPort("outRead2") {
+ public void sendToken(LoopFactory lf) { inAddrRead2.peer.sendToken(lf); }
+ public void recvWord(LoopFactory lf) { lf.recvWord(); }
+ public void build(Context ctx) { }
+ public void reset(Context ctx, int phase, Destination ackDestination) { }
+ };
+ this.outWrite = new DockOutPort("out", ship.getDock("out")) {
+ protected void build(Context ctx, LoopFactory lf) {
+ lf = lf.makeNext(0);
+ lf.abortLoopIfTorpedoPresent();
+ lf.collectWord();
+
+ lf.setFlags(FlagFunction.ZERO, FlagFunction.ZERO.add(FlagC));
+ if (this.peer != null) {
+ lf.setPredicate(Predicate.FlagB);
+ lf.literal(77);
+ lf.abortLoopIfTorpedoPresent();
+ this.peer.recvToken(lf);
+ this.peer.sendWord(lf);
+ }
+
+ lf.setPredicate(Predicate.NotFlagB);
+ lf.abortLoopIfTorpedoPresent();
+ lf.recvToken();
+ lf.setFlags(FlagFunction.ZERO.add(NotFlagC).add(FlagB), FlagFunction.ZERO.add(FlagC).add(FlagB));
+ if (outRead1.peer != null) {
+ lf.setPredicate(Predicate.NotFlagB);
+ outRead1.peer.sendWord(lf);
+ }
+ if (outRead2.peer != null) {
+ lf.setPredicate(Predicate.NotFlagA);
+ outRead2.peer.sendWord(lf);
+ }
+ lf.setPredicate(null);
+ }
+ };
+ }
+ public void build(Context ctx) {
+ super.build(ctx);
+ LoopFactory lf;
+
+ lf = new LoopFactory(ctx, ship.getDock("inAddrRead"), 0);
+ lf.abortLoopIfTorpedoPresent();
+ lf.recvWord();
+ lf.setFlags(FlagFunction.ZERO.add(FlagC), FlagFunction.ZERO);
+ lf.setPredicate(Predicate.NotFlagA);
+ lf.sendToken(ship.getDock("out").getDataDestination(), new BitVector(1).set(0));
+ lf.setPredicate(Predicate.FlagA);
+ lf.sendToken(ship.getDock("out").getDataDestination(), new BitVector(1).set(1));
+ lf.setPredicate(null);
+ lf.deliver();
+ }
+}
--- /dev/null
+package edu.berkeley.fleet.dataflow;
+import edu.berkeley.fleet.loops.*;
+import edu.berkeley.fleet.api.*;
+import java.util.*;
+
+public class MergeSort {
+ public static long[] mergeSort(FleetProcess fp, Fleet fleet,
+ long[] vals, int vals_length, int stride_length,
+ Ship memoryShip1, Ship memoryShip2) throws Exception {
+
+ if (vals != null) {
+ BitVector[] mem = new BitVector[vals_length];
+ for(int i=0; i<mem.length; i++) mem[i] = new BitVector(fleet.getWordWidth()).set(vals[i]);
+ MemoryUtils.writeMem(fp, memoryShip1, 0, mem);
+ }
+
+ //////////////////////////////////////////////////////////////////////////////
+
+ DataFlowGraph proc = new DataFlowGraph(fleet);
+ DebugNode dm = new DebugNode(proc);
+
+ int end_of_data = vals_length;
+ int num_strides = end_of_data / (stride_length * 2);
+
+ MemoryNode mm = new MemoryNode(proc, memoryShip1);
+ SortedMergeNode sm = new SortedMergeNode(proc);
+
+ // So far: we have four spare Counter ships; one can be used for resetting
+ for(int i=0; i<2; i++) {
+
+ DownCounterNode c0 = new DownCounterNode(proc);
+ DownCounterNode c1 = new DownCounterNode(proc);
+
+ c0.start.connect(new ForeverNode(proc, stride_length).out);
+ c0.incr.connect(new ForeverNode(proc, 1).out);
+
+ c1.start.connect(new OnceNode(proc, end_of_data + i*stride_length).out);
+ c1.incr.connect(new OnceNode(proc, stride_length*2).out);
+
+ RepeatNode r1 = new RepeatNode(proc);
+ r1.val.connect(c1.out);
+ r1.count.connect(new ForeverNode(proc, stride_length).out);
+
+ AluNode alu = new AluNode(proc);
+ alu.in1.connect(r1.out);
+ alu.in2.connect(c0.out);
+ alu.inOp.connect(new ForeverNode(proc, ((Node.DockInPort)alu.inOp).getConstant("ADD")).out);
+ alu.out.connect(i==0 ? mm.inAddrRead1 : mm.inAddrRead2);
+
+ PunctuatorNode punc = new PunctuatorNode(proc, -1);
+ punc.count.connect(new ForeverNode(proc, stride_length).out);
+ punc.val.connect(i==0 ? mm.outRead1 : mm.outRead2);
+ punc.out.connect(i==0 ? sm.in1 : sm.in2);
+ }
+
+ UnPunctuatorNode unpunc = new UnPunctuatorNode(proc);
+ unpunc.val.connect(sm.out);
+ unpunc.count.connect(new ForeverNode(proc, 2*stride_length).out);
+
+ DownCounterNode cw = new DownCounterNode(proc);
+ cw.start.connect(new OnceNode(proc, end_of_data).out);
+ cw.incr.connect(new OnceNode(proc, 1).out);
+
+ MemoryNode mm2 = new MemoryNode(proc, memoryShip2);
+ mm2.inAddrWrite.connect(cw.out);
+ mm2.inDataWrite.connect(unpunc.out);
+ mm2.outWrite.connect(dm.in);
+
+ //////////////////////////////////////////////////////////////////////////////
+
+ Context ctx = new Context(fp.getFleet());
+ ctx.setAutoflush(true);
+
+ ArrayList<Instruction> ai = new ArrayList<Instruction>();
+ proc.build(ctx);
+ ctx.emit(ai);
+ for(Instruction ins : ai) {
+ //System.out.println(ins);
+ fp.sendInstruction(ins);
+ }
+ fp.flush();
+
+ for(int i=0; i<vals_length; i++) {
+ System.out.print("\rreading back... " + i+"/"+vals_length+" ");
+ BitVector rec = fp.recvWord();
+ System.out.print(" (prev result: " + rec + " = " + rec.toLong() + ")");
+ }
+ System.out.println("\rdone. ");
+
+ //if (true) return ret;
+
+ Context ctx2 = new Context(fp.getFleet());
+ Dock debugIn = fleet.getShip("Debug",0).getDock("in");
+ Dock fred = debugIn;
+ fp.sendToken(debugIn.getInstructionDestination());
+ fp.flush();
+
+ LoopFactory lf = new LoopFactory(ctx2, debugIn, 0);
+ lf.literal(0);
+ lf.abortLoopIfTorpedoPresent();
+ lf.recvToken();
+ lf.deliver();
+
+ ctx2.dispatch(fp);
+ fp.flush();
+
+ int count = 0;
+
+ Ship counter = proc.pool.allocateShip("Counter");
+
+ for(int phase=0; phase<=3; phase++) {
+ System.out.println("== phase "+phase+" ==================================================================");
+ ctx2 = new Context(fp.getFleet());
+
+ Destination ackDestination = counter.getDock("in2").getDataDestination();
+ proc.reset(ctx2, phase, ackDestination);
+
+ Context ctx3 = new Context(fp.getFleet());
+ lf = new LoopFactory(ctx3, counter.getDock("inOp"), 1);
+ lf.literal("DROP_C1_V2");
+ lf.deliver();
+ lf.literal(5);
+ lf.deliver();
+ lf = new LoopFactory(ctx3, counter.getDock("in1"), 1);
+ lf.literal(DataFlowGraph.reset_count-1);
+ lf.deliver();
+ lf.literal(1);
+ lf.deliver();
+ lf = new LoopFactory(ctx3, counter.getDock("in2"), 0);
+ lf.abortLoopIfTorpedoPresent();
+ lf.recvWord();
+ lf.deliver();
+ lf = new LoopFactory(ctx3, counter.getDock("out"), 1);
+ lf.collectWord();
+ lf.sendToken(counter.getDock("in2").getInstructionDestination()); // HACK: we don't check to make sure this hits
+ lf.sendToken(debugIn.getDataDestination());
+ ctx3.dispatch(fp); // HACK: we don't check to make sure that this is "firmly in place"
+
+ for(Dock dock : DataFlowGraph.torpedoes) fp.sendToken(dock.getInstructionDestination());
+ ctx2.dispatch(fp);
+ fp.flush();
+ System.out.println("flushed");
+
+ fp.recvWord();
+ System.out.println("phase done");
+
+ System.out.println();
+ }
+
+ fp.sendToken(debugIn.getInstructionDestination());
+ fp.flush();
+
+ //System.out.println("verifying cleanup:");
+ //CleanupUtils.verifyClean(fp);
+
+ System.out.println("reading back:");
+ long[] ret = null;
+ if (vals != null) {
+ ret = new long[vals_length];
+ BitVector[] mem = new BitVector[vals_length];
+ MemoryUtils.readMem(fp, memoryShip2, 0, mem);
+ for(int i=0; i<ret.length; i++) ret[i] = mem[i].toLong();
+ }
+ return ret;
+ }
+}
\ No newline at end of file
--- /dev/null
+package edu.berkeley.fleet.dataflow;
+import edu.berkeley.fleet.loops.*;
+import java.util.concurrent.Semaphore;
+import java.util.*;
+import java.net.*;
+import edu.berkeley.fleet.two.*;
+import edu.berkeley.fleet.api.*;
+import edu.berkeley.fleet.fpga.*;
+import edu.berkeley.fleet.api.Instruction.*;
+import edu.berkeley.fleet.api.Instruction.Set;
+import edu.berkeley.fleet.api.Instruction.Set.*;
+import static edu.berkeley.fleet.api.Predicate.*;
+import static edu.berkeley.fleet.util.BitManipulations.*;
+
+public class Node {
+
+ void doReset(Context ctx, int phase, Dock dock, Port peer, Destination ackDestination, boolean peerUsed) {
+ if (dock.getShip().getType().equals("Debug")) return;
+
+ switch(phase) {
+
+ // Phase 0: torpedo every output dock, put it in
+ // collecting mode. Cannot combine with phase 1,
+ // because until output docks are in vacuum mode we
+ // cannot be sure that the tokens to the input docks
+ // will eventually succeed. This may cause the
+ // instructions sent after the tokens to back up into
+ // the switch fabric.
+ case 0: {
+ if (!dock.isInputDock()) {
+ DataFlowGraph.torpedoes.add(dock);
+ LoopFactory lf = new LoopFactory(ctx, dock, 1);
+ lf.sendToken(ackDestination);
+ lf = lf.makeNext(0);
+ lf.abortLoopIfTorpedoPresent();
+ lf.collectWord();
+ DataFlowGraph.reset_count++;
+ }
+ break;
+ }
+
+ // Phase 1: torpedo every input dock, put it in loopback mode
+ case 1: {
+ if (dock.isInputDock()) {
+ DataFlowGraph.torpedoes.add(dock);
+ LoopFactory lf = new LoopFactory(ctx, dock, 1);
+ lf.sendToken(ackDestination);
+
+ // FIXME: this won't work right for ports that
+ // get "shared" by two senders (for example,
+ // inAddrRead1/2)
+
+ if (peerUsed && peer!=null) {
+ lf = lf.makeNext(0);
+ lf.abortLoopIfTorpedoPresent();
+ ((OutPort)peer).recvWord(lf);
+ ((OutPort)peer).sendToken(lf);
+ }
+ DataFlowGraph.reset_count++;
+ }
+ break;
+ }
+
+ // Phase 2: torpedo every output dock, have it absorb tokens
+ case 2: {
+ if (!dock.isInputDock()) {
+ DataFlowGraph.torpedoes.add(dock);
+ LoopFactory lf = new LoopFactory(ctx, dock, 1);
+ if (peer != null)
+ for(int i=0; i<((InPort)peer).getTokensToAbsorb(); i++)
+ lf.recvToken();
+ lf.sendToken(ackDestination);
+ DataFlowGraph.reset_count++;
+ }
+ break;
+ }
+
+ // Phase 3: torpedo every input dock, and we're done
+ case 3: {
+ if (dock.isInputDock()) {
+ if (peerUsed && peer!=null) {
+ DataFlowGraph.torpedoes.add(dock);
+ }
+ LoopFactory lf = new LoopFactory(ctx, dock, 1);
+ lf.sendToken(ackDestination);
+ DataFlowGraph.reset_count++;
+ }
+ break;
+ }
+
+
+ }
+ }
+
+ public final DataFlowGraph dfg;
+ public Node(DataFlowGraph dfg) {
+ this.dfg = dfg;
+ dfg.addNode(this);
+ }
+
+ private HashMap<String,Port> ports = new HashMap<String,Port>();
+
+ public InPort getInPort(String name) { return (InPort)ports.get(name); }
+ public OutPort getOutPort(String name) { return (OutPort)ports.get(name); }
+
+ public void build(Context ctx) { for(Port p : ports.values()) p.build(ctx); }
+ public void reset(Context ctx, int phase, Destination ackDestination) {
+ for(Port p : ports.values()) p.reset(ctx, phase, ackDestination);
+ }
+
+ public abstract class Port {
+ public final String name;
+ public Port(String name) {
+ this.name = name;
+ if (Node.this.ports.get(name)!=null) throw new RuntimeException();
+ Node.this.ports.put(name,this);
+ }
+ public abstract void build(Context ctx);
+ public abstract void reset(Context ctx, int phase, Destination ackDestination);
+ }
+
+ public abstract class InPort extends Port {
+ OutPort peer;
+ public InPort(String name) { super(name); }
+ public void connect(OutPort peer) {
+ this.setPeer(peer);
+ peer.setPeer(this);
+ }
+ public void setPeer(OutPort peer) {
+ if (this.peer!=null) throw new RuntimeException("cannot call setPeer() twice");
+ this.peer = peer;
+ }
+
+ /** this port's peer (an OutPort) invokes this to have "recvToken" or equivalent inserted */
+ public abstract void recvToken(LoopFactory loopfactory_at_output_dock);
+ /** this port's peer (an OutPort) invokes this to have "sendWord" or equivalent inserted */
+ public abstract void sendWord(LoopFactory loopfactory_at_output_dock);
+
+ public int getTokensToAbsorb() { return 0; }
+ }
+
+ public abstract class OutPort extends Port {
+ InPort peer;
+ public OutPort(String name) { super(name); }
+ public void connect(InPort peer) {
+ this.setPeer(peer);
+ peer.setPeer(this);
+ }
+ public void setPeer(InPort peer) {
+ if (this.peer!=null) throw new RuntimeException("cannot call setPeer() twice");
+ this.peer = peer;
+ }
+
+ /** this port's peer (an InPort) invokes this to have "sendToken" or equivalent inserted */
+ public abstract void sendToken(LoopFactory loopfactory_at_input_dock);
+ /** this port's peer (an InPort) invokes this to have "recvWord" or equivalent inserted */
+ public abstract void recvWord(LoopFactory loopfactory_at_input_dock);
+ }
+
+ public final class DockInPort extends InPort {
+ final Dock dock;
+ int count;
+ BitVector[] pattern;
+ public DockInPort(String name, Dock dock) { this(name, dock, 0); }
+ public DockInPort(String name, Dock dock, int count) { this(name, dock, count, new BitVector[] { null }); }
+ public DockInPort(String name, Dock dock, int count, BitVector[] pattern) {
+ super(name);
+ this.dock = dock;
+ this.count = count;
+ this.pattern = pattern;
+ }
+ public void recvToken(LoopFactory lf) { lf.recvToken(); }
+ public void sendWord(LoopFactory lf) { lf.sendWord(dock.getDataDestination()); }
+ public void build(Context ctx) { build(ctx, new LoopFactory(ctx, dock, 1)); }
+ // number-in-flight is considered a property of the input dock in a pair
+ public int getInflight() { return 4; }
+ //public int getInflight() { return 1; }
+ public int getTokensToAbsorb() { return getInflight(); }
+ private boolean peerUsed() {
+ if (peer==null) return false;
+ for(int i=0; i<pattern.length; i++) if (pattern[i]==null) return true;
+ return false;
+ }
+ public void reset(Context ctx, int phase, Destination ackDestination) {
+ doReset(ctx, phase, dock, peer, ackDestination, peerUsed());
+ }
+ protected void build(Context ctx, LoopFactory lf) {
+ int inflight = (count != 0 && count < getInflight()) ? count : getInflight();
+
+ if (peer!=null)
+ for(int i=0; i<inflight; i++) peer.sendToken(lf);
+
+ lf = lf.makeNext(count, true);
+ for(int i=0; i<pattern.length; i++) {
+ if (pattern[i]==null) {
+ if (peer!=null) {
+ lf.abortLoopIfTorpedoPresent();
+ peer.recvWord(lf);
+ peer.sendToken(lf);
+ lf.deliver();
+ } else {
+ lf.interruptibleNop();
+ }
+ } else {
+ lf.literal(pattern[i]);
+ lf.abortLoopIfTorpedoPresent();
+ lf.deliver();
+ }
+ }
+
+ if (count!=0) {
+ // "torpedoable nop" to keep the dock in a receptive state
+ lf.abortLoopIfTorpedoPresent();
+ lf.recvToken();
+ }
+ }
+ public BitVector getConstant(String constantName) {
+ return dock.getConstant(constantName);
+ }
+ }
+
+ public /*final*/ class DockOutPort extends OutPort {
+ public final Dock dock;
+ public final int count;
+ public DockOutPort(String name, Dock dock) { this(name, dock, 0); }
+ public DockOutPort(String name, Dock dock, int count) { super(name); this.dock = dock; this.count = count; }
+ public void sendToken(LoopFactory lf) { lf.sendToken(dock.getDataDestination()); }
+ public void recvWord(LoopFactory lf) { lf.recvWord(); }
+ public void build(Context ctx) { build(ctx, new LoopFactory(ctx, dock, 1)); }
+ protected void build(Context ctx, LoopFactory lf) {
+ if (peer==null) return;
+ lf = lf.makeNext(count);
+ lf.abortLoopIfTorpedoPresent();
+ peer.recvToken(lf);
+ lf.collectWord();
+ peer.sendWord(lf);
+ }
+ public void reset(Context ctx, int phase, Destination ackDestination) {
+ doReset(ctx, phase, dock, peer, ackDestination, true);
+ }
+ }
+
+}
--- /dev/null
+package edu.berkeley.fleet.dataflow;
+import edu.berkeley.fleet.loops.*;
+import edu.berkeley.fleet.api.*;
+
+public class OnceNode extends Node {
+ private BitVector bv;
+ public final OutPort out = new OutPort("out") {
+ public void sendToken(LoopFactory lf) { }
+ public void recvWord(LoopFactory lf) { }
+ public void build(Context ctx) { }
+ public void reset(Context ctx, int phase, Destination ackDestination) { }
+ public void setPeer(InPort peer) {
+ this.peer = peer;
+ DockInPort pip = ((DockInPort)peer);
+ BitVector[] pip_pattern = pip.pattern;
+ BitVector[] temp = new BitVector[pip_pattern.length * 2];
+ int j = 0;
+ int i = 0;
+ boolean done = false;
+ // FIXME: if peer.count is already 1, this gets simpler and different
+ for(i=0; i<temp.length; i++) {
+ if (pip_pattern[j] != null) {
+ temp[i] = pip_pattern[j];
+ } else {
+ if (done) break;
+ done = true;
+ temp[i] = bv;
+ }
+ j++;
+ if (j >= pip_pattern.length) j = 0;
+ }
+ pip.pattern = new BitVector[i];
+ System.arraycopy(temp, 0, pip.pattern, 0, i);
+ pip.count = 1;
+ }
+ };
+ public OnceNode(DataFlowGraph dfg, long l) { this(dfg, new BitVector(dfg.fleet.getWordWidth()).set(l)); }
+ public OnceNode(DataFlowGraph dfg, final BitVector bv) { super(dfg); this.bv = bv; }
+}
--- /dev/null
+package edu.berkeley.fleet.dataflow;
+import edu.berkeley.fleet.loops.*;
+import edu.berkeley.fleet.api.*;
+
+public class PunctuatorNode extends Node {
+ private final long punc;
+ private final Ship ship = dfg.pool.allocateShip("Counter");
+ public final OutPort out = new DockOutPort("out", ship.getDock("out"));
+ public final InPort val = new DockInPort("in1", ship.getDock("in1"));
+ public final InPort op = new DockInPort("inOp", ship.getDock("inOp"), 0, new BitVector[] {
+ ship.getDock("inOp").getConstant("PASS_C2_V1"),
+ ship.getDock("inOp").getConstant("PASS_C2_V2") } );
+ public final InPort count;
+ public PunctuatorNode(DataFlowGraph dfg, long punc) {
+ super(dfg);
+ this.punc = punc;
+ this.count = new DockInPort("in2", ship.getDock("in2"), 0, new BitVector[] { null, dfg.bv(1), dfg.bv(punc) });
+ }
+}
--- /dev/null
+package edu.berkeley.fleet.dataflow;
+import edu.berkeley.fleet.loops.*;
+import edu.berkeley.fleet.api.*;
+
+public class RepeatNode extends Node {
+ public final Ship ship = dfg.pool.allocateShip("Counter");
+ public final InPort count = new DockInPort("in1", ship.getDock("in1"));
+ public final InPort val = new DockInPort("in2", ship.getDock("in2"));
+ public final InPort inOP = new DockInPort("inOp", ship.getDock("inOp"), 0, new BitVector[] {
+ ship.getDock("inOp").getConstant("REPEAT_C1_V2") });
+ public final OutPort out = new DockOutPort("out", ship.getDock("out"));
+ public RepeatNode(DataFlowGraph dfg) { super(dfg); }
+}
--- /dev/null
+package edu.berkeley.fleet.dataflow;
+import edu.berkeley.fleet.loops.*;
+import edu.berkeley.fleet.api.*;
+
+public class SortedMergeNode extends Node {
+ public final Ship ship = dfg.pool.allocateShip("Alu");
+ public final InPort in1 = new DockInPort("in1", ship.getDock("in1"));
+ public final InPort in2 = new DockInPort("in2", ship.getDock("in2"));
+ public final InPort inOp = new DockInPort("inOp", ship.getDock("inOp"), 0, new BitVector[] {
+ ship.getDock("inOp").getConstant("MAXMERGE") });
+ public final OutPort out = new DockOutPort("out", ship.getDock("out"));
+ public SortedMergeNode(DataFlowGraph dfg) { super(dfg); }
+}
--- /dev/null
+package edu.berkeley.fleet.dataflow;
+import edu.berkeley.fleet.loops.*;
+import edu.berkeley.fleet.api.*;
+
+public class UnPunctuatorNode extends Node {
+ private final Ship ship = dfg.pool.allocateShip("Counter");
+ public final OutPort out = new DockOutPort("out", ship.getDock("out"));
+ public final InPort val = new DockInPort("in1", ship.getDock("in1"));
+ public final InPort count = new DockInPort("in2", ship.getDock("in2"), 0, new BitVector[] { null, dfg.bv(1) });
+ public final InPort op = new DockInPort("inOp", ship.getDock("inOp"), 0, new BitVector[] {
+ ship.getDock("inOp").getConstant("PASS_C2_V1"),
+ ship.getDock("inOp").getConstant("DROP_C2_V1") } );
+ public UnPunctuatorNode(DataFlowGraph dfg) { super(dfg); }
+}