2e9be437ce16c7f504c8cc8c9dbb7985e4115a21
2 * yosys -- Yosys Open SYnthesis Suite
4 * Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
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.
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.
20 #include "kernel/rtlil.h"
21 #include "libs/bigint/BigIntegerLibrary.hh"
24 static BigInteger
const2big(const RTLIL::Const
&val
, bool as_signed
, int &undef_bit_pos
)
26 BigInteger result
= 0, this_bit
= 1;
27 for (size_t i
= 0; i
< val
.bits
.size(); i
++) {
28 if (val
.bits
[i
] == RTLIL::State::S1
) {
29 if (as_signed
&& i
+1 == val
.bits
.size())
34 else if (val
.bits
[i
] != RTLIL::State::S0
) {
35 if (undef_bit_pos
< 0)
43 static RTLIL::Const
big2const(const BigInteger
&val
, int result_len
, int undef_bit_pos
)
45 BigUnsigned mag
= val
.getMagnitude();
46 RTLIL::Const
result(0, result_len
);
50 if (val
.getSign() < 0)
53 for (int i
= 0; i
< result_len
; i
++)
54 result
.bits
[i
] = mag
.getBit(i
) ? RTLIL::State::S0
: RTLIL::State::S1
;
58 for (int i
= 0; i
< result_len
; i
++)
59 result
.bits
[i
] = mag
.getBit(i
) ? RTLIL::State::S1
: RTLIL::State::S0
;
63 if (undef_bit_pos
>= 0)
64 for (int i
= undef_bit_pos
; i
< result_len
; i
++)
65 result
.bits
[i
] = RTLIL::State::Sx
;
70 static RTLIL::State
logic_and(RTLIL::State a
, RTLIL::State b
)
72 if (a
== RTLIL::State::S0
) return RTLIL::State::S0
;
73 if (b
== RTLIL::State::S0
) return RTLIL::State::S0
;
74 if (a
!= RTLIL::State::S1
) return RTLIL::State::Sx
;
75 if (b
!= RTLIL::State::S1
) return RTLIL::State::Sx
;
76 return RTLIL::State::S1
;
79 static RTLIL::State
logic_or(RTLIL::State a
, RTLIL::State b
)
81 if (a
== RTLIL::State::S1
) return RTLIL::State::S1
;
82 if (b
== RTLIL::State::S1
) return RTLIL::State::S1
;
83 if (a
!= RTLIL::State::S0
) return RTLIL::State::Sx
;
84 if (b
!= RTLIL::State::S0
) return RTLIL::State::Sx
;
85 return RTLIL::State::S0
;
88 static RTLIL::State
logic_xor(RTLIL::State a
, RTLIL::State b
)
90 if (a
!= RTLIL::State::S0
&& a
!= RTLIL::State::S1
) return RTLIL::State::Sx
;
91 if (b
!= RTLIL::State::S0
&& b
!= RTLIL::State::S1
) return RTLIL::State::Sx
;
92 return a
!= b
? RTLIL::State::S1
: RTLIL::State::S0
;
95 static RTLIL::State
logic_xnor(RTLIL::State a
, RTLIL::State b
)
97 if (a
!= RTLIL::State::S0
&& a
!= RTLIL::State::S1
) return RTLIL::State::Sx
;
98 if (b
!= RTLIL::State::S0
&& b
!= RTLIL::State::S1
) return RTLIL::State::Sx
;
99 return a
== b
? RTLIL::State::S1
: RTLIL::State::S0
;
102 RTLIL::Const
RTLIL::const_not(const RTLIL::Const
&arg1
, const RTLIL::Const
&, bool signed1
, bool, int result_len
)
105 result_len
= arg1
.bits
.size();
107 RTLIL::Const arg1_ext
= arg1
;
108 while (int(arg1_ext
.bits
.size()) < result_len
)
109 arg1_ext
.bits
.push_back(signed1
&& arg1_ext
.bits
.size() ? arg1_ext
.bits
.back() : RTLIL::State::S0
);
111 RTLIL::Const
result(RTLIL::State::Sx
, result_len
);
112 for (size_t i
= 0; i
< size_t(result_len
); i
++) {
113 if (i
>= arg1_ext
.bits
.size())
114 result
.bits
[i
] = RTLIL::State::S0
;
115 else if (arg1_ext
.bits
[i
] == RTLIL::State::S0
)
116 result
.bits
[i
] = RTLIL::State::S1
;
117 else if (arg1_ext
.bits
[i
] == RTLIL::State::S1
)
118 result
.bits
[i
] = RTLIL::State::S0
;
124 static RTLIL::Const
logic_wrapper(RTLIL::State(*logic_func
)(RTLIL::State
, RTLIL::State
),
125 RTLIL::Const arg1
, RTLIL::Const arg2
, bool signed1
, bool signed2
, int result_len
= -1)
128 result_len
= std::max(arg1
.bits
.size(), arg2
.bits
.size());
130 while (int(arg1
.bits
.size()) < result_len
)
131 arg1
.bits
.push_back(signed1
&& arg1
.bits
.size() ? arg1
.bits
.back() : RTLIL::State::S0
);
133 while (int(arg2
.bits
.size()) < result_len
)
134 arg2
.bits
.push_back(signed2
&& arg2
.bits
.size() ? arg2
.bits
.back() : RTLIL::State::S0
);
136 RTLIL::Const
result(RTLIL::State::Sx
, result_len
);
137 for (size_t i
= 0; i
< size_t(result_len
); i
++) {
138 RTLIL::State a
= i
< arg1
.bits
.size() ? arg1
.bits
[i
] : RTLIL::State::S0
;
139 RTLIL::State b
= i
< arg2
.bits
.size() ? arg2
.bits
[i
] : RTLIL::State::S0
;
140 result
.bits
[i
] = logic_func(a
, b
);
146 RTLIL::Const
RTLIL::const_and(const RTLIL::Const
&arg1
, const RTLIL::Const
&arg2
, bool signed1
, bool signed2
, int result_len
)
148 return logic_wrapper(logic_and
, arg1
, arg2
, signed1
, signed2
, result_len
);
151 RTLIL::Const
RTLIL::const_or(const RTLIL::Const
&arg1
, const RTLIL::Const
&arg2
, bool signed1
, bool signed2
, int result_len
)
153 return logic_wrapper(logic_or
, arg1
, arg2
, signed1
, signed2
, result_len
);
156 RTLIL::Const
RTLIL::const_xor(const RTLIL::Const
&arg1
, const RTLIL::Const
&arg2
, bool signed1
, bool signed2
, int result_len
)
158 return logic_wrapper(logic_xor
, arg1
, arg2
, signed1
, signed2
, result_len
);
161 RTLIL::Const
RTLIL::const_xnor(const RTLIL::Const
&arg1
, const RTLIL::Const
&arg2
, bool signed1
, bool signed2
, int result_len
)
163 return logic_wrapper(logic_xnor
, arg1
, arg2
, signed1
, signed2
, result_len
);
166 static RTLIL::Const
logic_reduce_wrapper(RTLIL::State initial
, RTLIL::State(*logic_func
)(RTLIL::State
, RTLIL::State
), const RTLIL::Const
&arg1
)
168 RTLIL::State temp
= initial
;
170 for (size_t i
= 0; i
< arg1
.bits
.size(); i
++)
171 temp
= logic_func(temp
, arg1
.bits
[i
]);
173 return RTLIL::Const(temp
);
176 RTLIL::Const
RTLIL::const_reduce_and(const RTLIL::Const
&arg1
, const RTLIL::Const
&, bool, bool, int)
178 return logic_reduce_wrapper(RTLIL::State::S1
, logic_and
, arg1
);
181 RTLIL::Const
RTLIL::const_reduce_or(const RTLIL::Const
&arg1
, const RTLIL::Const
&, bool, bool, int)
183 return logic_reduce_wrapper(RTLIL::State::S0
, logic_or
, arg1
);
186 RTLIL::Const
RTLIL::const_reduce_xor(const RTLIL::Const
&arg1
, const RTLIL::Const
&, bool, bool, int)
188 return logic_reduce_wrapper(RTLIL::State::S0
, logic_xor
, arg1
);
191 RTLIL::Const
RTLIL::const_reduce_xnor(const RTLIL::Const
&arg1
, const RTLIL::Const
&, bool, bool, int)
193 RTLIL::Const not_y
= logic_reduce_wrapper(RTLIL::State::S0
, logic_xor
, arg1
);
194 if (not_y
.bits
.front() == RTLIL::State::S0
) return RTLIL::State::S1
;
195 if (not_y
.bits
.front() == RTLIL::State::S1
) return RTLIL::State::S0
;
196 return RTLIL::State::Sx
;
199 RTLIL::Const
RTLIL::const_reduce_bool(const RTLIL::Const
&arg1
, const RTLIL::Const
&, bool, bool, int)
201 return logic_reduce_wrapper(RTLIL::State::S0
, logic_or
, arg1
);
204 RTLIL::Const
RTLIL::const_logic_not(const RTLIL::Const
&arg1
, const RTLIL::Const
&, bool signed1
, bool, int)
206 int undef_bit_pos_a
= -1;
207 BigInteger a
= const2big(arg1
, signed1
, undef_bit_pos_a
);
210 if (undef_bit_pos_a
>= 0)
211 return RTLIL::Const(RTLIL::State::Sx
);
212 return RTLIL::Const(RTLIL::State::S1
);
215 return RTLIL::Const(RTLIL::State::S0
);
218 RTLIL::Const
RTLIL::const_logic_and(const RTLIL::Const
&arg1
, const RTLIL::Const
&arg2
, bool signed1
, bool signed2
, int)
220 int undef_bit_pos_a
= -1, undef_bit_pos_b
= -1;
221 BigInteger a
= const2big(arg1
, signed1
, undef_bit_pos_a
);
222 BigInteger b
= const2big(arg2
, signed2
, undef_bit_pos_b
);
224 if (a
.isZero() || b
.isZero()) {
225 if (undef_bit_pos_a
>= 0 && undef_bit_pos_b
>= 0)
226 return RTLIL::Const(RTLIL::State::Sx
);
227 return RTLIL::Const(RTLIL::State::S0
);
230 return RTLIL::Const(RTLIL::State::S1
);
233 RTLIL::Const
RTLIL::const_logic_or(const RTLIL::Const
&arg1
, const RTLIL::Const
&arg2
, bool signed1
, bool signed2
, int)
235 int undef_bit_pos_a
= -1, undef_bit_pos_b
= -1;
236 BigInteger a
= const2big(arg1
, signed1
, undef_bit_pos_a
);
237 BigInteger b
= const2big(arg2
, signed2
, undef_bit_pos_b
);
239 if (a
.isZero() && b
.isZero()) {
240 if (undef_bit_pos_a
>= 0 || undef_bit_pos_b
>= 0)
241 return RTLIL::Const(RTLIL::State::Sx
);
242 return RTLIL::Const(RTLIL::State::S0
);
245 return RTLIL::Const(RTLIL::State::S1
);
248 static RTLIL::Const
const_shift(const RTLIL::Const
&arg1
, const RTLIL::Const
&arg2
, bool sign_ext
, int direction
, int result_len
)
250 int undef_bit_pos
= -1;
251 BigInteger offset
= const2big(arg2
, false, undef_bit_pos
) * direction
;
254 result_len
= arg1
.bits
.size();
256 RTLIL::Const
result(RTLIL::State::Sx
, result_len
);
257 if (undef_bit_pos
>= 0)
260 for (int i
= 0; i
< result_len
; i
++) {
261 BigInteger pos
= BigInteger(i
) + offset
;
263 result
.bits
[i
] = RTLIL::State::S0
;
264 else if (pos
>= arg1
.bits
.size())
265 result
.bits
[i
] = sign_ext
? arg1
.bits
.back() : RTLIL::State::S0
;
267 result
.bits
[i
] = arg1
.bits
[pos
.toInt()];
273 RTLIL::Const
RTLIL::const_shl(const RTLIL::Const
&arg1
, const RTLIL::Const
&arg2
, bool signed1
, bool, int result_len
)
275 RTLIL::Const arg1_ext
= arg1
;
276 while (int(arg1_ext
.bits
.size()) < result_len
)
277 arg1_ext
.bits
.push_back(signed1
&& arg1_ext
.bits
.size() ? arg1_ext
.bits
.back() : RTLIL::State::S0
);
278 return const_shift(arg1_ext
, arg2
, false, -1, result_len
);
281 RTLIL::Const
RTLIL::const_shr(const RTLIL::Const
&arg1
, const RTLIL::Const
&arg2
, bool signed1
, bool, int result_len
)
283 RTLIL::Const arg1_ext
= arg1
;
284 while (int(arg1_ext
.bits
.size()) < result_len
)
285 arg1_ext
.bits
.push_back(signed1
&& arg1_ext
.bits
.size() ? arg1_ext
.bits
.back() : RTLIL::State::S0
);
286 return const_shift(arg1_ext
, arg2
, false, +1, result_len
);
289 RTLIL::Const
RTLIL::const_sshl(const RTLIL::Const
&arg1
, const RTLIL::Const
&arg2
, bool, bool, int result_len
)
291 return const_shift(arg1
, arg2
, true, -1, result_len
);
294 RTLIL::Const
RTLIL::const_sshr(const RTLIL::Const
&arg1
, const RTLIL::Const
&arg2
, bool, bool, int result_len
)
296 return const_shift(arg1
, arg2
, true, +1, result_len
);
299 RTLIL::Const
RTLIL::const_lt(const RTLIL::Const
&arg1
, const RTLIL::Const
&arg2
, bool signed1
, bool signed2
, int)
301 int undef_bit_pos
= -1;
302 bool y
= const2big(arg1
, signed1
, undef_bit_pos
) < const2big(arg2
, signed2
, undef_bit_pos
);
303 return RTLIL::Const(undef_bit_pos
>= 0 ? RTLIL::State::Sx
: y
? RTLIL::State::S1
: RTLIL::State::S0
);
306 RTLIL::Const
RTLIL::const_le(const RTLIL::Const
&arg1
, const RTLIL::Const
&arg2
, bool signed1
, bool signed2
, int)
308 int undef_bit_pos
= -1;
309 bool y
= const2big(arg1
, signed1
, undef_bit_pos
) <= const2big(arg2
, signed2
, undef_bit_pos
);
310 return RTLIL::Const(undef_bit_pos
>= 0 ? RTLIL::State::Sx
: y
? RTLIL::State::S1
: RTLIL::State::S0
);
313 RTLIL::Const
RTLIL::const_eq(const RTLIL::Const
&arg1
, const RTLIL::Const
&arg2
, bool signed1
, bool signed2
, int)
315 int undef_bit_pos
= -1;
316 bool y
= const2big(arg1
, signed1
, undef_bit_pos
) == const2big(arg2
, signed2
, undef_bit_pos
);
317 return RTLIL::Const(undef_bit_pos
>= 0 ? RTLIL::State::Sx
: y
? RTLIL::State::S1
: RTLIL::State::S0
);
320 RTLIL::Const
RTLIL::const_ne(const RTLIL::Const
&arg1
, const RTLIL::Const
&arg2
, bool signed1
, bool signed2
, int)
322 int undef_bit_pos
= -1;
323 bool y
= const2big(arg1
, signed1
, undef_bit_pos
) != const2big(arg2
, signed2
, undef_bit_pos
);
324 return RTLIL::Const(undef_bit_pos
>= 0 ? RTLIL::State::Sx
: y
? RTLIL::State::S1
: RTLIL::State::S0
);
327 RTLIL::Const
RTLIL::const_ge(const RTLIL::Const
&arg1
, const RTLIL::Const
&arg2
, bool signed1
, bool signed2
, int)
329 int undef_bit_pos
= -1;
330 bool y
= const2big(arg1
, signed1
, undef_bit_pos
) >= const2big(arg2
, signed2
, undef_bit_pos
);
331 return RTLIL::Const(undef_bit_pos
>= 0 ? RTLIL::State::Sx
: y
? RTLIL::State::S1
: RTLIL::State::S0
);
334 RTLIL::Const
RTLIL::const_gt(const RTLIL::Const
&arg1
, const RTLIL::Const
&arg2
, bool signed1
, bool signed2
, int)
336 int undef_bit_pos
= -1;
337 bool y
= const2big(arg1
, signed1
, undef_bit_pos
) > const2big(arg2
, signed2
, undef_bit_pos
);
338 return RTLIL::Const(undef_bit_pos
>= 0 ? RTLIL::State::Sx
: y
? RTLIL::State::S1
: RTLIL::State::S0
);
341 RTLIL::Const
RTLIL::const_add(const RTLIL::Const
&arg1
, const RTLIL::Const
&arg2
, bool signed1
, bool signed2
, int result_len
)
343 int undef_bit_pos
= -1;
344 BigInteger y
= const2big(arg1
, signed1
, undef_bit_pos
) + const2big(arg2
, signed2
, undef_bit_pos
);
345 return big2const(y
, result_len
>= 0 ? result_len
: std::max(arg1
.bits
.size(), arg2
.bits
.size()), undef_bit_pos
);
348 RTLIL::Const
RTLIL::const_sub(const RTLIL::Const
&arg1
, const RTLIL::Const
&arg2
, bool signed1
, bool signed2
, int result_len
)
350 int undef_bit_pos
= -1;
351 BigInteger y
= const2big(arg1
, signed1
, undef_bit_pos
) - const2big(arg2
, signed2
, undef_bit_pos
);
352 return big2const(y
, result_len
>= 0 ? result_len
: std::max(arg1
.bits
.size(), arg2
.bits
.size()), undef_bit_pos
);
355 RTLIL::Const
RTLIL::const_mul(const RTLIL::Const
&arg1
, const RTLIL::Const
&arg2
, bool signed1
, bool signed2
, int result_len
)
357 int undef_bit_pos
= -1;
358 BigInteger y
= const2big(arg1
, signed1
, undef_bit_pos
) * const2big(arg2
, signed2
, undef_bit_pos
);
359 return big2const(y
, result_len
>= 0 ? result_len
: std::max(arg1
.bits
.size(), arg2
.bits
.size()), std::min(undef_bit_pos
, 0));
362 RTLIL::Const
RTLIL::const_div(const RTLIL::Const
&arg1
, const RTLIL::Const
&arg2
, bool signed1
, bool signed2
, int result_len
)
364 int undef_bit_pos
= -1;
365 BigInteger a
= const2big(arg1
, signed1
, undef_bit_pos
);
366 BigInteger b
= const2big(arg2
, signed2
, undef_bit_pos
);
368 return RTLIL::Const(RTLIL::State::Sx
, result_len
);
369 bool result_neg
= (a
.getSign() == BigInteger::negative
) != (b
.getSign() == BigInteger::negative
);
370 a
= a
.getSign() == BigInteger::negative
? -a
: a
;
371 b
= b
.getSign() == BigInteger::negative
? -b
: b
;
372 return big2const(result_neg
? -(a
/ b
) : (a
/ b
), result_len
>= 0 ? result_len
: std::max(arg1
.bits
.size(), arg2
.bits
.size()), std::min(undef_bit_pos
, 0));
375 RTLIL::Const
RTLIL::const_mod(const RTLIL::Const
&arg1
, const RTLIL::Const
&arg2
, bool signed1
, bool signed2
, int result_len
)
377 int undef_bit_pos
= -1;
378 BigInteger a
= const2big(arg1
, signed1
, undef_bit_pos
);
379 BigInteger b
= const2big(arg2
, signed2
, undef_bit_pos
);
381 return RTLIL::Const(RTLIL::State::Sx
, result_len
);
382 bool result_neg
= a
.getSign() == BigInteger::negative
;
383 a
= a
.getSign() == BigInteger::negative
? -a
: a
;
384 b
= b
.getSign() == BigInteger::negative
? -b
: b
;
385 return big2const(result_neg
? -(a
% b
) : (a
% b
), result_len
>= 0 ? result_len
: std::max(arg1
.bits
.size(), arg2
.bits
.size()), std::min(undef_bit_pos
, 0));
388 RTLIL::Const
RTLIL::const_pow(const RTLIL::Const
&arg1
, const RTLIL::Const
&arg2
, bool signed1
, bool signed2
, int result_len
)
390 int undef_bit_pos
= -1;
392 BigInteger a
= const2big(arg1
, signed1
, undef_bit_pos
);
393 BigInteger b
= const2big(arg2
, signed2
, undef_bit_pos
);
396 if (b
< 0 || a
== 0) {
401 if (y
.getLength() > 0x10000) {
409 return big2const(y
, result_len
>= 0 ? result_len
: std::max(arg1
.bits
.size(), arg2
.bits
.size()), std::min(undef_bit_pos
, 0));
412 RTLIL::Const
RTLIL::const_pos(const RTLIL::Const
&arg1
, const RTLIL::Const
&, bool signed1
, bool, int result_len
)
414 RTLIL::Const arg1_ext
= arg1
;
415 while (int(arg1_ext
.bits
.size()) < result_len
)
416 arg1_ext
.bits
.push_back(signed1
&& arg1_ext
.bits
.size() ? arg1_ext
.bits
.back() : RTLIL::State::S0
);
418 RTLIL::Const
zero(RTLIL::State::S0
, 1);
419 return RTLIL::const_add(zero
, arg1_ext
, false, signed1
, result_len
);
422 RTLIL::Const
RTLIL::const_neg(const RTLIL::Const
&arg1
, const RTLIL::Const
&, bool signed1
, bool, int result_len
)
424 RTLIL::Const arg1_ext
= arg1
;
425 while (int(arg1_ext
.bits
.size()) < result_len
)
426 arg1_ext
.bits
.push_back(signed1
&& arg1_ext
.bits
.size() ? arg1_ext
.bits
.back() : RTLIL::State::S0
);
428 RTLIL::Const
zero(RTLIL::State::S0
, 1);
429 return RTLIL::const_sub(zero
, arg1_ext
, false, signed1
, result_len
);