add src/edu/berkeley/fleet/ir/Gadgets.java
authoradam <adam@megacz.com>
Mon, 3 Nov 2008 10:18:57 +0000 (11:18 +0100)
committeradam <adam@megacz.com>
Mon, 3 Nov 2008 10:18:57 +0000 (11:18 +0100)
src/edu/berkeley/fleet/ir/Gadgets.java [new file with mode: 0644]

diff --git a/src/edu/berkeley/fleet/ir/Gadgets.java b/src/edu/berkeley/fleet/ir/Gadgets.java
new file mode 100644 (file)
index 0000000..d2aa279
--- /dev/null
@@ -0,0 +1,241 @@
+package edu.berkeley.fleet.ir;
+import java.util.concurrent.Semaphore;
+import java.util.*;
+import java.net.*;
+import edu.berkeley.fleet.two.*;
+import edu.berkeley.fleet.fpga.*;
+import edu.berkeley.fleet.api.*;
+import edu.berkeley.fleet.api.Instruction.*;
+import edu.berkeley.fleet.api.Instruction.Set;
+import edu.berkeley.fleet.api.Instruction.Set.*;
+import edu.berkeley.fleet.ir.Context.LoopFactory;
+import static edu.berkeley.fleet.util.BitManipulations.*;
+import edu.berkeley.fleet.api.Instruction.Set.FlagFunction;
+import edu.berkeley.fleet.api.Instruction.Set;
+import edu.berkeley.fleet.api.Instruction.Set.SetDest;
+import edu.berkeley.fleet.api.Instruction.Set.FlagFunction;
+import static edu.berkeley.fleet.api.Predicate.*;
+import edu.berkeley.fleet.ir.Context.LoopFactory;
+
+/*
+  - Change Alu behavior to "drain one"
+  - DROP1, DROP2
+  - secondary DDR chip
+  - facility for launching and Concluding a context
+  - implement the merge operation and test it
+  - test case for DRAM ship
+  - hideously ugly hacks in Verilog.java!
+  - dispatch ALWAYS needs to go via memory first, unless transmissions to
+    debugIn are flow-controlled properly
+  - current write-to-mem transformation screws up -- it can clog
+ */
+
+public class Gadgets {
+
+    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, BitVector[] vals) throws RuntimeException {
+        doMem(false, fp, memory, offset, vals);
+    }
+    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();
+
+        final Semaphore sem = new Semaphore(12 /* FIXME */);
+
+        Context ctx = new Context(fp.getFleet());
+        LoopFactory lf;
+        if (read) {
+            lf = ctx.new LoopFactory(inAddrRead, 0);
+            lf.abortLoopIfTorpedoPresent();
+            lf.recvWord();
+            lf.deliver();
+        } else {
+            lf = ctx.new LoopFactory(inAddrWrite, 0);
+            lf.abortLoopIfTorpedoPresent();
+            lf.recvWord();
+            lf.deliver();
+            lf = ctx.new LoopFactory(inDataWrite, 0);
+            lf.abortLoopIfTorpedoPresent();
+            lf.recvWord();
+            lf.deliver();
+        }
+
+        lf = ctx.new LoopFactory(out, 0);
+        lf.abortLoopIfTorpedoPresent();
+        lf.collectWord();
+        lf.sendWord(debugIn.getDataDestination());
+
+        lf = ctx.new LoopFactory(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();
+        }
+
+        if (read) {
+            fp.sendToken(inAddrRead.getInstructionDestination());
+        } else {
+            fp.sendToken(inAddrWrite.getInstructionDestination());
+            fp.sendToken(inDataWrite.getInstructionDestination());
+        }
+        fp.sendToken(out.getInstructionDestination());
+        fp.sendToken(debugIn.getInstructionDestination());
+        System.out.println();
+    }
+
+    /** returns the output Dock at which the merged values may be collected */
+    public static Dock mergeSort(FleetProcess fp,
+                                 Context ctx,
+                                 Ship sourceMem,
+                                 Ship destMem,
+                                 long read_start,
+                                 long write_start,
+                                 int  stride_length,    /* per arity */
+                                 int  num_strides,
+                                 int  arity
+                                 )
+        throws RuntimeException {
+
+        if (arity != 2) throw new RuntimeException();
+        if (num_strides != 1) throw new RuntimeException();
+        LoopFactory lf;
+
+        Dock mem_inAddrData = sourceMem.getDock("inAddrData");
+        Dock mem_out        = sourceMem.getDock("out");
+
+        Ship merger = ctx.allocateShip("Alu");
+        Dock[] merger_inputs = new Dock[] { merger.getDock("in1"), merger.getDock("in2") };
+        Dock merger_inOp = merger.getDock("inOp");
+
+        // Address Generators (arity-many) /////////////////////////////////////////////////////////////////////
+
+        Ship[] address_generators = new Ship[arity];
+        for(int i=0; i<address_generators.length; i++) {
+            address_generators[i] = ctx.allocateShip("Alu");
+            long start = read_start + i*stride_length;
+            int  count = stride_length;
+
+            Dock ag_out = address_generators[i].getDock("out");
+            Dock ag_op  = address_generators[i].getDock("inOp");
+            Dock ag_in1 = address_generators[i].getDock("in1");
+            Dock ag_in2 = address_generators[i].getDock("in2");
+            BitVector signal = new BitVector(1/*FIXME*/).set(i/*FIXME*/);
+
+            lf = ctx.new LoopFactory(ag_in1, 0);
+            lf.literal(1);
+            lf = lf.makeNext(count);
+            
+
+            lf = ctx.new LoopFactory(ag_out, 1);
+            lf.literal(start);
+            lf = lf.makeNext(0);
+            lf.recvToken();
+            lf.sendWord(mem_inAddrData.getDataDestination(), signal);
+            //lf.sendWord(ag_in1);
+            // FIXME ...
+        }
+
+        // Memory Read ////////////////////////////////////////////////////////////////////////////////////////
+
+        lf = ctx.new LoopFactory(mem_inAddrData, 0);
+        lf.recvWord();
+        lf.setFlags(FlagFunction.ZERO.add(FlagC), FlagFunction.ZERO);
+        lf.setPredicate(Predicate.NotFlagA);
+        lf.sendToken(mem_out.getDataDestination(), new BitVector(1/*FIXME*/).set(0));   // note: arity-many tokens may pile up at mem_out...
+        lf.setPredicate(Predicate.FlagA);
+        lf.sendToken(mem_out.getDataDestination(), new BitVector(1/*FIXME*/).set(1));
+        lf.setPredicate(null);
+        lf.deliver();
+
+        lf = ctx.new LoopFactory(mem_out, 0);
+        lf.collectWord();
+        lf.recvToken();
+        lf.setFlags(FlagFunction.ZERO.add(FlagC), FlagFunction.ZERO);
+        lf.setPredicate(Predicate.NotFlagA);
+        lf.sendWord(merger_inputs[0].getDataDestination());
+        lf.setPredicate(Predicate.FlagA);
+        lf.sendWord(merger_inputs[1].getDataDestination());
+        lf.setPredicate(null);
+
+        // Merger /////////////////////////////////////////////////////////////////////////////////////////////
+
+        for(int i=0; i<merger_inputs.length; i++) {
+            lf = ctx.new LoopFactory(merger_inputs[i], stride_length);
+            lf.sendToken(address_generators[i].getDock("out").getDataDestination());
+            lf.recvWord();
+            lf.deliver();
+
+            lf = lf.makeNext(1);
+            lf.literal(-1);
+            lf.deliver();
+        }
+
+        lf = ctx.new LoopFactory(merger_inOp, 1);
+        lf.literal(5); // MIN
+        lf = lf.makeNext(stride_length * arity);
+        lf.deliver();
+        lf = lf.makeNext(1);
+        lf.literal(7); // DROP1
+        lf.deliver();
+        lf.literal(8); // DROP2
+        lf.deliver();
+
+        return merger.getDock("out");
+    }
+
+    public static void main(String[] s) throws Exception {
+        Random random = new Random(System.currentTimeMillis());
+        Fleet fleet = new Fpga();
+        FleetProcess fp = fleet.run(new Instruction[0]);
+        Ship memory = fleet.getShip("DRAM",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++)
+            vals[i] = new BitVector(fleet.getWordWidth()).set(random.nextLong());
+        writeMem(fp, memory, 0, vals);
+        readMem(fp, memory, 0, vals2);
+        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!");
+    }
+}