mirror of https://github.com/YosysHQ/yosys.git
New techmap default rules for $shr $sshr $shl $sshl
This commit is contained in:
parent
3f0a5746ef
commit
6c05badc43
|
@ -30,6 +30,9 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
`define MIN(_a, _b) ((_a) < (_b) ? (_a) : (_b))
|
||||||
|
`define MAX(_a, _b) ((_a) > (_b) ? (_a) : (_b))
|
||||||
|
|
||||||
// --------------------------------------------------------
|
// --------------------------------------------------------
|
||||||
|
|
||||||
(* techmap_simplemap *)
|
(* techmap_simplemap *)
|
||||||
|
@ -65,7 +68,7 @@ output [Y_WIDTH-1:0] Y;
|
||||||
.A_WIDTH(1),
|
.A_WIDTH(1),
|
||||||
.B_WIDTH(A_WIDTH),
|
.B_WIDTH(A_WIDTH),
|
||||||
.Y_WIDTH(Y_WIDTH)
|
.Y_WIDTH(Y_WIDTH)
|
||||||
) sub (
|
) _TECHMAP_REPLACE_ (
|
||||||
.A(1'b0),
|
.A(1'b0),
|
||||||
.B(A),
|
.B(A),
|
||||||
.Y(Y)
|
.Y(Y)
|
||||||
|
@ -129,34 +132,55 @@ endmodule
|
||||||
|
|
||||||
// --------------------------------------------------------
|
// --------------------------------------------------------
|
||||||
|
|
||||||
module \$__shift (XL, XR, A, Y);
|
(* techmap_celltype = "$shr $shl $sshl $sshr" *)
|
||||||
|
module shift_ops_shr_shl_sshl_sshr (A, B, Y);
|
||||||
|
|
||||||
parameter WIDTH = 1;
|
parameter A_SIGNED = 0;
|
||||||
parameter SHIFT = 0;
|
parameter B_SIGNED = 0;
|
||||||
|
parameter A_WIDTH = 1;
|
||||||
|
parameter B_WIDTH = 1;
|
||||||
|
parameter Y_WIDTH = 1;
|
||||||
|
|
||||||
input XL, XR;
|
parameter _TECHMAP_CELLTYPE_ = "";
|
||||||
input [WIDTH-1:0] A;
|
localparam shift_left = _TECHMAP_CELLTYPE_ == "$shl" || _TECHMAP_CELLTYPE_ == "$sshl";
|
||||||
output [WIDTH-1:0] Y;
|
localparam sign_extend = A_SIGNED && _TECHMAP_CELLTYPE_ == "$sshr";
|
||||||
|
|
||||||
genvar i;
|
input [A_WIDTH-1:0] A;
|
||||||
generate
|
input [B_WIDTH-1:0] B;
|
||||||
for (i = 0; i < WIDTH; i = i + 1) begin:V
|
output [Y_WIDTH-1:0] Y;
|
||||||
if (i+SHIFT < 0) begin
|
|
||||||
assign Y[i] = XR;
|
localparam WIDTH = `MAX(A_WIDTH, Y_WIDTH);
|
||||||
end else
|
localparam BB_WIDTH = `MIN($clog2(shift_left ? Y_WIDTH : A_SIGNED ? WIDTH : A_WIDTH) + 1, B_WIDTH);
|
||||||
if (i+SHIFT < WIDTH) begin
|
|
||||||
assign Y[i] = A[i+SHIFT];
|
wire [1023:0] _TECHMAP_DO_ = "proc; opt_muxtree; opt_const -mux_undef -mux_bool -fine;;;";
|
||||||
end else begin
|
|
||||||
assign Y[i] = XL;
|
integer i;
|
||||||
|
reg [WIDTH-1:0] buffer;
|
||||||
|
reg overflow;
|
||||||
|
|
||||||
|
always @* begin
|
||||||
|
overflow = B_WIDTH > BB_WIDTH ? |B[B_WIDTH-1:BB_WIDTH] : 1'b0;
|
||||||
|
buffer = overflow ? {WIDTH{sign_extend ? A[A_WIDTH-1] : 1'b0}} : {{WIDTH-A_WIDTH{A_SIGNED ? A[A_WIDTH-1] : 1'b0}}, A};
|
||||||
|
|
||||||
|
for (i = 0; i < BB_WIDTH; i = i+1)
|
||||||
|
if (B[i]) begin
|
||||||
|
if (shift_left)
|
||||||
|
buffer = {buffer, (2**i)'b0};
|
||||||
|
else if (2**i < WIDTH)
|
||||||
|
buffer = {{2**i{sign_extend ? buffer[WIDTH-1] : 1'b0}}, buffer[WIDTH-1 : 2**i]};
|
||||||
|
else
|
||||||
|
buffer = {WIDTH{sign_extend ? buffer[WIDTH-1] : 1'b0}};
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
endgenerate
|
|
||||||
|
assign Y = buffer;
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
// --------------------------------------------------------
|
// --------------------------------------------------------
|
||||||
|
|
||||||
module \$shl (A, B, Y);
|
(* techmap_celltype = "$shift $shiftx" *)
|
||||||
|
module shift_shiftx (A, B, Y);
|
||||||
|
|
||||||
parameter A_SIGNED = 0;
|
parameter A_SIGNED = 0;
|
||||||
parameter B_SIGNED = 0;
|
parameter B_SIGNED = 0;
|
||||||
|
@ -164,294 +188,50 @@ parameter A_WIDTH = 1;
|
||||||
parameter B_WIDTH = 1;
|
parameter B_WIDTH = 1;
|
||||||
parameter Y_WIDTH = 1;
|
parameter Y_WIDTH = 1;
|
||||||
|
|
||||||
parameter WIDTH = Y_WIDTH;
|
|
||||||
localparam BB_WIDTH = $clog2(WIDTH) + 2 < B_WIDTH ? $clog2(WIDTH) + 2 : B_WIDTH;
|
|
||||||
|
|
||||||
input [A_WIDTH-1:0] A;
|
input [A_WIDTH-1:0] A;
|
||||||
input [B_WIDTH-1:0] B;
|
input [B_WIDTH-1:0] B;
|
||||||
output [Y_WIDTH-1:0] Y;
|
output [Y_WIDTH-1:0] Y;
|
||||||
|
|
||||||
genvar i;
|
localparam BB_WIDTH = `MIN($clog2(`MAX(A_WIDTH, Y_WIDTH)) + (B_SIGNED ? 2 : 1), B_WIDTH);
|
||||||
generate
|
localparam WIDTH = `MAX(A_WIDTH, Y_WIDTH) + (B_SIGNED ? 2**(BB_WIDTH-1) : 0);
|
||||||
wire [WIDTH*(BB_WIDTH+1)-1:0] chain;
|
|
||||||
\$bu0 #(
|
|
||||||
.A_SIGNED(A_SIGNED),
|
|
||||||
.A_WIDTH(A_WIDTH),
|
|
||||||
.Y_WIDTH(WIDTH)
|
|
||||||
) expand (
|
|
||||||
.A(A),
|
|
||||||
.Y(chain[WIDTH-1:0])
|
|
||||||
);
|
|
||||||
assign Y = chain[WIDTH*(BB_WIDTH+1)-1 : WIDTH*BB_WIDTH];
|
|
||||||
for (i = 0; i < BB_WIDTH; i = i + 1) begin:V
|
|
||||||
wire [WIDTH-1:0] unshifted, shifted, result;
|
|
||||||
assign unshifted = chain[WIDTH*i + WIDTH-1 : WIDTH*i];
|
|
||||||
assign chain[WIDTH*(i+1) + WIDTH-1 : WIDTH*(i+1)] = result;
|
|
||||||
wire BBIT;
|
|
||||||
if (i == BB_WIDTH-1 && BB_WIDTH < B_WIDTH)
|
|
||||||
assign BBIT = |B[B_WIDTH-1:BB_WIDTH-1];
|
|
||||||
else
|
|
||||||
assign BBIT = B[i];
|
|
||||||
\$__shift #(
|
|
||||||
.WIDTH(WIDTH),
|
|
||||||
.SHIFT(0 - (2 ** (i > 30 ? 30 : i)))
|
|
||||||
) sh (
|
|
||||||
.XL(1'b0),
|
|
||||||
.XR(1'b0),
|
|
||||||
.A(unshifted),
|
|
||||||
.Y(shifted)
|
|
||||||
);
|
|
||||||
\$mux #(
|
|
||||||
.WIDTH(WIDTH)
|
|
||||||
) mux (
|
|
||||||
.A(unshifted),
|
|
||||||
.B(shifted),
|
|
||||||
.Y(result),
|
|
||||||
.S(BBIT)
|
|
||||||
);
|
|
||||||
end
|
|
||||||
endgenerate
|
|
||||||
|
|
||||||
endmodule
|
parameter _TECHMAP_CELLTYPE_ = "";
|
||||||
|
localparam extbit = _TECHMAP_CELLTYPE_ == "$shift" ? 1'b0 : 1'bx;
|
||||||
|
|
||||||
// --------------------------------------------------------
|
wire [1023:0] _TECHMAP_DO_ = "proc; opt_muxtree; opt_const -mux_undef -mux_bool -fine;;;";
|
||||||
|
|
||||||
module \$shr (A, B, Y);
|
integer i;
|
||||||
|
reg [WIDTH-1:0] buffer;
|
||||||
|
reg overflow;
|
||||||
|
|
||||||
parameter A_SIGNED = 0;
|
always @* begin
|
||||||
parameter B_SIGNED = 0;
|
overflow = 0;
|
||||||
parameter A_WIDTH = 1;
|
buffer = {WIDTH{extbit}};
|
||||||
parameter B_WIDTH = 1;
|
buffer[`MAX(A_WIDTH, Y_WIDTH)-1:0] = A;
|
||||||
parameter Y_WIDTH = 1;
|
|
||||||
|
|
||||||
localparam WIDTH = A_WIDTH > Y_WIDTH ? A_WIDTH : Y_WIDTH;
|
if (B_WIDTH > BB_WIDTH) begin
|
||||||
localparam BB_WIDTH = $clog2(WIDTH) + 2 < B_WIDTH ? $clog2(WIDTH) + 2 : B_WIDTH;
|
if (B_SIGNED) begin
|
||||||
|
for (i = BB_WIDTH; i < B_WIDTH; i = i+1)
|
||||||
input [A_WIDTH-1:0] A;
|
if (B[i] != B[BB_WIDTH-1])
|
||||||
input [B_WIDTH-1:0] B;
|
overflow = 1;
|
||||||
output [Y_WIDTH-1:0] Y;
|
|
||||||
|
|
||||||
genvar i;
|
|
||||||
generate
|
|
||||||
wire [WIDTH*(BB_WIDTH+1)-1:0] chain;
|
|
||||||
\$bu0 #(
|
|
||||||
.A_SIGNED(A_SIGNED),
|
|
||||||
.A_WIDTH(A_WIDTH),
|
|
||||||
.Y_WIDTH(WIDTH)
|
|
||||||
) expand (
|
|
||||||
.A(A),
|
|
||||||
.Y(chain[WIDTH-1:0])
|
|
||||||
);
|
|
||||||
assign Y = chain[WIDTH*(BB_WIDTH+1)-1 : WIDTH*BB_WIDTH];
|
|
||||||
for (i = 0; i < BB_WIDTH; i = i + 1) begin:V
|
|
||||||
wire [WIDTH-1:0] unshifted, shifted, result;
|
|
||||||
assign unshifted = chain[WIDTH*i + WIDTH-1 : WIDTH*i];
|
|
||||||
assign chain[WIDTH*(i+1) + WIDTH-1 : WIDTH*(i+1)] = result;
|
|
||||||
wire BBIT;
|
|
||||||
if (i == BB_WIDTH-1 && BB_WIDTH < B_WIDTH)
|
|
||||||
assign BBIT = |B[B_WIDTH-1:BB_WIDTH-1];
|
|
||||||
else
|
|
||||||
assign BBIT = B[i];
|
|
||||||
\$__shift #(
|
|
||||||
.WIDTH(WIDTH),
|
|
||||||
.SHIFT(2 ** (i > 30 ? 30 : i))
|
|
||||||
) sh (
|
|
||||||
.XL(1'b0),
|
|
||||||
.XR(1'b0),
|
|
||||||
.A(unshifted),
|
|
||||||
.Y(shifted)
|
|
||||||
);
|
|
||||||
\$mux #(
|
|
||||||
.WIDTH(WIDTH)
|
|
||||||
) mux (
|
|
||||||
.A(unshifted),
|
|
||||||
.B(shifted),
|
|
||||||
.Y(result),
|
|
||||||
.S(BBIT)
|
|
||||||
);
|
|
||||||
end
|
|
||||||
endgenerate
|
|
||||||
|
|
||||||
endmodule
|
|
||||||
|
|
||||||
// --------------------------------------------------------
|
|
||||||
|
|
||||||
module \$sshl (A, B, Y);
|
|
||||||
|
|
||||||
parameter A_SIGNED = 0;
|
|
||||||
parameter B_SIGNED = 0;
|
|
||||||
parameter A_WIDTH = 1;
|
|
||||||
parameter B_WIDTH = 1;
|
|
||||||
parameter Y_WIDTH = 1;
|
|
||||||
|
|
||||||
localparam WIDTH = Y_WIDTH;
|
|
||||||
localparam BB_WIDTH = $clog2(WIDTH) + 2 < B_WIDTH ? $clog2(WIDTH) + 2 : B_WIDTH;
|
|
||||||
|
|
||||||
input [A_WIDTH-1:0] A;
|
|
||||||
input [B_WIDTH-1:0] B;
|
|
||||||
output [Y_WIDTH-1:0] Y;
|
|
||||||
|
|
||||||
genvar i;
|
|
||||||
generate
|
|
||||||
wire [WIDTH*(BB_WIDTH+1)-1:0] chain;
|
|
||||||
\$bu0 #(
|
|
||||||
.A_SIGNED(A_SIGNED),
|
|
||||||
.A_WIDTH(A_WIDTH),
|
|
||||||
.Y_WIDTH(WIDTH)
|
|
||||||
) expand (
|
|
||||||
.A(A),
|
|
||||||
.Y(chain[WIDTH-1:0])
|
|
||||||
);
|
|
||||||
assign Y = chain[WIDTH*(BB_WIDTH+1)-1 : WIDTH*BB_WIDTH];
|
|
||||||
for (i = 0; i < BB_WIDTH; i = i + 1) begin:V
|
|
||||||
wire [WIDTH-1:0] unshifted, shifted, result;
|
|
||||||
assign unshifted = chain[WIDTH*i + WIDTH-1 : WIDTH*i];
|
|
||||||
assign chain[WIDTH*(i+1) + WIDTH-1 : WIDTH*(i+1)] = result;
|
|
||||||
wire BBIT;
|
|
||||||
if (i == BB_WIDTH-1 && BB_WIDTH < B_WIDTH)
|
|
||||||
assign BBIT = |B[B_WIDTH-1:BB_WIDTH-1];
|
|
||||||
else
|
|
||||||
assign BBIT = B[i];
|
|
||||||
\$__shift #(
|
|
||||||
.WIDTH(WIDTH),
|
|
||||||
.SHIFT(0 - (2 ** (i > 30 ? 30 : i)))
|
|
||||||
) sh (
|
|
||||||
.XL(1'b0),
|
|
||||||
.XR(1'b0),
|
|
||||||
.A(unshifted),
|
|
||||||
.Y(shifted)
|
|
||||||
);
|
|
||||||
\$mux #(
|
|
||||||
.WIDTH(WIDTH)
|
|
||||||
) mux (
|
|
||||||
.A(unshifted),
|
|
||||||
.B(shifted),
|
|
||||||
.Y(result),
|
|
||||||
.S(BBIT)
|
|
||||||
);
|
|
||||||
end
|
|
||||||
endgenerate
|
|
||||||
|
|
||||||
endmodule
|
|
||||||
|
|
||||||
// --------------------------------------------------------
|
|
||||||
|
|
||||||
module \$sshr (A, B, Y);
|
|
||||||
|
|
||||||
parameter A_SIGNED = 0;
|
|
||||||
parameter B_SIGNED = 0;
|
|
||||||
parameter A_WIDTH = 1;
|
|
||||||
parameter B_WIDTH = 1;
|
|
||||||
parameter Y_WIDTH = 1;
|
|
||||||
|
|
||||||
localparam WIDTH = A_WIDTH > Y_WIDTH ? A_WIDTH : Y_WIDTH;
|
|
||||||
localparam BB_WIDTH = $clog2(WIDTH) + 2 < B_WIDTH ? $clog2(WIDTH) + 2 : B_WIDTH;
|
|
||||||
|
|
||||||
input [A_WIDTH-1:0] A;
|
|
||||||
input [B_WIDTH-1:0] B;
|
|
||||||
output [Y_WIDTH-1:0] Y;
|
|
||||||
|
|
||||||
genvar i;
|
|
||||||
generate
|
|
||||||
wire [WIDTH*(BB_WIDTH+1)-1:0] chain;
|
|
||||||
\$bu0 #(
|
|
||||||
.A_SIGNED(A_SIGNED),
|
|
||||||
.A_WIDTH(A_WIDTH),
|
|
||||||
.Y_WIDTH(WIDTH)
|
|
||||||
) expand (
|
|
||||||
.A(A),
|
|
||||||
.Y(chain[WIDTH-1:0])
|
|
||||||
);
|
|
||||||
for (i = 0; i < Y_WIDTH; i = i + 1) begin:Y
|
|
||||||
if (i < WIDTH) begin
|
|
||||||
assign Y[i] = chain[WIDTH*BB_WIDTH + i];
|
|
||||||
end else
|
end else
|
||||||
if (A_SIGNED) begin
|
overflow = |B[B_WIDTH-1:BB_WIDTH];
|
||||||
assign Y[i] = chain[WIDTH*BB_WIDTH + WIDTH-1];
|
if (overflow)
|
||||||
end else begin
|
buffer = {WIDTH{extbit}};
|
||||||
assign Y[i] = 0;
|
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
|
end
|
||||||
for (i = 0; i < BB_WIDTH; i = i + 1) begin:V
|
|
||||||
wire [WIDTH-1:0] unshifted, shifted, result;
|
|
||||||
assign unshifted = chain[WIDTH*i + WIDTH-1 : WIDTH*i];
|
|
||||||
assign chain[WIDTH*(i+1) + WIDTH-1 : WIDTH*(i+1)] = result;
|
|
||||||
wire BBIT;
|
|
||||||
if (i == BB_WIDTH-1 && BB_WIDTH < B_WIDTH)
|
|
||||||
assign BBIT = |B[B_WIDTH-1:BB_WIDTH-1];
|
|
||||||
else
|
|
||||||
assign BBIT = B[i];
|
|
||||||
\$__shift #(
|
|
||||||
.WIDTH(WIDTH),
|
|
||||||
.SHIFT(2 ** (i > 30 ? 30 : i))
|
|
||||||
) sh (
|
|
||||||
.XL(A_SIGNED && A[A_WIDTH-1]),
|
|
||||||
.XR(1'b0),
|
|
||||||
.A(unshifted),
|
|
||||||
.Y(shifted)
|
|
||||||
);
|
|
||||||
\$mux #(
|
|
||||||
.WIDTH(WIDTH)
|
|
||||||
) mux (
|
|
||||||
.A(unshifted),
|
|
||||||
.B(shifted),
|
|
||||||
.Y(result),
|
|
||||||
.S(BBIT)
|
|
||||||
);
|
|
||||||
end
|
|
||||||
endgenerate
|
|
||||||
|
|
||||||
endmodule
|
assign Y = buffer;
|
||||||
|
|
||||||
// --------------------------------------------------------
|
|
||||||
|
|
||||||
module \$shift (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;
|
|
||||||
|
|
||||||
generate
|
|
||||||
if (B_SIGNED) begin:BLOCK1
|
|
||||||
assign Y = $signed(B) < 0 ? A << -B : A >> B;
|
|
||||||
end else begin:BLOCK2
|
|
||||||
assign Y = A >> B;
|
|
||||||
end
|
|
||||||
endgenerate
|
|
||||||
|
|
||||||
endmodule
|
|
||||||
|
|
||||||
// --------------------------------------------------------
|
|
||||||
|
|
||||||
module \$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;
|
|
||||||
|
|
||||||
\$shift #(
|
|
||||||
.A_SIGNED(A_SIGNED),
|
|
||||||
.B_SIGNED(B_SIGNED),
|
|
||||||
.A_WIDTH(A_WIDTH),
|
|
||||||
.B_WIDTH(B_WIDTH),
|
|
||||||
.Y_WIDTH(Y_WIDTH),
|
|
||||||
) sh (
|
|
||||||
.A(A),
|
|
||||||
.B(B),
|
|
||||||
.Y(Y)
|
|
||||||
);
|
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue