mirror of
https://github.com/verilator/verilator.git
synced 2025-07-31 07:56:10 +00:00
Support 'with' in unique, unique_index, min, max in queues (#3772)
This commit is contained in:
parent
66d85b3381
commit
57975c82b7
@ -429,9 +429,9 @@ public:
|
||||
void shuffle() { std::shuffle(m_deque.begin(), m_deque.end(), VlURNG{}); }
|
||||
VlQueue unique() const {
|
||||
VlQueue out;
|
||||
std::unordered_set<T_Value> saw;
|
||||
std::set<T_Value> saw;
|
||||
for (const auto& i : m_deque) {
|
||||
auto it = saw.find(i);
|
||||
const auto it = saw.find(i);
|
||||
if (it == saw.end()) {
|
||||
saw.insert(it, i);
|
||||
out.push_back(i);
|
||||
@ -439,12 +439,26 @@ public:
|
||||
}
|
||||
return out;
|
||||
}
|
||||
template <typename Func>
|
||||
VlQueue unique(Func with_func) const {
|
||||
VlQueue out;
|
||||
std::set<T_Value> saw;
|
||||
for (const auto& i : m_deque) {
|
||||
const auto i_mapped = with_func(0, i);
|
||||
const auto it = saw.find(i_mapped);
|
||||
if (it == saw.end()) {
|
||||
saw.insert(it, i_mapped);
|
||||
out.push_back(i);
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
VlQueue<IData> unique_index() const {
|
||||
VlQueue<IData> out;
|
||||
IData index = 0;
|
||||
std::unordered_set<T_Value> saw;
|
||||
std::set<T_Value> saw;
|
||||
for (const auto& i : m_deque) {
|
||||
auto it = saw.find(i);
|
||||
const auto it = saw.find(i);
|
||||
if (it == saw.end()) {
|
||||
saw.insert(it, i);
|
||||
out.push_back(index);
|
||||
@ -454,6 +468,22 @@ public:
|
||||
return out;
|
||||
}
|
||||
template <typename Func>
|
||||
VlQueue<IData> unique_index(Func with_func) const {
|
||||
VlQueue<IData> out;
|
||||
IData index = 0;
|
||||
std::unordered_set<T_Value> saw;
|
||||
for (const auto& i : m_deque) {
|
||||
const auto i_mapped = with_func(index, i);
|
||||
auto it = saw.find(i_mapped);
|
||||
if (it == saw.end()) {
|
||||
saw.insert(it, i_mapped);
|
||||
out.push_back(index);
|
||||
}
|
||||
++index;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
template <typename Func>
|
||||
VlQueue find(Func with_func) const {
|
||||
VlQueue out;
|
||||
IData index = 0;
|
||||
@ -517,11 +547,29 @@ public:
|
||||
const auto it = std::min_element(m_deque.begin(), m_deque.end());
|
||||
return VlQueue::cons(*it);
|
||||
}
|
||||
template <typename Func>
|
||||
VlQueue min(Func with_func) const {
|
||||
if (m_deque.empty()) return VlQueue{};
|
||||
const auto it = std::min_element(m_deque.begin(), m_deque.end(),
|
||||
[&with_func](const IData& a, const IData& b) {
|
||||
return with_func(0, a) < with_func(0, b);
|
||||
});
|
||||
return VlQueue::cons(*it);
|
||||
}
|
||||
VlQueue max() const {
|
||||
if (m_deque.empty()) return VlQueue{};
|
||||
const auto it = std::max_element(m_deque.begin(), m_deque.end());
|
||||
return VlQueue::cons(*it);
|
||||
}
|
||||
template <typename Func>
|
||||
VlQueue max(Func with_func) const {
|
||||
if (m_deque.empty()) return VlQueue{};
|
||||
const auto it = std::max_element(m_deque.begin(), m_deque.end(),
|
||||
[&with_func](const IData& a, const IData& b) {
|
||||
return with_func(0, a) < with_func(0, b);
|
||||
});
|
||||
return VlQueue::cons(*it);
|
||||
}
|
||||
|
||||
T_Value r_sum() const {
|
||||
T_Value out(0); // Type must have assignment operator
|
||||
|
@ -3231,10 +3231,12 @@ private:
|
||||
newp->dtypeSetVoid();
|
||||
} else if (nodep->name() == "min" || nodep->name() == "max" || nodep->name() == "unique"
|
||||
|| nodep->name() == "unique_index") {
|
||||
AstWith* const withp = methodWithArgument(
|
||||
nodep, false, true, nullptr, nodep->findUInt32DType(), adtypep->subDTypep());
|
||||
methodOkArguments(nodep, 0, 0);
|
||||
methodCallLValueRecurse(nodep, nodep->fromp(), VAccess::READ);
|
||||
newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(),
|
||||
nodep->name()};
|
||||
nodep->name(), withp};
|
||||
if (nodep->name() == "unique_index") {
|
||||
newp->dtypep(newp->findQueueIndexDType());
|
||||
} else {
|
||||
|
@ -44,10 +44,17 @@ module t (/*AUTOARG*/);
|
||||
v = $sformatf("%p", qv); `checks(v, "'{'h2, 'h4, 'h1, 'h3} ");
|
||||
qv = qe.unique;
|
||||
`checkh(qv.size(), 0);
|
||||
qv = q.unique(x) with (x % 2);
|
||||
`checkh(qv.size(), 2);
|
||||
qi = q.unique_index; qv.sort;
|
||||
v = $sformatf("%p", qi); `checks(v, "'{'h0, 'h2, 'h3, 'h4} ");
|
||||
// According to 7.12.1 of IEEE Std 1800-2017, it is not specified which index of duplicated value should be returned
|
||||
`checkh(qi.size(), 4);
|
||||
qi.delete(1);
|
||||
v = $sformatf("%p", qi); `checks(v, "'{'h0, 'h3, 'h4} ");
|
||||
qi = qe.unique_index;
|
||||
`checkh(qi.size(), 0);
|
||||
qi = q.unique_index(x) with (x % 3); qv.sort;
|
||||
`checkh(qi.size(), 3);
|
||||
|
||||
q.reverse;
|
||||
v = $sformatf("%p", q); `checks(v, "'{'h3, 'h1, 'h4, 'h2, 'h2} ");
|
||||
@ -104,8 +111,12 @@ module t (/*AUTOARG*/);
|
||||
|
||||
qv = q.min;
|
||||
v = $sformatf("%p", qv); `checks(v, "'{'h1} ");
|
||||
qv = q.min(x) with (x + 1);
|
||||
v = $sformatf("%p", qv); `checks(v, "'{'h1} ");
|
||||
qv = q.max;
|
||||
v = $sformatf("%p", qv); `checks(v, "'{'h4} ");
|
||||
qv = q.max(x) with ((x % 4) + 100);
|
||||
v = $sformatf("%p", qv); `checks(v, "'{'h3} ");
|
||||
qv = qe.min;
|
||||
v = $sformatf("%p", qv); `checks(v, "'{}");
|
||||
qv = qe.max;
|
||||
|
@ -1,41 +1,37 @@
|
||||
%Error: t/t_queue_method_bad.v:15:21: 'with' not legal on this method
|
||||
: ... In instance t
|
||||
15 | qv = q.unique with (1);
|
||||
| ^~~~
|
||||
%Error: t/t_queue_method_bad.v:16:9: The 1 arguments passed to .reverse method does not match its requiring 0 arguments
|
||||
%Error: t/t_queue_method_bad.v:15:9: The 1 arguments passed to .reverse method does not match its requiring 0 arguments
|
||||
: ... In instance t
|
||||
16 | q.reverse(1);
|
||||
15 | q.reverse(1);
|
||||
| ^~~~~~~
|
||||
%Error: t/t_queue_method_bad.v:17:9: The 1 arguments passed to .shuffle method does not match its requiring 0 arguments
|
||||
%Error: t/t_queue_method_bad.v:16:9: The 1 arguments passed to .shuffle method does not match its requiring 0 arguments
|
||||
: ... In instance t
|
||||
17 | q.shuffle(1);
|
||||
16 | q.shuffle(1);
|
||||
| ^~~~~~~
|
||||
%Error: t/t_queue_method_bad.v:18:14: 'with' statement is required for .find method
|
||||
%Error: t/t_queue_method_bad.v:17:14: 'with' statement is required for .find method
|
||||
: ... In instance t
|
||||
18 | qv = q.find;
|
||||
17 | qv = q.find;
|
||||
| ^~~~
|
||||
%Error: t/t_queue_method_bad.v:19:14: 'with' statement is required for .find_first method
|
||||
%Error: t/t_queue_method_bad.v:18:14: 'with' statement is required for .find_first method
|
||||
: ... In instance t
|
||||
19 | qv = q.find_first;
|
||||
18 | qv = q.find_first;
|
||||
| ^~~~~~~~~~
|
||||
%Error: t/t_queue_method_bad.v:20:14: 'with' statement is required for .find_last method
|
||||
%Error: t/t_queue_method_bad.v:19:14: 'with' statement is required for .find_last method
|
||||
: ... In instance t
|
||||
20 | qv = q.find_last;
|
||||
19 | qv = q.find_last;
|
||||
| ^~~~~~~~~
|
||||
%Error: t/t_queue_method_bad.v:21:14: 'with' statement is required for .find_index method
|
||||
%Error: t/t_queue_method_bad.v:20:14: 'with' statement is required for .find_index method
|
||||
: ... In instance t
|
||||
21 | qi = q.find_index;
|
||||
20 | qi = q.find_index;
|
||||
| ^~~~~~~~~~
|
||||
%Error: t/t_queue_method_bad.v:22:14: 'with' statement is required for .find_first_index method
|
||||
%Error: t/t_queue_method_bad.v:21:14: 'with' statement is required for .find_first_index method
|
||||
: ... In instance t
|
||||
22 | qi = q.find_first_index;
|
||||
21 | qi = q.find_first_index;
|
||||
| ^~~~~~~~~~~~~~~~
|
||||
%Error: t/t_queue_method_bad.v:23:14: 'with' statement is required for .find_last_index method
|
||||
%Error: t/t_queue_method_bad.v:22:14: 'with' statement is required for .find_last_index method
|
||||
: ... In instance t
|
||||
23 | qi = q.find_last_index;
|
||||
22 | qi = q.find_last_index;
|
||||
| ^~~~~~~~~~~~~~~
|
||||
%Error: t/t_queue_method_bad.v:25:19: 'with' not legal on this method
|
||||
%Error: t/t_queue_method_bad.v:24:19: 'with' not legal on this method
|
||||
: ... In instance t
|
||||
25 | qi = q.size with (1);
|
||||
24 | qi = q.size with (1);
|
||||
| ^~~~
|
||||
%Error: Exiting due to
|
||||
|
@ -12,7 +12,6 @@ module t (/*AUTOARG*/);
|
||||
int qi[$]; // Index returns
|
||||
|
||||
q = '{2, 2, 4, 1, 3};
|
||||
qv = q.unique with (1); // Bad no with allowed
|
||||
q.reverse(1); // Bad no args allowed
|
||||
q.shuffle(1); // Bad no args allowed
|
||||
qv = q.find; // Bad missing with
|
||||
|
Loading…
Reference in New Issue
Block a user