lots of changes to Marina test code, mostly for scan chain counters
[fleet.git] / ships / Alu.ship
index 29293e4..67effe4 100644 (file)
@@ -14,6 +14,9 @@ data  in:   inOp
   constant DROP1: 7
   constant DROP2: 8
   constant MAXMERGE: 9
+  constant AND: 10
+  constant OR: 11
+  constant XOR: 12
 
 data  out:  out
 
@@ -88,25 +91,27 @@ public void service() {
               b = box_in2.removeDataForShip();
               box_out.addDataFromShip(a-b); // SUB
               break;
-          case 9:
+
+          case 9: // MAXMERGE
               if (box_in1.peekDataForShip()<0 && box_in2.peekDataForShip()<0) {
                 a = box_in1.removeDataForShip();
                 b = box_in2.removeDataForShip();
                 box_out.addDataFromShip(a, false);
                 break;
               }
-              // fall through
+              // fall through to MAX
           case 4:
               a = box_in1.peekDataForShip();
               b = box_in2.peekDataForShip();
               box_out.addDataFromShip(Math.max(a,b), !(a>b)); // MAX
-              if (a<b) box_in1.removeDataForShip(); else box_in2.removeDataForShip();
+              if (a>b) box_in1.removeDataForShip(); else box_in2.removeDataForShip();
               break;
+
           case 5:
               a = box_in1.peekDataForShip();
               b = box_in2.peekDataForShip();
               box_out.addDataFromShip(Math.min(a,b), a>b); // MIN
-              if (a>b) box_in1.removeDataForShip(); else box_in2.removeDataForShip();
+              if (a<b) box_in1.removeDataForShip(); else box_in2.removeDataForShip();
               break;
           case 6:
               a = box_in1.removeDataForShip();
@@ -121,6 +126,21 @@ public void service() {
               box_in2.removeDataForShip();      // DROP2
               break;
 */
+          case 10:
+              a = box_in1.removeDataForShip();
+              b = box_in2.removeDataForShip();
+              box_out.addDataFromShip(a & b); // CMP
+              break;
+          case 11:
+              a = box_in1.removeDataForShip();
+              b = box_in2.removeDataForShip();
+              box_out.addDataFromShip(a | b); // CMP
+              break;
+          case 12:
+              a = box_in1.removeDataForShip();
+              b = box_in2.removeDataForShip();
+              box_out.addDataFromShip(a ^ b); // CMP
+              break;
           default:
               throw new RuntimeException("invalid opcode: " + op);
       }
@@ -140,10 +160,10 @@ public void service() {
   wire                    eq;
   wire                    cout;
 
-  wire [3:0]              inOp_d_trunc;
-  assign                  inOp_d_trunc = inOp_d[3:0];
+  wire [4:0]              inOp_d_trunc;
+  assign                  inOp_d_trunc = inOp_d[4:0];
 
-  assign isplus        = inOp_d_trunc[2:0]==2;
+  assign isplus        = inOp_d_trunc[4:0]==2;
   assign cin           = isplus ? 0 : 1;
   assign in2_inverted  = isplus ? in2_d : ~in2_d;
   assign sum           = {in1_d,cin} + {in2_inverted,cin};
@@ -175,10 +195,21 @@ public void service() {
           (inOp_d_trunc==5) ? (greater ? in2_d : in1_d)  :
           (inOp_d_trunc==6) ? {{ (`WORDWIDTH-1) {1'b0 }}, eq  } :
           (inOp_d_trunc==9) ? (both_negative ? in1_d : (greater ? in1_d : in2_d)) :
+          (inOp_d_trunc==10) ? (in1_d & in2_d) :
+          (inOp_d_trunc==11) ? (in1_d | in2_d) :
+          (inOp_d_trunc==12) ? (in1_d ^ in2_d) :
           0;
 
+  wire firing_condition;
+  assign firing_condition =
+          (inOp_d_trunc==0) ? `in1_full  :
+          (inOp_d_trunc==1) ? `in2_full  :
+          (inOp_d_trunc==7) ? `in1_full  :
+          (inOp_d_trunc==8) ? `in2_full  :
+          ((`in1_full) && (`in2_full));
+
   always @(posedge clk) begin
-    if (!rst) begin
+    if (rst) begin
       `reset
       out_draining <= 0;
     end else begin
@@ -188,6 +219,8 @@ public void service() {
         out_draining <= 0;
         if      (inOp_d_trunc==0) `drain_in1
         else if (inOp_d_trunc==1) `drain_in2
+        else if (inOp_d_trunc==7) `drain_in1
+        else if (inOp_d_trunc==8) `drain_in2
         else if (inOp_d_trunc==9 &&  both_negative) begin `drain_in1 `drain_in2 end
         else if (inOp_d_trunc==4 &&  greater) `drain_in1
         else if (inOp_d_trunc==5 &&  greater) `drain_in2
@@ -200,8 +233,8 @@ public void service() {
           `drain_in2
         end
       end
-      if (!out_draining && `out_empty && `in1_full && `in2_full && `inOp_full) begin
-        `fill_out
+      if (!out_draining && `out_empty && firing_condition && `inOp_full) begin
+        if (inOp_d_trunc!=7 && inOp_d_trunc!=8) `fill_out
         out_draining <= 1;
       end
     end