Merge pull request #2529 from zachjs/unnamed-genblk
[yosys.git] / techlibs / xilinx / arith_map.v
1 /*
2 * yosys -- Yosys Open SYnthesis Suite
3 *
4 * Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
5 *
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 *
18 */
19
20 // ============================================================================
21 // LCU
22
23 (* techmap_celltype = "$lcu" *)
24 module _80_xilinx_lcu (P, G, CI, CO);
25 parameter WIDTH = 2;
26
27 (* force_downto *)
28 input [WIDTH-1:0] P, G;
29 input CI;
30
31 (* force_downto *)
32 output [WIDTH-1:0] CO;
33
34 wire _TECHMAP_FAIL_ = WIDTH <= 2;
35
36 genvar i;
37
38 generate if (`LUT_SIZE == 4) begin
39
40 (* force_downto *)
41 wire [WIDTH-1:0] C = {CO, CI};
42 (* force_downto *)
43 wire [WIDTH-1:0] S = P & ~G;
44
45 generate for (i = 0; i < WIDTH; i = i + 1) begin:slice
46 MUXCY muxcy (
47 .CI(C[i]),
48 .DI(G[i]),
49 .S(S[i]),
50 .O(CO[i])
51 );
52 end endgenerate
53
54 end else begin
55
56 localparam CARRY4_COUNT = (WIDTH + 3) / 4;
57 localparam MAX_WIDTH = CARRY4_COUNT * 4;
58 localparam PAD_WIDTH = MAX_WIDTH - WIDTH;
59
60 (* force_downto *)
61 wire [MAX_WIDTH-1:0] S = {{PAD_WIDTH{1'b0}}, P & ~G};
62 (* force_downto *)
63 wire [MAX_WIDTH-1:0] GG = {{PAD_WIDTH{1'b0}}, G};
64 (* force_downto *)
65 wire [MAX_WIDTH-1:0] C;
66 assign CO = C;
67
68 generate for (i = 0; i < CARRY4_COUNT; i = i + 1) begin:slice
69 if (i == 0) begin
70 CARRY4 carry4
71 (
72 .CYINIT(CI),
73 .CI (1'd0),
74 .DI (GG[i*4 +: 4]),
75 .S (S [i*4 +: 4]),
76 .CO (C [i*4 +: 4]),
77 );
78 end else begin
79 CARRY4 carry4
80 (
81 .CYINIT(1'd0),
82 .CI (C [i*4 - 1]),
83 .DI (GG[i*4 +: 4]),
84 .S (S [i*4 +: 4]),
85 .CO (C [i*4 +: 4]),
86 );
87 end
88 end endgenerate
89 end endgenerate
90
91 endmodule
92
93
94 // ============================================================================
95 // ALU
96
97 (* techmap_celltype = "$alu" *)
98 module _80_xilinx_alu (A, B, CI, BI, X, Y, CO);
99 parameter A_SIGNED = 0;
100 parameter B_SIGNED = 0;
101 parameter A_WIDTH = 1;
102 parameter B_WIDTH = 1;
103 parameter Y_WIDTH = 1;
104 parameter _TECHMAP_CONSTVAL_CI_ = 0;
105 parameter _TECHMAP_CONSTMSK_CI_ = 0;
106
107 (* force_downto *)
108 input [A_WIDTH-1:0] A;
109 (* force_downto *)
110 input [B_WIDTH-1:0] B;
111 (* force_downto *)
112 output [Y_WIDTH-1:0] X, Y;
113
114 input CI, BI;
115 (* force_downto *)
116 output [Y_WIDTH-1:0] CO;
117
118 wire _TECHMAP_FAIL_ = Y_WIDTH <= 2;
119
120 (* force_downto *)
121 wire [Y_WIDTH-1:0] A_buf, B_buf;
122 \$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf));
123 \$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf));
124
125 (* force_downto *)
126 wire [Y_WIDTH-1:0] AA = A_buf;
127 (* force_downto *)
128 wire [Y_WIDTH-1:0] BB = BI ? ~B_buf : B_buf;
129
130 genvar i;
131
132 generate if (`LUT_SIZE == 4) begin
133
134 (* force_downto *)
135 wire [Y_WIDTH-1:0] C = {CO, CI};
136 (* force_downto *)
137 wire [Y_WIDTH-1:0] S = {AA ^ BB};
138
139 genvar i;
140 generate for (i = 0; i < Y_WIDTH; i = i + 1) begin:slice
141 MUXCY muxcy (
142 .CI(C[i]),
143 .DI(AA[i]),
144 .S(S[i]),
145 .O(CO[i])
146 );
147 XORCY xorcy (
148 .CI(C[i]),
149 .LI(S[i]),
150 .O(Y[i])
151 );
152 end endgenerate
153
154 assign X = S;
155
156 end else begin
157
158 localparam CARRY4_COUNT = (Y_WIDTH + 3) / 4;
159 localparam MAX_WIDTH = CARRY4_COUNT * 4;
160 localparam PAD_WIDTH = MAX_WIDTH - Y_WIDTH;
161
162 (* force_downto *)
163 wire [MAX_WIDTH-1:0] S = {{PAD_WIDTH{1'b0}}, AA ^ BB};
164 (* force_downto *)
165 wire [MAX_WIDTH-1:0] DI = {{PAD_WIDTH{1'b0}}, AA};
166
167 (* force_downto *)
168 wire [MAX_WIDTH-1:0] O;
169 (* force_downto *)
170 wire [MAX_WIDTH-1:0] C;
171 assign Y = O, CO = C;
172
173 genvar i;
174 generate for (i = 0; i < CARRY4_COUNT; i = i + 1) begin:slice
175 if (i == 0) begin
176 CARRY4 carry4
177 (
178 .CYINIT(CI),
179 .CI (1'd0),
180 .DI (DI[i*4 +: 4]),
181 .S (S [i*4 +: 4]),
182 .O (O [i*4 +: 4]),
183 .CO (C [i*4 +: 4])
184 );
185 end else begin
186 CARRY4 carry4
187 (
188 .CYINIT(1'd0),
189 .CI (C [i*4 - 1]),
190 .DI (DI[i*4 +: 4]),
191 .S (S [i*4 +: 4]),
192 .O (O [i*4 +: 4]),
193 .CO (C [i*4 +: 4])
194 );
195 end
196 end endgenerate
197
198 assign X = S;
199
200 end endgenerate
201 endmodule
202