import edu.berkeley.fleet.api.*;
public class AluNode extends Node {
- public final Ship ship = dfg.pool.allocateShip("Alu");
+ private 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); }
}
import java.util.*;
import java.net.*;
-// public class ReplaceNode extends Node { }
-// public class CountMergeNode extends Node { }
-// public class SortMergeNode extends Node { }
-// public class FanOutNode extends Node { }
-// public class DoneNode extends Node { }
-
public class DataFlowGraph {
public final Fleet fleet;
import edu.berkeley.fleet.api.*;
public class DebugNode extends Node {
- public final Ship ship = dfg.pool.allocateShip("Debug");
+ private 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); }
}
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"));
+ private final Ship ship = dfg.pool.allocateShip("Counter");
+ private final InPort inOp = new DockInPort("inOp", ship.getDock("inOp"), 0, new BitVector[] {
+ ship.getDock("inOp").getConstant("COUNT") });
+
+ public final InPort start = new DockInPort("start", ship.getDock("in1"));
+ public final InPort incr = new DockInPort("incr", ship.getDock("in2"));
+ public final OutPort out = new DockOutPort("out", ship.getDock("out"));
+
public DownCounterNode(DataFlowGraph dfg) { super(dfg); }
}
public class MemoryNode extends Node {
- public final Ship ship;
+ private final Ship ship;
public final InPort inCBD;
public final InPort inAddrRead1;
public final InPort inAddrRead2;
import java.util.*;
public class MergeSort {
- public static long[] mergeSort(FleetProcess fp, Fleet fleet,
+ public static long[] mergeSort(FleetProcess fp, Fleet fleet, ShipPool pool,
long[] vals, int vals_length, int stride_length,
Ship memoryShip1, Ship memoryShip2) throws Exception {
//////////////////////////////////////////////////////////////////////////////
- DataFlowGraph proc = new DataFlowGraph(fleet);
+ DataFlowGraph proc = new DataFlowGraph(fleet, pool);
DebugNode dm = new DebugNode(proc);
int end_of_data = vals_length;
//////////////////////////////////////////////////////////////////////////////
+ Ship codeMemoryShip = proc.pool.allocateShip("Memory");
+
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();
+ ctx.dispatch(fp, true);
for(int i=0; i<vals_length; i++) {
System.out.print("\rreading back... " + i+"/"+vals_length+" ");
}
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());
+
+ LoopFactory lf;
Destination ackDestination = counter.getDock("in2").getDataDestination();
HashSet<Dock> sendTorpedoesTo = new HashSet<Dock>();
- int expected_tokens = proc.reset(ctx2, phase, ackDestination, sendTorpedoesTo);
+ Context ctx_reset = new Context(fp.getFleet());
+ int expected_tokens = proc.reset(ctx_reset, phase, ackDestination, sendTorpedoesTo);
- Context ctx3 = new Context(fp.getFleet());
- lf = new LoopFactory(ctx3, counter.getDock("inOp"), 1);
+ Context ctx_debug = new Context(fp.getFleet());
+ lf = new LoopFactory(ctx_debug, debugIn, 0);
+ lf.literal(0);
+ lf.abortLoopIfTorpedoPresent();
+ lf.recvToken();
+ lf.deliver();
+
+ Context ctx_count = new Context(fp.getFleet());
+ lf = new LoopFactory(ctx_count, 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 = new LoopFactory(ctx_count, counter.getDock("in1"), 1);
lf.literal(expected_tokens-1);
lf.deliver();
lf.literal(1);
lf.deliver();
- lf = new LoopFactory(ctx3, counter.getDock("in2"), 0);
+ lf = new LoopFactory(ctx_count, counter.getDock("in2"), 0);
lf.abortLoopIfTorpedoPresent();
lf.recvWord();
lf.deliver();
- lf = new LoopFactory(ctx3, counter.getDock("out"), 1);
+ lf = new LoopFactory(ctx_count, 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 : sendTorpedoesTo) fp.sendToken(dock.getInstructionDestination());
- ctx2.dispatch(fp);
+ Program program = new Program(codeMemoryShip);
+ CodeBag cb = program.makeCodeBag(ctx_count);
+ program.install(fp);
+ MemoryUtils.putMemoryShipInDispatchMode(fp, codeMemoryShip);
+ program.run(fp, cb);
fp.flush();
+
+ ctx_debug.dispatch(fp, true);
+ //ctx_count.dispatch(fp, true); // HACK: we don't check to make sure that this is "firmly in place"
+ for(Dock dock : sendTorpedoesTo) fp.sendToken(dock.getInstructionDestination());
+ ctx_reset.dispatch(fp, true);
System.out.println("flushed");
fp.recvWord();
+ fp.sendToken(debugIn.getInstructionDestination());
System.out.println("phase done");
+ MemoryUtils.removeMemoryShipFromDispatchMode(fp, codeMemoryShip);
System.out.println();
}
- fp.sendToken(debugIn.getInstructionDestination());
fp.flush();
//System.out.println("verifying cleanup:");
// if we reset the FleetProcess, restart it
if (fp==null) fp = fleet.run(new Instruction[0]);
+ ShipPool pool = new ShipPool(fleet);
+ pool.allocateShip(mem1);
+ pool.allocateShip(mem2);
+
// do the mergeSort
- vals = MergeSort.mergeSort(fp, fleet, vals, vals_length, stride, mem1, mem2);
+ vals = MergeSort.mergeSort(fp, fleet, pool, vals, vals_length, stride, mem1, mem2);
// verify the cleanup
//CleanupUtils.verifyClean(fp);
public class Node {
- int doReset(Context ctx, int phase, Dock dock, Port peer, Destination ackDestination, HashSet<Dock> sendTorpedoesTo, boolean peerUsed) {
- int ret = 0;
- if (dock.getShip().getType().equals("Debug")) return ret;
-
- 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()) {
- sendTorpedoesTo.add(dock);
- LoopFactory lf = new LoopFactory(ctx, dock, 1);
- lf.sendToken(ackDestination);
- lf = lf.makeNext(0);
- lf.abortLoopIfTorpedoPresent();
- lf.collectWord();
- ret++;
- }
- break;
- }
-
- // Phase 1: torpedo every input dock, put it in loopback mode
- case 1: {
- if (dock.isInputDock()) {
- sendTorpedoesTo.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);
- }
- ret++;
- }
- break;
- }
-
- // Phase 2: torpedo every output dock, have it absorb tokens
- case 2: {
- if (!dock.isInputDock()) {
- sendTorpedoesTo.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);
- ret++;
- }
- break;
- }
-
- // Phase 3: torpedo every input dock, and we're done
- case 3: {
- if (dock.isInputDock()) {
- if (peerUsed && peer!=null) {
- sendTorpedoesTo.add(dock);
- }
- LoopFactory lf = new LoopFactory(ctx, dock, 1);
- lf.sendToken(ackDestination);
- ret++;
- }
- break;
- }
- }
- return ret;
- }
-
public final DataFlowGraph dfg;
public Node(DataFlowGraph dfg) {
this.dfg = dfg;
}
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 int reset(Context ctx, int phase, Destination ackDestination, HashSet<Dock> sendTorpedoesTo) {
int ret = 0;
}
public abstract void build(Context ctx);
public abstract int reset(Context ctx, int phase, Destination ackDestination, HashSet<Dock> sendTorpedoesTo);
+ public String toString() { return Node.this+"."+name; }
}
public abstract class InPort extends Port {
for(int i=0; i<ret.length; i++) ret[i] = bv(l[i]);
return ret;
}
+
+ // Reset //////////////////////////////////////////////////////////////////////////////
+
+ int doReset(Context ctx,
+ int phase,
+ Dock dock,
+ Port peer,
+ Destination ackDestination,
+ HashSet<Dock> sendTorpedoesTo,
+ boolean peerUsed) {
+ int ret = 0;
+ if (dock.getShip().getType().equals("Debug")) return ret;
+
+ 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()) {
+ sendTorpedoesTo.add(dock);
+ LoopFactory lf = new LoopFactory(ctx, dock, 1);
+ lf.sendToken(ackDestination);
+ lf = lf.makeNext(0);
+ lf.abortLoopIfTorpedoPresent();
+ lf.collectWord();
+ ret++;
+ }
+ break;
+ }
+
+ // [wait for all output docks to confirm that they've been torpedoed]
+ // Phase 1: torpedo every input dock (causing them to flush), put it in loopback mode
+ case 1: {
+ if (dock.isInputDock()) {
+ sendTorpedoesTo.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);
+ }
+ ret++;
+ }
+ break;
+ }
+
+ // [wait for all input docks to confirm that they've been torpedoed and have flushed]
+ // Phase 2: torpedo every output dock, have it absorb tokens
+ case 2: {
+ if (!dock.isInputDock()) {
+ sendTorpedoesTo.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);
+ ret++;
+ }
+ break;
+ }
+
+ // [wait for all output docks to confirm that they've absorbed enough tokens]
+ // Phase 3: torpedo every input dock, await confirmation, and we're done
+ case 3: {
+ if (dock.isInputDock()) {
+ if (peerUsed && peer!=null) {
+ sendTorpedoesTo.add(dock);
+ }
+ LoopFactory lf = new LoopFactory(ctx, dock, 1);
+ lf.sendToken(ackDestination);
+ ret++;
+ }
+ break;
+ }
+ }
+ return ret;
+ }
+
}
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[] {
+ private 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 final OutPort out = new DockOutPort("out", ship.getDock("out"));
+ public final InPort val = new DockInPort("val", ship.getDock("in1"));
+
public PunctuatorNode(DataFlowGraph dfg, long punc) {
super(dfg);
this.punc = punc;
- this.count = new DockInPort("in2", ship.getDock("in2"), 0, new BitVector[] { null, bv(1), bv(punc) });
+ this.count = new DockInPort("in2", ship.getDock("in2"), 0, new BitVector[] { null, bv(1), bv(punc) });
}
}
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[] {
+ private final Ship ship = dfg.pool.allocateShip("Counter");
+ private final InPort inOp = new DockInPort("inOp", ship.getDock("inOp"), 0, new BitVector[] {
ship.getDock("inOp").getConstant("REPEAT_C1_V2") });
+
+ public final InPort count = new DockInPort("count", ship.getDock("in1"));
+ public final InPort val = new DockInPort("val", ship.getDock("in2"));
public final OutPort out = new DockOutPort("out", ship.getDock("out"));
+
public RepeatNode(DataFlowGraph dfg) { super(dfg); }
}
import edu.berkeley.fleet.api.*;
public class SortedMergeNode extends Node {
- public final Ship ship = dfg.pool.allocateShip("Alu");
+ private final Ship ship = dfg.pool.allocateShip("Alu");
+ private final InPort inOp = new DockInPort("inOp", ship.getDock("inOp"), 0, new BitVector[] {
+ ship.getDock("inOp").getConstant("MAXMERGE") });
+
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 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, bv(1) });
- public final InPort op = new DockInPort("inOp", ship.getDock("inOp"), 0, new BitVector[] {
+ private final InPort op = new DockInPort("op", ship.getDock("inOp"), 0, new BitVector[] {
ship.getDock("inOp").getConstant("PASS_C2_V1"),
ship.getDock("inOp").getConstant("DROP_C2_V1") } );
+
+ public final OutPort out = new DockOutPort("out", ship.getDock("out"));
+ public final InPort val = new DockInPort("val", ship.getDock("in1"));
+ public final InPort count = new DockInPort("count", ship.getDock("in2"), 0, new BitVector[] { null, bv(1) });
+
public UnPunctuatorNode(DataFlowGraph dfg) { super(dfg); }
}
*
*/
+ final Program program;
+ final Instruction[] instructions;
+ final long baseAddress;
+
/**
* Given a Context, creates a CodeBag which will live in the
* Memory ship memoryShip at the address given by baseAddress.
*/
- public CodeBag(Context ctx, Ship memoryShip, long baseAddress) {
-
- }
+ CodeBag(Program program, Instruction[] instructions, long baseAddress) {
+ this.program = program;
+ this.instructions = instructions;
+ this.baseAddress = baseAddress;
+ // FIXME
+ if (instructions.length >= (1<<7))
+ throw new RuntimeException("code bag size is "+instructions.length+", which exceeds maximum of "+((1<<7)-1));
+ }
}
HashSet<LoopFactory> loopFactories = new HashSet<LoopFactory>();
private final ShipPool pool;
+
+ // FIXME: currently not used
+ private boolean sealed = false;
+ public boolean isSealed() { return sealed; }
+
public Context(Fleet fleet) { this(fleet, new ShipPool(fleet)); }
public Context(Fleet fleet, ShipPool pool) {
this.fleet = fleet;
public void setAutoflush(boolean a) { this.autoflush = a; }
public void emit(ArrayList<Instruction> ic) {
+ sealed = true;
for(LoopFactory lf : startupLoopFactories.values())
lf.emit(ic);
}
- public void dispatch(FleetProcess fp) {
+ public Instruction[] emit() {
+ ArrayList<Instruction> ic = new ArrayList<Instruction>();
+ emit(ic);
+ return (Instruction[])ic.toArray(new Instruction[0]);
+ }
+
+ public void dispatch(FleetProcess fp) { dispatch(fp, false); }
+ public void dispatch(FleetProcess fp, boolean flushWhenDone) {
ArrayList<Instruction> ai;
emit(ai = new ArrayList<Instruction>());
- for(Instruction ins : ai) {
+ for(Instruction ins : ai)
fp.sendInstruction(ins);
- }
+ if (flushWhenDone) fp.flush();
}
}
return bv;
}
+ public static void putMemoryShipInDispatchMode(FleetProcess fp, Ship memoryShip) {
+ Context ctx = new Context(fp.getFleet());
+ LoopFactory lf;
+ lf = new LoopFactory(ctx, memoryShip.getDock("out"), 0);
+ lf.abortLoopIfTorpedoPresent();
+ lf.collectPacket();
+ lf.sendWord(null);
+ ctx.dispatch(fp);
+ }
+
+ public static void removeMemoryShipFromDispatchMode(FleetProcess fp, Ship memoryShip) {
+ fp.sendToken(memoryShip.getDock("out").getInstructionDestination());
+ }
+
public static void main(String[] s) throws Exception {
Random random = new Random(System.currentTimeMillis());
Fleet fleet = new Fpga();
public Iterator<Ship> iterator() { return allocatedShips.iterator(); }
+ public void allocateShip(Ship ship) {
+ if (allocatedShips.contains(ship))
+ throw new RuntimeException("already allocated!");
+ allocatedShips.add(ship);
+ }
+
/** allocate a ship */
public Ship allocateShip(String type) {
Ship ship = null;