Move from +/shiftx2mux.v into +/techmap.v; cleanup
authorEddie Hung <eddie@fpgeh.com>
Tue, 21 Jan 2020 22:08:24 +0000 (14:08 -0800)
committerEddie Hung <eddie@fpgeh.com>
Tue, 21 Jan 2020 23:19:41 +0000 (15:19 -0800)
techlibs/common/Makefile.inc
techlibs/common/shiftx2mux.v [deleted file]
techlibs/common/techmap.v
tests/techmap/shiftx2mux.ys

index 5d797ec1d242552f7d4936b46074849a34193bf4..a42f63128042a766dcf3bc7ed43aeff3fe8bf0d7 100644 (file)
@@ -30,4 +30,3 @@ $(eval $(call add_share_file,share,techlibs/common/cmp2lut.v))
 $(eval $(call add_share_file,share,techlibs/common/cells.lib))
 $(eval $(call add_share_file,share,techlibs/common/mul2dsp.v))
 $(eval $(call add_share_file,share,techlibs/common/dummy.box))
-$(eval $(call add_share_file,share,techlibs/common/shiftx2mux.v))
diff --git a/techlibs/common/shiftx2mux.v b/techlibs/common/shiftx2mux.v
deleted file mode 100644 (file)
index 5366d67..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-(* techmap_celltype = /*"$shift*/ "$shiftx" *)
-module _80_shift_shiftx (A, B, Y);
-       parameter A_SIGNED = 0;
-       parameter B_SIGNED = 0;
-       parameter A_WIDTH = 1;
-       parameter B_WIDTH = 1;
-       parameter Y_WIDTH = 1;
-
-       input [A_WIDTH-1:0] A;
-       input [B_WIDTH-1:0] B;
-       output [Y_WIDTH-1:0] Y;
-
-    parameter [B_WIDTH-1:0] _TECHMAP_CONSTMSK_B_ = 0;
-    parameter [B_WIDTH-1:0] _TECHMAP_CONSTVAL_B_ = 0;
-
-    generate
-        genvar i;
-        localparam CLOG2_Y_WIDTH = $clog2(Y_WIDTH);
-
-        if (B_WIDTH <= CLOG2_Y_WIDTH+1)
-            wire _TECHMAP_FAIL_ = 1;
-        // In order to perform this optimisation, this $shiftx must
-        //   only shift in units of Y_WIDTH, which we check by ensuring
-        //   that the appropriate LSBs of B are zero
-        else if (_TECHMAP_CONSTMSK_B_[CLOG2_Y_WIDTH-1:0] == {CLOG2_Y_WIDTH{1'b1}} && _TECHMAP_CONSTVAL_B_[CLOG2_Y_WIDTH-1:0] != {CLOG2_Y_WIDTH{1'b0}})
-            wire _TECHMAP_FAIL_ = 1;
-        else begin
-            // Halve the size of $shiftx by $mux-ing A according to 
-            //   the LSB of B, after discarding the zeroed bits
-            wire [(A_WIDTH+Y_WIDTH)/2-1:0] AA;
-            for (i = 0; i < (A_WIDTH/Y_WIDTH); i=i+2)
-                assign AA[(i/2)*Y_WIDTH +: Y_WIDTH] = B[CLOG2_Y_WIDTH] ? A[(i+1)*Y_WIDTH +: Y_WIDTH] : A[(i+0)*Y_WIDTH +: Y_WIDTH];
-            $shiftx #(.A_SIGNED(A_SIGNED), .B_SIGNED(B_SIGNED), .A_WIDTH((A_WIDTH+Y_WIDTH)/2'd2), .B_WIDTH(B_WIDTH-1), .Y_WIDTH(Y_WIDTH)) _TECHMAP_REPLACE_ (.A(AA), .B({B[B_WIDTH-1:CLOG2_Y_WIDTH+1], {CLOG2_Y_WIDTH{1'b0}}}), .Y(Y));
-        end
-    endgenerate
-endmodule
-
-
index d7ec3947eb89bc8578ddc40467dfaf76684a6650..83bd4333c3dc9cd6ecd6427a882032b8c13f0af6 100644 (file)
@@ -129,47 +129,82 @@ module _90_shift_shiftx (A, B, Y);
        input [B_WIDTH-1:0] B;
        output [Y_WIDTH-1:0] Y;
 
-       localparam BB_WIDTH = `MIN($clog2(`MAX(A_WIDTH, Y_WIDTH)) + (B_SIGNED ? 2 : 1), B_WIDTH);
-       localparam WIDTH = `MAX(A_WIDTH, Y_WIDTH) + (B_SIGNED ? 2**(BB_WIDTH-1) : 0);
-
        parameter _TECHMAP_CELLTYPE_ = "";
+       parameter [B_WIDTH-1:0] _TECHMAP_CONSTMSK_B_ = 0;
+       parameter [B_WIDTH-1:0] _TECHMAP_CONSTVAL_B_ = 0;
+
        localparam extbit = _TECHMAP_CELLTYPE_ == "$shift" ? 1'b0 : 1'bx;
 
-       wire [1023:0] _TECHMAP_DO_00_ = "proc;;";
-       wire [1023:0] _TECHMAP_DO_01_ = "CONSTMAP; opt_muxtree; opt_expr -mux_undef -mux_bool -fine;;;";
+       generate
+`ifndef NO_LSB_FIRST_SHIFT_SHIFTX
+               // If $shift/$shiftx only shifts in units of Y_WIDTH
+               //   (a common pattern created by pmux2shiftx)
+               //   which is checked by ensuring that all that
+               //   the appropriate LSBs of B are constant zero,
+               //   then we can decompose LSB first instead of
+               //   MSB first
+               localparam CLOG2_Y_WIDTH = $clog2(Y_WIDTH);
+               if (B_WIDTH > CLOG2_Y_WIDTH+1 &&
+                       _TECHMAP_CONSTMSK_B_[CLOG2_Y_WIDTH-1:0] == {CLOG2_Y_WIDTH{1'b1}} &&
+                       _TECHMAP_CONSTVAL_B_[CLOG2_Y_WIDTH-1:0] == {CLOG2_Y_WIDTH{1'b0}}) begin
+                       // Halve the size of $shift/$shiftx by $mux-ing A according to
+                       //   the LSB of B, after discarding the zeroed bits
+                       localparam len = 2**(B_WIDTH-1);
+                       wire [len-1:0] T, F;
+                       genvar i;
+                       for (i = 0; i < A_WIDTH; i=i+Y_WIDTH*2) begin
+                               assign F[i/2 +: Y_WIDTH] = A[i +: Y_WIDTH];
+                               assign T[i/2 +: Y_WIDTH] = (i + Y_WIDTH < A_WIDTH) ? A[i+Y_WIDTH +: Y_WIDTH] : {Y_WIDTH{extbit}};
+                       end
+                       wire [len-1:0] AA = B[CLOG2_Y_WIDTH] ? T : F;
+                       wire [B_WIDTH-2:0] BB = {B[B_WIDTH-1:CLOG2_Y_WIDTH+1], {CLOG2_Y_WIDTH{1'b0}}};
+                       if (_TECHMAP_CELLTYPE_ == "$shift")
+                               $shift #(.A_SIGNED(A_SIGNED), .B_SIGNED(B_SIGNED), .A_WIDTH(len), .B_WIDTH(B_WIDTH-1), .Y_WIDTH(Y_WIDTH)) _TECHMAP_REPLACE_ (.A(AA), .B(BB), .Y(Y));
+                       else
+                               $shiftx #(.A_SIGNED(A_SIGNED), .B_SIGNED(B_SIGNED), .A_WIDTH(len), .B_WIDTH(B_WIDTH-1), .Y_WIDTH(Y_WIDTH)) _TECHMAP_REPLACE_ (.A(AA), .B(BB), .Y(Y));
+               end
+               else
+`endif
+               begin
+                       localparam BB_WIDTH = `MIN($clog2(`MAX(A_WIDTH, Y_WIDTH)) + (B_SIGNED ? 2 : 1), B_WIDTH);
+                       localparam WIDTH = `MAX(A_WIDTH, Y_WIDTH) + (B_SIGNED ? 2**(BB_WIDTH-1) : 0);
 
-       integer i;
-       reg [WIDTH-1:0] buffer;
-       reg overflow;
+                       wire [1023:0] _TECHMAP_DO_00_ = "proc;;";
+                       wire [1023:0] _TECHMAP_DO_01_ = "CONSTMAP; opt_muxtree; opt_expr -mux_undef -mux_bool -fine;;;";
 
-       always @* begin
-               overflow = 0;
-               buffer = {WIDTH{extbit}};
-               buffer[`MAX(A_WIDTH, Y_WIDTH)-1:0] = A;
-
-               if (B_WIDTH > BB_WIDTH) begin
-                       if (B_SIGNED) begin
-                               for (i = BB_WIDTH; i < B_WIDTH; i = i+1)
-                                       if (B[i] != B[BB_WIDTH-1])
-                                               overflow = 1;
-                       end else
-                               overflow = |B[B_WIDTH-1:BB_WIDTH];
-                       if (overflow)
-                               buffer = {WIDTH{extbit}};
-               end
+                       integer i;
+                       reg [WIDTH-1:0] buffer;
+                       reg overflow;
 
-               for (i = BB_WIDTH-1; i >= 0; i = i-1)
-                       if (B[i]) begin
-                               if (B_SIGNED && i == BB_WIDTH-1)
-                                       buffer = {buffer, {2**i{extbit}}};
-                               else if (2**i < WIDTH)
-                                       buffer = {{2**i{extbit}}, buffer[WIDTH-1 : 2**i]};
-                               else
-                                       buffer = {WIDTH{extbit}};
+                       always @* begin
+                               overflow = 0;
+                               buffer = {WIDTH{extbit}};
+                               buffer[`MAX(A_WIDTH, Y_WIDTH)-1:0] = A;
+
+                               if (B_WIDTH > BB_WIDTH) begin
+                                       if (B_SIGNED) begin
+                                               for (i = BB_WIDTH; i < B_WIDTH; i = i+1)
+                                                       if (B[i] != B[BB_WIDTH-1])
+                                                               overflow = 1;
+                                       end else
+                                               overflow = |B[B_WIDTH-1:BB_WIDTH];
+                                       if (overflow)
+                                               buffer = {WIDTH{extbit}};
+                               end
+
+                               for (i = BB_WIDTH-1; i >= 0; i = i-1)
+                                       if (B[i]) begin
+                                               if (B_SIGNED && i == BB_WIDTH-1)
+                                                       buffer = {buffer, {2**i{extbit}}};
+                                               else if (2**i < WIDTH)
+                                                       buffer = {{2**i{extbit}}, buffer[WIDTH-1 : 2**i]};
+                                               else
+                                                       buffer = {WIDTH{extbit}};
+                                       end
                        end
-       end
-
-       assign Y = buffer;
+                       assign Y = buffer;
+               end
+       endgenerate
 endmodule
 
 
index acdd54e9e243f2569807e739318b56abb16fc4a2..c13b5f600baf9ee635980056b01a2bd55a297b56 100644 (file)
@@ -74,13 +74,13 @@ design -save gold
 
 
 design -load gold
-techmap
+techmap -D NO_LSB_FIRST_SHIFT_SHIFTX
 abc -lut 6
 select -assert-min 17 t:$lut
 
 
 design -load gold
-techmap -map +/shiftx2mux.v -map +/techmap.v
+techmap
 abc -lut 6
 select -assert-count 16 t:$lut
 
@@ -92,13 +92,13 @@ sat -verify -prove-asserts -show-ports miter
 
 
 design -load gold
-techmap
+techmap -D NO_LSB_FIRST_SHIFT_SHIFTX
 abc9 -lut 6
 select -assert-min 17 t:$lut
 
 
 design -load gold
-techmap -map +/shiftx2mux.v -map +/techmap.v
+techmap
 abc9 -lut 6
 select -assert-count 16 t:$lut