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/yosys.h"
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
; }
42 void add(RTLIL::SigSpec sig
)
49 void add(const SigPool
&other
)
51 for (auto &bit
: other
.bits
)
55 void del(RTLIL::SigSpec sig
)
62 void del(const SigPool
&other
)
64 for (auto &bit
: other
.bits
)
68 void expand(RTLIL::SigSpec from
, RTLIL::SigSpec to
)
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)
78 RTLIL::SigSpec
extract(RTLIL::SigSpec sig
)
80 RTLIL::SigSpec result
;
82 if (bit
.wire
!= NULL
&& bits
.count(bit
))
83 result
.append_bit(bit
);
87 RTLIL::SigSpec
remove(RTLIL::SigSpec sig
)
89 RTLIL::SigSpec result
;
91 if (bit
.wire
!= NULL
&& bits
.count(bit
) == 0)
96 bool check(RTLIL::SigBit bit
)
98 return bit
.wire
!= NULL
&& bits
.count(bit
);
101 bool check_any(RTLIL::SigSpec sig
)
103 for (auto &bit
: sig
)
104 if (bit
.wire
!= NULL
&& bits
.count(bit
))
109 bool check_all(RTLIL::SigSpec sig
)
111 for (auto &bit
: sig
)
112 if (bit
.wire
!= NULL
&& bits
.count(bit
) == 0)
117 RTLIL::SigSpec
export_one()
119 for (auto &bit
: bits
)
120 return RTLIL::SigSpec(bit
.first
, bit
.second
);
121 return RTLIL::SigSpec();
124 RTLIL::SigSpec
export_all()
126 pool
<RTLIL::SigBit
> sig
;
127 for (auto &bit
: bits
)
128 sig
.insert(RTLIL::SigBit(bit
.first
, bit
.second
));
138 template <typename T
, class Compare
= void>
141 static_assert(!std::is_same
<Compare
,void>::value
, "Default value for `Compare' class not found for SigSet<T>. Please specify.");
143 struct bitDef_t
: public std::pair
<RTLIL::Wire
*, int> {
144 bitDef_t() : std::pair
<RTLIL::Wire
*, int>(NULL
, 0) { }
145 bitDef_t(const RTLIL::SigBit
&bit
) : std::pair
<RTLIL::Wire
*, int>(bit
.wire
, bit
.offset
) { }
146 unsigned int hash() const { return first
->name
.hash() + second
; }
149 dict
<bitDef_t
, std::set
<T
, Compare
>> bits
;
156 void insert(RTLIL::SigSpec sig
, T data
)
158 for (auto &bit
: sig
)
159 if (bit
.wire
!= NULL
)
160 bits
[bit
].insert(data
);
163 void insert(RTLIL::SigSpec sig
, const std::set
<T
> &data
)
165 for (auto &bit
: sig
)
166 if (bit
.wire
!= NULL
)
167 bits
[bit
].insert(data
.begin(), data
.end());
170 void erase(RTLIL::SigSpec sig
)
172 for (auto &bit
: sig
)
173 if (bit
.wire
!= NULL
)
177 void erase(RTLIL::SigSpec sig
, T data
)
179 for (auto &bit
: sig
)
180 if (bit
.wire
!= NULL
)
181 bits
[bit
].erase(data
);
184 void erase(RTLIL::SigSpec sig
, const std::set
<T
> &data
)
186 for (auto &bit
: sig
)
187 if (bit
.wire
!= NULL
)
188 bits
[bit
].erase(data
.begin(), data
.end());
191 void find(RTLIL::SigSpec sig
, std::set
<T
> &result
)
193 for (auto &bit
: sig
)
194 if (bit
.wire
!= NULL
) {
195 auto &data
= bits
[bit
];
196 result
.insert(data
.begin(), data
.end());
200 void find(RTLIL::SigSpec sig
, pool
<T
> &result
)
202 for (auto &bit
: sig
)
203 if (bit
.wire
!= NULL
) {
204 auto &data
= bits
[bit
];
205 result
.insert(data
.begin(), data
.end());
209 std::set
<T
> find(RTLIL::SigSpec sig
)
216 bool has(RTLIL::SigSpec sig
)
218 for (auto &bit
: sig
)
219 if (bit
.wire
!= NULL
&& bits
.count(bit
))
226 class SigSet
<T
, typename
std::enable_if
<!std::is_pointer
<T
>::value
>::type
> : public SigSet
<T
, std::less
<T
>> {};
228 using sort_by_name_id_guard
= typename
std::enable_if
<std::is_same
<T
,RTLIL::Cell
*>::value
>::type
;
230 class SigSet
<T
, sort_by_name_id_guard
<T
>> : public SigSet
<T
, RTLIL::sort_by_name_id
<typename
std::remove_pointer
<T
>::type
>> {};
234 mfp
<SigBit
> database
;
236 SigMap(RTLIL::Module
*module
= NULL
)
242 void swap(SigMap
&other
)
244 database
.swap(other
.database
);
252 void set(RTLIL::Module
*module
)
255 for (auto &it
: module
->connections())
256 bitcount
+= it
.first
.size();
259 database
.reserve(bitcount
);
261 for (auto &it
: module
->connections())
262 add(it
.first
, it
.second
);
265 void add(RTLIL::SigSpec from
, RTLIL::SigSpec to
)
267 log_assert(GetSize(from
) == GetSize(to
));
269 for (int i
= 0; i
< GetSize(from
); i
++)
271 int bfi
= database
.lookup(from
[i
]);
272 int bti
= database
.lookup(to
[i
]);
274 const RTLIL::SigBit
&bf
= database
[bfi
];
275 const RTLIL::SigBit
&bt
= database
[bti
];
277 if (bf
.wire
|| bt
.wire
)
279 database
.imerge(bfi
, bti
);
281 if (bf
.wire
== nullptr)
282 database
.ipromote(bfi
);
284 if (bt
.wire
== nullptr)
285 database
.ipromote(bti
);
290 void add(RTLIL::SigSpec sig
)
292 for (auto &bit
: sig
) {
293 RTLIL::SigBit b
= database
.find(bit
);
294 if (b
.wire
!= nullptr)
295 database
.promote(bit
);
299 void apply(RTLIL::SigBit
&bit
) const
301 bit
= database
.find(bit
);
304 void apply(RTLIL::SigSpec
&sig
) const
306 for (auto &bit
: sig
)
310 RTLIL::SigBit
operator()(RTLIL::SigBit bit
) const
316 RTLIL::SigSpec
operator()(RTLIL::SigSpec sig
) const
322 RTLIL::SigSpec
operator()(RTLIL::Wire
*wire
) const
329 RTLIL::SigSpec
allbits() const
332 for (auto &bit
: database
)
333 if (bit
.wire
!= nullptr)
341 #endif /* SIGTOOLS_H */