switch MemoryUtil to use MemoryStream
authorAdam Megacz <adam@megacz.com>
Fri, 31 Jul 2009 23:39:18 +0000 (16:39 -0700)
committerAdam Megacz <adam@megacz.com>
Fri, 31 Jul 2009 23:39:18 +0000 (16:39 -0700)
src/edu/berkeley/fleet/loops/MemoryUtils.java

index 7a92a32..3f0bfe6 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.*;
@@ -130,137 +131,192 @@ public class MemoryUtils {
                              final ShipPool pool,
                              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     = read ? fp.getDebugInputDock() : null;
-        if (debugIn!=null) pool.allocateShip(debugIn.getShip());
+                             final BitVector[] vals) {
+
+        try {
+            MemoryOutputStream mos = new MemoryOutputStream(fp, pool, memory, offset, read);
+            for(int i=0; i<vals.length; i++) {
+                if (read) vals[i] = mos.readWord();
+                else      mos.writeWord(vals[i]);
+                int pct = (int)Math.ceil(100.0*((double)(i)/((double)(vals.length-1))));
+                String status = i + "/" + (vals.length-1) + "= " + pct + "%";
+                if (read) System.out.print("\rread from address: " + status + ", got " + vals[i] + " = " + vals[i].toLong()+"           ");
+                else      System.out.print("\rwrote to address: " + status +"           ");
+            }
+            mos.close();
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
 
-        Ship counter = pool.allocateShip("Counter");
-        Dock counter_in1  = counter.getDock("in1");
-        Dock counter_in2  = counter.getDock("in2");
-        Dock counter_inOp = counter.getDock("inOp");
-        Dock counter_out  = counter.getDock("out");
 
-        Ship alu = pool.allocateShip("Alu");
+    public static class MemoryOutputStream {
+        private FleetProcess fp;
+        private ShipPool pool;
+        private Ship memory;
+        private Ship alu;
+        private long offset;
+        private int inflight;
+        private boolean read;
+
+        public MemoryOutputStream(FleetProcess fp,
+                                  ShipPool pool,
+                                  Ship memory,
+                                  long offset,
+                                  boolean read) throws IOException {
+            this(fp, pool, memory, offset, read, 1);
+        }
 
-        CodeBag ctx = new CodeBag(fp.getFleet());
-        LoopFactory lf;
-        if (read) {
-            lf = ctx.loopFactory(inAddrRead, 0);
+        public MemoryOutputStream(FleetProcess fp,
+                                  ShipPool pool,
+                                  Ship memory,
+                                  long offset,
+                                  boolean read,
+                                  int inflight) throws IOException {
+
+            if (fp.getFleet() != memory.getFleet())
+                throw new RuntimeException("Fleet mismatch");
+            this.fp = fp;
+            this.pool = pool;
+            this.memory = memory;
+            this.offset = offset;
+            this.inflight = inflight;
+            this.read = read;
+            this.alu = pool.allocateShip("Alu");
+            pool.allocateShip(fp.getDebugInputDock().getShip());
+
+            CodeBag ctx = new CodeBag(fp.getFleet());
+            LoopFactory lf;
+
+            // alu.in1: receive and deliver
+            lf = ctx.loopFactory(alu.getDock("in1"), 0);
             lf.abortLoopIfTorpedoPresent();
-            lf.sendToken(counter_out);
             lf.recvWord();
             lf.deliver();
-        } else {
-            lf = ctx.loopFactory(inAddrWrite, 0);
-            lf.sendToken(counter_out);
+            
+            // alu.in2: receive tokens, deliver 1's
+            lf = ctx.loopFactory(alu.getDock("in2"), 1);
+            lf.literal(1);
+            lf = lf.makeNext(0);
             lf.abortLoopIfTorpedoPresent();
-            lf.recvWord();
+            lf.recvToken();
             lf.deliver();
-            lf = ctx.loopFactory(inDataWrite, 0);
+            
+            // alu.inOp: receive tokens, deliver ADD's
+            lf = ctx.loopFactory(alu.getDock("inOp"), 1);
+            lf.literal("ADD");
+            lf = lf.makeNext(0);
             lf.abortLoopIfTorpedoPresent();
-            lf.recvWord();
+            lf.recvToken();
             lf.deliver();
-        }
-
-        lf = ctx.loopFactory(counter_in1, 1);
-        lf.literal(vals.length);
-        lf.deliver();
-
-        lf = ctx.loopFactory(counter_in2, 1);
-        lf.literal(1);
-        lf.deliver();
-
-        lf = ctx.loopFactory(counter_inOp, 1);
-        lf.literal("COUNT");
-        lf.deliver();
-
-        lf = ctx.loopFactory(counter_out, 0);
-        lf.recvToken();
-        lf.abortLoopIfTorpedoPresent();
-        lf.collectWord();
-        lf.sendWord(alu.getDock("in1"));
-        lf.sendToken(alu.getDock("in2"));
-        lf.sendToken(alu.getDock("inOp"));
-
-        lf = ctx.loopFactory(alu.getDock("in1"), 0);
-        lf.abortLoopIfTorpedoPresent();
-        lf.recvWord();
-        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(read ? memory.getDock("inAddrRead") : memory.getDock("inAddrWrite"));
+            lf.sendWord(alu.getDock("in1"));
+            lf.sendToken(alu.getDock("in2"));
+            lf.sendToken(alu.getDock("inOp"));
+            lf.collectWord();
 
-        lf = ctx.loopFactory(alu.getDock("in2"), 0);
-        lf.abortLoopIfTorpedoPresent();
-        lf.recvToken();
-        lf.literal(offset);
-        lf.deliver();
+            if (read) {
+                // memory.inAddrRead: just recv and deliver
+                lf = ctx.loopFactory(memory.getDock("inAddrRead"), 0);
+                lf.abortLoopIfTorpedoPresent();
+                lf.recvWord();
+                lf.deliver();
+
+            } else {
+                // memory.inDataWrite: recv a word, send a token to alu.out, deliver the word
+                lf = ctx.loopFactory(memory.getDock("inDataWrite"), 0);
+                lf.abortLoopIfTorpedoPresent();
+                lf.recvWord();
+                lf.setFlags(FlagFunction.ZERO.add(FlagC), FlagFunction.ZERO);
+                lf.setPredicate(Predicate.FlagA);
+                lf.sendToken(fp.getDebugInputDock());
+                lf.setPredicate(Predicate.NotFlagA);
+                lf.sendToken(alu.getDock("out"));
+                lf.deliver();
+                lf.setPredicate(null);
+                
+                // memory.inAddrWrite: just recv and deliver
+                lf = ctx.loopFactory(memory.getDock("inAddrWrite"), 0);
+                lf.abortLoopIfTorpedoPresent();
+                lf.recvWord();
+                lf.deliver();
+            }
 
-        lf = ctx.loopFactory(alu.getDock("inOp"), 0);
-        lf.abortLoopIfTorpedoPresent();
-        lf.recvToken();
-        lf.literal("ADD");
-        lf.deliver();
+            // memory.out: send a token to debug.in, recv a word, deliver it
+            lf = ctx.loopFactory(memory.getDock("out"), 0);
+            lf.abortLoopIfTorpedoPresent();
+            lf.collectWord();
+            if (read) lf.sendWord(fp.getDebugInputDock());
+            // FIXME: perhaps feed-through here if we get fancy
 
-        lf = ctx.loopFactory(alu.getDock("out"), 0);
-        lf.abortLoopIfTorpedoPresent();
-        lf.collectWord();
-        lf.sendWord(read ? inAddrRead : inAddrWrite);
+            if (read) {
+                lf = ctx.loopFactory(fp.getDebugInputDock(), inflight);
+                lf.sendToken(alu.getDock("out"));
+                lf = lf.makeNext(0);
+                lf.abortLoopIfTorpedoPresent();
+                lf.recvWord();
+                lf.deliver();
+                lf.sendToken(alu.getDock("out"));
+            }
+            ctx.dispatch(fp);
+            fp.flush();
+        }
 
-        lf = ctx.loopFactory(out, 0);
-        if (read) lf.recvToken();
-        lf.abortLoopIfTorpedoPresent();
-        lf.collectWord();
-        if (read) lf.sendWord(debugIn.getDataDestination());
+        public BitVector readWord() {
+            return fp.recvWord();
+        }
 
-        if (read) {
-            lf = ctx.loopFactory(debugIn, 0);
-            lf.sendToken(out);
-            lf.abortLoopIfTorpedoPresent();
-            lf.recvWord();
-            lf.deliver();
+        public void writeWord(BitVector bv) {
+            fp.sendWord(memory.getDock("inDataWrite").getDataDestination(), bv, new BitVector(1).set(0));
         }
 
-        ctx.dispatch(fp);
+        public void close() {
+            CodeBag ctx = new CodeBag(fp.getFleet());
+            LoopFactory lf;
+            lf = ctx.loopFactory(fp.getDebugInputDock(), 1);
+            if (read) {
+                fp.sendTorpedo(fp.getDebugInputDock());
+                fp.flush();
+                for(int i=0; i<inflight; i++) // FIXME: use a loop counter here
+                    lf.recvWord();
+                lf.deliver();
+            } else {
+                lf.recvWord();
+                lf.deliver();
+                BitVector bv = new BitVector(fp.getFleet().getWordWidth());
+                fp.sendWord(memory.getDock("inDataWrite").getDataDestination(), bv, new BitVector(1).set(1));
+            }
+            ctx.dispatch(fp);
+            fp.flush();
+            fp.recvWord();
 
-        for(int i=vals.length-1; i>=0; i--) {
-            if (!read)
-                fp.sendWord(inDataWrite.getDataDestination(), vals[i]);
             if (read) {
-                BitVector outv = fp.recvWord();
-                vals[i] = outv;
+                fp.sendTorpedo(memory.getDock("inAddrRead"));
+            } else {
+                fp.sendTorpedo(memory.getDock("inAddrWrite"));
+                fp.sendTorpedo(memory.getDock("inDataWrite"));
             }
-            int pct = (int)Math.ceil(100.0*((double)(vals.length-1-i)/((double)(vals.length-1))));
-            String status = i + "/" + (vals.length-1) + "= " + pct + "%";
-            if (read) System.out.print("\rread from address: " + status + ", got " + vals[i] + " = " + vals[i].toLong()+"           ");
-            else      System.out.print("\rwrote to address: " + status +"           ");
-        }
-        fp.flush();
-
-        if (read) {
-            fp.sendToken(inAddrRead.getInstructionDestination());
-            fp.sendToken(debugIn.getInstructionDestination());
-        } else {
-            fp.sendToken(inAddrWrite.getInstructionDestination());
-            fp.sendToken(inDataWrite.getInstructionDestination());
-        }
-        fp.sendToken(alu.getDock("in1").getInstructionDestination());
-        fp.sendToken(alu.getDock("in2").getInstructionDestination());
-        fp.sendToken(alu.getDock("inOp").getInstructionDestination());
-        fp.sendToken(alu.getDock("out").getInstructionDestination());
-        fp.sendToken(counter_out.getInstructionDestination());
-        fp.sendToken(out.getInstructionDestination());
-        System.out.println();
 
-        pool.releaseShip(alu);
-        pool.releaseShip(counter);
-        if (read) pool.releaseShip(debugIn.getShip());
+            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"));
+            fp.flush();
+            
+            pool.releaseShip(alu);
+            pool.releaseShip(fp.getDebugInputDock().getShip());
+        }
     }
 
+
     private static BitVector[] long2bv(Fleet fleet, long[] initialValues) {
         BitVector[] bv = new BitVector[initialValues.length];
         for(int i=0; i<initialValues.length; i++)
@@ -294,8 +350,8 @@ public class MemoryUtils {
         Random random = new Random(System.currentTimeMillis());
         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("DDR2",0);
+        //Ship memory = fleet.getShip("Dvi",0);
         //Ship memory = fleet.getShip("Memory",0);
 
         //int size = (548 * 478) / 2;
@@ -311,21 +367,17 @@ public class MemoryUtils {
             vals[i].set(1, false);
         }
 
-        BitVector bv = new BitVector(fleet.getWordWidth());
-        /*
-        for(int i=0; i<bv.length(); i++) bv.set(i, true);
-        for(int i=0; i<vals.length; i++)
-            vals[i] = bv;
-        */
         ShipPool pool = new ShipPool(fleet);
         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("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);
     }
 }