massive overhaul of FleetCode to support multiple destinations (and major cleanup)
authoradam <adam@megacz.com>
Thu, 22 Feb 2007 15:31:28 +0000 (16:31 +0100)
committeradam <adam@megacz.com>
Thu, 22 Feb 2007 15:31:28 +0000 (16:31 +0100)
38 files changed:
src/edu/berkeley/fleet/Main.java
src/edu/berkeley/fleet/assembler/Parser.java
src/edu/berkeley/fleet/assembler/fleet.g
src/edu/berkeley/fleet/doc/BenkoBoxDescription.java [new file with mode: 0644]
src/edu/berkeley/fleet/doc/ShipDescription.java
src/edu/berkeley/fleet/interpreter/CodeBag.java [deleted file]
src/edu/berkeley/fleet/interpreter/DataInbox.java [deleted file]
src/edu/berkeley/fleet/interpreter/DataOutbox.java [deleted file]
src/edu/berkeley/fleet/interpreter/Dispatchable.java [deleted file]
src/edu/berkeley/fleet/interpreter/Inbox.java
src/edu/berkeley/fleet/interpreter/InstructionBenkoBox.java [new file with mode: 0644]
src/edu/berkeley/fleet/interpreter/InstructionPort.java [deleted file]
src/edu/berkeley/fleet/interpreter/Interpreter.java
src/edu/berkeley/fleet/interpreter/InterpreterBenkoBox.java
src/edu/berkeley/fleet/interpreter/InterpreterDestination.java [new file with mode: 0644]
src/edu/berkeley/fleet/interpreter/InterpreterShip.java
src/edu/berkeley/fleet/interpreter/Log.java
src/edu/berkeley/fleet/interpreter/Main.java [deleted file]
src/edu/berkeley/fleet/interpreter/Outbox.java
src/edu/berkeley/fleet/interpreter/Packet.java [new file with mode: 0644]
src/edu/berkeley/fleet/interpreter/TokenInbox.java [deleted file]
src/edu/berkeley/fleet/interpreter/TokenOutbox.java [deleted file]
src/edu/berkeley/fleet/interpreter/ships/ArithmeticShip.java [deleted file]
src/edu/berkeley/fleet/interpreter/ships/Counter.java [deleted file]
src/edu/berkeley/fleet/interpreter/ships/DeMux.java [deleted file]
src/edu/berkeley/fleet/interpreter/ships/Dup.java [deleted file]
src/edu/berkeley/fleet/interpreter/ships/Dup3.java [deleted file]
src/edu/berkeley/fleet/interpreter/ships/DuplicatorShip.java [deleted file]
src/edu/berkeley/fleet/interpreter/ships/HomeworkCounter.java [deleted file]
src/edu/berkeley/fleet/interpreter/ships/MemoryReadShip.java [deleted file]
src/edu/berkeley/fleet/interpreter/ships/MemoryWriteShip.java [deleted file]
src/edu/berkeley/fleet/interpreter/ships/MultiplierShip.java [deleted file]
src/edu/berkeley/fleet/interpreter/ships/Mux.java [deleted file]
src/edu/berkeley/fleet/interpreter/ships/ScatterShip.java [deleted file]
src/edu/berkeley/fleet/interpreter/ships/Sort2.java [deleted file]
src/edu/berkeley/fleet/slipway/Slipway.java
src/edu/berkeley/fleet/slipway/SlipwayBenkoBox.java [new file with mode: 0644]
src/edu/berkeley/fleet/slipway/SlipwayShip.java [new file with mode: 0644]

index 24b09b2..e213d11 100644 (file)
@@ -40,7 +40,7 @@ public class Main {
         } else if ("sim".equals(target) || "fleetsim".equals(target)) {
             fleet = (Fleet)Class.forName("com.sunlabs.fleetsim.fleet.FleetDescription").newInstance();
         } else {
-            fleet = new Interpreter.DynamicInterpreter();
+            fleet = new Interpreter();
         }
 
         if (!"true".equals(options.get("verbose")))
index 2782870..98fbed3 100644 (file)
@@ -1,7 +1,5 @@
 package edu.berkeley.fleet.assembler;
-
 import edu.berkeley.fleet.api.*;
-
 import edu.berkeley.sbp.*;
 import edu.berkeley.sbp.chr.*;
 import edu.berkeley.sbp.misc.*;
@@ -62,13 +60,12 @@ public class Parser {
         // map from arbitrary identifiers to actual addresses
         int[] codeBagMap = new int[codeBags.size()];
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        CountingOutputStream cos   = new CountingOutputStream(baos);
-        DataOutputStream dos       = new DataOutputStream(cos);
+        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;//cos.getCount();
+            codeBagMap[i] = count;
             for(Instruction inst : c) {
                 fleet.writeInstruction(dos, inst);
                 count++;
@@ -76,8 +73,7 @@ public class Parser {
         }
 
         // now write for real
-        cos = new CountingOutputStream(out);
-        dos = new DataOutputStream(cos);
+        dos = new DataOutputStream(out);
         count = 0;
         for(int i=0; i<codeBags.size(); i++) {
             CodeBag c = codeBags.get(i);
@@ -85,7 +81,6 @@ public class Parser {
             for(Instruction inst : c) {
                 if (inst instanceof Instruction.Literal.CodeBagDescriptor) {
                     dos.flush();
-                    cos.getCount();
                     Instruction.Literal.CodeBagDescriptor old = (Instruction.Literal.CodeBagDescriptor)inst;
                     int offset = codeBagMap[(int)old.offset] - count;
                     inst = new Instruction.Literal.CodeBagDescriptor(old.dest,
@@ -97,7 +92,6 @@ public class Parser {
             }
         }
         dos.flush();
-        cos.flush();
         out.flush();
         out.close();
     }
@@ -142,14 +136,6 @@ public class Parser {
         } else if (head.equals("Expect")) {
             expect.add(Long.parseLong(string(t.child(0))));
 
-        } else if (head.equals("Memory")) {
-            if (((edu.berkeley.fleet.interpreter.Interpreter)fleet).mem.length != 0)
-                throw new RuntimeException("multiple memory directives found");
-            Tree<String> m = t.child(0);
-            int[] mem = new int[m.size()];
-            for(int i=0; i<mem.length; i++)
-                mem[i] = Integer.parseInt(string(m.child(i)));
-            ((edu.berkeley.fleet.interpreter.Interpreter)fleet).mem = mem;
         }
     }
 
@@ -165,16 +151,25 @@ public class Parser {
         return string(t.child(0))+string(t.child(1));
     }
 
-    BenkoBox portReference(Tree<String> t) {
-        if (!"Port".equals(t.head()) && !"ShipSpecificLiteral".equals(t.head())) return null;
+    Destination portReference(Tree<String> t) {
+        if (!"Port".equals(t.head()) && !"SubPort".equals(t.head()) && !"ShipSpecificLiteral".equals(t.head())) return null;
         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+"\"");
+        BenkoBox ret = null;
         for(BenkoBox b : ship.getBenkoBoxes())
-            if (b.getName().equals(portName))
-                return b;
-        throw new RuntimeException("no such benkobox \""+portName+"\" on ships of type \""+ship.getType()+"\"");
+            if (b.getName().equals(portName)) {
+                ret = b;
+            }
+        if (subPort != null)
+            for(Destination d : ret.getDestinations())
+                if (d.getDestinationName().equals(subPort))
+                    return d;
+        if (ret==null)
+            throw new RuntimeException("no such benkobox \""+portName+"\" on ships of type \""+ship.getType()+"\"");
+        return ret;
     }
 
     private HashMap<String,Integer> numAllocated = new HashMap<String,Integer>();
@@ -214,22 +209,19 @@ public class Parser {
                 }
             }
             long literal = chosenship.resolveLiteral(portName);
-            BenkoBox benkobox = portReference(t.child(1));
-            cb.add(new Instruction.Literal.Absolute(benkobox, literal));
+            cb.add(new Instruction.Literal.Absolute(portReference(t.child(1)), literal));
 
         } else if (t.head().equals("Literal")) {
-            int literal = Integer.parseInt(string(t.child(0)));
-            BenkoBox benkobox = portReference(t.child(1));
-            cb.add(new Instruction.Literal.Absolute(benkobox, literal));
+            long literal = Long.parseLong(string(t.child(0)));
+            cb.add(new Instruction.Literal.Absolute(portReference(t.child(1)), literal));
 
         } else if (t.head().equals("CodeBagDescriptor")) {
             String refname = name(t.child(0).child(0));
             CodeBag cb2 = getCodeBag(refname);
-            BenkoBox benkobox = portReference(t.child(1));
-            cb.add(new Instruction.Literal.CodeBagDescriptor(benkobox, cb2.getFakeAddress(), 0));
+            cb.add(new Instruction.Literal.CodeBagDescriptor(portReference(t.child(1)), cb2.getFakeAddress(), 0));
 
         } else if (t.head().equals("Fiber")) {
-            BenkoBox benkobox = portReference(t.child(0));
+            BenkoBox benkobox = (BenkoBox)portReference(t.child(0));
             
             OUTER: for(Tree tt : t.child(1)) {
                 int count = 1;
@@ -257,7 +249,7 @@ public class Parser {
                 boolean latch = false;
                 boolean dataOut = false;
                 boolean tokenOut = false;
-                BenkoBox dest = null;
+                Destination dest = null;
                 for(int i=0; i<ttx.size(); i++) {
                     Tree ttt = ttx.child(i);
                     if      ("Wait".equals(ttt.head()))    { tokenIn = true; }
@@ -282,22 +274,8 @@ public class Parser {
         }
     }
 
-    private static class CountingOutputStream extends FilterOutputStream {
-        public CountingOutputStream(OutputStream os) { super(os); }
-        int count = 0;
-        public int getCount() { return count; }
-        public void write(int b) throws IOException {
-            super.write(b);
-            count++;
-        }
-        public void write(byte[] b, int off, int len) throws IOException {
-            super.write(b, off, len);
-            count += len;
-        }
-    }
-
     private class CodeBag extends ArrayList<Instruction> {
-        public int address = -1;
+        public long address = -1;
         public CodeBag() { codeBags.add(this); }
         public CodeBag(String name) { this(); codeBagsByName.put(name, this); }
         public long getFakeAddress() { return codeBags.indexOf(this); }
index d406c3d..8262356 100644 (file)
@@ -41,6 +41,7 @@ Source         = Port
 
 SSL            = ShipSpecificLiteral:: shiptype "." ShipSpecificLiteral
 Port           = Port::     shipname "." portname
+               | SubPort::  shipname "." portname "." portname
                |           ^"()"
 
 CodeBagBody    = Statement +/ ws
diff --git a/src/edu/berkeley/fleet/doc/BenkoBoxDescription.java b/src/edu/berkeley/fleet/doc/BenkoBoxDescription.java
new file mode 100644 (file)
index 0000000..6a01297
--- /dev/null
@@ -0,0 +1,32 @@
+package edu.berkeley.fleet.doc;
+
+import java.io.*;
+import java.util.*;
+
+public class BenkoBoxDescription implements Iterable<String> {
+
+    public String getName() { return name; }
+    public boolean isInbox() { return inbox; }
+    public boolean isOutbox() { return !inbox; }
+    public boolean tokensOnly() { return tokenOnly; }
+    public Iterator<String> iterator() { return destinations.iterator(); }
+
+    // private //////////////////////////////////////////////////////////////////////////////
+
+    private final ShipDescription ship;
+    private final String name;
+    private final boolean inbox;
+    private final boolean tokenOnly;
+    private ArrayList<String> destinations = new ArrayList<String>();
+
+    BenkoBoxDescription(ShipDescription ship, String name, boolean tokenOnly, boolean inbox) {
+        this.ship = ship;
+        this.name = name;
+        this.inbox = inbox;
+        this.tokenOnly = tokenOnly;
+        ship.add(this);
+    }
+
+    void addDest(String dest) { destinations.add(dest); }
+
+}
index f32b7ab..facafce 100644 (file)
@@ -3,25 +3,12 @@ package edu.berkeley.fleet.doc;
 import java.io.*;
 import java.util.*;
 
-public class ShipDescription {
+/** the Java representation of a .ship file */
+public class ShipDescription implements Iterable<BenkoBoxDescription> {
 
-    public String name;
-    public String texDocumentation;
-    public ArrayList<BenkoBox> benkoBoxes = new ArrayList<BenkoBox>();
-
-    public HashMap<String,String> sections =
-        new HashMap<String,String>();
-
-    public class BenkoBox {
-        public boolean inbox;
-        public boolean tokenOnly;
-        public boolean leftSide;
-        public String[] ports;
-    }
-
-    public class Literal {
-        public String name;
-    }
+    public String getName() { return name; }
+    public String getSection(String sectionName) { return sections.get(sectionName); }
+    public Iterator<BenkoBoxDescription> iterator() { return benkoBoxes.iterator(); }
 
     public ShipDescription(BufferedReader r) throws IOException {
         String sectionName = "";
@@ -46,7 +33,17 @@ public class ShipDescription {
             processSection(s);
     }
 
-    public void processSection(String section) throws IOException {
+    // private //////////////////////////////////////////////////////////////////////////////
+
+    private String name;
+    private String texDocumentation;
+
+    // must keep proper ordering for FPGA (FIXME: should alphabetize when synthesizing)
+    private ArrayList<BenkoBoxDescription> benkoBoxes = new ArrayList<BenkoBoxDescription>();
+
+    private HashMap<String,String> sections = new HashMap<String,String>();
+
+    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()) {
@@ -61,23 +58,29 @@ public class ShipDescription {
             boolean rightSide = false;
             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();
-                String val = s.substring(s.indexOf(':')+1).trim();
-                BenkoBox p = new BenkoBox();
+                boolean tokenOnly = false;
+                boolean inbox = false;
                 key = key.replaceAll("  +", " ");
-                if      (key.equals("token in"))  { p.tokenOnly = true;   p.inbox = true;  }
-                else if (key.equals("token out")) { p.tokenOnly = true;   p.inbox = false; }
-                else if (key.equals("data in"))   { p.tokenOnly = false;  p.inbox = true;  }
-                else if (key.equals("data out"))  { p.tokenOnly = false;  p.inbox = false; }
+                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 throw new RuntimeException("unknown port type: \""+key+"\"");
-                StringTokenizer st = new StringTokenizer(val, " ");
-                p.ports = new String[st.countTokens()];
-                for(int i=0; i<p.ports.length; i++)
-                    p.ports[i] = st.nextToken();
-                p.leftSide = !rightSide;
-                benkoBoxes.add(p);
+
+                String val = s.substring(s.indexOf(':')+1).trim();
+                BenkoBoxDescription p = null;
+                String boxname = val.indexOf('.') != -1 ? val.substring(0, val.indexOf('.')) : val;
+                String dest    = val.indexOf('.') != -1 ? val.substring(val.indexOf('.')+1)  : "";
+                for (BenkoBoxDescription b : benkoBoxes)
+                    if (b.getName().equals(boxname)) { p = b; break; }
+                if (p==null) p = new BenkoBoxDescription(this, boxname, tokenOnly, inbox);
+                p.addDest(dest);
             }
         }
     }
 
+    void add(BenkoBoxDescription b) { benkoBoxes.add(b); }
+
 }
\ No newline at end of file
diff --git a/src/edu/berkeley/fleet/interpreter/CodeBag.java b/src/edu/berkeley/fleet/interpreter/CodeBag.java
deleted file mode 100644 (file)
index 41ef0bf..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-package edu.berkeley.fleet.interpreter;
-import edu.berkeley.fleet.api.*;
-import edu.berkeley.fleet.api.Instruction;
-
-import java.util.*;
-import java.io.*;
-
-/** a codebag */
-public class CodeBag {
-
-    private static int max_allocated_descriptor = 1;
-    private static HashMap<Integer,CodeBag> codeBagsByDescriptor = new HashMap<Integer,CodeBag>();
-
-    public static CodeBag getCodeBagByDescriptor(int descriptor) {
-        return codeBagsByDescriptor.get(descriptor);
-    }
-
-    private final int descriptor;
-    private final CodeBag parent;
-    private final String name;
-    private ArrayList<Instruction> dispatchables = new ArrayList<Instruction>();
-    private HashMap<String,CodeBag> codeBags = new HashMap<String,CodeBag>();
-
-    public CodeBag(CodeBag parent, String name) {
-        this.parent = parent;
-        this.name = name;
-        this.descriptor = max_allocated_descriptor++;
-        codeBagsByDescriptor.put(descriptor, this);
-        if (parent != null && name != null)
-            parent.add(name, this);
-    }
-
-    public void dispatch(Fleet fleet) {
-        /*
-        for(Instruction d : dispatchables) {
-            Log.dispatch(d);
-            ((Interpreter)fleet).dispatch(d);
-        }
-        */
-        throw new RuntimeException();
-    }
-
-    public void add(Instruction instr) {
-        dispatchables.add(instr);
-    }
-
-    public void add(String name, CodeBag instr) {
-        codeBags.put(name, instr);
-    }
-
-    public int getDescriptor() {
-        return descriptor;
-    }
-
-    public CodeBag getCodeBag(String name) {
-        CodeBag ret = codeBags.get(name);
-        if (ret != null) return ret;
-        if (parent==null) return null;
-        return parent.getCodeBag(name);
-    }
-
-    public void dump(Fleet fleet) throws Exception {
-        DataOutputStream os = new DataOutputStream(new FileOutputStream("fleet.bin"));
-        for(Instruction i : dispatchables) 
-            fleet.writeInstruction(os, i);
-        os.flush();
-        os.close();
-    }
-
-    public String toString() {
-        if (name != null) return name;
-        StringBuffer ret = new StringBuffer();
-        for(Instruction d : dispatchables) {
-            ret.append(d);
-            ret.append("\n");
-        }
-        for(String n : codeBags.keySet()) {
-            ret.append(n + ": ");
-            ret.append(codeBags.get(n));
-            ret.append("\n");
-        }
-        return "{\n  "+Log.indent(ret.toString(), "  ")+"\n}";
-    }
-
-
-}
diff --git a/src/edu/berkeley/fleet/interpreter/DataInbox.java b/src/edu/berkeley/fleet/interpreter/DataInbox.java
deleted file mode 100644 (file)
index 869a734..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-package edu.berkeley.fleet.interpreter;
-import edu.berkeley.fleet.api.*;
-
-import java.util.*;
-
-public class DataInbox extends Inbox {
-
-    public DataInbox(InterpreterShip ship, String name) {
-        super(ship, name);
-    }
-    public DataInbox(InterpreterShip ship, String name, boolean special) {
-        super(ship, name);
-        this.special = special;
-    }
-
-    void addDataFromFabric(int data) {
-        addItemFromFabric(data);
-    }
-
-    public boolean dataReadyForShip() {
-        return super.itemReadyForShip();
-    }
-
-    public int removeDataForShip() {
-        return super.accept();
-    }
-
-}
diff --git a/src/edu/berkeley/fleet/interpreter/DataOutbox.java b/src/edu/berkeley/fleet/interpreter/DataOutbox.java
deleted file mode 100644 (file)
index 0292499..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-package edu.berkeley.fleet.interpreter;
-import edu.berkeley.fleet.api.*;
-
-public class DataOutbox extends Outbox {
-
-    public DataOutbox(InterpreterShip ship, String name) { super(ship, name); }
-    public DataOutbox(InterpreterShip ship, String name, boolean special) {
-        super(ship, name); this.special = special; }
-    public DataOutbox(InterpreterShip ship, String name, boolean special, boolean ihorn) {
-        super(ship, name); this.special = special; this.ihorn = ihorn; }
-    public DataOutbox(InterpreterShip ship, String name, boolean special, boolean ihorn, boolean dhorn) {
-        super(ship, name); this.special = special; this.ihorn = ihorn; this.dhorn = dhorn; }
-
-    private Interpreter getInterpreter() { return ((InterpreterShip)getShip()).getInterpreter(); }
-    public void addDataFromShip(int data) {
-        addItemFromShip(data);
-    }
-
-    public boolean readyForDataFromShip() {
-        return super.readyForItemFromShip();
-    }
-
-    protected void send(InterpreterBenkoBox port, int data) {
-        getInterpreter().sendData(this, data, port);
-    }
-}
diff --git a/src/edu/berkeley/fleet/interpreter/Dispatchable.java b/src/edu/berkeley/fleet/interpreter/Dispatchable.java
deleted file mode 100644 (file)
index e73572c..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-package edu.berkeley.fleet.interpreter;
-import edu.berkeley.fleet.api.*;
-
-public abstract class Dispatchable {
-    public abstract void dispatch(Fleet fleet);
-}
index 85c3fd4..a1e4769 100644 (file)
@@ -1,57 +1,45 @@
 package edu.berkeley.fleet.interpreter;
 import edu.berkeley.sbp.util.ANSI;
 import edu.berkeley.fleet.api.*;
-import edu.berkeley.fleet.api.Instruction;
-
 import java.util.*;
 
 /** this is a generic inbox which stores <32-bit items (tokens or data) */
-public class Inbox extends InstructionPort {
+public class Inbox extends InstructionBenkoBox {
+
+    public boolean dataReadyForShip()            { return itemReadyForShip; }
+    public Packet removePacketForShip()          { remove(); return register; }
+    public Packet peekPacketForShip()            { return register; }
+    public long removeDataForShip()              { remove(); return register.value; }
 
     // private data //////////////////////////////////////////////////////////////////////////////
 
-    /** data which has arrived from the switch fabric but not been acted on */
-    private Queue<Integer> itemsFromFabric = new LinkedList<Integer>();
+    private Packet register = null;
 
-    /** a datum which has been presented to the ship */
-    //private int itemPresentedToShip;
+    /** data which has arrived from the switch fabric but not been acted on */
+    private Queue<Packet> itemsFromFabric = new LinkedList<Packet>();
 
     /** true iff data is currently being presented to the ship */
     private boolean itemReadyForShip = false;
 
     /** if an ack token is pending, this is where it should be sent once the item is accepted */
-    private InterpreterBenkoBox ackDestinationUponAccept;
+    private Packet bufferedAck = null;
 
+    public boolean isInbox() { return true; }
+    public boolean isOutbox() { return false; }
 
-    // protected methods /////////////////////////////////////////////////////////////////////////
-
-    Inbox(InterpreterShip ship, String name) { super(ship, name); }
-
-    /** subclasses invoke this when items arrive from the fabric */
-    protected final void addItemFromFabric(int data) {
-        itemsFromFabric.add(data);
-    }
+    public Inbox(InterpreterShip ship, String name)                 { super(ship, name, new String[] { "" }); }
+    public Inbox(InterpreterShip ship, String name, String[] ports) { super(ship, name, ports); }
 
-    /** true iff data is ready for the ship to accept */
-    protected final boolean itemReadyForShip() {
-        return itemReadyForShip;
-    }
-
-    private Interpreter getInterpreter() { return ((InterpreterShip)getShip()).getInterpreter(); }
-
-    /** accpets (removes) an item -- invoked by the ship */
-    protected final int accept() {
+    public void addDataFromFabric(Packet packet) { itemsFromFabric.add(packet); }
+    private void remove() {
         if (!itemReadyForShip)
             throw new RuntimeException("invoked accept() on an inbox which does not have items ready; your ship is buggy");
         itemReadyForShip = false;
-        if (ackDestinationUponAccept != null) {
-            getInterpreter().sendToken(this, ackDestinationUponAccept);
-            ackDestinationUponAccept = null;
-        }
-        return register;
+        if (bufferedAck != null) { bufferedAck.send(); bufferedAck = null; }
     }
 
-    int register = 0;
+    //////////////////////////////////////////////////////////////////////////////
+
     /** invoked by superclass */
     protected final boolean service(Instruction.Executable instruction) {
 
@@ -71,10 +59,11 @@ public class Inbox extends InstructionPort {
 
         // consume inbound data+token
         if (instruction.dataIn) {
-            if (instruction.latch)
+            if (instruction.latch) {
                 register = itemsFromFabric.remove();
-            else
+            } else {
                 itemsFromFabric.remove();
+            }
         }
 
         // if dataOut, present data to the ship
@@ -83,27 +72,23 @@ public class Inbox extends InstructionPort {
 
             // and make note of the fact that we need to send an ack (if requested)
             if (instruction.tokenOut)
-                ackDestinationUponAccept = (InterpreterBenkoBox)instruction.dest;
+                bufferedAck = new Packet(getInterpreter(), this, 0, (InterpreterBenkoBox)instruction.dest);
 
         } else if (instruction.tokenOut) {
 
             // if dataOut is not set, we can send the data immediately
-            getInterpreter().sendToken(this, (InterpreterBenkoBox)instruction.dest);
+            new Packet(getInterpreter(), this, 0, (InterpreterBenkoBox)instruction.dest).send();
         }
         return true;
     }
 
     protected void shutdown() {
-        /*
-        if (itemReadyForShip)
-            Log.println(Log.red(" WARNING: a datum ("+register+") was left in inbox " +
-                                this + " -- the ship has not consumed it"));
-        */              
         if (itemsFromFabric.size() > 0) {
             Log.println(ANSI.red(" WARNING: you left data on the input to inbox " + this + ":"));
-            for(int i : itemsFromFabric)
-                Log.println("  " + i);
+            for(Packet p : itemsFromFabric)
+                Log.println("  " + p.value);
         }
         super.shutdown(true);
     }
+
 }
diff --git a/src/edu/berkeley/fleet/interpreter/InstructionBenkoBox.java b/src/edu/berkeley/fleet/interpreter/InstructionBenkoBox.java
new file mode 100644 (file)
index 0000000..2ff5f1b
--- /dev/null
@@ -0,0 +1,88 @@
+package edu.berkeley.fleet.interpreter;
+import edu.berkeley.sbp.util.ANSI;
+import edu.berkeley.fleet.api.*;
+import edu.berkeley.fleet.api.Instruction;
+
+import java.util.*;
+
+/** anything that has a source (instruction horn) address on the switch fabric */
+abstract class InstructionBenkoBox extends InterpreterBenkoBox {
+
+    /** the currently executing instruction */
+    private Instruction.Executable executing = null;
+
+    /** all instructions waiting to be executed (excludes executing) */
+    private Queue<Instruction.Executable> instructions = new LinkedList<Instruction.Executable>();
+
+    /** count of how many "standing instruction only" kills remain to be executed */
+    private int killNextStandingInstruction = 0;
+
+    InstructionBenkoBox(InterpreterShip ship, String name, String[] ports) {
+        super(ship, name, ports);
+    }
+
+    public void kill(int count, boolean killOnlyStandingInstructions) {
+        if (count==0) return;
+        if (!killOnlyStandingInstructions) {
+            if (executing != null) { executing = null; count--; }
+            for(;count > 0;count--) {
+                if (instructions.size()==0)
+                    throw new RuntimeException("deadlocked " + this + " by killing too many instructions");
+                instructions.remove();
+            }
+        } else {
+            if (count != 1) throw new RuntimeException("this should never happen");
+            this.killNextStandingInstruction++;
+        }
+    }
+
+    /** an instruction arrives from the instruction horn */
+    void addInstruction(Instruction.Executable instr) {
+        if (killNextStandingInstruction > 0) { /* FIXME technically we should refuse to take the next instruction here */ }
+        instructions.add(instr);
+    }
+
+    protected void shutdown(boolean leaveAsInbox) {
+        if (!(executing != null || instructions.size() > 0)) return;
+        Log.println(ANSI.red(" WARNING: you left instructions on the instruction queue of port " +
+                             this + "; they are:"));
+        if (executing != null)
+            Log.println("   " + executing);
+        for(Instruction.Executable i : instructions)
+            Log.println("   " + i);
+    }
+
+    // interface to subclass ///////////////////////////////////////////////////////////////////////
+
+    /** this will be invoked periodically; should return true to "consume" an instruction, false to leave it executing */
+    protected abstract boolean service(Instruction.Executable instr);
+
+    protected final void service() {
+        if (executing == null)
+            if (instructions.size() > 0)
+                executing = instructions.remove();
+            else
+                return;
+
+        if (executing != null && killNextStandingInstruction>0 && executing.isStanding()) {
+            executing = null;
+            killNextStandingInstruction--;
+            return;
+        }
+
+        boolean ret = service(executing);
+        if (!ret) return;
+        if (executing.recycle) {
+            executing = executing.decrementCount();
+            if (executing != null)
+                addInstruction(executing);
+            executing = null;
+
+        } else {
+            if (executing != null && !executing.isStanding())
+                executing = executing.decrementCount();
+        }
+    }
+
+
+}
diff --git a/src/edu/berkeley/fleet/interpreter/InstructionPort.java b/src/edu/berkeley/fleet/interpreter/InstructionPort.java
deleted file mode 100644 (file)
index 0ff6925..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-package edu.berkeley.fleet.interpreter;
-import edu.berkeley.sbp.util.ANSI;
-import edu.berkeley.fleet.api.*;
-import edu.berkeley.fleet.api.Instruction;
-
-import java.util.*;
-
-/** anything that has a source (instruction horn) address on the switch fabric */
-public abstract class InstructionPort extends InterpreterBenkoBox {
-
-    /** the currently executing instruction */
-    Instruction.Executable currentlyExecuting = null;
-
-    /** all instructions waiting to be executed (excludes currentlyExecuting) */
-    Queue<Instruction.Executable> instructions = new LinkedList<Instruction.Executable>();
-
-    /** the count field of currentlyExecuting, taking into account actions already performed */
-    int currentlyExecutingCount;
-
-    InstructionPort(InterpreterShip ship, String name) {
-        super(ship, name);
-    }
-
-    int killCount = 0;
-    boolean killOnlyStandingInstructions = false;
-
-    public void kill(int count, boolean killOnlyStandingInstructions) {
-        if (killCount > 0 && killOnlyStandingInstructions != this.killOnlyStandingInstructions)
-            throw new RuntimeException("you mixed kill and kill*");
-        killCount += count;
-        this.killOnlyStandingInstructions = killOnlyStandingInstructions;
-    }
-
-    /** an instruction arrives from the instruction horn */
-    void addInstruction(Instruction.Executable instr) {
-        if (killCount > 0)
-            throw new RuntimeException("you tried to add an instruction to a BenkoBox that hadn't finished a kill yet");
-        instructions.add(instr);
-    }
-
-    protected void shutdown(boolean leaveAsInbox) {
-        if (currentlyExecuting != null || instructions.size() > 0) {
-            Log.println(ANSI.red(" WARNING: you left instructions on the instruction queue of port " +
-                                this + "; they are:"));
-            if (currentlyExecuting != null)
-                Log.println("   " + currentlyExecuting);
-            for(Instruction.Executable i : instructions)
-                Log.println("   " + i);
-        }
-    }
-
-    // interface to subclass ///////////////////////////////////////////////////////////////////////
-
-    /** this will be invoked periodically; should return true to "consume" an instruction, false to leave it executing */
-    protected abstract boolean service(Instruction.Executable instr);
-
-    protected final void service() {
-        if (currentlyExecutingCount <= 0)
-            currentlyExecuting = null;
-        if (currentlyExecuting == null && instructions.size() > 0) {
-            currentlyExecuting = instructions.remove();
-            currentlyExecutingCount = currentlyExecuting.count;
-            if (currentlyExecutingCount == 0) currentlyExecutingCount = Integer.MAX_VALUE;
-        }
-
-        if (currentlyExecuting != null &&
-            (killCount > 0 && (!killOnlyStandingInstructions || currentlyExecutingCount == Integer.MAX_VALUE))) {
-            killCount--;
-            currentlyExecuting = null;
-            return;
-        }
-
-        boolean ret = service(currentlyExecuting);
-        if (!ret) return;
-        if (currentlyExecuting.recycle) {
-            currentlyExecuting = currentlyExecuting.decrementCount();
-            if (currentlyExecuting != null)
-                addInstruction(currentlyExecuting);
-            currentlyExecuting = null;
-
-        } else {
-            if (currentlyExecuting != null && currentlyExecutingCount != Integer.MAX_VALUE)
-                currentlyExecutingCount--;
-        }
-    }
-
-
-}
index e4bde06..e5a0ea8 100644 (file)
@@ -8,81 +8,12 @@ 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.interpreter.ships.*;
 
-public class Interpreter extends Fleet {
+public class Interpreter extends Fleet implements Fleet.WithDynamicShips {
 
     /** some "halt ship" can turn this on to stop the interpreter */
-    public boolean       halt         = false;
-    public ArrayList<InterpreterShip> shiplist   = new ArrayList<InterpreterShip>();
-    public HashMap<String,InterpreterShip> ships = new HashMap<String,InterpreterShip>();
-    private BlockingQueue<Long> debugStream = new LinkedBlockingQueue<Long>();
-    public int[] mem = new int[0];
-
-
-    public void debug(long data) {
-        try {
-            if (debugStream != null) {
-                debugStream.put(data);
-            } else {
-                Log.println(ANSI.invert("   DEBUG: got a datum: " +  data+ANSI.clreol()));
-            }
-        } catch (Exception e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    public static class DynamicInterpreter extends Interpreter implements Fleet.WithDynamicShips {
-    }
-
-    public void expand(ShipDescription sd) {
-        try {
-            String filename = (sd.name.charAt(0)+"").toUpperCase() + sd.name.substring(1).toLowerCase();
-            File outf = new File("build/java/edu/berkeley/fleet/interpreter/ships/"+filename+".java");
-            new File(outf.getParent()).mkdirs();
-            System.err.println("writing to " + outf);
-            FileOutputStream out = new FileOutputStream(outf);
-            PrintWriter pw = new PrintWriter(out);
-
-            pw.println("package edu.berkeley.fleet.interpreter.ships;");
-            pw.println("import edu.berkeley.sbp.util.ANSI;");
-            pw.println("import edu.berkeley.fleet.interpreter.*;");
-            pw.println("import edu.berkeley.fleet.api.*;");
-            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(ShipDescription.BenkoBox b : sd.benkoBoxes) {
-                if (b.ports.length != 1)
-                    throw new RuntimeException("multiple ports not supported");
-                String name = b.ports[0];
-                pw.print("    ");
-                if (!b.tokenOnly &&  b.inbox) pw.print("DataInbox");
-                if ( b.tokenOnly &&  b.inbox) pw.print("TokenInbox");
-                if (!b.tokenOnly && !b.inbox) pw.print("DataOutbox");
-                if ( b.tokenOnly && !b.inbox) pw.print("TokenOutbox");
-                pw.print(" box_");
-                pw.print(name);
-                pw.print(" = new ");
-                if (!b.tokenOnly &&  b.inbox) pw.print("DataInbox");
-                if ( b.tokenOnly &&  b.inbox) pw.print("TokenInbox");
-                if (!b.tokenOnly && !b.inbox) pw.print("DataOutbox");
-                if ( b.tokenOnly && !b.inbox) pw.print("TokenOutbox");
-                pw.println("(this, \""+name+"\");");
-            }
-            pw.println("");
-            pw.println("    public "+filename+"(Interpreter fleet, String name) { super(fleet, name); }");
-            pw.println("");
-            //pw.println("    public void service() {");
-            pw.println(sd.sections.get("fleeterpreter"));
-            //pw.println("}");
-            pw.println("}");
-            pw.flush();
-            pw.close();
-        } catch (Exception e) { throw new RuntimeException(e); }
-    }
+    private HashMap<String,InterpreterShip> ships       = new HashMap<String,InterpreterShip>();
+    private BlockingQueue<Long>             debugStream = new LinkedBlockingQueue<Long>();
 
     public FleetProcess run(final byte[] instructions) {
         try {
@@ -95,16 +26,47 @@ public class Interpreter extends Fleet {
                             throw new RuntimeException(e);
                         } }
                     protected void _terminate() {
-                        shiplist   = new ArrayList<InterpreterShip>();
+                        // FIXME: hack
                         ships = new HashMap<String,InterpreterShip>();
                         debugStream = new LinkedBlockingQueue<Long>();
-                        mem = new int[0];
                     }
                 };
             new Thread() {
                 public void run() {
                     try {
-                        go(fp, instructions);
+                        // find the first icache
+                        InterpreterShip iscratch = null;
+                        for(Ship ship : Interpreter.this)
+                            if (ship.getClass().getSimpleName().equals("Memory")) {
+                                iscratch = (InterpreterShip)ship;
+                                break;
+                            }
+                        if (iscratch==null)
+                            iscratch = (InterpreterShip)Class.forName("edu.berkeley.fleet.interpreter.Memory")
+                                .getConstructor(new Class[] { Interpreter.class, String.class })
+                                .newInstance(new Object[] { Interpreter.this, "memory" });
+                        iscratch
+                            .getClass()
+                            .getMethod("boot", new Class[] { byte[].class })
+                            .invoke(iscratch, new Object[] { instructions });
+                        
+                        while(!fp.isTerminated())
+                            for(InterpreterShip ship : ships.values())
+                                for(int j=0; j<10; j++)
+                                    ship._service();
+                        
+                        // run the ships a bit longer for good measure
+                        for(int i=0; i<100; i++)
+                            for(InterpreterShip ship : ships.values())
+                                for(int j=0; j<10; j++)
+                                    ship._service();
+                        
+                        // check the state of the ships
+                        for(InterpreterShip ship : ships.values())
+                            ship.shutdown();
+                        
+                        Log.println(ANSI.yellow("    DONE: ====== FLEET is halted.  Have a nice day.  ======"));
+                        
                     } catch (Exception e) {
                         if (fp.isTerminated()) return;
                         throw new RuntimeException(e);
@@ -117,65 +79,25 @@ public class Interpreter extends Fleet {
         }
     }
 
-    public void go(FleetProcess fp, byte[] instructions) {
-        try {
-            // find the first icache
-            InterpreterShip iscratch = null;
-            for(Ship ship : this)
-                if (ship.getClass().getSimpleName().equals("Iscratch")) {
-                    iscratch = (InterpreterShip)ship;
-                    break;
-                }
-            if (iscratch==null)
-                iscratch = (InterpreterShip)Class.forName("edu.berkeley.fleet.interpreter.ships.Iscratch")
-                    .getConstructor(new Class[] { Interpreter.class, String.class })
-                    .newInstance(new Object[] { this, "iscratch" });
-            iscratch
-                .getClass()
-                .getMethod("boot", new Class[] { byte[].class })
-                .invoke(iscratch, new Object[] { instructions });
-
-            while(!halt && !fp.isTerminated())
-                for(InterpreterShip ship : ships.values())
-                    for(int j=0; j<10; j++)
-                        ship._service();
-
-            // run the ships a bit longer for good measure
-            for(int i=0; i<100; i++)
-                for(InterpreterShip ship : ships.values())
-                    for(int j=0; j<10; j++)
-                        ship._service();
-
-            // check the state of the ships
-            for(InterpreterShip ship : ships.values())
-                ship.shutdown();
-
-            Log.println(ANSI.yellow("    DONE: ====== FLEET is halted.  Have a nice day.  ======"));
-        } catch (Exception e) {
-            throw new RuntimeException(e);
-        }
-    }
-
     public void dispatch(Instruction i, long address) {
         Log.dispatch(i);
         if (i instanceof Instruction.Executable) {
             InterpreterBenkoBox sourceBenkoBox = (InterpreterBenkoBox)(((Instruction.Executable)i).benkoBox);
-            ((InstructionPort)sourceBenkoBox).addInstruction(((Instruction.Executable)i));
+            ((InstructionBenkoBox)sourceBenkoBox).addInstruction(((Instruction.Executable)i));
 
         } else if (i instanceof Instruction.Literal.CodeBagDescriptor) {
             Instruction.Literal.CodeBagDescriptor cbd = (Instruction.Literal.CodeBagDescriptor)i;
-            InterpreterBenkoBox destBenkoBox = (InterpreterBenkoBox)(cbd.dest);
             long absolute_cbd = ((cbd.offset+address) << 6) | cbd.size;
-            destBenkoBox.addDataFromFabric((int)absolute_cbd);
+            new Packet(this, null, (int)absolute_cbd, (InterpreterDestination)cbd.dest).send();
             
         } else if (i instanceof Instruction.Literal.Absolute) {
-            InterpreterBenkoBox destBenkoBox = (InterpreterBenkoBox)(((Instruction.Literal.Absolute)i).dest);
-            Log.data(((Instruction.Literal.Absolute)i).value+"", null, destBenkoBox);
-            destBenkoBox.addDataFromFabric((int)((Instruction.Literal.Absolute)i).value);
+            new Packet(this, null,
+                       (int)((Instruction.Literal.Absolute)i).value,
+                       (InterpreterDestination)(((Instruction.Literal.Absolute)i).dest)).send();
 
         } else if (i instanceof Instruction.Kill) {
             InterpreterBenkoBox benkoBox = (InterpreterBenkoBox)(((Instruction.Kill)i).benkoBox);
-            ((InstructionPort)benkoBox).kill(((Instruction.Kill)i).count,
+            ((InstructionBenkoBox)benkoBox).kill(((Instruction.Kill)i).count,
                                              ((Instruction.Kill)i).killOnlyStandingInstructions);
 
         } else {
@@ -183,62 +105,108 @@ public class Interpreter extends Fleet {
         }
     }
 
-    public void sendToken(InterpreterBenkoBox source, InterpreterBenkoBox dest) {
-        Log.token(source, dest);
-        dest.addTokenFromFabric();
-    }
+    public Iterator<Ship> iterator() { return (Iterator<Ship>)(Object)ships.values().iterator(); }
 
-    public void sendData(InterpreterBenkoBox source, int data, InterpreterBenkoBox dest) {
-        Log.data(data+"", source, dest);
-        dest.addDataFromFabric(data);
+    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 });
+            ships.put(shipname, ret);
+            return ret;
+        } catch (Exception e) {
+            return null;
+        }
     }
 
+    public void debug(long data) {
+        try {
+            if (debugStream != null) debugStream.put(data);
+            else Log.println(ANSI.invert("   DEBUG: got a datum: " +  data+ANSI.clreol()));
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
 
-    // Implementation of the Fleet class abstract methods /////////////////////////////////////////////////////////
-
-    public Iterator<Ship> iterator() { return (Iterator<Ship>)(Object)shiplist.iterator(); }
-
-    public int computeOffset(int origin, int target) { return (target - origin)/6; }
-    public int computeTarget(int origin, int offset) { return origin + (offset*6); }
+    // Instruction Encoding /////////////////////////////////////////////////////////////////////////
 
     private 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); }
-
     private class InterpreterInstructionEncoder extends InstructionEncoder {
-        public long getBoxAddr(Destination box) { return ((InterpreterBenkoBox)box).addr; }
-        public long getBoxInstAddr(BenkoBox box) { return ((InterpreterBenkoBox)box).instr_addr; }
-        public BenkoBox getBoxByAddr(long dest) {
+        public long getDestAddr(Destination box) { return ((InterpreterDestination)box).getDestAddr(); }
+        public long getBoxInstAddr(BenkoBox box) { return ((InterpreterBenkoBox)box).getDestAddr(); }
+        public Destination getDestByAddr(long dest) {
             for(Ship ship : Interpreter.this)
                 for(BenkoBox bb : ship.getBenkoBoxes())
-                    if (((InterpreterBenkoBox)bb).addr == dest)
-                        return bb;
+                    for(Destination d : bb.getDestinations())
+                        if (getDestAddr(d)==dest)
+                            return d;
             return null;
         }
         public BenkoBox getBoxByInstAddr(long dest) {
             for(Ship ship : Interpreter.this)
                 for(BenkoBox bb : ship.getBenkoBoxes())
-                    if (((InterpreterBenkoBox)bb).instr_addr == dest)
+                    if (getBoxInstAddr(bb) == dest)
                         return bb;
             return null;
         }
     }
 
-    public Ship createShip(String shipType, String shipname) {
+    // ShipDescription //////////////////////////////////////////////////////////////////////////////
+
+    public void expand(ShipDescription sd) {
         try {
-            Class c = Class.forName("edu.berkeley.fleet.interpreter.ships."+shipType);
-            Constructor con = c.getConstructor(new Class[] { Interpreter.class, String.class });
-            InterpreterShip ret = (InterpreterShip)con.newInstance(new Object[] { this, shipname });
-            ships.put(shipname, ret);
-            shiplist.add(ret);
-            return ret;
-        } catch (Exception e) {
-            return null;
-        }
-    }
+            String filename = (sd.getName().charAt(0)+"").toUpperCase() + sd.getName().substring(1).toLowerCase();
+            File outf = new File("build/java/edu/berkeley/fleet/interpreter/"+filename+".java");
+            new File(outf.getParent()).mkdirs();
+            System.err.println("writing to " + outf);
+            FileOutputStream out = new FileOutputStream(outf);
+            PrintWriter pw = new PrintWriter(out);
 
+            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.*;");
+            pw.println("import java.util.*;");
+            pw.println("import java.io.*;");
+            pw.println("");
+            pw.println("public class "+filename+" extends InterpreterShip {");
+            pw.println("");
+            for(BenkoBoxDescription b : sd) {
+                String name = b.getName();
+                pw.print("    ");
+                if ( b.isInbox()) pw.print("Inbox");
+                if (!b.isInbox()) 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[] { ");
+                boolean first = true;
+                for(String destination : b) {
+                    if (!first) pw.print(", ");
+                    first = false;
+                    pw.print("\""+destination+"\"");
+                }
+                pw.println("});");
+            }
+            pw.println("");
+            pw.println("    public "+filename+"(Interpreter fleet, String name) {");
+            pw.println("       super(fleet, name, \""+filename+"\");");
+            for(BenkoBoxDescription b : sd)
+                pw.println("       addBenkoBox(\""+b.getName()+"\", box_"+b.getName()+");");
+            pw.println("    }");
+            pw.println("");
+            pw.println(sd.getSection("fleeterpreter"));
+            pw.println("}");
+            pw.flush();
+            pw.close();
+        } catch (Exception e) { throw new RuntimeException(e); }
+    }
 
 }
 
index 820e3fd..70fb7e2 100644 (file)
@@ -1,56 +1,60 @@
 package edu.berkeley.fleet.interpreter;
 import edu.berkeley.fleet.api.*;
 import edu.berkeley.fleet.api.BenkoBox;
+import java.util.*;
 
 /** anything that has a destination address on the switch fabric */
-public abstract class InterpreterBenkoBox extends BenkoBox {
+public abstract class InterpreterBenkoBox extends BenkoBox implements InterpreterDestination {
         
     private final String name;
     private final InterpreterShip ship;
+    private final Destination[] ports;
+    private final int addr = max_addr++;
         
-    public InterpreterBenkoBox(InterpreterShip ship, String name) {
+    public InterpreterBenkoBox(InterpreterShip ship, String name, String[] ports) {
         this.ship = ship;
         this.name = name;
-        ship.addBenkoBox(name, this);
+        this.ports = new Destination[ports.length];
+        for(int i=0; i<ports.length; i++)
+            this.ports[i] =
+                ports[i].equals("")
+                ? this
+                : new InterpreterBenkoBoxDestination(ports[i]);
     }
 
-    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++);
-    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; }
-        
-    /** 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!"); }
-
-    /** 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 Iterable<Destination> getDestinations() {
+        HashSet<Destination> ret = new HashSet<Destination>();
+        for(Destination d : ports) ret.add(d);
+        return ret;
+    }
 
-    public Ship getShip() { return ship; }
+    /** adds the included datum to the port from the switch fabric  side */
+    public abstract void addDataFromFabric(Packet packet);
 
-    public Fleet getFleet() { return getShip().getFleet(); }
+    abstract void service();
 
-    public String toString() { return ship+"."+name; }
+    abstract void   shutdown();
 
-    abstract void shutdown();
+    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; }
+    
+    Interpreter getInterpreter() { return ((InterpreterShip)getShip()).getInterpreter(); }
 
-    public String getName() { return name; }
+    public long getDestAddr() { return addr; }
 
-    public int getInstructionFifoLength() { return 4; }
+    private static int max_addr;
 
+    private class InterpreterBenkoBoxDestination extends Destination implements InterpreterDestination {
+        public String name;
+        public long addr = max_addr++;
+        public InterpreterBenkoBoxDestination(String name)          { this.name = name; }
+        public String getDestinationName()               { return name; }
+        public Ship getShip()                    { return InterpreterBenkoBox.this.getShip(); }
+        public void addDataFromFabric(Packet packet) { InterpreterBenkoBox.this.addDataFromFabric(packet); }
+        public String toString()                 { return getShip()+"."+getName(); }
+        public long getDestAddr() { return addr; }
+    }
 }
diff --git a/src/edu/berkeley/fleet/interpreter/InterpreterDestination.java b/src/edu/berkeley/fleet/interpreter/InterpreterDestination.java
new file mode 100644 (file)
index 0000000..445a8eb
--- /dev/null
@@ -0,0 +1,9 @@
+package edu.berkeley.fleet.interpreter;
+import edu.berkeley.fleet.api.*;
+import java.util.*;
+
+interface InterpreterDestination {
+    public long getDestAddr();
+    public void addDataFromFabric(Packet packet);
+    public String getDestinationName();
+}
\ No newline at end of file
index d4465ab..70bbd80 100644 (file)
@@ -6,21 +6,19 @@ import java.util.*;
 import java.io.*;
 
 /** a ship, which belongs to a fleet and which may have many ports */
-public abstract class InterpreterShip extends Ship {
+abstract class InterpreterShip extends Ship {
         
     /** You should instantiate a bunch of Inboxes and Outboxes in your constructor */
-    public InterpreterShip(Interpreter fleet, String name) { this.fleet = fleet; }
+    public InterpreterShip(Interpreter fleet, String name, String type) { this.fleet = fleet; this.type = type; }
 
     private Interpreter  fleet;
-
-    // this is dumb, the fpga fleet currently requires these in declaration-order; it shouldn't
-    private ArrayList<InterpreterBenkoBox> portlist = new ArrayList<InterpreterBenkoBox>();
+    private String       type;
     private HashMap<String,InterpreterBenkoBox> ports = new HashMap<String,InterpreterBenkoBox>();
 
-    public Iterable<BenkoBox> getBenkoBoxes() { return (Iterable<BenkoBox>)(Object)portlist; }
-    public String getType()                   { return getClass().getSimpleName(); }
-    public Fleet  getFleet()                  { return fleet; }
-    public Interpreter  getInterpreter()      { return fleet; }
+    public Iterable<BenkoBox> getBenkoBoxes()  { return (Iterable<BenkoBox>)(Object)ports.values(); }
+    public String             getType()        { return type; }
+    public Fleet              getFleet()       { return fleet; }
+    public Interpreter        getInterpreter() { return fleet; }
 
     /**
      *  Override this method, check inboxes for the data you need, and
@@ -34,7 +32,9 @@ public abstract class InterpreterShip extends Ship {
         service();
     }
 
-    void addBenkoBox(String name, InterpreterBenkoBox port) { ports.put(name, port); portlist.add(port); }
+    protected void addBenkoBox(String name, InterpreterBenkoBox port) {
+        ports.put(name, port);
+    }
 
     public void shutdown() {
         for(InterpreterBenkoBox p : ports.values())
index 6e39ebb..18e8d01 100644 (file)
@@ -1,13 +1,11 @@
 package edu.berkeley.fleet.interpreter;
 import edu.berkeley.sbp.util.ANSI;
 import edu.berkeley.fleet.api.*;
-import edu.berkeley.fleet.api.Instruction;
 import java.io.*;
 
 public class Log {
 
     public static boolean ansi_color = true;
-
     public static PrintWriter log = new PrintWriter(new OutputStreamWriter(System.out));
 
     public static void print(Object o) {
@@ -29,35 +27,26 @@ public class Log {
         }
     }
 
+    /*
     public static void dispatch(Dispatchable d) {
         println(ANSI.green("dispatch: " + indent(d+"", "          ")));
     }
+    */
     public static void dispatch(Instruction d) {
         println(ANSI.green("dispatch: " + indent(d+"", "          ")));
     }
 
-    public static void data(String data, BenkoBox source, BenkoBox dest) {
+    public static void data(String data, BenkoBox source, Destination dest) {
         println(("    data: ") + indent(ANSI.purple(data) +
                                         (source==null ? "" :
                                          (" : " + source))+(" -> "+ANSI.purple(""+dest)), "          "));
     }
 
-    public static void token(BenkoBox source, BenkoBox dest) {
+    public static void token(BenkoBox source, Destination dest) {
         println(ANSI.purple("   token: ") + (source + " -> " + ANSI.purple(dest+"")));
     }
 
     public static String clreol() { return ""; }
-    /*
-    public static String black(Object o) { if (!ansi_color) return o+""; return o+""; }
-    public static String red(Object o) { if (!ansi_color) return o+""; return "\033[31m"+o+"\033[0m"; }
-    public static String green(Object o) { if (!ansi_color) return o+""; return "\033[32m"+o+"\033[0m"; }
-    public static String yellow(Object o) { if (!ansi_color) return o+""; return "\033[33m"+o+"\033[0m"; }
-    public static String blue(Object o) { if (!ansi_color) return o+""; return "\033[34m"+o+"\033[0m"; }
-    public static String purple(Object o) { if (!ansi_color) return o+""; return "\033[35m"+o+"\033[0m"; }
-    public static String cyan(Object o) { if (!ansi_color) return o+""; return "\033[36m"+o+"\033[0m"; }
-    public static String invert(Object o) { if (!ansi_color) return o+""; return "\033[7m"+o+"\033[0m"; }
-    public static String bold(Object o) { if (!ansi_color) return o+""; return "\033[1m"+o+"\033[0m"; }
-    */
     public static void error(Object o) { println(ANSI.red(o)); }
 
     public static String indent(String s, String indent) {
diff --git a/src/edu/berkeley/fleet/interpreter/Main.java b/src/edu/berkeley/fleet/interpreter/Main.java
deleted file mode 100644 (file)
index 9049eff..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-package edu.berkeley.fleet.interpreter;
-import edu.berkeley.fleet.api.*;
-
-import java.util.*;
-import java.io.*;
-import edu.berkeley.fleet.api.Instruction;
-import edu.berkeley.fleet.api.BenkoBox;
-import edu.berkeley.fleet.*;
-import edu.berkeley.fleet.assembler.*;
-import edu.berkeley.fleet.interpreter.*;
-import edu.berkeley.fleet.slipway.*;
-
-public class Main {
-    static boolean debugMemory = true;
-    static boolean dump_fabric = false;
-    static boolean dump_code = false;
-    static boolean test = false;
-
-    public static void main(String[] s) throws Exception {
-        for(int i=0; i<s.length; i++) {
-            if (s[i].startsWith("--color=")) {
-                String val = s[i].substring(s[i].indexOf('=')+1);
-                if (val.equals("on")) {
-                    Log.ansi_color = true;
-                    continue;
-                } else if (val.equals("off")) {
-                    Log.ansi_color = false;
-                    continue;
-                }
-            } else if (s[i].startsWith("--dump-fabric")) {
-                dump_fabric = true;
-                continue;
-            } else if (s[i].startsWith("--dump-code")) {
-                dump_code = true;
-                continue;
-
-            } else if (s[i].startsWith("--test")) {
-                test = true;
-                continue;
-
-            } else if (s[i].startsWith("--memory=")) {
-                String val = s[i].substring(s[i].indexOf('=')+1);
-                if (val.equals("hide")) {
-                    debugMemory = false;
-                    continue;
-                } else if (val.equals("show")) {
-                    debugMemory = true;
-                    continue;
-                }
-            }
-            System.out.println("Fleeterpreter usage:");
-            System.out.println("");
-            System.out.println("  --dump-fabric");
-            System.out.println("  --dump-code");
-            System.out.println("  --color={on|off}");
-            System.out.println("  --inboxes={configured|unconfigured}");
-            System.out.println("  --memory={hide|show}");
-            System.exit(-1);
-        }
-        new Main().go();
-    }
-
-
-    public void go() throws Exception {
-        /*
-        if (test) {
-            test(new File("tests"));
-            System.exit(0);
-        }
-        */
-
-        Slipway fleet = new Slipway();
-        if (dump_fabric) {
-            fleet.dumpFabric(false);
-        } else {
-            fleet.dumpFabric(true);
-            ByteArrayOutputStream baos = new ByteArrayOutputStream();
-            edu.berkeley.fleet.assembler.Main.assemble(fleet, new InputStreamReader(System.in), baos);
-            if (dump_code) {
-                DataOutputStream dos = new DataOutputStream(new FileOutputStream("build/fleet.bin"));
-                dos.write(baos.toByteArray());
-                dos.close();
-            } else {
-                /*
-                if (debugMemory) { fleet.dumpMem(); }
-                fleet.go(baos.toByteArray());
-                if (debugMemory) { fleet.dumpMem(); }
-                */
-            }
-        }
-    }
-
-}
\ No newline at end of file
index f3be1ab..4c82c28 100644 (file)
@@ -3,33 +3,25 @@ import edu.berkeley.sbp.util.ANSI;
 import edu.berkeley.fleet.api.*;
 import edu.berkeley.fleet.api.Instruction;
 
-public abstract class Outbox extends InstructionPort {
+public class Outbox extends InstructionBenkoBox {
 
     /** are we ready to accept another item from the ship? */
     private boolean readyForItemFromShip = true;
 
     /** data which has been presented by the ship and is waiting to depart */
-    private int     itemPresentedByShip;
+    private long    itemPresentedByShip;
 
     /** number of tokens queued on the trigger input */
     private int     triggersReceived = 0;
 
-    private Interpreter getInterpreter() { return ((InterpreterShip)getShip()).getInterpreter(); }
+    /** the latched value */
+    private long register;
 
-    protected Outbox(InterpreterShip ship, String name) {
-        super(ship, name);
-    }
-
-    public final boolean readyForItemFromShip() {
-        return readyForItemFromShip;
-    }
+    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); }
 
-    void addDataFromFabric(int datum)  { addTokenFromFabric(); }
-    final void addTokenFromFabric() {
-        triggersReceived++;
-    }
-
-    int register;
     protected final boolean service(Instruction.Executable instruction) {
 
         // if no instruction waiting, do nothing
@@ -52,24 +44,26 @@ public abstract class Outbox extends InstructionPort {
         if (instruction.dataOut) {
 
             // if item to be transmitted, send it
-            send((InterpreterBenkoBox)instruction.dest, register);
+            new Packet(getInterpreter(), this, register, (InterpreterDestination)instruction.dest).send();
             if (instruction.tokenOut)
                 throw new RuntimeException("outboxes may not send acks!");
 
         } else if (instruction.tokenOut) {
 
             // if no item was sent, we might still send an ack
-            getInterpreter().sendToken(this, (InterpreterBenkoBox)instruction.dest);
+            new Packet(getInterpreter(), this, 0, (InterpreterBenkoBox)instruction.dest).send();
         }
 
         return true;
     }
 
-    /** this is invoked to transmit data; the subclass decides if it is a token or not */
-    protected abstract void send(InterpreterBenkoBox port, int data);
+    public final boolean readyForItemFromShip() { return readyForItemFromShip; }
+    public       void addDataFromShip(long data) { addItemFromShip(data); }
+    public       boolean readyForDataFromShip() { return readyForItemFromShip(); }
+    public       void addDataFromFabric(Packet packet) { triggersReceived++; }
 
     /** subclass invokes this to add an item from the ship */
-    protected final void addItemFromShip(int data) {
+    protected final void addItemFromShip(long data) {
         if (!readyForItemFromShip)
             throw new RuntimeException("tried to add an item to an outbox which was not ready!  you have a buggy ship!");
         readyForItemFromShip = false;
@@ -83,4 +77,5 @@ public abstract class Outbox extends InstructionPort {
             Log.println(ANSI.red(" WARNING: you left a token on the trigger input to port " + this));
         super.shutdown(false);
     }
+
 }
diff --git a/src/edu/berkeley/fleet/interpreter/Packet.java b/src/edu/berkeley/fleet/interpreter/Packet.java
new file mode 100644 (file)
index 0000000..7591c56
--- /dev/null
@@ -0,0 +1,29 @@
+package edu.berkeley.fleet.interpreter;
+import java.io.*;
+import java.util.*;
+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.*;
+
+class Packet {
+
+    Interpreter interpreter;
+    long        value;
+    InterpreterDestination destination;
+
+    public Packet(Interpreter interpreter, InterpreterBenkoBox source, long value, InterpreterDestination destination) {
+        Log.data(value+"", source, (Destination)destination);
+        this.interpreter = interpreter;
+        this.value = value;
+        this.destination = destination;
+    }
+
+    public void send() {
+        destination.addDataFromFabric(this);
+    }
+
+}
\ No newline at end of file
diff --git a/src/edu/berkeley/fleet/interpreter/TokenInbox.java b/src/edu/berkeley/fleet/interpreter/TokenInbox.java
deleted file mode 100644 (file)
index cfeb9b6..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-package edu.berkeley.fleet.interpreter;
-import edu.berkeley.fleet.api.*;
-
-/** a port which receives only tokens */
-public class TokenInbox extends Inbox {
-
-    public TokenInbox(InterpreterShip ship, String name) {
-        super(ship, name);
-    }
-
-    void addTokenFromFabric() {
-        addItemFromFabric(0);
-    }
-
-    public boolean tokenReadyForShip() {
-        return super.itemReadyForShip();
-    }
-
-    public void removeTokenForShip() {
-        super.accept();
-    }
-}
diff --git a/src/edu/berkeley/fleet/interpreter/TokenOutbox.java b/src/edu/berkeley/fleet/interpreter/TokenOutbox.java
deleted file mode 100644 (file)
index b5c5cc0..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-package edu.berkeley.fleet.interpreter;
-import edu.berkeley.fleet.api.*;
-
-/** a port which outputs only tokens */
-public class TokenOutbox extends Outbox {
-
-    public TokenOutbox(InterpreterShip ship, String name) {
-        super(ship, name);
-    }
-
-    private Interpreter getInterpreter() { return ((InterpreterShip)getShip()).getInterpreter(); }
-    protected void send(InterpreterBenkoBox port, int data) {
-        getInterpreter().sendToken(this, port);
-    }
-
-    public boolean readyForTokenFromShip() {
-        return super.readyForItemFromShip();
-    }
-
-    public void addTokenFromShip() {
-        addItemFromShip(0);
-    }
-
-}
diff --git a/src/edu/berkeley/fleet/interpreter/ships/ArithmeticShip.java b/src/edu/berkeley/fleet/interpreter/ships/ArithmeticShip.java
deleted file mode 100644 (file)
index 3335c26..0000000
+++ /dev/null
@@ -1,162 +0,0 @@
-package edu.berkeley.fleet.interpreter.ships;
-import edu.berkeley.fleet.interpreter.*;
-import edu.berkeley.fleet.*;
-
-import java.util.*;
-import java.io.*;
-
-/*
-You should note the following:
-I haven't implemented all the link-out policies.
-You can give the SHIP a single cmd with up to four operations.  For
-example, "ADD ZERO 0 SUBTRACT SIGN 1 MAX MAX 0".  These will be done
-in left-to-right order.
-You can use any link-out policy with any operation, though some don't
-make much sense.
-*/
-
-/**
- * @author Dominic Antonelli <dantonel@berkeley.edu>
- */
-public class ArithmeticShip extends InterpreterShip {
-
-    private int link;
-
-    DataInbox A = new DataInbox(this, "A");
-    DataInbox B = new DataInbox(this, "B");
-    DataInbox cmd = new DataInbox(this, "cmd");
-    DataOutbox out = new DataOutbox(this, "out");
-
-    public ArithmeticShip(Interpreter fleet, String name) {
-        super(fleet, name);
-    }
-
-    public enum Operation {
-        // NOTE: NOP is not to be used, but rather simply prevents other ops from using opcode 0
-        // This is so that we can detect the "end" of a command - when the command is all zero
-        NOP       { int eval(int a, int b, int link) { System.out.println("ERROR: Arith_NOP\n"); return 0; } },
-        ADD       { int eval(int a, int b, int link) { return a + b + link;            } },
-        SUBTRACT  { int eval(int a, int b, int link) { return a - b + link;            } },
-        COPY_A    { int eval(int a, int b, int link) { return a + link;                } },
-        COPY_B    { int eval(int a, int b, int link) { return b + link;                } },
-        SELECT    { int eval(int a, int b, int link) { return ((link==1) ? b : a);     } },
-        NEGATE_A  { int eval(int a, int b, int link) { return -(a+link);               } },
-        NEGATE_B  { int eval(int a, int b, int link) { return -(b+link);               } },
-        ABS_A     { int eval(int a, int b, int link) { a+=link; return (a<0 ? -a : a); } },
-        ABS_B     { int eval(int a, int b, int link) { b+=link; return (b<0 ? -b : b); } },
-        MAX       { int eval(int a, int b, int link) { return (a>b ?  a : b) + link;   } },
-        MIN       { int eval(int a, int b, int link) { return (a<b ?  a : b) + link;   } },
-        INC_A     { int eval(int a, int b, int link) { return a+1+link;                } },
-        INC_B     { int eval(int a, int b, int link) { return b+1+link;                } },
-        RESERVED1 { int eval(int a, int b, int link) { System.out.println("ERROR: Arith_RESERVED0\n"); return 0; } },
-        RESERVED2 { int eval(int a, int b, int link) { System.out.println("ERROR: Arith_RESERVED1\n"); return 0; } };
-
-
-
-        // Do arithmetic op represented by this constant
-        abstract int eval(int a, int b, int link);
-        public static Operation convertInt( int i ) {
-            return values()[i];
-        }
-    }
-
-    public enum LinkOutPolicy {
-        LINK_IN, ZERO, CARRY, SIGN, OLD_SIGN, OVERFLOW, MAX, MIN;
-        public static LinkOutPolicy convertInt( int i ) {
-            return values()[i];
-        }
-    }
-
-    private long savedCommand = 0;
-
-    public void service() {
-        if (!out.readyForDataFromShip()) return;
-        if (!A.dataReadyForShip()) return;
-        if (!B.dataReadyForShip()) return;
-
-        long command;
-
-        if (savedCommand != 0) {
-            command = savedCommand;
-        } else if (!cmd.dataReadyForShip()) {
-            return;
-        } else {
-            command = cmd.removeDataForShip();
-        }
-
-        int inA = A.removeDataForShip();
-        int inB = B.removeDataForShip();
-        int linkInPolicy = (int)(command & 0x1);
-        LinkOutPolicy linkOutPolicy = LinkOutPolicy.convertInt((int)((command >> 1) & 0x7));
-        Operation op = Operation.convertInt((int)((command >> 4) & 0xf));
-        int result = 0;
-
-        int oldLink = link;
-        if (op == Operation.SELECT) {
-            link = link ^ linkInPolicy; // LinkInPolicy = 1 mean flip the selection for the SELECT op.
-        } else {
-            link = link & linkInPolicy; // If linkInPolicy is zero, unset the link bit for the upcoming computation.
-                                        // NOTE: The final value of link will be computed after eval.
-        }
-
-        result = op.eval(inA, inB, link);
-
-        switch (linkOutPolicy) {
-            case LINK_IN:
-                link = oldLink;
-                break;
-            case ZERO:
-                link = (result == 0) ? 1 : 0;
-//                link = 0;
-                break;
-            case SIGN:
-                link = (result >> 31) & 0x1;
-                break;
-            case MAX:
-                if (inA > inB) link = 1; else link = 0;
-                break;
-            case MIN:
-                if (inA < inB) link = 1; else link = 0;
-                break;
-            case CARRY:
-            case OLD_SIGN:
-            case OVERFLOW:
-                System.out.println("ERROR: non-implemented linkOutPolicy selected");
-                break;
-            default:
-                System.out.println("ERROR: Unknown linkOutPolicy selected");
-                break;
-        };
-        out.addDataFromShip(result);
-
-        savedCommand = command >> 8;
-
-//        System.out.println("Link is now " + link);
-    }
-
-    public int resolveShipSpecificConstant(String shipSpecificData) {
-        String[] data = shipSpecificData.split("\\s");
-        int result = 0;
-
-        if ((data.length % 3) != 0) {
-            System.out.println("ERROR: ArithmeticShip received invalid ShipSpecificConstant");
-        }
-        for (int i = data.length - 1; i >= 2; i-=3) {
-            result <<= 8;
-            if (data[i].equals("1")) {
-                result |= 1;
-            }
-            for (LinkOutPolicy policy : LinkOutPolicy.values()) {
-                if (data[i-1].equals(policy.toString())) {
-                    result |= (policy.ordinal() << 1);
-                }
-            }
-            for (Operation op : Operation.values()) {
-                if (data[i-2].equals(op.toString())) {
-                    result |= (op.ordinal() << 4);
-                }
-            }
-        }
-        return result;
-    }
-}
diff --git a/src/edu/berkeley/fleet/interpreter/ships/Counter.java b/src/edu/berkeley/fleet/interpreter/ships/Counter.java
deleted file mode 100644 (file)
index 921a2b3..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-package edu.berkeley.fleet.interpreter.ships;
-import edu.berkeley.fleet.interpreter.*;
-import edu.berkeley.fleet.*;
-
-import java.util.*;
-import java.io.*;
-
-public class Counter extends InterpreterShip {
-
-    private int count = 0;
-
-    DataInbox   load      = new DataInbox(this, "load");
-    TokenInbox  decrement = new TokenInbox(this, "decrement");
-    TokenOutbox zero      = new TokenOutbox(this, "zero");
-
-    public Counter(Interpreter fleet, String name) {
-        super(fleet, name);
-    }
-
-    public String getBalsaName() { return "counter"; }
-    public void service() {
-        if (!zero.readyForTokenFromShip()) return;
-        if (count==0 && load.dataReadyForShip()) {
-            count = load.removeDataForShip();
-            return;
-        }
-        if (count>0 && decrement.tokenReadyForShip()) {
-            decrement.removeTokenForShip();
-            count--;
-            if (count==0)
-                zero.addTokenFromShip();
-        }
-    }
-
-}
diff --git a/src/edu/berkeley/fleet/interpreter/ships/DeMux.java b/src/edu/berkeley/fleet/interpreter/ships/DeMux.java
deleted file mode 100644 (file)
index 3006dd9..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-package edu.berkeley.fleet.interpreter.ships;
-import edu.berkeley.fleet.interpreter.*;
-import edu.berkeley.fleet.*;
-
-import java.util.*;
-import java.io.*;
-
-public class DeMux extends InterpreterShip {
-
-    DataInbox   inp  = new DataInbox(this,  "in");
-    DataInbox   selp = new DataInbox(this,  "select");
-    DataOutbox  truep   = new DataOutbox(this, "true");
-    DataOutbox  falsep   = new DataOutbox(this, "false");
-
-    public String getBalsaName() { return "demux"; }
-
-    public DeMux (Interpreter fleet, String name) {
-        super(fleet, name);
-    }
-
-    public void service() {
-        if (inp.dataReadyForShip() && selp.dataReadyForShip() &&
-            truep.readyForDataFromShip() && falsep.readyForDataFromShip()) {
-            int in = inp.removeDataForShip();
-            int sel = selp.removeDataForShip();
-            if (sel==0)
-                falsep.addDataFromShip(in);
-            else
-                truep.addDataFromShip(in);
-        }
-    }
-
-}
-
diff --git a/src/edu/berkeley/fleet/interpreter/ships/Dup.java b/src/edu/berkeley/fleet/interpreter/ships/Dup.java
deleted file mode 100644 (file)
index e78273a..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-package edu.berkeley.fleet.interpreter.ships;
-import edu.berkeley.fleet.interpreter.*;
-import edu.berkeley.fleet.*;
-
-import java.util.*;
-import java.io.*;
-
-public class Dup extends InterpreterShip {
-
-    DataInbox   in  = new DataInbox(this, "in");
-    DataOutbox  a   = new DataOutbox(this, "a");
-    DataOutbox  b   = new DataOutbox(this, "b");
-
-    public String getBalsaName() { return "dup"; }
-
-    public Dup (Interpreter fleet, String name) {
-        super(fleet, name);
-    }
-
-    public void service() {
-        if (in.dataReadyForShip() && a.readyForDataFromShip() && b.readyForDataFromShip()) {
-            int data = in.removeDataForShip();
-            a.addDataFromShip(data);
-            b.addDataFromShip(data);
-        }
-    }
-
-}
-
diff --git a/src/edu/berkeley/fleet/interpreter/ships/Dup3.java b/src/edu/berkeley/fleet/interpreter/ships/Dup3.java
deleted file mode 100644 (file)
index 1820970..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-package edu.berkeley.fleet.interpreter.ships;
-import edu.berkeley.fleet.interpreter.*;
-import edu.berkeley.fleet.*;
-
-import java.util.*;
-import java.io.*;
-
-public class Dup3 extends InterpreterShip {
-
-    DataInbox   in  = new DataInbox(this, "in");
-    DataOutbox  a   = new DataOutbox(this, "a");
-    DataOutbox  b   = new DataOutbox(this, "b");
-    DataOutbox  c   = new DataOutbox(this, "c");
-
-    public String getBalsaName() { return "dup3"; }
-
-    public Dup3 (Interpreter fleet, String name) {
-        super(fleet, name);
-    }
-
-    public void service() {
-        if (in.dataReadyForShip() && a.readyForDataFromShip() && b.readyForDataFromShip() && c.readyForDataFromShip()) {
-            int data = in.removeDataForShip();
-            a.addDataFromShip(data);
-            b.addDataFromShip(data);
-            c.addDataFromShip(data);
-        }
-    }
-
-}
-
diff --git a/src/edu/berkeley/fleet/interpreter/ships/DuplicatorShip.java b/src/edu/berkeley/fleet/interpreter/ships/DuplicatorShip.java
deleted file mode 100644 (file)
index 70d3e5e..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-package edu.berkeley.fleet.interpreter.ships;
-import edu.berkeley.fleet.interpreter.*;
-import edu.berkeley.fleet.*;
-
-import java.util.*;
-import java.io.*;
-
-/**
- * @author Dominic Antonelli <dantonel@berkeley.edu>
- */
-public class DuplicatorShip extends InterpreterShip {
-
-    DataInbox   in  = new DataInbox(this, "in");
-    DataOutbox  out0 = new DataOutbox(this, "out0");
-    DataOutbox  out1 = new DataOutbox(this, "out1");
-    DataOutbox  out2 = new DataOutbox(this, "out2");
-    DataOutbox  out3 = new DataOutbox(this, "out3");
-
-    public DuplicatorShip (Interpreter fleet, String name) {
-        super(fleet, name);
-    }
-
-    public void service() {
-        if (in.dataReadyForShip()       && out0.readyForDataFromShip() && 
-            out1.readyForDataFromShip() && out2.readyForDataFromShip() &&
-            out3.readyForDataFromShip()) {
-            int data = in.removeDataForShip();
-            out0.addDataFromShip(data);
-            out1.addDataFromShip(data);
-            out2.addDataFromShip(data);
-            out3.addDataFromShip(data);
-        }
-    }
-
-}
-
diff --git a/src/edu/berkeley/fleet/interpreter/ships/HomeworkCounter.java b/src/edu/berkeley/fleet/interpreter/ships/HomeworkCounter.java
deleted file mode 100644 (file)
index 0aa8be8..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-package edu.berkeley.fleet.interpreter.ships;
-import edu.berkeley.fleet.interpreter.*;
-import edu.berkeley.fleet.*;
-
-import java.util.*;
-import java.io.*;
-
-public class HomeworkCounter extends InterpreterShip {
-
-    private int count = -1;
-
-    TokenOutbox zero     = new TokenOutbox(this, "zero");
-    TokenOutbox positive = new TokenOutbox(this, "positive");
-    DataInbox    load     = new DataInbox(this, "load");
-    TokenInbox  ask      = new TokenInbox(this, "ask");
-
-    public HomeworkCounter(Interpreter fleet, String name) {
-        super(fleet, name);
-    }
-
-    public void service() {
-        if (!zero.readyForTokenFromShip()) return;
-        if (!positive.readyForTokenFromShip()) return;
-        if (load.dataReadyForShip()) {
-            count = load.removeDataForShip();
-            return;
-        }
-        if (ask.tokenReadyForShip()) {
-            ask.removeTokenForShip();
-            if (count > 0) {
-                count--;
-                positive.addTokenFromShip();
-            } else if (count<=0) {
-                zero.addTokenFromShip();
-            }
-        }
-    }
-
-}
diff --git a/src/edu/berkeley/fleet/interpreter/ships/MemoryReadShip.java b/src/edu/berkeley/fleet/interpreter/ships/MemoryReadShip.java
deleted file mode 100644 (file)
index ffe4511..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-package edu.berkeley.fleet.interpreter.ships;
-import edu.berkeley.fleet.interpreter.*;
-
-import edu.berkeley.fleet.*;
-import java.util.*;
-import java.io.*;
-
-public class MemoryReadShip extends InterpreterShip {
-
-    boolean _loaded = false;
-    int _count = 0;
-    int _stride = 0;
-    int _addr = 0;
-
-    DataInbox  addr   = new DataInbox(this, "addr");
-    DataInbox  stride = new DataInbox(this, "stride");
-    DataInbox  count  = new DataInbox(this, "count");
-    DataOutbox data   = new DataOutbox(this, "data");
-    TokenOutbox done  = new TokenOutbox(this, "done");
-
-    public MemoryReadShip(Interpreter fleet, String name) {
-        super(fleet, name);
-    }
-
-    public void service() {
-        if (_count > 0) {
-            if (!data.readyForDataFromShip()) return;
-            data.addDataFromShip(_addr>=getInterpreter().mem.length ? 0 : getInterpreter().mem[_addr]);
-            _count--;
-            _addr += _stride;
-            if (_count==0)
-                done.addTokenFromShip();
-        } else {
-            if (count.dataReadyForShip() &&
-                addr.dataReadyForShip() &&
-                stride.dataReadyForShip() &&
-                done.readyForTokenFromShip() &&
-                data.readyForDataFromShip()) {
-
-                _count  = count.removeDataForShip();
-                _addr   = addr.removeDataForShip();
-                _stride = stride.removeDataForShip();
-            }
-        }
-    }
-
-}
diff --git a/src/edu/berkeley/fleet/interpreter/ships/MemoryWriteShip.java b/src/edu/berkeley/fleet/interpreter/ships/MemoryWriteShip.java
deleted file mode 100644 (file)
index 7e33936..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-package edu.berkeley.fleet.interpreter.ships;
-import edu.berkeley.fleet.interpreter.*;
-
-import edu.berkeley.fleet.*;
-import java.util.*;
-import java.io.*;
-
-/**
- *  @author Thomas Kho <tkho@eecs.berkeley.edu>
- */
-public class MemoryWriteShip extends InterpreterShip {
-
-    int _count = 0;
-    int _stride = 0;
-    int _addr = 0;
-
-    DataInbox  addr   = new DataInbox(this, "addr");
-    DataInbox  stride = new DataInbox(this, "stride");
-    DataInbox  count  = new DataInbox(this, "count");
-    DataInbox  data   = new DataInbox(this, "data");
-    TokenOutbox done  = new TokenOutbox(this, "done");
-
-    public MemoryWriteShip(Interpreter fleet, String name) {
-        super(fleet, name);
-    }
-
-    public void service() {
-        if (_count > 0) {
-            if (!data.dataReadyForShip()) return;
-            //getInterpreter().writeMem(_addr, data.removeDataForShip());
-            _count--;
-            _addr += _stride;
-            if (_count==0)
-                done.addTokenFromShip();
-        } else {
-            if (count.dataReadyForShip() &&
-                addr.dataReadyForShip() &&
-                stride.dataReadyForShip() &&
-                done.readyForTokenFromShip() &&
-                data.dataReadyForShip()) {
-
-                _count  = count.removeDataForShip();
-                _addr   = addr.removeDataForShip();
-                _stride = stride.removeDataForShip();
-            }
-        }
-    }
-
-}
diff --git a/src/edu/berkeley/fleet/interpreter/ships/MultiplierShip.java b/src/edu/berkeley/fleet/interpreter/ships/MultiplierShip.java
deleted file mode 100644 (file)
index 3efd5da..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-package edu.berkeley.fleet.interpreter.ships;
-import edu.berkeley.fleet.interpreter.*;
-import edu.berkeley.fleet.*;
-
-import java.util.*;
-import java.io.*;
-
-/**
- * @author Dominic Antonelli <dantonel@berkeley.edu>
- */
-public class MultiplierShip extends InterpreterShip {
-
-    private int link;
-
-    DataInbox A = new DataInbox(this, "A");
-    DataInbox B = new DataInbox(this, "B");
-    DataOutbox out0 = new DataOutbox(this, "out0");
-    DataOutbox out1 = new DataOutbox(this, "out1");
-
-    public MultiplierShip(Interpreter fleet, String name) {
-        super(fleet, name);
-    }
-
-    public void service() {
-        if (!out0.readyForDataFromShip()) return;
-        if (!out1.readyForDataFromShip()) return;
-        if (!A.dataReadyForShip()) return;
-        if (!B.dataReadyForShip()) return;
-
-        long inA = (long)A.removeDataForShip();
-        long inB = (long)B.removeDataForShip();
-        long result = inA * inB;
-        int result0 = (int)(result >> 32);
-        int result1 = (int)(result & 0xffffffff);
-
-        out0.addDataFromShip(result0);
-        out1.addDataFromShip(result1);
-    }
-}
diff --git a/src/edu/berkeley/fleet/interpreter/ships/Mux.java b/src/edu/berkeley/fleet/interpreter/ships/Mux.java
deleted file mode 100644 (file)
index 86a2822..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-package edu.berkeley.fleet.interpreter.ships;
-import edu.berkeley.fleet.interpreter.*;
-import edu.berkeley.fleet.*;
-
-import java.util.*;
-import java.io.*;
-
-public class Mux extends InterpreterShip {
-
-    DataInbox   ap      = new DataInbox(this,  "a");
-    DataInbox   bp      = new DataInbox(this,  "b");
-    DataInbox   choicep = new DataInbox(this, "select");
-    DataOutbox  out     = new DataOutbox(this, "out");
-
-    public Mux(Interpreter fleet, String name) { super(fleet, name); }
-
-    public String getBalsaName() { return "mux"; }
-
-    public void service() {
-        if (ap.dataReadyForShip() && bp.dataReadyForShip() && choicep.dataReadyForShip()) {
-            int a      = ap.removeDataForShip();
-            int b      = bp.removeDataForShip();
-            int choice = choicep.removeDataForShip();
-            out.addDataFromShip(choice==0 ? a : b);
-        }
-    }
-
-}
diff --git a/src/edu/berkeley/fleet/interpreter/ships/ScatterShip.java b/src/edu/berkeley/fleet/interpreter/ships/ScatterShip.java
deleted file mode 100644 (file)
index 4f6b892..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-package edu.berkeley.fleet.interpreter.ships;
-import edu.berkeley.fleet.interpreter.*;
-import edu.berkeley.fleet.*;
-
-import java.util.*;
-import java.io.*;
-
-/**
- * @author Dominic Antonelli <dantonel@berkeley.edu>
- */
-public class ScatterShip extends InterpreterShip {
-
-    DataInbox   in  = new DataInbox(this, "in");
-    Vector<DataOutbox> out = new Vector<DataOutbox>();
-
-    private int size = 2;
-    private int state = 0;
-
-    public ScatterShip(Interpreter fleet, String name) {
-        super(fleet, name);
-        init();
-    }
-
-    private boolean initialized = false;
-    private void init() {
-        for (int i = 0; i < size; i++) {
-            out.add(new DataOutbox(this, "out" + i));
-        }
-        initialized = true;
-    }
-
-    public void service() {
-        if (!initialized) init();
-        if (in.dataReadyForShip() && out.get(state).readyForDataFromShip()) {
-            out.get(state).addDataFromShip(in.removeDataForShip());
-            state = (state + 1) % size;
-        }
-    }
-
-    public int resolveShipSpecificConstant(String shipSpecificData) {
-        return 0;
-    }
-
-}
diff --git a/src/edu/berkeley/fleet/interpreter/ships/Sort2.java b/src/edu/berkeley/fleet/interpreter/ships/Sort2.java
deleted file mode 100644 (file)
index 90cb3e4..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-package edu.berkeley.fleet.interpreter.ships;
-import edu.berkeley.fleet.interpreter.*;
-import edu.berkeley.fleet.*;
-
-import java.util.*;
-import java.io.*;
-
-public class Sort2 extends InterpreterShip {
-
-    DataInbox   ap  = new DataInbox(this,  "a");
-    DataInbox   bp  = new DataInbox(this,  "b");
-    DataOutbox  min = new DataOutbox(this, "min");
-    DataOutbox  max = new DataOutbox(this, "max");
-
-    public Sort2(Interpreter fleet, String name) { super(fleet, name); }
-
-    public String getBalsaName() { return "sort2"; }
-
-    public void service() {
-        if (ap.dataReadyForShip() && bp.dataReadyForShip()) {
-            int a      = ap.removeDataForShip();
-            int b      = bp.removeDataForShip();
-            max.addDataFromShip(Math.max(a,b));
-            min.addDataFromShip(Math.min(a,b));
-        }
-    }
-
-}
index a0a7f2b..02f9303 100644 (file)
@@ -1,5 +1,5 @@
 package edu.berkeley.fleet.slipway;
-import edu.berkeley.fleet.interpreter.*;
+import edu.berkeley.fleet.slipway.*;
 import edu.berkeley.fleet.doc.*;
 import edu.berkeley.fleet.api.*;
 import edu.berkeley.fleet.ies44.*;
@@ -12,12 +12,19 @@ import edu.berkeley.sbp.bind.*;
 import edu.berkeley.sbp.util.*;
 import java.util.*;
 import java.io.*;
-import edu.berkeley.fleet.interpreter.ships.*;
 
-public class Slipway extends Interpreter {
+public class Slipway extends Fleet {
+
+    public ArrayList<SlipwayShip> shiplist   = new ArrayList<SlipwayShip>();
+    public HashMap<String,SlipwayShip> ships = new HashMap<String,SlipwayShip>();
+    public Iterator<Ship> iterator() { return (Iterator<Ship>)(Object)shiplist.iterator(); }
 
     private String bitfile;
 
+    public static void main(String[] s) throws Exception {
+        new Slipway().dumpFabric(false);
+    }
+
     public Slipway() { this("valentine.bit"); }
     public Slipway(String bitfile) {
         this.bitfile = bitfile;
@@ -42,20 +49,13 @@ public class Slipway extends Interpreter {
     }
 
     public Ship createShip(String type, String name) {
-        InterpreterShip ship = (InterpreterShip)super.createShip(type, name);
-        if        (ship.getClass().getSimpleName().equals("Debug")) {
-            new DataOutbox(ship, "out", true);
-            
-        } else if (ship.getClass().getSimpleName().equals("Execute")) {
-            new DataOutbox(ship, "ihorn", true, true, false);
-            new DataOutbox(ship, "dhorn", true, false, true);
-            
-        } else if (ship.getClass().getSimpleName().equals("Iscratch")) {
-            new DataInbox(ship,  "command", true);
-            new DataOutbox(ship, "ihorn",   true, true, false);
-            new DataOutbox(ship, "dhorn",   true, false, true);
-        }
-        return ship;
+        try {
+            ShipDescription sd = new ShipDescription(new BufferedReader(new InputStreamReader(new FileInputStream("ships/"+type+".ship"))));
+            SlipwayShip ship = new SlipwayShip(this, name, type, sd);
+            ships.put(name, ship);
+            shiplist.add(ship);
+            return ship;
+        } catch (IOException e) { throw new RuntimeException(e); }
     }
 
     public FleetProcess run(final byte[] instructions) {
@@ -68,43 +68,43 @@ public class Slipway extends Interpreter {
         // 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<InterpreterBenkoBox>();
-        for(InterpreterShip ship : shiplist)
+        ArrayList instructionports = new ArrayList<SlipwayBenkoBox>();
+        for(SlipwayShip ship : shiplist)
             for(BenkoBox port : ship.getBenkoBoxes())
-                if (!((InterpreterBenkoBox)port).special())
+                if (!((SlipwayBenkoBox)port).special())
                     instructionports.add(port);
         FabricTree instructions =
-            new FabricTree((InterpreterBenkoBox[])instructionports.toArray(new InterpreterBenkoBox[0]),
+            new FabricTree((SlipwayBenkoBox[])instructionports.toArray(new SlipwayBenkoBox[0]),
                            "ihorn",
                            "instruction");
 
-        ArrayList inputports = new ArrayList<InterpreterBenkoBox>();
-        for(InterpreterShip ship : shiplist)
+        ArrayList inputports = new ArrayList<SlipwayBenkoBox>();
+        for(SlipwayShip ship : shiplist)
             for(BenkoBox port : ship.getBenkoBoxes())
-                if (!((InterpreterBenkoBox)port).special())
+                if (!((SlipwayBenkoBox)port).special())
                     inputports.add(port);
         FabricTree inputs =
-            new FabricTree((InterpreterBenkoBox[])inputports.toArray(new InterpreterBenkoBox[0]),
+            new FabricTree((SlipwayBenkoBox[])inputports.toArray(new SlipwayBenkoBox[0]),
                            "horn",
                            "dest");
 
-        ArrayList outputports = new ArrayList<InterpreterBenkoBox>();
-        for(InterpreterShip ship : shiplist)
+        ArrayList outputports = new ArrayList<SlipwayBenkoBox>();
+        for(SlipwayShip ship : shiplist)
             for(BenkoBox port : ship.getBenkoBoxes())
-                if (!((InterpreterBenkoBox)port).special() || ((InterpreterBenkoBox)port).dhorn())
+                if (!((SlipwayBenkoBox)port).special() || ((SlipwayBenkoBox)port).dhorn())
                     outputports.add(port);
         FabricTree outputs =
-            new FabricTree((InterpreterBenkoBox[])outputports.toArray(new InterpreterBenkoBox[0]),
+            new FabricTree((SlipwayBenkoBox[])outputports.toArray(new SlipwayBenkoBox[0]),
                            "funnel",
                            "source");
 
-        ArrayList ihornports = new ArrayList<InterpreterBenkoBox>();
-        for(InterpreterShip ship : shiplist)
+        ArrayList ihornports = new ArrayList<SlipwayBenkoBox>();
+        for(SlipwayShip ship : shiplist)
             for(BenkoBox port : ship.getBenkoBoxes())
-                if (((InterpreterBenkoBox)port).ihorn())
+                if (((SlipwayBenkoBox)port).ihorn())
                     ihornports.add(port);
         FabricTree ihorns =
-            new FabricTree((InterpreterBenkoBox[])ihornports.toArray(new InterpreterBenkoBox[0]),
+            new FabricTree((SlipwayBenkoBox[])ihornports.toArray(new SlipwayBenkoBox[0]),
                            "funnel",
                            "ihorn");
         
@@ -129,9 +129,9 @@ public class Slipway extends Interpreter {
         outputs.dumpChannels(true);
         inputs.dumpChannels(true);
         ihorns.dumpChannels(true);
-        for(InterpreterShip ship : shiplist)
+        for(SlipwayShip ship : shiplist)
             for(BenkoBox port : ship.getBenkoBoxes())
-                if (!((InterpreterBenkoBox)port).special() || ((InterpreterBenkoBox)port).dhorn())
+                if (!((SlipwayBenkoBox)port).special() || ((SlipwayBenkoBox)port).dhorn())
                     System.out.println("  wire [(`PACKET_WIDTH-1):0] data_"
                                        +getUniqueName(ship)+"_"+port.getName()+";");
 
@@ -144,8 +144,8 @@ public class Slipway extends Interpreter {
         System.out.println("");
         ihorns.dumpChannels(false);
         System.out.println("");
-        for(InterpreterShip ship : shiplist) {
-            System.out.print(ship.getClass().getSimpleName().toLowerCase());
+        for(SlipwayShip ship : shiplist) {
+            System.out.print(ship.getType().toLowerCase());
             System.out.print(" ");
             System.out.print("krunk"+(krunk++));
             System.out.print("(clk, ");
@@ -154,8 +154,8 @@ public class Slipway extends Interpreter {
                 if (!first) System.out.print(", ");
                 first = false;
                 String prefix = "data_";
-                if (((InterpreterBenkoBox)port).ihorn()) prefix = "ihorn_";
-                if (((InterpreterBenkoBox)port).dhorn()) prefix = "source_";
+                if (((SlipwayBenkoBox)port).ihorn()) prefix = "ihorn_";
+                if (((SlipwayBenkoBox)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());
@@ -164,8 +164,8 @@ public class Slipway extends Interpreter {
             System.out.println(");");
 
             for(BenkoBox port : ship.getBenkoBoxes()) {
-                if (((InterpreterBenkoBox)port).special()) continue;
-                if (port instanceof Inbox) {
+                if (((SlipwayBenkoBox)port).special()) continue;
+                if (((SlipwayBenkoBox)port).inbox) {
                     System.out.print("inbox");
                 } else {
                     System.out.print("outbox");
@@ -208,21 +208,28 @@ public class Slipway extends Interpreter {
         String prefix;
         Node root;
         public void dumpChannels(boolean decl) { root.dumpChannels(0, decl); }
-        public FabricTree(InterpreterBenkoBox[] ports, String component, String prefix) {
+        public FabricTree(SlipwayBenkoBox[] 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, InterpreterBenkoBox[] ports,
+        private Object mkNode(String name, String component, SlipwayBenkoBox[] ports,
                               int start, int end, int addr, int bits) {
             if (end-start == 0) return null;
             if (end-start == 1) {
-                InterpreterBenkoBox p = ports[start];
+                SlipwayBenkoBox p = ports[start];
                 if (prefix.equals("instruction")) {
                     p.instr_addr = addr;
                     p.instr_bits = bits;
                 } else if (prefix.equals("dest")) {
                     p.addr = addr;
                     p.bits = bits;
+                    int count = 1;
+                    for(Destination d : p.getDestinations()) {
+                        if (!(d instanceof SlipwayBenkoBox.VirtualPort)) continue;
+                        SlipwayBenkoBox.VirtualPort vp = (SlipwayBenkoBox.VirtualPort)d;
+                        vp.addr = p.addr | (count << (bits+1));
+                        count++;
+                    }
                 }
                 return p;
             }
@@ -236,8 +243,8 @@ public class Slipway extends Interpreter {
         }
         private String describe(String prefix, Object o) {
             if (o==null) return null;
-            if (o instanceof InterpreterBenkoBox) {
-                InterpreterBenkoBox p = (InterpreterBenkoBox)o;
+            if (o instanceof SlipwayBenkoBox) {
+                SlipwayBenkoBox p = (SlipwayBenkoBox)o;
                 return prefix+"_"+getUniqueName(p.getShip())+"_"+p.getName();
             }
             if (o instanceof Node) {
@@ -312,7 +319,7 @@ public class Slipway extends Interpreter {
 
     public void expand(ShipDescription sd) {
         try {
-            String filename = sd.name.toLowerCase();
+            String filename = sd.getName().toLowerCase();
             File outf = new File("src/edu/berkeley/fleet/slipway/"+filename+".v");
             new File(outf.getParent()).mkdirs();
             System.err.println("writing to " + outf);
@@ -324,11 +331,10 @@ public class Slipway extends Interpreter {
                 pw.println("`include \"macros.v\"");
                 pw.println();
                 pw.println("module " + filename + "( clk");
-                for(ShipDescription.BenkoBox bb : sd.benkoBoxes) {
-                    if (bb.ports.length > 1) throw new RuntimeException("gah");
-                    String bb_name = bb.ports[0];
+                for(BenkoBoxDescription bb : sd) {
+                    String bb_name = bb.getName();
                     pw.print("        ");
-                    if (bb.inbox) {
+                    if (bb.isInbox()) {
                         pw.print(", " + bb_name+"_r");
                         pw.print(", " + bb_name+"_a_");
                         pw.print(", " + bb_name+"_d");
@@ -342,11 +348,10 @@ public class Slipway extends Interpreter {
                 pw.println("        );");
                 pw.println();
                 pw.println("    input clk;");
-                for(ShipDescription.BenkoBox bb : sd.benkoBoxes) {
-                    if (bb.ports.length > 1) throw new RuntimeException("gah");
-                    String bb_name = bb.ports[0];
+                for(BenkoBoxDescription bb : sd) {
+                    String bb_name = bb.getName();
                     pw.print("        ");
-                    if (bb.inbox) {
+                    if (bb.isInbox()) {
                         pw.println("`input(" +
                                    bb_name+"_r,  "+
                                    bb_name+"_a,  "+
@@ -372,7 +377,7 @@ public class Slipway extends Interpreter {
                 }
             }
 
-            pw.println(sd.sections.get("fpga"));
+            pw.println(sd.getSection("fpga"));
 
             if (auto)
                 pw.println("endmodule");
@@ -382,4 +387,43 @@ public class Slipway extends Interpreter {
         } 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 SlipwayInstructionEncoder iie = new SlipwayInstructionEncoder();
+    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); }
+
+    private class SlipwayInstructionEncoder extends InstructionEncoder {
+        public long getDestAddr(Destination box) {
+            long ret;
+            if (box instanceof SlipwayBenkoBox)
+                ret = ((SlipwayBenkoBox)box).addr;
+            else
+                ret = ((SlipwayBenkoBox.VirtualPort)box).addr;
+            return ret;
+        }
+        public long getBoxInstAddr(BenkoBox box) { return ((SlipwayBenkoBox)box).instr_addr; }
+        public Destination getDestByAddr(long dest) {
+            for(Ship ship : Slipway.this)
+                for(BenkoBox bb : ship.getBenkoBoxes()) {
+                    if (((SlipwayBenkoBox)bb).addr == dest)
+                        return bb;
+                    for(Destination d : bb.getDestinations())
+                        if (getDestAddr(d)==dest)
+                            return d;
+                }
+            return null;
+        }
+        public BenkoBox getBoxByInstAddr(long dest) {
+            for(Ship ship : Slipway.this)
+                for(BenkoBox bb : ship.getBenkoBoxes())
+                    if (((SlipwayBenkoBox)bb).instr_addr == dest)
+                        return bb;
+            return null;
+        }
+    }
+
 }
\ No newline at end of file
diff --git a/src/edu/berkeley/fleet/slipway/SlipwayBenkoBox.java b/src/edu/berkeley/fleet/slipway/SlipwayBenkoBox.java
new file mode 100644 (file)
index 0000000..322c9dc
--- /dev/null
@@ -0,0 +1,95 @@
+package edu.berkeley.fleet.slipway;
+import edu.berkeley.fleet.api.*;
+import edu.berkeley.fleet.api.BenkoBox;
+import java.util.*;
+
+/** anything that has a destination address on the switch fabric */
+public class SlipwayBenkoBox extends BenkoBox {
+        
+    private final String name;
+    private final SlipwayShip ship;
+    private final Destination[] ports;
+        
+    public Iterable<Destination> getDestinations() {
+        HashSet<Destination> ret = new HashSet<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++);
+    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 SlipwayBenkoBox(boolean inbox, SlipwayShip ship, String name) {
+        this(inbox, ship, name, false, false, false);
+    }
+    public SlipwayBenkoBox(boolean inbox, SlipwayShip ship, String name, boolean special) {
+        this(inbox, ship, name, special, false, false);
+    }
+    public SlipwayBenkoBox(boolean inbox, SlipwayShip ship, String name, boolean special, boolean ihorn, boolean dhorn) {
+        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] =
+                ports[i].equals("")
+                ? this
+                : new VirtualPort(ports[i]);
+        ship.addBenkoBox(name, this);
+    }
+
+
+    public class VirtualPort extends Destination {
+        public String name;
+        public VirtualPort(String name) { this.name = name; }
+        public String getDestinationName() { return name; }
+        public Ship getShip() { return SlipwayBenkoBox.this.getShip(); }
+        public void addDataFromFabric(long data) { SlipwayBenkoBox.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; }
+
+}
diff --git a/src/edu/berkeley/fleet/slipway/SlipwayShip.java b/src/edu/berkeley/fleet/slipway/SlipwayShip.java
new file mode 100644 (file)
index 0000000..cbcf968
--- /dev/null
@@ -0,0 +1,55 @@
+package edu.berkeley.fleet.slipway;
+import edu.berkeley.fleet.doc.*;
+import edu.berkeley.fleet.api.*;
+import java.util.*;
+import java.io.*;
+
+/** a ship, which belongs to a fleet and which may have many ports */
+public class SlipwayShip extends Ship {
+        
+    /** You should instantiate a bunch of Inboxes and Outboxes in your constructor */
+    public SlipwayShip(Slipway fleet, String name, String type, ShipDescription sd) {
+        this.fleet = fleet; this.type = type;
+        for(BenkoBoxDescription sdbb : sd)
+            new SlipwayBenkoBox(sdbb.isInbox(), this, sdbb.getName());
+        if        (type.equals("Debug")) {
+            new SlipwayBenkoBox(false, this, "out", true);
+            
+        } else if (type.equals("Execute")) {
+            new SlipwayBenkoBox(false, this, "ihorn", true, true, false);
+            new SlipwayBenkoBox(false, this, "dhorn", true, false, true);
+            
+        } else if (type.equals("Iscratch")) {
+            new SlipwayBenkoBox(true,  this,  "command", true);
+            new SlipwayBenkoBox(false, this, "ihorn",   true, true, false);
+            new SlipwayBenkoBox(false, this, "dhorn",   true, false, true);
+        }
+    }
+
+    private Slipway 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<SlipwayBenkoBox> portlist = new ArrayList<SlipwayBenkoBox>();
+    private HashMap<String,SlipwayBenkoBox> ports = new HashMap<String,SlipwayBenkoBox>();
+
+    public Iterable<BenkoBox> getBenkoBoxes() { return (Iterable<BenkoBox>)(Object)portlist; }
+    public String getType()                   { return type; }
+    public Fleet  getFleet()                  { return fleet; }
+    public Slipway  getSlipway()              { return fleet; }
+
+    void addBenkoBox(String name, SlipwayBenkoBox port) { ports.put(name, port); portlist.add(port); }
+
+}