remove extraneous torpedo transmission from MemoryUtils
[fleet.git] / src / edu / berkeley / fleet / loops / MemoryUtils.java
index 78d80f0..8290954 100644 (file)
@@ -2,6 +2,7 @@ package edu.berkeley.fleet.loops;
 import edu.berkeley.fleet.loops.*;
 import java.util.concurrent.Semaphore;
 import java.util.*;
+import java.io.*;
 import java.net.*;
 import edu.berkeley.fleet.two.*;
 import edu.berkeley.fleet.fpga.*;
@@ -15,117 +16,192 @@ import static edu.berkeley.fleet.api.Predicate.*;
 
 public class MemoryUtils {
 
-    public static void readMem(FleetProcess fp, Ship memory, long offset, BitVector[] vals) throws RuntimeException {
-        doMem(true, fp, memory, offset, vals);
-    }
-    public static void writeMem(FleetProcess fp, Ship memory, long offset, long[] vals) throws RuntimeException {
-        doMem(false, fp, memory, offset, long2bv(fp.getFleet(), vals));
+    public static void readMem(FleetProcess fp,
+                               ShipPool pool,
+                               Ship memory,
+                               long offset,
+                               BitVector[] vals) throws RuntimeException {
+        try {
+            Ship alu = pool.allocateShip("Alu");
+            pool.assertAllocated(memory);
+            MemoryInputStream mos = new MemoryInputStream(fp, pool, memory, alu, offset, 1);
+            fp.flush();
+            for(int i=0; i<vals.length; i++) {
+                int pct = (int)Math.ceil(100.0*((double)(i)/((double)(vals.length-1))));
+                String status = i + "/" + (vals.length-1) + "= " + pct + "%";
+                System.out.print("\rreading from address: " + status + "...");
+                vals[i] = mos.readWord();
+                System.out.print("\rread    from address: " + status + ", got " + vals[i] + " = " + vals[i].toLong()+"           ");
+            }
+            mos.close();
+            pool.releaseShip(alu);
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
     }
-    public static void writeMem(FleetProcess fp, Ship memory, long offset, BitVector[] vals) throws RuntimeException {
-        doMem(false, fp, memory, offset, vals);
+
+    public static void writeMem(FleetProcess fp,
+                                ShipPool pool,
+                                Ship memory,
+                                long offset,
+                                BitVector[] vals) throws RuntimeException {
+        try {
+            Ship alu = pool.allocateShip("Alu");
+            pool.assertAllocated(memory);
+            MemoryOutputStream mos = new MemoryOutputStream(fp, pool, memory, alu, offset);
+            for(int i=0; i<vals.length; i++) {
+                int pct = (int)Math.ceil(100.0*((double)(i)/((double)(vals.length-1))));
+                String status = i + "/" + (vals.length-1) + "= " + pct + "%";
+                System.out.print("\rwrote to address: " + status +"           ");
+                mos.writeWord(vals[i]);
+            }
+            mos.close();
+            pool.releaseShip(alu);
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
     }
-    public static void doMem(final boolean read, final FleetProcess fp, final Ship memory, final long offset, final BitVector[] vals) throws RuntimeException {
-        if (fp.getFleet() != memory.getFleet())
-            throw new RuntimeException("Fleet mismatch");
 
-        final Dock inAddrWrite = memory.getDock("inAddrWrite");
-        final Dock inDataWrite = memory.getDock("inDataWrite");
-        final Dock inAddrRead  = memory.getDock("inAddrRead");
-        final Dock out         = memory.getDock("out");
-        final Dock debugIn     = fp.getDebugInputDock();
+    public static class MemoryOutputStream extends DockOutputStream {
 
-        final Semaphore sem = new Semaphore(12 /* FIXME */);
+        private FleetProcess fp;
+        private Ship memory;
+        private Ship alu;
 
-        Context ctx = new Context(fp.getFleet());
-        LoopFactory lf;
-        if (read) {
-            lf = new LoopFactory(ctx, inAddrRead, 0);
-            lf.abortLoopIfTorpedoPresent();
-            lf.recvWord();
-            lf.deliver();
-        } else {
-            lf = new LoopFactory(ctx, inAddrWrite, 0);
-            lf.abortLoopIfTorpedoPresent();
-            lf.recvWord();
-            lf.deliver();
-            lf = new LoopFactory(ctx, inDataWrite, 0);
+        public MemoryOutputStream(FleetProcess fp,
+                                  ShipPool pool,
+                                  Ship memory,
+                                  Ship alu,
+                                  long offset) throws IOException {
+
+            super(fp, pool, memory.getDock("inDataWrite"), alu.getDock("out").getDataDestination());
+            pool.assertAllocated(memory);
+            pool.assertAllocated(alu);
+
+            this.fp = fp;
+            this.memory = memory;
+            this.alu = alu;
+
+            buildIt(fp, memory, alu, memory.getDock("inAddrWrite"), offset);
+            CodeBag cb = new CodeBag(fp.getFleet());
+            LoopFactory lf;
+            lf = cb.loopFactory(memory.getDock("out"), 0);
             lf.abortLoopIfTorpedoPresent();
-            lf.recvWord();
-            lf.deliver();
+            lf.collectWord();
+            cb.dispatch(fp);
         }
 
-        lf = new LoopFactory(ctx, out, 0);
-        lf.abortLoopIfTorpedoPresent();
-        lf.collectWord();
-        lf.sendWord(debugIn.getDataDestination());
+        public void close() {
+            super.close();
+            fp.sendTorpedo(memory.getDock("inAddrWrite"));
+            fp.sendTorpedo(memory.getDock("out"));
+            fp.sendTorpedo(alu.getDock("in1"));
+            fp.sendTorpedo(alu.getDock("in2"));
+            fp.sendTorpedo(alu.getDock("inOp"));
+            fp.sendTorpedo(alu.getDock("out"));
+        }
 
-        lf = new LoopFactory(ctx, debugIn, 0);
-        lf.abortLoopIfTorpedoPresent();
-        lf.recvWord();
-        lf.deliver();
+    }
 
-        ArrayList<Instruction> ai = new ArrayList<Instruction>();
-        ctx.emit(ai);
-        for(Instruction ins : ai)
-            fp.sendInstruction(ins);
-
-        new Thread() {
-            public void run() { try {
-                    for(int i=0; i<vals.length; i++) {
-                        if (!sem.tryAcquire()) {
-                            fp.flush();
-                            sem.acquire();
-                        }
-                        if (read) {
-                            fp.sendWord(inAddrRead.getDataDestination(), new BitVector(fp.getFleet().getWordWidth()).set(i+offset));
-                        } else {
-                            fp.sendWord(inAddrWrite.getDataDestination(), new BitVector(fp.getFleet().getWordWidth()).set(i+offset));
-                            fp.sendWord(inDataWrite.getDataDestination(), vals[i]);
-                        }
-                    }
-                    fp.flush();
-                } catch (Exception e) { throw new RuntimeException(e); }
-                }
-        }.start();
 
-        for(int i=0; i<vals.length; i++) {
-            BitVector outv = fp.recvWord();
-            if (read) vals[i] = outv;
-            if (read) System.out.print("\rread from address: " + i + ", got " + vals[i] + " = " + vals[i].toLong()+"           ");
-            else      System.out.print("\rwrote to address: " + i+"           ");
-            sem.release();
+    public static class MemoryInputStream extends DockInputStream {
+
+        private FleetProcess fp;
+        private Ship memory;
+        private Ship alu;
+
+        public MemoryInputStream(FleetProcess fp,
+                                 ShipPool pool,
+                                 Ship memory,
+                                 Ship alu,
+                                 long offset,
+                                 int inflight) throws IOException {
+            super(fp, pool, memory.getDock("out"), alu.getDock("out").getDataDestination(), inflight);
+            pool.assertAllocated(memory);
+            pool.assertAllocated(alu);
+            this.fp = fp;
+            this.memory = memory;
+            this.alu = alu;
+            buildIt(fp, memory, alu, memory.getDock("inAddrRead"), offset);
         }
 
-        if (read) {
-            fp.sendToken(inAddrRead.getInstructionDestination());
-        } else {
-            fp.sendToken(inAddrWrite.getInstructionDestination());
-            fp.sendToken(inDataWrite.getInstructionDestination());
+        public void close() {
+            super.close();
+            fp.sendTorpedo(memory.getDock("inAddrRead"));
+            fp.sendTorpedo(alu.getDock("in1"));
+            fp.sendTorpedo(alu.getDock("in2"));
+            fp.sendTorpedo(alu.getDock("inOp"));
+            fp.sendTorpedo(alu.getDock("out"));
         }
-        fp.sendToken(out.getInstructionDestination());
-        fp.sendToken(debugIn.getInstructionDestination());
-        System.out.println();
     }
 
-    private static BitVector[] long2bv(Fleet fleet, long[] initialValues) {
-        BitVector[] bv = new BitVector[initialValues.length];
-        for(int i=0; i<initialValues.length; i++)
-            bv[i] = new BitVector(fleet.getWordWidth()).set(initialValues[i]);
-        return bv;
+    private static void buildIt(FleetProcess fp, Ship memory, Ship alu, Dock dest, long offset) {
+
+        CodeBag ctx = new CodeBag(fp.getFleet());
+
+        LoopFactory lf;
+        // alu.in1: receive and deliver
+        lf = ctx.loopFactory(alu.getDock("in1"), 0);
+        lf.abortLoopIfTorpedoPresent();
+        lf.recvWord();
+        lf.deliver();
+            
+        // alu.in2: receive tokens, deliver 1's
+        lf = ctx.loopFactory(alu.getDock("in2"), 1);
+        lf.literal(1);
+        lf = lf.makeNext(0);
+        lf.abortLoopIfTorpedoPresent();
+        lf.recvToken();
+        lf.deliver();
+            
+        // alu.inOp: receive tokens, deliver ADD's
+        lf = ctx.loopFactory(alu.getDock("inOp"), 1);
+        lf.literal("ADD");
+        lf = lf.makeNext(0);
+        lf.abortLoopIfTorpedoPresent();
+        lf.recvToken();
+        lf.deliver();
+            
+        // alu.out: for each token, provide a word of count-data
+        lf = ctx.loopFactory(alu.getDock("out"), 1);
+        lf.literal(offset);
+        lf = lf.makeNext(0);
+        lf.abortLoopIfTorpedoPresent();
+        lf.recvToken();
+        lf.sendWord(dest);
+        lf.sendWord(alu.getDock("in1"));
+        lf.sendToken(alu.getDock("in2"));
+        lf.sendToken(alu.getDock("inOp"));
+        lf.collectWord();
+
+        lf = ctx.loopFactory(dest, 0);
+        lf.abortLoopIfTorpedoPresent();
+        lf.recvWord();
+        lf.deliver();
+
+        ctx.dispatch(fp);
     }
 
     public static void putMemoryShipInDispatchMode(FleetProcess fp, Ship memoryShip) {
-        Context ctx = new Context(fp.getFleet());
+        CodeBag ctx = new CodeBag(fp.getFleet());
         LoopFactory lf;
-        lf = new LoopFactory(ctx, memoryShip.getDock("out"), 0);
+
+        lf = ctx.loopFactory(memoryShip.getDock("out"), 0);
         lf.abortLoopIfTorpedoPresent();
         lf.collectPacket();
-        lf.sendWord(null);
+        lf.sendPacket();
+
+        lf = ctx.loopFactory(memoryShip.getDock("inCBD"), 0);
+        lf.abortLoopIfTorpedoPresent();
+        lf.recvWord();
+        lf.deliver();
+
         ctx.dispatch(fp);
     }
 
     public static void removeMemoryShipFromDispatchMode(FleetProcess fp, Ship memoryShip) {
         fp.sendToken(memoryShip.getDock("out").getInstructionDestination());
+        fp.sendToken(memoryShip.getDock("inCBD").getInstructionDestination());
     }
 
     public static void main(String[] s) throws Exception {
@@ -133,16 +209,33 @@ public class MemoryUtils {
         Fleet fleet = new Fpga();
         FleetProcess fp = fleet.run(new Instruction[0]);
         Ship memory = fleet.getShip("DDR2",0);
+        //Ship memory = fleet.getShip("Dvi",0);
         //Ship memory = fleet.getShip("Memory",0);
-        BitVector[] vals  = new BitVector[2 * 1024];
-        BitVector[] vals2 = new BitVector[2 * 1024];
-        for(int i=0; i<vals.length; i++)
+
+        //int size = (548 * 478) / 2;
+        int size = 2048;
+
+        BitVector[] vals  = new BitVector[size];
+        BitVector[] vals2 = new BitVector[size];
+
+        for(int i=0; i<vals.length; i++) {
             vals[i] = new BitVector(fleet.getWordWidth()).set(random.nextLong());
-        writeMem(fp, memory, 0, vals);
-        readMem(fp, memory, 0, vals2);
+            for(int j=36; j<vals[i].length(); j++)
+                vals[i].set(j, false);
+        }
+
+        ShipPool pool = new ShipPool(fleet);
+        pool.allocateShip(memory);
+        writeMem(fp, pool, memory, 0, vals);
+        readMem(fp, pool, memory, 0, vals2);
+        System.out.println();
+        int fails = 0;
         for(int i=0; i<vals.length; i++)
-            if (!vals[i].equals(vals2[i]))
-                System.out.println("disagreement!  on index " + i + "\n  "+vals[i]+"\n  "+vals2[i]);
-        System.out.println("done!");
+            if (!vals[i].equals(vals2[i])) {
+                System.out.println("disagreement!  on index " + i + "\n  expected="+vals[i]+"\n       got="+vals2[i]);
+                fails++;
+            }
+        System.out.println("done! ("+fails+" failures)");
+        if (fails>0) System.exit(-1);
     }
 }