add FleetProcess.sendWord() that takes a signal
[fleet.git] / src / edu / berkeley / fleet / fpga / Client.java
index e3cc39f..4c223fd 100644 (file)
@@ -4,8 +4,10 @@ import static edu.berkeley.fleet.util.BitManipulations.*;
 import edu.berkeley.fleet.api.*;
 import java.io.*;
 import java.net.*;
+import edu.berkeley.fleet.util.*;
 import java.util.*;
 import java.util.concurrent.*;
+import static edu.berkeley.fleet.two.FleetTwoFleet.*;
 import static edu.berkeley.fleet.api.Instruction.Set.*;
 import static edu.berkeley.fleet.api.Predicate.*;
 import static edu.berkeley.fleet.api.Instruction.*;
@@ -16,20 +18,11 @@ public class Client extends FleetProcess {
     private Socket s;
     private BlockingQueue<BitVector> queue = new LinkedBlockingQueue<BitVector>();
 
-    public void invokeInstruction(Instruction i) {
-        throw new RuntimeException("not implemented");
-    }
-
-    public static long signExtend(long val) {
-        if ((val & (1L << 36)) != 0)
-            val = val | (0xffffffffffffffffL << 36);
-        return val;
-    }
-                                    
+    public Fleet getFleet() { return fpga; }
     public Dock getDebugInputDock() {
-        throw new RuntimeException();
+        return fpga.getShip("Debug",0).getDock("in");
     }
-    public BitVector readWord() {
+    public BitVector recvWord() {
         if (isTerminated())
             throw new RuntimeException("this fleet has been terminated");
         try {
@@ -43,109 +36,59 @@ public class Client extends FleetProcess {
         } catch (Exception e) { e.printStackTrace(); }
     }
 
-    public Client(String bitfile, byte[] program) throws Exception {
+    private Fpga fpga;
+    private OutputStream os = null;
+
+    public void flush() {
+        try {
+            os.flush();
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public Client(Fpga fpga, String bitfile, Instruction[] instructions) throws Exception {
+        this.fpga = fpga;
+
         s = new Socket(InetAddress.getByName("goliath.megacz.com"), 3133);
-        OutputStream os = new BufferedOutputStream(s.getOutputStream());
+        //s = new Socket(InetAddress.getByName("localhost"), 3133);
+        this.os = new BufferedOutputStream(s.getOutputStream());
+        final InputStream is = new BufferedInputStream(s.getInputStream());
         PrintWriter pw = new PrintWriter(new OutputStreamWriter(os));
         pw.print(Server.pass_string+" "+bitfile+"\n");
         pw.flush();
 
-
-        Fpga fpga = new Fpga();
-        ByteArrayOutputStream newp = new ByteArrayOutputStream();
-        DataOutputStream newpd = new DataOutputStream(newp);
-        long startcbd = 0;
-
-        Dock inAddrWrite = null;
-        Dock inDataWrite = null;
-        Dock inCBD       = null;
-        Dock out         = null;
-        Dock debugIn     = null;
-        Dock ihorn       = null;
-
-        for(Ship ship : fpga) {
-            if ("Memory".equals(ship.getType()) && ship.getOrdinal()==0) {
-                inAddrWrite = ship.getDock("inAddrWrite");
-                inDataWrite = ship.getDock("inDataWrite");
-                inCBD = ship.getDock("inCBD");
-                out = ship.getDock("out");
-                ihorn = ship.getDock("outIhorn");
-            }
-            if ("Debug".equals(ship.getType()) && ship.getOrdinal()==0) {
-                debugIn = ship.getDock("in");
-            }
-        }
-
-        for(int i=0; i<program.length; i+=6) {
-            long lit = 0
-                | ((program[i+0] & 0xffL) << 40)
-                | ((program[i+1] & 0xffL) << 32)
-                | ((program[i+2] & 0xffL) << 24)
-                | ((program[i+3] & 0xffL) << 16)
-                | ((program[i+4] & 0xffL) << 8)
-                | ((program[i+5] & 0xffL) << 0);
-            Instruction inst = fpga.readInstruction(fpga.getUniversalSource(), lit);
-            if (i==0) {
-                long offset = (lit >> 6) & ~(-1L << 10);
-                long size   = (lit >> 0) & ~(-1L << 6);
-                startcbd = (offset << 6) | size;
-                size = 0;
-                offset = 0;
-                inst = new Instruction.Shift(fpga.getUniversalSource(), false, IgnoreOLC, new BitVector(fpga.getWordWidth()).set(0));
-            } else {
-                if (fpga.writeInstruction(fpga.getUniversalSource(), inst) != lit)
-                    throw new RuntimeException("no match: " + inst + " @"+(i/6)+"\n"+Long.toString(lit,16)+
-                                               "\n"+Long.toString(fpga.writeInstruction(fpga.getUniversalSource(), inst),16));
+        // goofy reset sequence
+        new Thread() {
+            public void run() {
+                try {
+                    for(int i=0; i<255; i++) os.write( (3<<6) | 0);
+                    for(int i=0; i<60; i++) os.write( (3<<6) | i);
+                    os.flush();
+                } catch (Exception e) { throw new RuntimeException(e); }
             }
-            //fpga.writeInstruction(newpd, fpga.getUniversalSource(), inst);
-        }
-
-        for(int i=0; i<program.length; i+=6) {
-            long lit = 0
-                | ((program[i+0] & 0xffL) << 40)
-                | ((program[i+1] & 0xffL) << 32)
-                | ((program[i+2] & 0xffL) << 24)
-                | ((program[i+3] & 0xffL) << 16)
-                | ((program[i+4] & 0xffL) << 8)
-                | ((program[i+5] & 0xffL) << 0);
-            fpga.writeInstruction(newpd, fpga.getUniversalSource(), discard(out));
-            fpga.writeInstruction(newpd, fpga.getUniversalSource(), new Instruction.Shift(inDataWrite, false, IgnoreOLC, new BitVector(fpga.getWordWidth()).set(getField(36, 19, lit))));
-            fpga.writeInstruction(newpd, fpga.getUniversalSource(), new Instruction.Shift(inDataWrite, false, IgnoreOLC, new BitVector(fpga.getWordWidth()).set(getField(18,  0, lit))));
-            fpga.writeInstruction(newpd, fpga.getUniversalSource(), deliver(inDataWrite));
-            fpga.writeInstruction(newpd, fpga.getUniversalSource(), new Instruction.Shift(inAddrWrite, false, IgnoreOLC, new BitVector(fpga.getWordWidth()).set(getField(36, 19, i/6))));
-            fpga.writeInstruction(newpd, fpga.getUniversalSource(), new Instruction.Shift(inAddrWrite, false, IgnoreOLC, new BitVector(fpga.getWordWidth()).set(getField(18,  0, i/6))));
-            fpga.writeInstruction(newpd, fpga.getUniversalSource(), deliver(inAddrWrite));
+        }.start();
+        int k = 1;
+        while(k<60) {
+            int i = is.read();
+            if ( (i & (3<<6)) != (3<<6) ) { k=1; continue; }
+            i = i & ~((-1)<<6);
+            if (i==k) k++; else k = 1;
         }
-        fpga.writeInstruction(newpd, fpga.getUniversalSource(), new Instruction.Shift(inCBD, false, IgnoreOLC, new BitVector(fpga.getWordWidth()).set(getField(36, 19, startcbd))));
-        fpga.writeInstruction(newpd, fpga.getUniversalSource(), new Instruction.Shift(inCBD, false, IgnoreOLC, new BitVector(fpga.getWordWidth()).set(getField(18,  0, startcbd))));
-        fpga.writeInstruction(newpd, fpga.getUniversalSource(), wait(inCBD));
-        fpga.writeInstruction(newpd, fpga.getUniversalSource(), deliver(inCBD));
-        fpga.writeInstruction(newpd, fpga.getUniversalSource(), sendto(out, out.getPath(inCBD.getDataDestination(),null)));
-        fpga.writeInstruction(newpd, fpga.getUniversalSource(), new Instruction.Set(ihorn, false, IgnoreOLC, SetDest.InnerLoopCounter, SetSource.Infinity));
-        fpga.writeInstruction(newpd, fpga.getUniversalSource(),
-                              new Instruction.Move(ihorn, false, IgnoreOLC, false, null,false,true,true,true,true,false));
+        
+        // initial flow-control credits
+        os.write( (1<<6) | 15);
 
-        newpd.flush();
-        program = newp.toByteArray();
-
-        os.write(program);
-        os.flush();
-
-        final InputStream is = new BufferedInputStream(s.getInputStream());
-        new Thread() {
+        Thread t = new Thread() {
             public void run() {
                 try {
-                    while(true) {
+                    OUTER: while(true) {
                         long result = 0;
-                        int val = 0;
-                        for(int i=0; i<6; i++) {
-                            val = is.read();
-                            if (val==-1) break;
-                            long val2 = (val & 0xffL);
-                            val2 = val2 << (i * 8);
-                            result |= val2;
+                        for(int i=0; i<8; i++) {
+                            int val = is.read();
+                            if (val==-1) break OUTER;
+                            result |= ((val & 0xffL) << (i * 6L));
                         }
-                        if (val==-1) break;
                         BitVector bs = new BitVector(37);
                         for(int i=0; i<37; i++)
                             bs.set(i, ((result >> i) & 1L)!=0);
@@ -155,30 +98,45 @@ public class Client extends FleetProcess {
                 } catch (Exception e) { throw new RuntimeException(e);
                 } finally { terminate(); }
             }
-        }.start();
+            };
+        t.setDaemon(true);
+        t.start();
+
+        for(Instruction inst : instructions) sendInstruction(inst);
+        flush();
     }
-    /*
-    public static void main(String[] args) throws Exception {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        byte[] buf = new byte[1024];
-        while(true) {
-            int numread = System.in.read(buf, 0, buf.length);
-            if (numread==-1) break;
-            baos.write(buf, 0, numread);
-        }
-        Client client = new Client(args.length==0 ? "main.bit" : args[0], baos.toByteArray());
-        while(true) {
-            long result = client.readWord();
-            System.err.print(result);
-            System.err.print(" 0x");
-            System.err.print(Long.toString(result, 16));
-            System.err.println();
+
+    public void sendToken(Destination d) { sendWord(d, new BitVector(fpga.getWordWidth()), null, true); }
+    public void sendWord(Destination d, BitVector word) { sendWord(d, word, null, false); }
+    public void sendWord(Destination d, BitVector word, BitVector signal) { sendWord(d, word, signal, false); }
+    private void sendWord(Destination d, BitVector word, BitVector signal, boolean token) {
+        try {
+            Dock dispatchFrom = fpga.debugShip.getDock("in");
+            long out = 0;
+            out = fpga.PACKET_DATA.setval(out, word);
+            out = fpga.PACKET_TOKEN.setval(out, token ? 1 : 0);
+            if (signal==null)
+                out = fpga.PACKET_SIGNAL.setval(out, 0);
+            else 
+                out = fpga.PACKET_SIGNAL.setval(out, signal);
+            out = fpga.PACKET_DEST.setval(out, ((FpgaPath)dispatchFrom.getPath(d, null)).toLong());
+            synchronized(this) {
+                for(int i=9; i>=0; i--)
+                    os.write(BitManipulations.getIntField(i*6+5, i*6, out));
+                os.flush();
+            }
+        } catch (Exception e) {
+            throw new RuntimeException(e);
         }
     }
-    */
-    public void dispatchInstruction(Instruction i) { throw new RuntimeException(); }
-    private static Move discard(Dock dock)           { return new Move(dock, false, IgnoreOLC, false, null, false, true,  false, false, false, false); }
-    private static Move deliver(Dock dock)           { return new Move(dock, false, IgnoreOLC, false, null, false, false, false, false, true,  false); }
-    private static Move wait(Dock dock)              { return new Move(dock, false, IgnoreOLC, false, null, true,  false, false, false, false, false); }
-    private static Move sendto(Dock dock, Path path) { return new Move(dock, false, IgnoreOLC, false, path, false, false, false, false, true,  false); }
+    public void sendInstruction(Instruction inst) {
+        Dock dispatchFrom = fpga.debugShip.getDock("in");
+        sendWord(inst.dock.getInstructionDestination(),
+                 new BitVector(fpga.getWordWidth()).set(fpga.writeInstruction(inst, dispatchFrom)));
+    }
+
+    private static Move discard(Dock dock)           { return new Move(dock, IgnoreFlagD, false, null, false, true,  false, false, false, false); }
+    private static Move deliver(Dock dock)           { return new Move(dock, IgnoreFlagD, false, null, false, false, false, false, true,  false); }
+    private static Move wait(Dock dock)              { return new Move(dock, IgnoreFlagD, false, null, true,  false, false, false, false, false); }
+    private static Move sendto(Dock dock, Path path) { return new Move(dock, IgnoreFlagD, false, path, false, false, false, false, true,  false); }
 }