overhaul Alu2 fpga code, add new opcodes
authoradam <adam@megacz.com>
Thu, 21 Aug 2008 10:33:34 +0000 (11:33 +0100)
committeradam <adam@megacz.com>
Thu, 21 Aug 2008 10:33:34 +0000 (11:33 +0100)
ships/Alu2.ship

index 10b3eeb..7f270b6 100644 (file)
@@ -4,10 +4,13 @@ ship: Alu2
 data  in:   in1
 data  in:   in2
 data  in:   inOp
-  constant ADD: 0
-  constant SUB: 1
-  constant MAX: 2
-  constant MIN: 3
+  constant IN1: 0
+  constant IN2: 1
+  constant ADD: 2
+  constant SUB: 3
+  constant MAX: 4
+  constant MIN: 5
+  constant CMP: 6
 
 data  out:  out
 
@@ -30,6 +33,18 @@ at {\tt inOp}, the requested operation is performed on the values
 consumed from {\tt in1} and {\tt in2}.  The result of this operation
 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
+\end{verbatim}
+
 \subsection*{To Do}
 
 The {\it link bit} and other features of \cite{ies31} are not yet
@@ -49,13 +64,19 @@ public void service() {
       long b      = box_in2.removeDataForShip();
       long op     = box_inOp.removeDataForShip();
       switch((int)op) {
-          case 0: box_out.addDataFromShip(a+b); // ADD
+          case 0: box_out.addDataFromShip(a); // IN1
+              break;
+          case 1: box_out.addDataFromShip(b); // IN2
               break;
-          case 1: box_out.addDataFromShip(a-b); // SUB
+          case 2: box_out.addDataFromShip(a+b); // ADD
               break;
-          case 2: box_out.addDataFromShip(Math.max(a,b)); // MAX
+          case 3: box_out.addDataFromShip(a-b); // SUB
               break;
-          case 3: box_out.addDataFromShip(Math.min(a,b)); // MIN
+          case 4: box_out.addDataFromShip(Math.max(a,b)); // MAX
+              box_out.flag_c = !(a>b);
+              break;
+          case 5: box_out.addDataFromShip(Math.min(a,b)); // MIN
+              box_out.flag_c = a>b;
               break;
           default: box_out.addDataFromShip(0);
               break;
@@ -67,58 +88,137 @@ public void service() {
 
 == FPGA ==============================================================
 
+  wire [`DATAWIDTH:0]     sum;
+  wire                    cin;
+  wire [(`DATAWIDTH-1):0] in2_inverted;
+
+  wire [(`DATAWIDTH-1):0] res;
+  wire                    isplus;
+  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 out_d_[`DATAWIDTH] =
+          (inOp_d==0) ? 1'b0 :
+          (inOp_d==1) ? 1'b0 :
+          (inOp_d==2) ? cout :
+          (inOp_d==3) ? 1'b0 :
+          (inOp_d==4) ? ~greater :
+          (inOp_d==5) ?  greater :
+          (inOp_d==6) ?  eq :
+          0;
+
+  assign out_d_[(`DATAWIDTH-1):0] =
+          (inOp_d==0) ? (in1_d)  :
+          (inOp_d==1) ? (in2_d)  :
+          (inOp_d==2) ? (res)  :
+          (inOp_d==3) ? (res)  :
+          (inOp_d==4) ? (greater ? in1_d : in2_d)  :
+          (inOp_d==5) ? (greater ? in2_d : in1_d)  :
+          (inOp_d==6) ? {{ (`DATAWIDTH-1) {1'b0 }}, eq  } :
+          0;
+
   always @(posedge clk) begin
     if (!rst) begin
       `reset
     end else begin
-      if (out_r    && out_a)    out_r    <= 0;
       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 && in1_r && !in1_a && in2_r && !in2_a && inOp_r && !inOp_a) begin
-        out_r <= 1;
+      if (out_r    && out_a) begin
+        out_r    <= 0;
         in1_a <= 1;
         in2_a <= 1;
         inOp_a <= 1;
-        case (inOp_d)
-          0: out_d <= in1_d + in2_d;
-          1: out_d <= in1_d - in2_d;
-          2: out_d <= in1_d > in2_d ? in1_d : in2_d;
-          3: out_d <= in1_d > in2_d ? in2_d : in1_d;
-          default: out_d <= 0;
-        endcase        
+      end
+      if (!out_r && !out_a && in1_r && !in1_a && in2_r && !in2_a && inOp_r && !inOp_a) begin
+        out_r <= 1;
       end
     end
   end
 
 == Test ==============================================================================
-// expected output
+
+// FIXME: need test for ADD carry-out c-flag
+
 #ship debug : Debug
 #ship alu   : Alu2
 
 #expect 17
 #expect 1
+#expect 9
+#expect 8
 #expect 8
+#expect 1
 #expect 9
+#expect 0
+#expect 0
+#expect 0
+#expect 1
+#expect 1
 
 debug.in:   [*] take, deliver;
 alu.in1:
-  literal 9; load repeat counter with 4; deliver;
+  literal 9;
+  load repeat counter with 7;
+  deliver;
+  literal 9;
+  deliver;
 
 alu.in2:
-  literal 8; load repeat counter with 4; deliver;
-
+  literal 8;
+  load repeat counter with 7;
+  deliver;
+  literal 9;
+  deliver;
+
+alu.out:
+  load repeat counter with 4;
+  take, sendto debug.in;
 alu.inOp:
  literal Alu2.inOp[ADD]; deliver;
  literal Alu2.inOp[SUB]; deliver;
+ literal Alu2.inOp[IN1]; deliver;
+ literal Alu2.inOp[IN2]; deliver;
+
+alu.inOp:
  literal Alu2.inOp[MIN]; deliver;
  literal Alu2.inOp[MAX]; deliver;
-
-alu.in1:    [*] take, deliver;
-alu.in2:    [*] take, deliver;
-alu.out:    [*] take, sendto debug.in;
-
-
+ literal Alu2.inOp[CMP]; deliver;
+ literal Alu2.inOp[CMP]; deliver;
+
+alu.out:
+  take, sendto debug.in;        // MIN
+  setflags a=c, b=b;
+  [a]  literal 1;
+  [!a] literal 0;
+  sendto debug.in;
+
+  take, sendto debug.in;        // MAX
+  setflags a=c, b=b;
+  [a]  literal 1;
+  [!a] literal 0;
+  sendto debug.in;
+
+  take, sendto debug.in;        // CMP
+  setflags a=c, b=b;
+  [a]  literal 1;
+  [!a] literal 0;
+  sendto debug.in;
+
+  take, sendto debug.in;        // CMP
+  setflags a=c, b=b;
+  [a]  literal 1;
+  [!a] literal 0;
+  sendto debug.in;
 
 == Contributors =========================================================
 Adam Megacz <megacz@cs.berkeley.edu>