updates to get some of the shutdown code to execute via Program
authormegacz <adam@megacz.com>
Sun, 15 Mar 2009 04:15:59 +0000 (21:15 -0700)
committermegacz <adam@megacz.com>
Sun, 15 Mar 2009 04:15:59 +0000 (21:15 -0700)
15 files changed:
src/edu/berkeley/fleet/dataflow/AluNode.java
src/edu/berkeley/fleet/dataflow/DataFlowGraph.java
src/edu/berkeley/fleet/dataflow/DebugNode.java
src/edu/berkeley/fleet/dataflow/DownCounterNode.java
src/edu/berkeley/fleet/dataflow/MemoryNode.java
src/edu/berkeley/fleet/dataflow/MergeSort.java
src/edu/berkeley/fleet/dataflow/Node.java
src/edu/berkeley/fleet/dataflow/PunctuatorNode.java
src/edu/berkeley/fleet/dataflow/RepeatNode.java
src/edu/berkeley/fleet/dataflow/SortedMergeNode.java
src/edu/berkeley/fleet/dataflow/UnPunctuatorNode.java
src/edu/berkeley/fleet/loops/CodeBag.java
src/edu/berkeley/fleet/loops/Context.java
src/edu/berkeley/fleet/loops/MemoryUtils.java
src/edu/berkeley/fleet/loops/ShipPool.java

index 2ba00cc..b5fa765 100644 (file)
@@ -4,10 +4,12 @@ import edu.berkeley.fleet.loops.*;
 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); }
 }
index 5419c93..9ab17f6 100644 (file)
@@ -5,12 +5,6 @@ import edu.berkeley.fleet.api.*;
 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;
index 36f20e9..1c6e842 100644 (file)
@@ -4,8 +4,7 @@ import edu.berkeley.fleet.loops.*;
 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); }
 }
index fb03f6c..a17daef 100644 (file)
@@ -4,11 +4,13 @@ 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"));
+    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); }
 }
index 68414ca..f0f3cad 100644 (file)
@@ -9,7 +9,7 @@ import static edu.berkeley.fleet.api.Predicate.*;
 
 
 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;
index db2790d..9a8c70e 100644 (file)
@@ -6,7 +6,7 @@ import edu.berkeley.fleet.fpga.*;
 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 {
 
@@ -18,7 +18,7 @@ public class MergeSort {
 
         //////////////////////////////////////////////////////////////////////////////
 
-        DataFlowGraph proc = new DataFlowGraph(fleet);
+        DataFlowGraph proc = new DataFlowGraph(fleet, pool);
         DebugNode dm = new DebugNode(proc);
 
         int end_of_data = vals_length;
@@ -70,17 +70,12 @@ public class MergeSort {
 
         //////////////////////////////////////////////////////////////////////////////
 
+        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+"  ");
@@ -89,68 +84,71 @@ public class MergeSort {
         }
         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:");
@@ -203,8 +201,12 @@ public class MergeSort {
             // 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);
index 640d488..b4bb13a 100644 (file)
@@ -15,84 +15,6 @@ import static edu.berkeley.fleet.util.BitManipulations.*;
 
 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;
@@ -100,10 +22,6 @@ public class Node {
     }
 
     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;
@@ -120,6 +38,7 @@ public class Node {
         }
         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 {
@@ -249,4 +168,94 @@ public class Node {
         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;
+    }
+
 }
index aff99fd..cee58ae 100644 (file)
@@ -6,15 +6,17 @@ 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[] {
+    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) });
     }
 }
index 7edf678..2cc54db 100644 (file)
@@ -4,11 +4,13 @@ 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[] {
+    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); }
 }
index eade9c7..7de8a8b 100644 (file)
@@ -4,11 +4,13 @@ import edu.berkeley.fleet.loops.*;
 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); }
 }
index be74d60..038b388 100644 (file)
@@ -5,11 +5,13 @@ 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, 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); }
 }
index 1e6a9f2..e14ed17 100644 (file)
@@ -31,13 +31,22 @@ public class CodeBag {
      * 
      */
 
+    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));
+    }
 
 }
index 00bd35d..0f0f0d0 100644 (file)
@@ -47,6 +47,11 @@ public class Context {
     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;
@@ -58,16 +63,24 @@ public class Context {
     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();
     }
 
 }
index bfbd26a..78d80f0 100644 (file)
@@ -114,6 +114,20 @@ public class MemoryUtils {
         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();
index 673872a..e829c7c 100644 (file)
@@ -23,6 +23,12 @@ public class ShipPool implements Iterable<Ship> {
 
     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;