Remove kernel/cost.cc since master has refactored it
[yosys.git] / kernel / sigtools.h
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 #ifndef SIGTOOLS_H
21 #define SIGTOOLS_H
22
23 #include "kernel/yosys.h"
24
25 YOSYS_NAMESPACE_BEGIN
26
27 struct SigPool
28 {
29 struct bitDef_t : public std::pair<RTLIL::Wire*, int> {
30 bitDef_t() : std::pair<RTLIL::Wire*, int>(NULL, 0) { }
31 bitDef_t(const RTLIL::SigBit &bit) : std::pair<RTLIL::Wire*, int>(bit.wire, bit.offset) { }
32 unsigned int hash() const { return first->name.hash() + second; }
33 };
34
35 pool<bitDef_t> bits;
36
37 void clear()
38 {
39 bits.clear();
40 }
41
42 void add(RTLIL::SigSpec sig)
43 {
44 for (auto &bit : sig)
45 if (bit.wire != NULL)
46 bits.insert(bit);
47 }
48
49 void add(const SigPool &other)
50 {
51 for (auto &bit : other.bits)
52 bits.insert(bit);
53 }
54
55 void del(RTLIL::SigSpec sig)
56 {
57 for (auto &bit : sig)
58 if (bit.wire != NULL)
59 bits.erase(bit);
60 }
61
62 void del(const SigPool &other)
63 {
64 for (auto &bit : other.bits)
65 bits.erase(bit);
66 }
67
68 void expand(RTLIL::SigSpec from, RTLIL::SigSpec to)
69 {
70 log_assert(GetSize(from) == GetSize(to));
71 for (int i = 0; i < GetSize(from); i++) {
72 bitDef_t bit_from(from[i]), bit_to(to[i]);
73 if (bit_from.first != NULL && bit_to.first != NULL && bits.count(bit_from) > 0)
74 bits.insert(bit_to);
75 }
76 }
77
78 RTLIL::SigSpec extract(RTLIL::SigSpec sig)
79 {
80 RTLIL::SigSpec result;
81 for (auto &bit : sig)
82 if (bit.wire != NULL && bits.count(bit))
83 result.append_bit(bit);
84 return result;
85 }
86
87 RTLIL::SigSpec remove(RTLIL::SigSpec sig)
88 {
89 RTLIL::SigSpec result;
90 for (auto &bit : sig)
91 if (bit.wire != NULL && bits.count(bit) == 0)
92 result.append(bit);
93 return result;
94 }
95
96 bool check(RTLIL::SigBit bit)
97 {
98 return bit.wire != NULL && bits.count(bit);
99 }
100
101 bool check_any(RTLIL::SigSpec sig)
102 {
103 for (auto &bit : sig)
104 if (bit.wire != NULL && bits.count(bit))
105 return true;
106 return false;
107 }
108
109 bool check_all(RTLIL::SigSpec sig)
110 {
111 for (auto &bit : sig)
112 if (bit.wire != NULL && bits.count(bit) == 0)
113 return false;
114 return true;
115 }
116
117 RTLIL::SigSpec export_one()
118 {
119 for (auto &bit : bits)
120 return RTLIL::SigSpec(bit.first, bit.second);
121 return RTLIL::SigSpec();
122 }
123
124 RTLIL::SigSpec export_all()
125 {
126 pool<RTLIL::SigBit> sig;
127 for (auto &bit : bits)
128 sig.insert(RTLIL::SigBit(bit.first, bit.second));
129 return sig;
130 }
131
132 size_t size() const
133 {
134 return bits.size();
135 }
136 };
137
138 template <typename T, class Compare = std::less<T>>
139 struct SigSet
140 {
141 struct bitDef_t : public std::pair<RTLIL::Wire*, int> {
142 bitDef_t() : std::pair<RTLIL::Wire*, int>(NULL, 0) { }
143 bitDef_t(const RTLIL::SigBit &bit) : std::pair<RTLIL::Wire*, int>(bit.wire, bit.offset) { }
144 unsigned int hash() const { return first->name.hash() + second; }
145 };
146
147 dict<bitDef_t, std::set<T, Compare>> bits;
148
149 void clear()
150 {
151 bits.clear();
152 }
153
154 void insert(RTLIL::SigSpec sig, T data)
155 {
156 for (auto &bit : sig)
157 if (bit.wire != NULL)
158 bits[bit].insert(data);
159 }
160
161 void insert(RTLIL::SigSpec sig, const std::set<T> &data)
162 {
163 for (auto &bit : sig)
164 if (bit.wire != NULL)
165 bits[bit].insert(data.begin(), data.end());
166 }
167
168 void erase(RTLIL::SigSpec sig)
169 {
170 for (auto &bit : sig)
171 if (bit.wire != NULL)
172 bits[bit].clear();
173 }
174
175 void erase(RTLIL::SigSpec sig, T data)
176 {
177 for (auto &bit : sig)
178 if (bit.wire != NULL)
179 bits[bit].erase(data);
180 }
181
182 void erase(RTLIL::SigSpec sig, const std::set<T> &data)
183 {
184 for (auto &bit : sig)
185 if (bit.wire != NULL)
186 bits[bit].erase(data.begin(), data.end());
187 }
188
189 void find(RTLIL::SigSpec sig, std::set<T> &result)
190 {
191 for (auto &bit : sig)
192 if (bit.wire != NULL) {
193 auto &data = bits[bit];
194 result.insert(data.begin(), data.end());
195 }
196 }
197
198 void find(RTLIL::SigSpec sig, pool<T> &result)
199 {
200 for (auto &bit : sig)
201 if (bit.wire != NULL) {
202 auto &data = bits[bit];
203 result.insert(data.begin(), data.end());
204 }
205 }
206
207 std::set<T> find(RTLIL::SigSpec sig)
208 {
209 std::set<T> result;
210 find(sig, result);
211 return result;
212 }
213
214 bool has(RTLIL::SigSpec sig)
215 {
216 for (auto &bit : sig)
217 if (bit.wire != NULL && bits.count(bit))
218 return true;
219 return false;
220 }
221 };
222
223 struct SigMap
224 {
225 mfp<SigBit> database;
226
227 SigMap(RTLIL::Module *module = NULL)
228 {
229 if (module != NULL)
230 set(module);
231 }
232
233 void swap(SigMap &other)
234 {
235 database.swap(other.database);
236 }
237
238 void clear()
239 {
240 database.clear();
241 }
242
243 void set(RTLIL::Module *module)
244 {
245 int bitcount = 0;
246 for (auto &it : module->connections())
247 bitcount += it.first.size();
248
249 database.clear();
250 database.reserve(bitcount);
251
252 for (auto &it : module->connections())
253 add(it.first, it.second);
254 }
255
256 void add(RTLIL::SigSpec from, RTLIL::SigSpec to)
257 {
258 log_assert(GetSize(from) == GetSize(to));
259
260 for (int i = 0; i < GetSize(from); i++)
261 {
262 int bfi = database.lookup(from[i]);
263 int bti = database.lookup(to[i]);
264
265 const RTLIL::SigBit &bf = database[bfi];
266 const RTLIL::SigBit &bt = database[bti];
267
268 if (bf.wire || bt.wire)
269 {
270 database.imerge(bfi, bti);
271
272 if (bf.wire == nullptr)
273 database.ipromote(bfi);
274
275 if (bt.wire == nullptr)
276 database.ipromote(bti);
277 }
278 }
279 }
280
281 void add(RTLIL::SigSpec sig)
282 {
283 for (auto &bit : sig) {
284 RTLIL::SigBit b = database.find(bit);
285 if (b.wire != nullptr)
286 database.promote(bit);
287 }
288 }
289
290 void apply(RTLIL::SigBit &bit) const
291 {
292 bit = database.find(bit);
293 }
294
295 void apply(RTLIL::SigSpec &sig) const
296 {
297 for (auto &bit : sig)
298 apply(bit);
299 }
300
301 RTLIL::SigBit operator()(RTLIL::SigBit bit) const
302 {
303 apply(bit);
304 return bit;
305 }
306
307 RTLIL::SigSpec operator()(RTLIL::SigSpec sig) const
308 {
309 apply(sig);
310 return sig;
311 }
312
313 RTLIL::SigSpec operator()(RTLIL::Wire *wire) const
314 {
315 SigSpec sig(wire);
316 apply(sig);
317 return sig;
318 }
319
320 RTLIL::SigSpec allbits() const
321 {
322 RTLIL::SigSpec sig;
323 for (auto &bit : database)
324 if (bit.wire != nullptr)
325 sig.append(bit);
326 return sig;
327 }
328 };
329
330 YOSYS_NAMESPACE_END
331
332 #endif /* SIGTOOLS_H */