Fix queue assignment with different limits, negative indicies
This commit is contained in:
parent
835905bdae
commit
046c0a7aa1
|
|
@ -272,7 +272,15 @@ public:
|
||||||
// m_defaultValue isn't defaulted. Caller's constructor must do it.
|
// m_defaultValue isn't defaulted. Caller's constructor must do it.
|
||||||
}
|
}
|
||||||
~VlQueue() {}
|
~VlQueue() {}
|
||||||
|
|
||||||
// Standard copy constructor works. Verilog: assoca = assocb
|
// Standard copy constructor works. Verilog: assoca = assocb
|
||||||
|
// Also must allow conversion from a different T_MaxSize queue
|
||||||
|
template <size_t U_MaxSize = 0> VlQueue operator=(const VlQueue<T_Value, U_MaxSize>& rhs) {
|
||||||
|
m_deque = rhs.privateDeque();
|
||||||
|
if (VL_UNLIKELY(T_MaxSize && T_MaxSize < m_deque.size())) m_deque.resize(T_MaxSize - 1);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
static VlQueue cons(const T_Value& lhs) {
|
static VlQueue cons(const T_Value& lhs) {
|
||||||
VlQueue out;
|
VlQueue out;
|
||||||
out.push_back(lhs);
|
out.push_back(lhs);
|
||||||
|
|
@ -302,13 +310,15 @@ public:
|
||||||
|
|
||||||
// METHODS
|
// METHODS
|
||||||
T_Value& atDefault() { return m_defaultValue; }
|
T_Value& atDefault() { return m_defaultValue; }
|
||||||
|
const Deque& privateDeque() const { return m_deque; }
|
||||||
|
|
||||||
// Size. Verilog: function int size(), or int num()
|
// Size. Verilog: function int size(), or int num()
|
||||||
int size() const { return m_deque.size(); }
|
int size() const { return m_deque.size(); }
|
||||||
// Clear array. Verilog: function void delete([input index])
|
// Clear array. Verilog: function void delete([input index])
|
||||||
void clear() { m_deque.clear(); }
|
void clear() { m_deque.clear(); }
|
||||||
void erase(size_t index) {
|
void erase(vlsint32_t index) {
|
||||||
if (VL_LIKELY(index < m_deque.size())) m_deque.erase(m_deque.begin() + index);
|
if (VL_LIKELY(index >= 0 && index < m_deque.size()))
|
||||||
|
m_deque.erase(m_deque.begin() + index);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dynamic array new[] becomes a renew()
|
// Dynamic array new[] becomes a renew()
|
||||||
|
|
@ -353,10 +363,10 @@ public:
|
||||||
// Setting. Verilog: assoc[index] = v
|
// Setting. Verilog: assoc[index] = v
|
||||||
// Can't just overload operator[] or provide a "at" reference to set,
|
// Can't just overload operator[] or provide a "at" reference to set,
|
||||||
// because we need to be able to insert only when the value is set
|
// because we need to be able to insert only when the value is set
|
||||||
T_Value& at(size_t index) {
|
T_Value& at(vlsint32_t index) {
|
||||||
static T_Value s_throwAway;
|
static T_Value s_throwAway;
|
||||||
// Needs to work for dynamic arrays, so does not use T_MaxSize
|
// Needs to work for dynamic arrays, so does not use T_MaxSize
|
||||||
if (VL_UNLIKELY(index >= m_deque.size())) {
|
if (VL_UNLIKELY(index < 0 || index >= m_deque.size())) {
|
||||||
s_throwAway = atDefault();
|
s_throwAway = atDefault();
|
||||||
return s_throwAway;
|
return s_throwAway;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -364,27 +374,28 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Accessing. Verilog: v = assoc[index]
|
// Accessing. Verilog: v = assoc[index]
|
||||||
const T_Value& at(size_t index) const {
|
const T_Value& at(vlsint32_t index) const {
|
||||||
static T_Value s_throwAway;
|
static T_Value s_throwAway;
|
||||||
// Needs to work for dynamic arrays, so does not use T_MaxSize
|
// Needs to work for dynamic arrays, so does not use T_MaxSize
|
||||||
if (VL_UNLIKELY(index >= m_deque.size())) {
|
if (VL_UNLIKELY(index < 0 || index >= m_deque.size())) {
|
||||||
return atDefault();
|
return atDefault();
|
||||||
} else {
|
} else {
|
||||||
return m_deque[index];
|
return m_deque[index];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// function void q.insert(index, value);
|
// function void q.insert(index, value);
|
||||||
void insert(size_t index, const T_Value& value) {
|
void insert(vlsint32_t index, const T_Value& value) {
|
||||||
if (VL_UNLIKELY(index >= m_deque.size())) return;
|
if (VL_UNLIKELY(index < 0 || index >= m_deque.size())) return;
|
||||||
m_deque.insert(m_deque.begin() + index, value);
|
m_deque.insert(m_deque.begin() + index, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return slice q[lsb:msb]
|
// Return slice q[lsb:msb]
|
||||||
VlQueue slice(size_t lsb, size_t msb) const {
|
VlQueue slice(vlsint32_t lsb, vlsint32_t msb) const {
|
||||||
VlQueue out;
|
VlQueue out;
|
||||||
|
if (VL_UNLIKELY(lsb < 0)) lsb = 0;
|
||||||
if (VL_UNLIKELY(lsb >= m_deque.size())) lsb = m_deque.size() - 1;
|
if (VL_UNLIKELY(lsb >= m_deque.size())) lsb = m_deque.size() - 1;
|
||||||
if (VL_UNLIKELY(msb >= m_deque.size())) msb = m_deque.size() - 1;
|
if (VL_UNLIKELY(msb >= m_deque.size())) msb = m_deque.size() - 1;
|
||||||
for (size_t i = lsb; i <= msb; ++i) out.push_back(m_deque[i]);
|
for (vlsint32_t i = lsb; i <= msb; ++i) out.push_back(m_deque[i]);
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,8 @@ module t (/*AUTOARG*/);
|
||||||
string q[$];
|
string q[$];
|
||||||
string v;
|
string v;
|
||||||
int i;
|
int i;
|
||||||
|
int qi[$:5];
|
||||||
|
int ri[$];
|
||||||
|
|
||||||
q.push_front("non-empty");
|
q.push_front("non-empty");
|
||||||
i = q.size(); `checkh(i, 1);
|
i = q.size(); `checkh(i, 1);
|
||||||
|
|
@ -43,6 +45,9 @@ module t (/*AUTOARG*/);
|
||||||
|
|
||||||
// Slicing
|
// Slicing
|
||||||
q = '{"q", "b", "c", "d", "e", "f"};
|
q = '{"q", "b", "c", "d", "e", "f"};
|
||||||
|
q = q[-1:0];
|
||||||
|
v = $sformatf("%p", q); `checks(v, "'{\"q\"} ");
|
||||||
|
q = '{"q", "b", "c", "d", "e", "f"};
|
||||||
q = q[2:3];
|
q = q[2:3];
|
||||||
v = $sformatf("%p", q); `checks(v, "'{\"c\", \"d\"} ");
|
v = $sformatf("%p", q); `checks(v, "'{\"c\", \"d\"} ");
|
||||||
q = '{"q", "b", "c", "d", "e", "f"};
|
q = '{"q", "b", "c", "d", "e", "f"};
|
||||||
|
|
@ -80,7 +85,34 @@ module t (/*AUTOARG*/);
|
||||||
v = q.pop_front(); `checks(v, "CC");
|
v = q.pop_front(); `checks(v, "CC");
|
||||||
end
|
end
|
||||||
|
|
||||||
|
begin
|
||||||
|
qi.push_back(0);
|
||||||
|
qi.push_back(1);
|
||||||
|
qi.push_back(2);
|
||||||
|
qi.push_back(3);
|
||||||
|
qi.push_back(4);
|
||||||
|
qi.push_back(5);
|
||||||
|
|
||||||
|
// Assignment to unsized queue from sized queue
|
||||||
|
ri = qi[ 2 : 4 ];
|
||||||
|
`checkh(ri.size, 3);
|
||||||
|
ri = qi[ 4 : 2 ];
|
||||||
|
`checkh(ri.size, 0);
|
||||||
|
ri = qi[ 2 : 2 ];
|
||||||
|
`checkh(ri.size, 1);
|
||||||
|
ri = qi[ -2 : 2 ]; // 2 - 0 + 1 = 3
|
||||||
|
`checkh(ri.size, 3);
|
||||||
|
ri = qi[ 2 : 10 ]; // 5 - 2 + 1 = 4
|
||||||
|
`checkh(ri.size, 4);
|
||||||
|
|
||||||
|
// Assignment from unsized to sized
|
||||||
|
ri = '{1,2,3,4,5,6,7,8,9};
|
||||||
|
qi = ri;
|
||||||
|
`checkh(qi.size, 5);
|
||||||
|
end
|
||||||
|
|
||||||
$write("*-* All Finished *-*\n");
|
$write("*-* All Finished *-*\n");
|
||||||
$finish;
|
$finish;
|
||||||
end
|
end
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue