Try new LUT delays
[yosys.git] / techlibs / common / cmp2lut.v
1 // Certain arithmetic operations between a signal of width n and a constant can be directly mapped
2 // to a single k-LUT (where n <= k). This is preferable to normal alumacc techmapping process
3 // because for many targets, arithmetic techmapping creates hard logic (such as carry cells) which often
4 // cannot be optimized further.
5 //
6 // TODO: Currently, only comparisons with 1-bit output are mapped. Potentially, all arithmetic cells
7 // with n <= k inputs should be techmapped in this way, because this shortens the critical path
8 // from n to 1 by avoiding carry chains.
9
10 (* techmap_celltype = "$eq $ne $lt $le $gt $ge" *)
11 module _90_lut_cmp_ (A, B, Y);
12
13 parameter A_SIGNED = 0;
14 parameter B_SIGNED = 0;
15 parameter A_WIDTH = 0;
16 parameter B_WIDTH = 0;
17 parameter Y_WIDTH = 0;
18
19 input [A_WIDTH-1:0] A;
20 input [B_WIDTH-1:0] B;
21 output [Y_WIDTH-1:0] Y;
22
23 parameter _TECHMAP_CELLTYPE_ = "";
24
25 parameter _TECHMAP_CONSTMSK_A_ = 0;
26 parameter _TECHMAP_CONSTVAL_A_ = 0;
27 parameter _TECHMAP_CONSTMSK_B_ = 0;
28 parameter _TECHMAP_CONSTVAL_B_ = 0;
29
30 function automatic integer gen_lut;
31 input integer width;
32 input integer operation;
33 input integer swap;
34 input integer sign;
35 input integer operand;
36 integer n, i_var, i_cst, lhs, rhs, o_bit;
37 begin
38 gen_lut = width'b0;
39 for (n = 0; n < (1 << width); n++) begin
40 if (sign)
41 i_var = n[width-1:0];
42 else
43 i_var = n;
44 i_cst = operand;
45 if (swap) begin
46 lhs = i_cst;
47 rhs = i_var;
48 end else begin
49 lhs = i_var;
50 rhs = i_cst;
51 end
52 if (operation == 0)
53 o_bit = (lhs < rhs);
54 if (operation == 1)
55 o_bit = (lhs <= rhs);
56 if (operation == 2)
57 o_bit = (lhs > rhs);
58 if (operation == 3)
59 o_bit = (lhs >= rhs);
60 if (operation == 4)
61 o_bit = (lhs == rhs);
62 if (operation == 5)
63 o_bit = (lhs != rhs);
64 gen_lut = gen_lut | (o_bit << n);
65 end
66 end
67 endfunction
68
69 generate
70 if (_TECHMAP_CELLTYPE_ == "$lt")
71 localparam operation = 0;
72 if (_TECHMAP_CELLTYPE_ == "$le")
73 localparam operation = 1;
74 if (_TECHMAP_CELLTYPE_ == "$gt")
75 localparam operation = 2;
76 if (_TECHMAP_CELLTYPE_ == "$ge")
77 localparam operation = 3;
78 if (_TECHMAP_CELLTYPE_ == "$eq")
79 localparam operation = 4;
80 if (_TECHMAP_CELLTYPE_ == "$ne")
81 localparam operation = 5;
82
83 if (A_WIDTH > `LUT_WIDTH || B_WIDTH > `LUT_WIDTH || Y_WIDTH != 1)
84 wire _TECHMAP_FAIL_ = 1;
85 else if (&_TECHMAP_CONSTMSK_B_)
86 \$lut #(
87 .WIDTH(A_WIDTH),
88 .LUT({ gen_lut(A_WIDTH, operation, 0, A_SIGNED && B_SIGNED, _TECHMAP_CONSTVAL_B_) })
89 ) _TECHMAP_REPLACE_ (
90 .A(A),
91 .Y(Y)
92 );
93 else if (&_TECHMAP_CONSTMSK_A_)
94 \$lut #(
95 .WIDTH(B_WIDTH),
96 .LUT({ gen_lut(B_WIDTH, operation, 1, A_SIGNED && B_SIGNED, _TECHMAP_CONSTVAL_A_) })
97 ) _TECHMAP_REPLACE_ (
98 .A(B),
99 .Y(Y)
100 );
101 else
102 wire _TECHMAP_FAIL_ = 1;
103 endgenerate
104
105 endmodule