MemoryNode: make sure not to do phase 0 of reset on out port
[fleet.git] / src / edu / berkeley / fleet / dataflow / MemoryNode.java
index 68414ca..e72f1c1 100644 (file)
@@ -2,6 +2,7 @@ package edu.berkeley.fleet.dataflow;
 import java.util.*;
 import edu.berkeley.fleet.loops.*;
 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.*;
@@ -9,7 +10,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;
@@ -21,49 +22,80 @@ public class MemoryNode extends Node {
     public MemoryNode(DataFlowGraph dfg, Ship memoryShip) {
         super(dfg);
         this.ship = memoryShip;
+
+        // ugly hack
+        if (ship.getType().equals("Dvi")) {
+            new DockInPort("inPixelX", ship.getDock("inPixelX"), 0, new BitVector[] { null });
+            new DockInPort("inPixelY", ship.getDock("inPixelY"), 0, new BitVector[] { null });
+            new DockInPort("inPixelValue", ship.getDock("inPixelValue"), 0, new BitVector[] { null });
+        }
+
         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.inAddrWrite  = new InPort("inAddrWrite") {
+                public void recvToken(LoopFactory lf) { lf.recvToken(); }
+                public void sendWord(LoopFactory lf) { lf.sendWord(ship.getDock("inAddrWrite").getDataDestination()); }
+                public void build(CodeBag ctx) {
+                    LoopFactory lf = ctx.loopFactory(ship.getDock("inAddrWrite"), 0);
+                    lf.abortLoopIfTorpedoPresent();
+                    lf.recvWord();
+                    lf.deliver();
+                }
+                public int getTokensToAbsorb() { return outWrite.peer.getTokensToAbsorb(); }
+                public int reset(CodeBag ctx, int phase, Destination ackDestination) {
+                    return DoneNode.doReset(ctx, phase, ship.getDock("inAddrWrite"), this, null, ackDestination, false);
+                }
+            };
         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 void build(CodeBag ctx) { }
                 public int getTokensToAbsorb() { return outRead1.peer.getTokensToAbsorb(); }
-                public int reset(Context ctx, int phase, Destination ackDestination, HashSet<Dock> sendTorpedoesTo) {
-                    return doReset(ctx, phase, ship.getDock("inAddrRead"), null, ackDestination, sendTorpedoesTo, false);
+                public int reset(CodeBag ctx, int phase, Destination ackDestination) {
+                    return DoneNode.doReset(ctx, phase, ship.getDock("inAddrRead"), this, 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 void build(CodeBag ctx) { }
                 public int getTokensToAbsorb() { return outRead2.peer.getTokensToAbsorb(); }
-                public int reset(Context ctx, int phase, Destination ackDestination, HashSet<Dock> sendTorpedoesTo) { return 0; }
+                public int reset(CodeBag ctx, int phase, Destination ackDestination) { return 0; }
             };
         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 int  reset(Context ctx, int phase, Destination ackDestination, HashSet<Dock> sendTorpedoesTo) { return 0; }
+                public int getNumInitialTokens() { return Math.max(1,Node.CAPACITY/2); }
+                public void build(CodeBag ctx) { }
+                public int  reset(CodeBag ctx, int phase, Destination ackDestination) { return 0; }
             };
         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 int  reset(Context ctx, int phase, Destination ackDestination, HashSet<Dock> sendTorpedoesTo) { return 0; }
+                public int getNumInitialTokens() { return Math.max(1,Node.CAPACITY/2); }
+                public void build(CodeBag ctx) { }
+                public int  reset(CodeBag ctx, int phase, Destination ackDestination) { return 0; }
             };
         this.outWrite = new DockOutPort("out", ship.getDock("out")) {
-                protected void build(Context ctx, LoopFactory lf) {
+                public void sendToken(LoopFactory lf) { inAddrWrite.peer.sendToken(lf); }
+                public void recvWord(LoopFactory lf) { lf.recvWord(); }
+                public int getTokensToAbsorb() { return 0; }
+                public int reset(CodeBag ctx, int phase, Destination ackDestination) {
+                    // ugly-ass hack
+                    if (phase!=0)
+                        return DoneNode.doReset(ctx, phase, dock, this, peer, ackDestination, true);
+                    return 0;
+                }
+                protected void build(CodeBag ctx, LoopFactory lf) {
                     lf = lf.makeNext(0);
                     lf.abortLoopIfTorpedoPresent();
                     lf.collectWord();
                         
-                    lf.setFlags(FlagFunction.ZERO, FlagFunction.ZERO.add(FlagC));
+                    lf.setFlags(FlagFunction.ONE, 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);
                     }
                         
@@ -83,11 +115,11 @@ public class MemoryNode extends Node {
                 }
             };
     }
-    public void build(Context ctx) {
+    public void build(CodeBag ctx) {
         super.build(ctx);
         LoopFactory lf;
 
-        lf = new LoopFactory(ctx, ship.getDock("inAddrRead"), 0);
+        lf = ctx.loopFactory(ship.getDock("inAddrRead"), 0);
         lf.abortLoopIfTorpedoPresent();
         lf.recvWord();
         lf.setFlags(FlagFunction.ZERO.add(FlagC), FlagFunction.ZERO);
@@ -98,4 +130,59 @@ public class MemoryNode extends Node {
         lf.setPredicate(null);
         lf.deliver();
     }
+
+
+
+    public static void clearMem(FleetProcess fp,
+                                Ship memory,
+                                ShipPool pool,
+                                long offset,
+                                long count) throws RuntimeException {
+
+        DataFlowGraph dfg = new DataFlowGraph(fp.getFleet(), pool);
+
+        MemoryNode mem = new MemoryNode(dfg, memory);
+        UnPunctuatorNode discard = new UnPunctuatorNode(dfg, true);
+        discard.count.connect(new OnceNode(dfg, (int)(count)).out);
+        DebugNode debug = new DebugNode(dfg);
+        DownCounterNode c1 = new DownCounterNode(dfg);
+        c1.start.connect(new OnceNode(dfg, count).out);
+        c1.incr.connect(new OnceNode(dfg, 1).out);
+        mem.inAddrWrite.connect(c1.out);
+        mem.inDataWrite.connect(new ForeverNode(dfg, 0).out);
+        mem.outWrite.connect(discard.val);
+        discard.out.connect(debug.in);
+
+        CodeBag ctx = new CodeBag(fp.getFleet());
+        dfg.build(ctx);
+        ctx.dispatch(fp, true);
+        System.out.println("waiting...");
+        fp.recvWord();
+        System.out.println("... done");
+
+        // FIXME: cleanup?
+    }
+
+    public static void main(String[] s) throws Exception {
+        Fleet fleet = new Fpga();
+        FleetProcess fp;
+        ShipPool pool = new ShipPool(fleet);
+        Ship mem1 = pool.allocateShip("Memory");
+        Ship mem2 = pool.allocateShip("Memory");
+        Ship mem3 = pool.allocateShip("Memory");
+
+        fp = fleet.run(new Instruction[0]);
+        clearMem(fp, mem1, new ShipPool(fleet), 0, 16 * 1024);
+        fp.terminate();
+
+        fp = fleet.run(new Instruction[0]);
+        clearMem(fp, mem2, new ShipPool(fleet), 0, 16 * 1024);
+        fp.terminate();
+
+        fp = fleet.run(new Instruction[0]);
+        clearMem(fp, mem3, new ShipPool(fleet), 0, 16 * 1024);
+        fp.terminate();
+    }
+
+
 }