finish overhaul of interpreter
authoradam <adam@megacz.com>
Thu, 26 Jun 2008 10:32:56 +0000 (11:32 +0100)
committeradam <adam@megacz.com>
Thu, 26 Jun 2008 10:32:56 +0000 (11:32 +0100)
ships/Memory.ship
src/edu/berkeley/fleet/assembler/Parser.java
src/edu/berkeley/fleet/interpreter/Interpreter.java
src/edu/berkeley/fleet/interpreter/InterpreterDestination.java
src/edu/berkeley/fleet/interpreter/InterpreterDock.java
src/edu/berkeley/fleet/two/FleetTwoFleet.java

index 8d86208..4718196 100644 (file)
@@ -94,15 +94,22 @@ sequence guarantee problem mentioned in the previous paragraph.
     private long addr = 0;
     private boolean writing = false;
 
+    private Queue<Long> toDispatch = new LinkedList<Long>();
     public void service() {
-/*
-        if (box_inCBD.dataReadyForShip()) {
+
+        if (toDispatch.size() > 0) {
+            //if (!box_out.readyForDataFromShip()) return;
+            //box_out.addDataFromShip(toDispatch.remove());
+            getInterpreter().dispatch(getInterpreter().readInstruction(toDispatch.remove(), getDock("out")));
+        }
+
+        if (box_inCBD.dataReadyForShip() && box_out.readyForDataFromShip()) {
             long val = box_inCBD.removeDataForShip();
             long addr = val >> 6;
             long size = val & 0x3f;
-            dispatch((int)addr, (int)size);
+            for(int i=0; i<size; i++)
+              toDispatch.add(readMem((int)(addr+i)));
         }
-*/
         if (count > 0) {
             if (writing) {
               if (box_inDataWrite.dataReadyForShip() && box_out.readyForDataFromShip()) {
@@ -126,8 +133,7 @@ sequence guarantee problem mentioned in the previous paragraph.
             writing = false;
 
         } else if (box_inAddrWrite.dataReadyForShip()) {
-//            addr = box_inAddrWrite.peekPacketForShip().value;
-            box_inAddrWrite.removeDataForShip();
+            addr = box_inAddrWrite.removeDataForShip();
             stride = 0;
             count = 1;
             writing = true;
index 9f374be..34688a3 100644 (file)
@@ -150,7 +150,7 @@ public class Parser {
         }
 
         for(int i=0; i<instructions.length; i++) {
-            long lit = ((Fpga)fpga).writeInstruction(instructions[i], out);
+            long lit = ((FleetTwoFleet)fpga).writeInstruction(instructions[i], out);
             ret.add(discard(out));
             ret.add(new Instruction.Shift(inDataWrite, false, IgnoreOLC, new BitVector(fpga.getWordWidth()).set(getField(36, 19, lit))));
             ret.add(new Instruction.Shift(inDataWrite, false, IgnoreOLC, new BitVector(fpga.getWordWidth()).set(getField(18,  0, lit))));
index 556650a..2109085 100644 (file)
@@ -11,8 +11,8 @@ import edu.berkeley.fleet.util.*;
 
 public class Interpreter extends FleetTwoFleet implements Parser.FleetWithDynamicShips {
 
-    private BlockingQueue<BitVector> debugStream = new LinkedBlockingQueue<BitVector>();
     private InterpreterShip debugShip = null;
+    private BlockingQueue<BitVector> debugStream = new LinkedBlockingQueue<BitVector>();
     private HashMap<String,InterpreterShip> ships = new HashMap<String,InterpreterShip>();
     public Iterator<Ship> iterator() { return (Iterator<Ship>)(Object)ships.values().iterator(); }
     public Ship getShip(String type, int ordinal) {
@@ -25,7 +25,9 @@ public class Interpreter extends FleetTwoFleet implements Parser.FleetWithDynami
 
     void dispatch(Instruction i) {
         Log.dispatch(i);
-        ((InterpreterDock)i.dock).addInstruction(i);
+        long il = writeInstruction(i, debugShip.getDock("in"));
+        Path path = debugShip.getDock("in").getPath(i.dock.getInstructionDestination(), null);
+        new Packet((InterpreterPath)path, new BitVector(getWordWidth()).set(il), false).send();
     }
 
     public Ship createShip(String shipType, String shipname) {
@@ -45,9 +47,7 @@ public class Interpreter extends FleetTwoFleet implements Parser.FleetWithDynami
         }
     }
 
-    void debug(long d) {
-        throw new RuntimeException();
-    }
+    void debug(long d) { debug(new BitVector(getWordWidth()).set(d)); }
     void debug(BitVector data) {
         try {
             if (debugStream != null) debugStream.put(data);
@@ -62,8 +62,10 @@ public class Interpreter extends FleetTwoFleet implements Parser.FleetWithDynami
     public long getDestAddr(Path path) {
         long ret = ((InterpreterDestination)path.getDestination()).addr;
         BitVector bv = path.getSignal();
-        if (bv.length() > 1) throw new RuntimeException();
-        if (bv.length() > 0 && bv.get(0)) ret |= 1;
+        if (bv != null) {
+            if (bv.length() > 1) throw new RuntimeException("signal was " + bv.length() + " bits long!");
+            if (bv.length() > 0 && bv.get(0)) ret |= 1;
+        }
         return ret;
     }
 
@@ -122,6 +124,8 @@ public class Interpreter extends FleetTwoFleet implements Parser.FleetWithDynami
         private Instruction[] instructions;
         public InterpreterProcess(Instruction[] instructions) {
             this.instructions = instructions;
+            for(Instruction i : instructions)
+                dispatchInstruction(i);
         }
         public void dispatchInstruction(Instruction i) { dispatch(i); }
         public Dock getDebugInputDock() { return debugShip.getDock("in"); }
index 6bb3971..e228a4d 100644 (file)
@@ -8,8 +8,13 @@ class InterpreterDestination extends Destination {
 
     int addr;
 
+    Queue<Packet> packets = new LinkedList<Packet>();
+
+    private boolean isInstructionDestination;
+
     public InterpreterDestination(InterpreterDock d, boolean isInstructionDestination) {
         super(d);
+        this.isInstructionDestination = isInstructionDestination;
         synchronized(InterpreterDestination.class) {
             this.addr = max_dest;
             max_dest += 2;
@@ -18,11 +23,10 @@ class InterpreterDestination extends Destination {
 
     /** adds the included datum to the port from the switch fabric  side */
     public void addDataFromFabric(Packet packet) {
-        throw new RuntimeException();
+        packets.add(packet);
     }
 
-
     public String toString() {
-        return "";
+        return getDock()+(isInstructionDestination ? ":i" : "");
     }
 }
index a578fa9..1610d19 100644 (file)
@@ -18,9 +18,15 @@ class InterpreterDock extends FleetTwoDock {
     public int olc = 1;
     public BitVector dataLatch = new BitVector(getShip().getFleet().getWordWidth());
     public InterpreterPath pathLatch = null;
+    public InterpreterPath tapl = null;
     public boolean hatchIsOpen = true;
     private Instruction executing = null;
     private Queue<Instruction> instructions = new LinkedList<Instruction>();
+    private Queue<Instruction> epilogue = new LinkedList<Instruction>();
+    private boolean dataReadyForShip = false;
+    private boolean readyForDataFromShip = true;
+    private long dataFromShip;
+    private boolean torpedoWaiting = false;
 
     protected void reset() {
         ilc = 1;
@@ -33,6 +39,11 @@ class InterpreterDock extends FleetTwoDock {
         hatchIsOpen = true;
         executing = null;
         instructions.clear();
+        epilogue.clear();
+        dataReadyForShip = false;
+        readyForDataFromShip = true;
+        tapl = null;
+        torpedoWaiting = false;
     }
 
     // Destinations //////////////////////////////////////////////////////////////////////////////
@@ -45,10 +56,6 @@ class InterpreterDock extends FleetTwoDock {
         super(ship, bbd);
     }
 
-    public void addInstruction(Instruction i) {
-        throw new RuntimeException();
-    }
-
     public Path getPath(Destination d, BitVector signal) { return new InterpreterPath(this, (InterpreterDestination)d, signal); }
     public Destination getInstructionDestination() { return instructionDestination; }
     public Destination getDataDestination() { return dataDestination; }
@@ -58,93 +65,229 @@ class InterpreterDock extends FleetTwoDock {
     // interface to subclass ///////////////////////////////////////////////////////////////////////
 
     /** this will be invoked periodically; should return true to "consume" an instruction, false to leave it executing */
-    protected void setDataLatch(long value) { throw new RuntimeException(); }
-    protected long peekDataLatch() { throw new RuntimeException(); }
-    public boolean dataReadyForShip()            { throw new RuntimeException(); }
-    public Packet removePacketForShip()          { throw new RuntimeException(); }
-    public Packet peekPacketForShip()            { throw new RuntimeException(); }
-    public long removeDataForShip()              { throw new RuntimeException(); }
-    public final boolean readyForDataFromShip() { throw new RuntimeException(); }
-    public       void addDataFromShip(long data) { throw new RuntimeException(); }
-    public       void addDataFromFabric(Packet packet) { throw new RuntimeException(); }
-    protected final void addItemFromShip(long data) { throw new RuntimeException(); }
+
+    public boolean dataReadyForShip() { return dataReadyForShip; }
+    public final boolean readyForDataFromShip() { return readyForDataFromShip; }
+
+    public long removeDataForShip() {
+        if (!dataReadyForShip) throw new RuntimeException();
+        dataReadyForShip = false;
+        BitVector bv = dataLatch;
+        long val = 0;
+        for(int i=0; i<bv.length(); i++)
+            if (bv.get(i))
+                val |= (1L << i);
+        return val;
+    }
+    public void addDataFromShip(long data) {
+        if (!readyForDataFromShip()) throw new RuntimeException();
+        readyForDataFromShip = false;
+        dataFromShip = data;
+    }
 
     protected final void service() {
-            /*
+
+        if (instructionDestination.packets.size() > 0) {
+            Packet p = instructionDestination.packets.remove();
+            if (p.isToken) {
+                if (torpedoWaiting) throw new RuntimeException("two torpedoes collided!");
+                torpedoWaiting = true;
+            } else {
+                BitVector bv = p.value;
+                long val = 0;
+                for(int i=0; i<bv.length(); i++)
+                    if (bv.get(i))
+                        val |= (1L << i);
+                epilogue.add(getInterpreter().readInstruction(val, this));
+            }
+        }
+
+        if (hatchIsOpen && epilogue.size() > 0) {
+            Instruction inst = epilogue.remove();
+            if (inst instanceof Instruction.Tail)
+                hatchIsOpen = false;
+            else
+                instructions.add(inst);
+        }
+
+        if (dataReadyForShip) return;
+
         if (executing==null && instructions.size() > 0) executing = instructions.remove();
         if (executing==null) return;
 
+        if (executing.looping && hatchIsOpen && olc>0) return;
+
         boolean enabled = true;
-        if (executing instanceof Instruction.PredicatedInstruction) {
-            Instruction.PredicatedInstruction ip = (Instruction.PredicatedInstruction)executing;
-            switch(ip.predicate) {
-                case IgnoreOLC:      enabled = true; break;
-                case Default:  enabled = loopCounter!=0; break;
-                case FlagA:   enabled = flag_a; break;
-                case FlagB:   enabled = flag_b; break;
-                    //case FlagC:   enabled = ; break;
-                case NotFlagA:   enabled = !flag_a; break;
-                case NotFlagB:   enabled = !flag_b; break;
-                    //case NotFlagC:   enabled = loopCounter==0; break;
-            }
+        switch(executing.predicate) {
+            case IgnoreOLC:  enabled =  true;   break;
+            case Default:    enabled =  olc>0;  break;
+            case FlagA:      enabled =  flag_a; break;
+            case FlagB:      enabled =  flag_b; break;
+            case FlagC:      enabled =  flag_c; break;
+            case NotFlagA:   enabled = !flag_a; break;
+            case NotFlagB:   enabled = !flag_b; break;
+            case NotFlagC:   enabled = !flag_c; break;
+            default: throw new RuntimeException();
+        }
+        if (!enabled) {
+            if (executing.looping && olc>0)
+                instructions.add(executing);
+            executing = null;
+            return;
         }
 
-        int oldLoopCounter = loopCounter;
-        if (enabled) {
-            if (executing instanceof Instruction.Set.OLC.Decrement) loopCounter = Math.max(0, loopCounter-1);
-            if (executing instanceof Instruction.Counter) {
-                Instruction.Counter ic = (Instruction.Counter)executing;
-                if (ic.source == Instruction.Counter.LOOP_COUNTER && ic.dest == Instruction.Counter.DATA_LATCH) {
-                    setDataLatch(oldLoopCounter); // FIXME: which is correct here?
-                } else if (ic.dest == Instruction.Counter.LOOP_COUNTER && ic.source == Instruction.Counter.DATA_LATCH) {
-                    loopCounter = (int)peekDataLatch();
-                } else if (ic.dest == Instruction.Counter.REPEAT_COUNTER && ic.source == Instruction.Counter.DATA_LATCH) {
-                    // FIXME: is there any way to load the "standing" value?
-                    repeatCounter = (int)peekDataLatch();
-                } else if (ic.dest == Instruction.Counter.LOOP_COUNTER) {
-                    loopCounter = ic.source;
-                } else if (ic.dest == Instruction.Counter.REPEAT_COUNTER && ic.source==Instruction.Counter.STANDING) {
-                    repeatCounter = -1;
-                } else if (ic.dest == Instruction.Counter.REPEAT_COUNTER) {
-                    repeatCounter = ic.source;
-                }
+        if (executing instanceof Instruction.Move) {
+            Instruction.Move move = (Instruction.Move)executing;
 
-                } else if (executing instanceof Instruction.Set.Flags) {
-                Instruction.Set.Flags sf = (Instruction.Set.Flags)executing;
-                boolean old_c = oldLoopCounter == 0;
-                boolean old_a = flag_a;
-                boolean old_b = flag_b;
-                flag_a =
-                    (((sf.flag_a & sf.FLAG_A)     != 0) ?  old_a : false) |
-                    (((sf.flag_a & sf.FLAG_NOT_A) != 0) ? !old_a : false) |
-                    (((sf.flag_a & sf.FLAG_B)     != 0) ?  old_b : false) |
-                    (((sf.flag_a & sf.FLAG_NOT_B) != 0) ? !old_b : false) |
-                    (((sf.flag_a & sf.FLAG_C)     != 0) ?  old_c : false) |
-                    (((sf.flag_a & sf.FLAG_NOT_C) != 0) ? !old_c : false);
-                flag_b =
-                    (((sf.flag_b & sf.FLAG_A)     != 0) ?  old_a : false) |
-                    (((sf.flag_b & sf.FLAG_NOT_A) != 0) ? !old_a : false) |
-                    (((sf.flag_b & sf.FLAG_B)     != 0) ?  old_b : false) |
-                    (((sf.flag_b & sf.FLAG_NOT_B) != 0) ? !old_b : false) |
-                    (((sf.flag_b & sf.FLAG_C)     != 0) ?  old_c : false) |
-                    (((sf.flag_b & sf.FLAG_NOT_C) != 0) ? !old_c : false);
-            } else if (executing instanceof Instruction.Set.OLC.Decrement) {
-            } else {
-                if (!service(executing)) return;
+            if (move.interruptible && torpedoWaiting) {
+                torpedoWaiting = false;
+                executing = null;
+                ilc = 1;
+                olc = 0;
+                if (tapl != null)
+                    new Packet(tapl, new BitVector(getInterpreter().getWordWidth()), true).send();
+                hatchIsOpen = true;
+                return;
             }
+
+            if (move.dataIn  && !isInputDock() && readyForDataFromShip) return;
+            if (move.dataIn  &&  isInputDock() && dataDestination.packets.size()==0) return;
+            if (move.tokenIn &&                   dataDestination.packets.size()==0) return;
         }
 
-        if (executing==null) return;
-        if ((executing instanceof Instruction.Move) && repeatCounter > 1) {
-            repeatCounter--;
-        } else if ((executing instanceof Instruction.Move) && repeatCounter == -1) {
-            // repeat
-        } else if ((executing instanceof Instruction.PredicatedInstruction && ((Instruction.PredicatedInstruction)executing).looping) && oldLoopCounter > 0) {
-            addInstruction(executing);
+        if (executing.looping && olc>0)
+            instructions.add(executing);
+
+        if (executing instanceof Instruction.Shift) {
+            Instruction.Shift shift = (Instruction.Shift)executing;
+            for(int i=dataLatch.length()-1; i>=19; i--)
+                dataLatch.set(i, dataLatch.get(i-19));
+            for(int i=18; i>=0; i--)
+                dataLatch.set(i, shift.immediate.get(i));
             executing = null;
-        } else {
+            return;
+        }
+
+        if (executing instanceof Instruction.Set) {
+            Instruction.Set set = (Instruction.Set)executing;
+            switch(set.dest) {
+                case DataLatch:
+                    dataLatch = new BitVector(getInterpreter().getWordWidth()).setAndSignExtend(set.immediate);
+                    break;
+                case InnerLoopCounter:
+                    switch(set.source) {
+                        case Infinity:
+                            ilc = -1;
+                            break;
+                        case DataLatch:
+                            ilc = 0;
+                            for(int i=0; i<FleetTwoFleet.SET_ILC_FROM_IMMEDIATE.valmaskwidth-1; i++)
+                                if (dataLatch.get(i))
+                                    ilc |= (1 << i);
+                            break;
+                        case Immediate:
+                            ilc = (int)set.immediate;
+                            break;
+                        default:
+                            throw new RuntimeException("FIXME!");
+                    }
+                    break;
+                case OuterLoopCounter:
+                    switch(set.source) {
+                        case Decrement:
+                            olc = Math.max(0,olc-1);
+                            if (olc==0) hatchIsOpen = true;
+                            break;
+                        case DataLatch:
+                            olc = 0;
+                            for(int i=0; i<FleetTwoFleet.SET_OLC_FROM_IMMEDIATE.valmaskwidth-1; i++)
+                                if (dataLatch.get(i))
+                                    olc |= (1 << i);
+                            if (olc==0) hatchIsOpen = true;
+                            break;
+                        case Immediate:
+                            olc = (int)set.immediate;
+                            if (olc==0) hatchIsOpen = true;
+                            break;
+                        default:
+                            throw new RuntimeException("FIXME!");
+                    }
+                    break;
+
+                case TAPL:
+                    tapl = (InterpreterPath)set.path;
+                    break;
+
+                case Flags: {
+                    boolean new_flag_a = false;
+                    boolean new_flag_b = false;
+                    for(Predicate p : set.newFlagA)
+                        switch(p) {
+                            case FlagA: new_flag_a |= flag_a; break;
+                            case FlagB: new_flag_a |= flag_b; break;
+                            case FlagC: new_flag_a |= flag_c; break;
+                            case NotFlagA: new_flag_a |= !flag_a; break;
+                            case NotFlagB: new_flag_a |= !flag_b; break;
+                            case NotFlagC: new_flag_a |= !flag_c; break;
+                        }
+                    for(Predicate p : set.newFlagB)
+                        switch(p) {
+                            case FlagA: new_flag_b |= flag_a; break;
+                            case FlagB: new_flag_b |= flag_b; break;
+                            case FlagC: new_flag_b |= flag_c; break;
+                            case NotFlagA: new_flag_b |= !flag_a; break;
+                            case NotFlagB: new_flag_b |= !flag_b; break;
+                            case NotFlagC: new_flag_b |= !flag_c; break;
+                        }
+                    flag_a = new_flag_a;
+                    flag_b = new_flag_b;
+                    break;
+                }
+                default:
+                    throw new RuntimeException("FIXME!");
+            }
             executing = null;
+            return;
+        }
+
+        Instruction.Move move = (Instruction.Move)executing;
+
+        // if ILC==0, don't even bother
+        if (ilc==0) { ilc = 1; executing = null; return; }
+
+        if (ilc==-1)     { }
+        else if (ilc==1) executing = null;
+        else             ilc--;
+
+        Packet p = null;
+        if (move.tokenIn) {
+            p = dataDestination.packets.remove();
+            if (p.path.signal != null) flag_c = p.path.signal.get(0);
+        }
+        if (move.dataIn) {
+            BitVector bv = null;
+            if (isInputDock()) {
+                p = dataDestination.packets.remove();
+                bv = new BitVector(p.value);
+                if (p.path.signal != null) flag_c = p.path.signal.get(0);
+            } else {
+                bv = new BitVector(getInterpreter().getWordWidth()).set(dataFromShip);
+                readyForDataFromShip = true;
+            }
+            if (move.latchData) dataLatch = bv;
+            if (move.latchPath)
+                pathLatch = (InterpreterPath)getInterpreter().getPathByAddr(this, FleetTwoFleet.DISPATCH_PATH.getval(bv));
+            // FIXME: c-flag at output docks
         }
-            */
+
+        if (move.path != null) pathLatch = (InterpreterPath)move.path;
+
+        if (move.dataOut && isInputDock()) dataReadyForShip = true;
+        if (move.dataOut && !isInputDock())
+            new Packet(pathLatch, new BitVector(dataLatch), true).send();
+        if (move.tokenOut)
+            new Packet(pathLatch, new BitVector(getInterpreter().getWordWidth()), true).send();
+
+        return;
     }
 }
index d65d40c..454b73b 100644 (file)
@@ -100,7 +100,7 @@ public abstract class FleetTwoFleet extends Fleet {
     /** decode a path, given the starting point and the bits that comprise it */
     // FIXME this should use a BitVector not a long!
     //protected abstract Path getPathByAddr(Dock source, long dest);
-    protected Path getPathByAddr(Dock source, long dest) {
+    public Path getPathByAddr(Dock source, long dest) {
         for(Ship ship : this)
             for(Dock bb : ship) {
                 for(Destination d : new Destination[] { bb.getInstructionDestination(), bb.getDataDestination() }) {