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.
23 #include "kernel/log.h"
24 #include "kernel/rtlil.h"
32 std::vector
<RTLIL::State
> bitdata
;
33 mutable unsigned int cached_hash
;
34 bits_t(int width
= 0) : bitdata(width
), cached_hash(0) { }
35 RTLIL::State
&operator[](int index
) {
36 return bitdata
[index
];
38 const RTLIL::State
&operator[](int index
) const {
39 return bitdata
[index
];
41 bool operator==(const bits_t
&other
) const {
42 if (hash() != other
.hash())
44 return bitdata
== other
.bitdata
;
46 unsigned int hash() const {
48 cached_hash
= hash_ops
<std::vector
<RTLIL::State
>>::hash(bitdata
);
52 pool
<bits_t
> database
;
54 BitPatternPool(RTLIL::SigSpec sig
)
58 bits_t
pattern(width
);
59 for (int i
= 0; i
< width
; i
++) {
60 if (sig
[i
].wire
== NULL
&& sig
[i
].data
<= RTLIL::State::S1
)
61 pattern
[i
] = sig
[i
].data
;
63 pattern
[i
] = RTLIL::State::Sa
;
65 database
.insert(pattern
);
69 BitPatternPool(int width
)
73 bits_t
pattern(width
);
74 for (int i
= 0; i
< width
; i
++)
75 pattern
[i
] = RTLIL::State::Sa
;
76 database
.insert(pattern
);
80 bits_t
sig2bits(RTLIL::SigSpec sig
)
83 bits
.bitdata
= sig
.as_const().bits
;
84 for (auto &b
: bits
.bitdata
)
85 if (b
> RTLIL::State::S1
)
90 bool match(bits_t a
, bits_t b
)
92 log_assert(int(a
.bitdata
.size()) == width
);
93 log_assert(int(b
.bitdata
.size()) == width
);
94 for (int i
= 0; i
< width
; i
++)
95 if (a
[i
] <= RTLIL::State::S1
&& b
[i
] <= RTLIL::State::S1
&& a
[i
] != b
[i
])
100 bool has_any(RTLIL::SigSpec sig
)
102 bits_t bits
= sig2bits(sig
);
103 for (auto &it
: database
)
109 bool has_all(RTLIL::SigSpec sig
)
111 bits_t bits
= sig2bits(sig
);
112 for (auto &it
: database
)
113 if (match(it
, bits
)) {
114 for (int i
= 0; i
< width
; i
++)
115 if (bits
[i
] > RTLIL::State::S1
&& it
[i
] <= RTLIL::State::S1
)
116 goto next_database_entry
;
118 next_database_entry
:;
123 bool take(RTLIL::SigSpec sig
)
126 bits_t bits
= sig2bits(sig
);
127 for (auto it
= database
.begin(); it
!= database
.end();)
128 if (match(*it
, bits
)) {
129 for (int i
= 0; i
< width
; i
++) {
130 if ((*it
)[i
] != RTLIL::State::Sa
|| bits
[i
] == RTLIL::State::Sa
)
133 new_pattern
.bitdata
= it
->bitdata
;
134 new_pattern
[i
] = bits
[i
] == RTLIL::State::S1
? RTLIL::State::S0
: RTLIL::State::S1
;
135 database
.insert(new_pattern
);
137 it
= database
.erase(it
);
147 if (database
.empty())
155 return database
.empty();