added Dominics contributions
authoradam <adam@megacz.com>
Fri, 1 Dec 2006 10:45:13 +0000 (11:45 +0100)
committeradam <adam@megacz.com>
Fri, 1 Dec 2006 10:45:13 +0000 (11:45 +0100)
src/edu/berkeley/fleet/ships/ArithmeticShip.java
src/edu/berkeley/fleet/ships/DuplicatorShip.java [new file with mode: 0644]
src/edu/berkeley/fleet/ships/MultiplierShip.java [new file with mode: 0644]
src/edu/berkeley/fleet/ships/ScatterShip.java [new file with mode: 0644]

index c866aa0..7d104d0 100644 (file)
@@ -4,56 +4,158 @@ 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 Ship {
 
-    TokenOutbox tout    = new TokenOutbox(this, "tout");
-    TokenInbox  tin     = new TokenInbox(this, "tin");
-    DataOutbox dout     = new DataOutbox(this, "dout");
-    DataInbox  din      = new DataInbox(this, "din");
+    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(Fleet fleet, String name) {
         super(fleet, name);
     }
 
-    public void service() {
+    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; } };
 
-        // dominic, pretend this method is inside an infinite loop;
-        // every time it is invoked you should:
 
-        // 1. check your input ports to see if they have stuff
 
-        // 2. make sure your output ports don't still have stuff stuck
-        //    in them (if they do, just return and wait until later)
+        // 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];
+        }
+    }
 
-        // 3. do your thing
+    public enum LinkOutPolicy {
+        LINK_IN, ZERO, CARRY, SIGN, OLD_SIGN, OVERFLOW, MAX, MIN;
+        public static LinkOutPolicy convertInt( int i ) {
+            return values()[i];
+        }
+    }
 
-        // here's some sample code snippets that should cover all the
-        //    cases you need
+    private long savedCommand = 0;
 
-        if (!din.dataReadyForShip())
-            return;
-        /*
-        if (!tin.tokenReadyForShip())
+    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;
-        */
-
-        int mydat = din.removeDataForShip();
-        Log.println("ArithmeticShip: got a " + mydat);
-        /*
-        tin.removeTokenForShip();
-        */
-
-        /*
-        if (tout.readyForTokenFromShip())
-            tout.addTokenFromShip();
-        if (dout.readyForDataFromShip())
-            dout.addDataFromShip(123);
-        */
+        } 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) {
-        // normally you would want to parse shipSpecificData somehow
-        return shipSpecificData.length();
-    }
+        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/ships/DuplicatorShip.java b/src/edu/berkeley/fleet/ships/DuplicatorShip.java
new file mode 100644 (file)
index 0000000..271dd16
--- /dev/null
@@ -0,0 +1,35 @@
+package edu.berkeley.fleet.ships;
+import edu.berkeley.fleet.*;
+
+import java.util.*;
+import java.io.*;
+
+/**
+ * @author Dominic Antonelli <dantonel@berkeley.edu>
+ */
+public class DuplicatorShip extends Ship {
+
+    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 (Fleet 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/ships/MultiplierShip.java b/src/edu/berkeley/fleet/ships/MultiplierShip.java
new file mode 100644 (file)
index 0000000..f5a8945
--- /dev/null
@@ -0,0 +1,38 @@
+package edu.berkeley.fleet.ships;
+import edu.berkeley.fleet.*;
+
+import java.util.*;
+import java.io.*;
+
+/**
+ * @author Dominic Antonelli <dantonel@berkeley.edu>
+ */
+public class MultiplierShip extends Ship {
+
+    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(Fleet 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/ships/ScatterShip.java b/src/edu/berkeley/fleet/ships/ScatterShip.java
new file mode 100644 (file)
index 0000000..a1919ef
--- /dev/null
@@ -0,0 +1,43 @@
+package edu.berkeley.fleet.ships;
+import edu.berkeley.fleet.*;
+
+import java.util.*;
+import java.io.*;
+
+/**
+ * @author Dominic Antonelli <dantonel@berkeley.edu>
+ */
+public class ScatterShip extends Ship {
+
+    DataInbox   in  = new DataInbox(this, "in");
+    Vector<DataOutbox> out = new Vector<DataOutbox>();
+
+    private int size = 2;
+    private int state = 0;
+
+    public ScatterShip(Fleet 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;
+    }
+
+}