total overhaul: fleetcode-1.0 api finished
authoradam <adam@megacz.com>
Wed, 25 Jun 2008 10:18:28 +0000 (11:18 +0100)
committeradam <adam@megacz.com>
Wed, 25 Jun 2008 10:18:28 +0000 (11:18 +0100)
52 files changed:
src/edu/berkeley/fleet/Main.java
src/edu/berkeley/fleet/api/BitVector.java [new file with mode: 0644]
src/edu/berkeley/fleet/api/Destination.java
src/edu/berkeley/fleet/api/Dock.java [new file with mode: 0644]
src/edu/berkeley/fleet/api/Fleet.java
src/edu/berkeley/fleet/api/FleetProcess.java
src/edu/berkeley/fleet/api/Instruction.java
src/edu/berkeley/fleet/api/Path.java [new file with mode: 0644]
src/edu/berkeley/fleet/api/Predicate.java [new file with mode: 0644]
src/edu/berkeley/fleet/api/Pump.java [deleted file]
src/edu/berkeley/fleet/api/Ship.java
src/edu/berkeley/fleet/api/package.html [new file with mode: 0644]
src/edu/berkeley/fleet/assembler/Main.java
src/edu/berkeley/fleet/assembler/Parser.java
src/edu/berkeley/fleet/assembler/fleet.g
src/edu/berkeley/fleet/doc/Constant.java [deleted file]
src/edu/berkeley/fleet/doc/Doc.java [deleted file]
src/edu/berkeley/fleet/doc/PumpDescription.java [deleted file]
src/edu/berkeley/fleet/doc/ShipDescription.java [deleted file]
src/edu/berkeley/fleet/fpga/Client.java
src/edu/berkeley/fleet/fpga/FabricElement.java [new file with mode: 0644]
src/edu/berkeley/fleet/fpga/FifoModule.java [new file with mode: 0644]
src/edu/berkeley/fleet/fpga/Fpga.java
src/edu/berkeley/fleet/fpga/FpgaDestination.java [new file with mode: 0644]
src/edu/berkeley/fleet/fpga/FpgaDock.java [new file with mode: 0644]
src/edu/berkeley/fleet/fpga/FpgaPath.java [new file with mode: 0644]
src/edu/berkeley/fleet/fpga/FpgaPump.java [deleted file]
src/edu/berkeley/fleet/fpga/FpgaShip.java
src/edu/berkeley/fleet/fpga/FunnelModule.java [new file with mode: 0644]
src/edu/berkeley/fleet/fpga/Generator.java [deleted file]
src/edu/berkeley/fleet/fpga/HornModule.java [new file with mode: 0644]
src/edu/berkeley/fleet/fpga/Server.java
src/edu/berkeley/fleet/fpga/main.v
src/edu/berkeley/fleet/fpga/main.xst
src/edu/berkeley/fleet/gasp/Verilog.java [new file with mode: 0644]
src/edu/berkeley/fleet/ies44/InstructionEncoder.java
src/edu/berkeley/fleet/interpreter/Inbox.java
src/edu/berkeley/fleet/interpreter/InstructionDock.java [moved from src/edu/berkeley/fleet/interpreter/InstructionPump.java with 69% similarity]
src/edu/berkeley/fleet/interpreter/Interpreter.java
src/edu/berkeley/fleet/interpreter/InterpreterDestination.java
src/edu/berkeley/fleet/interpreter/InterpreterDock.java [moved from src/edu/berkeley/fleet/interpreter/InterpreterPump.java with 63% similarity]
src/edu/berkeley/fleet/interpreter/InterpreterShip.java
src/edu/berkeley/fleet/interpreter/Log.java
src/edu/berkeley/fleet/interpreter/Outbox.java
src/edu/berkeley/fleet/interpreter/Packet.java
src/edu/berkeley/fleet/ir/IR.java [new file with mode: 0644]
src/edu/berkeley/fleet/two/DockDescription.java [new file with mode: 0644]
src/edu/berkeley/fleet/two/FleetTwoDock.java [new file with mode: 0644]
src/edu/berkeley/fleet/two/FleetTwoShip.java [new file with mode: 0644]
src/edu/berkeley/fleet/two/ShipDescription.java [new file with mode: 0644]
src/edu/berkeley/fleet/util/BitManipulations.java
src/edu/berkeley/fleet/util/Mask.java

index 74f89db..f7f21e3 100644 (file)
@@ -2,8 +2,9 @@ package edu.berkeley.fleet;
 import edu.berkeley.sbp.util.ANSI;
 import edu.berkeley.fleet.api.*;
 import edu.berkeley.fleet.fpga.*;
-import edu.berkeley.fleet.doc.*;
 import edu.berkeley.fleet.interpreter.*;
+import edu.berkeley.fleet.two.*;
+import edu.berkeley.fleet.util.*;
 import java.io.*;
 import java.util.*;
 
@@ -36,7 +37,7 @@ public class Main {
         Fleet fleet;
         if ("fpga".equals(target)) {
             String bitfile = options.get("bitfile");
-            fleet = bitfile == null ? new Fpga() : new Fpga(bitfile);
+            fleet = new Fpga();
         } else if ("sim".equals(target) || "fleetsim".equals(target)) {
             fleet = (Fleet)Class.forName("com.sunlabs.fleetsim.fleet.FleetDescription").newInstance();
         } else {
@@ -48,40 +49,37 @@ public class Main {
 
         if (command.equals("run")) {
             InputStream is;
-            if (args.size()==0) {
-                ByteArrayOutputStream baos = new ByteArrayOutputStream();
-                Reader r = new InputStreamReader(System.in);
-                edu.berkeley.fleet.assembler.Main.assemble(fleet, r, baos);
-                is = new ByteArrayInputStream(baos.toByteArray());
-            } else {
-                String filename = args.get(0);
-                if (filename.endsWith(".fa") || filename.endsWith(".fleet")) {
-                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
-                    Reader r = new InputStreamReader(new FileInputStream(args.get(0)));
-                    edu.berkeley.fleet.assembler.Main.assemble(fleet, r, baos);
-                    is = new ByteArrayInputStream(baos.toByteArray());
-                } else {
-                    is = new FileInputStream(args.get(0));
-                }
-            }
-            run(fleet, is);
+            String filename = args.get(0);
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            Reader r = new InputStreamReader(new FileInputStream(args.get(0)));
+            run(fleet, edu.berkeley.fleet.assembler.Main.assemble(fleet, r));
 
         } else if (command.equals("expand")) {
-            fleet.expand(new ShipDescription(args.get(0), new BufferedReader(new InputStreamReader(new FileInputStream(args.get(0))))));
+            String name = new File(args.get(0)).getName();
+            if (name.endsWith(".ship"))
+                name = name.substring(0, name.length() - ".ship".length());
+            if (fleet instanceof edu.berkeley.fleet.fpga.Fpga) {
+                ((edu.berkeley.fleet.fpga.Fpga)fleet).expand(new ShipDescription(name, new BufferedReader(new InputStreamReader(new FileInputStream(args.get(0))))));
+            } else {
+                ((Interpreter)fleet).expand(new ShipDescription(name, new BufferedReader(new InputStreamReader(new FileInputStream(args.get(0))))));
+            }
 
         } else if (command.equals("doc")) {
-            Doc.print();
+            if (!new File(".tmp").exists())
+                new File(".tmp").mkdirs();
+            PrintWriter pw = new PrintWriter(new FileOutputStream(".tmp/FleetTwo.Manual.tex"));
+            BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("doc/archman.tex")));
+            for(String ss = br.readLine(); ss!=null; ss = br.readLine())
+                pw.println(ss);
+            for(String f : new File("ships").list()) {
+                new ShipDescription(f, new BufferedReader(new InputStreamReader(new FileInputStream(new File("ships/"+f))))).printTeX(pw);
+            }
+            pw.println("\\end{document}");
+            pw.close();
 
         } else if (command.equals("test")) {
             for(int i=0; i<args.size(); i++)
                 test(fleet, new File(args.get(i)));
-        } else if (command.equals("asm")) {
-            String filename = args.get(0);
-            FileOutputStream out = new FileOutputStream("fleet.fo");
-            Reader r = new InputStreamReader(new FileInputStream(args.get(0)));
-            edu.berkeley.fleet.assembler.Main.assemble(fleet, r, out);
-            out.flush();
-
         } else {
             usage();
             System.exit(-1);
@@ -89,15 +87,15 @@ public class Main {
     }
 
     static void runTest(Fleet fleet, Reader reader, String title) throws Exception {
-            ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        edu.berkeley.fleet.assembler.Main.assemble(fleet, reader, baos);
+        Instruction[] instructions = edu.berkeley.fleet.assembler.Main.assemble(fleet, reader);
         if (edu.berkeley.fleet.assembler.Parser.skip) {
             System.out.println("\r[" + ANSI.yellow("SKIP") +
                                "] "  + ANSI.yellow(title));
             edu.berkeley.fleet.assembler.Parser.skip = false;
             return;
         }
-        FleetProcess fp = fleet.run(baos.toByteArray());
+        FleetProcess fp = fleet.run(instructions);
+        //long now = System.currentTimeMillis();
         try {
             ArrayList<Long> expect = edu.berkeley.fleet.assembler.Parser.expect;
             String output = "";
@@ -111,7 +109,8 @@ public class Main {
                 System.out.print("\r" + verdict + " " + ANSI.yellow(title) + ": " + output);
                 if (failed) break;
                 if (expect.size() == 0) break;
-                long l = fp.readWord();
+                //if (now!=0) { System.err.println(); System.err.println(System.currentTimeMillis()-now); now=0;}
+                long l = unBitSet(fp.readWord());
                 long l2 = expect.remove(0);
 
                 // FIXME, this is ugly and not size-independent
@@ -156,17 +155,10 @@ public class Main {
         }
     }
 
-    public static void run(Fleet fleet, InputStream is) throws IOException {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        byte[] buf = new byte[1024];
+    public static void run(Fleet fleet, Instruction[] instructions) throws IOException {
+        FleetProcess client = fleet.run(instructions);
         while(true) {
-            int numread = is.read(buf, 0, buf.length);
-            if (numread==-1) break;
-            baos.write(buf, 0, numread);
-        }
-        FleetProcess client = fleet.run(baos.toByteArray());
-        while(true) {
-            long result = client.readWord();
+            long result = unBitSet(client.readWord());
             System.err.print(result);
             System.err.print(" 0x");
             System.err.print(Long.toString(result, 16));
@@ -174,6 +166,17 @@ public class Main {
         }
     }
 
+    public static long unBitSet(BitVector bs) {
+        long val = 0;
+        for(int i=0; i<37; i++) {
+            if (bs.get(i))
+                val |= (1L << i);
+        }
+        if ((val & (1L << 36)) != 0)
+            val = val | (0xffffffffffffffffL << 36);
+        return val;
+    }
+
     static void usage() {
         System.err.println(".........................................................................");
         System.err.println("Fleet Framework                              UC Berkeley, Sun Labs / 2007");
diff --git a/src/edu/berkeley/fleet/api/BitVector.java b/src/edu/berkeley/fleet/api/BitVector.java
new file mode 100644 (file)
index 0000000..e217e6c
--- /dev/null
@@ -0,0 +1,45 @@
+package edu.berkeley.fleet.api;
+
+/**
+ *  A sequence of bits with a fixed length.  This class performs
+ *  important error-checking not found in the Java BitSet and
+ *  BigInteger classes.
+ */
+public class BitVector {
+
+    private final boolean[] bits;
+
+    public BitVector(int length) {
+        this.bits = new boolean[length];
+    }
+
+    /** copy the low-order bits of the argument into this BitVector; returns this */
+    public BitVector set(long value) {
+        for(int i=0; i<length(); i++)
+            set(i, ((value >>> i) & 1L) != 0);
+        return this;
+    }
+
+    public int length() {
+        return bits.length;
+    }
+    
+    public void set(int bit, boolean value) {
+        bits[bit] = value;
+    }
+
+    public boolean get(int bit) {
+        return bits[bit];
+    }
+
+    public String toString() {
+        StringBuffer ret = new StringBuffer();
+        ret.append(length()+"");
+        ret.append("'b");
+        for(int i=length()-1; i>=0; i--)
+            ret.append(get(i) ? '1' : '0');
+        return ret.toString();
+    }
+}
+
+
index eeda1d2..238db4f 100644 (file)
@@ -1,14 +1,21 @@
 package edu.berkeley.fleet.api;
 
+/**
+ *  A physical destination on the switch fabric -- may have multiple
+ *  paths to it from any particular source.
+ */
 public abstract class Destination {
 
-    /** return the Ship to which this Pump belongs */
-    public abstract Ship   getShip();
+    private final Dock dock;
+
+    public Destination(Dock dock) {
+        this.dock = dock;
+    }
+
+    /** Get the Dock to which this destination belongs, null if none. */
+    public Dock getDock() { return dock; }
+
+    /** subclasses must override this */
+    public abstract String toString();
 
-    /**
-     *  this returns the third component of the name; that is in
-     *  "ship.port.foo", it returns "foo", and in "ship.port" it
-     *  returns ""
-     */
-    public abstract String getDestinationName();
 }            
diff --git a/src/edu/berkeley/fleet/api/Dock.java b/src/edu/berkeley/fleet/api/Dock.java
new file mode 100644 (file)
index 0000000..c0d77af
--- /dev/null
@@ -0,0 +1,43 @@
+package edu.berkeley.fleet.api;
+import java.util.*;
+
+/** A dock on a ship */
+public abstract class Dock {
+
+    private final Ship ship;
+
+    public Dock(Ship ship) {
+        this.ship = ship;
+    }
+
+    /** return the Ship to which this Dock belongs */
+    public Ship getShip() { return ship; }
+
+    /** the descriptive name of this dock (relative to its ship) */
+    public abstract String getName();
+
+    /** returns true if this is an input dock */
+    public abstract boolean isInputDock();
+
+    /** returns true if this is an output dock */
+    public abstract boolean isOutputDock();
+
+    /** returns the <tt>Path</tt> from this dock to <tt>dest</tt>, carrying the signal specified or none if null */
+    public abstract Path        getPath(Destination dest, BitVector signal);
+
+    /** the data destination of this dock */
+    public abstract Destination getDataDestination();
+
+    /** the instruction destination of this dock */
+    public abstract Destination getInstructionDestination();
+
+    /** 
+     *  The maximum number of instructions we can put in the Dock
+     *  instruction fifo, or Integer.MAX_VALUE if unbounded; note that
+     *  this does not include the epilogue fifo -- that can be
+     *  determined with getInstructionDestination().getFifoLength()
+     */
+    public abstract int getInstructionFifoSize();
+
+    public String toString() { return getShip()+"."+getName(); }
+}            
index 6391bf5..48651f0 100644 (file)
@@ -1,35 +1,51 @@
 package edu.berkeley.fleet.api;
-import edu.berkeley.fleet.doc.*;
 import java.io.*;
 import java.util.*;
 
+/**
+ *  An instance of Fleet; each Fleet consists of a collection of
+ *  <tt>Ship</tt>s.
+ *
+ *  <p><b>Note about instruction representation:</b> it is very
+ *  important to understand that the binary representation of an
+ *  instruction includes a path from the dock which will
+ *  <i>dispatch</i> the instruction to the dock which will
+ *  <i>execute</i> the instruction.  Therefore, an instruction cannot
+ *  be converted <i>to</i> binary form without supplying a
+ *  <i>dispatching dock</i> so the necessary path can be computed.
+ *  <b>Moreover:</b> because a given string of bits uniquely describes
+ *  a path only if given along with a starting point, instructions
+ *  cannot be converted <i>from</i> binary format without knowing the
+ *  dispatch dock from which they are meant to be dispatched. <i>This
+ *  is why the {@link readInstruction} and {@link writeInstruction}
+ *  methods take a "<tt>dispatchFrom</tt>" argument.</i>
+ */
 public abstract class Fleet implements Iterable<Ship> {
 
-    /** read a machine-formatted instruction from a file (into a Java object) */
-    public abstract Instruction readInstruction(DataInputStream is) throws IOException;
-
-    /** write a machine-formatted instruction to a file (from a Java object) */
-    public abstract void        writeInstruction(DataOutputStream os, Instruction instr) throws IOException;
-
-    /** ships must be returned in the same order every time -- ordering may be significant */
     public abstract Iterator<Ship> iterator();
 
-    /** if possible, run the given code and create a FleetProcess */
-    public FleetProcess run(byte[] code) {
-        throw new RuntimeException("class " + this.getClass().getName() + " does not implement method run()");
-    }
+    /** A ship is uniquely identified by its type (a string) and its ordinal; for example, Fifo[7]. */
+    public abstract Ship getShip(String type, int ordinal);
 
-    /** extract the portion of ShipDescription which is specific to this fleet and generate any source code necessary */
-    public void expand(ShipDescription sd) {
-        throw new RuntimeException("class " + this.getClass().getName() + " does not implement method expand()");
-    }
+    /** the natural word width of this machine */
+    public abstract int getWordWidth();
 
     /**
-     *  This interface marks Fleets which can create ships on the fly, like the fleeterpreter;
-     *  if available, the parser will use this interface to create ships out of #ship definitions.
+     *  Read a machine-formatted instruction from a file.
+     *   @is           The stream to read from.
+     *   @dispatchFrom The dock from which the instructions being read are to be dispatched (required for decoding)
      */
-    public static interface WithDynamicShips {
-        public Ship createShip(String shiptype, String shipname);
-    }
+    public abstract Instruction readInstruction(DataInputStream is, Dock dispatchFrom) throws IOException;
 
-}
\ No newline at end of file
+    /**
+     *  Write a machine-formatted instruction to a file.
+     *   @os           The stream to write to.
+     *   @dispatchFrom The dock from which the instruction being written is to be dispatched (required for encoding)
+     */
+    public abstract void        writeInstruction(DataOutputStream os, Dock dispatchFrom, Instruction instr) throws IOException;
+
+    /** If supported, run the given code and create a FleetProcess to interact with it. */
+    public FleetProcess run(Instruction[] program) {
+        throw new RuntimeException("class " + this.getClass().getName() + " does not implement method run()");
+    }
+}
index 096c29e..ef9297c 100644 (file)
@@ -2,18 +2,31 @@ package edu.berkeley.fleet.api;
 import java.io.*;
 import java.util.*;
 
-/** represents a <i>running</i> "slave" fleet with a debug connection */
+/**
+ *  Represents a <i>running</i> "slave" fleet with debugging
+ *  facilities controlled by the "master" JVM.
+ *
+ *  <p>Each Fleet which supports this API must include:
+ *  <ul><li> The ability to dispatch instructions from the master, "on
+ *           the fly".
+ *      <li> A "debug.in" dock such that any words delivered there
+ *           are sent back to the master.
+ *  </ul>
+ */
 public abstract class FleetProcess {
 
     private boolean terminated = false;
 
-    /** dumps an instruction into the fetch unit */
-    public abstract void invokeInstruction(Instruction i);
+    /** dispatch an instruction */
+    public abstract void dispatchInstruction(Instruction i);
 
-    /** reads a word back from the debug port */
-    public abstract long readWord();
+    /** the dock used to read back data from the slave */
+    public abstract Dock getDebugInputDock();
 
-    /** subclasses may be assured that this will be called exactly once */
+    /** returns the next word delivered at the dock specified by <tt>getDebugInputDock()</tt> */
+    public abstract BitVector readWord();
+
+    /** Terminate the process; subclasses may be assured that this will be called exactly once. */
     protected abstract void _terminate();
 
     public final synchronized void terminate() {
@@ -22,13 +35,6 @@ public abstract class FleetProcess {
         _terminate();
     }
 
-    public final boolean isTerminated() {
-        return terminated;
-    }
-
-    public synchronized void finalize() {
-        if (!terminated)
-            terminate();
-    }
-
+    public final boolean isTerminated() { return terminated; }
+    public synchronized void finalize() { terminate(); }
 }
index 290fcac..f889393 100644 (file)
 package edu.berkeley.fleet.api;
+import java.util.*;
 
+/** a Fleet instruction; includes execution location but not full dispatch path */
 public abstract class Instruction {
 
-    public final Pump pump;
-    public Instruction(Pump pump) { this.pump = pump; }
-    public String toString() { return pump+": "; }
+    /** the dock which is to execute this instruction */
+    public final Dock      dock;
 
-    public boolean isLooping() { return true; }
-    public boolean isRepeating() { return false; }
-    public boolean isSK() { return false; }
-    public boolean isDL() { return false; }
+    /** true if the instruction is an outer-looping instruction */
+    public final boolean   looping;
 
-    public static class Clog extends Instruction {
-        public Clog(Pump pump) { super(pump); }
-        public String toString() { return super.toString() + "clog;"; }
-        public boolean isLooping() { return false; }
-    }
+    /** the instruction's predicate */
+    public final Predicate predicate;
 
-    public static class UnClog extends Instruction {
-        public UnClog(Pump pump) { super(pump); }
-        public String toString() { return super.toString() + "unclog;"; }
+    Instruction(Dock dock, boolean looping, Predicate predicate) {
+        if (dock==null)      throw new RuntimeException("dock may not be null");
+        if (predicate==null) throw new RuntimeException("predicate may not be null");
+        this.dock = dock;
+        this.looping = looping;
+        this.predicate = predicate;
     }
 
-    public static class Massacre extends Instruction {
-        public Massacre(Pump pump) { super(pump); }
+    public String toString() {
+        String s = predicate.toString();
+        if (s.length()>0) s = "["+s+"] ";
+        return s+dock+": ";
     }
 
-    public static class Kill extends Instruction {
-        public final int count;
-        public Kill(Pump pump, int count) { super(pump); this.count = count; }
-        public String toString() { return super.toString() + "kill"+(count==1?"":(" "+count))+";"; }
-    }
+    /**
+     *  A <tt>set</tt> instruction.
+     *
+     *  Note that immediates are supplied as Java <tt>long</tt> values
+     *  because they are actual integers with two's complement
+     *  sign-extension semantics.  This is in contrast to most other
+     *  immediate values in the API which are raw bit sequences of
+     *  fixed length -- these are represented by instances of
+     *  <tt>BitVector</tt>.
+     */
+    public static class Set extends Instruction {
 
-    public static class PredicatedInstruction extends Instruction {
-        public static final int P_ALWAYS = 0x0001;
-        public static final int P_IF_A   = 0x0002;
-        public static final int P_IF_B   = 0x0003;
-        public static final int P_IF_Z   = 0x0004;
-
-        public final int predicate;
-        public final boolean dl;
-        public boolean isDL() { return dl; }
-        
-        public PredicatedInstruction(Pump pump, boolean dl, int predicate) {
-            super(pump);
-            this.predicate = predicate;
-            this.dl = dl;
-        }
-        public String toString() {
-            String dlx = dl ? "[dl] " : "";
-            switch(predicate) {
-                case P_ALWAYS: return dlx+       super.toString();
-                case P_IF_A:   return dlx+"[a] "+super.toString();
-                case P_IF_B:   return dlx+"[b] "+super.toString();
-                case P_IF_Z:   return dlx+"[z] "+super.toString();
+        /** the destination (latch to be set) */
+        public final SetDest        dest;
+
+        /** the source (what will be put in the <tt>dest</tt> latch) */
+        public final SetSource      source;
+
+        /** if <tt>source</tt> is <tt>Immediate</tt>, this is the immediate value; an integer */
+        public final long           immediate;
+
+        /** if <tt>source</tt> is <tt>ImmediatePath</tt>, this is the immediate path */
+        public final Path           path;
+
+        /** if <tt>dest</tt> is <tt>Flags</tt>, this is the truth table to update flag "a" */
+        public final FlagFunction   newFlagA;
+
+        /** if <tt>dest</tt> is <tt>Flags</tt>, this is the truth table to update flag "b" */
+        public final FlagFunction   newFlagB;
+
+        /** basic constructor */
+        public Set(Dock dock, boolean looping, Predicate predicate, SetDest dest, SetSource source) {
+            super(dock, looping, predicate);
+            OUTER: switch(dest) {
+                case InnerLoopCounter:
+                    switch(source) {
+                        case Infinity: case DataLatch: case Immediate: break OUTER;
+                        default: break;
+                    }
+                case OuterLoopCounter:
+                    switch(source) {
+                        case Decrement: case DataLatch: case Immediate: break OUTER;
+                        default: break;
+                    }
+                case DataLatch:
+                    if (source==SetSource.Immediate) break;
+                default: throw new RuntimeException("cannot set " + dest + " to " + source);
             }
-            throw new Error();
+            this.source = source;
+            this.dest = dest;
+            this.immediate = 0;
+            this.path = null;
+            this.newFlagA = null;
+            this.newFlagB = null;
         }
-    }
 
-    public static class SetFlags extends PredicatedInstruction {
-        public static final int FLAG_Z     = 0x0001;
-        public static final int FLAG_NOT_Z = 0x0002;
-        public static final int FLAG_S     = 0x0004;
-        public static final int FLAG_NOT_S = 0x0008;
-        public static final int FLAG_B     = 0x0010;
-        public static final int FLAG_NOT_B = 0x0020;
-        public static final int FLAG_A     = 0x0040;
-        public static final int FLAG_NOT_A = 0x0080;
-
-        public final int flag_a;
-        public final int flag_b;
-        public SetFlags(Pump pump, boolean dl, int predicate, int flag_a, int flag_b) {
-            super(pump, dl, predicate);
-            this.flag_a = flag_a;
-            this.flag_b = flag_b;
+        /** constructor for set instructions with immediates */
+        public Set(Dock dock, boolean looping, Predicate predicate, SetDest dest, long immediate) {
+            super(dock, looping, predicate);
+            if (dest!=SetDest.InnerLoopCounter && dest!=SetDest.OuterLoopCounter && dest!=SetDest.DataLatch)
+                throw new RuntimeException("a set instruction with dest="+dest+" may not take an immediate");
+            this.source = SetSource.Immediate;
+            this.dest = dest;
+            this.immediate = immediate;
+            this.path = null;
+            this.newFlagA = null;
+            this.newFlagB = null;
         }
-        public SetFlags(Pump pump, int flag_a, int flag_b) { this(pump, false, P_ALWAYS, flag_a, flag_b); }
-
-        public boolean isLooping() { return true; }
-        private String printFlag(int flag) {
-            if (flag==0) return "0";
-            if ((flag & (FLAG_Z | FLAG_NOT_Z)) == (FLAG_Z | FLAG_NOT_Z)) return "1";
-            if ((flag & (FLAG_B | FLAG_NOT_B)) == (FLAG_B | FLAG_NOT_B)) return "1";
-            if ((flag & (FLAG_A | FLAG_NOT_A)) == (FLAG_A | FLAG_NOT_A)) return "1";
-            if ((flag & (FLAG_S | FLAG_NOT_S)) == (FLAG_S | FLAG_NOT_S)) return "1";
-            String ret = "";
-            if ((flag & FLAG_A)     != 0) ret += (ret.length()>=0?"|":"") +  "a";
-            if ((flag & FLAG_NOT_A) != 0) ret += (ret.length()>=0?"|":"") + "!a";
-            if ((flag & FLAG_B)     != 0) ret += (ret.length()>=0?"|":"") +  "b";
-            if ((flag & FLAG_NOT_B) != 0) ret += (ret.length()>=0?"|":"") + "!b";
-            if ((flag & FLAG_S)     != 0) ret += (ret.length()>=0?"|":"") +  "s";
-            if ((flag & FLAG_NOT_S) != 0) ret += (ret.length()>=0?"|":"") + "!s";
-            if ((flag & FLAG_Z)     != 0) ret += (ret.length()>=0?"|":"") +  "z";
-            if ((flag & FLAG_NOT_Z) != 0) ret += (ret.length()>=0?"|":"") + "!z";
-            return ret;
+
+        /** constructor for set instructions with immediate paths */
+        public Set(Dock dock, boolean looping, Predicate predicate, SetDest dest, Path path) {
+            super(dock, looping, predicate);
+            if (dest!=SetDest.TAPL)
+                throw new RuntimeException("a set instruction with dest="+dest+" may not take an immediate path");
+            this.source = SetSource.ImmediatePath;
+            this.dest = dest;
+            this.immediate = 0;
+            this.path = path;
+            this.newFlagA = null;
+            this.newFlagB = null;
         }
-        public String toString() {
-            return super.toString() + " setflags a=" + printFlag(flag_a) + ", b=" + printFlag(flag_b);
+
+        /** constructor for <tt>set flags</tt> instructions */
+        public Set(Dock dock, boolean looping, Predicate predicate, FlagFunction newFlagA, FlagFunction newFlagB) {
+            super(dock, looping, predicate);
+            this.source = SetSource.Immediate;
+            this.dest = SetDest.Flags;
+            this.immediate = 0;
+            this.path = null;
+            this.newFlagA = newFlagA;
+            this.newFlagB = newFlagB;
         }
-    }
 
-    public static class DecrLoop extends PredicatedInstruction {
-        public DecrLoop(Pump pump) { super(pump, true, P_ALWAYS); }
-        public DecrLoop(Pump pump, boolean dl, int predicate) { super(pump, dl, predicate); }
-        public boolean isDL() { return true; }
-        public boolean isLooping() { return true; }
-    }
+        /** possible sources for the Set instruction */
+        public static enum SetSource {
+            Infinity, DataLatch, Immediate, ImmediatePath, Decrement;
+        }
+        /** possible destinations for the Set instruction */
+        public static enum SetDest {
+            InnerLoopCounter, OuterLoopCounter, TAPL, Flags, DataLatch;
+        }
 
-    public static class Counter extends PredicatedInstruction {
-        public static final int DATA_LATCH = -1;
-        public static final int REPEAT_COUNTER = -2;
-        public static final int LOOP_COUNTER = -3;
-        public static final int STANDING = -3;
-        public final int source;
-        public final int dest;
-        public Counter(Pump pump, int source, int dest) { this(pump, false, P_ALWAYS, source, dest); }
-        public Counter(Pump pump, boolean dl, int predicate, int source, int dest) {
-            super(pump, dl, predicate);
-            this.source = source;
-            this.dest = dest;
+        /**
+         *  (Immutable) a truth table describing how to update a flag
+         *  based on the value of other flags; it is the logical OR of
+         *  a set of flag predicates.  This class is immutable; all
+         *  methods that alter the function return a new object.
+         */
+        public static class FlagFunction implements Iterable<Predicate> {
+
+            /** the function that always assigns zero */
+            public static final FlagFunction ZERO = new FlagFunction();
+
+            /** the function that always assigns one */
+            public static final FlagFunction ONE  = ZERO.add(Predicate.FlagA).add(Predicate.NotFlagA);
+
+            private final java.util.Set<Predicate> predicates;
+
+            public Iterator<Predicate> iterator() { return predicates.iterator(); }
+
+            private FlagFunction() { this(Collections.EMPTY_SET); }
+            private FlagFunction(java.util.Set<Predicate> set) { this.predicates = Collections.unmodifiableSet(set); }
+
+            /** returns the function which is the logical OR of this function and <tt>ff</tt> */
+            public FlagFunction add(FlagFunction ff) {
+                FlagFunction ret = this;
+                for(Predicate p : ff) ret = ret.add(p);
+                return ret;
+            }
+
+            /** returns the function which is the logical OR of this function and <tt>p</tt> */
+            public FlagFunction add(Predicate p) {
+                HashSet h = new HashSet();
+                h.addAll(predicates);
+                switch(p) {
+                    case FlagA: case NotFlagA:
+                    case FlagB: case NotFlagB:
+                    case FlagC: case NotFlagC:
+                        break;
+                    default:
+                        throw new RuntimeException("invalid predicate in FlagFunction: " + p);
+                }
+                h.add(p);
+                return new FlagFunction(h);
+            }
+
+            /** remove <tt>p</tt> from the set of terms which this function is the logical OR of */
+            public FlagFunction remove(Predicate p) {
+                HashSet h = new HashSet();
+                h.addAll(predicates);
+                h.remove(p);
+                return new FlagFunction(h);
+            }
+
+            public String toString() {
+                if (predicates.isEmpty()) return "0";
+                if (predicates.contains(Predicate.FlagA) && predicates.contains(Predicate.NotFlagA)) return "1";
+                if (predicates.contains(Predicate.FlagB) && predicates.contains(Predicate.NotFlagB)) return "1";
+                if (predicates.contains(Predicate.FlagC) && predicates.contains(Predicate.NotFlagC)) return "1";
+                StringBuffer ret = new StringBuffer();
+                boolean empty = true;
+                for(Predicate p : new Predicate[] {
+                        Predicate.FlagA, Predicate.NotFlagA,
+                        Predicate.FlagB, Predicate.NotFlagB,
+                        Predicate.FlagC, Predicate.NotFlagC })
+                    if (predicates.contains(p)) {
+                        if (!empty) ret.append("| ");
+                        ret.append(p);
+                        empty = false;
+                    }
+                return ret.toString();
+            }
         }
+
         public String toString() {
-            if (source==LOOP_COUNTER && dest==DATA_LATCH) return "take loop counter;";
-            StringBuffer ret = new StringBuffer();
-            ret.append("load ");
             switch(dest) {
-                case LOOP_COUNTER: ret.append("loop"); break;
-                case REPEAT_COUNTER: ret.append("repeat"); break;
-                default: throw new RuntimeException("invalid");
-            }
-            ret.append(" counter");
-            if (source == STANDING)
-                ret.append(" with *");
-            else if (source >= 0) {
-                ret.append(" with " + source);
-            } else if (source!=DATA_LATCH) {
-                throw new RuntimeException("invalid");
+                case InnerLoopCounter:
+                    switch(source) {
+                        case Infinity: return super.toString()+"set ilc=*";
+                        case DataLatch: return super.toString()+"set ilc=data";
+                        case Immediate: return super.toString()+"set ilc="+immediate;
+                    }
+                case OuterLoopCounter:
+                    switch(source) {
+                        case Decrement: return super.toString()+"set olc--";
+                        case DataLatch: return super.toString()+"set olc=data";
+                        case Immediate: return super.toString()+"set olc="+immediate;
+                    }
+                case TAPL: return super.toString()+"set tapl="+path;
+                case Flags: return super.toString()+"set flags a="+newFlagA+" b="+newFlagB;
+                case DataLatch: return super.toString()+"set data="+immediate;
             }
-            ret.append(";");
-            return ret.toString();
+            throw new Error("impossible");
         }
-        public boolean isLooping() { return true; }
     }
 
-    public static class Move extends PredicatedInstruction {
-        public final Destination dest;
+    /** shifts an immediate into the low-order bits of the data latch */
+    public static class Shift extends Instruction {
+        public final BitVector immediate;
+        public Shift(Dock dock, boolean looping, Predicate predicate, BitVector immediate) {
+            super(dock, looping, predicate);
+            this.immediate = immediate;
+        }
+        public String toString() { return super.toString()+"shift "+immediate; }
+    }
 
+    /** all communication is performed with this instruction */
+    public static class Move extends Instruction {
+
+        /** if true, this instruction is vulnerable to torpedoes */
+        public final boolean     interruptible;
+
+        /** if non-null, the path to load into the path latch */
+        public final Path        path;
+
+        /** if true, a token will be consumed before execution */
         public final boolean     tokenIn;
+
+        /** if true, data will be consumed before execution */
         public final boolean     dataIn;
-        public final boolean     latch;
-        public final boolean     dataOutDest;
+
+        /** if true, the data consumed will be copied into the data latch */
+        public final boolean     latchData;
+
+        /** if true, the data consumed will be copied into the path latch */
+        public final boolean     latchPath;
+
+        /** if true, the value in the data latch will be transmitted (to the location in the path latch if at an output dock) */
         public final boolean     dataOut;
+
+        /** if true, the a token will be transmitted to the location in the path latch */
         public final boolean     tokenOut;
-        public final boolean     requeue;
-        public final boolean     ignoreUntilLast;
-
-        /** count=0 denotes a standing move */
-        public Move(Pump        pump,
-                    boolean     dl,
-                    int         predicate,
-                    Destination dest,
+
+        public Move(Dock        dock,
+                    boolean     looping,
+                    Predicate   predicate,
+                    boolean     interruptible,
+                    Path        path,
                     boolean     tokenIn,
                     boolean     dataIn,
-                    boolean     latch,
-                    boolean     dataOutDest,
+                    boolean     latchData,
+                    boolean     latchPath,
                     boolean     dataOut,
-                    boolean     tokenOut,
-                    boolean     requeue,
-                    boolean     ignoreUntilLast) {
-            super(pump, dl, predicate);
-            this.dest = dest;
+                    boolean     tokenOut
+                    ) {
+            super(dock, looping, predicate);
+            this.path = path;
             this.tokenIn = tokenIn;
             this.dataIn = dataIn;
-            this.latch = latch;
-            this.dataOutDest = dataOutDest;
+            this.latchData = latchData;
+            this.latchPath = latchPath;
             this.dataOut = dataOut;
             this.tokenOut = tokenOut;
-            this.requeue = requeue;
-            this.ignoreUntilLast = ignoreUntilLast;
-            if (pump.isInbox() && tokenIn && dataIn)
-                throw new RuntimeException("cannot have both \"wait\" and \"take\"/\"recieve\" on an inbox: " + this);
-            if (pump.isOutbox() && tokenOut && dataOut)
-                throw new RuntimeException("cannot have both \"sendto\" and \"notify\" on an outbox: " + this);
-            if (latch && !dataIn)
-                throw new RuntimeException("cannot have latch bit set without dataIn bit: " + this);
+            this.interruptible = interruptible;
+            if (dock != null && dock.isInputDock() && tokenIn && dataIn)
+                throw new RuntimeException("cannot have both \"wait\" and \"take\"/\"recieve\" on an input dock: " + this);
+            if (dock != null && dock.isOutputDock() && tokenOut && dataOut)
+                throw new RuntimeException("cannot have both \"sendto\" and \"notify\" on an output dock: " + this);
+            if (latchData && !dataIn)
+                throw new RuntimeException("cannot have latchData bit set without dataIn bit: " + this);
+            if (latchPath && !dataIn)
+                throw new RuntimeException("cannot have latchPath bit set without dataIn bit: " + this);
+            if (latchPath && path!=null)
+                throw new RuntimeException("cannot have latchPath and a non-null path: " + this);
         }
 
         public String toString() {
-            // FIXME
-            String ret = super.toString();
-            boolean needcomma = false;
-            if (tokenIn)           { ret += (needcomma ? ", " : "") + "wait";    needcomma = true; }
-            if (dataIn && latch)  {
-                if (pump.isInbox())
-                    ret += (needcomma ? ", " : "") + "receive";
-                else
-                    ret += (needcomma ? ", " : "") + "take";
-                needcomma = true;
-            }
-            if (dataIn && !latch)  { ret += (needcomma ? ", " : "") + "dismiss"; needcomma = true; }
-            if (dataOut)  {
-                if (pump.isInbox() || dest==null)
-                    ret += (needcomma ? ", " : "") + "deliver";
-                else
-                    ret += (needcomma ? ", " : "") + "sendto "+dest;
-                needcomma = true;
+            StringBuffer ret = new StringBuffer();
+            if (tokenIn)                        ret.append(", wait");
+            if (dataIn) {
+                if (latchPath)                  ret.append(dock.isInputDock() ? ", collect path" : ", recv path");
+                if (latchData)                  ret.append(dock.isInputDock() ? ", collect"      : ", recv");
+                if (!latchPath && !latchData)   ret.append(", discard");
             }
-            if (tokenOut) { ret += (needcomma ? ", " : "") + "notify "+dest; needcomma = true; }
-            return ret;
-        }
-
-        public boolean isLooping() { return true; }
-        public boolean isRepeating() { return true; }
-    }
-
-    public static class HalfLiteral extends PredicatedInstruction {
-        public final long literal;
-        public final boolean high;
-        public HalfLiteral(Pump pump, boolean dl, int predicate, long literal, int count, boolean high) {
-            super(pump, dl, predicate);
-            this.literal = literal;
-            this.high = high;
+            if (dataOut && dock.isInputDock())  ret.append(", deliver");
+            if (dataOut && !dock.isInputDock()) ret.append(path==null ? ", send"  : "sendto "  + path);
+            if (tokenOut)                       ret.append(path==null ? ", token" : "tokento " + path);
+            String s = ret.toString();
+            s = s.equals("") ? "nop" : s.substring(2);
+            if (interruptible) s = "[i] " + s;
+            return super.toString()+s;
         }
-        public boolean isRequeueing() { return true; }
-        public boolean isLooping() { return true; }
     }
 
-    public static class Literal extends PredicatedInstruction {
-        public final long literal;
-        public Literal(Pump pump, boolean dl, int predicate, long literal) {
-            super(pump, dl, predicate);
-            this.literal = literal;
-        }
-        public boolean isLooping() { return true; }
-        public boolean isRequeueing() { return true; }
-        public static boolean canRepresent(long literal) {
-            long il = literal;
-            long allones = ~(-1L << 37);
-            il = literal = literal & allones;
-            if      (((il & ~(-1L << 19)) & allones) == 0)       return true;
-            else if (((il | ~(-1L << 19)) & allones) == allones) return true;
-            else if (((il &  (-1L << 19)) & allones) == 0)       return true;
-            else if (((il |  (-1L << 19)) & allones) == allones) return true;
-            return false;
-        }
-    }
-
-
-    public static class CodeBagDescriptor extends PredicatedInstruction {
-        // address of CBD, relative to address that this instruction was loaded from
-        public final long offset;
-        public final long size;
-        public CodeBagDescriptor(Pump pump, long offset, long size) { this(pump, false, P_ALWAYS, offset, size); }
-        public CodeBagDescriptor(Pump pump, boolean dl, int predicate, long offset, long size) {
-            super(pump, dl, predicate);
-            this.offset = offset;
-            this.size = size;
-        }
-        public String toString() {
-            String off = ""+offset;
-            if (offset > 0) off = "+"+off;
-            return "(CBD @"+off+"+"+size+"): sendto " + pump;
-        }
+    /** marks the end of a loop; closes the hatch */
+    public static class Tail extends Instruction {
+        public Tail(Dock dock) { super(dock, false, Predicate.IgnoreOLC); }
+        public String toString() { return super.toString() + "tail;"; }
     }
 
 }
diff --git a/src/edu/berkeley/fleet/api/Path.java b/src/edu/berkeley/fleet/api/Path.java
new file mode 100644 (file)
index 0000000..5de20fb
--- /dev/null
@@ -0,0 +1,29 @@
+package edu.berkeley.fleet.api;
+import java.util.*;
+
+/**
+ *  Represents a path through the switch fabric, from a Dock (source)
+ *  to a Destination, plus an optional "signal" value.
+ */
+public abstract class Path {
+
+    /** The start of the path. */
+    public abstract Dock        getSource();
+
+    /** The end of the path. */
+    public abstract Destination getDestination();
+
+    /** The number of units of buffering along this path. */
+    public abstract int         getBufferingAmount();
+
+    /** A metric, in unspecified units, of the latency along this path; less is better. */
+    public abstract int         getLatencyMetric();
+
+    /** An additional quantity of bits to be transmitted along with a packet, or null if none. */
+    public abstract BitVector   getSignal();
+
+    public String toString() {
+        return getSource() + "->" + getDestination() + ((getSignal()==null||getSignal().length()==0)?"":(":"+getSignal()));
+    }
+
+}            
diff --git a/src/edu/berkeley/fleet/api/Predicate.java b/src/edu/berkeley/fleet/api/Predicate.java
new file mode 100644 (file)
index 0000000..5392807
--- /dev/null
@@ -0,0 +1,19 @@
+package edu.berkeley.fleet.api;
+
+/** possible predicate field values */
+public enum Predicate {
+    Default, FlagA, NotFlagA, FlagB, NotFlagB, FlagC, NotFlagC, IgnoreOLC;
+    public String toString() {
+        switch(this) {
+            case Default:    return "";
+            case FlagA:      return "a";
+            case FlagB:      return "b";
+            case FlagC:      return "c";
+            case NotFlagA:   return "!a";
+            case NotFlagB:   return "!b";
+            case NotFlagC:   return "!c";
+            case IgnoreOLC:  return "+";
+            default:         throw new Error("unknown predicate " + this);
+        }
+    }
+}
diff --git a/src/edu/berkeley/fleet/api/Pump.java b/src/edu/berkeley/fleet/api/Pump.java
deleted file mode 100644 (file)
index a5e04ff..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-package edu.berkeley.fleet.api;
-import java.util.*;
-
-public abstract class Pump {
-
-    public Pump() { }
-
-    /** the descriptive name of this pump (relative to its ship) */
-    public abstract String getName();
-
-    /** return the Ship to which this Pump belongs */
-    public abstract Ship   getShip();
-
-    /** the maximum number of instructions we can put in the Pump instruction fifo,
-     *  or Integer.MAX_VALUE if unbounded */
-    public abstract int getInstructionFifoLength();
-
-    /** returns true if this is an inbox */
-    public abstract boolean isInbox();
-
-    /** returns true if this is an outbox */
-    public abstract boolean isOutbox();
-
-    /** get all destinations associated with this Pump; default implementation: just itself */
-    public abstract Iterable<Destination> getDestinations();
-
-    /** default implementation: the empty string */
-    public String getDestinationName() { return ""; }
-
-    /** return the Pump which is the destination of this Box's shortcut (if any) */
-    public Pump getShortcut() { return null; }
-
-    public abstract long resolveLiteral(String literal);
-}            
index 0f207da..11e0f60 100644 (file)
@@ -1,36 +1,28 @@
 package edu.berkeley.fleet.api;
-import java.io.*;
 import java.util.*;
 
-public abstract class Ship {
+/** A ship in a Fleet; each ship consists of a collection of <tt>Dock</tt>s */
+public abstract class Ship implements Iterable<Dock> {
+
+    private final Fleet fleet;
+
+    public Ship(Fleet fleet) {
+        this.fleet = fleet;
+    }
 
     /** return the Fleet that this Ship belongs to */
-    public abstract Fleet  getFleet();
+    public Fleet  getFleet() { return fleet; }
 
-    /** returns the type of the ship ("Fetch", "ALU", etc) */
+    /** returns the type of the ship ("Fetch", "Alu", etc) */
     public abstract String getType();
     
-    /** return all pumps which feed this ship; order is NOT significant */
-    public abstract Iterable<Pump> getPumps();
-
-    public Pump getPump(String s) {
-        for(Pump b : getPumps())
-            if (b.getName().equals(s))
-                return b;
-        throw new RuntimeException("unknown port \""+getType()+"."+s+"\"");
-    }
+    public abstract Iterator<Dock> iterator();
 
-    public int getOrdinal() {
-        int ord = 0;
-        for(Ship s : getFleet()) {
-            if (s==this) return ord;
-            if (s.getType() != null && s.getType().equals(getType())) ord++;
-        }
-        throw new RuntimeException("inconsistency: Ship does not belong to its own Fleet!");
-    }
+    /** returns the dock on this ship having name "name" */
+    public abstract Dock getDock(String name);
+
+    /** the docks of a given type are numbered; this returns the ordinal number of this dock */
+    public abstract int getOrdinal();
 
     public String toString() { return getType() + "[" + getOrdinal() + "]"; }
-    public long resolveLiteral(String literal) {
-        throw new RuntimeException("unknown literal \""+literal+"\" on ship "+this);
-    }
 }
diff --git a/src/edu/berkeley/fleet/api/package.html b/src/edu/berkeley/fleet/api/package.html
new file mode 100644 (file)
index 0000000..30815b1
--- /dev/null
@@ -0,0 +1,11 @@
+<body>
+<p>
+API for the FleetCode; see the class {@link edu.berkeley.fleet.api.Fleet} for a starting point and drill down from there.
+</p>
+
+<p>
+<b>Note:</b> all <tt>Instruction</tt> objects and their constituent parts
+(<tt>Path</tt>, <tt>Destination</tt>, etc) are immutable,
+like <tt>java.lang.String</tt>.
+</p>
+</body>
index 0b98b42..24c45cd 100644 (file)
@@ -8,8 +8,8 @@ import java.util.*;
 public class Main {
 
     /** parse the assembly code on <tt>r</tt>, encode it for <tt>fleet</tt>, and write a binary on <tt>out</tt> */
-    public static void assemble(Fleet fleet, Reader r, OutputStream out) throws Exception {
-        new Parser(fleet).parse(r, out);
+    public static Instruction[] assemble(Fleet fleet, Reader r) throws Exception {
+        return new Parser(fleet).parse(r);
     }
 
-}
\ No newline at end of file
+}
index 2cc226e..9359422 100644 (file)
@@ -6,15 +6,29 @@ import edu.berkeley.sbp.misc.*;
 import edu.berkeley.sbp.meta.*;
 import edu.berkeley.sbp.util.*;
 import static edu.berkeley.fleet.util.BitManipulations.*;
-import static edu.berkeley.fleet.api.Instruction.SetFlags.*;
+import edu.berkeley.fleet.ies44.*;
+import edu.berkeley.fleet.api.Instruction.Set;
+import static edu.berkeley.fleet.api.Instruction.*;
+import static edu.berkeley.fleet.api.Instruction.Set.*;
+import static edu.berkeley.fleet.api.Predicate.*;
+import edu.berkeley.fleet.two.*;
+import edu.berkeley.fleet.fpga.*;
+import edu.berkeley.fleet.interpreter.*;
 import java.util.*;
 import java.io.*;
 
+
 /**
  *  @author Adam Megacz <megacz@cs.berkeley.edu>
  */
 public class Parser {
 
+    private static final BitVector SIGNAL_ZERO = new BitVector(1);
+    private static final BitVector SIGNAL_ONE  = new BitVector(1);
+    static {
+        SIGNAL_ONE.set(0,true);
+    }
+    
     Parser(Fleet fleet) {
         expect = new ArrayList<Long>();
         this.fleet = fleet;
@@ -50,57 +64,61 @@ public class Parser {
         return grammar;
     }
 
-    Tree<String> parse(Reader r) throws Exception {
-        return new CharParser(getGrammar()).parse(new CharInput(r)).expand1();
+    // FIXME: this ought to be cached via serialization, I think
+    private static CharParser cp = null;
+    Tree<String> parseIt(Reader r) throws Exception {
+        if (cp==null)
+            cp = new CharParser(getGrammar());
+        CharInput ci = new CharInput(r);
+        Forest f = cp.parse(ci);
+        return f.expand1();
     }
 
-    public void parse(Reader r, OutputStream out) throws Exception {
+    public Instruction[] parse(Reader r) throws Exception {
         // this needs to be "code bag zero"
         CodeBag baseCodeBag = new CodeBag();
         CodeBag rootCodeBag = new CodeBag();
         skip = false;
-        baseCodeBag.add(new Instruction.CodeBagDescriptor(null, rootCodeBag.getFakeAddress(), 1));
-        walk((Tree<String>)parse(r), rootCodeBag);
-        if (fleet instanceof edu.berkeley.fleet.fpga.Fpga)
-            ((edu.berkeley.fleet.fpga.Fpga)fleet).dumpFabric(true);
+        Dock dock = null;
+        if (fleet instanceof Fpga) {
+            dock = ((Fpga)fleet).getUniversalSource();
+        } else {
+            dock = ((Interpreter)fleet).getUniversalSource();
+        }
+        baseCodeBag.add(new Set(dock, false, IgnoreOLC, SetDest.DataLatch, (rootCodeBag.getFakeAddress())), true);
+        Tree<String> parsed = (Tree<String>)parseIt(r);
+        walk(parsed, rootCodeBag);
 
         // map from arbitrary identifiers to actual addresses
         int[] codeBagMap = new int[codeBags.size()];
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        DataOutputStream dos       = new DataOutputStream(baos);
         int count = 0;
         for(int i=0; i<codeBags.size(); i++) {
             CodeBag c = codeBags.get(i);
-            dos.flush();
             codeBagMap[i] = count;
             for(Instruction inst : c) {
-                fleet.writeInstruction(dos, inst);
                 count++;
             }
         }
 
         // now write for real
-        dos = new DataOutputStream(out);
         count = 0;
+        ArrayList<Instruction> ret = new ArrayList<Instruction>();
         for(int i=0; i<codeBags.size(); i++) {
             CodeBag c = codeBags.get(i);
-            dos.flush();
-            for(Instruction inst : c) {
-                if (inst instanceof Instruction.CodeBagDescriptor) {
-                    dos.flush();
-                    Instruction.CodeBagDescriptor old = (Instruction.CodeBagDescriptor)inst;
-                    int offset = codeBagMap[(int)old.offset];// - count;
-                    inst = new Instruction.CodeBagDescriptor(old.pump,
-                                                                     offset,
-                                                                     codeBags.get((int)old.offset).size());
+            for(int j=0; j<c.size(); j++) {
+                Instruction inst = c.get(j);
+                if (c.isCBD.contains(j)) {
+                    Set old = (Set)inst;
+                    long lit = 0;
+                    lit = InstructionEncoder.CBD_SIZE.setval(lit, codeBags.get((int)old.immediate).size());
+                    lit = InstructionEncoder.CBD_OFFSET.setval(lit, codeBagMap[(int)old.immediate]);
+                    inst = new Set(old.dock, false, IgnoreOLC, SetDest.DataLatch, lit);
                 }
-                fleet.writeInstruction(dos, inst);
+                ret.add(inst);
                 count++;
             }
         }
-        dos.flush();
-        out.flush();
-        out.close();
+        return (Instruction[])ret.toArray(new Instruction[0]);
     }
 
     /** in the first pass, codebags are assigned "addresses" in arbitrary order */
@@ -123,8 +141,8 @@ public class Parser {
             String type = string(t.child(1));
             Ship ship = null;
 
-            if (fleet instanceof Fleet.WithDynamicShips) {
-                Fleet.WithDynamicShips dyn = ((Fleet.WithDynamicShips)fleet);
+            if (fleet instanceof FleetWithDynamicShips) {
+                FleetWithDynamicShips dyn = ((FleetWithDynamicShips)fleet);
                 ship = dyn.createShip(type, name);
                 if (ship==null)
                     throw new RuntimeException("couldn't find a ship called \""+type+"\"");
@@ -135,7 +153,7 @@ public class Parser {
 
         } else if (head.equals("#include")) {
             try {
-                walk(parse(new InputStreamReader(new FileInputStream(string(t.child(0))))), cb);
+                walk(parseIt(new InputStreamReader(new FileInputStream(string(t.child(0))))), cb);
             } catch (Exception e) {
                 throw new RuntimeException(e);
             }
@@ -167,39 +185,38 @@ public class Parser {
         return string(t.child(0))+string(t.child(1));
     }
 
-    Destination portReference(Tree<String> t) {
-        if (!"Pump".equals(t.head()) && !"Destination".equals(t.head()) && !"ShipSpecificLiteral".equals(t.head())) return null;
+    Path path(Dock dock, Tree<String> t) {
+        if (!"Dock".equals(t.head()) && !"Destination".equals(t.head()) && !"ShipSpecificLiteral".equals(t.head())) return null;
+        t = t.child(0);
         String shipName = name(t.child(0));
         String portName = name(t.child(1));
         String subPort = t.size()<3 ? null : name(t.child(2));
         Ship ship = shipMap.get(shipName);
         if (ship==null) throw new RuntimeException("no such ship \""+shipName+"\"");
         Destination ret = null;
-        Pump bb = null;
-        for(Pump b : ship.getPumps())
+        Dock bb = null;
+        for(Dock b : ship)
             if (b.getName().equals(portName)) {
                 bb = b;
             }
         if (bb==null)
             throw new RuntimeException("no such pump \""+portName+"\"");
         if (subPort==null) subPort="";
-        for(Destination d : bb.getDestinations())
-            if (d.getDestinationName().equals(subPort))
-                return d;
-        if (ret==null)
-            throw new RuntimeException("no such pump \""+portName+"\" on ships of type \""+ship.getType()+"\"");
-        return ret;
+        if (":i".equals(t.head())) return dock.getPath(bb.getInstructionDestination(),SIGNAL_ZERO);
+        if (":1".equals(t.head())) return dock.getPath(bb.getDataDestination(),SIGNAL_ONE);
+        if (":0".equals(t.head())) return dock.getPath(bb.getDataDestination(),SIGNAL_ZERO);
+        return dock.getPath(bb.getDataDestination(),SIGNAL_ZERO);
     }
 
-    Pump pump(Tree<String> t) {
-        if (!"Pump".equals(t.head()) && !"Destination".equals(t.head()) && !"ShipSpecificLiteral".equals(t.head()))
+    Dock dock(Tree<String> t) {
+        if (!"Dock".equals(t.head()) && !"Destination".equals(t.head()) && !"ShipSpecificLiteral".equals(t.head()))
             throw new RuntimeException(t+"");
         String shipName = name(t.child(0));
         String portName = name(t.child(1));
         Ship ship = shipMap.get(shipName);
         if (ship==null) throw new RuntimeException("no such ship \""+shipName+"\"");
-        Pump bb = null;
-        for(Pump b : ship.getPumps())
+        Dock bb = null;
+        for(Dock b : ship)
             if (b.getName().equals(portName))
                 return b;
         throw new RuntimeException("no such pump \""+portName+"\"");
@@ -234,30 +251,47 @@ public class Parser {
                 break;
             }
         }
-        Pump chosenport = chosenship.getPump(portName);
+        if (chosenship==null) throw new RuntimeException("no ships of type " + shipType);
+        Dock chosenport = chosenship.getDock(portName);
         Tree specs = t.child(2);
         long literal = 0;
         for(int i=0; i<specs.size(); i++) {
             Tree tt = specs.child(i);
-            literal |= chosenport.resolveLiteral(stringBody(tt));
+            literal |= resolveLiteral(chosenport, stringBody(tt));
         }
         return literal;
     }
 
-    private static int parseFlags(Tree<String> t) {
-        int ret = 0;
+    private static long resolveLiteral(Dock dd, String s) {
+        long val = 0;
+        long ret = 0;
+        boolean hasval = false;
+        if (s.indexOf('=') != -1) {
+            val = Long.parseLong(s.substring(s.indexOf('=')+1));
+            s = s.substring(0, s.indexOf('='));
+            hasval = true;
+        }
+        ShipDescription.Constant c = ((FleetTwoDock)dd).getConstant(s);
+        if (c==null) throw new RuntimeException("no constant " + s + " on dock " + dd);
+        ret |= c.setbits;
+        ret &= ~c.clearbits;
+        if (hasval)
+            ret |= ((~(0xffffffffffffffffL << c.numberWidth)) & val) << c.numberOffset;
+        return ret;
+    }
+
+    private static FlagFunction parseFlags(Tree<String> t) {
+        FlagFunction ret = FlagFunction.ZERO;
         for(int i=0; i<t.size(); i++) {
             String s = t.child(i).head();
-            if (s.equals("0")) continue;
-            if (s.equals("1")) { ret |= (FLAG_A | FLAG_NOT_A); }
-            if (s.equals("a"))  ret |= FLAG_A;
-            if (s.equals("!a")) ret |= FLAG_NOT_A;
-            if (s.equals("b"))  ret |= FLAG_B;
-            if (s.equals("!b")) ret |= FLAG_NOT_B;
-            if (s.equals("z"))  ret |= FLAG_Z;
-            if (s.equals("!z")) ret |= FLAG_NOT_Z;
-            if (s.equals("s"))  ret |= FLAG_S;
-            if (s.equals("!s")) ret |= FLAG_NOT_S;
+            if (s.equals("0"))  ret = ret.add(FlagFunction.ZERO);
+            if (s.equals("1"))  ret = ret.add(FlagFunction.ONE);
+            if (s.equals("a"))  ret = ret.add(FlagA);
+            if (s.equals("!a")) ret = ret.add(NotFlagA);
+            if (s.equals("b"))  ret = ret.add(FlagB);
+            if (s.equals("!b")) ret = ret.add(NotFlagB);
+            if (s.equals("c"))  ret = ret.add(FlagC);
+            if (s.equals("!c")) ret = ret.add(NotFlagC);
         }
         return ret;
     }
@@ -271,53 +305,52 @@ public class Parser {
                 fillCodeBag(statement, cb2);
 
         } else if (t.head().equals("Fiber")) {
-            Pump pump = (Pump)pump(t.child(0));
+            Dock dock = (Dock)dock(t.child(0));
             
             OUTER: for(Tree tt : t.child(1)) {
                 int count = 1;
-                int predicate = Instruction.PredicatedInstruction.P_ALWAYS;
-                boolean dl = false;
-                if ("[dl]".equals(tt.child(0).head())) dl = true;
-                if ("[a]".equals(tt.child(1).head())) predicate = Instruction.PredicatedInstruction.P_IF_A;
-                if ("[b]".equals(tt.child(1).head())) predicate = Instruction.PredicatedInstruction.P_IF_B;
-                if ("[z]".equals(tt.child(1).head())) predicate = Instruction.PredicatedInstruction.P_IF_Z;
-                tt = tt.child(2);
-                if ("unclog".equals(tt.head()))    {
-                    cb.add(new Instruction.UnClog(pump));
-                    continue;
-                } else if ("clog".equals(tt.head()))    {
-                    cb.add(new Instruction.Clog(pump));
-                    continue;
-                } else if ("kill".equals(tt.head()))    {
-                    count = tt.size()==0 ? 1 : (int)number(tt.child(0));
-                    cb.add(new Instruction.Kill(pump, count));
+                Predicate predicate = Default;
+                boolean looping = false;
+                boolean interruptible = false;
+                for(int i=0; i<tt.child(0).size(); i++) {
+                    Tree ttt = tt.child(0).child(i);
+                    if ("[a]".equals(ttt.head()))  predicate = FlagA;
+                    if ("[b]".equals(ttt.head()))  predicate = FlagB;
+                    if ("[c]".equals(ttt.head()))  predicate = FlagC;
+                    if ("[!a]".equals(ttt.head())) predicate = NotFlagA;
+                    if ("[!b]".equals(ttt.head())) predicate = NotFlagB;
+                    if ("[!c]".equals(ttt.head())) predicate = NotFlagC;
+                    if ("[+]".equals(ttt.head()))  predicate = IgnoreOLC;
+                    if ("[I]".equals(ttt.head()))  interruptible = true;
+                    if ("[L]".equals(ttt.head()))  looping = true;
+                }
+                tt = tt.child(1);
+                if ("tail".equals(tt.head()))    {
+                    cb.add(new Tail(dock));
                     continue;
                 } else if ("setflags".equals(tt.head()))    {
-                    cb.add(new Instruction.SetFlags(pump, dl, predicate, parseFlags(tt.child(0)), parseFlags(tt.child(1))));
+                    cb.add(new Set(dock, looping, predicate, parseFlags(tt.child(0)), parseFlags(tt.child(1))));
                     continue;
-                } else if ("loop".equals(tt.head()))    {
-                    cb.add(new Instruction.Counter(pump, dl, predicate, Instruction.Counter.LOOP_COUNTER, Instruction.Counter.DATA_LATCH));
+                } else if ("tapl".equals(tt.head()))    {
+                    cb.add(new Set(dock, looping, predicate, SetDest.TAPL, path(dock, tt.child(0))));
                     continue;
                 } else if ("load".equals(tt.head()) && "loop".equals(tt.child(0).head()))    {
-                    cb.add(new Instruction.Counter(pump, dl, predicate, Instruction.Counter.DATA_LATCH, Instruction.Counter.LOOP_COUNTER));
+                    cb.add(new Set(dock, looping, predicate, SetDest.OuterLoopCounter, SetSource.DataLatch));
                     continue;
                 } else if ("load".equals(tt.head()) && "repeat".equals(tt.child(0).head()))    {
-                    cb.add(new Instruction.Counter(pump, dl, predicate, Instruction.Counter.DATA_LATCH, Instruction.Counter.REPEAT_COUNTER));
+                    cb.add(new Set(dock, looping, predicate, SetDest.InnerLoopCounter, SetSource.DataLatch));
                     continue;
                 } else if ("*".equals(tt.head()))    {
-                    cb.add(new Instruction.Counter(pump, dl, predicate, Instruction.Counter.STANDING, Instruction.Counter.REPEAT_COUNTER));
+                    cb.add(new Set(dock, looping, predicate, SetDest.InnerLoopCounter, SetSource.Infinity));
                     continue;
                 } else if ("with".equals(tt.head()) && "loop".equals(tt.child(0).head()))    {
-                    cb.add(new Instruction.Counter(pump, dl, predicate, (int)number(tt.child(1)), Instruction.Counter.LOOP_COUNTER));
+                    cb.add(new Set(dock, looping, predicate, SetDest.OuterLoopCounter, (number(tt.child(1)))));
                     continue;
                 } else if ("with".equals(tt.head()) && "repeat".equals(tt.child(0).head()))    {
-                    cb.add(new Instruction.Counter(pump, dl, predicate, (int)number(tt.child(1)), Instruction.Counter.REPEAT_COUNTER));
-                    continue;
-                } else if ("massacre".equals(tt.head())) {
-                    cb.add(new Instruction.Massacre(pump));
+                    cb.add(new Set(dock, looping, predicate, SetDest.InnerLoopCounter, (number(tt.child(1)))));
                     continue;
                 } else if ("decrement".equals(tt.head())) {
-                    cb.add(new Instruction.DecrLoop(pump));
+                    cb.add(new Set(dock, looping, predicate, SetDest.OuterLoopCounter, SetSource.Decrement));
                     continue;
                 } else if ("literal".equals(tt.head())) {
                     long literal = 0;
@@ -326,12 +359,12 @@ public class Parser {
                         CodeBag cb2 = getCodeBag("anon"+(anoncount++));
                         for(Tree<String> statement : tq.child(0))
                             fillCodeBag(statement, cb2);
-                        cb.add(new Instruction.CodeBagDescriptor(pump, dl, predicate, cb2.getFakeAddress(), 0));
+                        cb.add(new Set(dock, looping, predicate, SetDest.DataLatch, (cb2.getFakeAddress())), true);
                         continue OUTER;
                     } else if (tt.child(0).head().equals("Name")) {
                         String refname = name(tt.child(0));
                         CodeBag cb2 = getCodeBag(refname);
-                        cb.add(new Instruction.CodeBagDescriptor(pump, dl, predicate, cb2.getFakeAddress(), 0));
+                        cb.add(new Set(dock, looping, predicate, SetDest.DataLatch, (cb2.getFakeAddress())), true);
                         continue OUTER;
                     } else if (tt.child(0).head().equals("[")) {
                         literal = parseSSL(tt.child(0));
@@ -345,12 +378,15 @@ public class Parser {
                         count = 0;
                     }
 
-                    if (Instruction.Literal.canRepresent(literal)) {
-                        cb.add(new Instruction.Literal(pump, dl, predicate, literal));
+
+                    if (InstructionEncoder.isSmallEnoughToFit(literal)) {
+                        cb.add(new Set(dock, looping, predicate, SetDest.DataLatch, (literal)));
                     } else {
-                        cb.add(new Instruction.HalfLiteral(pump, dl, predicate, getField(36, 19, literal), count, true));
-                        cb.add(new Instruction.HalfLiteral(pump, dl, predicate, getField(18,  0, literal), count, false));
+                        // FIXME bitwidth hardwired!
+                        cb.add(new Shift(dock, looping, predicate, new BitVector(37).set(getField(36, 19, literal))));
+                        cb.add(new Shift(dock, looping, predicate, new BitVector(37).set(getField(18,  0, literal))));
                     }
+                        
                     continue;
                 }
                 Tree ttx = null;
@@ -365,7 +401,7 @@ public class Parser {
                 }
                 tt = tt.child(0);
                 if (tt.head().equals("[*]")) {
-                    cb.add(new Instruction.Counter(pump, dl, predicate, Instruction.Counter.STANDING, Instruction.Counter.REPEAT_COUNTER));
+                    cb.add(new Set(dock, looping, predicate, SetDest.InnerLoopCounter, SetSource.Infinity));
                     //count = 0;
                     requeue = false;
                 } else if (tt.head().equals("int")) {
@@ -377,31 +413,29 @@ public class Parser {
                 boolean latch = false;
                 boolean dataOut = false;
                 boolean tokenOut = false;
-                boolean dataOutDest = false;
+                boolean dispatch = false;
                 boolean localLiteral = false;
                 boolean ignoreUntilLast = false;
                 long literal = 0;
-                Destination dest = null;
+                Path path = null;
                 for(int i=0; i<ttx.size(); i++) {
                     Tree ttt = ttx.child(i);
                     if      ("wait".equals(ttt.head()))    { tokenIn = true; }
                     else if ("nop".equals(ttt.head()))     { }
-                    else if ("kill".equals(ttt.head()))    {
-                        cb.add(new Instruction.Kill(pump, 1));
-                        continue OUTER;
-                    }
                     else if ("discard".equals(ttt.head())) { dataIn = true; latch = false; }
                     else if ("take".equals(ttt.head()))    { dataIn = true; latch = true; }
+                    else if ("recv".equals(ttt.head()))    { dataIn = true; latch = true; }
+                    else if ("collect".equals(ttt.head()))    { dataIn = true; latch = true; }
                     else if ("recieve".equals(ttt.head()))    { dataIn = true; latch = true; }
-                    else if ("send".equals(ttt.head()))  { dataOutDest = true; dataOut = true; }
-                    else if ("sendto".equals(ttt.head()))  { dataOut = true; dest = portReference(ttt.child(0)); }
+                    else if ("send".equals(ttt.head()))  { dispatch = true; dataOut = true; }
+                    else if ("sendto".equals(ttt.head()))  { dataOut = true; path = path(dock, ttt.child(0)); }
                     else if ("deliver".equals(ttt.head())) { dataOut = true;  }
-                    else if ("notify".equals(ttt.head()))     { tokenOut = true; dest = portReference(ttt.child(0)); }
-                    else if ("notifyLast".equals(ttt.head()))     { tokenOut = true; ignoreUntilLast = true; dest = portReference(ttt.child(0)); }
+                    else if ("notify".equals(ttt.head()))     { tokenOut = true; path = path(dock, ttt.child(0)); }
+                    else if ("notifyLast".equals(ttt.head()))     { tokenOut = true; ignoreUntilLast = true; path = path(dock, ttt.child(0)); }
                 }
-                cb.add(new Instruction.Move(pump, dl, predicate,
-                                            dest, tokenIn, dataIn,
-                                            latch, dataOutDest, dataOut, tokenOut, requeue, ignoreUntilLast));
+                cb.add(new Move(dock, looping, predicate,
+                                            interruptible, path, tokenIn, dataIn,
+                                            latch, dispatch, dataOut, tokenOut));
             }
         }
     }
@@ -409,10 +443,15 @@ public class Parser {
     private class CodeBag extends ArrayList<Instruction> {
         public long address = -1;
         public final String name;
+        private HashSet<Integer> isCBD = new HashSet<Integer>();
         public CodeBag() { codeBags.add(this); this.name = "root"; }
         public CodeBag(String name) { codeBags.add(this); codeBagsByName.put(name, this); this.name = name; }
         public long getFakeAddress() { return codeBags.indexOf(this); }
         public boolean equals(Object o) { return this==o; }
+        public void add(Instruction i, boolean isCBD) {
+            if (isCBD) this.isCBD.add(size());
+            add(i);
+        }
     }
 
     // hideous hack
@@ -431,4 +470,11 @@ public class Parser {
         if (negative) val = -1L * val;
         return val;
     }
+    /**
+     *  This interface marks Fleets which can create ships on the fly, like the fleeterpreter;
+     *  if available, the parser will use this interface to create ships out of #ship definitions.
+     */
+    public static interface FleetWithDynamicShips {
+        public Ship createShip(String shiptype, String shipname);
+    }
 }
index 1d6a60b..e560fa8 100644 (file)
@@ -9,24 +9,24 @@ Program::       = Directives CodeBagBody /ws
 Directives::    = Directive */ ws
 CodeBagBody::   = (Fiber | CodeBagDef) */ ws
 CodeBagDef::    = CodeBagName ":" "{" CodeBagBody "}" /ws
-Fiber::         = Pump        ":" Instructions        /ws
+Fiber::         = Dock        ":" Instructions        /ws
 
-// FIXME: should not have predicates on clog/unclog/kill/massacre
+// FIXME: should not have predicates on tail/untail/kill/massacre
 Instructions::  = Instruction +/ ws
-Instruction::   = DL Predicate InstructionX
-DL              = "" | ^"[dl]" ws
-Predicate       = "" | ^"[a]" ws | ^"[b]" ws | ^"[z]" ws
-InstructionX    = ^"unclog"                          ";" /ws
-                | ^"clog"                            ";" /ws
-                | ^"massacre"                        ";" /ws
-                | ^"kill"                            ";" /ws
+Instruction::   = (Tags:: Tag*) InstructionX
+Tag             = ^"[a]"  ws |  ^"[b]" ws |  ^"[c]" ws
+                | ^"[!a]" ws | ^"[!b]" ws | ^"[!c]" ws
+                | ^"[+]" ws
+                | ^"[I]" ws
+                | ^"[L]" ws
+InstructionX    = ^"tail"                          ";" /ws
                 |  "take" ^"loop" "counter"                            ";" /ws
                 | ^"load" (^"loop"|^"repeat") ws "counter"             ";" /ws
                 |  "load" (^"loop"|^"repeat") ws "counter" ^"with" int ";" /ws
                 |  "load" (^"loop"|^"repeat") ws "counter" "with" ^"*" ";" /ws
+                |  "load" ^"tapl" "with" Destination                   ";" /ws
                 | ^"decrement" "loop" "counter"                        ";" /ws
                 | ^"setflags" "a" "=" Flags "," "b" "=" Flags          ";" /ws
-                | ^"kill"     int                    ";" /ws
                 | ^"literal"  Literal  RequeueCount  ";" /ws
                 | RepeatCount Commands RequeueCount ^";" /ws
 RepeatCount     = "" | ^"[*]" | "[" int "]"
@@ -38,19 +38,19 @@ Flag =  ^"0"
      |  ^"1"
      |  ^"a"
      |  ^"b"
-     |  ^"s"
-     |  ^"z"
+     |  ^"c"
      | ^"!a"
      | ^"!b"
-     | ^"!s"
-     | ^"!z"
+     | ^"!c"
 
 Commands::      = Command +/ (ws "," ws)
 Command         = ^"wait"
                 | ^"nop"
                 | ^"discard"
                 | ^"recieve"
+                | ^"recv"
                 | ^"take"
+                | ^"collect"
                 | ^"deliver"
                 | ^"send"
                 | ^"sendto"     Destination /ws
@@ -58,19 +58,22 @@ Command         = ^"wait"
                 | ^"notifyLast" Destination /ws
 
 Literal         = int
-                | ShipType "." PortName ^"[" Constants "]"
+                | ShipType "." DockName ^"[" Constants "]"
                 | CodeBagName
                 | "{" CodeBagBody "}" /ws
 
-Pump::          = ShipName "." PortName
-Destination::   = ShipName "." PortName
+Dock::          = ShipName "." DockName
+Destination::   = (ShipName ^"." DockName)
+                | (ShipName  "." DockName ^":i")
+                | (ShipName  "." DockName ^":0")
+                | (ShipName  "." DockName ^":1")
 Constants::     = Constant +/ ","
 Constant::      = [a-zA-Z0-9=_\-]++
 
 CodeBagName     = UpcaseWord
 ShipType        = UpcaseWord
 ShipName        = DowncaseWord
-PortName        = DowncaseWord
+DockName        = DowncaseWord
 Word            = UpcaseWord | DowncaseWord
 UpcaseWord      = Name:: [A-Z]    ("":: [A-Za-z0-9_]**)
 DowncaseWord    = Name:: [a-z]    ("":: [A-Za-z0-9_]**)
diff --git a/src/edu/berkeley/fleet/doc/Constant.java b/src/edu/berkeley/fleet/doc/Constant.java
deleted file mode 100644 (file)
index f6d04a0..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-package edu.berkeley.fleet.doc;
-
-import java.io.*;
-import java.util.*;
-
-public class Constant {
-
-    long setbits   = 0;
-    long clearbits = 0;
-    boolean signExtend = false;
-    int numberOffset = 0;
-    int numberWidth = 0;
-
-    public Constant(String s) {
-        if (s.startsWith("0x")) {
-            setbits = Long.parseLong(s.substring(2), 16);
-            clearbits = ~setbits;
-        } else if (s.length() == 37) {
-            for(int i=36; i>=0; i--) {
-                char c = s.charAt(36-i);
-                switch(c) {
-                    case '0': clearbits |= (1<<i); break;
-                    case '1': setbits   |= (1<<i); break;
-                    case '.': break;
-                    case 's': signExtend = true;  numberOffset = i; numberWidth++; break;
-                    case 'u': signExtend = false; numberOffset = i; numberWidth++; break;
-                }
-            }
-        } else {
-            setbits = Long.parseLong(s);
-            clearbits = ~setbits;
-        }
-    }
-
-
-}
\ No newline at end of file
diff --git a/src/edu/berkeley/fleet/doc/Doc.java b/src/edu/berkeley/fleet/doc/Doc.java
deleted file mode 100644 (file)
index 8d23880..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-package edu.berkeley.fleet.doc;
-
-import java.io.*;
-import java.util.*;
-
-
-public class Doc {
-    
-    public static void print() throws Exception {
-        if (!new File(".tmp").exists())
-            new File(".tmp").mkdirs();
-        PrintWriter pw = new PrintWriter(new FileOutputStream(".tmp/FleetTwo.Manual.tex"));
-        BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("doc/archman.tex")));
-        for(String s = br.readLine(); s!=null; s = br.readLine())
-            pw.println(s);
-        for(String f : new File("ships").list()) {
-            print(pw, new ShipDescription(f, new BufferedReader(new InputStreamReader(new FileInputStream(new File("ships/"+f))))));
-        }
-        pw.println("\\end{document}");
-        pw.close();
-    }
-
-    private static void print(PrintWriter pw, ShipDescription sd) throws Exception {
-        pw.println("\\pagebreak");
-        pw.println("\\section*{The {\\tt "+sd.getName()+"} Ship}");
-        pw.println("\\addcontentsline{toc}{subsection}{"+sd.getName()+"}");
-        String tex = sd.getSection("tex");
-        /*
-        for(PumpDescription bbd : sd) {
-            pw.println("{\\bf "+(bbd.isInbox() ? "Input: " : "Output: ")+"{\\tt "+bbd.getName()+"}}\n\n");
-        }
-        */
-        int boxGap = 5;
-        int boxHeight = 25;
-        int boxWidth = 75;
-
-        int leftSize = 0;
-        int rightSize = 0;
-        for(PumpDescription bbd : sd)
-            if (bbd.isLeft()) leftSize += (boxHeight+boxGap);
-            else              rightSize += (boxHeight+boxGap);
-
-        int totalHeight = Math.max(leftSize, rightSize);
-        int shipWidth = (int)(boxWidth * 1.5);
-        int totalWidth = boxGap*2 + boxWidth*2 + shipWidth;
-
-        pw.println("");
-        pw.println("\\begin{center}");
-        pw.println("\\begin{empfile}["+sd.getName()+"]");
-        pw.println("\\begin{emp}["+sd.getName()+"]("+(totalWidth+10)+","+(totalHeight+10)+")");
-        pw.println("  beginfig(1)");
-        pw.println("      pickup pencircle scaled 1pt;");
-        pw.println("      draw "+
-                   "("+((totalWidth-shipWidth)/2)+","+0+")--"+
-                   "("+((totalWidth-shipWidth)/2)+","+totalHeight+")--"+
-                   "("+(totalWidth-((totalWidth-shipWidth)/2))+","+totalHeight+")--"+
-                   "("+(totalWidth-((totalWidth-shipWidth)/2))+","+0+")--"+
-                   "("+((totalWidth-shipWidth)/2)+","+0+");");
-        int left = 0;
-        int right = 0;
-        for(PumpDescription bbd : sd) {
-            int ypos = (totalHeight - (boxGap/2) - (bbd.isLeft() ? left : right));
-            int half = (totalWidth-shipWidth)/2;
-            int p1 = bbd.isLeft() ? (half-5) : ((totalWidth-half)+5);
-            int p3 = bbd.isLeft() ? (p1 - boxWidth) : (p1 + boxWidth);
-            if (bbd.isInbox()) {
-                int p1x = p1;
-                p1 = p3;
-                p3 = p1x;
-            }
-            boolean goo = ((bbd.isLeft() && bbd.isInbox()) || (!bbd.isLeft() && bbd.isOutbox()));
-            int p2 = goo ? (p3 - (boxHeight/2)) : (p3 + (boxHeight/2));
-            if (bbd.isLeft()) left += (boxHeight+boxGap);
-            else              right += (boxHeight+boxGap);
-            if (goo) {
-                pw.println("      label.rt(btex \\tt "+bbd.getName()+" etex, ("+(p1+3)+","+(ypos-boxHeight/2)+"));");
-            } else {
-                pw.println("      label.lft(btex \\tt "+bbd.getName()+" etex, ("+(p1-3)+","+(ypos-boxHeight/2)+"));");
-            }
-            pw.println("      draw "+
-                       "  ("+p1+","+ypos+")--"+
-                       "  ("+p2+","+ypos+")--"+
-                       "  ("+p3+","+(ypos-(boxHeight/2))+")--"+
-                       "  ("+p2+","+(ypos-boxHeight)+")--"+
-                       "  ("+p1+","+(ypos-boxHeight)+")--"+
-                       "  ("+p1+","+ypos+");");
-            if (bbd.isLeft()) leftSize += boxHeight;
-            else              rightSize += boxHeight;
-        }
-        pw.println("  endfig;");
-        pw.println("\\end{emp}");
-        pw.println("\\end{empfile}");
-        pw.println("\\end{center}");
-        pw.println("");
-
-        if (tex!=null)
-            pw.println(tex);
-    }
-
-}
\ No newline at end of file
diff --git a/src/edu/berkeley/fleet/doc/PumpDescription.java b/src/edu/berkeley/fleet/doc/PumpDescription.java
deleted file mode 100644 (file)
index 510f6e8..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-package edu.berkeley.fleet.doc;
-
-import java.io.*;
-import java.util.*;
-
-public class PumpDescription implements Iterable<String> {
-
-    public String getName() { return name; }
-    public boolean isInbox() { return inbox; }
-    public boolean isOutbox() { return !inbox; }
-    public boolean isLeft() { return left; }
-    public boolean tokensOnly() { return tokenOnly; }
-    public String  getShortcut() { return shortcut; }
-    public Iterator<String> iterator() { return destinations.iterator(); }
-
-    // private //////////////////////////////////////////////////////////////////////////////
-
-    private final ShipDescription ship;
-    private final String shortcut;
-    private final String name;
-    private final boolean inbox;
-    private final boolean tokenOnly;
-    private final boolean left;
-    private ArrayList<String> destinations = new ArrayList<String>();
-
-    // FIXME
-    public HashMap<String,Constant> constants = new HashMap<String,Constant>();
-
-    PumpDescription(ShipDescription ship, String name, boolean tokenOnly, boolean left, boolean inbox) {
-        this(ship, name, tokenOnly, inbox, left, null);
-    }
-    PumpDescription(ShipDescription ship, String name, boolean tokenOnly, boolean left, boolean inbox, String shortcut) {
-        this.left = left;
-        this.ship = ship;
-        this.name = name;
-        this.inbox = inbox;
-        this.tokenOnly = tokenOnly;
-        this.shortcut = shortcut;
-        ship.add(this);
-    }
-
-    void addDest(String dest) { destinations.add(dest); }
-
-    public Constant getConstant(String name) {
-        Constant ret = constants.get(name);
-        if (ret == null) ret = ship.getConstant(name);
-        return ret;
-    }
-
-    public long resolveLiteral(String s) {
-        long val = 0;
-        long ret = 0;
-        boolean hasval = false;
-        if (s.indexOf('=') != -1) {
-            val = Long.parseLong(s.substring(s.indexOf('=')+1));
-            s = s.substring(0, s.indexOf('='));
-            hasval = true;
-        }
-        Constant c = getConstant(s);
-        if (c==null) throw new RuntimeException("no constant " + s + " on pump " + this);
-        ret |= c.setbits;
-        ret &= ~c.clearbits;
-        if (hasval)
-            ret |= ((~(0xffffffffffffffffL << c.numberWidth)) & val) << c.numberOffset;
-        return ret;
-    }
-}
diff --git a/src/edu/berkeley/fleet/doc/ShipDescription.java b/src/edu/berkeley/fleet/doc/ShipDescription.java
deleted file mode 100644 (file)
index 4a4c467..0000000
+++ /dev/null
@@ -1,118 +0,0 @@
-package edu.berkeley.fleet.doc;
-
-import java.io.*;
-import java.util.*;
-
-/** the Java representation of a .ship file */
-public class ShipDescription implements Iterable<PumpDescription> {
-
-    public String getName() { return name; }
-    public String getSection(String sectionName) { return sections.get(sectionName); }
-    public Iterator<PumpDescription> iterator() { return pumps.iterator(); }
-
-    public ShipDescription(String name, BufferedReader r) throws IOException {
-        if (name.endsWith(".ship"))
-            name = name.substring(0, name.length() - ".ship".length());
-        while(name.indexOf('/') != -1) name = name.substring(name.indexOf('/')+1);
-        this.name = name;
-        String sectionName = null;
-        StringBuffer sb = new StringBuffer();
-        while(true) {
-            String s = r.readLine();
-            if (s==null || s.startsWith("==")) {
-                if (sectionName != null) sections.put(sectionName, sb.toString());
-                if (s==null) break;
-                sb = new StringBuffer();
-                sectionName = s.trim();
-                while(sectionName.startsWith("="))
-                    sectionName = sectionName.substring(1);
-                while(sectionName.endsWith("="))
-                    sectionName = sectionName.substring(0, sectionName.length()-1);
-                sectionName = sectionName.trim().toLowerCase();
-                continue;
-            }
-            sb.append(s+"\n");
-        }
-        for(String s : sections.keySet())
-            processSection(s);
-    }
-
-    // private //////////////////////////////////////////////////////////////////////////////
-
-    private String name;
-    private String texDocumentation;
-
-    // must keep proper ordering for FPGA (FIXME: should alphabetize when synthesizing)
-    private ArrayList<PumpDescription> pumps = new ArrayList<PumpDescription>();
-
-    private HashMap<String,String> sections = new HashMap<String,String>();
-
-    // FIXME
-    public HashMap<String,Constant> constants = new HashMap<String,Constant>();
-
-    public Constant getConstant(String name) {
-        return constants.get(name);
-    }
-
-    private void processSection(String section) throws IOException {
-        if (section.equals("")) {
-            BufferedReader br = new BufferedReader(new StringReader(sections.get(section)));
-            for(String s = br.readLine(); s != null; s = br.readLine()) {
-                if (s.trim().length()==0) continue;
-                String key = s.substring(0, s.indexOf(':')).trim();
-                String val = s.substring(s.indexOf(':')+1).trim();
-                if (key.toLowerCase().equals("ship"))
-                    name = val.trim();
-            }
-        } else if (section.equals("constants")) {
-            BufferedReader br = new BufferedReader(new StringReader(sections.get(section)));
-            for(String s = br.readLine(); s != null; s = br.readLine()) {
-                if (s.indexOf(':')==-1) continue;
-                String key = s.substring(0, s.indexOf(':')).trim();
-                if (key.startsWith("constant")) {
-                    String constname = key.substring("constant".length()+1).trim();
-                    String val       = s.substring(s.indexOf(':')+1).trim();
-                    constants.put(constname, new Constant(val));
-                }
-            }
-        } else if (section.equals("ports")) {
-            BufferedReader br = new BufferedReader(new StringReader(sections.get(section)));
-            boolean rightSide = false;
-            PumpDescription p = null;
-            for(String s = br.readLine(); s != null; s = br.readLine()) {
-                if (s.trim().length()==0) { rightSide = true; continue; }
-
-                String key = s.substring(0, s.indexOf(':')).trim();
-                boolean tokenOnly = false;
-                boolean inbox = false;
-                key = key.replaceAll("  +", " ");
-                if      (key.equals("token in"))  { tokenOnly = true;   inbox = true;  }
-                else if (key.equals("token out")) { tokenOnly = true;   inbox = false; }
-                else if (key.equals("data in"))   { tokenOnly = false;  inbox = true;  }
-                else if (key.equals("data out"))  { tokenOnly = false;  inbox = false; }
-                else if (key.equals("in"))        { tokenOnly = false;  inbox = true;  }
-                else if (key.equals("out"))       { tokenOnly = false;  inbox = false; }
-                else if (key.startsWith("constant")) {
-                    String constname = key.substring("constant".length()+1).trim();
-                    String val       = s.substring(s.indexOf(':')+1).trim();
-                    p.constants.put(constname, new Constant(val));
-                    continue;
-                } else if (key.startsWith("shortcut to")) {
-                    continue;
-                }
-                else throw new RuntimeException("unknown port type: \""+key+"\"");
-
-                p = null;
-                String val = s.substring(s.indexOf(':')+1).trim();
-                String boxname = val.indexOf('.') != -1 ? val.substring(0, val.indexOf('.')) : val;
-                String dest    = val.indexOf('.') != -1 ? val.substring(val.indexOf('.')+1)  : "";
-                for (PumpDescription b : pumps)
-                    if (b.getName().equals(boxname)) { p = b; break; }
-                if (p==null) p = new PumpDescription(this, boxname, tokenOnly, inbox, !rightSide);
-                p.addDest(dest);
-            }
-        }
-    }
-
-    void add(PumpDescription b) { pumps.add(b); }
-}
\ No newline at end of file
index 0ff6da1..e3cc39f 100644 (file)
@@ -1,15 +1,20 @@
 package edu.berkeley.fleet.fpga;
 
+import static edu.berkeley.fleet.util.BitManipulations.*;
 import edu.berkeley.fleet.api.*;
 import java.io.*;
 import java.net.*;
 import java.util.*;
 import java.util.concurrent.*;
+import static edu.berkeley.fleet.api.Instruction.Set.*;
+import static edu.berkeley.fleet.api.Predicate.*;
+import static edu.berkeley.fleet.api.Instruction.*;
+
 
 public class Client extends FleetProcess {
 
     private Socket s;
-    private BlockingQueue<Long> queue = new LinkedBlockingQueue<Long>();
+    private BlockingQueue<BitVector> queue = new LinkedBlockingQueue<BitVector>();
 
     public void invokeInstruction(Instruction i) {
         throw new RuntimeException("not implemented");
@@ -21,11 +26,14 @@ public class Client extends FleetProcess {
         return val;
     }
                                     
-    public long readWord() {
+    public Dock getDebugInputDock() {
+        throw new RuntimeException();
+    }
+    public BitVector readWord() {
         if (isTerminated())
             throw new RuntimeException("this fleet has been terminated");
         try {
-            return signExtend(queue.take());
+            return queue.take();
         } catch (InterruptedException e) { throw new RuntimeException(e); }
     }
 
@@ -35,24 +43,95 @@ public class Client extends FleetProcess {
         } catch (Exception e) { e.printStackTrace(); }
     }
 
-    public Client(String bitfile, byte[] program) throws IOException {
+    public Client(String bitfile, byte[] program) throws Exception {
         s = new Socket(InetAddress.getByName("goliath.megacz.com"), 3133);
-        OutputStream os = s.getOutputStream();
+        OutputStream os = new BufferedOutputStream(s.getOutputStream());
         PrintWriter pw = new PrintWriter(new OutputStreamWriter(os));
         pw.print(Server.pass_string+" "+bitfile+"\n");
         pw.flush();
 
-        int numinstrs = (program.length / 6);
-        os.write((numinstrs >> (5*8)) & 0xff);
-        os.write((numinstrs >> (4*8)) & 0xff);
-        os.write((numinstrs >> (3*8)) & 0xff);
-        os.write((numinstrs >> (2*8)) & 0xff);
-        os.write((numinstrs >> (1*8)) & 0xff);
-        os.write((numinstrs >> (0*8)) & 0xff);
+
+        Fpga fpga = new Fpga();
+        ByteArrayOutputStream newp = new ByteArrayOutputStream();
+        DataOutputStream newpd = new DataOutputStream(newp);
+        long startcbd = 0;
+
+        Dock inAddrWrite = null;
+        Dock inDataWrite = null;
+        Dock inCBD       = null;
+        Dock out         = null;
+        Dock debugIn     = null;
+        Dock ihorn       = null;
+
+        for(Ship ship : fpga) {
+            if ("Memory".equals(ship.getType()) && ship.getOrdinal()==0) {
+                inAddrWrite = ship.getDock("inAddrWrite");
+                inDataWrite = ship.getDock("inDataWrite");
+                inCBD = ship.getDock("inCBD");
+                out = ship.getDock("out");
+                ihorn = ship.getDock("outIhorn");
+            }
+            if ("Debug".equals(ship.getType()) && ship.getOrdinal()==0) {
+                debugIn = ship.getDock("in");
+            }
+        }
+
+        for(int i=0; i<program.length; i+=6) {
+            long lit = 0
+                | ((program[i+0] & 0xffL) << 40)
+                | ((program[i+1] & 0xffL) << 32)
+                | ((program[i+2] & 0xffL) << 24)
+                | ((program[i+3] & 0xffL) << 16)
+                | ((program[i+4] & 0xffL) << 8)
+                | ((program[i+5] & 0xffL) << 0);
+            Instruction inst = fpga.readInstruction(fpga.getUniversalSource(), lit);
+            if (i==0) {
+                long offset = (lit >> 6) & ~(-1L << 10);
+                long size   = (lit >> 0) & ~(-1L << 6);
+                startcbd = (offset << 6) | size;
+                size = 0;
+                offset = 0;
+                inst = new Instruction.Shift(fpga.getUniversalSource(), false, IgnoreOLC, new BitVector(fpga.getWordWidth()).set(0));
+            } else {
+                if (fpga.writeInstruction(fpga.getUniversalSource(), inst) != lit)
+                    throw new RuntimeException("no match: " + inst + " @"+(i/6)+"\n"+Long.toString(lit,16)+
+                                               "\n"+Long.toString(fpga.writeInstruction(fpga.getUniversalSource(), inst),16));
+            }
+            //fpga.writeInstruction(newpd, fpga.getUniversalSource(), inst);
+        }
+
+        for(int i=0; i<program.length; i+=6) {
+            long lit = 0
+                | ((program[i+0] & 0xffL) << 40)
+                | ((program[i+1] & 0xffL) << 32)
+                | ((program[i+2] & 0xffL) << 24)
+                | ((program[i+3] & 0xffL) << 16)
+                | ((program[i+4] & 0xffL) << 8)
+                | ((program[i+5] & 0xffL) << 0);
+            fpga.writeInstruction(newpd, fpga.getUniversalSource(), discard(out));
+            fpga.writeInstruction(newpd, fpga.getUniversalSource(), new Instruction.Shift(inDataWrite, false, IgnoreOLC, new BitVector(fpga.getWordWidth()).set(getField(36, 19, lit))));
+            fpga.writeInstruction(newpd, fpga.getUniversalSource(), new Instruction.Shift(inDataWrite, false, IgnoreOLC, new BitVector(fpga.getWordWidth()).set(getField(18,  0, lit))));
+            fpga.writeInstruction(newpd, fpga.getUniversalSource(), deliver(inDataWrite));
+            fpga.writeInstruction(newpd, fpga.getUniversalSource(), new Instruction.Shift(inAddrWrite, false, IgnoreOLC, new BitVector(fpga.getWordWidth()).set(getField(36, 19, i/6))));
+            fpga.writeInstruction(newpd, fpga.getUniversalSource(), new Instruction.Shift(inAddrWrite, false, IgnoreOLC, new BitVector(fpga.getWordWidth()).set(getField(18,  0, i/6))));
+            fpga.writeInstruction(newpd, fpga.getUniversalSource(), deliver(inAddrWrite));
+        }
+        fpga.writeInstruction(newpd, fpga.getUniversalSource(), new Instruction.Shift(inCBD, false, IgnoreOLC, new BitVector(fpga.getWordWidth()).set(getField(36, 19, startcbd))));
+        fpga.writeInstruction(newpd, fpga.getUniversalSource(), new Instruction.Shift(inCBD, false, IgnoreOLC, new BitVector(fpga.getWordWidth()).set(getField(18,  0, startcbd))));
+        fpga.writeInstruction(newpd, fpga.getUniversalSource(), wait(inCBD));
+        fpga.writeInstruction(newpd, fpga.getUniversalSource(), deliver(inCBD));
+        fpga.writeInstruction(newpd, fpga.getUniversalSource(), sendto(out, out.getPath(inCBD.getDataDestination(),null)));
+        fpga.writeInstruction(newpd, fpga.getUniversalSource(), new Instruction.Set(ihorn, false, IgnoreOLC, SetDest.InnerLoopCounter, SetSource.Infinity));
+        fpga.writeInstruction(newpd, fpga.getUniversalSource(),
+                              new Instruction.Move(ihorn, false, IgnoreOLC, false, null,false,true,true,true,true,false));
+
+        newpd.flush();
+        program = newp.toByteArray();
+
         os.write(program);
         os.flush();
 
-        final InputStream is = s.getInputStream();
+        final InputStream is = new BufferedInputStream(s.getInputStream());
         new Thread() {
             public void run() {
                 try {
@@ -67,7 +146,10 @@ public class Client extends FleetProcess {
                             result |= val2;
                         }
                         if (val==-1) break;
-                        queue.put(result);
+                        BitVector bs = new BitVector(37);
+                        for(int i=0; i<37; i++)
+                            bs.set(i, ((result >> i) & 1L)!=0);
+                        queue.put(bs);
                     }
                 } catch (SocketException e) {
                 } catch (Exception e) { throw new RuntimeException(e);
@@ -75,7 +157,7 @@ public class Client extends FleetProcess {
             }
         }.start();
     }
-
+    /*
     public static void main(String[] args) throws Exception {
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
         byte[] buf = new byte[1024];
@@ -93,4 +175,10 @@ public class Client extends FleetProcess {
             System.err.println();
         }
     }
-}
\ No newline at end of file
+    */
+    public void dispatchInstruction(Instruction i) { throw new RuntimeException(); }
+    private static Move discard(Dock dock)           { return new Move(dock, false, IgnoreOLC, false, null, false, true,  false, false, false, false); }
+    private static Move deliver(Dock dock)           { return new Move(dock, false, IgnoreOLC, false, null, false, false, false, false, true,  false); }
+    private static Move wait(Dock dock)              { return new Move(dock, false, IgnoreOLC, false, null, true,  false, false, false, false, false); }
+    private static Move sendto(Dock dock, Path path) { return new Move(dock, false, IgnoreOLC, false, path, false, false, false, false, true,  false); }
+}
diff --git a/src/edu/berkeley/fleet/fpga/FabricElement.java b/src/edu/berkeley/fleet/fpga/FabricElement.java
new file mode 100644 (file)
index 0000000..2893d20
--- /dev/null
@@ -0,0 +1,25 @@
+package edu.berkeley.fleet.fpga;
+import edu.berkeley.fleet.api.*;
+import edu.berkeley.fleet.ies44.*;
+import edu.berkeley.fleet.*;
+import java.lang.reflect.*;
+import edu.berkeley.sbp.chr.*;
+import edu.berkeley.sbp.misc.*;
+import edu.berkeley.sbp.meta.*;
+import edu.berkeley.sbp.util.*;
+import java.util.*;
+import java.io.*;
+import static edu.berkeley.fleet.ies44.InstructionEncoder.*;
+import static edu.berkeley.fleet.verilog.Verilog.*;
+
+
+public interface FabricElement {
+
+    public FpgaPath getPath(FabricElement dest, BitVector signal);
+
+    public void addInput(FabricElement in, Module.Port inPort);
+    public void addOutput(FabricElement out, Module.Port outPort);
+
+    public Module.Port getOutputPort();
+    public Module.Port getInputPort();
+}
diff --git a/src/edu/berkeley/fleet/fpga/FifoModule.java b/src/edu/berkeley/fleet/fpga/FifoModule.java
new file mode 100644 (file)
index 0000000..0367c86
--- /dev/null
@@ -0,0 +1,34 @@
+package edu.berkeley.fleet.fpga;
+import edu.berkeley.fleet.api.*;
+import edu.berkeley.fleet.ies44.*;
+import edu.berkeley.fleet.*;
+import java.lang.reflect.*;
+import edu.berkeley.sbp.chr.*;
+import edu.berkeley.sbp.misc.*;
+import edu.berkeley.sbp.meta.*;
+import edu.berkeley.sbp.util.*;
+import java.util.*;
+import java.io.*;
+import static edu.berkeley.fleet.ies44.InstructionEncoder.*;
+import static edu.berkeley.fleet.verilog.Verilog.*;
+
+public class FifoModule extends Module {
+    public FifoModule(int len) {
+        super("fifo"+len);
+        Module.SourcePort  in  = createInputPort("in", WIDTH_PACKET);
+        Module.SinkPort    out = createOutputPort("out", WIDTH_PACKET, "");
+        Module.InstantiatedModule[] stages = new Module.InstantiatedModule[len];
+        if (len==0) {
+            new Event(new Object[] { in, out },
+                      new Action[] { in, out, new AssignAction(out, in) });
+        } else {
+            Module fifo0 = new FifoModule(0);
+            for(int i=0; i<=len; i++) {
+                if (i<len) stages[i] = new Module.InstantiatedModule(this, fifo0);
+                Module.SourcePort driver = i==0 ? in : stages[i-1].getOutputPort("out");
+                Module.SinkPort   driven = i==len ? out : stages[i].getInputPort("in");
+                driver.connect(driven);
+            }
+        }
+    }
+}
index 3198d88..c409eb0 100644 (file)
@@ -1,6 +1,5 @@
 package edu.berkeley.fleet.fpga;
 import edu.berkeley.fleet.fpga.*;
-import edu.berkeley.fleet.doc.*;
 import edu.berkeley.fleet.api.*;
 import edu.berkeley.fleet.ies44.*;
 import edu.berkeley.fleet.*;
@@ -11,356 +10,159 @@ import edu.berkeley.sbp.meta.*;
 import edu.berkeley.sbp.util.*;
 import java.util.*;
 import java.io.*;
+import edu.berkeley.fleet.two.*;
+import static edu.berkeley.fleet.ies44.InstructionEncoder.*;
+import static edu.berkeley.fleet.verilog.Verilog.*;
 
-public class Fpga extends Fleet {
 
-    public ArrayList<FpgaShip> shiplist   = new ArrayList<FpgaShip>();
-    public HashMap<String,FpgaShip> ships = new HashMap<String,FpgaShip>();
-    public Iterator<Ship> iterator() { return (Iterator<Ship>)(Object)shiplist.iterator(); }
+public class Fpga extends Fleet {
 
-    private String bitfile;
+    public Ship getShip(String type, int ordinal) {
+        for(Ship s : this)
+            if (s.getType().equals(type))
+                if (ordinal-- < 0)
+                    return s;
+        return null;
+    }
 
-    public static void main(String[] s) throws Exception {
-        new Fpga().dumpFabric(false);
+    public int getWordWidth() { return 37; }
+    private static final BitVector SIGNAL_ZERO = new BitVector(1);
+    private static final BitVector SIGNAL_ONE  = new BitVector(1);
+    static {
+        SIGNAL_ONE.set(0,true);
     }
 
-    public Fpga() { this("gaspified.bit"); }
-    public Fpga(String bitfile) {
-        this.bitfile = bitfile;
-        createShip("Debug",     "debug");
-        createShip("Memory",    "memory");
-        createShip("Memory",    "memory2");  // need this to avoid a bug
+    public Module top;
+    public FabricElement top_horn;
 
-        createShip("Fifo",      "fifo1");
-        createShip("Fifo",      "fifo2");
-        createShip("Alu2",      "alu2a");
-        createShip("BitFifo",   "bitfifo");
-        createShip("Rotator",   "rotator");
-        // above is the minimal ship set needed to run the regression suite, excluding "ships" tests
-        createShip("Alu1",      "alu1");
-        createShip("Lut3",      "lut3");
-        createShip("Alu3",      "alu3");
+    public LinkedHashMap<String,FpgaShip> ships = new LinkedHashMap<String,FpgaShip>();
+    public Iterator<Ship> iterator() { return (Iterator<Ship>)(Object)ships.values().iterator(); }
 
-        /*
-        createShip("Stack",     "Stack");
-        createShip("Fifo",    "fifo3");
-        createShip("Choice",    "Choice");
-        */
-        // above is the minimal ship set needed to run the regression suite, including "ships" tests
-
-        // below are extra bonus ships
-        /*
-        createShip("Alu2",    "alu2b");
-        createShip("Alu2",    "alu2c");
-        createShip("Alu2",    "alu2d");
-        createShip("Fifo",    "fifo4");
-        createShip("Memory",    "Memory");
-        createShip("Choice",    "Choice");
-        createShip("Choice",    "Choice");
-        createShip("Choice",    "Choice");
-        */
-        dumpFabric(true);
-    }
+    public static void main(String[] s) throws Exception { 
+        String prefix = s[0];
 
-    public Ship createShip(String type, String name) {
-        try {
-            ShipDescription sd = new ShipDescription(name, new BufferedReader(new InputStreamReader(new FileInputStream("ships/"+type+".ship"))));
-            FpgaShip ship = new FpgaShip(this, name, type, sd);
-            ships.put(name, ship);
-            shiplist.add(ship);
-            return ship;
-        } catch (IOException e) { throw new RuntimeException(e); }
+        new FunnelModule().dump(prefix);
+        new HornModule().dump(prefix);
+
+        new FifoModule(0).dump(prefix);
+        new FifoModule(4).dump(prefix);
+        new FifoModule(8).dump(prefix);
+        new FpgaDock.DockModule(false).dump(prefix);
+        new FpgaDock.DockModule(true).dump(prefix);
+
+        Module top = new Module("root");
+        new Fpga(top).top.dump(prefix);
     }
 
-    public FleetProcess run(final byte[] instructions) {
+    public FleetProcess run(Instruction[] instructions) {
         try {
-            return new Client(bitfile, instructions);
-        } catch (IOException e) { throw new RuntimeException(e); }
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            DataOutputStream dos = new DataOutputStream(baos);
+            for(Instruction i : instructions)
+                writeInstruction(dos, getUniversalSource(), i);
+            dos.flush();
+            return new Client("none", baos.toByteArray());
+        } catch (Exception e) { throw new RuntimeException(e); }
     }
 
-    public void dumpFabric(boolean quiet) {
-        // FIXME: this is really ugly: the order of port declarations in
-        //        the XXXShip.java file must match the order in the .balsa file!
-
-        ArrayList instructionports = new ArrayList<FpgaPump>();
-        for(FpgaShip ship : shiplist)
-            for(Pump port : ship.getPumps())
-                if (!((FpgaPump)port).special())
-                    instructionports.add(port);
-        FabricTree instructions =
-            new FabricTree((FpgaPump[])instructionports.toArray(new FpgaPump[0]),
-                           "ihorn",
-                           "instruction");
-
-        ArrayList inputports = new ArrayList<FpgaPump>();
-        for(FpgaShip ship : shiplist)
-            for(Pump port : ship.getPumps())
-                if (!((FpgaPump)port).special())
-                    inputports.add(port);
-        FabricTree inputs =
-            new FabricTree((FpgaPump[])inputports.toArray(new FpgaPump[0]),
-                           "horn",
-                           "dest");
-
-        ArrayList outputports = new ArrayList<FpgaPump>();
-        for(FpgaShip ship : shiplist)
-            for(Pump port : ship.getPumps())
-                if (!((FpgaPump)port).special() || ((FpgaPump)port).dhorn())
-                    outputports.add(port);
-        FabricTree outputs =
-            new FabricTree((FpgaPump[])outputports.toArray(new FpgaPump[0]),
-                           "funnel",
-                           "source");
-
-        ArrayList ihornports = new ArrayList<FpgaPump>();
-        for(FpgaShip ship : shiplist)
-            for(Pump port : ship.getPumps())
-                if (((FpgaPump)port).ihorn())
-                    ihornports.add(port);
-        FabricTree ihorns =
-            new FabricTree((FpgaPump[])ihornports.toArray(new FpgaPump[0]),
-                           "funnel",
-                           "ihorn");
-
-        if (quiet) return;
-        System.out.println("`include \"macros.v\"");
-        System.out.println("module fabric(clk, rst, data_Memory0_command_r, data_Memory0_command_a, data_Memory0_command,");
-        System.out.println("                   data_Debug0_out_r, data_Debug0_out_a, data_Debug0_out);");
-        System.out.println("  input  clk;");
-        System.out.println("  input  rst;");
-        System.out.println("  input  data_Memory0_command_r;");
-        System.out.println("  output data_Memory0_command_a;");
-        System.out.println("  output data_Debug0_out_r;");
-        System.out.println("  input  data_Debug0_out_a;");
-        System.out.println("  output [(`PACKET_WIDTH-1):0]      data_Debug0_out;");
-        System.out.println("  input  [(`PACKET_WIDTH-1):0]      data_Memory0_command;");
-        //System.out.println("  wire   [(`INSTRUCTION_WIDTH-1):0] data_Memory0_ihorn;");
-        //System.out.println("  wire   [(`PACKET_WIDTH-1):0]      data_Memory0_dhorn;");
-        System.out.println();
-        
-        System.out.println();
-
-        instructions.dumpChannels(true);
-        outputs.dumpChannels(true);
-        inputs.dumpChannels(true);
-        ihorns.dumpChannels(true);
-        for(FpgaShip ship : shiplist)
-            for(Pump port : ship.getPumps())
-                if (!((FpgaPump)port).special() || ((FpgaPump)port).dhorn())
-                    System.out.println("  wire [(`PACKET_WIDTH-1):0] data_"
-                                       +getUniqueName(ship)+"_"+port.getName()+";");
-
-        System.out.println("wire [(`PACKET_WIDTH-1):0] ihornleft;");
-
-        System.out.println("");
-        instructions.dumpChannels(false);
-        System.out.println("");
-        outputs.dumpChannels(false);
-        System.out.println("");
-        inputs.dumpChannels(false);
-        System.out.println("");
-        ihorns.dumpChannels(false);
-        System.out.println("");
-        for(FpgaShip ship : shiplist) {
-            System.out.print(ship.getType().toLowerCase());
-            System.out.print(" ");
-            System.out.print("krunk"+(krunk++));
-            System.out.print("(clk, rst, ");
-            boolean first = true;
-            for(Pump port : ship.getPumps()) {
-                if (!first) System.out.print(", ");
-                first = false;
-                String prefix = "data_";
-                if (((FpgaPump)port).ihorn()) prefix = "ihorn_";
-                if (((FpgaPump)port).dhorn()) prefix = "source_";
-                System.out.print(prefix+getUniqueName(port.getShip())+"_"+port.getName()+"_r, ");
-                System.out.print(prefix+getUniqueName(port.getShip())+"_"+port.getName()+"_a, ");
-                System.out.print(prefix+getUniqueName(port.getShip())+"_"+port.getName());
-                System.out.print(" ");
-            }
-            System.out.println(");");
-
-            for(Pump port : ship.getPumps()) {
-                if (((FpgaPump)port).special()) continue;
-                if (((FpgaPump)port).inbox) {
-                    System.out.print("inbox");
-                } else {
-                    System.out.print("outbox");
-                }
-                System.out.print(" krunk"+(krunk++)+"(clk, rst, ");
-                System.out.print("instruction_"+getUniqueName(port.getShip())+"_"+port.getName()+"_r, ");
-                System.out.print("instruction_"+getUniqueName(port.getShip())+"_"+port.getName()+"_a, ");
-                System.out.print("`packet_data(instruction_"+getUniqueName(port.getShip())+"_"+port.getName()+"), ");
-                System.out.print("dest_"+getUniqueName(port.getShip())+"_"+port.getName()+"_r, ");
-                System.out.print("dest_"+getUniqueName(port.getShip())+"_"+port.getName()+"_a, ");
-                System.out.print("dest_"+getUniqueName(port.getShip())+"_"+port.getName()+", ");
-                System.out.print("source_"+getUniqueName(port.getShip())+"_"+port.getName()+"_r, ");
-                System.out.print("source_"+getUniqueName(port.getShip())+"_"+port.getName()+"_a, ");
-                System.out.print("source_"+getUniqueName(port.getShip())+"_"+port.getName()+", ");
-                System.out.print("data_"+getUniqueName(port.getShip())+"_"+port.getName()+"_r, ");
-                System.out.print("data_"+getUniqueName(port.getShip())+"_"+port.getName()+"_a, ");
-                System.out.print("data_"+getUniqueName(port.getShip())+"_"+port.getName());
-                System.out.print(");");
-                System.out.println();
-            }
-
-        }
+    // Setup //////////////////////////////////////////////////////////////////////////////
 
-        System.out.println("funnel ihornfun(clk, rst, "+
-                           "             ihornleft_r, ihornleft_a, ihornleft,"+
-                           "             ihorn_r, ihorn_a, ihorn,"+
-                           "             source_r, source_a, source);");
-        System.out.println("horn tophorn(clk, rst, "+
-                           "             ihornleft_r, ihornleft_a, ihornleft,"+
-                           "             instruction_r, instruction_a, instruction,"+
-                           "             dest_r, dest_a, dest);");
-        /*
-        System.out.println("assign instruction_r = ihorn_r;");
-        System.out.println("assign ihorn_a = instruction_a;");
-        System.out.println("assign instruction = ihorn;");
-        System.out.println("assign dest_r = source_r;");
-        System.out.println("assign source_a = dest_a;");
-        System.out.println("assign dest = source;");
-        */
-        System.out.println("endmodule");
+    public Ship createShip(String type, String name) throws IOException {
+        ShipDescription sd = new ShipDescription(type, new BufferedReader(new InputStreamReader(new FileInputStream("ships/"+type+".ship"))));
+        FpgaShip ship = new FpgaShip(this, sd);
+        ships.put(name, ship);
+        return ship;
     }
 
-    private static class FabricTree {
-        int master_idx = 1;
-        String prefix;
-        Node root;
-        public void dumpChannels(boolean decl) { root.dumpChannels(0, decl); }
-        public FabricTree(FpgaPump[] ports, String component, String prefix) {
-            this.prefix = prefix;
-            root = (Node)mkNode("", component, ports, 0, ports.length, 0, 0);
-        }
-        private Object mkNode(String name, String component, FpgaPump[] ports,
-                              int start, int end, int addr, int bits) {
-            if (end-start == 0) return null;
-            if (end-start == 1) {
-                FpgaPump p = ports[start];
-                if (prefix.equals("instruction")) {
-                    p.instr_addr = (addr<<1);
-                    p.instr_bits = bits+1;
-                } else if (prefix.equals("dest")) {
-                    p.addr = (addr << 1) | 1;
-                    p.bits = bits+1;
-                    if (bits >= 11)
-                        throw new RuntimeException("too many pumps!");
-                    int count = 0;
-                    for(Destination d : p.getDestinations()) {
-                        if (!(d instanceof FpgaPump.VirtualPort)) continue;
-                        FpgaPump.VirtualPort vp = (FpgaPump.VirtualPort)d;
-                        vp.addr = p.addr | (count << bits);
-                        count++;
-                    }
-                }
-                return p;
-            }
-            int len = end-start;
-            int count   = 0;
-            int count2  = 0;
-            int breakpt = 0;
-            if (end-start <= 2) {
-                breakpt = (start+end)/2;
-            } else {
-                for(int i=start; i<end; i++)
-                    count += count(ports[i].getDestinations());
-                for(int i=start; i<end-1; i++) {
-                    count2 += count(ports[i].getDestinations());
-                    breakpt = i;
-                    if (i>start && count2 >= count/2) break;
-                }
-            }
-            return new Node(name,
-                            component,
-                            mkNode(name+"_0", component, ports, start, breakpt, addr,               bits+1),
-                            mkNode(name+"_1", component, ports, breakpt, end,   addr | (1 << bits), bits+1),
-                            addr,
-                            bits);
+    public Fpga() throws Exception { this(new Module("root")); }
+    public Fpga(Module top) throws Exception {
+        this.top = top;
+        debugShip = createShip("Debug",     "debug");
+        createShip("Memory",    "memory");
+        createShip("Fifo",      "fifo1");
+        createShip("Fifo",      "fifo2");
+        createShip("Alu2",      "alu2a");
+        createShip("Rotator",   "rotator");
+        //createShip("Alu1",      "alu1");
+        createShip("Lut3",      "lut3");
+        createShip("Alu3",      "alu3");
+
+        Module fifostage = new FifoModule(0);
+        Module fifo4     = new FifoModule(4);
+        Module fifo8     = new FifoModule(8);
+        Module horn      = new HornModule();
+        Module funnel    = new FunnelModule();
+        Module outbox    = new FpgaDock.DockModule(false);
+        Module inbox     = new FpgaDock.DockModule(true);
+
+        Module.SinkPort    debug_in    = top.createWirePort("debug_in", WIDTH_PACKET);
+        Module.SourcePort  debug_out   = null;
+        for(FpgaShip ship : (Iterable<FpgaShip>)(Object)this) {
+            if (ship.getType().toLowerCase().equals("debug"))
+                debug_out = ship.getVerilogModule().getOutputPort("debug_out");
         }
-        private String describe(String prefix, Object o) {
-            if (o==null) return null;
-            if (o instanceof FpgaPump) {
-                FpgaPump p = (FpgaPump)o;
-                return prefix+"_"+getUniqueName(p.getShip())+"_"+p.getName();
-            }
-            if (o instanceof Node) {
-                return ((Node)o).describe(prefix);
+
+        Module.SourcePort  in          = top.createInputPort("in", 8);
+        Module.SinkPort    out         = top.createOutputPort("out", 8, "");
+        Module.Latch       temp_in     = top.new Latch("temp", WIDTH_PACKET) { public String doReset() { return name+"=0;"; } };
+        Module.Latch       count       = top.new Latch("count", 8);
+        Module.Latch       count_out   = top.new Latch("count_out", 8);
+        top.new Event(new Object[] { in, debug_in },
+                      new Object[] { new SimpleAction(temp_in.getVerilogName()+" = ("+temp_in.getVerilogName()+" << 8) | in;"),
+                                     new SimpleAction("if (count >= 5) begin"+
+                                                          " count <= 0; "+
+                                                          " `packet_token("+debug_in.getVerilogName()+") <= 0;"+
+                                                          " `packet_data("+debug_in.getVerilogName()+") <= "+temp_in.getVerilogName()+";"+
+                                                          " `packet_dest("+debug_in.getVerilogName()+") <= `instruction_dest("+temp_in.getVerilogName()+");"+
+                                                          " "+debug_in.getVerilogName()+"_r <= 1; "+
+                                                          "end else count <= count+1; "),
+                                     in
+                  });
+        top.new Event(new Object[] { out, debug_out },
+                      new Object[] { new SimpleAction(out.getVerilogName()+" <= ("+debug_out.getVerilogName()+">> (count_out*8));"),
+                                     new SimpleAction("if (count_out >= 5) begin "+
+                                                          "count_out <= 0; "+debug_out.getVerilogName()+"_a <= 1; end"+
+                                                          " else count_out <= count_out+1; "),
+                                     out });
+
+        ArrayList sources = new ArrayList<FabricElement>();
+        ArrayList dests   = new ArrayList<FabricElement>();
+        for(FpgaShip ship : (Iterable<FpgaShip>)(Object)this) {
+            if (ship.getType().toLowerCase().equals("debug"))
+                debug_out = ship.getVerilogModule().getOutputPort("debug_out");
+            for(Dock port : ship) {
+                sources.add(((FpgaDock)port));
+                dests.add(port.getInstructionDestination());
+                dests.add(port.getDataDestination());
             }
-            return null;
         }
-        private class Node {
-            Object left;
-            Object right;
-            String name;
-            String component;
-            int addr;
-            int bits;
-            public Node(String name, String component, Object left, Object right, int addr, int bits) {
-                this.left = left;
-                this.right = right;
-                this.name = name;
-                this.component = component;
-                this.addr = addr;
-                this.bits = bits;
-            }
-            public void dumpChannels(int indentamount, boolean decl) {
-                String indent = "";
-                for(int i=0; i<indentamount; i++) indent += "  ";
-                if (decl) {
-                    String n = describe(prefix).startsWith("instruction")
-                        ? "[(`PACKET_WIDTH-1):0]" : "[(`PACKET_WIDTH-1):0]";
-                    System.out.println("  wire "+n+" "+indent+describe(prefix)+";");
-                } else {
-                    System.out.println("     "+indent+
-                                       component+" "+
-                                       "krunk"+(krunk++)+"(clk, rst, "+
-                                       describe(prefix)+"_r, "+
-                                       describe(prefix)+"_a, "+
-                                       describe(prefix)+", "+
-                                       FabricTree.this.describe(prefix, left)+"_r, "+
-                                       FabricTree.this.describe(prefix, left)+"_a, "+
-                                       FabricTree.this.describe(prefix, left)+", "+
-                                       FabricTree.this.describe(prefix, right)+"_r, "+
-                                       FabricTree.this.describe(prefix, right)+"_a, "+
-                                       FabricTree.this.describe(prefix, right)+
-                                       ");");
-                }
-                dumpChannels(left, indentamount+1, decl);
-                dumpChannels(right, indentamount+1, decl);
-            }
-            public void dumpChannels(Object o, int indentamount, boolean decl) {
-                if (o==null) return;
-                if (o instanceof Node) {
-                    ((Node)o).dumpChannels(indentamount, decl);
-                } else {
-                    String indent = "";
-                    for(int i=0; i<indentamount; i++) indent += "  ";
-                    if (decl) {
-                        String n = FabricTree.this.describe(prefix,o).startsWith("instruction")
-                            ? "[(`PACKET_WIDTH-1):0]" : "[(`PACKET_WIDTH-1):0]";
-                        System.out.println("  wire "+n+" "+indent+FabricTree.this.describe(prefix,o)+";");
-                    }
-                }
-            }
-            public String describe(String prefix) {
-                return prefix+name;
+        top_horn = mkNode((FabricElement[])dests.toArray(new FabricElement[0]), true);
+        FabricElement   source  = mkNode((FabricElement[])sources.toArray(new FabricElement[0]), false);
+        FunnelModule.FunnelInstance top_funnel = new FunnelModule.FunnelInstance(top, debug_in, source.getOutputPort());
+        ((FunnelModule.FunnelInstance)source).out = top_funnel;
+        //top_horn.addInput(top_funnel, top_funnel.getOutputPort());
+        top_funnel.addOutput(top_horn, top_horn.getInputPort());
+    }
+
+    public FabricElement mkNode(FabricElement[] ports, boolean is_horn) { return mkNode(ports, is_horn, 0, ports.length); }
+    public FabricElement mkNode(FabricElement[] ports, boolean is_horn, int start, int end) {
+        switch(end-start) {
+            case 0: return null;
+            case 1: return ports[start];
+            default: {
+                FabricElement leftPort  = mkNode(ports, is_horn,  start,         (end+start)/2);
+                FabricElement rightPort = mkNode(ports, is_horn,  (end+start)/2, end);
+                return is_horn
+                    ? new HornModule.HornInstance(top,     leftPort, rightPort)
+                    : new FunnelModule.FunnelInstance(top, leftPort, rightPort);
             }
         }
     }
-    public static int krunk=0;
 
-    private static String getUniqueName(Ship ship) {
-        return ship.getType() + ship.getOrdinal();
-    }
+    public Module getVerilogModule() { return top; }
 
-    private static int count(Iterable<Destination> it) {
-        int ret = 0;
-        for(Destination d : it)
-            ret++;
-        return ret;
-    }
+
+    // Expand //////////////////////////////////////////////////////////////////////////////
 
     public void expand(ShipDescription sd) {
         try {
@@ -372,32 +174,25 @@ public class Fpga extends Fleet {
             FileOutputStream out = new FileOutputStream(outf);
             PrintWriter pw = new PrintWriter(out);
 
-            boolean auto =
-                !"debug".equals(filename) &&
-                !"execute".equals(filename) &&
-                !"memory".equals(filename) &&
-                !"fifo".equals(filename);
+            boolean auto = !"debug".equals(filename);
 
             if (auto) {
                 pw.println("`include \"macros.v\"");
                 pw.println();
 
-            pw.print("`define reset ");
-            for(PumpDescription bb : sd) {
-                String bb_name = bb.getName();
-                if (bb.isInbox()) {
-                    pw.print(bb_name+"_a <= 1; ");
-                } else {
-                    pw.print(bb_name+"_r <= 0; ");
+                pw.print("`define reset ");
+                for(DockDescription bb : sd) {
+                    String bb_name = bb.getName();
+                    if (bb.isInputDock()) pw.print(bb_name+"_a <= 1; ");
+                    else              pw.print(bb_name+"_r <= 0; ");
                 }
-            }
-            pw.println();
+                pw.println();
 
                 pw.println("module " + filename + "( clk, rst ");
-                for(PumpDescription bb : sd) {
+                for(DockDescription bb : sd) {
                     String bb_name = bb.getName();
                     pw.print("        ");
-                    if (bb.isInbox()) {
+                    if (bb.isInputDock()) {
                         pw.print(", " + bb_name+"_r");
                         pw.print(", " + bb_name+"_a_");
                         pw.print(", " + bb_name+"_d");
@@ -412,15 +207,15 @@ public class Fpga extends Fleet {
                 pw.println();
                 pw.println("    input clk;");
                 pw.println("    input rst;");
-                for(PumpDescription bb : sd) {
+                for(DockDescription bb : sd) {
                     String bb_name = bb.getName();
                     pw.print("        ");
-                    if (bb.isInbox()) {
+                    if (bb.isInputDock()) {
                         pw.println("`input(" +
                                    bb_name+"_r,  "+
                                    bb_name+"_a,  "+
                                    bb_name+"_a_, "+
-                                   "[(`PACKET_WIDTH-1):0],"+
+                                   "[("+WIDTH_WORD+"-1):0],"+
                                    bb_name+"_d)"
                                    );
                     } else {
@@ -428,14 +223,15 @@ public class Fpga extends Fleet {
                                    bb_name+"_r,  "+
                                    bb_name+"_r_, "+
                                    bb_name+"_a,  "+
-                                   "[(`PACKET_WIDTH-1):0],"+
+                                   "[("+WIDTH_WORD+"-1):0],"+
                                    bb_name+"_d_)"
                                    );
-                        pw.println("`defreg(" +
-                                   bb_name+"_d_,  "+
-                                   "[(`PACKET_WIDTH-1):0],"+
-                                   bb_name+"_d)"
-                                   );
+                        if (!bb_name.equals("out") || !"memory".equals(filename))
+                            pw.println("`defreg(" +
+                                       bb_name+"_d_,  "+
+                                       "[("+WIDTH_WORD+"-1):0],"+
+                                       bb_name+"_d)"
+                                       );
                     }
                     pw.println();
                 }
@@ -451,33 +247,39 @@ public class Fpga extends Fleet {
         } catch (Exception e) { throw new RuntimeException(e); }
     }
 
-    public int computeOffset(int origin, int target) { return (target - origin)/6; }
-    public int computeTarget(int origin, int offset) { return origin + (offset*6); }
-
     private FpgaInstructionEncoder iie = new FpgaInstructionEncoder();
-    public Instruction readInstruction(DataInputStream is) throws IOException { return iie.readInstruction(is); }
-    public Instruction readInstruction(long instr) { return iie.readInstruction(instr); }
-    public long writeInstruction(Instruction d) { return writeInstruction(d); }
-    public void writeInstruction(DataOutputStream os, Instruction d) throws IOException { iie.writeInstruction(os, d); }
+    public Instruction readInstruction(DataInputStream is, Dock dispatchFrom) throws IOException { return iie.readInstruction(dispatchFrom, is); }
+    public Instruction readInstruction(Dock dispatchFrom, long instr) { return iie.readInstruction(dispatchFrom, instr); }
+    public long writeInstruction(Dock dispatchFrom, Instruction d) { return iie.writeInstruction(dispatchFrom, d); }
+    public void writeInstruction(DataOutputStream os, Dock dispatchFrom, Instruction d) throws IOException { iie.writeInstruction(os, dispatchFrom, d); }
+
+    private Ship debugShip;
 
+
+    public Dock getUniversalSource() { return debugShip.getDock("in"); }
     private class FpgaInstructionEncoder extends InstructionEncoder {
-        public long getDestAddr(Destination box) { return ((FpgaPump.VirtualPort)box).addr; }
-        public long getBoxInstAddr(Pump box) { return ((FpgaPump)box).instr_addr; }
-        public Destination getDestByAddr(long dest) {
+        public Dock getUniversalSource() { return debugShip.getDock("in"); }
+        public long getDestAddr(Path path) {
+            return ((FpgaPath)path).toLong();
+        }
+        public Path getPathByAddr(Dock source, long dest) {
             for(Ship ship : Fpga.this)
-                for(Pump bb : ship.getPumps())
-                    for(Destination d : bb.getDestinations())
-                        if (getDestAddr(d)==dest)
-                            return d;
+                for(Dock bb : ship) {
+                    for(Destination d : new Destination[] { bb.getInstructionDestination(), bb.getDataDestination() }) {
+                        for(BitVector signal : new BitVector[] { SIGNAL_ZERO, SIGNAL_ONE }) {
+                            FpgaPath p = (FpgaPath)source.getPath(d, signal);
+                            if (p.toLong() == dest) return p;
+                        }
+                    }
+                }
             return null;
         }
-        public Pump getBoxByInstAddr(long dest) {
+        public Dock getBoxByInstAddr(long dest) {
             for(Ship ship : Fpga.this)
-                for(Pump bb : ship.getPumps())
-                    if (((FpgaPump)bb).instr_addr == dest)
+                for(Dock bb : ship)
+                    if (((FpgaDestination)((FpgaDock)bb).getInstructionDestination()).getAddr() == dest)
                         return bb;
             return null;
         }
     }
-
-}
\ No newline at end of file
+}
diff --git a/src/edu/berkeley/fleet/fpga/FpgaDestination.java b/src/edu/berkeley/fleet/fpga/FpgaDestination.java
new file mode 100644 (file)
index 0000000..a57910c
--- /dev/null
@@ -0,0 +1,47 @@
+package edu.berkeley.fleet.fpga;
+import edu.berkeley.fleet.api.*;
+import edu.berkeley.fleet.ies44.*;
+import edu.berkeley.fleet.*;
+import java.lang.reflect.*;
+import edu.berkeley.sbp.chr.*;
+import edu.berkeley.sbp.misc.*;
+import edu.berkeley.sbp.meta.*;
+import edu.berkeley.sbp.util.*;
+import java.util.*;
+import java.io.*;
+import static edu.berkeley.fleet.ies44.InstructionEncoder.*;
+import static edu.berkeley.fleet.verilog.Verilog.*;
+import edu.berkeley.fleet.api.*;
+import static edu.berkeley.fleet.verilog.Verilog.*;
+import edu.berkeley.fleet.api.Dock;
+import java.util.*;
+
+
+public class FpgaDestination extends Destination implements FabricElement {
+    private Module.Port port;
+    private FpgaDock dock;
+
+    public FpgaDestination(FpgaDock dock, Module.Port port, boolean isInstructionDestination) {
+        super(dock);
+        this.port = port;
+        this.dock = dock;
+    }
+
+    public Module.Port getOutputPort() { throw new RuntimeException(); }
+    public Module.Port getInputPort()  { throw new RuntimeException(); }
+    public void addOutput(FabricElement out, Module.Port outPort) { throw new RuntimeException(); }
+
+    public long getAddr() {
+        return ((Fpga)dock.getShip().getFleet()).top_horn.getPath(this,null).toLong();
+    }
+    public FpgaPath getPath(FabricElement dest, BitVector signal) {
+        if (dest==this) return FpgaPath.emptyPath(this, signal);
+        return null;
+    }
+    public void addInput(FabricElement in, Module.Port inPort) {
+        inPort.connect((Module.SinkPort)port);
+    }
+    public String toString() {
+        return dock.toString();
+    }
+}
diff --git a/src/edu/berkeley/fleet/fpga/FpgaDock.java b/src/edu/berkeley/fleet/fpga/FpgaDock.java
new file mode 100644 (file)
index 0000000..259409d
--- /dev/null
@@ -0,0 +1,328 @@
+package edu.berkeley.fleet.fpga;
+import edu.berkeley.fleet.api.*;
+import edu.berkeley.fleet.ies44.*;
+import edu.berkeley.fleet.*;
+import java.lang.reflect.*;
+import edu.berkeley.sbp.chr.*;
+import edu.berkeley.sbp.misc.*;
+import edu.berkeley.sbp.meta.*;
+import edu.berkeley.sbp.util.*;
+import java.util.*;
+import java.io.*;
+import static edu.berkeley.fleet.ies44.InstructionEncoder.*;
+import static edu.berkeley.fleet.verilog.Verilog.*;
+import edu.berkeley.fleet.api.*;
+import static edu.berkeley.fleet.verilog.Verilog.*;
+import edu.berkeley.fleet.api.Dock;
+import edu.berkeley.fleet.two.*;
+import java.util.*;
+
+
+/** the pump itself is a */
+public class FpgaDock extends FleetTwoDock implements FabricElement {
+
+    private static final int INSTRUCTION_FIFO_SIZE = 8;
+        
+    private FpgaDestination dataDestination;
+    private FpgaDestination instructionDestination;
+
+    private Module.InstantiatedModule instance;
+
+    public Module.InstantiatedModule getInstance() { return instance; }
+
+    public Destination getDataDestination() { return dataDestination; }
+    public Destination getInstructionDestination() { return instructionDestination; }
+    public int         getInstructionFifoSize() { return INSTRUCTION_FIFO_SIZE; }
+
+    FpgaDock(FpgaShip ship, DockDescription bbd) {
+        super(ship, bbd);
+        this.instance = new Module.InstantiatedModule(((Fpga)ship.getFleet()).top, new DockModule(isInputDock()));
+        this.dataDestination = new FpgaDestination(this, this.instance.getInputPort("fabric_in"), false);
+        this.instructionDestination = new FpgaDestination(this, this.instance.getInputPort("instruction"), true);
+        Module.InstantiatedModule shipm = ship.getVerilogModule();            
+        if (isInputDock()) {
+            instance.getOutputPort("ship").connect(shipm.getInputPort(getName()));
+        } else {
+            shipm.getOutputPort(getName()).connect(instance.getInputPort("ship"));
+        }
+    }
+
+
+    // FabricElement methods //////////////////////////////////////////////////////////////////////////////
+
+    private FabricElement upstream;
+    public Module.Port getOutputPort() { throw new RuntimeException(); }
+    public Module.Port getInputPort()  { throw new RuntimeException(); }
+    public FpgaPath getPath(FabricElement dest, BitVector signal) { return upstream.getPath((FabricElement)dest, signal); }
+    public FpgaPath getPath(Destination dest,BitVector signal) { return upstream.getPath((FabricElement)dest, signal); }
+    public void addInput(FabricElement in, Module.Port inPort) { throw new RuntimeException(); }
+    public void addOutput(FabricElement out, Module.Port outPort) {
+        this.upstream = out;
+        instance.getOutputPort("fabric_out").connect((Module.SinkPort)outPort);
+    }
+
+    public static class DockModule extends Module {
+
+        public DockModule(boolean inbox) {
+            super(inbox ? "inbox" : "outbox");
+            Module fifo4     = new FifoModule(4);
+            Module fifo8     = new FifoModule(8);
+            Module fifo      = fifo8;
+            Module ififo_m   = new FifoModule(INSTRUCTION_FIFO_SIZE);
+            Module efifo_m   = fifo4;
+            Module.SourcePort instruction   = createInputPort("instruction",       WIDTH_PACKET);
+            instruction.hasLatch = true;
+
+            Module.SourcePort fabric_in     = createInputPort("fabric_in",   WIDTH_PACKET);
+            Module.SinkPort   fabric_out    = createOutputPort("fabric_out", WIDTH_PACKET, "");
+            Module.InstantiatedModule dfifo = new Module.InstantiatedModule(this, fifo);
+            fabric_in.connect(dfifo.getInputPort("in"));
+        
+            Module.SourcePort dfifo_out = dfifo.getOutputPort("out");
+            Module.SourcePort   ship_out    = null;
+            if (!inbox) {
+                ship_out = createInputPort("ship",        WIDTH_WORD);
+                ship_out.hasLatch = true;
+            }
+
+            Module.SinkPort   ship_in     = null;
+            if (inbox) {
+                ship_in = createOutputPort("ship",        WIDTH_PACKET, "");
+                ship_in.hasLatch = true;
+            }
+
+            Module.Latch     ondeck         = new Latch("ondeck", WIDTH_WORD);
+            Module.Latch     repeat_counter = new Latch("repeat_counter", SET_ILC_FROM_IMMEDIATE.valmaskwidth+1, 1);
+            Module.Latch     loop_counter   = new Latch("loop_counter", SET_OLC_FROM_IMMEDIATE.valmaskwidth, 1);
+            Module.Latch     tapl           = new Latch("tapl", SET_TAPL_FROM_IMMEDIATE.valmaskwidth);
+            Module.Latch     flag_a         = new Latch("flag_a", 1);
+            Module.Latch     flag_b         = new Latch("flag_b", 1);
+            Module.Latch     flag_c         = new Latch("flag_c", 1);
+            Module.StateWire ondeckFull     = new StateWire("ondeck_full");
+            Module.StateWire newMayProceed  = new StateWire("newmayproceed", true);
+            Module.StateWire doRepeat       = new StateWire("dorepeat", false);
+
+            Module.StateWire  isHatchOpen   = new StateWire("hatch", true);
+        
+            Module.SinkPort   token_out     = fabric_out;
+            Module.SourcePort token_in      = dfifo_out;
+            Module.SinkPort   data_out      = inbox ? ship_in   : fabric_out;
+            Module.SourcePort data_in       = inbox ? dfifo_out : ship_out;
+
+            Module.InstantiatedModule ififo = new Module.InstantiatedModule(this, ififo_m);
+            Module.SinkPort   ififo_in      = ififo.getInputPort("in");
+            Module.SourcePort ififo_out     = ififo.getOutputPort("out");
+
+            Module.InstantiatedModule efifo = new Module.InstantiatedModule(this, efifo_m);
+            Module.SinkPort   efifo_in      = efifo.getInputPort("in");
+            Module.SourcePort efifo_out     = efifo.getOutputPort("out");
+            efifo_in.hasLatch = true;
+
+            addPreCrap("wire [(`DATAWIDTH-1):0] data_latch_output;");
+            addPreCrap("wire [(`DATAWIDTH-1):0] data_latch_input;");
+            addPreCrap("assign data_latch_output = " +
+                       (inbox ? data_out.getName() : "`packet_data("+data_out.getName()+")")+";");
+            addPreCrap("assign data_latch_input = " +
+                       (inbox ? "`packet_data("+data_in.getName()+")" : data_in.getName())+";");
+            Assignable data_latch    = new SimpleAssignable(inbox ? data_out.getName() :
+                                                            "`packet_data("+data_out.getName()+")");
+            String data_latch_input  = "data_latch_input";
+
+            // Open the Hatch
+            new Event(new Object[] { "loop_counter==0" },
+                      new Action[] { isHatchOpen.doFill() });
+
+            // Torpedo Arrival
+            new Event(new Object[] { instruction,
+                                     PACKET_TOKEN.verilogVal("instruction"),
+                                     ondeckFull.isFull(),
+                                     token_out,
+                                     I.verilog("ondeck"),
+                },
+                new Action[] { instruction,
+                               ondeckFull.doDrain(),
+                               newMayProceed.doFill(),
+                               new AssignAction(loop_counter, "0"),
+                               new AssignAction(repeat_counter, "1"),
+                               new AssignAction(new SimpleAssignable("`packet_token("+token_out.getName()+")"), "1"),
+                               new AssignAction(new SimpleAssignable("`packet_dest("+token_out.getName()+")"), "tapl"),
+                               token_out,
+                               isHatchOpen.doFill(),
+                });
+            // Non-Torpedo Arrival
+            new Event(new Object[] { instruction,
+                                     efifo_in,
+                                     "!("+PACKET_TOKEN.verilogVal("instruction")+")"
+                },
+                new Action[] {
+                    efifo_in,
+                    instruction,
+                    new AssignAction(efifo_in, instruction)
+                });
+
+            // Tail
+            new Event(new Object[] { efifo_out, TAIL.verilog("`packet_data("+efifo_out.getName()+")") },
+                      new Action[] { efifo_out, isHatchOpen.doDrain() } );
+            // Enqueue
+            new Event(new Object[] { efifo_out,
+                                     ififo_in,
+                                     "!("+TAIL.verilog("`packet_data("+efifo_out.getName()+")")+")",
+                                     isHatchOpen.isFull() },
+                new Action[] { efifo_out, ififo_in, new AssignAction(ififo_in, "`packet_data("+efifo_out.getName()+")")  } );
+
+            // New
+            new Event(new Object[] { ififo_out,
+                                     ondeckFull.isEmpty(),
+                                     newMayProceed.isFull(),
+                                     },
+                      new Action[] { ififo_out,
+                                     ondeckFull.doFill(),
+                                     newMayProceed.doDrain(),
+                                     new AssignAction(ondeck, ififo_out)
+                      }
+                      );
+
+            // RepeatExecute
+            new Event(new Object[] { doRepeat.isFull() },
+                      new Action[] { doRepeat.doDrain(), ondeckFull.doFill(),
+                                     new AssignAction(repeat_counter,
+                                                      "repeat_counter==`magic_standing_value?`magic_standing_value:(repeat_counter-1)")
+                      });
+
+            // Execute                                     
+            new Event(
+                      new Object[] { ondeckFull.isFull(),
+                                     data_out,
+                                     token_out,
+                                     ififo_in,
+                                     "(!`predicate_met(ondeck) || "+OS.verilog("ondeck")+" || !hatch)",
+                                     new ConditionalTrigger("(`predicate_met(ondeck) && `instruction_bit_datain(ondeck))", data_in),
+                                     new ConditionalTrigger("(`predicate_met(ondeck) && `instruction_bit_tokenin(ondeck))", token_in)
+                      },
+                      new Action[] { ondeckFull.doDrain(),
+                                     new ConditionalAction("`done_executing(ondeck)",                            newMayProceed.doFill()),
+                                     new ConditionalAction("`done_executing(ondeck) && `instruction_is_normal(ondeck)",
+                                                           new AssignAction(repeat_counter, "1")),
+                                     new ConditionalAction("`should_requeue(ondeck) && `done_executing(ondeck)", ififo_in),
+                                     new ConditionalAction("`should_requeue(ondeck) && `done_executing(ondeck)", new AssignAction(ififo_in, ondeck)),
+                                     new ConditionalAction("!`done_executing(ondeck)", doRepeat.doFill()),
+
+                                     new ConditionalAction("`predicate_met(ondeck) && `instruction_is_load_data_to_loop(ondeck)",
+                                                           new AssignAction(loop_counter, "data_latch_output")),
+                                     new ConditionalAction("`predicate_met(ondeck) && `instruction_is_load_immediate_to_loop(ondeck)",
+                                                           new AssignAction(loop_counter, "`instruction_loop_count_immediate(ondeck)")),
+                                     new ConditionalAction("`predicate_met(ondeck) && `instruction_is_decr_loop(ondeck)",
+                                                           new AssignAction(loop_counter, "loop_counter==0 ? 0 : (loop_counter-1)")),
+
+                                     new ConditionalAction("`predicate_met(ondeck) && `instruction_is_load_data_to_repeat(ondeck)",
+                                                           new AssignAction(repeat_counter, "data_latch_output")),
+                                     new ConditionalAction("`predicate_met(ondeck) && `instruction_is_load_immediate_to_repeat(ondeck)",
+                                                           new AssignAction(repeat_counter, "`instruction_repeat_count_immediate(ondeck)")),
+                                     new ConditionalAction("`predicate_met(ondeck) && `instruction_is_load_standing_to_repeat(ondeck)",
+                                                           new AssignAction(repeat_counter, "`magic_standing_value")),
+                                     new ConditionalAction("`predicate_met(ondeck) &&"+SHIFT.verilog("ondeck"),
+                                                           new AssignAction(data_latch,
+                                                                            "({ data_latch_output["+(WIDTH_WORD-1-19)+":0], 19'b0 } | "+
+                                                                            SHIFT.verilogVal("ondeck")+")")),
+                                     new ConditionalAction("`predicate_met(ondeck) && "+SET_IMMEDIATE.verilog("ondeck"),
+                                                           new AssignAction(data_latch,
+                                                                            "{ {"+(WIDTH_WORD-InstructionEncoder.DataLatch_WIDTH)+
+                                                                            "{"+SET_IMMEDIATE_EXTEND.verilogVal("ondeck")+"}}, "+
+                                                                            SET_IMMEDIATE.verilogVal("ondeck")+" }")),
+                                     new ConditionalAction("`predicate_met(ondeck) && `instruction_is_setflags(ondeck)",
+                                                           new AssignAction(flag_a, "`new_flag_a(ondeck)")),
+                                     new ConditionalAction("`predicate_met(ondeck) && `instruction_is_setflags(ondeck)",
+                                                           new AssignAction(flag_b, "`new_flag_b(ondeck)")),
+                                     (inbox
+                                      ? new ConditionalAction("`predicate_met(ondeck) && "+
+                                                              "(`instruction_bit_datain(ondeck) || `instruction_bit_tokenin(ondeck))",
+                                                              new AssignAction(flag_c, PACKET_SIGNAL.verilogVal(dfifo_out.getName())))
+                                      : new ConditionalAction("`predicate_met(ondeck) && "+
+                                                              "(!`instruction_bit_datain(ondeck) && `instruction_bit_tokenin(ondeck))",
+                                                              new AssignAction(flag_c, PACKET_SIGNAL.verilogVal(dfifo_out.getName())))
+                                      /* FIXME: C-flag-from-ship */
+                                      ),
+                                     new ConditionalAction("`predicate_met(ondeck) && `instruction_bit_datain(ondeck)",   data_in),
+                                     new ConditionalAction("`predicate_met(ondeck) && `instruction_bit_dataout(ondeck)",  data_out),
+                                     new ConditionalAction("`predicate_met(ondeck) && `instruction_bit_tokenin(ondeck)",  token_in),
+                                     new ConditionalAction("`predicate_met(ondeck) && `instruction_bit_tokenout(ondeck)", token_out),
+                                     new ConditionalAction("`predicate_met(ondeck) && `instruction_bit_tokenout(ondeck)",
+                                                           new AssignAction(new SimpleAssignable("`packet_token("+token_out.getName()+")"),
+                                                                            "1")),
+                                     new ConditionalAction("`predicate_met(ondeck) && !`instruction_bit_tokenout(ondeck)",
+                                                           new AssignAction(new SimpleAssignable("`packet_token("+token_out.getName()+")"),
+                                                                            "0")),
+                                     new ConditionalAction("`predicate_met(ondeck) && `instruction_bit_latch(ondeck)",
+                                                           new AssignAction(data_latch, data_latch_input)),
+                                     new ConditionalAction("`predicate_met(ondeck) && `instruction_path_from_data(ondeck)",
+                                                           new AssignAction(new SimpleAssignable("`packet_signal_and_dest("+token_out.getName()+")"),
+                                                                            DISPATCH_PATH.verilogVal(data_latch_input))),
+                                     new ConditionalAction("`predicate_met(ondeck) && "+SET_TAPL_FROM_IMMEDIATE.verilog("ondeck"),
+                                                           new AssignAction(tapl, SET_TAPL_FROM_IMMEDIATE.verilogVal("ondeck"))),
+                                     new ConditionalAction("`predicate_met(ondeck) && `instruction_path_from_immediate(ondeck)",
+                                                           new AssignAction(new SimpleAssignable("`packet_signal_and_dest("+token_out.getName()+")"),
+                                                                            "`instruction_path_immediate(ondeck)")),
+                      }
+                      );
+        }
+
+        public void dump(PrintWriter pw, boolean fix) {
+
+            pw.println("`define packet_signal_and_dest(p)                 { "+PACKET_SIGNAL.verilogVal("p")+", "+PACKET_DEST.verilogVal("p")+" }");
+            pw.println("`define instruction_is_load_data_to_repeat(i)     "+SET_ILC_FROM_DATA_LATCH.verilog("i"));
+            pw.println("`define instruction_is_load_data_to_loop(i)       "+SET_OLC_FROM_DATA_LATCH.verilog("i"));
+            pw.println("`define instruction_is_load_immediate_to_repeat(i)  "+SET_ILC_FROM_IMMEDIATE.verilog("i"));
+            pw.println("`define instruction_is_load_immediate_to_loop(i)    "+SET_OLC_FROM_IMMEDIATE.verilog("i"));
+            pw.println("`define instruction_is_load_standing_to_repeat(i) "+SET_ILC_FROM_INFINITY.verilog("i"));
+            pw.println("`define instruction_repeat_count_immediate(i)       "+SET_ILC_FROM_IMMEDIATE.verilogVal("i"));
+            pw.println("`define instruction_loop_count_immediate(i)         "+SET_OLC_FROM_IMMEDIATE.verilogVal("i"));
+
+            pw.println("`define instruction_path_immediate(i)              "+PATH_IMMEDIATE.verilogVal("i"));
+            pw.println("`define instruction_path_from_immediate(i)         "+PATH_IMMEDIATE.verilog("i"));
+            pw.println("`define instruction_path_from_data(i)            "+PATH_DATA.verilog("i"));
+
+            pw.println("`define instruction_is_tail(i)                   "+TAIL.verilog("i"));
+            pw.println("`define instruction_is_normal(i)                 "+MOVE.verilog("i"));
+            pw.println("`define instruction_is_setflags(i)               "+SET_FLAGS.verilog("i"));
+            pw.println("`define instruction_is_set(i)                    "+SET.verilog("i"));
+
+            pw.println("`define instruction_is_decr_loop(i)              "+SET_OLC_FROM_OLC_MINUS_ONE.verilog("i"));
+
+            pw.println("`define instruction_bit_tokenout(i)     (`instruction_is_normal(i) && "+TO.verilog("i")+")");
+            pw.println("`define instruction_bit_dataout(i)      (`instruction_is_normal(i) && "+DO.verilog("i")+")");
+            pw.println("`define instruction_bit_latch(i)        (`instruction_is_normal(i) && "+DC.verilog("i")+")");
+            pw.println("`define instruction_bit_datain(i)       (`instruction_is_normal(i) && "+DI.verilog("i")+")");
+            pw.println("`define instruction_bit_tokenin(i)      (`instruction_is_normal(i) && "+TI.verilog("i")+")");
+            pw.println("`define should_requeue(i)               (loop_counter > 0 && !("+OS.verilog("i")+"))");
+            pw.println("`define predicate_met(i)  ("+
+                       "("+
+                       "!`instruction_is_normal(i) || repeat_counter>0"+
+                       ") && ("+
+              " " + P_A.verilog("i")+" ? flag_a "+
+              ":" + P_B.verilog("i")+" ? flag_b "+
+              ":" + P_C.verilog("i")+" ? flag_c "+
+              ":" + P_NOT_A.verilog("i")+" ? !flag_a "+
+              ":" + P_NOT_B.verilog("i")+" ? !flag_b "+
+              ":" + P_NOT_C.verilog("i")+" ? !flag_c "+
+              ":" + P_OLC.verilog("i")+" ? (loop_counter>0) "+
+              ": 1"+
+                       ")"+
+              ")");
+            pw.println("`define new_flag(x)         ("+
+                       "( ((x >> 0) & 1) & !flag_c) |" +
+                       "( ((x >> 1) & 1) &  flag_c) |" +
+                       "( ((x >> 2) & 1) & !flag_b) |" +
+                       "( ((x >> 3) & 1) &  flag_b) |" +
+                       "( ((x >> 4) & 1) & !flag_a) |" +
+                       "( ((x >> 5) & 1) &  flag_a) | 0" +
+                       ")");
+            pw.println("`define new_flag_a(i)                   `new_flag("+SET_FLAGS_A.verilogVal("i")+")");
+            pw.println("`define new_flag_b(i)                   `new_flag("+SET_FLAGS_B.verilogVal("i")+")");
+            pw.println("`define done_executing(i)               (repeat_counter==0 || repeat_counter==1 || !`instruction_is_normal(i))");
+
+            pw.println("`define magic_standing_value            (1<<"+SET_ILC_FROM_IMMEDIATE.valmaskwidth+")");
+
+            super.dump(pw,fix);
+        }
+    }
+}
diff --git a/src/edu/berkeley/fleet/fpga/FpgaPath.java b/src/edu/berkeley/fleet/fpga/FpgaPath.java
new file mode 100644 (file)
index 0000000..d265803
--- /dev/null
@@ -0,0 +1,80 @@
+package edu.berkeley.fleet.fpga;
+import edu.berkeley.fleet.api.*;
+import edu.berkeley.fleet.ies44.*;
+import edu.berkeley.fleet.*;
+import java.lang.reflect.*;
+import edu.berkeley.sbp.chr.*;
+import edu.berkeley.sbp.misc.*;
+import edu.berkeley.sbp.meta.*;
+import edu.berkeley.sbp.util.*;
+import java.util.*;
+import java.io.*;
+import static edu.berkeley.fleet.ies44.InstructionEncoder.*;
+import static edu.berkeley.fleet.verilog.Verilog.*;
+
+
+public class FpgaPath extends Path {
+
+    private boolean[] path;
+    private FpgaDestination dest;
+    public final BitVector signal;
+
+    public Dock        getSource() { throw new RuntimeException("not implemented"); }
+    public Destination getDestination() { return dest; }
+    
+    private FpgaPath(boolean[] path, FpgaDestination dest, BitVector signal) {
+        this.signal = signal;
+        this.path = path;
+        this.dest = dest;
+    }
+
+    public long toLong() {
+        long ret = 0;
+        for(int i=0; i<path.length; i++) {
+            if (path[i]) ret |= (1 << i);
+        }
+        if (signal != null)
+            for(int i=0; i<signal.length(); i++) {
+                if (signal.get(i))
+                    ret |= (1L << (i+11));
+            }
+        return ret;
+    }
+
+    public String toString() {
+        StringBuffer ret = new StringBuffer();
+        for(int i=0; i<path.length; i++) {
+            if (i>0) ret.append('_');
+            ret.append(path[i] ? "1" : "0");
+        }
+        return ret.toString()+(signal==null?"":(":"+signal));
+    }
+
+    public FpgaPath prepend(boolean b) {
+        boolean[] newpath = new boolean[path.length+1];
+        System.arraycopy(path, 0, newpath, 1, path.length);
+        newpath[0] = b;
+        return new FpgaPath(newpath, dest, signal);
+    }
+    public FpgaPath append(boolean b, FpgaDestination newdest) {
+        boolean[] newpath = new boolean[path.length+1];
+        System.arraycopy(path, 0, newpath, 0, path.length);
+        newpath[newpath.length-1] = b;
+        return new FpgaPath(newpath, newdest, signal);
+    }
+
+    public int getBufferingAmount() {
+        throw new RuntimeException("not implemented");
+    }
+
+    public int getLatencyMetric() {
+        return 0;
+    }
+
+    public static FpgaPath emptyPath(FpgaDestination dest, BitVector signal) {
+        return new FpgaPath(new boolean[0], dest, signal);
+    }
+
+    public BitVector getSignal() { return null; }
+
+}
diff --git a/src/edu/berkeley/fleet/fpga/FpgaPump.java b/src/edu/berkeley/fleet/fpga/FpgaPump.java
deleted file mode 100644 (file)
index 0346b8d..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-package edu.berkeley.fleet.fpga;
-import edu.berkeley.fleet.doc.*;
-import edu.berkeley.fleet.api.*;
-import edu.berkeley.fleet.api.*;
-import edu.berkeley.fleet.api.Pump;
-import java.util.*;
-
-/** anything that has a destination address on the switch fabric */
-public class FpgaPump extends Pump {
-        
-    private final String name;
-    private final FpgaShip ship;
-    private  Destination[] ports;
-        
-    public Iterable<Destination> getDestinations() {
-        ArrayList<Destination> ret = new ArrayList<Destination>();
-        for(Destination d : ports) ret.add(d);
-        return ret;
-    }
-    private static int default_addr;
-    private static int default_instr_addr;
-
-    public int bits;
-    public int addr = (default_addr++);
-    public int instr_bits;
-    public int instr_addr = (default_instr_addr++);
-    private final PumpDescription bbd;
-    protected boolean special = false;
-    protected boolean ihorn = false;
-    protected boolean dhorn = false;
-    void service() { }
-    public boolean special() { return special; }
-    public boolean ihorn() { return ihorn; }
-    public boolean dhorn() { return dhorn; }
-    public boolean inbox;
-    public boolean isInbox() { return inbox; }
-    public boolean isOutbox() { return !inbox; }
-    public long resolveLiteral(String literal) {
-        return bbd.resolveLiteral(literal);
-    }
-    public FpgaPump(PumpDescription bbd, boolean inbox, FpgaShip ship, String name) {
-        this(bbd, inbox, ship, name, false, false, false);
-    }
-    public FpgaPump(PumpDescription bbd, boolean inbox, FpgaShip ship, String name, boolean special) {
-        this(bbd, inbox, ship, name, special, false, false);
-    }
-    public FpgaPump(PumpDescription bbd, boolean inbox, FpgaShip ship, String name, boolean special, boolean ihorn, boolean dhorn) {
-        this.bbd = bbd;
-        this.inbox = inbox;
-        this.special = special;
-        this.dhorn = dhorn;
-        this.ihorn = ihorn;
-        this.ship = ship;
-        this.name = name;
-        String[] ports = new String[] { "" };
-        this.ports = new Destination[ports.length];
-        for(int i=0; i<ports.length; i++)
-            this.ports[i] = new VirtualPort(ports[i]);
-        ship.addPump(name, this);
-    }
-
-    public void addDestination(String dest) {
-        Destination[] newports = new Destination[ports.length+1];
-        System.arraycopy(ports, 0, newports, 0, ports.length);
-        newports[newports.length-1] = new VirtualPort(dest);
-        ports = newports;
-    }
-
-    public class VirtualPort extends Destination {
-        public String name;
-        public VirtualPort(String name) { this.name = name; }
-        public String getDestinationName() { return name; }
-        public Ship getShip() { return FpgaPump.this.getShip(); }
-        public void addDataFromFabric(long data) { FpgaPump.this.addDataFromFabric(name, (int)data); }
-        public String toString() { return getShip()+"."+getName(); }
-        // fixme
-        public long addr = (default_addr++);
-    }
-        
-    /** adds one token to the port from the switch fabric side */
-    void addTokenFromFabric() { addDataFromFabric(0); }
-        
-    /** adds the included datum to the port from the switch fabric  side */
-    void addDataFromFabric(int datum)  { throw new RuntimeException("this should never happen!"); }
-    void addDataFromFabric(String name, int datum)  {
-        addDataFromFabric(datum);   
-    }
-
-    /** adds one token to the port from the ship side */
-    public void addTokenFromShip() { addDataFromShip(0); }
-        
-    /** adds the included datum to the port from the switch fabric side */
-    public void addDataFromShip(int datum) { throw new RuntimeException("this should never happen!"); }
-
-    public Ship getShip() { return ship; }
-
-    public Fleet getFleet() { return getShip().getFleet(); }
-
-    public String toString() { return ship+"."+name; }
-
-    public String getName() { return name; }
-
-    public int getInstructionFifoLength() { return 4; }
-
-}
index 5658fde..d5f9595 100644 (file)
@@ -1,60 +1,33 @@
 package edu.berkeley.fleet.fpga;
-import edu.berkeley.fleet.doc.*;
 import edu.berkeley.fleet.api.*;
 import java.util.*;
 import java.io.*;
+import edu.berkeley.fleet.two.*;
+import static edu.berkeley.fleet.ies44.InstructionEncoder.*;
+import static edu.berkeley.fleet.verilog.Verilog.*;
 
 /** a ship, which belongs to a fleet and which may have many ports */
-public class FpgaShip extends Ship {
+public class FpgaShip extends FleetTwoShip {
         
+    private Module module;
+    private Module.InstantiatedModule instance;
+    private LinkedHashMap<String,FpgaDock> ports = new LinkedHashMap<String,FpgaDock>();
+
     /** You should instantiate a bunch of Inboxes and Outboxes in your constructor */
-    public FpgaShip(Fpga fleet, String name, String type, ShipDescription sd) {
-        this.fleet = fleet; this.type = type;
-        for(PumpDescription sdbb : sd) {
-            FpgaPump sbb = new FpgaPump(sdbb, sdbb.isInbox(), this, sdbb.getName());
-            for(String port : sdbb) {
-                if (port.equals("")) continue;
-                sbb.addDestination(port);
-            }
-        }
-        if        (type.equals("Debug")) {
-            new FpgaPump(null, false, this, "out", true);
-            
-        } else if (type.equals("Execute")) {
-            new FpgaPump(null, false, this, "ihorn", true, true, false);
-            new FpgaPump(null, false, this, "dhorn", true, false, true);
-            
-        } else if (type.equals("Memory")) {
-            new FpgaPump(null, true,  this, "command", true);
-            new FpgaPump(null, false, this, "ihorn",   true, true, false);
-            new FpgaPump(null, false, this, "dhorn",   true, false, true);
+    public FpgaShip(Fpga fleet, ShipDescription sd) {
+        super(fleet, sd);
+        this.module = new Module(getType().toLowerCase());
+        this.instance = new Module.InstantiatedModule(fleet.getVerilogModule(), module);
+        for(DockDescription sdbb : sd) {
+            if (sdbb.isInputDock()) module.createInputPort(sdbb.getName(), WIDTH_WORD);
+            else                module.createOutputPort(sdbb.getName(), WIDTH_WORD, "");
+            ports.put(sdbb.getName(), new FpgaDock(this, sdbb));
         }
+        if (getType().toLowerCase().equals("debug"))
+            module.createOutputPort("debug_out", WIDTH_WORD, "");
     }
 
-    private Fpga fleet;
-    private String  type;
-
-    public long resolveLiteral(String s) {
-        if (s.equals("NEG")) return 0;
-        if (s.equals("INC")) return 1;
-        if (s.equals("DEC")) return 2;
-        if (s.equals("ABS")) return 3;
-        if (s.equals("ADD")) return 0;
-        if (s.equals("SUB")) return 1;
-        if (s.equals("MAX")) return 2;
-        if (s.equals("MIN")) return 3;
-        return super.resolveLiteral(s);
-    }
-
-    // this is dumb, the fpga fleet currently requires these in declaration-order; it shouldn't
-    private ArrayList<FpgaPump> portlist = new ArrayList<FpgaPump>();
-    private HashMap<String,FpgaPump> ports = new HashMap<String,FpgaPump>();
-
-    public Iterable<Pump> getPumps() { return (Iterable<Pump>)(Object)portlist; }
-    public String getType()                   { return type; }
-    public Fleet  getFleet()                  { return fleet; }
-    public Fpga  getSlipway()              { return fleet; }
-
-    void addPump(String name, FpgaPump port) { ports.put(name, port); portlist.add(port); }
+    public Iterator<Dock> iterator() { return (Iterator<Dock>)(Object)ports.values().iterator(); }
 
+    public Module.InstantiatedModule getVerilogModule() { return instance; }
 }
diff --git a/src/edu/berkeley/fleet/fpga/FunnelModule.java b/src/edu/berkeley/fleet/fpga/FunnelModule.java
new file mode 100644 (file)
index 0000000..4646cb7
--- /dev/null
@@ -0,0 +1,61 @@
+package edu.berkeley.fleet.fpga;
+import edu.berkeley.fleet.api.*;
+import edu.berkeley.fleet.ies44.*;
+import edu.berkeley.fleet.*;
+import java.lang.reflect.*;
+import edu.berkeley.sbp.chr.*;
+import edu.berkeley.sbp.misc.*;
+import edu.berkeley.sbp.meta.*;
+import edu.berkeley.sbp.util.*;
+import java.util.*;
+import java.io.*;
+import static edu.berkeley.fleet.ies44.InstructionEncoder.*;
+import static edu.berkeley.fleet.verilog.Verilog.*;
+
+
+public class FunnelModule extends Module {
+
+    public FunnelModule() {
+        super("funnel");
+        Module.SinkPort    outp = createOutputPort("out", WIDTH_PACKET, "");
+        Module.SourcePort  in1p = createInputPort("in1", WIDTH_PACKET);
+        Module.SourcePort  in2p = createInputPort("in2", WIDTH_PACKET);
+        new Event(new Object[] { in1p, outp },
+                  new Action[] { in1p, outp,
+                                 new AssignAction(outp, in1p) });
+        new Event(new Object[] { in2p, outp },
+                  new Action[] { in2p, outp,
+                                 new AssignAction(outp, in2p) });
+    }
+
+    public static class FunnelInstance extends Module.InstantiatedModule implements FabricElement {
+        private FabricElement in1 = null;
+        private FabricElement in2 = null;
+        public FabricElement out = null;
+        public Module.Port getOutputPort() { return getOutputPort("out"); }
+        public Module.Port getInputPort()  { throw new RuntimeException("funnel has multiple inputs"); }
+        public FunnelInstance(Module thisModule, Module.Port p1, Module.Port p2) {
+            super(thisModule, new FunnelModule());
+            p1.connect(this.getInputPort("in1"));
+            p2.connect(this.getInputPort("in2"));
+        }
+        public FunnelInstance(Module thisModule, FabricElement in1, FabricElement in2) {
+            super(thisModule, new FunnelModule());
+            this.in1 = in1;
+            this.in2 = in2;
+            in1.addOutput(this, this.getInputPort("in1"));
+            in2.addOutput(this, this.getInputPort("in2"));
+        }
+        public void addOutput(FabricElement out, Module.Port outPort) {
+            this.out = out;
+            getOutputPort("out").connect((Module.SinkPort)outPort);
+        }
+        public void addInput(FabricElement in, Module.Port source) {
+            throw new RuntimeException("cannot add inputs to a funnel once constructed");
+        }
+        public FpgaPath getPath(FabricElement dest, BitVector signal) {
+            return out.getPath(dest, signal);
+        }
+    }
+
+}
diff --git a/src/edu/berkeley/fleet/fpga/Generator.java b/src/edu/berkeley/fleet/fpga/Generator.java
deleted file mode 100644 (file)
index 9556247..0000000
+++ /dev/null
@@ -1,917 +0,0 @@
-// note: got rid of funnel "fairness" code
-package edu.berkeley.fleet.fpga;
-import edu.berkeley.fleet.doc.*;
-import edu.berkeley.fleet.api.*;
-import edu.berkeley.fleet.ies44.*;
-import edu.berkeley.fleet.*;
-import java.lang.reflect.*;
-import edu.berkeley.sbp.chr.*;
-import edu.berkeley.sbp.misc.*;
-import edu.berkeley.sbp.meta.*;
-import edu.berkeley.sbp.util.*;
-import java.util.*;
-import java.io.*;
-import static edu.berkeley.fleet.ies44.InstructionEncoder.*;
-
-public class Generator {
-
-    public static final int WIDTH_PACKET = WIDTH_WORD + WIDTH_ADDR;
-
-    public static class SimpleValue implements Value {
-        private final String s;
-        public SimpleValue(String s) { this.s = s; }
-        public SimpleValue(String s, int high, int low) { this.s = s+"["+high+":"+low+"]"; }
-        public Value getBits(int high, int low) { return new SimpleValue(s, high, low); }
-        public Assignable getAssignableBits(int high, int low) { return new SimpleValue(s, high, low); }
-        public String getVerilogName() { return s; }
-        public String toString() { return s; }
-    }
-
-    public static interface Action {
-        public String getVerilogAction();
-    }
-
-    public static interface Trigger {
-        public String getVerilogTrigger();
-    }
-
-    public static interface Assignable {
-        public String getVerilogName();
-        public Assignable getAssignableBits(int high, int low);
-    }
-
-    public static interface Value extends Assignable {
-        public String getVerilogName();
-        public Value getBits(int high, int low);
-    }
-
-    public static class ConditionalAction implements Action {
-        private String condition;
-        private Action action;
-        public ConditionalAction(String condition, Action action) {
-            this.condition = condition;
-            this.action = action;
-        }
-        public String toString() { return getVerilogAction(); }
-        public String getVerilogAction() { return "if ("+condition+") begin "+action.getVerilogAction()+" end"; }
-    }
-
-    public static class ConditionalTrigger implements Trigger {
-        private String condition;
-        private Trigger trigger;
-        public ConditionalTrigger(String condition, Trigger trigger) {
-            this.condition = condition;
-            this.trigger = trigger;
-            if (trigger instanceof Module.Port)
-                ((Module.Port)trigger).hasLatch = true;
-        }
-        public String getVerilogTrigger() {
-            return "&& (("+condition+") ? (1 " + trigger.getVerilogTrigger() + ") : 1)";
-        }
-    }
-
-    public static class SimpleAssignable implements Assignable {
-        private final String s;
-        public SimpleAssignable(String s) { this.s = s; }
-        public String getVerilogName() { return s; }
-        public Assignable getAssignableBits(int high, int low) { return new SimpleValue(s, high, low); }
-    }
-
-    public static class AssignAction implements Action {
-        private String left;
-        private String right;
-        public AssignAction(Assignable left, Value right) {
-            this.left = left.getVerilogName();
-            this.right = right.getVerilogName().toString();
-        }
-        public AssignAction(Assignable left, String right) {
-            this.left = left.getVerilogName();
-            this.right = right;
-        }
-        public String getVerilogAction() { return left + "<=" + right + ";"; }
-        public String toString() { return getVerilogAction(); }
-    }
-    
-    public static class SimpleAction implements Action {
-        private final String verilog;
-        public SimpleAction(String verilog) { this.verilog = verilog; }
-        public String getVerilogAction() { return verilog; }
-        public String toString() { return verilog; }
-    }
-
-    public static class Module {
-        private int id = 0;
-        private final String name;
-        public String getName() { return name; }
-        public Port getPort(String name) { return ports.get(name); }
-
-        private HashSet<InstantiatedModule> instantiatedModules = new HashSet<InstantiatedModule>();
-        private final ArrayList<Event> events = new ArrayList<Event>();
-
-        // FIXME: always-alphabetical convention?
-        private final HashMap<String,Port> ports = new HashMap<String,Port>();
-        private final ArrayList<String> portorder = new ArrayList<String>();
-        private final HashMap<String,StateWire> statewires = new HashMap<String,StateWire>();
-        private final HashMap<String,Latch> latches = new HashMap<String,Latch>();
-        
-        private StringBuffer crap = new StringBuffer();
-        private StringBuffer precrap = new StringBuffer();
-        public void addCrap(String s) { crap.append(s); crap.append('\n'); }
-        public void addPreCrap(String s) { precrap.append(s); precrap.append('\n'); }
-
-        public Module(String name) {
-            this.name = name;
-        }
-
-        public SourcePort createInputPort(String name, int width) {
-            if (ports.get(name)!=null) throw new RuntimeException();
-            return new SourcePort(name, width, true);
-        }
-        public SourcePort getInputPort(String name) {
-            SourcePort ret = (SourcePort)ports.get(name);
-            if (ret==null) throw new RuntimeException();
-            return ret;
-        }
-        public SinkPort createOutputPort(String name, int width, String resetBehavior) {
-            if (ports.get(name)!=null) throw new RuntimeException();
-            return new SinkPort(name, width, true, resetBehavior);
-        }
-        public SinkPort getOutputPort(String name) {
-            SinkPort ret = (SinkPort)ports.get(name);
-            if (ret==null) throw new RuntimeException();
-            return ret;
-        }
-
-        private class StateWire {
-            public final String name;
-            public final boolean initiallyFull;
-            public String getName() { return name; }
-            public Action isFull()  { return new SimpleAction(name+"==1"); }
-            public Action isEmpty() { return new SimpleAction(name+"==0"); }
-            public Action doFill()  { return new SimpleAction(name+"<=1;"); }
-            public Action doDrain() { return new SimpleAction(name+"<=0;"); }
-            public String doReset() { return name+"<="+(initiallyFull?"1":"0")+";"; }
-            public StateWire(String name) { this(name, false); }
-            public StateWire(String name, boolean initiallyFull) {
-                this.name = name;
-                this.initiallyFull = initiallyFull;
-                statewires.put(name, this);
-            }
-            public void dump(PrintWriter pw) {
-                pw.println("  reg "+name+";");
-                pw.println("  initial "+name+"="+(initiallyFull?"1":"0")+";");
-            }
-        }
-
-        public class Latch implements Assignable, Value {
-            public final String name;
-            public final int width;
-            public Latch(String name, int width) {
-                this.width = width;
-                this.name = name;
-                latches.put(name, this);
-            }
-            public String getVerilogName() { return name; }
-            public Value getBits(int high, int low) { return new SimpleValue(getVerilogName(), high, low); }
-            public Assignable getAssignableBits(int high, int low) { return new SimpleValue(getVerilogName(), high, low); }
-            public String doReset() { return name+"<=0;"; }
-            public void dump(PrintWriter pw) {
-                pw.println("  reg ["+(width-1)+":0] "+name+";");
-                pw.println("  initial "+name+"=0;");
-            }
-        }
-
-        private abstract class Port implements Action, Assignable, Trigger {
-            public final String name;
-            public String getName() { return name; }
-            public final int width;
-            public int getWidth() { return width; }
-            public boolean hasLatch = false;
-            public boolean external;
-            public Port(String name, int width, boolean external) {
-                this.width = width;
-                this.name = name;
-                this.external = external;
-                ports.put(name, this);
-                if (external)
-                    portorder.add(name);
-            }
-            public String getVerilogName() { return name; }
-            public String getAck() { return name+"_a"; }
-            public String getReq() { return name+"_r"; }
-            public abstract String getInterface();
-            public abstract String getSimpleInterface();
-            public abstract String getDeclaration();
-            public abstract String getAssignments();
-        }
-
-        private class InstantiatedModule {
-            public final Module module;
-            public final int id;
-            private final HashMap<String,Port> ports = new HashMap<String,Port>();
-            public String getName() { return module.getName()+"_"+id; }
-            public InstantiatedModule(Module module) {
-                this.module = module;
-                this.id = Module.this.id++;
-                instantiatedModules.add(this);
-            }
-            public void dump(PrintWriter pw) {
-                pw.println("  " + module.getName() + " " + getName() + "(clk, rst ");
-                for(String s : module.portorder)
-                    pw.println(", " + getPort(s).getSimpleInterface());
-                pw.println("   );");
-            }
-            public Port getPort(String name) {
-                return (module.ports.get(name) instanceof SinkPort) ? getOutputPort(name) : getInputPort(name);
-            }
-            public SinkPort getInputPort(String name) {
-                int width = module.getPort(name).getWidth();
-                SinkPort port = (SinkPort)ports.get(name);
-                if (port == null) {
-                    port = new SinkPort(getName()+"_"+name, width, false, "");
-                    ports.put(name, port);
-                }
-                return port;
-            }
-            public SourcePort getOutputPort(String name) {
-                int width = module.getPort(name).getWidth();
-                SourcePort port = (SourcePort)ports.get(name);
-                if (port == null) {
-                    port = new SourcePort(getName()+"_"+name, width, false);
-                    ports.put(name, port);
-                }
-                return port;
-            }
-        }
-
-        private class SourcePort extends Port implements Value {
-            private SinkPort driven = null;
-            public SourcePort(String name, int width, boolean external) { 
-                super(name, width, external); }
-            public Value getBits(int high, int low) { return new SimpleValue(getVerilogName(), high, low); }
-            public Assignable getAssignableBits(int high, int low) { return new SimpleValue(getVerilogName(), high, low); }
-            public String getVerilogTrigger() { return " && " + getReq() + " && !"+getAck(); }
-            public String getVerilogAction() { return getAck() + " <= 1;"; }
-            public String getInterface() { return getReq()+", "+getAck()+"_, "+name+""; }
-            public String getSimpleInterface() { return getReq()+", "+getAck()+", "+name+""; }
-            public String getDeclaration() {
-                StringBuffer sb = new StringBuffer();
-                if (external) {
-                    sb.append("input "  +                 name +"_r;\n");
-                    sb.append("output " +                 name +"_a_;\n");
-                    sb.append("input ["+(width-1)+":0]" + name +";\n");
-                } else {
-                    sb.append("wire "  +                 name +"_r;\n");
-                    sb.append("wire ["+(width-1)+":0]" + name +";\n");
-                }
-                if (!hasLatch) {
-                    sb.append("wire "    +                 name +"_a;\n");
-                } else {
-                    sb.append("reg "    +                 name +"_a;\n");
-                    sb.append("initial " +                name +"_a = 0;\n");
-                }
-                return sb.toString();
-            }
-            public String getAssignments() {
-                StringBuffer sb = new StringBuffer();
-                if (external)
-                    sb.append("assign " +                 name +"_a_ = " + name + "_a;\n");
-                if (driven != null) {
-                    sb.append("assign " + driven.name +"_r = " + name + "_r;\n");
-                    sb.append("assign " + name +"_a = " + driven.name + "_a;\n");
-                    sb.append("assign " + driven.name +"   = " + name + ";\n");
-                }
-                return sb.toString();
-            }
-            public void connect(SinkPort driven) {
-                this.driven = driven;
-            }
-        }
-        private class SinkPort extends Port {
-            public final String resetBehavior;
-            public Assignable getAssignableBits(int high, int low) { return new SimpleValue(getVerilogName(), high, low); }
-            public String getVerilogAction() { return getReq() + " <= 1;"; }
-            public String getVerilogTrigger() { return " && !" + getReq() + " && !"+getAck(); }
-            public SinkPort(String name, int width, boolean external, String resetBehavior) {
-                super(name, width, external); this.resetBehavior=resetBehavior; }
-            public String getResetBehavior() { return resetBehavior; }
-            public String getInterface() { return name+"_r_, "+name+"_a, "+name+"_"; }
-            public String getSimpleInterface() { return name+"_r, "+name+"_a, "+name; }
-            public String getDeclaration() {
-                StringBuffer sb = new StringBuffer();
-                if (external) {
-                    sb.append("output "  +                 name +"_r_;\n");
-                    sb.append("input "   +                 name +"_a;\n");
-                    sb.append("output ["+(width-1)+":0]" + name +"_;\n");
-                } else {
-                    sb.append("wire "   +                 name +"_a;\n");
-                }
-                if (!hasLatch) {
-                    sb.append("wire "    +                 name +"_r;\n");
-                    sb.append("wire   ["+(width-1)+":0]" + name +";\n");
-                } else {
-                    sb.append("reg "    +                  name +"_r;\n");
-                    sb.append("initial " +                 name +"_r = 0;\n");
-                    sb.append("reg    ["+(width-1)+":0]" + name +";\n");
-                    sb.append("initial " +                 name +" = 0;\n");
-                }
-                return sb.toString();
-            }
-            public String getAssignments() {
-                StringBuffer sb = new StringBuffer();
-                if (external) {
-                    sb.append("assign " +                  name +"_r_ = " + name + "_r;\n");
-                    sb.append("assign " +                  name +"_ = " + name + ";\n");
-                }
-                return sb.toString();
-            }
-        }
-
-        public void dump(PrintWriter pw, boolean fix) {
-            pw.println("`include \"macros.v\"");
-            pw.println("module "+name+"(clk, rst ");
-            for(String name : portorder) {
-                Port p = ports.get(name);
-                pw.println("    , " + p.getInterface());
-            }
-            pw.println("   );");
-            pw.println();
-            pw.println("    input clk;");
-            pw.println("    input rst;");
-            for(String name : ports.keySet()) {
-                Port p = ports.get(name);
-                pw.println("    " + p.getDeclaration());
-            }
-            for(StateWire sw : statewires.values())
-                sw.dump(pw);
-            for(Latch l : latches.values())
-                l.dump(pw);
-            for(String name : ports.keySet()) {
-                Port p = ports.get(name);
-                pw.println("    " + p.getAssignments());
-            }
-            for(InstantiatedModule m : instantiatedModules) {
-                m.dump(pw);
-            }
-            pw.println(precrap);
-            pw.println("always @(posedge clk) begin");
-            pw.println("  if (!rst) begin");
-            for(Latch l : latches.values())
-                pw.println(l.doReset());
-            for(StateWire sw : statewires.values())
-                pw.println(sw.doReset());
-            for(Port p : ports.values()) {
-                if (p instanceof SourcePort) {
-                    SourcePort ip = (SourcePort)p;
-                    if (ip.hasLatch)
-                        pw.println(ip.getAck()+" <=1;");
-                } else {
-                    SinkPort op = (SinkPort)p;
-                    if (op.hasLatch)
-                        pw.println(op.getReq()+" <=0;");
-                }
-            }
-            pw.println("  end else begin");
-            for(Port p : ports.values()) {
-                if (p instanceof SourcePort) {
-                    SourcePort ip = (SourcePort)p;
-                    if (ip.hasLatch)
-                        pw.println("if (!"+ip.getReq()+" && "+ip.getAck()+") "+ip.getAck()+"<=0;");
-                } else {
-                    SinkPort op = (SinkPort)p;
-                    if (op.hasLatch)
-                        pw.println("if ("+op.getReq()+" && "+op.getAck()+") begin "+
-                                   op.getReq()+"<=0; "+
-                                   op.getResetBehavior()+" end");
-                }
-            }
-            for(Event a : events) a.dump(pw, fix);
-            pw.println("    begin end");
-            pw.println("    end");
-            pw.println("  end");
-
-            pw.println(crap);
-            pw.println("endmodule");
-        }
-
-        private class Event {
-            private Object[]  triggers;
-            private Object[]  actions;
-            public Event(Object[] triggers, Object action) { this(triggers, new Object[] { action }); }
-            public Event(Object[] triggers, Object[] actions) {
-                Module.this.events.add(this);
-                this.triggers = triggers;
-                this.actions = actions;
-                for(int i=0; i<triggers.length; i++)
-                    if (triggers[i] instanceof Port)
-                        ((Port)triggers[i]).hasLatch = true;
-            }
-            public void dump(PrintWriter pw, boolean fix) {
-                pw.print("if (1");
-                for(Object o : triggers) {
-                    if (o instanceof Trigger) pw.print(((Trigger)o).getVerilogTrigger());
-                    else                      pw.print(" && " + o);
-                }
-                pw.println(") begin ");
-                for(Object a : actions) pw.println(((Action)a).getVerilogAction());
-                if (fix) pw.println("end /*else*/ ");
-                else     pw.println("end else ");
-            }
-        }
-    }
-
-    public static void main(String[] s) throws Exception {
-        String prefix = s[0];
-        PrintWriter pw;
-
-        pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(prefix+"/bitfields.v")));
-        pw.println("`define DATAWIDTH                "+WIDTH_WORD);
-        pw.println("`define CODEBAG_SIZE_BITS        "+WIDTH_CODEBAG_SIZE);
-        pw.println("`define PUMP_ADDRESS_BITS    "+WIDTH_ADDR);
-        pw.println("`define DESTINATION_ADDRESS_BITS "+WIDTH_ADDR);
-        /*
-        pw.println("`define COUNT_BITS               "+WIDTH_COUNT);
-        pw.println("`define COUNT_WIDTH              "+WIDTH_COUNT);
-        */
-        pw.println("`define PACKET_WIDTH             (`DATAWIDTH + `DESTINATION_ADDRESS_BITS)");
-        pw.println("`define INSTRUCTION_WIDTH        "+WIDTH_WORD);
-        pw.println("`define packet_data(p)              p[(`DESTINATION_ADDRESS_BITS+`DATAWIDTH-1):(`DESTINATION_ADDRESS_BITS)]");
-        pw.println("`define packet_dest(p)              p[(`DESTINATION_ADDRESS_BITS-1):0]");
-        pw.println("`define instruction_data(p)         p[(`DATAWIDTH-1):0]");
-        pw.println("`define instruction_dest(p)         "+PUMP_NAME.verilogVal("p"));
-        pw.flush();
-        pw.close();
-
-        mkfunnel("funnel", prefix);
-        mkhorn(    "horn", prefix, WIDTH_PACKET-1, WIDTH_ADDR-1, 0, 0);
-        mkhorn(   "ihorn", prefix, WIDTH_PACKET-1, WIDTH_ADDR-1, 0, 0);
-
-        Module fifostage = mkfifo("fifostage", 0, null,      prefix);
-        Module fifo4     = mkfifo("fifo4",     4, fifostage, prefix);
-        Module fifo8     = mkfifo("fifo8",     8, fifostage, prefix);
-        Module fifoship  = mkfifo("fifo",      4, fifo4,     prefix);
-        mkBox("outbox", false, prefix, fifo4, fifo8);
-        mkBox("inbox", true, prefix, fifo4, fifo8);
-
-        Module fabric = new Module("fabric");
-        fabric.createInputPort("horn_in",     WIDTH_PACKET);
-        fabric.createOutputPort("funnel_out", WIDTH_PACKET, "");
-        mkRoot("root", prefix, fabric);
-    }
-
-    private static Module mkRoot(String name, String prefix, Module fabricm) throws Exception {
-        Module root = new Module(name);
-        Module.SourcePort  in  = root.createInputPort("in", 8);
-        Module.SinkPort    out = root.createOutputPort("out", 8, "");
-        Module.InstantiatedModule fabric = root.new InstantiatedModule(fabricm);
-        Module.SinkPort    fabric_in   = fabric.getInputPort("horn_in");
-        Module.SourcePort  fabric_out  = fabric.getOutputPort("funnel_out");
-        Module.Latch       count       = root.new Latch("count", 8);
-        Module.Latch       count_out   = root.new Latch("count_out", 8);
-        root.new Event(new Object[] { in, fabric_in },
-                       new Object[] { new SimpleAction(fabric_in.getName()+" <= ("+fabric_in.getName()+" << 8) | in;"),
-                                      new SimpleAction("if (count >= 5) begin count <= 0; "+fabric_in.getName()+"_r <= 1; end else count <= count+1; "),
-                                      in
-                       });
-        root.new Event(new Object[] { out, fabric_out },
-                       new Object[] { new SimpleAction(out.getName()+" <= ("+fabric_out.getName()+">> (count_out*8));"),
-                                      new SimpleAction("if (count_out >= 5) begin count_out <= 0; "+fabric_out.getName()+"_a <= 1; end else count_out <= count_out+1; "),
-                                      out });
-        PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(prefix+"/"+name+".v")));
-        root.dump(pw, true);
-        pw.flush();
-        return root;
-    }
-
-    private static Module mkfunnel(String name, String prefix) throws Exception {
-        Module funnel = new Module(name);
-        Module.SinkPort    out = funnel.createOutputPort("out", WIDTH_PACKET, "");
-        Module.SourcePort  in1 = funnel.createInputPort("in1", WIDTH_PACKET);
-        Module.SourcePort  in2 = funnel.createInputPort("in2", WIDTH_PACKET);
-        funnel.new Event(new Object[] { in1, out },
-                         new Action[] { in1, out,
-                                        new AssignAction(out, in1) });
-        funnel.new Event(new Object[] { in2, out },
-                         new Action[] { in2, out,
-                                        new AssignAction(out, in2) });
-        PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(prefix+"/"+name+".v")));
-        funnel.dump(pw, true);
-        pw.flush();
-        return funnel;
-    }
-
-    private static Module mkfifo(String name, int len, Module instance, String prefix) throws Exception {
-        Module fifo = new Module(name);
-        Module.SourcePort  in  = fifo.createInputPort("in", WIDTH_PACKET);
-        Module.SinkPort    out = fifo.createOutputPort("out", WIDTH_PACKET, "");
-        Module.InstantiatedModule[] stages = new Module.InstantiatedModule[len];
-        if (len==0) {
-            fifo.new Event(new Object[] { in, out },
-                            new Action[] { in, out, new AssignAction(out, in) });
-        } else for(int i=0; i<=len; i++) {
-            if (i<len) stages[i] = fifo.new InstantiatedModule(instance);
-            Module.SourcePort driver = i==0 ? in : stages[i-1].getOutputPort("out");
-            Module.SinkPort   driven = i==len ? out : stages[i].getInputPort("in");
-            driver.connect(driven);
-        }
-        PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(prefix+"/"+name+".v")));
-        fifo.dump(pw, true);
-        /*
-          pw.println("`define FIFO_LENGTH " + len);
-          //pw.println("`define NAME " + name);
-          pw.println("`include \"macros.v\"");
-          pw.println("module "+name+"(clk, rst ");
-          pw.println("              , in_r, in_a_, in");
-          pw.println("              , out_r_, out_a, out_);");
-          BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("src/edu/berkeley/fleet/fpga/fifo.inc")));
-          String s;
-          while((s = br.readLine())!=null)
-          pw.println(s);
-        */
-        pw.flush();
-        return fifo;
-    }
-
-    public static void mkhorn(String name, 
-                              String prefix,
-                              int top,
-                              int top_of_addr_field,
-                              int bot_of_addr_field,
-                              int bot) throws Exception {
-        Module horn = new Module(name);
-        Module.SourcePort in   = horn.createInputPort("in",    WIDTH_PACKET);
-        Module.SinkPort   out0 = horn.createOutputPort("out0", WIDTH_PACKET, "");
-        Module.SinkPort   out1 = horn.createOutputPort("out1", WIDTH_PACKET, "");
-        String shifted_packet = "{ ";
-        if (top_of_addr_field+1 < top) shifted_packet += " in["+top+":"+(top_of_addr_field+1)+"], ";
-        shifted_packet += " (in["+(top_of_addr_field)+":"+bot_of_addr_field+"] >> 1) ";
-        if (bot_of_addr_field > 0) shifted_packet += ",  in["+(bot_of_addr_field-1)+":0]  ";
-        shifted_packet += " }";
-        // same behavior as FLEET -- wait for both
-        horn.new Event(new Object[] { in, out0, out1, "(in["+bot_of_addr_field+"]==0)" },
-                       new Action[] { in, out0, new AssignAction(out0, shifted_packet) });
-        horn.new Event(new Object[] { in, out0, out1, "(in["+bot_of_addr_field+"]==1)" },
-                       new Action[] { in, out1, new AssignAction(out1, shifted_packet) });
-        PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(prefix+"/"+name+".v")));
-        horn.dump(pw, true);
-        pw.flush();
-    }
-
-    private static Module mkBox(String name, boolean inbox, String prefix, Module fifo, Module ififo_m) throws Exception {
-        Module box = new Module(name);
-        Module.SourcePort instr         = box.createInputPort("instr",       WIDTH_WORD);
-        Module.SourcePort fabric_in     = box.createInputPort("fabric_in",   WIDTH_PACKET);
-        Module.SinkPort   fabric_out    = box.createOutputPort("fabric_out", WIDTH_PACKET, "");
-        Module.InstantiatedModule dfifo = box.new InstantiatedModule(fifo);
-        fabric_in.connect(dfifo.getInputPort("in"));
-        
-        Module.SourcePort dfifo_out = dfifo.getOutputPort("out");
-        Module.SourcePort   ship_out    = null;
-        if (!inbox) {
-            ship_out = box.createInputPort("ship",        WIDTH_WORD);
-            ship_out.hasLatch = true;
-        }
-
-        Module.SinkPort   ship_in     = null;
-        if (inbox) {
-            ship_in = box.createOutputPort("ship",        WIDTH_PACKET, "");
-            ship_in.hasLatch = true;
-        }
-
-        Module.Latch     ondeck         = box.new Latch("ondeck", WIDTH_WORD);
-        Module.Latch     repcount       = box.new Latch("repcount", WIDTH_COUNTER_LITERAL+1);
-        Module.Latch     repcount2      = box.new Latch("repcount2", WIDTH_COUNTER_LITERAL+1);
-        Module.Latch     repeat_counter = box.new Latch("repeat_counter", WIDTH_COUNTER_LITERAL+1);
-        Module.Latch     loop_counter   = box.new Latch("loop_counter", WIDTH_COUNTER_LITERAL);
-        Module.Latch     flag_a         = box.new Latch("flag_a", 1);
-        Module.Latch     flag_b         = box.new Latch("flag_b", 1);
-        Module.StateWire ondeckFull     = box.new StateWire("ondeck_full");
-        Module.StateWire newMayProceed  = box.new StateWire("newmayproceed", true);
-        Module.StateWire doRepeat       = box.new StateWire("dorepeat", false);
-        Module.StateWire isClogged      = box.new StateWire("clogged", false);
-        Module.StateWire isMassacreing  = box.new StateWire("massacreing", false);
-        
-        Module.SinkPort   token_out     = fabric_out;
-        Module.SourcePort token_in      = dfifo_out;
-        Module.SinkPort   data_out      = inbox ? ship_in   : fabric_out;
-        Module.SourcePort data_in       = inbox ? dfifo_out : ship_out;
-
-        Module.InstantiatedModule ififo = box.new InstantiatedModule(ififo_m);
-        Module.SinkPort   ififo_in      = ififo.getInputPort("in");
-        Module.SourcePort ififo_out     = ififo.getOutputPort("out");
-
-
-        // Massacre (when enqueued)
-        box.new Event(
-                      new Object[] { ififo_out, "!`instruction_is_massacre("+ififo_out.getName()+")", isMassacreing.isFull() },
-                      new Action[] { ififo_out }
-                      );
-        box.new Event(
-                      new Object[] { ififo_out, "`instruction_is_massacre("+ififo_out.getName()+")", isMassacreing.isFull() },
-                      new Action[] { ififo_out, isMassacreing.doDrain(), newMayProceed.doFill() }
-                      );
-        box.new Event(
-                      new Object[] { instr, ififo_in, "`instruction_is_massacre(instr)", isMassacreing.isEmpty() },
-                      new Action[] { instr, ififo_in,
-                                     new AssignAction(ififo_in, instr),
-                                     isMassacreing.doFill(),
-                                     ondeckFull.doDrain(),
-                                     newMayProceed.doDrain(),
-                                     new AssignAction(repeat_counter, "0"),
-                                     new AssignAction(repcount2, "0"),
-                                     new AssignAction(repcount, "0"),
-                                     new AssignAction(loop_counter, "0"),
-                      }
-                      );
-
-        // Clog (must be first)
-        box.new Event(
-                      new Object[] { ififo_out, newMayProceed.isFull(), "`instruction_is_clog("+ififo_out.getName()+")", isMassacreing.isEmpty() },
-                      new Action[] { ififo_out, isClogged.doFill(), newMayProceed.doDrain() }
-                      );
-
-        // UnClog
-        box.new Event(
-                      new Object[] { instr, isClogged.isFull(), "`instruction_is_unclog(instr)", isMassacreing.isEmpty() },
-                      new Action[] { instr, isClogged.doDrain(), newMayProceed.doFill()  }
-                      );
-
-        // First Kill
-        box.new Event(
-                      new Object[] { instr,
-                                     "`instruction_is_kill(instr)",
-                                     "!`instruction_is_unclog(instr)",
-                                     ondeckFull.isFull(),
-                                     isMassacreing.isEmpty()
-                      },
-                      new Action[] { instr,
-                                     ondeckFull.doDrain(),
-                                     new AssignAction(repeat_counter, "1"),
-                                     new AssignAction(repcount2, "1"),
-                                     newMayProceed.doFill()
-                      });
-
-
-        // Enqueue
-        box.new Event(
-                      new Object[] { instr,
-                                     ififo_in,
-                                     "!`instruction_is_kill(instr) && !`instruction_is_unclog(instr) && !`instruction_is_massacre(instr)",
-                                     isMassacreing.isEmpty()
-                      },
-                      new Action[] { instr, ififo_in, new AssignAction(ififo_in, instr)  }
-                      );
-
-        // New
-        box.new Event(
-                      new Object[] { ififo_out,
-                                     ondeckFull.isEmpty(),
-                                     newMayProceed.isFull(),
-                                     "!`instruction_is_clog("+ififo_out.getName()+")",
-                                     "!`instruction_is_kill(instr)",
-                                     isMassacreing.isEmpty() },
-                      new Action[] { ififo_out,
-                                     ondeckFull.doFill(),
-                                     newMayProceed.doDrain(),
-                                     new AssignAction(ondeck, ififo_out),
-                                     new ConditionalAction("`instruction_is_normal("+ififo_out.getName()+")",
-                                                           new AssignAction(repcount2, "(repeat_counter==0?1:repeat_counter)")),
-                                     new ConditionalAction("`instruction_is_normal("+ififo_out.getName()+")",
-                                                           new AssignAction(repeat_counter, "1")),
-                      }
-                      );
-
-        // RepeatExecute
-        box.new Event(
-                      new Object[] { doRepeat.isFull() },
-                      new Action[] { doRepeat.doDrain(),
-                                     ondeckFull.doFill(),
-                                     new AssignAction(repcount2, repcount)
-                      }
-                      );
-
-        box.addPreCrap("wire [(`DATAWIDTH-1):0] data_latch_output;");
-        box.addPreCrap("assign data_latch_output = " + (inbox ? data_out.getName() : "`packet_data("+data_out.getName()+")")+";");
-
-        Assignable data_latch    = new SimpleAssignable(inbox ? data_out.getName() : "`packet_data("+data_out.getName()+")");
-        String data_latch_input  = inbox ? "`packet_data("+data_in.getName()+")" : data_in.getName();
-
-        box.new Event(new Object[] { ondeckFull.isFull(),
-                                     isMassacreing.isEmpty(),
-                                     ififo_in,
-                                     "!`instruction_is_kill(instr)",
-                                     "`instruction_is_load_loop_to_data(ondeck)"
-            },
-            new Action[] { ondeckFull.doDrain(),
-                           newMayProceed.doFill(),
-                           new AssignAction(data_latch, loop_counter),
-                           new AssignAction(ififo_in, ondeck),
-                           new ConditionalAction("`should_requeue(ondeck)", ififo_in)
-            }
-            );
-        box.new Event(new Object[] { ondeckFull.isFull(),
-                                     isMassacreing.isEmpty(),
-                                     ififo_in,
-                                     "!`instruction_is_kill(instr)",
-                                     "`instruction_is_load_data_to_loop(ondeck)"
-            },
-            new Action[] { ondeckFull.doDrain(),
-                           newMayProceed.doFill(),
-                           new AssignAction(loop_counter, "data_latch_output"),
-                           new AssignAction(ififo_in, ondeck),
-                           new ConditionalAction("`should_requeue(ondeck)", ififo_in)
-            }
-            );
-        box.new Event(new Object[] { ondeckFull.isFull(),
-                                     isMassacreing.isEmpty(),
-                                     ififo_in,
-                                     "!`instruction_is_kill(instr)",
-                                     "`instruction_is_load_literal_to_loop(ondeck)"
-            },
-            new Action[] { ondeckFull.doDrain(),
-                           newMayProceed.doFill(),
-                           new AssignAction(loop_counter, "`instruction_loop_count_literal(ondeck)"),
-                           new AssignAction(ififo_in, ondeck),
-                           new ConditionalAction("`should_requeue(ondeck)", ififo_in)
-            }
-            );
-        box.new Event(new Object[] { ondeckFull.isFull(),
-                                     isMassacreing.isEmpty(),
-                                     ififo_in,
-                                     "!`instruction_is_kill(instr)",
-                                     "`instruction_is_load_data_to_repeat(ondeck)"
-            },
-            new Action[] { ondeckFull.doDrain(),
-                           newMayProceed.doFill(),
-                           new AssignAction(repeat_counter, "data_latch_output"),
-                           new ConditionalAction("`should_requeue(ondeck)", new AssignAction(ififo_in, ondeck)),
-                           new ConditionalAction("`should_requeue(ondeck)", ififo_in)
-            }
-            );
-        box.new Event(new Object[] { ondeckFull.isFull(),
-                                     isMassacreing.isEmpty(),
-                                     ififo_in,
-                                     "!`instruction_is_kill(instr)",
-                                     "`instruction_is_load_literal_to_repeat(ondeck)"
-            },
-            new Action[] { ondeckFull.doDrain(),
-                           newMayProceed.doFill(),
-                           new AssignAction(repeat_counter, "`instruction_repeat_count_literal(ondeck)"),
-                           new ConditionalAction("`should_requeue(ondeck)", new AssignAction(ififo_in, ondeck)),
-                           new ConditionalAction("`should_requeue(ondeck)", ififo_in)
-            }
-            );
-        box.new Event(new Object[] { ondeckFull.isFull(),
-                                     isMassacreing.isEmpty(),
-                                     ififo_in,
-                                     "!`instruction_is_kill(instr)",
-                                     "`instruction_is_load_standing_to_repeat(ondeck)"
-            },
-            new Action[] { ondeckFull.doDrain(),
-                           newMayProceed.doFill(),
-                           new AssignAction(repeat_counter, "`magic_standing_value"),
-                           new ConditionalAction("`should_requeue(ondeck)", new AssignAction(ififo_in, ondeck)),
-                           new ConditionalAction("`should_requeue(ondeck)", ififo_in)
-            }
-            );
-                           
-                                     
-        box.new Event(
-                      new Object[] { ondeckFull.isFull(),
-                                     isMassacreing.isEmpty(),
-                                     data_out,
-                                     token_out,
-                                     ififo_in,
-                                     "!`instruction_is_kill(instr)",
-                                     "(`instruction_is_normal(ondeck) || `instruction_is_literal_hi(ondeck) || `instruction_is_setflags(ondeck) || "+
-                                     " `instruction_is_literal_lo(ondeck) || `instruction_is_literal(ondeck))",
-                                     new ConditionalTrigger("`instruction_bit_datain(ondeck)", data_in),
-                                     new ConditionalTrigger("`instruction_bit_tokenin(ondeck)", token_in)
-                              },
-                              new Action[] { ondeckFull.doDrain(),
-                                             new ConditionalAction("`done_executing(ondeck)",                            newMayProceed.doFill()),
-                                             new ConditionalAction("`should_requeue(ondeck) && `done_executing(ondeck)", ififo_in),
-                                             new ConditionalAction("`should_requeue(ondeck) && `done_executing(ondeck)", new AssignAction(ififo_in, ondeck)),
-                                             new ConditionalAction("repcount2>1 || repcount2==`magic_standing_value", doRepeat.doFill()),
-                                             new ConditionalAction("repcount2!=`magic_standing_value", new AssignAction(repcount, "repcount2-1")),
-                                             new ConditionalAction("repcount2==`magic_standing_value", new AssignAction(repcount, "`magic_standing_value")),
-                                             new ConditionalAction("`predicate_met(ondeck) && `instruction_is_literal(ondeck)",
-                                                                   new AssignAction(data_latch, "`instruction_literal(ondeck)")),
-                                             new ConditionalAction("`predicate_met(ondeck) && `instruction_is_literal_hi(ondeck)",
-                                                                   new AssignAction(data_latch, "`instruction_literal_hi(ondeck,data_latch_output)")),
-                                             new ConditionalAction("`predicate_met(ondeck) && `instruction_is_literal_lo(ondeck)",
-                                                                   new AssignAction(data_latch, "`instruction_literal_lo(ondeck,data_latch_output)")),
-                                             new ConditionalAction("`predicate_met(ondeck) && `instruction_is_setflags(ondeck)",
-                                                                   new AssignAction(flag_a, "`new_flag_a(ondeck)")),
-                                             new ConditionalAction("`predicate_met(ondeck) && `instruction_is_setflags(ondeck)",
-                                                                   new AssignAction(flag_b, "`new_flag_b(ondeck)")),
-                                             new ConditionalAction("`predicate_met(ondeck) && `instruction_bit_datain(ondeck)",   data_in),
-                                             new ConditionalAction("`predicate_met(ondeck) && `instruction_bit_dataout(ondeck)",  data_out),
-                                             new ConditionalAction("`predicate_met(ondeck) && `instruction_bit_tokenin(ondeck)",  token_in),
-                                             new ConditionalAction("`predicate_met(ondeck) && `instruction_bit_tokenout(ondeck)", token_out),
-                                             new ConditionalAction("`predicate_met(ondeck) && `instruction_bit_latch(ondeck)",
-                                                                   new AssignAction(data_latch, data_latch_input)),
-                                             new ConditionalAction("`predicate_met(ondeck) && `instruction_path_from_data(ondeck)",
-                                                                   new AssignAction(new SimpleAssignable("`packet_dest("+token_out.getName()+")"),
-                                                                                    PUMP_NAME.verilogVal(data_latch_input))),
-                                             new ConditionalAction("`predicate_met(ondeck) && `instruction_path_from_literal(ondeck)",
-                                                                   new AssignAction(new SimpleAssignable("`packet_dest("+token_out.getName()+")"),
-                                                                                    "`instruction_path_literal(ondeck)")),
-                              }
-                      );
-        box.new Event(new Object[] { ondeckFull.isFull(),
-                                     isMassacreing.isEmpty(),
-                                     ififo_in,
-                                     "!`instruction_is_kill(instr)",
-                                     "`instruction_is_decr_loop(ondeck)"
-            },
-            new Action[] { new AssignAction(loop_counter, "loop_counter==0 ? 0 : (loop_counter-1)")
-            }
-            );
-
-        PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(prefix+"/"+name+".v")));
-
-        pw.println("`define instruction_is_load_loop_to_data(i)       "+TAKE_LOOP.verilog("i"));
-        pw.println("`define instruction_is_load_data_to_repeat(i)     "+REPEAT_FROM_DATA.verilog("i"));
-        pw.println("`define instruction_is_load_data_to_loop(i)       "+LOOP_FROM_DATA.verilog("i"));
-        pw.println("`define instruction_is_load_literal_to_repeat(i)  "+REPEAT_FROM_LITERAL.verilog("i"));
-        pw.println("`define instruction_is_load_literal_to_loop(i)    "+LOOP_FROM_LITERAL.verilog("i"));
-        pw.println("`define instruction_is_load_standing_to_repeat(i) "+REPEAT_FROM_STANDING.verilog("i"));
-        pw.println("`define instruction_repeat_count_literal(i)       "+REPEAT_FROM_LITERAL.verilogVal("i"));
-        pw.println("`define instruction_loop_count_literal(i)         "+LOOP_FROM_LITERAL.verilogVal("i"));
-
-        pw.println("`define instruction_path_literal(i)              "+PATH_LITERAL.verilogVal("i"));
-        pw.println("`define instruction_path_from_literal(i)         "+PATH_LITERAL.verilog("i"));
-        pw.println("`define instruction_path_from_data(i)            "+PATH_DATA.verilog("i"));
-
-        pw.println("`define instruction_is_literal_hi(i)             "+LITERAL_HI.verilog("i"));
-        pw.println("`define instruction_is_literal_lo(i)             "+LITERAL_LO.verilog("i"));
-        pw.println("`define instruction_is_literal(i)                "+LITERAL.verilog("i"));
-        pw.println("`define instruction_is_kill(i)                   "+KILL.verilog("i"));
-        pw.println("`define instruction_is_unclog(i)                 "+UNCLOG.verilog("i"));
-        pw.println("`define instruction_is_clog(i)                   "+CLOG.verilog("i"));
-        pw.println("`define instruction_is_massacre(i)               "+MASSACRE.verilog("i"));
-        pw.println("`define instruction_is_normal(i)                 "+MOVE.verilog("i"));
-        pw.println("`define instruction_is_setflags(i)               "+FLAGS.verilog("i"));
-
-        pw.println("`define instruction_is_decr_loop(i)              "+DL.verilog("i"));
-
-        pw.println("`define instruction_bit_tokenout(i)     (`instruction_is_normal(i) && "+TO.verilog("i")+")");
-        pw.println("`define instruction_bit_dataout(i)      (`instruction_is_normal(i) && "+DO.verilog("i")+")");
-        pw.println("`define instruction_bit_latch(i)        (`instruction_is_normal(i) && "+DC.verilog("i")+")");
-        pw.println("`define instruction_bit_datain(i)       (`instruction_is_normal(i) && "+DI.verilog("i")+")");
-        pw.println("`define instruction_bit_tokenin(i)      (`instruction_is_normal(i) && "+TI.verilog("i")+")");
-        pw.println("`define should_requeue(i)               (loop_counter > 0)");
-        pw.println("`define flag_a   flag_a");
-        pw.println("`define flag_b   flag_b");
-        pw.println("`define flag_z   (loop_counter==0 ? 1 : 0)");
-        pw.println("`define flag_s   (data_latch_output["+(WIDTH_WORD-1)+"])");
-        pw.println("`define predicate_met(i)  1");
-        /*
-        pw.println("`define predicate_met(i)  ("+
-                   " " + P_A.verilog("i")+" ? `flag_a "+
-                   ":" + P_B.verilog("i")+" ? `flag_b "+
-                   ":" + P_Z.verilog("i")+" ? `flag_z "+
-                   ": 1"+
-                   ")");
-        */
-        pw.println("`define new_flag(x)                     ("+
-                   "( ((x >> 0) & 1) & !`flag_z) |" +
-                   "( ((x >> 1) & 1) &  `flag_z) |" +
-                   "( ((x >> 2) & 1) & !`flag_s) |" +
-                   "( ((x >> 3) & 1) &  `flag_s) |" +
-                   "( ((x >> 4) & 1) & !`flag_b) |" +
-                   "( ((x >> 5) & 1) &  `flag_b) |" +
-                   "( ((x >> 6) & 1) & !`flag_a) |" +
-                   "( ((x >> 7) & 1) &  `flag_a) | 0" +
-                   ")");
-        pw.println("`define new_flag_a(i)                   `new_flag("+FLAGS_A.verilogVal("i")+")");
-        pw.println("`define new_flag_b(i)                   `new_flag("+FLAGS_B.verilogVal("i")+")");
-        pw.println("`define done_executing(i)               (repcount2==0 || repcount2==1)");
-
-        pw.println("`define magic_standing_value            (1<<"+WIDTH_COUNTER_LITERAL+")");
-
-        pw.println("`define instruction_literal_hi(i,d) { (i[17:0]),  (d[18:0]) }");
-        pw.println("`define instruction_literal_lo(i,d) { (d[36:19]), (i[18:0]) }");
-
-        pw.println("`define instruction_literal_sel(i) " + LITERAL_SEL.verilogVal("i"));
-        pw.println("`define instruction_literal(i) " +
-                   "("+
-                   "  `instruction_literal_sel(i) == 0 ? { (i[17:0]),  {19{1'b0}} } "+
-                   ": `instruction_literal_sel(i) == 1 ? { (i[17:0]),  {19{1'b1}} } "+
-                   ": `instruction_literal_sel(i) == 2 ? { {18{1'b0}}, (i[18:0]) } "+
-                   ":                                    { {18{1'b1}}, (i[18:0]) } "+
-                   ")"
-                   );
-
-
-        box.dump(pw, true);
-        pw.flush();
-        return box;
-    }
-
-}
-
-
-
-
diff --git a/src/edu/berkeley/fleet/fpga/HornModule.java b/src/edu/berkeley/fleet/fpga/HornModule.java
new file mode 100644 (file)
index 0000000..df380ed
--- /dev/null
@@ -0,0 +1,76 @@
+package edu.berkeley.fleet.fpga;
+import edu.berkeley.fleet.api.*;
+import edu.berkeley.fleet.ies44.*;
+import edu.berkeley.fleet.*;
+import java.lang.reflect.*;
+import edu.berkeley.sbp.chr.*;
+import edu.berkeley.sbp.misc.*;
+import edu.berkeley.sbp.meta.*;
+import edu.berkeley.sbp.util.*;
+import java.util.*;
+import java.io.*;
+import static edu.berkeley.fleet.ies44.InstructionEncoder.*;
+import static edu.berkeley.fleet.verilog.Verilog.*;
+
+
+public class HornModule extends Module {
+
+    public HornModule() {
+        this(PACKET_DEST.width-1,
+             PACKET_DEST.valmaskmax,
+             PACKET_DEST.valmaskmin,
+             0);
+    }
+    private HornModule(int top,
+                       int top_of_addr_field,
+                       int bot_of_addr_field,
+                       int bot) {
+        super("horn");
+        Module.SourcePort in   = createInputPort("in",    WIDTH_PACKET);
+        Module.SinkPort   out0 = createOutputPort("out0", WIDTH_PACKET, "");
+        Module.SinkPort   out1 = createOutputPort("out1", WIDTH_PACKET, "");
+        Module.Latch      out  = new Module.Latch("out",  WIDTH_PACKET);
+        out0.forceNoLatch = true;
+        out1.forceNoLatch = true;
+        addCrap("assign out0 = out;");
+        addCrap("assign out1 = out;");
+        String shifted_packet = "{ ";
+        if (top_of_addr_field < top) shifted_packet += " in["+top+":"+(top_of_addr_field+1)+"], ";
+        shifted_packet += " (in["+(top_of_addr_field)+":"+bot_of_addr_field+"] >> 1) ";
+        if (bot_of_addr_field > 0) shifted_packet += ",  in["+(bot_of_addr_field-1)+":0]  ";
+        shifted_packet += " }";
+        new Event(new Object[] { in, out0, out1, "(in["+bot_of_addr_field+"]==0)" },
+                  new Action[] { in, out0, new AssignAction(out, shifted_packet) });
+        new Event(new Object[] { in, out0, out1, "(in["+bot_of_addr_field+"]==1)" },
+                  new Action[] { in, out1, new AssignAction(out, shifted_packet) });
+    }
+
+    public static class HornInstance extends Module.InstantiatedModule implements FabricElement {
+        private FabricElement out0;
+        private FabricElement out1;
+        public void addInput(FabricElement in, Module.Port source) { source.connect(getInputPort("in")); }
+        public Module.Port getOutputPort() { throw new RuntimeException("horn has multiple outputs"); }
+        public Module.Port getInputPort()  { return getInputPort("in"); }
+        public HornInstance(Module thisModule, FabricElement out0, FabricElement out1) {
+            super(thisModule, new HornModule());
+            this.out0 = out0;
+            this.out1 = out1;
+            out0.addInput(this, getOutputPort("out0"));
+            out1.addInput(this, getOutputPort("out1"));
+        }
+        public void addOutput(FabricElement out, Module.Port outPort) { throw new RuntimeException(); }
+        public FpgaPath getPath(FabricElement dest, BitVector signal) {
+            FpgaPath path0 = out0==null ? null : out0.getPath(dest, signal);
+            FpgaPath path1 = out1==null ? null : out1.getPath(dest, signal);
+            if (path0 != null) path0 = path0.prepend(false);
+            if (path1 != null) path1 = path1.prepend(true);
+            if (path0==null) return path1;
+            if (path1==null) return path0;
+            if (path0.getLatencyMetric() < path1.getLatencyMetric()) return path0;
+            // FIXME: choke if latency metrics equal?
+            // FIXME: determinism of path-search?
+            return path1;
+        }
+    }
+
+}
index ba311f1..fb9049d 100644 (file)
@@ -5,7 +5,10 @@ import java.io.*;
 import java.net.*;
 import java.util.*;
 
+// FIXME: accept connections, but stall, during programming
 public class Server {
+    static boolean sign = false;
+
 
     static long jarFileTime = 0;
     static long bitFileTime = 0;
@@ -55,6 +58,7 @@ public class Server {
         while(true) {
             try {
                 Socket s = ss.accept();
+                System.out.println("accept!");
                 new Handler(s).start();
             } catch (Exception e) {
                 e.printStackTrace();
@@ -63,7 +67,6 @@ public class Server {
     }
 
     public static String pass_string = "password=security_is_for_wimps ";
-
     static class Handler extends Thread {
         private Socket socket;
         boolean closed = false;
@@ -75,7 +78,7 @@ public class Server {
                     this.sp = new RXTXPort("/dev/ttyS0");
                     sp.setInputBufferSize(0);
                     sp.setOutputBufferSize(0);
-                    sp.setSerialPortParams(9600, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
+                    sp.setSerialPortParams(38400, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
                     sp.setFlowControlMode(sp.FLOWCONTROL_RTSCTS_IN | sp.FLOWCONTROL_RTSCTS_OUT);
                     try {
                         _run();
@@ -87,7 +90,7 @@ public class Server {
         }
         public void _run() {
             try {
-                final InputStream is = socket.getInputStream();
+                final InputStream is = new BufferedInputStream(socket.getInputStream());
                 byte[] buf = new byte[1024];
                 StringBuffer sb = new StringBuffer();
                 while(true) {
@@ -98,31 +101,29 @@ public class Server {
                 }
                 System.err.println("login string: " + sb.toString());
                 if (!sb.toString().startsWith(pass_string)) return;
-
-                //try { Thread.sleep(500); } catch(Exception e) { }
-                final OutputStream os = socket.getOutputStream();
-
-                System.out.println("sending breaks");
-                for(int i=0; i<2; i++) {
-                    sp.sendBreak(100);
-                    Thread.sleep(100);
-                }
-                System.out.println("done sending breaks");
+                final OutputStream os = new BufferedOutputStream(socket.getOutputStream());
+                System.err.println("sending breaks...");
+                sp.sendBreak(100);
 
                 final OutputStream fos = sp.getOutputStream();
-                final InputStream fis = sp.getInputStream();
+                final InputStream fis = new BufferedInputStream(sp.getInputStream());
+                sign = false;
 
                 System.err.println("sending instructions...");
                 new Thread() {
                     public void run() {
                         try {
-                            byte[] buf = new byte[1024];
                             while(true) {
-                                int numread = is.read(buf, 0, buf.length);
-                                if (numread == -1) break;
-                                fos.write(buf, 0, numread);
-                                fos.flush();
+                                int r = is.read();
+                                if (r == -1) break;
+                                fos.write(r);
+                                if (!sign) {
+                                    fos.flush();
+                                    Thread.sleep(100);
+                                    sign = true;
+                                }
                             }
+                            fos.flush();
                         } catch (Exception e) { throw new RuntimeException(e);
                         } finally {
                             System.err.println("closing...");
@@ -132,22 +133,12 @@ public class Server {
                     }
                 }.start();
 
-                /*
-                int last = 0;
-                for(int j=0; j<3; j++)
-                    while(true) {
-                        int i = fis.read();
-                        if (i==-1) return;
-                        System.out.println("leader byte: 0x" + Integer.toString(i, 16) + " '"+((char)i)+"'");
-                        if (((char)last) == 'o' && ((char)i) == 'k') break;
-                        last = i;
-                    }
-                */
 
                 System.err.println("reading back...");
                 while(true) {
                     long result = 0;
                     int val = 0;
+                    boolean hit=false;
                     for(int i=0; i<6; i++) {
                         int k = 0;
                         while(!closed && fis.available()==0) {
@@ -157,14 +148,18 @@ public class Server {
                                 System.err.println("sleep");
                                 k = 0;
                             }
+                            if (k==10) os.flush();
                             Thread.sleep(10);
                         }
-                        if (closed) return;
+                        if (closed) { os.flush(); return; }
                         val = fis.read();
+                        if (!sign) {
+                            System.err.println("leader byte: 0x" + Integer.toString(val, 16) + " '"+((char)val)+"'");
+                            continue;
+                        }
                         if (val==-1) break;
                         System.err.println("byte: 0x"+Integer.toString(val & 0xff, 16));
                         os.write((byte)val);
-                        os.flush();
                         result |= ((long)val) << (i * 8);
                     }
                     if (val==-1) break;
@@ -173,6 +168,7 @@ public class Server {
                     System.err.print(Long.toString(result, 16));
                     System.err.println();
                 }
+                os.flush();
                 System.err.println("done.");
 
             } catch (Exception e) { throw new RuntimeException(e);
@@ -188,4 +184,4 @@ public class Server {
         }
     }
 
-}
\ No newline at end of file
+}
index 371f27c..548a633 100644 (file)
@@ -44,7 +44,8 @@ module main
 
   wire sio_ce;
   wire sio_ce_x4;
-  sasc_brg sasc_brg(clk, ser_rst, 10, 217, sio_ce, sio_ce_x4);
+  //sasc_brg sasc_brg(clk, ser_rst, 10, 217, sio_ce, sio_ce_x4);
+  sasc_brg sasc_brg(clk, ser_rst, 8, 65, sio_ce, sio_ce_x4);
   sasc_top sasc_top(clk, ser_rst,
                     fpga_0_RS232_Uart_1_sin_pin,
                     fpga_0_RS232_Uart_1_sout_pin,
@@ -79,8 +80,12 @@ module main
    wire [7:0] root_in_d;
    wire [7:0] root_out_d;
 
-
-   root my_root(clk, rst && !break, 
+   /*
+    * There is some very weird timing thing going on here; we need to
+    * hold reset low for more than one clock in order for it to propagate
+    * all the way to the docks.
+    */
+   root my_root(clk, rst && !break_o,
                 root_in_r,  root_in_a,  root_in_d,
                 root_out_r, root_out_a, root_out_d);
 /*
@@ -100,7 +105,7 @@ module main
      if (break) begin
        root_out_a_reg = 0;
        data_to_host_write_enable_reg <= 0;
-/*
+
      end else if (break_done) begin
        data_to_host_write_enable_reg <= 1;
        data_to_host_r <= 111;
@@ -109,7 +114,7 @@ module main
        data_to_host_write_enable_reg <= 1;
        data_to_host_r <= 107;
        send_k <= 0;
-*/
+
 
      end else if (root_out_r && !root_out_a_reg && !data_to_host_full) begin
        data_to_host_write_enable_reg <= 1;
index 2b62de5..9fa27f3 100644 (file)
@@ -1,4 +1,4 @@
 set -tmpdir ./tmp
 set -xsthdpdir ./xst
 run
--ifn main.prj -ifmt mixed -ofn main -ofmt NGC -p xc4vfx60 -top main -opt_mode Speed -opt_level 1 -iuc NO -lso main.lso -keep_hierarchy NO -rtlview Yes -glob_opt AllClockNets -read_cores YES -write_timing_constraints NO -cross_clock_analysis NO -hierarchy_separator / -bus_delimiter <> -case maintain -slice_utilization_ratio 100 -verilog2001 YES -fsm_extract Yes -fsm_encoding Auto -safe_implementation No -fsm_style lut -ram_extract Yes -ram_style Auto -rom_extract Yes -mux_style Auto -decoder_extract YES -priority_extract YES -shreg_extract YES -shift_extract YES -xor_collapse YES -rom_style Auto -mux_extract YES -resource_sharing YES -mult_style auto -iobuf YES -max_fanout 500 -bufg 1 -register_duplication YES -register_balancing No -slice_packing Yes -optimize_primitives Yes -tristate2logic Yes -use_clock_enable Yes -use_sync_set Yes -use_sync_reset Yes -iob auto -equivalent_register_removal YES -slice_utilization_ratio_maxmargin 5 
+-ifn main.prj -ifmt mixed -ofn main -ofmt NGC -p xc4vfx60 -top main -opt_mode Area -opt_level 1 -iuc NO -lso main.lso -keep_hierarchy NO -rtlview Yes -glob_opt AllClockNets -read_cores YES -write_timing_constraints NO -cross_clock_analysis NO -hierarchy_separator / -bus_delimiter <> -case maintain -slice_utilization_ratio 100 -verilog2001 YES -fsm_extract Yes -fsm_encoding Auto -safe_implementation No -fsm_style lut -ram_extract Yes -ram_style Auto -rom_extract Yes -mux_style Auto -decoder_extract YES -priority_extract YES -shreg_extract YES -shift_extract YES -xor_collapse YES -rom_style Auto -mux_extract YES -resource_sharing YES -mult_style auto -iobuf YES -max_fanout 500 -bufg 1 -register_duplication YES -register_balancing No -slice_packing Yes -optimize_primitives Yes -tristate2logic Yes -use_clock_enable Yes -use_sync_set Yes -use_sync_reset Yes -iob auto -equivalent_register_removal YES -slice_utilization_ratio_maxmargin 5 
diff --git a/src/edu/berkeley/fleet/gasp/Verilog.java b/src/edu/berkeley/fleet/gasp/Verilog.java
new file mode 100644 (file)
index 0000000..073d2b0
--- /dev/null
@@ -0,0 +1,463 @@
+package edu.berkeley.fleet.verilog;
+import edu.berkeley.fleet.api.*;
+import edu.berkeley.fleet.ies44.*;
+import edu.berkeley.fleet.*;
+import java.lang.reflect.*;
+import edu.berkeley.sbp.chr.*;
+import edu.berkeley.sbp.misc.*;
+import edu.berkeley.sbp.meta.*;
+import edu.berkeley.sbp.util.*;
+import java.util.*;
+import java.io.*;
+import static edu.berkeley.fleet.ies44.InstructionEncoder.*;
+
+public class Verilog {
+
+    public static class SimpleValue implements Value {
+        public final String s;
+        public SimpleValue(String s) { this.s = s; }
+        public SimpleValue(String s, int high, int low) { this.s = s+"["+high+":"+low+"]"; }
+        public Value getBits(int high, int low) { return new SimpleValue(s, high, low); }
+        public Assignable getAssignableBits(int high, int low) { return new SimpleValue(s, high, low); }
+        public String getVerilogName() { return s; }
+        public String toString() { return s; }
+    }
+
+    public static interface Action {
+        public String getVerilogAction();
+    }
+
+    public static interface Trigger {
+        public String getVerilogTrigger();
+    }
+
+    public static interface Assignable {
+        public String getVerilogName();
+        public Assignable getAssignableBits(int high, int low);
+    }
+
+    public static interface Value extends Assignable {
+        public String getVerilogName();
+        public Value getBits(int high, int low);
+    }
+
+    public static class ConditionalAction implements Action {
+        public String condition;
+        public Action action;
+        public ConditionalAction(String condition, Action action) {
+            this.condition = condition;
+            this.action = action;
+        }
+        public String toString() { return getVerilogAction(); }
+        public String getVerilogAction() { return "if ("+condition+") begin "+action.getVerilogAction()+" end"; }
+    }
+
+    public static class ConditionalTrigger implements Trigger {
+        public String condition;
+        public Trigger trigger;
+        public ConditionalTrigger(String condition, Trigger trigger) {
+            this.condition = condition;
+            this.trigger = trigger;
+            if (trigger instanceof Module.Port)
+                ((Module.Port)trigger).hasLatch = true;
+        }
+        public String getVerilogTrigger() {
+            return "&& (("+condition+") ? (1 " + trigger.getVerilogTrigger() + ") : 1)";
+        }
+    }
+
+    public static class SimpleAssignable implements Assignable {
+        public final String s;
+        public SimpleAssignable(String s) { this.s = s; }
+        public String getVerilogName() { return s; }
+        public Assignable getAssignableBits(int high, int low) { return new SimpleValue(s, high, low); }
+    }
+
+    public static class AssignAction implements Action {
+        public String left;
+        public String right;
+        public AssignAction(Assignable left, Value right) {
+            this.left = left.getVerilogName();
+            this.right = right.getVerilogName().toString();
+        }
+        public AssignAction(Assignable left, String right) {
+            this.left = left.getVerilogName();
+            this.right = right;
+        }
+        public String getVerilogAction() { return left + "<=" + right + ";"; }
+        public String toString() { return getVerilogAction(); }
+    }
+    
+    public static class SimpleAction implements Action {
+        public final String verilog;
+        public SimpleAction(String verilog) { this.verilog = verilog; }
+        public String getVerilogAction() { return verilog; }
+        public String toString() { return verilog; }
+    }
+
+    public static class Module {
+        public void dump(String prefix) throws IOException {
+            PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(prefix+"/bitfields.v")));
+            pw.println("`define DATAWIDTH                "+WIDTH_WORD);
+            pw.println("`define CODEBAG_SIZE_BITS        "+CBD_SIZE.valmaskwidth);
+            pw.println("`define INSTRUCTION_WIDTH        "+WIDTH_WORD);
+            pw.println("`define packet_token(p)          "+PACKET_TOKEN.verilogVal("p"));
+            pw.println("`define packet_data(p)           "+PACKET_DATA.verilogVal("p"));
+            pw.println("`define packet_dest(p)           "+PACKET_DEST.verilogVal("p"));
+            pw.println("`define instruction_dest(p)      "+DISPATCH_PATH.verilogVal("p"));
+            pw.flush();
+            pw.close();
+            pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(prefix+"/"+name+".v")));
+            dump(pw, true);
+            pw.flush();
+        }
+        public int id = 0;
+        public final String name;
+        public String getName() { return name; }
+        public Port getPort(String name) { return ports.get(name); }
+
+        public HashSet<InstantiatedModule> instantiatedModules = new HashSet<InstantiatedModule>();
+        public final ArrayList<Event> events = new ArrayList<Event>();
+
+        // FIXME: always-alphabetical convention?
+        public final HashMap<String,Port> ports = new HashMap<String,Port>();
+        public final ArrayList<String> portorder = new ArrayList<String>();
+        public final HashMap<String,StateWire> statewires = new HashMap<String,StateWire>();
+        public final HashMap<String,Latch> latches = new HashMap<String,Latch>();
+        
+        public StringBuffer crap = new StringBuffer();
+        public StringBuffer precrap = new StringBuffer();
+        public void addCrap(String s) { crap.append(s); crap.append('\n'); }
+        public void addPreCrap(String s) { precrap.append(s); precrap.append('\n'); }
+        public void addPreCrap0(String s) { precrap.append(s); }
+
+        public Module(String name) {
+            this.name = name;
+        }
+
+        public SourcePort createInputPort(String name, int width) {
+            if (ports.get(name)!=null) throw new RuntimeException();
+            return new SourcePort(name, width, true);
+        }
+        public SourcePort getInputPort(String name) {
+            SourcePort ret = (SourcePort)ports.get(name);
+            if (ret==null) throw new RuntimeException();
+            return ret;
+        }
+        public SinkPort createOutputPort(String name, int width, String resetBehavior) {
+            if (ports.get(name)!=null) throw new RuntimeException();
+            return new SinkPort(name, width, true, resetBehavior);
+        }
+        public SinkPort createWirePort(String name, int width) {
+            if (ports.get(name)!=null) throw new RuntimeException();
+            return new SinkPort(name, width, false, "");
+        }
+        public SourcePort createWireSourcePort(String name, int width) {
+            if (ports.get(name)!=null) throw new RuntimeException();
+            return new SourcePort(name, width, false);
+        }
+        public SinkPort getOutputPort(String name) {
+            SinkPort ret = (SinkPort)ports.get(name);
+            if (ret==null) throw new RuntimeException();
+            return ret;
+        }
+
+        public class StateWire {
+            public final String name;
+            public final boolean initiallyFull;
+            public String getName() { return name; }
+            public Action isFull()  { return new SimpleAction(name+"==1"); }
+            public Action isEmpty() { return new SimpleAction(name+"==0"); }
+            public Action doFill()  { return new SimpleAction(name+"<=1;"); }
+            public Action doDrain() { return new SimpleAction(name+"<=0;"); }
+            public String doReset() { return name+"<="+(initiallyFull?"1":"0")+";"; }
+            public StateWire(String name) { this(name, false); }
+            public StateWire(String name, boolean initiallyFull) {
+                this.name = name;
+                this.initiallyFull = initiallyFull;
+                statewires.put(name, this);
+            }
+            public void dump(PrintWriter pw) {
+                pw.println("  reg "+name+";");
+                pw.println("  initial "+name+"="+(initiallyFull?"1":"0")+";");
+            }
+        }
+
+        public class Latch implements Assignable, Value {
+            public final String name;
+            public final int width;
+            public final long initial;
+            public Latch(String name, int width) { this(name, width, 0); }
+            public Latch(String name, int width, long initial) {
+                this.width = width;
+                this.name = name;
+                this.initial = initial;
+                latches.put(name, this);
+            }
+            public String getVerilogName() { return name; }
+            public Value getBits(int high, int low) { return new SimpleValue(getVerilogName(), high, low); }
+            public Assignable getAssignableBits(int high, int low) { return new SimpleValue(getVerilogName(), high, low); }
+            public String doReset() { return name+"<="+initial+";"; }
+            public void dump(PrintWriter pw) {
+                pw.println("  reg ["+(width-1)+":0] "+name+";");
+                pw.println("  initial "+name+"="+initial+";");
+            }
+        }
+
+        public abstract class Port implements Action, Assignable, Trigger {
+            public abstract String doReset();
+            public final String name;
+            public String getName() { return name; }
+            public final int width;
+            public int getWidth() { return width; }
+            public boolean hasLatch = false;
+            public boolean external;
+            public Port(String name, int width, boolean external) {
+                this.width = width;
+                this.name = name;
+                this.external = external;
+                ports.put(name, this);
+                if (external)
+                    portorder.add(name);
+            }
+            public String getVerilogName() { return name; }
+            public String getAck() { return name+"_a"; }
+            public String getReq() { return name+"_r"; }
+            public abstract String getInterface();
+            public abstract String getSimpleInterface();
+            public abstract String getDeclaration();
+            public abstract String getAssignments();
+            public abstract void   connect(SinkPort driven);
+        }
+
+        public static class InstantiatedModule {
+            public final Module module;
+            public final Module thisModule;
+            public final int id;
+            public final HashMap<String,Port> ports = new HashMap<String,Port>();
+            public String getName() { return module.getName()+"_"+id; }
+            public InstantiatedModule(Module thisModule, Module module) {
+                this.thisModule = thisModule;
+                this.module = module;
+                this.id = thisModule.id++;
+                thisModule.instantiatedModules.add(this);
+            }
+            public void dump(PrintWriter pw) {
+                pw.println("  " + module.getName() + " " + getName() + "(clk, rst ");
+                for(String s : module.portorder)
+                    pw.println(", " + getPort(s).getSimpleInterface());
+                pw.println("   );");
+            }
+            public Port getPort(String name) {
+                return (module.ports.get(name) instanceof SinkPort) ? getOutputPort(name) : getInputPort(name);
+            }
+            public SinkPort getInputPort(String name) {
+                int width = module.getPort(name).getWidth();
+                SinkPort port = (SinkPort)ports.get(name);
+                if (port == null) {
+                    port = thisModule.new SinkPort(getName()+"_"+name, width, false, "");
+                    ports.put(name, port);
+                }
+                return port;
+            }
+            public SourcePort getOutputPort(String name) {
+                int width = module.getPort(name).getWidth();
+                SourcePort port = (SourcePort)ports.get(name);
+                if (port == null) {
+                    port = thisModule.new SourcePort(getName()+"_"+name, width, false);
+                    ports.put(name, port);
+                }
+                return port;
+            }
+        }
+
+        public class SourcePort extends Port implements Value {
+            public SinkPort driven = null;
+            public SourcePort(String name, int width, boolean external) { 
+                super(name, width, external); }
+            public Value getBits(int high, int low) { return new SimpleValue(getVerilogName(), high, low); }
+            public Assignable getAssignableBits(int high, int low) { return new SimpleValue(getVerilogName(), high, low); }
+            public String getVerilogTrigger() { return " && " + getReq() + " && !"+getAck(); }
+            public String getVerilogAction() { return getAck() + " <= 1;"; }
+            public String getInterface() { return getReq()+", "+getAck()+"_, "+name+""; }
+            public String getSimpleInterface() { return getReq()+", "+getAck()+", "+name+""; }
+            public String getDeclaration() {
+                StringBuffer sb = new StringBuffer();
+                if (external) {
+                    sb.append("input "  +                 name +"_r;\n");
+                    sb.append("output " +                 name +"_a_;\n");
+                    sb.append("input ["+(width-1)+":0]" + name +";\n");
+                } else {
+                    sb.append("wire "  +                 name +"_r;\n");
+                    sb.append("wire ["+(width-1)+":0]" + name +";\n");
+                }
+                if (!hasLatch) {
+                    sb.append("wire "    +                 name +"_a;\n");
+                } else {
+                    sb.append("reg "    +                 name +"_a;\n");
+                    sb.append("initial " +                name +"_a = 0;\n");
+                }
+                return sb.toString();
+            }
+            public String doReset() { return hasLatch ? name+"_a<=1;" : ""; }
+            public String getAssignments() {
+                StringBuffer sb = new StringBuffer();
+                if (external)
+                    sb.append("assign " +                 name +"_a_ = " + name + "_a;\n");
+                if (driven != null) {
+                    sb.append("assign " + driven.name +"_r = " + name + "_r;\n");
+                    sb.append("assign " + name +"_a = " + driven.name + "_a;\n");
+                    sb.append("assign " + driven.name +"   = " + name + ";\n");
+                }
+                return sb.toString();
+            }
+            public void connect(SinkPort driven) {
+                this.driven = driven;
+            }
+        }
+        public class SinkPort extends Port {
+            public boolean forceNoLatch = false;
+            public SinkPort driven = null;
+            public final String resetBehavior;
+            public Assignable getAssignableBits(int high, int low) { return new SimpleValue(getVerilogName(), high, low); }
+            public String getVerilogAction() { return getReq() + " <= 1;"; }
+            public String getVerilogTrigger() { return " && !" + getReq() + " && !"+getAck(); }
+            public SinkPort(String name, int width, boolean external, String resetBehavior) {
+                super(name, width, external); this.resetBehavior=resetBehavior; }
+            public String getResetBehavior() { return resetBehavior; }
+            public String getInterface() { return name+"_r_, "+name+"_a, "+name+"_"; }
+            public String getSimpleInterface() { return name+"_r, "+name+"_a, "+name; }
+            public String getDeclaration() {
+                StringBuffer sb = new StringBuffer();
+                if (external) {
+                    sb.append("output "  +                 name +"_r_;\n");
+                    sb.append("input "   +                 name +"_a;\n");
+                    sb.append("output ["+(width-1)+":0]" + name +"_;\n");
+                } else {
+                    sb.append("wire "   +                 name +"_a;\n");
+                }
+
+                if (forceNoLatch) {
+                    sb.append("reg "    +                  name +"_r;\n");
+                    sb.append("initial " +                 name +"_r = 0;\n");
+                    sb.append("wire   ["+(width-1)+":0]" + name +";\n");
+                } else if (!hasLatch) {
+                    sb.append("wire "    +                 name +"_r;\n");
+                    sb.append("wire   ["+(width-1)+":0]" + name +";\n");
+                } else {
+                    sb.append("reg "    +                  name +"_r;\n");
+                    sb.append("initial " +                 name +"_r = 0;\n");
+                    sb.append("reg    ["+(width-1)+":0]" + name +";\n");
+                    sb.append("initial " +                 name +" = 0;\n");
+                }
+                return sb.toString();
+            }
+            public String doReset() {
+                return forceNoLatch
+                    ? name+"_r<=0;"
+                    : hasLatch
+                    ? (name+"_r<=0; "+name+"<=0;")
+                    : "";
+            }
+            public String getAssignments() {
+                StringBuffer sb = new StringBuffer();
+                if (external) {
+                    sb.append("assign " +                  name +"_r_ = " + name + "_r;\n");
+                    sb.append("assign " +                  name +"_ = " + name + ";\n");
+                }
+                if (driven != null) {
+                    sb.append("assign " + driven.name +"_r = " + name + "_r;\n");
+                    sb.append("assign " + name +"_a = " + driven.name + "_a;\n");
+                    sb.append("assign " + driven.name +"   = " + name + ";\n");
+                }
+                return sb.toString();
+            }
+            public void connect(SinkPort driven) {
+                this.driven = driven;
+            }
+        }
+
+        public void dump(PrintWriter pw, boolean fix) {
+            pw.println("`include \"macros.v\"");
+            pw.println("module "+name+"(clk, rst ");
+            for(String name : portorder) {
+                Port p = ports.get(name);
+                pw.println("    , " + p.getInterface());
+            }
+            pw.println("   );");
+            pw.println();
+            pw.println("    input clk;");
+            pw.println("    input rst;");
+            for(String name : ports.keySet()) {
+                Port p = ports.get(name);
+                pw.println("    " + p.getDeclaration());
+            }
+            for(StateWire sw : statewires.values())
+                sw.dump(pw);
+            for(Latch l : latches.values())
+                l.dump(pw);
+            for(String name : ports.keySet()) {
+                Port p = ports.get(name);
+                pw.println("    " + p.getAssignments());
+            }
+            for(InstantiatedModule m : instantiatedModules) {
+                m.dump(pw);
+            }
+            pw.println(precrap);
+            pw.println("always @(posedge clk) begin");
+            pw.println("  if (!rst) begin");
+            for(Latch l : latches.values())
+                pw.println(l.doReset());
+            for(StateWire sw : statewires.values())
+                pw.println(sw.doReset());
+            for(Port p : ports.values())
+                pw.println(p.doReset());
+            pw.println("  end else begin");
+            for(Port p : ports.values()) {
+                if (p instanceof SourcePort) {
+                    SourcePort ip = (SourcePort)p;
+                    if (ip.hasLatch)
+                        pw.println("if (!"+ip.getReq()+" && "+ip.getAck()+") "+ip.getAck()+"<=0;");
+                } else {
+                    SinkPort op = (SinkPort)p;
+                    if (op.hasLatch)
+                        pw.println("if ("+op.getReq()+" && "+op.getAck()+") begin "+
+                                   op.getReq()+"<=0; "+
+                                   op.getResetBehavior()+" end");
+                }
+            }
+            for(Event a : events) a.dump(pw, fix);
+            pw.println("    begin end");
+            pw.println("    end");
+            pw.println("  end");
+
+            pw.println(crap);
+            pw.println("endmodule");
+        }
+
+        public class Event {
+            public Object[]  triggers;
+            public Object[]  actions;
+            public Event(Object[] triggers, Object action) { this(triggers, new Object[] { action }); }
+            public Event(Object[] triggers, Object[] actions) {
+                Module.this.events.add(this);
+                this.triggers = triggers;
+                this.actions = actions;
+                for(int i=0; i<triggers.length; i++)
+                    if (triggers[i] instanceof Port)
+                        ((Port)triggers[i]).hasLatch = true;
+            }
+            public void dump(PrintWriter pw, boolean fix) {
+                pw.print("if (1");
+                for(Object o : triggers) {
+                    if (o instanceof Trigger) pw.print(((Trigger)o).getVerilogTrigger());
+                    else                      pw.print(" && " + o);
+                }
+                pw.println(") begin ");
+                for(Object a : actions) pw.println(((Action)a).getVerilogAction());
+                if (fix) pw.println("end /*else*/ ");
+                else     pw.println("end else ");
+            }
+        }
+    }
+}
index c064487..9173e8c 100644 (file)
@@ -1,79 +1,98 @@
 package edu.berkeley.fleet.ies44;
+import java.io.*;
 import edu.berkeley.fleet.api.*;
-import edu.berkeley.fleet.*;
 import edu.berkeley.fleet.util.*;
-import java.io.*;
-import static edu.berkeley.fleet.util.BitManipulations.*;
+import edu.berkeley.fleet.api.Instruction.Set;
+import static edu.berkeley.fleet.api.Instruction.Set.*;
 import static edu.berkeley.fleet.api.Instruction.*;
-import static edu.berkeley.fleet.api.Instruction.Counter.*;
+import static edu.berkeley.fleet.api.Predicate.*;
 
-public abstract class InstructionEncoder {
 
-    public static final int WIDTH_WORD             = 37;
-    public static final int WIDTH_ADDR             = 11;
-    public static final int WIDTH_CODEBAG_SIZE     = 6;
-    public static final int WIDTH_COUNTER_LITERAL  = 6;
-
-    public static final Mask FLAGS                = new Mask("...............000000................");
-    public static final Mask FLAGS_A              = new Mask("...............000000vvvvvvvv........");
-    public static final Mask FLAGS_B              = new Mask("...............000000........vvvvvvvv");
-    public static final Mask REPEAT_FROM_DATA     = new Mask("...............000001........00......");
-    public static final Mask REPEAT_FROM_LITERAL  = new Mask("...............000001........10vvvvvv");
-    public static final Mask REPEAT_FROM_STANDING = new Mask("...............000001........11......");
-    public static final Mask LOOP_FROM_DATA       = new Mask("...............000010.........0......");
-    public static final Mask LOOP_FROM_LITERAL    = new Mask("...............000010.........1vvvvvv");
-    public static final Mask TAKE_LOOP            = new Mask("...............000011................");
-    public static final Mask KILL                 = new Mask("...............000100................");
-    public static final Mask MASSACRE             = new Mask("...............000101................");
-    public static final Mask CLOG                 = new Mask("...............000110................");
-    public static final Mask UNCLOG               = new Mask("...............000111................");
-
-    public static final Mask SK                  = new Mask("...........1.........................");
-    public static final Mask DL                  = new Mask("............1........................");
-    public static final Mask P                   = new Mask(".............vv......................");
-    public static final Mask P_A                 = new Mask(".............00......................");
-    public static final Mask P_B                 = new Mask(".............10......................");
-    public static final Mask P_Z                 = new Mask(".............01......................");
-    public static final Mask P_ALWAYS            = new Mask(".............11......................");
-    public static final Mask MOVE                = new Mask("...............001...................");
-    public static final Mask TI                  = new Mask("....................1................");
-    public static final Mask DI                  = new Mask(".....................1...............");
-    public static final Mask DC                  = new Mask("......................1..............");
-    public static final Mask DO                  = new Mask(".......................1.............");
-    public static final Mask TO                  = new Mask("........................1............");
-    public static final Mask PATH_LITERAL        = new Mask(".........................1vvvvvvvvvvv");
-    public static final Mask PATH_DATA           = new Mask(".........................01..........");
-    public static final Mask PATH_NOCHANGE       = new Mask(".........................00..........");
-
-    public static final Mask TOP_HALF_LITERAL    = new Mask("vvvvvvvvvvvvvvvvvv...................");
-    public static final Mask BOT_HALF_LITERAL    = new Mask("..................vvvvvvvvvvvvvvvvvvv");
-    public static final Mask TOP_HALF_ONE        = new Mask("111111111111111111...................");
-    public static final Mask BOT_HALF_ONE        = new Mask("..................1111111111111111111");
-    public static final Mask LITERAL_LO          = new Mask("...............010vvvvvvvvvvvvvvvvvvv");
-    public static final Mask LITERAL_HI          = new Mask("...............011vvvvvvvvvvvvvvvvvvv");
-    public static final Mask LITERAL             = new Mask("...............1..vvvvvvvvvvvvvvvvvvv");
-    public static final Mask LITERAL_SEL         = new Mask("................vv...................");
-    public static final Mask LITERAL_LOW_ZERO    = new Mask("...............100...................");
-    public static final Mask LITERAL_LOW_ONE     = new Mask("...............101...................");
-    public static final Mask LITERAL_HIGH_ZERO   = new Mask("...............110...................");
-    public static final Mask LITERAL_HIGH_ONE    = new Mask("...............111...................");
-    public static final Mask PUMP_NAME           = new Mask("vvvvvvvvvvv..........................");
+public abstract class InstructionEncoder {
 
+    public static final Mask PACKET_TOKEN               = new Mask("v.................................................");
+    public static final Mask PACKET_DATA                = new Mask(".vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv............");
+    public static final Mask PACKET_SIGNAL              = new Mask("......................................v...........");
+    public static final Mask PACKET_DEST                = new Mask(".......................................vvvvvvvvvvv");
+
+    public static final Mask CBD_SIZE                   = new Mask("...............................vvvvvv");
+    public static final Mask CBD_OFFSET                 = new Mask("vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv......");
+
+    public static final int  WIDTH_WORD                 = PACKET_DATA.valmaskwidth;
+    public static final int  WIDTH_PACKET               = PACKET_TOKEN.width;
+
+    public static final Mask DISPATCH_PATH              = new Mask("vvvvvvvvvvv..........................");
+    public static final Mask I                          = new Mask("...........1.........................");
+    public static final Mask OS                         = new Mask("............1........................");
+    public static final Mask P                          = new Mask(".............vvv.....................");
+    public static final Mask P_NOT_A                    = new Mask(".............000.....................");
+    public static final Mask P_A                        = new Mask(".............001.....................");
+    public static final Mask P_NOT_B                    = new Mask(".............010.....................");
+    public static final Mask P_B                        = new Mask(".............011.....................");
+    public static final Mask P_NOT_C                    = new Mask(".............100.....................");
+    public static final Mask P_C                        = new Mask(".............101.....................");
+    public static final Mask P_OLC                      = new Mask(".............110.....................");
+    public static final Mask P_ALWAYS                   = new Mask(".............111.....................");
+
+    public static final Mask SHIFT                      = new Mask("................00vvvvvvvvvvvvvvvvvvv");
+
+    public static final Mask TAIL                       = new Mask("................11...................");
+
+    public static final Mask MOVE                       = new Mask("................01...................");
+    public static final Mask TI                         = new Mask("..................1..................");
+    public static final Mask DI                         = new Mask("...................1.................");
+    public static final Mask DC                         = new Mask("....................1................");
+    public static final Mask DO                         = new Mask(".....................1...............");
+    public static final Mask TO                         = new Mask("......................1..............");
+    public static final Mask PATH_IMMEDIATE             = new Mask(".......................1vvvvvvvvvvvvv");
+    public static final Mask PATH_DATA                  = new Mask(".......................01............");
+    public static final Mask PATH_NOCHANGE              = new Mask(".......................00............");
+
+    public static final Mask SET                        = new Mask("................10...................");
+
+    public static final Mask SET_OLC_FROM_IMMEDIATE     = new Mask("................1010000100.....vvvvvv");
+    public static final Mask SET_OLC_FROM_DATA_LATCH    = new Mask("................1010000010...........");
+    public static final Mask SET_OLC_FROM_OLC_MINUS_ONE = new Mask("................1010000001...........");
+
+    public static final Mask SET_ILC_FROM_IMMEDIATE     = new Mask("................1001000100.....vvvvvv");
+    public static final Mask SET_ILC_FROM_INFINITY      = new Mask("................1001000010...........");
+    public static final Mask SET_ILC_FROM_DATA_LATCH    = new Mask("................1001000001...........");
+
+    public static final Mask SET_IMMEDIATE                = new Mask("................1000100.vvvvvvvvvvvvv");
+    public static final Mask SET_IMMEDIATE_EXTEND         = new Mask("................1000100v.............");
+
+    public static final Mask SET_FLAGS                  = new Mask("................1000010..............");
+    public static final Mask SET_FLAGS_A                = new Mask("................1000010..vvvvvv......");
+    public static final Mask SET_FLAGS_B                = new Mask("................1000010........vvvvvv");
+    public static final Mask SET_FLAGS_VALUE_A          = new Mask("1.....");
+    public static final Mask SET_FLAGS_VALUE_NOT_A      = new Mask(".1....");
+    public static final Mask SET_FLAGS_VALUE_B          = new Mask("..1...");
+    public static final Mask SET_FLAGS_VALUE_NOT_B      = new Mask("...1..");
+    public static final Mask SET_FLAGS_VALUE_C          = new Mask("....1.");
+    public static final Mask SET_FLAGS_VALUE_NOT_C      = new Mask(".....1");
+
+    public static final Mask SET_TAPL_FROM_IMMEDIATE    = new Mask("................1000001.vvvvvvvvvvvvv");
+
+
+        public static final long DataLatch_WIDTH = SET_IMMEDIATE.valmaskmax-SET_IMMEDIATE.valmaskmin+1;  // FIXME: this is an abstraction breakage
+        private static final long mask  = ~(-1L << DataLatch_WIDTH);
+        public static boolean isSmallEnoughToFit(long immediate) {
+            if ((immediate & ~mask) == 0)   return true;
+            if ((immediate |  mask) == -1L) return true;
+            return false;
+        }
 
     /** get the bits describing this box's location on the DESTINATION HORN */
-    protected abstract long getDestAddr(Destination box);
+    protected abstract long getDestAddr(Path box);
 
-    /** get the bits describing this box's location on the INSTRUCTION HORN */
-    protected abstract long getBoxInstAddr(Pump box);
+    /** decode a path, given the starting point and the bits that comprise it */
+    protected abstract Path getPathByAddr(Dock source, long dest);
 
-    /** given an INSTRUCTION HORN address, retrieve the corresponding Pump object */
-    protected abstract Pump getBoxByInstAddr(long dest);
-    
-    /** given a DESTINATION HORN address, retrieve the corresponding Pump object */
-    protected abstract Destination getDestByAddr(long dest);
+    /** FIXME: this is a hack for now */
+    protected abstract Dock getUniversalSource();
 
     /** read a machine-formatted instruction from a file (into a Java object) */
-    public Instruction readInstruction(DataInputStream is) throws IOException {
+    public Instruction readInstruction(Dock dispatchFrom, DataInputStream is) throws IOException {
         long inst = 0;
         try {
             inst = (inst << 8) | (is.readByte() & 0xff);
@@ -82,176 +101,202 @@ public abstract class InstructionEncoder {
             inst = (inst << 8) | (is.readByte() & 0xff);
             inst = (inst << 8) | (is.readByte() & 0xff);
             inst = (inst << 8) | (is.readByte() & 0xff);
-            return readInstruction(inst);
+            return readInstruction(dispatchFrom, inst);
         } catch (EOFException eof) {
             return null;
         }
     }
 
-    public Instruction readInstruction(long inst) {
-        Pump name           = getBoxByInstAddr(PUMP_NAME.getval(inst));
-
-        if (UNCLOG.get(inst))   return new Instruction.UnClog(name);
-        if (CLOG.get(inst))     return new Instruction.Clog(name);
-        if (MASSACRE.get(inst)) return new Instruction.Massacre(name);
-        if (KILL.get(inst))     return new Instruction.Kill(name, (int)(KILL.getval(inst)+1));
-
-        int predicate = 0;
-        if (P_ALWAYS.get(inst)) predicate = Instruction.PredicatedInstruction.P_ALWAYS;
-        if (P_A.get(inst)) predicate = Instruction.PredicatedInstruction.P_IF_A;
-        if (P_B.get(inst)) predicate = Instruction.PredicatedInstruction.P_IF_B;
-        if (P_Z.get(inst)) predicate = Instruction.PredicatedInstruction.P_IF_Z;
+    public Instruction readInstruction(Dock dispatchFrom, long inst) {
+        Dock dock = getPathByAddr(getUniversalSource(), DISPATCH_PATH.getval(inst)).getDestination().getDock();
+
+        if (TAIL.get(inst))   return new Tail(dock);
+
+        Predicate predicate = Default;
+        if (P_ALWAYS.get(inst)) predicate = IgnoreOLC;
+        if (P_OLC.get(inst))    predicate = Default;
+        if (P_A.get(inst))      predicate = FlagA;
+        if (P_B.get(inst))      predicate = FlagB;
+        if (P_C.get(inst))      predicate = FlagC;
+        if (P_NOT_A.get(inst))  predicate = NotFlagA;
+        if (P_NOT_B.get(inst))  predicate = NotFlagB;
+        if (P_NOT_C.get(inst))  predicate = NotFlagC;
+
+        boolean looping = !OS.get(inst);
+        if (SHIFT.get(inst))                return new Shift(dock, looping, predicate, new BitVector(dock.getShip().getFleet().getWordWidth()).set(SHIFT.getval(inst)));
+        if (SET_IMMEDIATE.get(inst)) {
+            boolean extend = SET_IMMEDIATE_EXTEND.getval(inst) != 0;
+            long immediate = SET_IMMEDIATE.getval(inst);
+            if (extend) immediate |= (-1L << DataLatch_WIDTH);
+            return new Set(dock, looping, predicate, SetDest.DataLatch, (immediate));
+        }
 
-        boolean dl = false;
-        if (DL.get(inst))                   dl = true;
-
-        if (LOOP_FROM_LITERAL.get(inst))    return new Counter(name, dl, predicate, (int)LOOP_FROM_LITERAL.getval(inst),   LOOP_COUNTER);
-        if (REPEAT_FROM_LITERAL.get(inst))  return new Counter(name, dl, predicate, (int)REPEAT_FROM_LITERAL.getval(inst), REPEAT_COUNTER);
-        if (LOOP_FROM_DATA.get(inst))       return new Counter(name, dl, predicate, DATA_LATCH, LOOP_COUNTER);
-        if (REPEAT_FROM_DATA.get(inst))     return new Counter(name, dl, predicate, DATA_LATCH, REPEAT_COUNTER);
-        if (REPEAT_FROM_STANDING.get(inst)) return new Counter(name, dl, predicate, STANDING, REPEAT_COUNTER);
-        if (TAKE_LOOP.get(inst))            return new Counter(name, dl, predicate, LOOP_COUNTER, DATA_LATCH);
-
-        if (LITERAL_LO.get(inst))  return new Instruction.HalfLiteral(name, dl, predicate, LITERAL_LO.getval(inst), 0, false);
-        if (LITERAL_HI.get(inst))  return new Instruction.HalfLiteral(name, dl, predicate, LITERAL_HI.getval(inst), 0, true);
-        if (LITERAL.get(inst)) {
-            long literal = LITERAL.getval(inst);
-            if      (LITERAL_LOW_ZERO.get(inst))  literal = TOP_HALF_LITERAL.setval(0, literal);
-            else if (LITERAL_LOW_ONE.get(inst))   literal = BOT_HALF_ONE.set(TOP_HALF_LITERAL.setval(0, literal));
-            else if (LITERAL_HIGH_ZERO.get(inst)) literal = BOT_HALF_LITERAL.setval(0, literal);
-            else if (LITERAL_HIGH_ONE.get(inst))  literal = TOP_HALF_ONE.set(BOT_HALF_LITERAL.setval(0, literal));
-            return new Instruction.Literal(name, dl, predicate, Mask.signExtend(literal, WIDTH_WORD));
-        }  
-        if (FLAGS.get(inst))       return new Instruction.SetFlags(name, dl, predicate, (int)FLAGS_A.getval(inst), (int)FLAGS_B.getval(inst));
-
-        if (!MOVE.get(inst)) throw new RuntimeException("unknown instruction: 0x" + Long.toString(inst, 16));
-
-        Destination dest    = getDestByAddr(PATH_LITERAL.getval(inst));
-        boolean tokenIn     = TI.get(inst);
-        boolean dataIn      = DI.get(inst);
-        boolean latch       = DC.get(inst);
-        boolean dataOut     = DO.get(inst);
-        boolean tokenOut    = TO.get(inst);
-        boolean dataOutDest = PATH_DATA.get(inst);
-        return new Instruction.Move(name,
-                                    dl,
-                                    predicate,
-                                    dest,
-                                    tokenIn,
-                                    dataIn,
-                                    latch,
-                                    dataOutDest,
-                                    dataOut,
-                                    tokenOut,
-                                    false,
-                                    false);
+        if (SET_OLC_FROM_OLC_MINUS_ONE.get(inst))
+            return new Set(dock, looping, predicate, SetDest.OuterLoopCounter, SetSource.Decrement);
+        if (SET_OLC_FROM_IMMEDIATE.get(inst))
+            return new Set(dock, looping, predicate, SetDest.OuterLoopCounter, (SET_OLC_FROM_IMMEDIATE.getval(inst)));
+        if (SET_ILC_FROM_IMMEDIATE.get(inst))
+            return new Set(dock, looping, predicate, SetDest.InnerLoopCounter, (SET_ILC_FROM_IMMEDIATE.getval(inst)));
+        if (SET_OLC_FROM_DATA_LATCH.get(inst))
+            return new Set(dock, looping, predicate, SetDest.OuterLoopCounter, SetSource.DataLatch);
+        if (SET_ILC_FROM_DATA_LATCH.get(inst))
+            return new Set(dock, looping, predicate, SetDest.InnerLoopCounter, SetSource.DataLatch);
+        if (SET_ILC_FROM_INFINITY.get(inst))
+            return new Set(dock, looping, predicate, SetDest.InnerLoopCounter, SetSource.Infinity);
+        if (SET_FLAGS.get(inst)) {
+            long flag_a = SET_FLAGS_A.getval(inst);
+            long flag_b = SET_FLAGS_B.getval(inst);
+            FlagFunction ap = FlagFunction.ZERO;
+            FlagFunction bp = FlagFunction.ZERO;
+            if (SET_FLAGS_VALUE_A    .get(flag_a)) ap = ap.add(FlagA    );
+            if (SET_FLAGS_VALUE_NOT_A.get(flag_a)) ap = ap.add(NotFlagA );
+            if (SET_FLAGS_VALUE_B    .get(flag_a)) ap = ap.add(FlagB    );
+            if (SET_FLAGS_VALUE_NOT_B.get(flag_a)) ap = ap.add(NotFlagB );
+            if (SET_FLAGS_VALUE_C    .get(flag_a)) ap = ap.add(FlagC    );
+            if (SET_FLAGS_VALUE_NOT_C.get(flag_a)) ap = ap.add(NotFlagC );
+            if (SET_FLAGS_VALUE_A    .get(flag_b)) bp = bp.add(FlagA    );
+            if (SET_FLAGS_VALUE_NOT_A.get(flag_b)) bp = bp.add(NotFlagA );
+            if (SET_FLAGS_VALUE_B    .get(flag_b)) bp = bp.add(FlagB    );
+            if (SET_FLAGS_VALUE_NOT_B.get(flag_b)) bp = bp.add(NotFlagB );
+            if (SET_FLAGS_VALUE_C    .get(flag_b)) bp = bp.add(FlagC    );
+            if (SET_FLAGS_VALUE_NOT_C.get(flag_b)) bp = bp.add(NotFlagC );
+            return new Set(dock, looping, predicate, ap, bp);
+        }
+        if (SET_TAPL_FROM_IMMEDIATE.get(inst))
+            return new Set(dock, looping, predicate, SetDest.TAPL, getPathByAddr(dock, SET_TAPL_FROM_IMMEDIATE.getval(inst)));
+        if (MOVE.get(inst))
+            return new Move(dock,
+                            looping,
+                            predicate,
+                            I.get(inst),
+                            getPathByAddr(dock, PATH_IMMEDIATE.getval(inst)),
+                            TI.get(inst),
+                            DI.get(inst),
+                            DC.get(inst),
+                            PATH_DATA.get(inst),
+                            DO.get(inst),
+                            TO.get(inst)
+                            );
+        throw new RuntimeException("unknown instruction: 0x" + Long.toString(inst, 16));
     }
 
-    public long writeInstruction(Instruction d) {
+    public long writeInstruction(Dock dispatchFrom, Instruction d) {
         long instr = 0;
 
-        if (d.pump != null)
-            instr = PUMP_NAME.setval(instr, getBoxInstAddr(d.pump));
+        if (d.dock != null)
+            instr = DISPATCH_PATH.setval(instr, getDestAddr(getUniversalSource().getPath(d.dock.getInstructionDestination(),null)));
 
         boolean dl = false;
-        if (d instanceof Instruction.PredicatedInstruction) {
-            Instruction.PredicatedInstruction pi = (Instruction.PredicatedInstruction)d;
-            if (pi.dl) instr = DL.set(instr);
-            switch(pi.predicate) {
-                case Instruction.PredicatedInstruction.P_ALWAYS: instr = P_ALWAYS.set(instr); break;
-                case Instruction.PredicatedInstruction.P_IF_A:   instr = P_A.set(instr);      break;
-                case Instruction.PredicatedInstruction.P_IF_B:   instr = P_B.set(instr);      break;
-                case Instruction.PredicatedInstruction.P_IF_Z:   instr = P_Z.set(instr);      break;
-            }
-        }
-
-        if (d instanceof Instruction.CodeBagDescriptor) {
-            Instruction.CodeBagDescriptor lc = (Instruction.CodeBagDescriptor)d;
-            // MAJOR MAJOR FIXME: upper half here...
-            d = new Instruction.HalfLiteral(lc.pump, dl, Instruction.PredicatedInstruction.P_ALWAYS,
-                                            ((lc.offset << WIDTH_CODEBAG_SIZE)) | lc.size, 1, false);
+        Instruction pi = d;
+        if (!pi.looping) instr = OS.set(instr);
+        switch(pi.predicate) {
+            case IgnoreOLC:         instr = P_ALWAYS.set(instr); break;
+            case Default: instr = P_OLC.set(instr); break;
+            case FlagA:      instr = P_A.set(instr);      break;
+            case FlagB:      instr = P_B.set(instr);      break;
+            case FlagC:      instr = P_C.set(instr);      break;
+            case NotFlagA:  instr = P_NOT_A.set(instr);      break;
+            case NotFlagB:  instr = P_NOT_B.set(instr);      break;
+            case NotFlagC:  instr = P_NOT_C.set(instr);      break;
         }
 
-        if (d instanceof Instruction.UnClog) {
-            instr = UNCLOG.set(instr);
-
-        } else if (d instanceof Instruction.Kill) {
-            Instruction.Kill k = (Instruction.Kill)d;
-            instr = KILL.set(instr);
-            instr = KILL.setval(instr, k.count);
-
-        } else if (d instanceof Instruction.Clog) {
-            instr = CLOG.set(instr);
-
-        } else if (d instanceof Instruction.Massacre) {
-            instr = MASSACRE.set(instr);
-
-        } else if (d instanceof Instruction.SetFlags) {
-            Instruction.SetFlags sf = (Instruction.SetFlags)d;
-            instr = FLAGS.set(instr);
-            instr = FLAGS_A.setval(instr, sf.flag_a);
-            instr = FLAGS_B.setval(instr, sf.flag_b);
-
-        } else if (d instanceof Instruction.Literal) {
-            long il = ((Instruction.Literal)d).literal;
-            if      (TOP_HALF_ONE.get(il))           instr = LITERAL_LO.setval(LITERAL_HIGH_ONE.set(instr),  BOT_HALF_LITERAL.getval(il));
-            else if (TOP_HALF_LITERAL.getval(il)==0) instr = LITERAL_LO.setval(LITERAL_HIGH_ZERO.set(instr), BOT_HALF_LITERAL.getval(il));
-            else if (BOT_HALF_ONE.get(il))           instr = LITERAL_HI.setval(LITERAL_LOW_ONE.set(instr),   TOP_HALF_LITERAL.getval(il));
-            else if (BOT_HALF_LITERAL.getval(il)==0) instr = LITERAL_HI.setval(LITERAL_LOW_ZERO.set(instr),  TOP_HALF_LITERAL.getval(il));
-            else throw new RuntimeException("literal cannot be encoded using a single instruction");
-            
-        } else if (d instanceof Instruction.HalfLiteral) {
-            Instruction.HalfLiteral inst = (Instruction.HalfLiteral)d;
-            if (inst.pump != null) {
-                if (inst.high) {
-                    instr = LITERAL_HI.set(instr);
-                    instr = LITERAL_HI.setval(instr, inst.literal);
-                } else {
-                    instr = LITERAL_LO.set(instr);
-                    instr = LITERAL_LO.setval(instr, inst.literal);
+        if (d instanceof Tail) {
+            instr = TAIL.set(instr);
+
+        } else if (d instanceof Shift) {
+            Shift shift = (Shift)d;
+            instr = SHIFT.set(instr);
+            instr = SHIFT.setval(instr, shift.immediate);
+
+        } else if (d instanceof Set) {
+            Set s = (Set)d;
+            switch(s.dest) {
+                case InnerLoopCounter:
+                    switch(s.source) {
+                        case DataLatch:
+                            instr = SET_ILC_FROM_DATA_LATCH.set(instr);
+                            break;
+                        case Immediate:
+                            instr = SET_ILC_FROM_IMMEDIATE.setval(SET_ILC_FROM_IMMEDIATE.set(instr), s.immediate);
+                            break;
+                        case Infinity:
+                            instr = SET_ILC_FROM_INFINITY.set(instr);
+                            break;
+                    }
+                    break;
+                case OuterLoopCounter:
+                    switch(s.source) {
+                        case Decrement:
+                            instr = SET_OLC_FROM_OLC_MINUS_ONE.set(instr);
+                            break;
+                        case DataLatch:
+                            instr = SET_OLC_FROM_DATA_LATCH.set(instr);
+                            break;
+                        case Immediate:
+                            instr = SET_OLC_FROM_IMMEDIATE.setval(SET_OLC_FROM_IMMEDIATE.set(instr), s.immediate);
+                            break;
+                    }
+                    break;
+                case TAPL: {
+                    instr = SET_TAPL_FROM_IMMEDIATE.set(instr);
+                    instr = SET_TAPL_FROM_IMMEDIATE.setval(instr, getDestAddr(s.path));
+                    break;
+                }
+                case Flags: {
+                    instr = SET_FLAGS.set(instr);
+                    instr = SET_FLAGS_A.setval(instr, flagFunctionToLong(s.newFlagA));
+                    instr = SET_FLAGS_B.setval(instr, flagFunctionToLong(s.newFlagB));
+                    break;
+                }
+                case DataLatch: {
+                    instr = SET_IMMEDIATE.set(instr);
+                    instr = SET_IMMEDIATE_EXTEND.setval(instr, s.immediate < 0 ? 1 : 0);
+                    instr = SET_IMMEDIATE.setval(instr, s.immediate & ~(-1L << DataLatch_WIDTH));
+                    break;
                 }
-            } else {
-                instr = inst.literal;
             }
 
-        } else if (d instanceof Instruction.DecrLoop) {
-            instr = DL.set(instr);
-
-        } else if (d instanceof Instruction.Counter) {
-            Instruction.Counter ic = (Instruction.Counter)d;
-            if      (ic.dest == DATA_LATCH && ic.source == LOOP_COUNTER)   instr = TAKE_LOOP.set(instr);
-            else if (ic.dest == LOOP_COUNTER && ic.source == DATA_LATCH)   instr = LOOP_FROM_DATA.set(instr);
-            else if (ic.dest == REPEAT_COUNTER && ic.source == DATA_LATCH) instr = REPEAT_FROM_DATA.set(instr);
-            else if (ic.dest == REPEAT_COUNTER && ic.source == STANDING)   instr = REPEAT_FROM_STANDING.set(instr);
-            else if (ic.dest == REPEAT_COUNTER)                            instr = REPEAT_FROM_LITERAL.setval(REPEAT_FROM_LITERAL.set(instr), ic.source);
-            else if (ic.dest == LOOP_COUNTER)                              instr = LOOP_FROM_LITERAL.setval(LOOP_FROM_LITERAL.set(instr), ic.source);
-            else throw new RuntimeException();
-
-        } else if (d instanceof Instruction.Move) {
-            Instruction.Move inst = (Instruction.Move)d;
+        } else if (d instanceof Move) {
+            Move inst = (Move)d;
             instr  = MOVE.set(instr);
             if (inst.tokenIn)                    instr = TI.set(instr);
             if (inst.dataIn)                     instr = DI.set(instr);
-            if (inst.latch)                      instr = DC.set(instr);
+            if (inst.latchData)                  instr = DC.set(instr);
             if (inst.dataOut)                    instr = DO.set(instr);
             if (inst.tokenOut)                   instr = TO.set(instr);
-            if (inst.dataOutDest)                instr = PATH_DATA.set(instr);
+            if (inst.interruptible)              instr = I.set(instr);
+
+            if (inst.latchPath)                  instr = PATH_DATA.set(instr);
             else {
-                instr  = PATH_LITERAL.set(instr);
-                instr  = PATH_LITERAL.setval(instr, inst.dest==null?0:getDestAddr(inst.dest));
+                instr  = PATH_IMMEDIATE.set(instr);
+                instr  = PATH_IMMEDIATE.setval(instr, inst.path==null?0:getDestAddr(inst.path));
             }
 
         } else {
-            throw new RuntimeException("unrecognized instruction " + d);
+            throw new RuntimeException("unrecognized instruction " + d.getClass().getName());
 
         }
         return instr;
     }
 
-    public void writeInstruction(DataOutputStream os, Instruction d) throws IOException {
-        long instr = writeInstruction(d);
+    public void writeInstruction(DataOutputStream os, Dock dispatchFrom, Instruction d) throws IOException {
+        long instr = writeInstruction(dispatchFrom, d);
         for(int i=5; i>=0; i--)
-            os.write(getIntField(i*8+7, i*8, instr));
-   }
+            os.write(BitManipulations.getIntField(i*8+7, i*8, instr));
+    }
 
-}
\ No newline at end of file
+    private static long flagFunctionToLong(FlagFunction ff) {
+        long ret = 0;
+        for(Predicate p : ff)
+            switch(p) {
+                case FlagA    : ret = SET_FLAGS_VALUE_A    .set(ret); break;
+                case NotFlagA : ret = SET_FLAGS_VALUE_NOT_A.set(ret); break;
+                case FlagB    : ret = SET_FLAGS_VALUE_B    .set(ret); break;
+                case NotFlagB : ret = SET_FLAGS_VALUE_NOT_B.set(ret); break;
+                case FlagC    : ret = SET_FLAGS_VALUE_C    .set(ret); break;
+                case NotFlagC : ret = SET_FLAGS_VALUE_NOT_C.set(ret); break;
+                default: throw new RuntimeException();
+            }
+        return ret;
+    }
+}
index 4fe5cb5..6d2f8ad 100644 (file)
@@ -2,10 +2,11 @@ package edu.berkeley.fleet.interpreter;
 import edu.berkeley.sbp.util.ANSI;
 import edu.berkeley.fleet.api.*;
 import static edu.berkeley.fleet.util.BitManipulations.*;
+import edu.berkeley.fleet.two.*;
 import java.util.*;
 
 /** this is a generic inbox which stores <32-bit items (tokens or data) */
-public class Inbox extends InstructionPump {
+public class Inbox extends InstructionDock {
 
     public boolean dataReadyForShip()            { return itemReadyForShip; }
     public Packet removePacketForShip()          { remove(); return register; }
@@ -25,11 +26,8 @@ public class Inbox extends InstructionPump {
     /** if an ack token is pending, this is where it should be sent once the item is accepted */
     private Packet bufferedAck = null;
 
-    public boolean isInbox() { return true; }
-    public boolean isOutbox() { return false; }
-
-    public Inbox(InterpreterShip ship, String name)                 { super(ship, name, new String[] { "" }); }
-    public Inbox(InterpreterShip ship, String name, String[] ports) { super(ship, name, ports); }
+    public Inbox(InterpreterShip ship, DockDescription dd) { super(ship, new String[] { "" }, dd); }
+    public Inbox(InterpreterShip ship, String[] ports, DockDescription dd) { super(ship, ports, dd); }
 
     public void addDataFromFabric(Packet packet) { itemsFromFabric.add(packet); }
     private void remove() {
@@ -54,6 +52,7 @@ public class Inbox extends InstructionPump {
         // if no instruction waiting, do nothing
         if (instruction_ == null) return false;
 
+        /*
         if (instruction_ instanceof Instruction.Literal) {
             register = new Packet(getInterpreter(), null, ((Instruction.Literal)instruction_).literal, null);
             return true;
@@ -67,6 +66,7 @@ public class Inbox extends InstructionPump {
             register = new Packet(getInterpreter(), null, val, null);
             return true;
         }
+        */
         Instruction.Move instruction = (Instruction.Move)instruction_;
 
         // check firing conditions
@@ -78,7 +78,7 @@ public class Inbox extends InstructionPump {
 
         // consume inbound data+token
         if (instruction.dataIn) {
-            if (instruction.latch) {
+            if (instruction.latchData) {
                 register = itemsFromFabric.remove();
             } else {
                 itemsFromFabric.remove();
@@ -91,12 +91,12 @@ public class Inbox extends InstructionPump {
 
             // and make note of the fact that we need to send an ack (if requested)
             if (instruction.tokenOut)
-                bufferedAck = new Packet(getInterpreter(), this, 0, (InterpreterDestination)instruction.dest);
+                bufferedAck = new Packet(getInterpreter(), this, 0, (InterpreterDestination)(Object)instruction.path);
 
         } else if (instruction.tokenOut) {
 
             // if dataOut is not set, we can send the data immediately
-            new Packet(getInterpreter(), this, 0, (InterpreterDestination)instruction.dest).send();
+            new Packet(getInterpreter(), this, 0, (InterpreterDestination)(Object)instruction.path).send();
         }
         return true;
     }
@@ -1,18 +1,20 @@
 package edu.berkeley.fleet.interpreter;
 import edu.berkeley.sbp.util.ANSI;
+import edu.berkeley.fleet.two.*;
 import edu.berkeley.fleet.api.*;
-import edu.berkeley.fleet.doc.*;
 import edu.berkeley.fleet.api.Instruction;
+import static edu.berkeley.fleet.api.Predicate.*;
 
 import java.util.*;
 
 /** anything that has a source (instruction horn) address on the switch fabric */
-abstract class InstructionPump extends InterpreterPump {
+abstract class InstructionDock extends InterpreterDock {
 
-    public int clogged = 0;
+    public int tailged = 0;
 
     public boolean flag_a = false;
     public boolean flag_b = false;
+    public boolean flag_c = false;
 
     /** the currently executing instruction */
     private Instruction executing = null;
@@ -23,8 +25,8 @@ abstract class InstructionPump extends InterpreterPump {
     public int loopCounter = 0;
     private int repeatCounter = 1;
 
-    InstructionPump(InterpreterShip ship, String name, String[] ports) {
-        super(ship, name, ports);
+    InstructionDock(InterpreterShip ship,  String[] ports, DockDescription bbd) {
+        super(ship, ports, bbd);
     }
 
     public void massacre() {
@@ -65,35 +67,33 @@ abstract class InstructionPump extends InterpreterPump {
     protected abstract long peekDataLatch();
 
     protected final void service() {
-        if (clogged > 0) return;
+            /*
+        if (tailged > 0) return;
         if (executing==null && instructions.size() > 0) executing = instructions.remove();
         if (executing==null) return;
 
-        if (executing instanceof Instruction.Clog) {
-            clogged++;
-            executing = null;
-            return;
-        }
-
         boolean enabled = true;
         if (executing instanceof Instruction.PredicatedInstruction) {
             Instruction.PredicatedInstruction ip = (Instruction.PredicatedInstruction)executing;
             switch(ip.predicate) {
-                case Instruction.PredicatedInstruction.P_ALWAYS: enabled = true; break;
-                case Instruction.PredicatedInstruction.P_IF_A:   enabled = flag_a; break;
-                case Instruction.PredicatedInstruction.P_IF_B:   enabled = flag_b; break;
-                case Instruction.PredicatedInstruction.P_IF_Z:   enabled = loopCounter==0; break;
+                case IgnoreOLC:      enabled = true; break;
+                case Default:  enabled = loopCounter!=0; break;
+                case FlagA:   enabled = flag_a; break;
+                case FlagB:   enabled = flag_b; break;
+                    //case FlagC:   enabled = ; break;
+                case NotFlagA:   enabled = !flag_a; break;
+                case NotFlagB:   enabled = !flag_b; break;
+                    //case NotFlagC:   enabled = loopCounter==0; break;
             }
         }
 
         int oldLoopCounter = loopCounter;
         if (enabled) {
-            if (executing.isDL()) loopCounter = Math.max(0, loopCounter-1);
-
+            if (executing instanceof Instruction.Set.OLC.Decrement) loopCounter = Math.max(0, loopCounter-1);
             if (executing instanceof Instruction.Counter) {
                 Instruction.Counter ic = (Instruction.Counter)executing;
                 if (ic.source == Instruction.Counter.LOOP_COUNTER && ic.dest == Instruction.Counter.DATA_LATCH) {
-                    setDataLatch(oldLoopCounter); /* FIXME: which is correct here? */
+                    setDataLatch(oldLoopCounter); // FIXME: which is correct here?
                 } else if (ic.dest == Instruction.Counter.LOOP_COUNTER && ic.source == Instruction.Counter.DATA_LATCH) {
                     loopCounter = (int)peekDataLatch();
                 } else if (ic.dest == Instruction.Counter.REPEAT_COUNTER && ic.source == Instruction.Counter.DATA_LATCH) {
@@ -107,10 +107,9 @@ abstract class InstructionPump extends InterpreterPump {
                     repeatCounter = ic.source;
                 }
 
-            } else if (executing instanceof Instruction.SetFlags) {
-                Instruction.SetFlags sf = (Instruction.SetFlags)executing;
-                boolean old_s = ((peekDataLatch() >> (getInterpreter().getWordSize()-1)) & 1) != 0;
-                boolean old_z = oldLoopCounter == 0;
+                } else if (executing instanceof Instruction.Set.Flags) {
+                Instruction.Set.Flags sf = (Instruction.Set.Flags)executing;
+                boolean old_c = oldLoopCounter == 0;
                 boolean old_a = flag_a;
                 boolean old_b = flag_b;
                 flag_a =
@@ -118,37 +117,35 @@ abstract class InstructionPump extends InterpreterPump {
                     (((sf.flag_a & sf.FLAG_NOT_A) != 0) ? !old_a : false) |
                     (((sf.flag_a & sf.FLAG_B)     != 0) ?  old_b : false) |
                     (((sf.flag_a & sf.FLAG_NOT_B) != 0) ? !old_b : false) |
-                    (((sf.flag_a & sf.FLAG_Z)     != 0) ?  old_z : false) |
-                    (((sf.flag_a & sf.FLAG_NOT_Z) != 0) ? !old_z : false) |
-                    (((sf.flag_a & sf.FLAG_S)     != 0) ?  old_s : false) |
-                    (((sf.flag_a & sf.FLAG_NOT_S) != 0) ? !old_s : false);
+                    (((sf.flag_a & sf.FLAG_C)     != 0) ?  old_c : false) |
+                    (((sf.flag_a & sf.FLAG_NOT_C) != 0) ? !old_c : false);
                 flag_b =
                     (((sf.flag_b & sf.FLAG_A)     != 0) ?  old_a : false) |
                     (((sf.flag_b & sf.FLAG_NOT_A) != 0) ? !old_a : false) |
                     (((sf.flag_b & sf.FLAG_B)     != 0) ?  old_b : false) |
                     (((sf.flag_b & sf.FLAG_NOT_B) != 0) ? !old_b : false) |
-                    (((sf.flag_b & sf.FLAG_Z)     != 0) ?  old_z : false) |
-                    (((sf.flag_b & sf.FLAG_NOT_Z) != 0) ? !old_z : false) |
-                    (((sf.flag_b & sf.FLAG_S)     != 0) ?  old_s : false) |
-                    (((sf.flag_b & sf.FLAG_NOT_S) != 0) ? !old_s : false);
-            } else if (executing instanceof Instruction.DecrLoop) {
+                    (((sf.flag_b & sf.FLAG_C)     != 0) ?  old_c : false) |
+                    (((sf.flag_b & sf.FLAG_NOT_C) != 0) ? !old_c : false);
+            } else if (executing instanceof Instruction.Set.OLC.Decrement) {
             } else {
                 if (!service(executing)) return;
             }
         }
 
         if (executing==null) return;
-        if (executing.isRepeating() && repeatCounter > 1) {
+        if ((executing instanceof Instruction.Move) && repeatCounter > 1) {
             repeatCounter--;
-        } else if (executing.isRepeating() && repeatCounter == -1) {
+        } else if ((executing instanceof Instruction.Move) && repeatCounter == -1) {
             // repeat
-        } else if (executing.isLooping() && oldLoopCounter > 0) {
+        } else if ((executing instanceof Instruction.PredicatedInstruction && ((Instruction.PredicatedInstruction)executing).looping) && oldLoopCounter > 0) {
             addInstruction(executing);
             executing = null;
         } else {
             executing = null;
         }
+            */
     }
 
 
+
 }
index cc5650b..5db6ae1 100644 (file)
@@ -5,12 +5,23 @@ import java.util.concurrent.*;
 import java.lang.reflect.*;
 import edu.berkeley.fleet.*;
 import edu.berkeley.sbp.util.ANSI;
-import edu.berkeley.fleet.doc.*;
 import edu.berkeley.fleet.api.*;
 import edu.berkeley.fleet.ies44.*;
+import edu.berkeley.fleet.assembler.*;
+import edu.berkeley.fleet.two.*;
+import edu.berkeley.fleet.util.*;
+
+public class Interpreter extends Fleet implements Parser.FleetWithDynamicShips {
+
+    public Ship getShip(String type, int ordinal) {
+        for(Ship s : this)
+            if (s.getType().equals(type))
+                if (ordinal-- < 0)
+                    return s;
+        return null;
+    }
 
-public class Interpreter extends Fleet implements Fleet.WithDynamicShips {
-
+    public int getWordWidth() { return 37; }
     /** some "halt ship" can turn this on to stop the interpreter */
     private HashMap<String,InterpreterShip> ships       = new HashMap<String,InterpreterShip>();
     private BlockingQueue<Long>             debugStream = new LinkedBlockingQueue<Long>();
@@ -20,13 +31,18 @@ public class Interpreter extends Fleet implements Fleet.WithDynamicShips {
     public FleetProcess run(final byte[] instructions) {
         try {
             final FleetProcess fp = new FleetProcess() {
+                    public void dispatchInstruction(Instruction i) { throw new RuntimeException(); }
                     public void invokeInstruction(Instruction i) { throw new RuntimeException("not supported"); }
-                    public long readWord() {
+                    public Dock getDebugInputDock() { return null; }
+                    public BitVector readWord() {
+                        /*
                         try {
                             return debugStream.take();
                         } catch (Exception e) {
                             throw new RuntimeException(e);
-                        } }
+                            }*/
+                        throw new RuntimeException();
+                        }
                     protected void _terminate() {
                         // FIXME: hack
                         ships = new HashMap<String,InterpreterShip>();
@@ -43,10 +59,14 @@ public class Interpreter extends Fleet implements Fleet.WithDynamicShips {
                                 iscratch = (InterpreterShip)ship;
                                 break;
                             }
-                        if (iscratch==null)
+                        if (iscratch==null) {
+                            BufferedReader br =
+                                new BufferedReader(new InputStreamReader(new FileInputStream("ships/Memory.ship")));
+                            ShipDescription sd = new ShipDescription("Memory", br);
                             iscratch = (InterpreterShip)Class.forName("edu.berkeley.fleet.interpreter.Memory")
-                                .getConstructor(new Class[] { Interpreter.class, String.class })
-                                .newInstance(new Object[] { Interpreter.this, "memory" });
+                                .getConstructor(new Class[] { Interpreter.class, String.class, ShipDescription.class })
+                                .newInstance(new Object[] { Interpreter.this, "memory", sd });
+                        }
                         iscratch
                             .getClass()
                             .getMethod("boot", new Class[] { byte[].class })
@@ -83,27 +103,14 @@ public class Interpreter extends Fleet implements Fleet.WithDynamicShips {
 
     public void dispatch(Instruction i, long address) {
         Log.dispatch(i);
-        if (i instanceof Instruction.CodeBagDescriptor) {
-            Instruction.CodeBagDescriptor cbd = (Instruction.CodeBagDescriptor)i;
-            long absolute_cbd = ((cbd.offset+address) << 6) | cbd.size;
-            throw new RuntimeException();
-            //new Packet(this, null, (int)absolute_cbd, (InterpreterDestination)cbd.pump).send();
-            
-        } else if (i instanceof Instruction.UnClog) {
-            Instruction.UnClog ic = (Instruction.UnClog)i;
-            ((InstructionPump)(ic.pump)).clogged--;
-
-        } else if (i instanceof Instruction.Kill) {
-            InterpreterPump pump = (InterpreterPump)(((Instruction.Kill)i).pump);
-            ((InstructionPump)pump).kill();
-
-        } else if (i instanceof Instruction.Massacre) {
-            InterpreterPump pump = (InterpreterPump)(((Instruction.Massacre)i).pump);
-            ((InstructionPump)pump).massacre();
+           
+        if (i instanceof Instruction.Tail) {
+            Instruction.Tail ic = (Instruction.Tail)i;
+            ((InstructionDock)(ic.dock)).tailged--;
 
         } else {
-            InterpreterPump sourcePump = (InterpreterPump)(((Instruction)i).pump);
-            ((InstructionPump)sourcePump).addInstruction(((Instruction)i));
+            InterpreterDock sourceDock = (InterpreterDock)(((Instruction)i).dock);
+            ((InstructionDock)sourceDock).addInstruction(((Instruction)i));
         }
     }
 
@@ -112,14 +119,14 @@ public class Interpreter extends Fleet implements Fleet.WithDynamicShips {
     public Ship createShip(String shipType, String shipname) {
         try {
             Class c = Class.forName("edu.berkeley.fleet.interpreter."+shipType);
-            Constructor con = c.getConstructor(new Class[] { Interpreter.class, String.class });
-            InterpreterShip ret = (InterpreterShip)con.newInstance(new Object[] { this, shipname });
+            Constructor con = c.getConstructor(new Class[] { Interpreter.class, String.class, ShipDescription.class });
             BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("ships/"+shipType+".ship")));
-            ShipDescription sd = new ShipDescription(shipname, br);
-            ret.setShipDescription(sd);
+            ShipDescription sd = new ShipDescription(shipType, br);
+            InterpreterShip ret = (InterpreterShip)con.newInstance(new Object[] { this, shipname, sd });
             ships.put(shipname, ret);
             return ret;
         } catch (Exception e) {
+            e.printStackTrace();
             return null;
         }
     }
@@ -136,24 +143,28 @@ public class Interpreter extends Fleet implements Fleet.WithDynamicShips {
     // Instruction Encoding /////////////////////////////////////////////////////////////////////////
 
     public final InterpreterInstructionEncoder iie = new InterpreterInstructionEncoder();
-    public Instruction readInstruction(DataInputStream is) throws IOException { return iie.readInstruction(is); }
-    public Instruction readInstruction(long instr) { return iie.readInstruction(instr); }
-    public long writeInstruction(Instruction d) { return writeInstruction(d); }
-    public void writeInstruction(DataOutputStream os, Instruction d) throws IOException { iie.writeInstruction(os, d); }
+    public Instruction readInstruction(DataInputStream is, Dock dispatchFrom) throws IOException { return iie.readInstruction(dispatchFrom, is); }
+    public Instruction readInstruction(Dock dispatchFrom, long instr) { return iie.readInstruction(dispatchFrom, instr); }
+    public long writeInstruction(Dock dispatchFrom, Instruction d) { return writeInstruction(dispatchFrom, d); }
+    public void writeInstruction(DataOutputStream os, Dock dispatchFrom, Instruction d) throws IOException { iie.writeInstruction(os, dispatchFrom, d); }
+    public Dock getUniversalSource() { return null; }
     public class InterpreterInstructionEncoder extends InstructionEncoder {
-        public long getDestAddr(Destination box) { return ((InterpreterDestination)box).getDestAddr(); }
-        public long getBoxInstAddr(Pump box) { return ((InterpreterPump)box).getDestAddr(); }
+    public Dock getUniversalSource() { return null; }
+        public long getDestAddr(Path path) { throw new RuntimeException(); }
+        public long getBoxInstAddr(Dock box) { return ((InterpreterDock)box).getDestAddr(); }
+        public Path getPathByAddr(Dock source, long dest) { throw new RuntimeException(); }
         public Destination getDestByAddr(long dest) {
+            /*
             for(Ship ship : Interpreter.this)
-                for(Pump bb : ship.getPumps())
-                    for(Destination d : bb.getDestinations())
-                        if (getDestAddr(d)==dest)
-                            return d;
+                for(Dock bb : ship)
+                    if (getDestAddr(bb.getDataDestination())==dest)
+                        return bb.getDataDestination();
+            */
             return null;
         }
-        public Pump getBoxByInstAddr(long dest) {
+        public Dock getBoxByInstAddr(long dest) {
             for(Ship ship : Interpreter.this)
-                for(Pump bb : ship.getPumps())
+                for(Dock bb : ship)
                     if (getBoxInstAddr(bb) == dest)
                         return bb;
             return null;
@@ -175,36 +186,33 @@ public class Interpreter extends Fleet implements Fleet.WithDynamicShips {
             pw.println("package edu.berkeley.fleet.interpreter;");
             pw.println("import edu.berkeley.sbp.util.ANSI;");
             pw.println("import edu.berkeley.fleet.api.*;");
+            pw.println("import edu.berkeley.fleet.two.*;");
             pw.println("import edu.berkeley.fleet.*;");
             pw.println("import java.util.*;");
             pw.println("import java.io.*;");
             pw.println("");
             pw.println("public class "+filename+" extends InterpreterShip {");
             pw.println("");
-            for(PumpDescription b : sd) {
+            for(DockDescription b : sd) {
                 String name = b.getName();
                 pw.print("    ");
-                if ( b.isInbox()) pw.print("Inbox");
-                if (!b.isInbox()) pw.print("Outbox");
+                if ( b.isInputDock()) pw.print("Inbox");
+                if (!b.isInputDock()) pw.print("Outbox");
                 pw.print(" box_");
                 pw.print(name);
                 pw.print(" = new ");
-                if ( b.isInbox()) pw.print("Inbox");
-                if (!b.isInbox()) pw.print("Outbox");
-                pw.print("(this, \""+name+"\", new String[] { ");
+                if ( b.isInputDock()) pw.print("Inbox");
+                if (!b.isInputDock()) pw.print("Outbox");
+                pw.print("(this, new String[] { ");
                 boolean first = true;
-                for(String destination : b) {
-                    if (!first) pw.print(", ");
-                    first = false;
-                    pw.print("\""+destination+"\"");
-                }
-                pw.println("});");
+                pw.print("\"\"");
+                pw.println("}, shipDescription.getDockDescription(\""+name+"\"));");
             }
             pw.println("");
-            pw.println("    public "+filename+"(Interpreter fleet, String name) {");
-            pw.println("       super(fleet, name, \""+filename+"\");");
-            for(PumpDescription b : sd)
-                pw.println("       addPump(\""+b.getName()+"\", box_"+b.getName()+");");
+            pw.println("    public "+filename+"(Interpreter fleet, String name, ShipDescription sd) {");
+            pw.println("       super(fleet, name, sd);");
+            for(DockDescription b : sd)
+                pw.println("       addDock(\""+b.getName()+"\", box_"+b.getName()+");");
             pw.println("    }");
             pw.println("");
             pw.println(sd.getSection("fleeterpreter"));
index 87748bd..ac466c8 100644 (file)
@@ -3,7 +3,8 @@ import edu.berkeley.fleet.api.*;
 import java.util.*;
 
 abstract class InterpreterDestination extends Destination {
+    public InterpreterDestination(InterpreterDock d, boolean isInstructionDestination) { super(d); }
     public abstract long getDestAddr();
     public abstract void addDataFromFabric(Packet packet);
     public abstract String getDestinationName();
-}
\ No newline at end of file
+}
@@ -1,32 +1,28 @@
 package edu.berkeley.fleet.interpreter;
-import edu.berkeley.fleet.doc.*;
 import edu.berkeley.fleet.api.*;
-import edu.berkeley.fleet.api.Pump;
+import edu.berkeley.fleet.api.Dock;
+import edu.berkeley.fleet.two.*;
 import java.util.*;
 
+
 /** anything that has a destination address on the switch fabric */
-public abstract class InterpreterPump extends Pump {
+public abstract class InterpreterDock extends FleetTwoDock {
         
-    private final String name;
     private final InterpreterShip ship;
     private final Destination[] ports;
     private final int addr = max_addr++;
-    private  PumpDescription bbd;
-
-    public void setDescription(PumpDescription bbd) {
-        this.bbd = bbd;
-    }
-    public long resolveLiteral(String literal) {
-        return bbd.resolveLiteral(literal);
-    }
     
-    public InterpreterPump(InterpreterShip ship, String name, String[] ports) {
+    public InterpreterDock(InterpreterShip ship, String[] ports, DockDescription bbd) {
+        super(ship, bbd);
         this.ship = ship;
-        this.name = name;
         this.ports = new Destination[ports.length];
         for(int i=0; i<ports.length; i++)
             this.ports[i] =
-                new InterpreterPumpDestination(ports[i]);
+                new InterpreterDockDestination(ports[i], this, false);
+    }
+
+    public Path getPath(Destination d, BitVector signal) {
+        throw new RuntimeException();
     }
 
     public Iterable<Destination> getDestinations() {
@@ -35,6 +31,14 @@ public abstract class InterpreterPump extends Pump {
         return ret;
     }
 
+    public Destination getInstructionDestination() {
+        return ports[0];
+    }
+    public Destination getDataDestination() {
+        return ports[0];
+    }
+
+
     /** adds the included datum to the port from the switch fabric  side */
     public abstract void addDataFromFabric(Packet packet);
 
@@ -44,23 +48,24 @@ public abstract class InterpreterPump extends Pump {
 
     public   Ship   getShip()                  { return ship; }
     public   Fleet  getFleet()                 { return getShip().getFleet(); }
-    public   String toString()                 { return ship+"."+name; }
-    public   String getName()                  { return name; }
-    public   int    getInstructionFifoLength() { return 4; }
+    public   String toString()                 { return ship+"."+getName(); }
+    public   int    getInstructionFifoSize() { return 4; }
     
     Interpreter getInterpreter() { return ((InterpreterShip)getShip()).getInterpreter(); }
 
     public long getDestAddr() { return addr; }
 
     private static int max_addr;
-
-    private class InterpreterPumpDestination extends InterpreterDestination {
+    private class InterpreterDockDestination extends InterpreterDestination {
         public String name;
         public long addr = max_addr++;
-        public InterpreterPumpDestination(String name)          { this.name = name; }
+        public InterpreterDockDestination(String name, InterpreterDock id, boolean isInstructionDestination) {
+            super(id, isInstructionDestination);
+            this.name = name;
+        }
         public String getDestinationName()               { return name; }
-        public Ship getShip()                    { return InterpreterPump.this.getShip(); }
-        public void addDataFromFabric(Packet packet) { InterpreterPump.this.addDataFromFabric(packet); }
+        public Ship getShip()                    { return InterpreterDock.this.getShip(); }
+        public void addDataFromFabric(Packet packet) { InterpreterDock.this.addDataFromFabric(packet); }
         public String toString()                 { return getShip()+"."+getName(); }
         public long getDestAddr() { return addr; }
     }
index 83fdaec..37c10cd 100644 (file)
@@ -1,35 +1,21 @@
 package edu.berkeley.fleet.interpreter;
 import edu.berkeley.fleet.api.*;
-import edu.berkeley.fleet.doc.*;
+import edu.berkeley.fleet.two.*;
 import java.util.*;
 import java.io.*;
 
 /** a ship, which belongs to a fleet and which may have many ports */
-abstract class InterpreterShip extends Ship {
+abstract class InterpreterShip extends FleetTwoShip {
         
     /** You should instantiate a bunch of Inboxes and Outboxes in your constructor */
-    public InterpreterShip(Interpreter fleet, String name, String type) {
-        this.fleet = fleet;
-        this.type = type;
+    public InterpreterShip(Interpreter fleet, String name, ShipDescription sd) {
+        super(fleet, sd);
     }
 
-    private Interpreter  fleet;
-    private String       type;
-    private HashMap<String,InterpreterPump> ports = new HashMap<String,InterpreterPump>();
+    private HashMap<String,InterpreterDock> ports = new HashMap<String,InterpreterDock>();
 
-    public Iterable<Pump> getPumps()  { return (Iterable<Pump>)(Object)ports.values(); }
-    public String             getType()        { return type; }
-    public Fleet              getFleet()       { return fleet; }
-    public Interpreter        getInterpreter() { return fleet; }
-
-    public void setShipDescription(ShipDescription sd) {
-        for(InterpreterPump ibb : ports.values()) {
-            for(PumpDescription bbd : sd) {
-                if (bbd.getName().equals(ibb.getName()))
-                    ibb.setDescription(bbd);
-            }
-        }
-    }
+    public Iterator<Dock> iterator() { return (Iterator<Dock>)(Object)ports.values().iterator(); }
+    public Interpreter        getInterpreter() { return (Interpreter)getFleet(); }
 
     /**
      *  Override this method, check inboxes for the data you need, and
@@ -39,16 +25,16 @@ abstract class InterpreterShip extends Ship {
     public abstract void service();
 
     public final void _service() {
-        for(InterpreterPump p : ports.values()) p.service();
+        for(InterpreterDock p : ports.values()) p.service();
         service();
     }
 
-    protected void addPump(String name, InterpreterPump port) {
+    protected void addDock(String name, InterpreterDock port) {
         ports.put(name, port);
     }
 
     public void shutdown() {
-        for(InterpreterPump p : ports.values())
+        for(InterpreterDock p : ports.values())
             p.shutdown();
     }
 }
index e012e32..9fbd93c 100644 (file)
@@ -36,13 +36,13 @@ public class Log {
         println(ANSI.green("dispatch: " + indent(d+"", "          ")));
     }
 
-    public static void data(String data, Pump source, Destination dest) {
+    public static void data(String data, Dock source, Destination dest) {
         println(("    data: ") + indent(ANSI.purple(data) +
                                         (source==null ? "" :
                                          (" : " + source))+(" -> "+ANSI.purple(""+dest)), "          "));
     }
 
-    public static void token(Pump source, Destination dest) {
+    public static void token(Dock source, Destination dest) {
         println(ANSI.purple("   token: ") + (source + " -> " + ANSI.purple(dest+"")));
     }
 
index 3a9d411..f3efd49 100644 (file)
@@ -5,9 +5,10 @@ import edu.berkeley.fleet.ies44.*;
 import edu.berkeley.sbp.util.*;
 import edu.berkeley.fleet.util.*;
 import static edu.berkeley.fleet.util.BitManipulations.*;
+import edu.berkeley.fleet.two.*;
 import edu.berkeley.fleet.api.Instruction;
 
-public class Outbox extends InstructionPump {
+public class Outbox extends InstructionDock {
 
     /** are we ready to accept another item from the ship? */
     private boolean readyForDataFromShip = false;
@@ -22,15 +23,14 @@ public class Outbox extends InstructionPump {
     /** the latched value */
     private long register;
 
-    public boolean isInbox() { return false; }
-    public boolean isOutbox() { return true; }
-    public Outbox(InterpreterShip ship, String name) { this(ship, name, new String[] { "" }); }
-    public Outbox(InterpreterShip ship, String name, String[] ports) { super(ship, name, ports); }
+    public Outbox(InterpreterShip ship, DockDescription dd) { this(ship, new String[] { "" }, dd); }
+    public Outbox(InterpreterShip ship, String[] ports, DockDescription dd) { super(ship, ports, dd); }
 
     protected void setDataLatch(long value) { register = value; }
     protected long peekDataLatch() { return register; }
 
     protected final boolean service(Instruction instruction_) {
+        /*
         if (instruction_ instanceof Instruction.Literal) {
             register = ((Instruction.Literal)instruction_).literal;
             return true;
@@ -42,6 +42,7 @@ public class Outbox extends InstructionPump {
                 : setField(18,  0, ll.literal, register);
             return true;
         }
+        */
         Instruction.Move instruction = (Instruction.Move)instruction_;
 
         // if no instruction waiting, do nothing
@@ -59,24 +60,24 @@ public class Outbox extends InstructionPump {
         // consume item
         if (instruction.dataIn) {
             haveDataFromShip = false;
-            if (instruction.latch) 
+            if (instruction.latchData) 
                 register = itemPresentedByShip;
         }
 
         if (instruction.dataOut) {
 
             // if item to be transmitted, send it
-            InterpreterDestination dest = (InterpreterDestination)instruction.dest;
-            if (instruction.dataOutDest) {
+            InterpreterDestination dest = (InterpreterDestination)(Object)instruction.path;
+            if (instruction.latchPath) {
                 // FIXME: still not supported
-                long bits = InstructionEncoder.PUMP_NAME.getval(register);
-                getInterpreter().dispatch(((Interpreter)getInterpreter()).iie.readInstruction(register), bits);
+                long bits = InstructionEncoder.DISPATCH_PATH.getval(register);
+                getInterpreter().dispatch(((Interpreter)getInterpreter()).iie.readInstruction(null, register), bits);
                 /*
                 dest = (InterpreterDestination)(((Interpreter)getInterpreter()).iie.getDestByAddr(bits));
                 if (dest == null) {
                     if (pump != null) {
                         
-                Pump pump = ((Interpreter)getInterpreter()).iie.getDestByInstAddr(bits);
+                Dock pump = ((Interpreter)getInterpreter()).iie.getDestByInstAddr(bits);
                     }
                 }
                 */
@@ -90,7 +91,7 @@ public class Outbox extends InstructionPump {
         } else if (instruction.tokenOut) {
 
             // if no item was sent, we might still send an ack
-            new Packet(getInterpreter(), this, 0, (InterpreterDestination)instruction.dest).send();
+            new Packet(getInterpreter(), this, 0, (InterpreterDestination)(Object)instruction.path).send();
         }
 
         return true;
index 3042201..8b5c940 100644 (file)
@@ -5,7 +5,6 @@ import java.util.concurrent.*;
 import java.lang.reflect.*;
 import edu.berkeley.fleet.*;
 import edu.berkeley.sbp.util.ANSI;
-import edu.berkeley.fleet.doc.*;
 import edu.berkeley.fleet.api.*;
 import edu.berkeley.fleet.ies44.*;
 
@@ -15,7 +14,7 @@ class Packet {
     long        value;
     InterpreterDestination destination;
 
-    public Packet(Interpreter interpreter, InterpreterPump source, long value, InterpreterDestination destination) {
+    public Packet(Interpreter interpreter, InterpreterDock source, long value, InterpreterDestination destination) {
         Log.data(value+"", source, (Destination)destination);
         this.interpreter = interpreter;
         this.value = value;
@@ -26,4 +25,4 @@ class Packet {
         destination.addDataFromFabric(this);
     }
 
-}
\ No newline at end of file
+}
diff --git a/src/edu/berkeley/fleet/ir/IR.java b/src/edu/berkeley/fleet/ir/IR.java
new file mode 100644 (file)
index 0000000..0c670fd
--- /dev/null
@@ -0,0 +1,84 @@
+package edu.berkeley.fleet;
+
+// interesting primitive: an "atomic"
+// take-from-fred-and-deliver-to-mary transition; you can give it
+// predecessors and successors.
+//   -- hitch: this artificially causes fred's successor to wait until
+//      mary has gotten the data item
+
+
+// Literal gets folded into anything involving a UsesData
+// Repeat-literal-count appears to the programmer just as repeat with a separate literal
+// FEATURE: apply tachio analysis to ensure kills never get stuck
+// FEATURE: ability to save the MSB flag for later use
+public class IR {
+    /*
+    public interface Nodes extends Iterable<Node> {
+    }
+
+    public class NodesImpl extends Nodes {
+        public NodesImpl(Node[] ns) { } // FIXME
+        public NodesImpl(Node n1, Node n2) { this(new Node[] { n1, n2 }); }
+        public NodesImpl() { this(new Node[0]); }
+        //public Iterator<Node> iterator() { return new SingletonIterator(this); }
+    }
+
+    public abstract class Node extends Nodes {
+        public abstract Nodes preds();
+        public abstract Nodes succs();
+        public Iterator<Node> iterator() { return new SingletonIterator(this); }
+    }
+
+    public class Join extends Node {
+        public Node  succ;
+        public Nodes preds;
+        public Nodes preds() { return preds; }
+        public Nodes succs() { return succ; }
+    }
+    public class Fork extends Node {
+        public Node  pred;
+        public Nodes succs;
+        public Nodes preds() { return pred; }
+        public Nodes succs() { return succs; }
+    }
+
+    public abstract class Linear extends Node {
+        public Node  pred;
+        public Node  succ;
+        public Nodes preds() { return pred; }
+        public Nodes succs() { return succ; }
+    }
+
+    // Actual Instructions //////////////////////////////////////////////////////////////////////////////
+
+    public class Repeat extends Linear {
+        public Node bodyFirst;
+        public Node bodyLast;
+        public Nodes preds() { return new Nodes(pred, bodyLast); }
+        public Nodes succs() { return new Nodes(succ, bodyFirst); }
+    }
+
+    public class RepeatCount extends Repeat implements UsesData {
+    }
+
+    // if nonnegative then...else...
+    public class IfThenElse extends Linear implements UsesData {
+        public Node thenFirst;
+        public Node thenLast;
+        public Node elseFirst;
+        public Node elseLast;
+        public Join impliedJoin;
+    }
+
+    public class Break extends Linear { }
+
+    public class Deliver extends Linear implements UsesData { }
+    public class Recv    extends Linear implements UsesData { } // is marked killable if any torpedo "points at" it
+    public class Collect extends Linear { }
+    public class Send    extends Linear {
+        public Ship    dest;   // if null, then this is a "dispatch"
+        public boolean token;
+        public boolean torpedo;
+    }
+    */
+}
diff --git a/src/edu/berkeley/fleet/two/DockDescription.java b/src/edu/berkeley/fleet/two/DockDescription.java
new file mode 100644 (file)
index 0000000..eaf79d0
--- /dev/null
@@ -0,0 +1,37 @@
+package edu.berkeley.fleet.two;
+import edu.berkeley.fleet.api.*;
+import java.io.*;
+import java.util.*;
+
+/** NOT YET FINALIZED: A description of a dock on a ship */
+public class DockDescription {
+
+    private final ShipDescription ship;
+    private final String name;
+    private final boolean inbox;
+    private final boolean left;
+    private final HashMap<String,ShipDescription.Constant> constants = new HashMap<String,ShipDescription.Constant>();
+
+    DockDescription(ShipDescription ship, String name, boolean left, boolean inbox) {
+        this.left = left;
+        this.ship = ship;
+        this.name = name;
+        this.inbox = inbox;
+    }
+
+    public String  getName() { return name; }
+    public boolean isInputDock() { return inbox; }
+    public boolean isOutputDock() { return !inbox; }
+
+    /** Indicates if this dock should be drawn on the "left hand side" of the ship for visual purposes */
+    boolean isLeft() { return left; }
+
+    /** Searches the dock-specific constants first, then ship-wide constants */
+    public ShipDescription.Constant getConstant(String name) {
+        ShipDescription.Constant ret = constants.get(name);
+        if (ret == null) ret = ship.getConstant(name);
+        return ret;
+    }
+
+    void addConstant(String s, ShipDescription.Constant c) { constants.put(s, c); }
+}
diff --git a/src/edu/berkeley/fleet/two/FleetTwoDock.java b/src/edu/berkeley/fleet/two/FleetTwoDock.java
new file mode 100644 (file)
index 0000000..5b7807a
--- /dev/null
@@ -0,0 +1,24 @@
+package edu.berkeley.fleet.two;
+import edu.berkeley.fleet.api.*;
+import java.util.*;
+
+/** A dock on a ship */
+public abstract class FleetTwoDock extends Dock {
+
+    private final DockDescription dockDescription;
+
+    public FleetTwoDock(Ship ship, DockDescription dockDescription) {
+        super(ship);
+        this.dockDescription = dockDescription;
+    }
+
+    public String getName() { return dockDescription.getName(); }
+
+    public ShipDescription.Constant getConstant(String s) { return dockDescription.getConstant(s); }
+
+    public boolean isInputDock() { return dockDescription.isInputDock(); }
+
+    public boolean isOutputDock() { return !dockDescription.isInputDock(); }
+
+
+}            
diff --git a/src/edu/berkeley/fleet/two/FleetTwoShip.java b/src/edu/berkeley/fleet/two/FleetTwoShip.java
new file mode 100644 (file)
index 0000000..5a89616
--- /dev/null
@@ -0,0 +1,33 @@
+package edu.berkeley.fleet.two;
+import edu.berkeley.fleet.api.*;
+import java.util.*;
+
+/** A ship in a Fleet; each ship consists of a collection of <tt>Dock</tt>s */
+public abstract class FleetTwoShip extends Ship {
+
+    protected final ShipDescription shipDescription;
+
+    public FleetTwoShip(Fleet fleet, ShipDescription shipDescription) {
+        super(fleet);
+        this.shipDescription = shipDescription;
+    }
+
+    /** returns the type of the ship ("Fetch", "ALU", etc) */
+    public String getType() { return shipDescription.getName(); }
+
+    public Dock getDock(String s) {
+        for(Dock b : this)
+            if (b.getName().equals(s))
+                return b;
+        throw new RuntimeException("unknown port \""+getType()+"."+s+"\"");
+    }
+
+    public int getOrdinal() {
+        int ord = 0;
+        for(Ship s : getFleet()) {
+            if (s==this) return ord;
+            if (s.getType() != null && s.getType().equals(getType())) ord++;
+        }
+        throw new RuntimeException("inconsistency: Ship does not belong to its own Fleet!");
+    }
+}
diff --git a/src/edu/berkeley/fleet/two/ShipDescription.java b/src/edu/berkeley/fleet/two/ShipDescription.java
new file mode 100644 (file)
index 0000000..13d56de
--- /dev/null
@@ -0,0 +1,211 @@
+package edu.berkeley.fleet.two;
+import edu.berkeley.fleet.api.*;
+import java.io.*;
+import java.util.*;
+
+/** NOT YET FINALIZED: A description (specification) of a ship */
+public class ShipDescription implements Iterable<DockDescription> {
+
+    private String name;
+    private LinkedHashMap<String,DockDescription> docks     = new LinkedHashMap<String,DockDescription>();
+    private HashMap<String,String>                sections  = new HashMap<String,String>();
+    private HashMap<String,Constant>              constants = new HashMap<String,Constant>();
+
+    public String getName() { return name; }
+    public String getSection(String sectionName) { return sections.get(sectionName); }
+    public DockDescription getDockDescription(String name) { return docks.get(name); }
+    public Iterator<DockDescription> iterator() { return docks.values().iterator(); }
+
+    public ShipDescription(String name, BufferedReader r) throws IOException {
+        this.name = name;
+        String sectionName = null;
+        StringBuffer sb = new StringBuffer();
+        while(true) {
+            String s = r.readLine();
+            if (s==null || s.startsWith("==")) {
+                if (sectionName != null) sections.put(sectionName, sb.toString());
+                if (s==null) break;
+                sb = new StringBuffer();
+                sectionName = s.trim();
+                while(sectionName.startsWith("="))
+                    sectionName = sectionName.substring(1);
+                while(sectionName.endsWith("="))
+                    sectionName = sectionName.substring(0, sectionName.length()-1);
+                sectionName = sectionName.trim().toLowerCase();
+                continue;
+            }
+            sb.append(s+"\n");
+        }
+        for(String s : sections.keySet())
+            processSection(s);
+    }
+
+    public Constant getConstant(String name) {
+        return constants.get(name);
+    }
+
+    private void processSection(String section) throws IOException {
+        if (section.equals("")) {
+            BufferedReader br = new BufferedReader(new StringReader(sections.get(section)));
+            for(String s = br.readLine(); s != null; s = br.readLine()) {
+                if (s.trim().length()==0) continue;
+                String key = s.substring(0, s.indexOf(':')).trim();
+                String val = s.substring(s.indexOf(':')+1).trim();
+                if (key.toLowerCase().equals("ship"))
+                    name = val.trim();
+            }
+        } else if (section.equals("constants")) {
+            BufferedReader br = new BufferedReader(new StringReader(sections.get(section)));
+            for(String s = br.readLine(); s != null; s = br.readLine()) {
+                if (s.indexOf(':')==-1) continue;
+                String key = s.substring(0, s.indexOf(':')).trim();
+                if (key.startsWith("constant")) {
+                    String constname = key.substring("constant".length()+1).trim();
+                    String val       = s.substring(s.indexOf(':')+1).trim();
+                    constants.put(constname, new Constant(val));
+                }
+            }
+        } else if (section.equals("ports")) {
+            BufferedReader br = new BufferedReader(new StringReader(sections.get(section)));
+            boolean rightSide = false;
+            DockDescription p = null;
+            for(String s = br.readLine(); s != null; s = br.readLine()) {
+                if (s.trim().length()==0) { rightSide = true; continue; }
+
+                String key = s.substring(0, s.indexOf(':')).trim();
+                boolean inbox = false;
+                key = key.replaceAll("  +", " ");
+                if      (key.equals("data in"))   { inbox = true;  }
+                else if (key.equals("data out"))  { inbox = false; }
+                else if (key.equals("in"))        { inbox = true;  }
+                else if (key.equals("out"))       { inbox = false; }
+                else if (key.startsWith("constant")) {
+                    String constname = key.substring("constant".length()+1).trim();
+                    String val       = s.substring(s.indexOf(':')+1).trim();
+                    p.addConstant(constname, new Constant(val));
+                    continue;
+                } else if (key.startsWith("shortcut to")) {
+                    continue;
+                }
+                else throw new RuntimeException("unknown port type: \""+key+"\"");
+
+                p = null;
+                String val = s.substring(s.indexOf(':')+1).trim();
+                String boxname = val.indexOf('.') != -1 ? val.substring(0, val.indexOf('.')) : val;
+                String dest    = val.indexOf('.') != -1 ? val.substring(val.indexOf('.')+1)  : "";
+                p = docks.get(boxname);
+                if (p==null) {
+                    p = new DockDescription(this, boxname, !rightSide, inbox);
+                    docks.put(boxname, p);
+                }
+            }
+        }
+    }
+
+    public void printTeX(PrintWriter pw) throws Exception {
+        ShipDescription sd = this;
+        pw.println("\\pagebreak");
+        pw.println("\\section*{The {\\tt "+sd.getName()+"} Ship}");
+        pw.println("\\addcontentsline{toc}{subsection}{"+sd.getName()+"}");
+        String tex = sd.getSection("tex");
+        /*
+        for(DockDescription bbd : sd) {
+            pw.println("{\\bf "+(bbd.isInputDock() ? "Input: " : "Output: ")+"{\\tt "+bbd.getName()+"}}\n\n");
+        }
+        */
+        int boxGap = 5;
+        int boxHeight = 25;
+        int boxWidth = 75;
+
+        int leftSize = 0;
+        int rightSize = 0;
+        for(DockDescription bbd : sd)
+            if (bbd.isLeft()) leftSize += (boxHeight+boxGap);
+            else              rightSize += (boxHeight+boxGap);
+
+        int totalHeight = Math.max(leftSize, rightSize);
+        int shipWidth = (int)(boxWidth * 1.5);
+        int totalWidth = boxGap*2 + boxWidth*2 + shipWidth;
+
+        pw.println("");
+        pw.println("\\begin{center}");
+        pw.println("\\begin{empfile}["+sd.getName()+"]");
+        pw.println("\\begin{emp}["+sd.getName()+"]("+(totalWidth+10)+","+(totalHeight+10)+")");
+        pw.println("  beginfig(1)");
+        pw.println("      pickup pencircle scaled 1pt;");
+        pw.println("      draw "+
+                   "("+((totalWidth-shipWidth)/2)+","+0+")--"+
+                   "("+((totalWidth-shipWidth)/2)+","+totalHeight+")--"+
+                   "("+(totalWidth-((totalWidth-shipWidth)/2))+","+totalHeight+")--"+
+                   "("+(totalWidth-((totalWidth-shipWidth)/2))+","+0+")--"+
+                   "("+((totalWidth-shipWidth)/2)+","+0+");");
+        int left = 0;
+        int right = 0;
+        for(DockDescription bbd : sd) {
+            int ypos = (totalHeight - (boxGap/2) - (bbd.isLeft() ? left : right));
+            int half = (totalWidth-shipWidth)/2;
+            int p1 = bbd.isLeft() ? (half-5) : ((totalWidth-half)+5);
+            int p3 = bbd.isLeft() ? (p1 - boxWidth) : (p1 + boxWidth);
+            if (bbd.isInputDock()) {
+                int p1x = p1;
+                p1 = p3;
+                p3 = p1x;
+            }
+            boolean goo = ((bbd.isLeft() && bbd.isInputDock()) || (!bbd.isLeft() && bbd.isOutputDock()));
+            int p2 = goo ? (p3 - (boxHeight/2)) : (p3 + (boxHeight/2));
+            if (bbd.isLeft()) left += (boxHeight+boxGap);
+            else              right += (boxHeight+boxGap);
+            if (goo) {
+                pw.println("      label.rt(btex \\tt "+bbd.getName()+" etex, ("+(p1+3)+","+(ypos-boxHeight/2)+"));");
+            } else {
+                pw.println("      label.lft(btex \\tt "+bbd.getName()+" etex, ("+(p1-3)+","+(ypos-boxHeight/2)+"));");
+            }
+            pw.println("      draw "+
+                       "  ("+p1+","+ypos+")--"+
+                       "  ("+p2+","+ypos+")--"+
+                       "  ("+p3+","+(ypos-(boxHeight/2))+")--"+
+                       "  ("+p2+","+(ypos-boxHeight)+")--"+
+                       "  ("+p1+","+(ypos-boxHeight)+")--"+
+                       "  ("+p1+","+ypos+");");
+            if (bbd.isLeft()) leftSize += boxHeight;
+            else              rightSize += boxHeight;
+        }
+        pw.println("  endfig;");
+        pw.println("\\end{emp}");
+        pw.println("\\end{empfile}");
+        pw.println("\\end{center}");
+        pw.println("");
+
+        if (tex!=null)
+            pw.println(tex);
+    }
+
+    public class Constant {
+        public long    setbits   = 0;
+        public long    clearbits = 0;
+        public boolean signExtend = false;
+        public int     numberOffset = 0;
+        public int     numberWidth = 0;
+        public Constant(String s) {
+            if (s.startsWith("0x")) {
+                setbits = Long.parseLong(s.substring(2), 16);
+                clearbits = ~setbits;
+            } else if (s.length() == 37) {
+                for(int i=36; i>=0; i--) {
+                    char c = s.charAt(36-i);
+                    switch(c) {
+                        case '0': clearbits |= (1<<i); break;
+                        case '1': setbits   |= (1<<i); break;
+                        case '.': break;
+                        case 's': signExtend = true;  numberOffset = i; numberWidth++; break;
+                        case 'u': signExtend = false; numberOffset = i; numberWidth++; break;
+                    }
+                }
+            } else {
+                setbits = Long.parseLong(s);
+                clearbits = ~setbits;
+            }
+        }
+    }
+
+}
index 9bd98d4..3ce48c3 100644 (file)
@@ -48,4 +48,4 @@ public class BitManipulations {
             throw new RuntimeException("bitfield width exceeded");
         return doPutField(highBit, lowBit, val);
     }
-}
\ No newline at end of file
+}
index 6b9d7e0..769b708 100644 (file)
@@ -9,17 +9,32 @@ public class Mask {
     public final long val;
     public final long valmask;
     public final int valmaskmin;
+    public final int valmaskmax;
+    public final int valmaskwidth;
+    public final int allmax;
+    public final int width;
 
     public String verilog(String var) {
-        return "(("+var+" & "+mask+")=="+val+")";
+        // FIXME: throw an exception if this is called when no 1-bits or 0-bits were specified (ie only v-bits)
+        return "(("+var+" & "+allmax+"'b"+Long.toString(mask,2)+")=="+allmax+"'b"+Long.toString(val,2)+")";
     }
     public String verilogVal(String var) {
-        return "(("+var+" & "+valmask+") >> "+valmaskmin+")";
+        //return "(("+var+" & "+allmax+"'b"+Long.toString(valmask,2)+") >> "+valmaskmin+")";
+        return ""+var+"["+valmaskmax+":"+valmaskmin+"]";
     }
 
     public long getval(long in) {
         return (in & valmask) >>> valmaskmin;
     }
+    public long setval(long in, BitVector targ) {
+        long ret = 0;
+        for(int i=0; i<targ.length(); i++)
+            if (targ.get(i))
+                ret |= (1L << i);
+        if (targ.get(targ.length()-1))
+            ret |= (-1L << targ.length());
+        return setval(in, ret);
+    }
     public long setval(long in, long targ) {
         if (((targ << valmaskmin) & ~valmask) != 0) throw new RuntimeException("setval() with argument bigger than mask field");
         return (in & ~valmask) | ((targ << valmaskmin) & valmask);
@@ -46,20 +61,27 @@ public class Mask {
         long valmask = 0;
         long val = 0;
         int valmaskmin = Integer.MAX_VALUE;
+        int valmaskmax = 0;
+        int allmax = 0;
+        this.width = s.length();
         for(int i=0; i<s.length(); i++) {
             char c = s.charAt(s.length()-1-i);
             switch(c) {
                 case '.': break;
-                case '0': mask |= (1<<i); val |= (0<<i); break;
-                case '1': mask |= (1<<i); val |= (1<<i); break;
-                case 'v': valmask |= (1<<i); valmaskmin = Math.min(valmaskmin,i);            break;
+                case '0': mask |= (1L<<i); val |= (0L<<i); break;
+                case '1': mask |= (1L<<i); val |= (1L<<i); break;
+                case 'v': valmask |= (1L<<i); valmaskmin = Math.min(valmaskmin,i); valmaskmax = Math.max(valmaskmax,i); break;
                 default: throw new Error(""+c);
             }
+            if (c!='.') allmax = Math.max(allmax,i);
         }
         this.mask = mask;
         this.val = val;
         this.valmask = valmask;
         this.valmaskmin = valmaskmin;
+        this.valmaskmax = valmaskmax;
+        this.allmax = allmax+1;
+        this.valmaskwidth = 1 + valmaskmax - valmaskmin;
     }
 
     public static long signExtend(long input, int wordWidth) {
@@ -68,4 +90,4 @@ public class Mask {
         return input;
     }
 
-}
\ No newline at end of file
+}