switch from using RS-232 BREAKs and no flow control to new command mode reset and...
authormegacz <adam@megacz.com>
Wed, 11 Mar 2009 22:34:42 +0000 (15:34 -0700)
committermegacz <adam@megacz.com>
Wed, 11 Mar 2009 22:34:42 +0000 (15:34 -0700)
ships/Debug.ship
src/edu/berkeley/fleet/fpga/Client.java
src/edu/berkeley/fleet/fpga/Server.java

index 134ae47..861e66c 100644 (file)
@@ -40,7 +40,6 @@ public void service() {
 == FPGA ==============================================================
 
   wire break_i;
-  reg break_last;
   reg send_k;
   initial send_k = 0;
 
@@ -56,6 +55,7 @@ public void service() {
   wire [7:0] data_to_fleet;
   reg        data_to_host_write_enable;
   reg        data_to_fleet_read_enable;
+  reg  [7:0] force_reset;
 
   wire sio_ce;
   wire sio_ce_x4;
@@ -63,7 +63,7 @@ public void service() {
   wire break;
   wire uart_cts;
   assign uart_cts = 0;
-  assign rst_out = rst_in || break;
+  assign rst_out = rst_in || (force_reset!=0);
 
   // fst=3 means clock divider is 3+2=5 for a 50Mhz clock => 10Mhz
   // using a 33Mhz clock,
@@ -87,16 +87,15 @@ public void service() {
                     break,
                     break_i);
 
-   // break and break are _active high_
-   always @(posedge clk) break_last <= break;
-   assign break_i    =  break && !break_last;
-   assign break_done = !break &&  break_last;
+   reg [16:0] credits;
 
    // fpga -> host
    always @(posedge clk) begin
-     if (rst) begin
-       count_in  <= 0;
-       count_out <= 0;
+     if (rst_in) begin
+       count_in    <= 0;
+       count_out   <= 0;
+       force_reset <= 0;
+       credits      = 0;
        `reset
      end else begin
 
@@ -104,37 +103,66 @@ public void service() {
 
        // fpga -> host
        data_to_host_write_enable <= 0;
-       if (break_i) begin
-       end else if (break_done) begin
+       if (force_reset == 1) begin
+         force_reset <= 0;
          data_to_host_write_enable <= 1;
-         data_to_host <= 111;
-         send_k <= 1;
-       end else if (send_k) begin
-         data_to_host_write_enable <= 1;
-         data_to_host <= 107;
-         send_k <= 0;
+         credits = 0;
+         count_in  <= 0;
+         count_out <= 0;
+         `reset
+       end else if (force_reset != 0) begin
+         force_reset <= force_reset-1;
        end else if (count_out==0 && `in_full) begin
          `drain_in
          data_to_host_full_word <= in_d;
          count_out <= 8;
-       end else if (count_out!=0 && !data_to_host_full && !data_to_host_write_enable) begin
+       end else if (count_out!=0 && !data_to_host_full && !data_to_host_write_enable && credits!=0) begin
          data_to_host <= { 2'b0, data_to_host_full_word[5:0] };
          data_to_host_full_word <= (data_to_host_full_word >> 6);
          data_to_host_write_enable <= 1;
          count_out <= count_out-1;
+         credits = credits - 1;
        end
 
        // host -> fpga
        data_to_fleet_read_enable <= 0;
-       if (!data_to_fleet_empty && `out_empty && !data_to_fleet_read_enable) begin
-         out_d <= { out_d[43:0], data_to_fleet[5:0] };
-         data_to_fleet_read_enable <= 1;
-         if (count_in==9) begin
-           count_in <= 0;
-           `fill_out
-         end else begin
-           count_in <= count_in+1;
-         end
+       if (!data_to_fleet_empty && !data_to_fleet_read_enable) begin
+
+           // command 0: data
+         if (data_to_fleet[7:6] == 2'b00 && `out_empty) begin
+           data_to_fleet_read_enable <= 1;
+           out_d <= { out_d[43:0], data_to_fleet[5:0] };
+           if (count_in==9) begin
+             count_in <= 0;
+             `fill_out
+           end else begin
+             count_in <= count_in+1;
+           end
+
+           // command 1: flow control credit
+         end else if (data_to_fleet[7:6] == 2'b01) begin
+           data_to_fleet_read_enable <= 1;
+           credits = credits + data_to_fleet[5:0];
+
+/*
+         // uncommenting this requires changing data_to_host_write_enable
+         // to a blocking assignment, and seems to cause data loss whenever
+         // more than four items are in flight.
+           // command 2: echo
+         end else if (data_to_fleet[7:6] == 2'b10 && !data_to_host_full && !data_to_host_write_enable) begin
+           data_to_fleet_read_enable <= 1;
+           data_to_host <= data_to_fleet;
+           data_to_host_write_enable = 1;
+*/
+
+           // command 3: reset (and echo back reset code)
+         end else if (data_to_fleet[7:6] == 2'b11) begin
+           data_to_fleet_read_enable <= 1;
+           data_to_host <= data_to_fleet;
+           force_reset <= 255;
+
+         end 
+
        end
 
     end
index 0048fa2..82ea35f 100644 (file)
@@ -1,6 +1,7 @@
 package edu.berkeley.fleet.fpga;
 
 import static edu.berkeley.fleet.util.BitManipulations.*;
+import java.util.concurrent.Semaphore;
 import edu.berkeley.fleet.api.*;
 import java.io.*;
 import java.net.*;
@@ -38,6 +39,7 @@ public class Client extends FleetProcess {
 
     protected void _terminate() {
         try {
+            closed = true;
             s.close();
         } catch (Exception e) { e.printStackTrace(); }
     }
@@ -47,12 +49,18 @@ public class Client extends FleetProcess {
 
     public void flush() {
         try {
-            dos.flush();
+            synchronized(this) {
+                dos.flush();
+            }
         } catch (Exception e) {
             throw new RuntimeException(e);
         }
     }
 
+    /** the 16550 has a 16-byte FIFO buffer */
+    private final Semaphore sem = new Semaphore(15);
+    private boolean closed = false;
+
     public Client(Fpga fpga, String bitfile, Instruction[] instructions) throws Exception {
         this.fpga = fpga;
 
@@ -64,20 +72,49 @@ public class Client extends FleetProcess {
         pw.flush();
 
         this.dos = new DataOutputStream(os);
-        for(Instruction inst : instructions)
-            sendInstruction(inst);
-        flush();
 
-        final InputStream is = new BufferedInputStream(s.getInputStream());
+        dos.write( (3<<6) | 9);
+        dos.flush();
+        Thread.sleep(1000);
+
+        final InputStream is0 = s.getInputStream();
+        while(is0.available() > 0) {
+            int i = is0.read();
+            //System.out.println("reset code: " + (i & ~(-1 << 6)));
+        }
+
+        final InputStream is = new BufferedInputStream(is0);
+
         Thread t = new Thread() {
             public void run() {
                 try {
                     while(true) {
+                        int count = sem.availablePermits();
+                        if (count >= (1<<6)) count = (1<<6)-1; 
+                        if (count < 1) count = 1;
+                        sem.acquire(count);
+                        if (closed) return;
+                        synchronized(this) {
+                            dos.write( (1<<6) | count );
+                            if (sem.availablePermits()==0) dos.flush();
+                        }
+                    }
+                } catch (Exception e) { throw new RuntimeException(e); }
+            }
+            };
+        t.setDaemon(true);
+        t.start();
+
+        t = new Thread() {
+            public void run() {
+                try {
+                    while(true) {
                         long result = 0;
                         int val = 0;
                         for(int i=0; i<8; i++) {
                             val = is.read();
                             if (val==-1) break;
+                            sem.release();
                             long val2 = (val & 0xffL);
                             val2 = val2 << (i * 6);
                             result |= val2;
@@ -95,6 +132,10 @@ public class Client extends FleetProcess {
             };
         t.setDaemon(true);
         t.start();
+
+        for(Instruction inst : instructions) sendInstruction(inst);
+        flush();
+
     }
 
     public void sendToken(Destination d) { sendWord(d, new BitVector(fpga.getWordWidth()), true); }
@@ -109,7 +150,8 @@ public class Client extends FleetProcess {
             out = fpga.PACKET_DEST.setval(out, ((FpgaPath)dispatchFrom.getPath(d, null)).toLong());
             synchronized(this) {
                 for(int i=9; i>=0; i--)
-                    dos.write(BitManipulations.getIntField(i*6+7, i*6, out));
+                    dos.write(BitManipulations.getIntField(i*6+5, i*6, out));
+                dos.flush();
             }
         } catch (Exception e) {
             throw new RuntimeException(e);
index 39a7132..f6ec790 100644 (file)
@@ -104,12 +104,9 @@ public class Server {
                 System.err.println("login string: " + sb.toString());
                 if (!sb.toString().startsWith(pass_string)) return;
                 final OutputStream os = new BufferedOutputStream(socket.getOutputStream());
-                System.err.println("sending breaks...");
-                sp.sendBreak(100);
 
                 final OutputStream fos = sp.getOutputStream();
                 final InputStream fis = new BufferedInputStream(sp.getInputStream());
-                sign = false;
 
                 System.err.println("sending instructions...");
                 new Thread() {
@@ -119,11 +116,6 @@ public class Server {
                                 int r = is.read();
                                 if (r == -1) break;
                                 fos.write(r);
-                                if (!sign) {
-                                    fos.flush();
-                                    Thread.sleep(100);
-                                    sign = true;
-                                }
                             }
                             fos.flush();
                         } catch (Exception e) { throw new RuntimeException(e);
@@ -135,7 +127,6 @@ public class Server {
                     }
                 }.start();
 
-
                 System.err.println("reading back...");
                 while(true) {
                     long result = 0;
@@ -155,10 +146,6 @@ public class Server {
                         }
                         if (closed) { os.flush(); return; }
                         val = fis.read();
-                        if (!sign) {
-                            System.err.println("leader byte: 0x" + Integer.toString(val, 16) + " '"+((char)val)+"'");
-                            continue;
-                        }
                         if (val==-1) break;
                         System.err.println("byte: 0x"+Integer.toString(val & 0xff, 16));
                         os.write((byte)val);