add flush support to ships
authoradam <adam@megacz.com>
Mon, 27 Oct 2008 06:36:53 +0000 (07:36 +0100)
committeradam <adam@megacz.com>
Mon, 27 Oct 2008 06:36:53 +0000 (07:36 +0100)
ships/Alu.ship
ships/CarrySaveAdder.ship
ships/DDR2.ship [new file with mode: 0644]
ships/DRAM.ship
ships/Debug.ship
ships/Fifo.ship
ships/Lut3.ship
ships/Memory.ship
ships/Rotator.ship
ships/Video.ship

index 9cc5e77..2089b8a 100644 (file)
@@ -11,6 +11,9 @@ data  in:   inOp
   constant MAX: 4
   constant MIN: 5
   constant CMP: 6
+  constant DROP1: 7
+  constant DROP2: 8
+  constant MAXMERGE: 9
 
 data  out:  out
 
@@ -36,13 +39,16 @@ is then made available at {\tt out}.
 \subsection*{C-Flag}
 
 \begin{verbatim}
-IN1 - undefined
-IN2 - undefined
-ADD - carry-out
-SUB - undefined
-MAX - 0 if in1>in2, else 1
-MIN - 1 if in1>in2, else 0
-CMP - 0 if in1!=in2, else 1
+IN1      - undefined; drain in1 only
+IN2      - undefined; drain in2 only
+ADD      - carry-out
+SUB      - undefined
+MAX      - if in1>in2 cflag=0 and drain in1, else cflag=1 and drain in2
+MIN      - if in1>in2 cflag=1 and drain in2, else cflag=0 and drain in1
+CMP      - if in1==in2 cflag=1, else cflag=0
+DROP1    - consume in1, produce no output
+DROP2    - consume in2, produce no output
+MAXMERGE - if (in1<0 && in2<0) consume both, emit either, cflag=undef else act as MAX
 \end{verbatim}
 
 \subsection*{To Do}
@@ -56,29 +62,56 @@ yet implemented.
 
 == Fleeterpreter ====================================================
 public void service() {
-  if (box_in1.dataReadyForShip() &&
+  if (box_inOp.dataReadyForShip() &&
+      box_in1.dataReadyForShip() &&
       box_in2.dataReadyForShip() &&
-      box_inOp.dataReadyForShip() &&
       box_out.readyForDataFromShip()) {
-      long a      = box_in1.removeDataForShip();
-      long b      = box_in2.removeDataForShip();
+      long a;
+      long b;
       long op     = box_inOp.removeDataForShip();
       switch((int)op) {
-          case 0: box_out.addDataFromShip(a); // IN1
+          case 0:
+              a = box_in1.removeDataForShip();
+              box_out.addDataFromShip(a); // IN1
               break;
-          case 1: box_out.addDataFromShip(b); // IN2
+          case 1:
+              b = box_in2.removeDataForShip();
+              box_out.addDataFromShip(b); // IN2
               break;
-          case 2: box_out.addDataFromShip(a+b); // ADD
+          case 2:
+              a = box_in1.removeDataForShip();
+              b = box_in2.removeDataForShip();
+              box_out.addDataFromShip(a+b); // ADD
               break;
-          case 3: box_out.addDataFromShip(a-b); // SUB
+          case 3:
+              a = box_in1.removeDataForShip();
+              b = box_in2.removeDataForShip();
+              box_out.addDataFromShip(a-b); // SUB
               break;
-          case 4: box_out.addDataFromShip(Math.max(a,b)); // MAX
+          case 4:
+              a = box_in1.peekDataForShip();
+              b = box_in2.peekDataForShip();
+              box_out.addDataFromShip(Math.max(a,b)); // MAX
               box_out.flag_c = !(a>b);
+              if (a<b) box_in1.removeDataForShip(); else box_in2.removeDataForShip();
               break;
-          case 5: box_out.addDataFromShip(Math.min(a,b)); // MIN
+          case 5:
+              a = box_in1.peekDataForShip();
+              b = box_in2.peekDataForShip();
+              box_out.addDataFromShip(Math.min(a,b)); // MIN
               box_out.flag_c = a>b;
+              if (a>b) box_in1.removeDataForShip(); else box_in2.removeDataForShip();
               break;
-          default: box_out.addDataFromShip(0);
+          case 6:
+              a = box_in1.removeDataForShip();
+              b = box_in2.removeDataForShip();
+              box_out.addDataFromShip(0); // CMP
+              box_out.flag_c = a==b;
+              break;
+          default:
+              a = box_in1.removeDataForShip();
+              b = box_in2.removeDataForShip();
+              box_out.addDataFromShip(0);
               break;
       }
   }
@@ -97,23 +130,25 @@ public void service() {
   wire                    eq;
   wire                    cout;
 
-  assign isplus       = inOp_d[2:0]==2;
-  assign cin          = isplus ? 0 : 1;
-  assign in2_inverted = isplus ? in2_d : ~in2_d;
-  assign sum          = {in1_d,cin} + {in2_inverted,cin};
-  assign res          = sum[`DATAWIDTH:1];
-  assign greater      = !res[`DATAWIDTH-1];
-  assign eq           = in1_d == in2_d;
-  assign cout         = sum[`DATAWIDTH];
+  assign isplus        = inOp_d[2:0]==2;
+  assign cin           = isplus ? 0 : 1;
+  assign in2_inverted  = isplus ? in2_d : ~in2_d;
+  assign sum           = {in1_d,cin} + {in2_inverted,cin};
+  assign res           = sum[`DATAWIDTH:1];
+  assign greater       = !res[`DATAWIDTH-1];
+  assign both_negative = in1_d[`DATAWIDTH-1] && in2_d[`DATAWIDTH-1];
+  assign eq            = in1_d == in2_d;
+  assign cout          = sum[`DATAWIDTH];
 
   assign out_d_[`DATAWIDTH] =
           (inOp_d==0) ? 1'b0 :
           (inOp_d==1) ? 1'b0 :
           (inOp_d==2) ? cout :
-          (inOp_d==3) ? 1'b0 :
+          (inOp_d==3) ? cout :
           (inOp_d==4) ? ~greater :
           (inOp_d==5) ?  greater :
           (inOp_d==6) ?  eq :
+          (inOp_d==9) ? ~greater :
           0;
 
   assign out_d_[(`DATAWIDTH-1):0] =
@@ -124,20 +159,34 @@ public void service() {
           (inOp_d==4) ? (greater ? in1_d : in2_d)  :
           (inOp_d==5) ? (greater ? in2_d : in1_d)  :
           (inOp_d==6) ? {{ (`DATAWIDTH-1) {1'b0 }}, eq  } :
+          (inOp_d==9) ? (both_negative ? in1_d : (greater ? in1_d : in2_d)) :
           0;
 
   always @(posedge clk) begin
     if (!rst) begin
       `reset
     end else begin
-      if (!in1_r   && in1_a)    in1_a    <= 0;
-      if (!in2_r   && in2_a)    in2_a    <= 0;
-      if (!inOp_r  && inOp_a)   inOp_a   <= 0;
+      `flush
+      if (!in1_r_  && in1_a)    in1_a    <= 0;
+      if (!in2_r_  && in2_a)    in2_a    <= 0;
+      if (!inOp_r_ && inOp_a)   inOp_a   <= 0;
       if (out_r    && out_a) begin
-        out_r    <= 0;
-        in1_a <= 1;
-        in2_a <= 1;
+        out_r  <= 0;
         inOp_a <= 1;
+
+        if      (inOp_d==0) in1_a <= 1;
+        else if (inOp_d==1) in2_a <= 1;
+        else if (inOp_d==9 &&  both_negative) begin in1_a <= 1; in2_a <= 1; end
+        else if (inOp_d==4 &&  greater) in1_a <= 1;
+        else if (inOp_d==5 &&  greater) in2_a <= 1;
+        else if (inOp_d==9 &&  greater) in1_a <= 1;
+        else if (inOp_d==4 && !greater) in2_a <= 1;
+        else if (inOp_d==5 && !greater) in1_a <= 1;
+        else if (inOp_d==9 && !greater) in2_a <= 1;
+        else begin
+          in1_a <= 1;
+          in2_a <= 1;
+        end
       end
       if (!out_r && !out_a && in1_r && !in1_a && in2_r && !in2_a && inOp_r && !inOp_a) begin
         out_r <= 1;
@@ -161,21 +210,19 @@ public void service() {
 #expect 9
 #expect 0
 #expect 0
-#expect 0
-#expect 1
 #expect 1
 
 debug.in:   set ilc=*;  recv, deliver;
 alu.in1:
   set word= 9;
-  set ilc=7;
+  set ilc=5;
   deliver;
   set word= 9;
   deliver;
 
 alu.in2:
   set word= 8;
-  set ilc=7;
+  set ilc=5;
   deliver;
   set word= 9;
   deliver;
@@ -188,8 +235,6 @@ alu.inOp:
  set word= Alu.inOp[SUB]; deliver;
  set word= Alu.inOp[IN1]; deliver;
  set word= Alu.inOp[IN2]; deliver;
-
-alu.inOp:
  set word= Alu.inOp[MIN]; deliver;
  set word= Alu.inOp[MAX]; deliver;
  set word= Alu.inOp[CMP]; deliver;
@@ -208,13 +253,13 @@ alu.out:
   [!a] set word= 0;
   send to debug.in;
 
-  collect, send to debug.in;        // CMP
+  collect;        // CMP
   set flags a=c, b=b;
   [a]  set word= 1;
   [!a] set word= 0;
   send to debug.in;
 
-  collect, send to debug.in;        // CMP
+  collect;        // CMP
   set flags a=c, b=b;
   [a]  set word= 1;
   [!a] set word= 0;
index 7bbb9e7..4371afd 100644 (file)
@@ -43,7 +43,8 @@ public void service() {
       `reset
       state <= 0;
     end else begin
-      if (!in_r        && in_a)       in_a        <= 0;
+      `flush
+      if (!in_r_       && in_a)       in_a        <= 0;
       if (out_r        && out_a)      out_r       <= 0;
       if (!out_r && !out_a && state==3) begin
         out_d <= { 1'b0, temp };
@@ -66,7 +67,6 @@ public void service() {
   end
 
 == Test ==============================================================
-
 // expected output
 #expect 0x3c4bc6
 #expect 0x1796d2
diff --git a/ships/DDR2.ship b/ships/DDR2.ship
new file mode 100644 (file)
index 0000000..b594c87
--- /dev/null
@@ -0,0 +1,79 @@
+ship: DDR2
+
+== Ports ===========================================================
+data  in:    inAddrRead
+data  in:    inAddrWrite
+data  in:    inDataWrite
+
+data  out:   out
+
+== TeX ==============================================================
+
+== Fleeterpreter ====================================================
+    public void service() { }
+== FleetSim ==============================================================
+
+== FPGA ==============================================================
+
+  reg         ddr2_addr_r;
+  reg         ddr2_isread;
+  reg         ddr2_write_data_push;
+  reg         ddr2_read_data_pop;
+  reg  [`DATAWIDTH:0]  out_d;
+
+  assign ddr2_addr_r_ = ddr2_addr_r;
+  assign ddr2_isread_ = ddr2_isread;
+  assign ddr2_addr_ = !ddr2_isread ? inAddrWrite_d[31:0] : inAddrRead_d[31:0];
+  assign ddr2_write_data_push_ = ddr2_write_data_push;
+  assign ddr2_read_data_pop_ = ddr2_read_data_pop;
+  assign ddr2_write_data_ = { inDataWrite_d[31:5], inDataWrite_d[4], inDataWrite_d[35:0] };
+//  assign ddr2_write_data_ = inDataWrite_d[(`DATAWIDTH-1):0];
+  assign out_d_ = out_d;
+
+  always @(posedge clk) begin
+
+    if (!rst) begin
+      `reset
+      ddr2_isread <= 0;
+      ddr2_addr_r <= 0;
+      ddr2_read_data_pop <= 0;
+
+    end else begin
+      `flush
+
+      if (!inAddrRead_r_  && inAddrRead_a)  inAddrRead_a  <= 0;
+      if (!inDataWrite_r_ && inDataWrite_a) inDataWrite_a <= 0;
+      if (!inAddrWrite_r_ && inAddrWrite_a) inAddrWrite_a <= 0;
+      if ( out_r          && out_a)         out_r <= 0;
+
+      if (ddr2_addr_r && !ddr2_addr_a) begin
+         // busy
+      end else if (ddr2_addr_r &&  ddr2_addr_a && !ddr2_isread) begin
+          ddr2_addr_r <= 0;
+          inAddrWrite_a <= 1;
+          inDataWrite_a <= 1;
+          out_d <= { 1'b1, 37'b0 };
+          out_r <= 1;
+      end else if (ddr2_addr_r &&  ddr2_addr_a && ddr2_isread) begin
+          ddr2_addr_r <= 0;
+          inAddrRead_a <= 1;
+          out_d <= { 1'b0, ddr2_read_data[36:0] };
+          out_r <= 1;
+      end else if (!out_r && !out_a && inAddrWrite_r && !inAddrWrite_a && inDataWrite_r && !inDataWrite_a && !ddr2_addr_r && !ddr2_addr_a) begin
+          ddr2_addr_r <= 1;
+          ddr2_isread <= 0;
+      end else if (!out_r && !out_a && inAddrRead_r && !inAddrRead_a && !ddr2_addr_r && !ddr2_addr_a) begin
+          ddr2_addr_r <= 1;
+          ddr2_isread <= 1;
+      end
+    end
+  end
+
+
+== Test ========================================================
+#skip
+
+== Constants ========================================================
+
+== Contributors =========================================================
+Adam Megacz <megacz@cs.berkeley.edu>
index b3758dc..d5d5338 100644 (file)
@@ -15,20 +15,21 @@ data  out:   out
 
 == FPGA ==============================================================
 
-  // FIXME: use the other chip (64-bit data bus)
-
   reg         dram_addr_r;
   reg         dram_isread;
   reg         dram_write_data_push;
   reg         dram_read_data_pop;
-  reg  [`DATAWIDTH-1:0]  out_d;
+  reg  [`DATAWIDTH:0]  out_d;
+  wire [31:0] dram_addr__;
 
   assign dram_addr_r_ = dram_addr_r;
   assign dram_isread_ = dram_isread;
-  assign dram_addr_ = !dram_isread ? inAddrWrite_d[31:0] : inAddrRead_d[31:0];
+  assign dram_addr__ = !dram_isread ? inAddrWrite_d[31:0] : inAddrRead_d[31:0];
+  assign dram_addr_  = { dram_addr__[30:6], 1'b0, dram_addr__[5:0] };
   assign dram_write_data_push_ = dram_write_data_push;
   assign dram_read_data_pop_ = dram_read_data_pop;
-  assign dram_write_data_ = inDataWrite_d[31:0];
+  assign dram_write_data_ = inDataWrite_d;
+//  assign dram_write_data_ = inDataWrite_d[(`DATAWIDTH-1):0];
   assign out_d_ = out_d;
 
   always @(posedge clk) begin
@@ -40,11 +41,12 @@ data  out:   out
       dram_read_data_pop <= 0;
 
     end else begin
+      `flush
 
-      if (!inAddrRead_r  && inAddrRead_a)  inAddrRead_a  <= 0;
-      if (!inDataWrite_r && inDataWrite_a) inDataWrite_a <= 0;
-      if (!inAddrWrite_r && inAddrWrite_a) inAddrWrite_a <= 0;
-      if ( out_r         && out_a)         out_r <= 0;
+      if (!inAddrRead_r_  && inAddrRead_a)  inAddrRead_a  <= 0;
+      if (!inDataWrite_r_ && inDataWrite_a) inDataWrite_a <= 0;
+      if (!inAddrWrite_r_ && inAddrWrite_a) inAddrWrite_a <= 0;
+      if ( out_r          && out_a)         out_r <= 0;
 
       if (dram_addr_r && !dram_addr_a) begin
          // busy
@@ -52,15 +54,17 @@ data  out:   out
           dram_addr_r <= 0;
           inAddrWrite_a <= 1;
           inDataWrite_a <= 1;
+          out_d <= { 1'b1, 37'b0 };
+          out_r <= 1;
       end else if (dram_addr_r &&  dram_addr_a && dram_isread) begin
           dram_addr_r <= 0;
           inAddrRead_a <= 1;
-          out_d <= dram_read_data;
+          out_d <= { 1'b0, dram_read_data[36:0] };
           out_r <= 1;
-      end else if (inAddrWrite_r && !inAddrWrite_a && inDataWrite_r && !inDataWrite_a && !dram_addr_r && !dram_addr_a) begin
+      end else if (!out_r && !out_a && inAddrWrite_r && !inAddrWrite_a && inDataWrite_r && !inDataWrite_a && !dram_addr_r && !dram_addr_a) begin
           dram_addr_r <= 1;
           dram_isread <= 0;
-      end else if (inAddrRead_r && !inAddrRead_a && !out_r && !out_a && !dram_addr_r && !dram_addr_a) begin
+      end else if (!out_r && !out_a && inAddrRead_r && !inAddrRead_a && !dram_addr_r && !dram_addr_a) begin
           dram_addr_r <= 1;
           dram_isread <= 1;
       end
index c8e102e..c3ea67d 100644 (file)
@@ -30,25 +30,17 @@ public void service() {
 
 == FPGA ==============================================================
 
-module debug (clk, rst,
-              data_debug_data_r, data_debug_data_a, data_debug_data,
-              data_debug_out_r, data_debug_out_a, data_debug_out );
-  input clk;
-  input rst;
-
-  input  data_debug_data_r;
-  output data_debug_data_a;
-  input  [`DATAWIDTH:0] data_debug_data;
-
-  output  data_debug_out_r;
-  input   data_debug_out_a;
-  output  [`DATAWIDTH:0] data_debug_out;
-
-  assign  data_debug_out_r  = data_debug_data_r;
-  assign  data_debug_data_a = data_debug_out_a;
-  assign  data_debug_out    = data_debug_data;
-
-endmodule
+  assign  out_d_ = in_d;
+  assign  out_r_ = in_r;
+
+  always @(posedge clk) begin
+    if (!rst) begin
+      `reset
+    end else begin
+      `flush
+      in_a  <= out_a;
+    end
+  end
 
 == Test ================================================================
 #expect 25
index 0a620b2..80dcebc 100644 (file)
@@ -31,16 +31,22 @@ at least 16 words.
 
 == FPGA ==============================================================
 
-  input  [(`DATAWIDTH-1):0] in_d;
-  output [(`DATAWIDTH-1):0] out_d_;
-  input in_r;
-  output in_a_;
-  output out_r_;
-  input out_a;
+  wire in_a__;
+  wire out_r__;
 
   fifo8x37 fifo8x37(clk, rst,
-                    in_r,  in_a_, in_d,
-                    out_r_, out_a, out_d_);
+                    in_r,    in_a__, in_d,
+                    out_r__, out_a,  out_d_);
+
+  always @(posedge clk) begin
+    if (!rst) begin
+      `reset
+    end else begin
+      `flush
+      out_r <= out_r__;
+      in_a  <= in_a__;
+    end
+  end
 
 
 == Test =================================================================
index 3820874..dd7831b 100644 (file)
@@ -77,10 +77,11 @@ is considered ``bit zero'').
     if (!rst) begin
       `reset
     end else begin
-      if (!in1_r && in1_a)     in1_a <= 0;
-      if (!in2_r && in2_a)     in2_a <= 0;
-      if (!in3_r && in3_a)     in3_a <= 0;
-      if (!inLut_r && inLut_a) inLut_a <= 0;
+      `flush
+      if (!in1_r_ && in1_a)     in1_a <= 0;
+      if (!in2_r_ && in2_a)     in2_a <= 0;
+      if (!in3_r_ && in3_a)     in3_a <= 0;
+      if (!inLut_r_ && inLut_a) inLut_a <= 0;
       if (out_r && out_a) begin
          in1_a <= 1;
          in2_a <= 1;
index 135102a..f97347c 100644 (file)
@@ -12,7 +12,25 @@ data  out:   out
 
 The {\tt Memory} ship represents an interface to a storage space,
 which can be used to read from it or write to it.  This storage space
-might be a fast on-chip cache, off chip DRAM, or perhaps even a disk drive.
+might be a fast on-chip cache, off chip DRAM, or perhaps even a disk
+drive.
+
+Generally, distinct {\tt Memory} ships do not access the same backing
+storage, although this is not strictly prohibited.
+
+Each {\tt Memory} ship may have multiple {\it interfaces}, numbered
+starting with {\tt 0}.  Each interface may have any subset of the
+following docks: {\tt inCBD}, {\tt inAddrRead}, {\tt inAddrWrite},
+{\tt inDataWrite}, and {\tt out}.  If {\tt inCBD} or {\tt inAddrRead}
+is present on an interface, then {\tt out} must be present as well.
+If {\tt inAddrWrite} is present then {\tt inDataWrite} must be present
+as well.
+
+Each interface serializes the operations presented to it; this means
+that an interface with both read and write capabilities will not be
+able to read and write concurrently.  Instead, a {\tt Memory} ship
+with the ability to read and write concurrently should have two
+interfaces, one which is read-only and one which is write-only.
 
 There may be multiple {\tt Memory} ships which interface to the same
 physical storage space.  An implementation of Fleet must provide
@@ -44,7 +62,8 @@ inCount=size}.
 \subsection*{Reading}
 
 When a word is delivered to {\tt inAddrRead}, the word residing in
-memory at that address is provided at {\tt out}.
+memory at that address is provided at {\tt out}.  The {\tt c-flag} at
+the {\tt out} port is set to zero.
 
 \subsection*{Writing}
 
@@ -52,7 +71,8 @@ When a word is delivered to {\tt inAddrWrite} and {\tt inDataWrite},
 the word at {\tt inDataWrite} is written to the address specified by
 {\tt inAddrWrite}.  Once the word is successfully committed to memory,
 the value {\tt inAddr+inStride} is provided at {\tt out} (that is, the
-address of the next word to be written).
+address of the next word to be written).  The {\tt c-flag} at
+the {\tt out} port is set to one.
 
 \subsection*{To Do}
 
@@ -171,12 +191,13 @@ sequence guarantee problem mentioned in the previous paragraph.
       write_flag <= 0;
       dispatching_cbd <= 0;
     end else begin
+      `flush
       write_flag <= 0;
 
-      if (!inAddrRead_r  && inAddrRead_a)  inAddrRead_a  <= 0;
-      if (!inDataWrite_r && inDataWrite_a) inDataWrite_a <= 0;
-      if (!inAddrWrite_r && inAddrWrite_a) inAddrWrite_a <= 0;
-      if (!inCBD_r &&  inCBD_a)            inCBD_a <= 0;
+      if (!inAddrRead_r_  && inAddrRead_a)  inAddrRead_a  <= 0;
+      if (!inDataWrite_r_ && inDataWrite_a) inDataWrite_a <= 0;
+      if (!inAddrWrite_r_ && inAddrWrite_a) inAddrWrite_a <= 0;
+      if (!inCBD_r_ &&  inCBD_a)            inCBD_a <= 0;
 
       // assumes we never want a zero-length codebag
       if ( inCBD_r && !inCBD_a && !out_r && !out_a) begin
@@ -216,6 +237,9 @@ sequence guarantee problem mentioned in the previous paragraph.
 
 
 == Test ==============================================================
+// FIXME: test c-flag at out dock
+// FIXME: rename to inCBD0, inAddrWrite0, etc
+
 // expected output
 #expect 12
 #expect 13
index 2e2270b..0049ab8 100644 (file)
@@ -46,8 +46,9 @@ public void service() {
     if (!rst) begin
       `reset
     end else begin
-      if (!in_r        && in_a && !inAmount_r)       in_a        <= 0;
-      if (!inAmount_r  && inAmount_a) inAmount_a  <= 0;
+      `flush
+      if (!in_r_       && in_a && !inAmount_r)       in_a        <= 0;
+      if (!inAmount_r_ && inAmount_a) inAmount_a  <= 0;
       if (out_r        && out_a)      out_r       <= 0;
       if (in_r && !in_a && inAmount_r && !inAmount_a && !out_r && !out_a) begin
         in_a  <= 1;
index 82aac06..ec54993 100644 (file)
@@ -92,12 +92,12 @@ data  in:    inData
     if (!rst) begin
       `reset
     end else begin
-
+      `flush
       vga_pixel_a <= vga_pixel_r;
 
-      if (!inData_r && inData_a) inData_a <= 0;
-      if (!inX_r    && inX_a)    inX_a <= 0;
-      if (!inY_r    && inY_a)    inY_a <= 0;
+      if (!inData_r_ && inData_a) inData_a <= 0;
+      if (!inX_r_    && inX_a)    inX_a <= 0;
+      if (!inY_r_    && inY_a)    inY_a <= 0;
       if (inX_r && !inX_a && inY_r && !inY_a && inData_r && !inData_a) begin
          we <= 1;
          inX_a <= 1;