summaryrefslogtreecommitdiff
path: root/techlibs/common/stdcells.v
diff options
context:
space:
mode:
authorClifford Wolf <clifford@clifford.at>2014-07-30 15:59:05 +0200
committerClifford Wolf <clifford@clifford.at>2014-07-30 18:49:12 +0200
commit6c05badc43f7c1691932d1c38869492311f9bd44 (patch)
tree94654bd2c09a31c385ea7c0e109a89942633abb1 /techlibs/common/stdcells.v
parent3f0a5746ef0940accb5fd14d97804c75c0531c0b (diff)
New techmap default rules for $shr $sshr $shl $sshl
Diffstat (limited to 'techlibs/common/stdcells.v')
-rw-r--r--techlibs/common/stdcells.v344
1 files changed, 62 insertions, 282 deletions
diff --git a/techlibs/common/stdcells.v b/techlibs/common/stdcells.v
index ee59048c..a2fce131 100644
--- a/techlibs/common/stdcells.v
+++ b/techlibs/common/stdcells.v
@@ -30,6 +30,9 @@
*
*/
+`define MIN(_a, _b) ((_a) < (_b) ? (_a) : (_b))
+`define MAX(_a, _b) ((_a) > (_b) ? (_a) : (_b))
+
// --------------------------------------------------------
(* techmap_simplemap *)
@@ -65,7 +68,7 @@ output [Y_WIDTH-1:0] Y;
.A_WIDTH(1),
.B_WIDTH(A_WIDTH),
.Y_WIDTH(Y_WIDTH)
-) sub (
+) _TECHMAP_REPLACE_ (
.A(1'b0),
.B(A),
.Y(Y)
@@ -129,34 +132,8 @@ endmodule
// --------------------------------------------------------
-module \$__shift (XL, XR, A, Y);
-
-parameter WIDTH = 1;
-parameter SHIFT = 0;
-
-input XL, XR;
-input [WIDTH-1:0] A;
-output [WIDTH-1:0] Y;
-
-genvar i;
-generate
- for (i = 0; i < WIDTH; i = i + 1) begin:V
- if (i+SHIFT < 0) begin
- assign Y[i] = XR;
- end else
- if (i+SHIFT < WIDTH) begin
- assign Y[i] = A[i+SHIFT];
- end else begin
- assign Y[i] = XL;
- end
- end
-endgenerate
-
-endmodule
-
-// --------------------------------------------------------
-
-module \$shl (A, B, Y);
+(* techmap_celltype = "$shr $shl $sshl $sshr" *)
+module shift_ops_shr_shl_sshl_sshr (A, B, Y);
parameter A_SIGNED = 0;
parameter B_SIGNED = 0;
@@ -164,119 +141,46 @@ parameter A_WIDTH = 1;
parameter B_WIDTH = 1;
parameter Y_WIDTH = 1;
-parameter WIDTH = Y_WIDTH;
-localparam BB_WIDTH = $clog2(WIDTH) + 2 < B_WIDTH ? $clog2(WIDTH) + 2 : B_WIDTH;
+parameter _TECHMAP_CELLTYPE_ = "";
+localparam shift_left = _TECHMAP_CELLTYPE_ == "$shl" || _TECHMAP_CELLTYPE_ == "$sshl";
+localparam sign_extend = A_SIGNED && _TECHMAP_CELLTYPE_ == "$sshr";
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
-
-// --------------------------------------------------------
+localparam WIDTH = `MAX(A_WIDTH, Y_WIDTH);
+localparam BB_WIDTH = `MIN($clog2(shift_left ? Y_WIDTH : A_SIGNED ? WIDTH : A_WIDTH) + 1, B_WIDTH);
-module \$shr (A, B, Y);
+wire [1023:0] _TECHMAP_DO_ = "proc; opt_muxtree; opt_const -mux_undef -mux_bool -fine;;;";
-parameter A_SIGNED = 0;
-parameter B_SIGNED = 0;
-parameter A_WIDTH = 1;
-parameter B_WIDTH = 1;
-parameter Y_WIDTH = 1;
+integer i;
+reg [WIDTH-1:0] buffer;
+reg overflow;
-localparam WIDTH = A_WIDTH > Y_WIDTH ? A_WIDTH : Y_WIDTH;
-localparam BB_WIDTH = $clog2(WIDTH) + 2 < B_WIDTH ? $clog2(WIDTH) + 2 : B_WIDTH;
+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};
-input [A_WIDTH-1:0] A;
-input [B_WIDTH-1:0] B;
-output [Y_WIDTH-1:0] Y;
+ 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
-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
+assign Y = buffer;
endmodule
// --------------------------------------------------------
-module \$sshl (A, B, Y);
+(* techmap_celltype = "$shift $shiftx" *)
+module shift_shiftx (A, B, Y);
parameter A_SIGNED = 0;
parameter B_SIGNED = 0;
@@ -284,174 +188,50 @@ 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
+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);
-// --------------------------------------------------------
-
-module \$sshr (A, B, Y);
+parameter _TECHMAP_CELLTYPE_ = "";
+localparam extbit = _TECHMAP_CELLTYPE_ == "$shift" ? 1'b0 : 1'bx;
-parameter A_SIGNED = 0;
-parameter B_SIGNED = 0;
-parameter A_WIDTH = 1;
-parameter B_WIDTH = 1;
-parameter Y_WIDTH = 1;
+wire [1023:0] _TECHMAP_DO_ = "proc; opt_muxtree; opt_const -mux_undef -mux_bool -fine;;;";
-localparam WIDTH = A_WIDTH > Y_WIDTH ? A_WIDTH : Y_WIDTH;
-localparam BB_WIDTH = $clog2(WIDTH) + 2 < B_WIDTH ? $clog2(WIDTH) + 2 : B_WIDTH;
+integer i;
+reg [WIDTH-1:0] buffer;
+reg overflow;
-input [A_WIDTH-1:0] A;
-input [B_WIDTH-1:0] B;
-output [Y_WIDTH-1:0] Y;
+always @* begin
+ overflow = 0;
+ buffer = {WIDTH{extbit}};
+ buffer[`MAX(A_WIDTH, Y_WIDTH)-1:0] = A;
-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];
+ 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
- if (A_SIGNED) begin
- assign Y[i] = chain[WIDTH*BB_WIDTH + WIDTH-1];
- end else begin
- assign Y[i] = 0;
- 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
-
-// --------------------------------------------------------
-
-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;
+ overflow = |B[B_WIDTH-1:BB_WIDTH];
+ if (overflow)
+ buffer = {WIDTH{extbit}};
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;
+ 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
-\$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)
-);
+assign Y = buffer;
endmodule