mux_map to drop sign bit, and eliminate 'bx-es
authorEddie Hung <eddie@fpgeh.com>
Thu, 20 Jun 2019 23:45:04 +0000 (16:45 -0700)
committerEddie Hung <eddie@fpgeh.com>
Thu, 20 Jun 2019 23:45:04 +0000 (16:45 -0700)
techlibs/xilinx/mux_map.v

index 0fa8db736ba5792e56a7d90d05e279cd16e76eb2..6ad83a4887bc8dbeca3ae442943b0a34eb76954f 100644 (file)
@@ -29,24 +29,58 @@ module \$shiftx (A, B, Y);
   input [B_WIDTH-1:0] B;
   output [Y_WIDTH-1:0] Y;
 
+  parameter [A_WIDTH-1:0] _TECHMAP_CONSTMSK_A_ = 0;
+  parameter [A_WIDTH-1:0] _TECHMAP_CONSTVAL_A_ = 0;
   parameter [B_WIDTH-1:0] _TECHMAP_CONSTMSK_B_ = 0;
   parameter [B_WIDTH-1:0] _TECHMAP_CONSTVAL_B_ = 0;
 
   generate
-    genvar i, j;
-    // TODO: Check if this opt still necessary
-    if (B_SIGNED) begin
-      if (_TECHMAP_CONSTMSK_B_[B_WIDTH-1] && _TECHMAP_CONSTVAL_B_[B_WIDTH-1] == 1'b0)
-        // Optimisation to remove B_SIGNED if sign bit of B is constant-0
-        \$__XILINX_SHIFTX  #(.A_SIGNED(A_SIGNED), .B_SIGNED(0), .A_WIDTH(A_WIDTH), .B_WIDTH(B_WIDTH-1'd1), .Y_WIDTH(Y_WIDTH)) _TECHMAP_REPLACE_ (.A(A), .B(B[B_WIDTH-2:0]), .Y(Y));
+    genvar i;
+    wire [A_WIDTH-1:0] A_forward;
+    assign A_forward[A_WIDTH-1] = A[A_WIDTH-1];
+    for (i = A_WIDTH-2; i >= 0; i = i - 1)
+      if (_TECHMAP_CONSTMSK_A_[i] && _TECHMAP_CONSTVAL_A_[i] === 1'bx)
+        assign A_forward[i] = A_forward[i+1];
       else
-        wire _TECHMAP_FAIL_ = 1;
-    end
-    else if (B_WIDTH < 3 || A_WIDTH <= 4) begin
-      wire _TECHMAP_FAIL_ = 1;
-    end
-    else begin
-        \$__XILINX_SHIFTX  #(.A_SIGNED(A_SIGNED), .B_SIGNED(B_SIGNED), .A_WIDTH(A_WIDTH), .B_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) _TECHMAP_REPLACE_ (.A(A), .B(B), .Y(Y));
+        assign A_forward[i] = A[i];
+
+      wire [A_WIDTH-1:0] A_without_x;
+      assign A_without_x[0] = A_forward[0];
+      for (i = 1; i < A_WIDTH; i = i + 1)
+        if (_TECHMAP_CONSTMSK_A_[i] && _TECHMAP_CONSTVAL_A_[i] === 1'bx)
+          assign A_without_x[i] = A_without_x[i-1];
+        else
+          assign A_without_x[i] = A[i];
+
+        if (B_SIGNED) begin
+          if (B_WIDTH < 4 || A_WIDTH <= 4)
+            wire _TECHMAP_FAIL_ = 1;
+          else
+            // Since negative indices are out of the range of A
+            // and hence return 'bx, drop the sign bit
+            \$__XILINX_SHIFTX #(
+              .A_SIGNED(A_SIGNED),
+              .B_SIGNED(0),
+              .A_WIDTH(A_WIDTH),
+              .B_WIDTH(B_WIDTH-1'd1),
+              .Y_WIDTH(Y_WIDTH)
+            ) _TECHMAP_REPLACE_ (
+              .A(A_without_x), .B(B[B_WIDTH-2:0]), .Y(Y)
+            );
+      end
+      else begin
+        if (B_WIDTH < 3 || A_WIDTH <= 4)
+          wire _TECHMAP_FAIL_ = 1;
+        else
+          \$__XILINX_SHIFTX #(
+            .A_SIGNED(A_SIGNED),
+            .B_SIGNED(B_SIGNED),
+            .A_WIDTH(A_WIDTH),
+            .B_WIDTH(B_WIDTH),
+            .Y_WIDTH(Y_WIDTH)
+          ) _TECHMAP_REPLACE_ (
+            .A(A_without_x), .B(B), .Y(Y)
+          );
     end
   endgenerate
 endmodule