techmap/shift_shiftx: Remove the "shiftx2mux" special path.
authorMarcelina Kościelnicka <mwk@0x04.net>
Wed, 19 Aug 2020 11:59:59 +0000 (13:59 +0200)
committerMarcelina Kościelnicka <mwk@0x04.net>
Thu, 20 Aug 2020 10:44:09 +0000 (12:44 +0200)
Our techmap rules for $shift and $shiftx cells contained a special path
that aimed to decompose the shift LSB-first instead of MSB-first in
select cases that come up in pmux lowering.  This path was needlessly
overcomplicated and contained bugs.

Instead of doing that, just switch over the main path to iterate
LSB-first (except for the specially-handled MSB for signed shifts
and overflow handling).  This also makes the code consistent with
shl/shr/sshl/sshr cells, which are already decomposed LSB-first.

Fixes #2346.

techlibs/common/techmap.v
tests/arch/intel_alm/mux.ys
tests/techmap/shiftx2mux.ys

index 03c27d49d9ecf42abf7c5cdd2808dd6740996df4..2ab28e6e68026e3fda51d8f83bafa3770774e15a 100644 (file)
@@ -143,78 +143,46 @@ module _90_shift_shiftx (A, B, Y);
        localparam extbit = _TECHMAP_CELLTYPE_ == "$shift" ? 1'b0 : 1'bx;
        wire a_padding = _TECHMAP_CELLTYPE_ == "$shiftx" ? extbit : (A_SIGNED ? A[A_WIDTH-1] : 1'b0);
 
-       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 Y_WIDTH2 = 2**CLOG2_Y_WIDTH;
-                       localparam entries = (A_WIDTH+Y_WIDTH-1)/Y_WIDTH2;
-                       localparam len = Y_WIDTH2 * ((entries+1)/2);
-                       wire [len-1:0] AA;
-                       wire [(A_WIDTH+Y_WIDTH2+Y_WIDTH-1)-1:0] Apad = {{(Y_WIDTH2+Y_WIDTH-1){a_padding}}, A};
-                       genvar i;
-                       for (i = 0; i < A_WIDTH; i=i+Y_WIDTH2*2)
-                               assign AA[i/2 +: Y_WIDTH2] = B[CLOG2_Y_WIDTH] ? Apad[i+Y_WIDTH2 +: Y_WIDTH2] : Apad[i +: Y_WIDTH2];
-                       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);
+       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);
 
-                       wire [1023:0] _TECHMAP_DO_00_ = "proc;;";
-                       wire [1023:0] _TECHMAP_DO_01_ = "CONSTMAP; opt_muxtree; opt_expr -mux_undef -mux_bool -fine;;;";
+       wire [1023:0] _TECHMAP_DO_00_ = "proc;;";
+       wire [1023:0] _TECHMAP_DO_01_ = "CONSTMAP; opt_muxtree; opt_expr -mux_undef -mux_bool -fine;;;";
 
-                       integer i;
-                       (* force_downto *)
-                       reg [WIDTH-1:0] buffer;
-                       reg overflow;
+       integer i;
+       (* force_downto *)
+       reg [WIDTH-1:0] buffer;
+       reg overflow;
 
-                       always @* begin
-                               overflow = 0;
+       always @* begin
+               overflow = 0;
+               buffer = {WIDTH{extbit}};
+               buffer[Y_WIDTH-1:0] = {Y_WIDTH{a_padding}};
+               buffer[A_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}};
-                               buffer[Y_WIDTH-1:0] = {Y_WIDTH{a_padding}};
-                               buffer[A_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
-                       assign Y = buffer;
                end
-       endgenerate
+
+               if (B_SIGNED && B[BB_WIDTH-1])
+                       buffer = {buffer, {2**(BB_WIDTH-1){extbit}}};
+
+               for (i = 0; i < (B_SIGNED ? BB_WIDTH-1 : BB_WIDTH); i = i+1)
+                       if (B[i]) begin
+                               if (2**i < WIDTH)
+                                       buffer = {{2**i{extbit}}, buffer[WIDTH-1 : 2**i]};
+                               else
+                                       buffer = {WIDTH{extbit}};
+                       end
+       end
+       assign Y = buffer;
 endmodule
 
 
index 01cc78e1b11fab0ec1750585726980488f18fcb4..ac3b9b08f084daf4f41ca20c4a69a90689d0eed9 100644 (file)
@@ -70,8 +70,9 @@ equiv_opt -assert -map +/intel_alm/common/alm_sim.v synth_intel_alm -family cycl
 design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
 cd mux16 # Constrain all select calls below inside the top module
 select -assert-count 1 t:MISTRAL_ALUT3
-select -assert-count 5 t:MISTRAL_ALUT6
-select -assert-none t:MISTRAL_ALUT3 t:MISTRAL_ALUT6 %% t:* %D
+select -assert-max 2 t:MISTRAL_ALUT5
+select -assert-max 5 t:MISTRAL_ALUT6
+select -assert-none t:MISTRAL_ALUT3 t:MISTRAL_ALUT5 t:MISTRAL_ALUT6 %% t:* %D
 
 
 design -load read
index eb29680f6659ea98e40cf3e7290dca1783c09e80..f749e79b2f28bce414fa551a8f58ceed0c4b96c9 100644 (file)
@@ -73,12 +73,6 @@ pmux2shiftx
 design -save gold
 
 
-design -load gold
-techmap -D NO_LSB_FIRST_SHIFT_SHIFTX
-abc -lut 6
-select -assert-min 17 t:$lut
-
-
 design -load gold
 techmap
 abc -lut 6
@@ -91,12 +85,6 @@ miter -equiv -flatten -make_assert -make_outputs gold gate miter
 sat -verify -prove-asserts -show-ports miter
 
 
-design -load gold
-techmap -D NO_LSB_FIRST_SHIFT_SHIFTX
-abc9 -lut 6
-select -assert-min 17 t:$lut
-
-
 design -load gold
 techmap
 abc9 -lut 6