21 template<
class Signal>
23 : parents(signals.size(), signals.size()), ranges(signals.size()) {
24 const std::size_t count = signals.size();
25 for (std::size_t index = 0U; index < count; ++index) {
27 if (mux.role != MultiplexRole::Unconditional && mux.role != MultiplexRole::Selector &&
28 mux.role != MultiplexRole::Branch && mux.role != MultiplexRole::BranchSelector)
31 throw MultiplexError(index,
"Selector name and ranges must be supplied together.");
32 if (mux.
selector.empty() && !IsMultiplexBranch(mux.role))
34 std::size_t parent = count;
35 for (std::size_t candidate = 0U; candidate < count; ++candidate) {
36 const Multiplexing &other = signals[candidate].multiplexing;
37 const bool matches = !mux.
selector.empty()
38 ? signals[candidate].name == mux.
selector
39 : other.role == MultiplexRole::Selector && other.
selector.empty();
43 throw MultiplexError(index,
"Ambiguous multiplex selector; use SG_MUL_VAL_.");
47 throw MultiplexError(index,
"Multiplexed branch has no selector.");
48 if (!IsMultiplexSelector(signals[parent].multiplexing.role))
49 throw MultiplexError(index,
"Referenced signal is not a multiplex selector.");
50 parents[index] = parent;
53 if (range.minimum > range.maximum)
55 if (signals[parent].length < 64U && range.maximum >= (std::uint64_t(1U) << signals[parent].length))
56 throw MultiplexError(index,
"Branch value exceeds selector raw range.");
59 for (std::size_t index = 0U; index < count; ++index) {
60 std::size_t current = index;
61 for (std::size_t depth = 0U; current != count; ++depth) {
63 throw MultiplexError(index,
"Cyclic multiplex selector dependency.");
64 current = parents[current];
69 bool Matches(std::size_t index, std::uint64_t value)
const {
71 if (range.minimum <= value && value <= range.maximum)
77 bool AreMutuallyExclusive(std::size_t first, std::size_t second)
const {
78 const std::size_t count = parents.size();
79 for (std::size_t left = first; parents[left] != count; left = parents[left]) {
80 for (std::size_t right = second; parents[right] != count; right = parents[right]) {
81 if (parents[left] != parents[right])
83 bool intersects =
false;
86 if (a.minimum <= b.maximum && b.minimum <= a.maximum)
97 std::vector<std::size_t> parents;
98 std::vector<std::vector<MultiplexRange>> ranges;