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/rtlil.h"
24 #include "kernel/log.h"
30 typedef std::pair
<RTLIL::Wire
*,int> bitDef_t
;
31 std::set
<bitDef_t
> bits
;
38 void add(RTLIL::SigSpec sig
)
41 for (auto &c
: sig
.chunks
) {
45 bitDef_t
bit(c
.wire
, c
.offset
);
50 void add(const SigPool
&other
)
52 for (auto &bit
: other
.bits
)
56 void del(RTLIL::SigSpec sig
)
59 for (auto &c
: sig
.chunks
) {
63 bitDef_t
bit(c
.wire
, c
.offset
);
68 void del(const SigPool
&other
)
70 for (auto &bit
: other
.bits
)
74 void expand(RTLIL::SigSpec from
, RTLIL::SigSpec to
)
78 assert(from
.chunks
.size() == to
.chunks
.size());
79 for (size_t i
= 0; i
< from
.chunks
.size(); i
++) {
80 bitDef_t
bit_from(from
.chunks
[i
].wire
, from
.chunks
[i
].offset
);
81 bitDef_t
bit_to(to
.chunks
[i
].wire
, to
.chunks
[i
].offset
);
82 if (bit_from
.first
== NULL
|| bit_to
.first
== NULL
)
84 if (bits
.count(bit_from
) > 0)
89 RTLIL::SigSpec
extract(RTLIL::SigSpec sig
)
91 RTLIL::SigSpec result
;
93 for (auto &c
: sig
.chunks
) {
96 bitDef_t
bit(c
.wire
, c
.offset
);
97 if (bits
.count(bit
) > 0)
103 RTLIL::SigSpec
remove(RTLIL::SigSpec sig
)
105 RTLIL::SigSpec result
;
107 for (auto &c
: sig
.chunks
) {
110 bitDef_t
bit(c
.wire
, c
.offset
);
111 if (bits
.count(bit
) == 0)
117 bool check_any(RTLIL::SigSpec sig
)
120 for (auto &c
: sig
.chunks
) {
123 bitDef_t
bit(c
.wire
, c
.offset
);
124 if (bits
.count(bit
) != 0)
130 bool check_all(RTLIL::SigSpec sig
)
133 for (auto &c
: sig
.chunks
) {
136 bitDef_t
bit(c
.wire
, c
.offset
);
137 if (bits
.count(bit
) == 0)
143 RTLIL::SigSpec
export_one()
146 for (auto &bit
: bits
) {
147 sig
.append(RTLIL::SigSpec(bit
.first
, 1, bit
.second
));
153 RTLIL::SigSpec
export_all()
156 for (auto &bit
: bits
)
157 sig
.append(RTLIL::SigSpec(bit
.first
, 1, bit
.second
));
158 sig
.sort_and_unify();
168 template <typename T
>
171 typedef std::pair
<RTLIL::Wire
*,int> bitDef_t
;
172 std::map
<bitDef_t
, std::set
<T
>> bits
;
179 void insert(RTLIL::SigSpec sig
, T data
)
182 for (auto &c
: sig
.chunks
) {
185 assert(c
.width
== 1);
186 bitDef_t
bit(c
.wire
, c
.offset
);
187 bits
[bit
].insert(data
);
191 void insert(RTLIL::SigSpec sig
, const std::set
<T
> &data
)
194 for (auto &c
: sig
.chunks
) {
197 assert(c
.width
== 1);
198 bitDef_t
bit(c
.wire
, c
.offset
);
199 bits
[bit
].insert(data
.begin(), data
.end());
203 void erase(RTLIL::SigSpec sig
)
206 for (auto &c
: sig
.chunks
) {
209 assert(c
.width
== 1);
210 bitDef_t
bit(c
.wire
, c
.offset
);
215 void erase(RTLIL::SigSpec sig
, T data
)
218 for (auto &c
: sig
.chunks
) {
221 assert(c
.width
== 1);
222 bitDef_t
bit(c
.wire
, c
.offset
);
223 bits
[bit
].erase(data
);
227 void erase(RTLIL::SigSpec sig
, const std::set
<T
> &data
)
230 for (auto &c
: sig
.chunks
) {
233 assert(c
.width
== 1);
234 bitDef_t
bit(c
.wire
, c
.offset
);
235 bits
[bit
].erase(data
.begin(), data
.end());
239 void find(RTLIL::SigSpec sig
, std::set
<T
> &result
)
242 for (auto &c
: sig
.chunks
) {
245 assert(c
.width
== 1);
246 bitDef_t
bit(c
.wire
, c
.offset
);
247 for (auto &data
: bits
[bit
])
252 std::set
<T
> find(RTLIL::SigSpec sig
)
259 bool has(RTLIL::SigSpec sig
)
262 for (auto &c
: sig
.chunks
) {
265 assert(c
.width
== 1);
266 bitDef_t
bit(c
.wire
, c
.offset
);
276 typedef std::pair
<RTLIL::Wire
*,int> bitDef_t
;
278 struct shared_bit_data_t
{
279 RTLIL::SigChunk chunk
;
280 std::set
<bitDef_t
> bits
;
283 std::map
<bitDef_t
, shared_bit_data_t
*> bits
;
285 SigMap(RTLIL::Module
*module
= NULL
)
291 SigMap(const SigMap
&other
)
296 const SigMap
&operator=(const SigMap
&other
)
302 void copy(const SigMap
&other
)
305 for (auto &bit
: other
.bits
) {
306 bits
[bit
.first
] = new shared_bit_data_t
;
307 bits
[bit
.first
]->chunk
= bit
.second
->chunk
;
308 bits
[bit
.first
]->bits
= bit
.second
->bits
;
312 void swap(SigMap
&other
)
314 bits
.swap(other
.bits
);
324 std::set
<shared_bit_data_t
*> all_bd_ptr
;
325 for (auto &it
: bits
)
326 all_bd_ptr
.insert(it
.second
);
327 for (auto bd_ptr
: all_bd_ptr
)
332 void set(RTLIL::Module
*module
)
335 for (auto &it
: module
->connections
)
336 add(it
.first
, it
.second
);
339 // internal helper function
340 void register_bit(const RTLIL::SigChunk
&c
)
342 assert(c
.width
== 1);
343 bitDef_t
bit(c
.wire
, c
.offset
);
344 if (c
.wire
&& bits
.count(bit
) == 0) {
345 shared_bit_data_t
*bd
= new shared_bit_data_t
;
347 bd
->bits
.insert(bit
);
352 // internal helper function
353 void unregister_bit(const RTLIL::SigChunk
&c
)
355 assert(c
.width
== 1);
356 bitDef_t
bit(c
.wire
, c
.offset
);
357 if (c
.wire
&& bits
.count(bit
) > 0) {
358 shared_bit_data_t
*bd
= bits
[bit
];
360 if (bd
->bits
.size() == 0)
366 // internal helper function
367 void merge_bit(const RTLIL::SigChunk
&c1
, const RTLIL::SigChunk
&c2
)
369 assert(c1
.wire
!= NULL
&& c2
.wire
!= NULL
);
370 assert(c1
.width
== 1 && c2
.width
== 1);
372 bitDef_t
b1(c1
.wire
, c1
.offset
);
373 bitDef_t
b2(c2
.wire
, c2
.offset
);
375 shared_bit_data_t
*bd1
= bits
[b1
];
376 shared_bit_data_t
*bd2
= bits
[b2
];
377 assert(bd1
!= NULL
&& bd2
!= NULL
);
382 if (bd1
->bits
.size() < bd2
->bits
.size())
384 for (auto &bit
: bd1
->bits
)
386 bd2
->bits
.insert(bd1
->bits
.begin(), bd1
->bits
.end());
391 bd1
->chunk
= bd2
->chunk
;
392 for (auto &bit
: bd2
->bits
)
394 bd1
->bits
.insert(bd2
->bits
.begin(), bd2
->bits
.end());
399 // internal helper function
400 void set_bit(const RTLIL::SigChunk
&c1
, const RTLIL::SigChunk
&c2
)
402 assert(c1
.wire
!= NULL
);
403 assert(c1
.width
== 1 && c2
.width
== 1);
404 bitDef_t
bit(c1
.wire
, c1
.offset
);
405 assert(bits
.count(bit
) > 0);
406 bits
[bit
]->chunk
= c2
;
409 // internal helper function
410 void map_bit(RTLIL::SigChunk
&c
)
412 assert(c
.width
== 1);
413 bitDef_t
bit(c
.wire
, c
.offset
);
414 if (c
.wire
&& bits
.count(bit
) > 0)
415 c
= bits
[bit
]->chunk
;
418 void add(RTLIL::SigSpec from
, RTLIL::SigSpec to
)
423 assert(from
.chunks
.size() == to
.chunks
.size());
424 for (size_t i
= 0; i
< from
.chunks
.size(); i
++)
426 RTLIL::SigChunk
&cf
= from
.chunks
[i
];
427 RTLIL::SigChunk
&ct
= to
.chunks
[i
];
442 void add(RTLIL::SigSpec sig
)
445 for (size_t i
= 0; i
< sig
.chunks
.size(); i
++)
447 RTLIL::SigChunk
&c
= sig
.chunks
[i
];
448 if (c
.wire
!= NULL
) {
455 void del(RTLIL::SigSpec sig
)
458 for (auto &c
: sig
.chunks
)
462 void apply(RTLIL::SigSpec
&sig
)
465 for (auto &c
: sig
.chunks
)
470 RTLIL::SigSpec
operator()(RTLIL::SigSpec sig
)
477 #endif /* SIGTOOLS_H */