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.
|
||||
}
|
||||
~VlQueue() {}
|
||||
|
||||
// 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) {
|
||||
VlQueue out;
|
||||
out.push_back(lhs);
|
||||
|
|
@ -302,13 +310,15 @@ public:
|
|||
|
||||
// METHODS
|
||||
T_Value& atDefault() { return m_defaultValue; }
|
||||
const Deque& privateDeque() const { return m_deque; }
|
||||
|
||||
// Size. Verilog: function int size(), or int num()
|
||||
int size() const { return m_deque.size(); }
|
||||
// Clear array. Verilog: function void delete([input index])
|
||||
void clear() { m_deque.clear(); }
|
||||
void erase(size_t index) {
|
||||
if (VL_LIKELY(index < m_deque.size())) m_deque.erase(m_deque.begin() + index);
|
||||
void erase(vlsint32_t index) {
|
||||
if (VL_LIKELY(index >= 0 && index < m_deque.size()))
|
||||
m_deque.erase(m_deque.begin() + index);
|
||||
}
|
||||
|
||||
// Dynamic array new[] becomes a renew()
|
||||
|
|
@ -353,10 +363,10 @@ public:
|
|||
// Setting. Verilog: assoc[index] = v
|
||||
// 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
|
||||
T_Value& at(size_t index) {
|
||||
T_Value& at(vlsint32_t index) {
|
||||
static T_Value s_throwAway;
|
||||
// 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();
|
||||
return s_throwAway;
|
||||
} else {
|
||||
|
|
@ -364,27 +374,28 @@ public:
|
|||
}
|
||||
}
|
||||
// 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;
|
||||
// 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();
|
||||
} else {
|
||||
return m_deque[index];
|
||||
}
|
||||
}
|
||||
// function void q.insert(index, value);
|
||||
void insert(size_t index, const T_Value& value) {
|
||||
if (VL_UNLIKELY(index >= m_deque.size())) return;
|
||||
void insert(vlsint32_t index, const T_Value& value) {
|
||||
if (VL_UNLIKELY(index < 0 || index >= m_deque.size())) return;
|
||||
m_deque.insert(m_deque.begin() + index, value);
|
||||
}
|
||||
|
||||
// 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;
|
||||
if (VL_UNLIKELY(lsb < 0)) lsb = 0;
|
||||
if (VL_UNLIKELY(lsb >= m_deque.size())) lsb = 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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,8 @@ module t (/*AUTOARG*/);
|
|||
string q[$];
|
||||
string v;
|
||||
int i;
|
||||
int qi[$:5];
|
||||
int ri[$];
|
||||
|
||||
q.push_front("non-empty");
|
||||
i = q.size(); `checkh(i, 1);
|
||||
|
|
@ -43,6 +45,9 @@ module t (/*AUTOARG*/);
|
|||
|
||||
// Slicing
|
||||
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];
|
||||
v = $sformatf("%p", q); `checks(v, "'{\"c\", \"d\"} ");
|
||||
q = '{"q", "b", "c", "d", "e", "f"};
|
||||
|
|
@ -80,7 +85,34 @@ module t (/*AUTOARG*/);
|
|||
v = q.pop_front(); `checks(v, "CC");
|
||||
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");
|
||||
$finish;
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
|
|||
Loading…
Reference in New Issue