major overhaul of FPGA code to support both ML509 and Bee2 at the same time
[fleet.git] / src / edu / berkeley / fleet / fpga / Client.java
index 269181e..e84b7c4 100644 (file)
@@ -17,6 +17,8 @@ public class Client extends FleetProcess {
 
     private Socket s;
     private BlockingQueue<BitVector> queue = new LinkedBlockingQueue<BitVector>();
+    private Fpga fpga;
+    private OutputStream os = null;
 
     public Fleet getFleet() { return fpga; }
     public Dock getDebugInputDock() {
@@ -32,13 +34,10 @@ public class Client extends FleetProcess {
 
     protected void _terminate() {
         try {
-            s.close();
+            if (s!=null) s.close();
         } catch (Exception e) { e.printStackTrace(); }
     }
 
-    private Fpga fpga;
-    private OutputStream os = null;
-
     public void flush() {
         try {
             os.flush();
@@ -47,18 +46,24 @@ public class Client extends FleetProcess {
         }
     }
 
-    public Client(Fpga fpga, String bitfile, Instruction[] instructions) throws Exception {
-        this.fpga = fpga;
+    private static class Gobbler extends Thread {
+        private final BufferedReader br;
+        public Gobbler(InputStream is) {
+            this.br = new BufferedReader(new InputStreamReader(is));
+        }
+        public void run() {
+            try {
+                for(String s = br.readLine(); s!=null; s=br.readLine())
+                    System.err.println("  > " + s);
+            } catch (Exception e) { throw new RuntimeException(e); }
+        }
+    }
 
-        s = fpga instanceof Bee2
-            ? new Socket(InetAddress.getByName("megacz.com"), 3133)
-            : new Socket(InetAddress.getByName("goliath.megacz.com"), 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();
+    private boolean needmc = false;
+    public void masterClear() {
+        queue.clear();
 
+        needmc = true;
         // goofy reset sequence
         new Thread() {
             public void run() {
@@ -69,42 +74,87 @@ public class Client extends FleetProcess {
                 } catch (Exception e) { throw new RuntimeException(e); }
             }
         }.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;
+        try {
+            while(needmc) Thread.sleep(100);
+        } catch (Exception e) { throw new RuntimeException(e); }
+    }
+
+    public Client(Fpga fpga, String bitfile, Instruction[] instructions) throws Exception {
+        this.fpga = fpga;
+
+        final InputStream xis;
+
+        if (fpga instanceof Bee2) {
+            int idx = 1;
+            String host = "bee2";
+            Process proc;
+            int res;
+            
+            System.err.println("== rsyncing");
+            proc = Runtime.getRuntime().exec("rsync -are ssh --progress --verbose build/bee2/main.bit misc/bicat.c "+host+":");
+            new Gobbler(proc.getInputStream()).start();
+            res = proc.waitFor();
+            if (res != 0) throw new RuntimeException("nonzero exit code");
+
+            System.err.println("== (un)programming fpga " + idx);
+            proc = Runtime.getRuntime().exec("ssh -t "+host+" -- (user_unprogram "+idx+" && gcc -o bicat bicat.c && user_program "+idx+" main.bit &>/dev/null) && ./bicat /dev/selectmap"+idx);
+            this.os = proc.getOutputStream();
+            xis = new BufferedInputStream(proc.getInputStream());
+        } else {
+            s = new Socket(InetAddress.getByName("goliath.megacz.com"), 3133);
+            this.os = new BufferedOutputStream(s.getOutputStream());
+            xis = new BufferedInputStream(s.getInputStream());
+            PrintWriter pw = new PrintWriter(new OutputStreamWriter(os));
+            pw.print(Server.pass_string+" "+bitfile+"\n");
+            pw.flush();
         }
-        
-        // initial flow-control credits
-        os.write( (1<<6) | 15);
+        final InputStream is = xis;
 
+        needmc = true;
         Thread t = new Thread() {
-            public void run() {
-                try {
-                    OUTER: while(true) {
-                        long result = 0;
-                        for(int i=0; i<8; i++) {
-                            int val = is.read();
-                            if (val==-1) break OUTER;
-                            result |= ((val & 0xffL) << (i * 6L));
+                public void run() {
+                    try {
+                        while(needmc) {
+                            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;
+                            }
+        
+                            // initial flow-control credits
+                            os.write( (1<<6) | 15);
+                            os.flush();
+                            needmc = false;
+                            OUTER: while(true) {
+                                long result = 0;
+                                if (needmc) break;
+                                for(int i=0; i<8; i++) {
+                                    int val = is.read();
+                                    if (needmc) break OUTER;
+                                    if (val==-1) break OUTER;
+                                    result |= ((val & 0xffL) << (i * 6L));
+                                }
+                                BitVector bs = new BitVector(37);
+                                for(int i=0; i<37; i++)
+                                    bs.set(i, ((result >> i) & 1L)!=0);
+                                queue.put(bs);
+                            }
                         }
-                        BitVector bs = new BitVector(37);
-                        for(int i=0; i<37; i++)
-                            bs.set(i, ((result >> i) & 1L)!=0);
-                        queue.put(bs);
-                    }
-                } catch (SocketException e) {
-                } catch (Exception e) { throw new RuntimeException(e);
-                } finally { terminate(); }
-            }
+                    } catch (SocketException e) {
+                    } catch (Exception e) { throw new RuntimeException(e);
+                    } finally { terminate(); }
+                }
             };
         t.setDaemon(true);
         t.start();
+        masterClear();
 
-        for(Instruction inst : instructions) sendInstruction(inst);
-        flush();
+        if (instructions!=null) {
+            for(Instruction inst : instructions) sendInstruction(inst);
+            flush();
+        }
     }
 
     public void sendToken(Destination d) { sendWord(d, new BitVector(fpga.getWordWidth()), null, true); }