SV: implement reverse() for queues and dynamic arrays
Lower a.reverse() and q.reverse() to $ivl_darray_method$reverse with new VVP opcodes %reverse/obj and %reverse/prop/obj. Implement reverse_elems() on vvp_darray and queue storage types; dispatch queues via peek<vvp_queue> before vvp_darray so virtual overrides apply. Includes regressions for standalone arrays/queues and class properties. README_sv_queue_locators.txt documents behavior and tests. Made-with: Cursor
This commit is contained in:
parent
084db5ef73
commit
e597156d4d
23
elaborate.cc
23
elaborate.cc
|
|
@ -3965,6 +3965,12 @@ NetProc* PCallTask::elaborate_method_(Design*des, NetScope*scope,
|
|||
&netvector_t::atom2s32,
|
||||
method_name, "$size");
|
||||
}
|
||||
if (method_name == "reverse") {
|
||||
static const std::vector<perm_string> parm_names;
|
||||
return elaborate_sys_task_method_(des, scope, prop, method_name,
|
||||
"$ivl_darray_method$reverse",
|
||||
parm_names);
|
||||
}
|
||||
} else if (ptype && ptype->base_type() == IVL_VT_DARRAY) {
|
||||
NetEProperty*prop = new NetEProperty(net, pidx, 0);
|
||||
prop->set_line(*this);
|
||||
|
|
@ -3981,6 +3987,12 @@ NetProc* PCallTask::elaborate_method_(Design*des, NetScope*scope,
|
|||
&netvector_t::atom2s32,
|
||||
method_name, "$size");
|
||||
}
|
||||
if (method_name == "reverse") {
|
||||
static const std::vector<perm_string> parm_names;
|
||||
return elaborate_sys_task_method_(des, scope, prop, method_name,
|
||||
"$ivl_darray_method$reverse",
|
||||
parm_names);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4055,11 +4067,12 @@ NetProc* PCallTask::elaborate_method_(Design*des, NetScope*scope,
|
|||
&netvector_t::atom2s32,
|
||||
method_name, "$size");
|
||||
} else if (method_name == "reverse") {
|
||||
cerr << get_fileline() << ": sorry: 'reverse()' "
|
||||
"array sorting method is not currently supported."
|
||||
<< endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
static const std::vector<perm_string> parm_names;
|
||||
NetESignal*sig = new NetESignal(net);
|
||||
sig->set_line(*this);
|
||||
return elaborate_sys_task_method_(des, scope, sig, method_name,
|
||||
"$ivl_darray_method$reverse",
|
||||
parm_names);
|
||||
} else if (method_name=="sort") {
|
||||
cerr << get_fileline() << ": sorry: 'sort()' "
|
||||
"array sorting method is not currently supported."
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ on unpacked queues (int q[$]) and dynamic arrays (int da[]):
|
|||
|
||||
find, find_index, find_first, find_first_index, find_last,
|
||||
find_last_index, min, max, unique, unique_index,
|
||||
sum/product (integral)
|
||||
sum/product (integral), reverse (ordering)
|
||||
|
||||
Behavior notes (LRM-oriented):
|
||||
|
||||
|
|
@ -29,6 +29,10 @@ Behavior notes (LRM-oriented):
|
|||
vector types).
|
||||
`product() with (expr)` reduces the expression result for each item.
|
||||
|
||||
* reverse() reverses the order of elements in place for queues and dynamic
|
||||
arrays (integral, vector, real, string, and class-handle elements as stored
|
||||
by Icarus).
|
||||
|
||||
* For dynamic arrays, runtime support treats storage as vvp_darray (including
|
||||
atom-backed integral arrays), not only vvp_queue_vec4. See vvp/vthread.cc:
|
||||
get_queue_or_darray_vec4_from_net() and the %queue/* opcodes used for
|
||||
|
|
@ -39,8 +43,10 @@ Compiler / codegen touchpoints (typical):
|
|||
* Elaboration: elab_expr.cc — NetESFunc $ivl_queue_method$* and with-predicate
|
||||
lowering.
|
||||
* Code generation: tgt-vvp/eval_object.c — eval_queue_method_find,
|
||||
eval_queue_method_find_with; eval_vec4.c for non-with find*.
|
||||
* VVP: vvp/vthread.cc — opcode implementations; vvp/compile.cc — opcode tables.
|
||||
eval_queue_method_find_with; eval_vec4.c for non-with find*;
|
||||
tgt-vvp/vvp_process.c — reverse/delete as system tasks (`%reverse/obj`, …).
|
||||
* VVP: vvp/vthread.cc — opcode implementations; vvp/vvp_darray.{h,cc} —
|
||||
reverse_elems(); vvp/compile.cc — opcode tables.
|
||||
|
||||
Regression tests (see ivtest/vvp_tests/*.json and regress-vvp.list):
|
||||
|
||||
|
|
@ -64,6 +70,8 @@ Regression tests (see ivtest/vvp_tests/*.json and regress-vvp.list):
|
|||
sv_darray_product.v integral product() reduction on dynamic arrays.
|
||||
sv_queue_product_with.v product() with expression on queues.
|
||||
sv_darray_product_with.v product() with expression on dynamic arrays.
|
||||
sv_darray_reverse.v reverse() ordering on dynamic arrays.
|
||||
sv_queue_reverse.v reverse() ordering on queues.
|
||||
sv_queue_sum.v integral sum() reduction on queues.
|
||||
sv_darray_sum.v integral sum() reduction on dynamic arrays.
|
||||
sv_queue_sum_with.v sum() with expression on queues.
|
||||
|
|
|
|||
|
|
@ -62,6 +62,12 @@ module test;
|
|||
`check(c.d.sum() with (item + 1), 12);
|
||||
`check(c.d.product() with (item + 1), 60);
|
||||
|
||||
c.d = '{1, 2, 3};
|
||||
c.d.reverse();
|
||||
`check(c.d[0], 3);
|
||||
`check(c.d[1], 2);
|
||||
`check(c.d[2], 1);
|
||||
|
||||
if (!failed)
|
||||
$display("PASSED");
|
||||
end
|
||||
|
|
|
|||
|
|
@ -54,6 +54,12 @@ module test;
|
|||
`check(c.q.sum() with (item + 1), 12);
|
||||
`check(c.q.product() with (item + 1), 60);
|
||||
|
||||
c.q = '{1, 2, 3};
|
||||
c.q.reverse();
|
||||
`check(c.q[0], 3);
|
||||
`check(c.q[1], 2);
|
||||
`check(c.q[2], 1);
|
||||
|
||||
if (!failed)
|
||||
$display("PASSED");
|
||||
end
|
||||
|
|
|
|||
|
|
@ -0,0 +1,32 @@
|
|||
// Regression: dynamic array reverse() ordering method.
|
||||
|
||||
module top;
|
||||
|
||||
bit failed = 0;
|
||||
|
||||
`define CHK(cond) \
|
||||
if (!(cond)) begin \
|
||||
$display("FAILED line %0d", `__LINE__); \
|
||||
failed = 1; \
|
||||
end
|
||||
|
||||
int a[];
|
||||
|
||||
initial begin
|
||||
a = '{1, 2, 3, 4};
|
||||
a.reverse();
|
||||
`CHK(a[0] === 4 && a[1] === 3 && a[2] === 2 && a[3] === 1);
|
||||
|
||||
a = new [1];
|
||||
a[0] = 42;
|
||||
a.reverse();
|
||||
`CHK(a[0] === 42);
|
||||
|
||||
a = new [0];
|
||||
a.reverse();
|
||||
`CHK(a.size() === 0);
|
||||
|
||||
if (!failed)
|
||||
$display("PASSED");
|
||||
end
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
// Regression: queue reverse() ordering method.
|
||||
|
||||
module top;
|
||||
|
||||
bit failed = 0;
|
||||
|
||||
`define CHK(cond) \
|
||||
if (!(cond)) begin \
|
||||
$display("FAILED line %0d", `__LINE__); \
|
||||
failed = 1; \
|
||||
end
|
||||
|
||||
int q[$];
|
||||
|
||||
initial begin
|
||||
q = '{1, 2, 3, 4};
|
||||
q.reverse();
|
||||
`CHK(q[0] === 4 && q[1] === 3 && q[2] === 2 && q[3] === 1);
|
||||
|
||||
q = '{99};
|
||||
q.reverse();
|
||||
`CHK(q[0] === 99);
|
||||
|
||||
q.delete();
|
||||
q.reverse();
|
||||
`CHK(q.size() === 0);
|
||||
|
||||
if (!failed)
|
||||
$display("PASSED");
|
||||
end
|
||||
endmodule
|
||||
|
|
@ -259,6 +259,7 @@ sv_darray_min_max vvp_tests/sv_darray_min_max.json
|
|||
sv_darray_min_max_with vvp_tests/sv_darray_min_max_with.json
|
||||
sv_darray_product vvp_tests/sv_darray_product.json
|
||||
sv_darray_product_with vvp_tests/sv_darray_product_with.json
|
||||
sv_darray_reverse vvp_tests/sv_darray_reverse.json
|
||||
sv_darray_sum vvp_tests/sv_darray_sum.json
|
||||
sv_darray_sum_with vvp_tests/sv_darray_sum_with.json
|
||||
sv_darray_unique vvp_tests/sv_darray_unique.json
|
||||
|
|
@ -290,6 +291,7 @@ sv_queue_min_max vvp_tests/sv_queue_min_max.json
|
|||
sv_queue_min_max_with vvp_tests/sv_queue_min_max_with.json
|
||||
sv_queue_product vvp_tests/sv_queue_product.json
|
||||
sv_queue_product_with vvp_tests/sv_queue_product_with.json
|
||||
sv_queue_reverse vvp_tests/sv_queue_reverse.json
|
||||
sv_queue_sum vvp_tests/sv_queue_sum.json
|
||||
sv_queue_sum_with vvp_tests/sv_queue_sum_with.json
|
||||
sv_wildcard_import8 vvp_tests/sv_wildcard_import8.json
|
||||
|
|
|
|||
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"type" : "normal",
|
||||
"source" : "sv_darray_reverse.v",
|
||||
"iverilog-args" : [ "-g2005-sv" ],
|
||||
"vlog95" : {
|
||||
"__comment" : "SystemVerilog dynamic array reverse()",
|
||||
"type" : "CE"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"type" : "normal",
|
||||
"source" : "sv_queue_reverse.v",
|
||||
"iverilog-args" : [ "-g2005-sv" ],
|
||||
"vlog95" : {
|
||||
"__comment" : "SystemVerilog queue reverse()",
|
||||
"type" : "CE"
|
||||
}
|
||||
}
|
||||
|
|
@ -3454,9 +3454,10 @@ bool NetScope::check_synth(ivl_process_type_t pr_type,
|
|||
bool NetSTask::check_synth(ivl_process_type_t pr_type,
|
||||
const NetScope* /* scope */) const
|
||||
{
|
||||
if (strcmp(name(), "$ivl_darray_method$delete") == 0) {
|
||||
if (strcmp(name(), "$ivl_darray_method$delete") == 0 ||
|
||||
strcmp(name(), "$ivl_darray_method$reverse") == 0) {
|
||||
cerr << get_fileline() << ": warning: Dynamic array "
|
||||
"delete method cannot be synthesized "
|
||||
"ordering/delete method cannot be synthesized "
|
||||
<< get_process_type_as_string(pr_type) << endl;
|
||||
} else {
|
||||
cerr << get_fileline() << ": warning: System task ("
|
||||
|
|
|
|||
|
|
@ -1691,11 +1691,41 @@ static int show_delete_method(ivl_statement_t net)
|
|||
draw_eval_expr_into_integer(ivl_stmt_parm(net, 1), 3);
|
||||
fprintf(vvp_out, " %%delete/elem v%p_0;\n", var);
|
||||
} else {
|
||||
fprintf(vvp_out, " %%delete/obj v%p_0;\n", var);
|
||||
fprintf(vvp_out, " %%delete/obj v%p_0;\n", var);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int show_reverse_method(ivl_statement_t net)
|
||||
{
|
||||
show_stmt_file_line(net, "reverse dynamic array or queue");
|
||||
|
||||
unsigned parm_count = ivl_stmt_parm_count(net);
|
||||
if (parm_count != 1)
|
||||
return 1;
|
||||
|
||||
ivl_expr_t parm = ivl_stmt_parm(net, 0);
|
||||
if (ivl_expr_type(parm) == IVL_EX_PROPERTY) {
|
||||
ivl_signal_t clas = ivl_expr_signal(parm);
|
||||
unsigned pidx = ivl_expr_property_idx(parm);
|
||||
ivl_type_t sig_type = ivl_signal_net_type(clas);
|
||||
ivl_type_t arr_type = ivl_type_prop_type(sig_type, pidx);
|
||||
ivl_variable_type_t bt = ivl_type_base(arr_type);
|
||||
if (bt != IVL_VT_QUEUE && bt != IVL_VT_DARRAY)
|
||||
return 1;
|
||||
|
||||
fprintf(vvp_out, " %%load/obj v%p_0;\n", clas);
|
||||
fprintf(vvp_out, " %%reverse/prop/obj %u;\n", pidx);
|
||||
fprintf(vvp_out, " %%pop/obj 1, 0;\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
assert(ivl_expr_type(parm) == IVL_EX_SIGNAL);
|
||||
ivl_signal_t var = ivl_expr_signal(parm);
|
||||
fprintf(vvp_out, " %%reverse/obj v%p_0;\n", var);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int show_insert_method(ivl_statement_t net)
|
||||
{
|
||||
show_stmt_file_line(net, "queue: insert");
|
||||
|
|
@ -1881,6 +1911,9 @@ static int show_system_task_call(ivl_statement_t net)
|
|||
if (strcmp(stmt_name,"$ivl_darray_method$delete") == 0)
|
||||
return show_delete_method(net);
|
||||
|
||||
if (strcmp(stmt_name,"$ivl_darray_method$reverse") == 0)
|
||||
return show_reverse_method(net);
|
||||
|
||||
if (strcmp(stmt_name,"$ivl_queue_method$insert") == 0)
|
||||
return show_insert_method(net);
|
||||
|
||||
|
|
|
|||
|
|
@ -213,6 +213,8 @@ extern bool of_REPLICATE(vthread_t thr, vvp_code_t code);
|
|||
extern bool of_RET_REAL(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_RET_STR(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_RET_VEC4(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_REVERSE_OBJ(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_REVERSE_PROP_OBJ(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_RETLOAD_REAL(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_RETLOAD_STR(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_RETLOAD_VEC4(vthread_t thr, vvp_code_t code);
|
||||
|
|
|
|||
|
|
@ -323,6 +323,8 @@ static const struct opcode_table_s opcode_table[] = {
|
|||
{ "%retload/real",of_RETLOAD_REAL,1,{OA_NUMBER, OA_NONE,OA_NONE} },
|
||||
{ "%retload/str", of_RETLOAD_STR, 1,{OA_NUMBER, OA_NONE,OA_NONE} },
|
||||
{ "%retload/vec4",of_RETLOAD_VEC4,1,{OA_NUMBER, OA_NONE,OA_NONE} },
|
||||
{ "%reverse/obj", of_REVERSE_OBJ, 1, {OA_FUNC_PTR, OA_NONE, OA_NONE} },
|
||||
{ "%reverse/prop/obj", of_REVERSE_PROP_OBJ, 1, {OA_NUMBER, OA_NONE, OA_NONE} },
|
||||
{ "%scopy", of_SCOPY, 0, {OA_NONE, OA_NONE, OA_NONE} },
|
||||
{ "%set/dar/obj/real",of_SET_DAR_OBJ_REAL,1,{OA_NUMBER,OA_NONE,OA_NONE} },
|
||||
{ "%set/dar/obj/str", of_SET_DAR_OBJ_STR, 1,{OA_NUMBER,OA_NONE,OA_NONE} },
|
||||
|
|
|
|||
|
|
@ -2610,6 +2610,62 @@ bool of_DELETE_OBJ(vthread_t thr, vvp_code_t cp)
|
|||
return true;
|
||||
}
|
||||
|
||||
/* %reverse/obj <label>
|
||||
* Reverse element order of the queue or dynamic array object at this net.
|
||||
*/
|
||||
bool of_REVERSE_OBJ(vthread_t /*thr*/, vvp_code_t cp)
|
||||
{
|
||||
vvp_net_t*net = cp->net;
|
||||
|
||||
vvp_fun_signal_object*obj = dynamic_cast<vvp_fun_signal_object*>(net->fun);
|
||||
assert(obj);
|
||||
|
||||
vvp_object_t stor = obj->get_object();
|
||||
if (stor.test_nil())
|
||||
return true;
|
||||
|
||||
/* Match other queue ops: peek queues before vvp_darray so concrete
|
||||
queue types dispatch reverse_elems() correctly. */
|
||||
if (vvp_queue* queue = stor.peek<vvp_queue>()) {
|
||||
queue->reverse_elems();
|
||||
return true;
|
||||
}
|
||||
|
||||
vvp_darray*darray = stor.peek<vvp_darray>();
|
||||
assert(darray);
|
||||
darray->reverse_elems();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* %reverse/prop/obj <property-index>
|
||||
* Reverse queue/darray property storage inside the class object on stack top.
|
||||
*/
|
||||
bool of_REVERSE_PROP_OBJ(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
size_t pid = cp->number;
|
||||
|
||||
vvp_object_t& top = thr->peek_object();
|
||||
vvp_cobject*cobj = top.peek<vvp_cobject>();
|
||||
assert(cobj);
|
||||
|
||||
vvp_object_t arr_obj;
|
||||
cobj->get_object(pid, arr_obj, 0);
|
||||
if (arr_obj.test_nil())
|
||||
return true;
|
||||
|
||||
if (vvp_queue* queue = arr_obj.peek<vvp_queue>()) {
|
||||
queue->reverse_elems();
|
||||
return true;
|
||||
}
|
||||
|
||||
vvp_darray*darray = arr_obj.peek<vvp_darray>();
|
||||
assert(darray);
|
||||
darray->reverse_elems();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* %delete/tail <label>, idx
|
||||
*
|
||||
* Remove all elements after the one specified.
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
*/
|
||||
|
||||
# include "vvp_darray.h"
|
||||
# include <algorithm>
|
||||
# include <iostream>
|
||||
# include <typeinfo>
|
||||
|
||||
|
|
@ -27,6 +28,12 @@ vvp_darray::~vvp_darray()
|
|||
{
|
||||
}
|
||||
|
||||
void vvp_darray::reverse_elems(void)
|
||||
{
|
||||
cerr << "XXXX reverse_elems() not implemented for "
|
||||
<< typeid(*this).name() << endl;
|
||||
}
|
||||
|
||||
void vvp_darray::set_word(unsigned, const vvp_vector4_t&)
|
||||
{
|
||||
cerr << "XXXX set_word(vvp_vector4_t) not implemented for " << typeid(*this).name() << endl;
|
||||
|
|
@ -82,6 +89,13 @@ template <class TYPE> size_t vvp_darray_atom<TYPE>::get_size() const
|
|||
return array_.size();
|
||||
}
|
||||
|
||||
template <class TYPE> void vvp_darray_atom<TYPE>::reverse_elems(void)
|
||||
{
|
||||
size_t n = array_.size();
|
||||
for (size_t idx = 0 ; idx < n/2 ; idx += 1)
|
||||
std::swap(array_[idx], array_[n-1-idx]);
|
||||
}
|
||||
|
||||
template <class TYPE> void vvp_darray_atom<TYPE>::set_word(unsigned adr, const vvp_vector4_t&value)
|
||||
{
|
||||
if (adr >= array_.size())
|
||||
|
|
@ -225,6 +239,20 @@ vvp_vector4_t vvp_darray_vec4::get_bitstream(bool as_vec4)
|
|||
return vec;
|
||||
}
|
||||
|
||||
void vvp_darray_vec4::reverse_elems(void)
|
||||
{
|
||||
size_t n = array_.size();
|
||||
for (size_t idx = 0 ; idx < n/2 ; idx += 1)
|
||||
std::swap(array_[idx], array_[n-1-idx]);
|
||||
}
|
||||
|
||||
void vvp_darray_vec2::reverse_elems(void)
|
||||
{
|
||||
size_t n = array_.size();
|
||||
for (size_t idx = 0 ; idx < n/2 ; idx += 1)
|
||||
std::swap(array_[idx], array_[n-1-idx]);
|
||||
}
|
||||
|
||||
vvp_darray_vec2::~vvp_darray_vec2()
|
||||
{
|
||||
}
|
||||
|
|
@ -322,6 +350,13 @@ void vvp_darray_object::shallow_copy(const vvp_object*obj)
|
|||
array_[idx] = that->array_[idx];
|
||||
}
|
||||
|
||||
void vvp_darray_object::reverse_elems(void)
|
||||
{
|
||||
size_t n = array_.size();
|
||||
for (size_t idx = 0 ; idx < n/2 ; idx += 1)
|
||||
std::swap(array_[idx], array_[n-1-idx]);
|
||||
}
|
||||
|
||||
vvp_darray_real::~vvp_darray_real()
|
||||
{
|
||||
}
|
||||
|
|
@ -358,6 +393,13 @@ void vvp_darray_real::shallow_copy(const vvp_object*obj)
|
|||
array_[idx] = that->array_[idx];
|
||||
}
|
||||
|
||||
void vvp_darray_real::reverse_elems(void)
|
||||
{
|
||||
size_t n = array_.size();
|
||||
for (size_t idx = 0 ; idx < n/2 ; idx += 1)
|
||||
std::swap(array_[idx], array_[n-1-idx]);
|
||||
}
|
||||
|
||||
vvp_object* vvp_darray_real::duplicate(void) const
|
||||
{
|
||||
vvp_darray_real*that = new vvp_darray_real(array_.size());
|
||||
|
|
@ -430,6 +472,13 @@ void vvp_darray_string::shallow_copy(const vvp_object*obj)
|
|||
array_[idx] = that->array_[idx];
|
||||
}
|
||||
|
||||
void vvp_darray_string::reverse_elems(void)
|
||||
{
|
||||
size_t n = array_.size();
|
||||
for (size_t idx = 0 ; idx < n/2 ; idx += 1)
|
||||
std::swap(array_[idx], array_[n-1-idx]);
|
||||
}
|
||||
|
||||
vvp_object* vvp_darray_string::duplicate(void) const
|
||||
{
|
||||
vvp_darray_string*that = new vvp_darray_string(array_.size());
|
||||
|
|
@ -769,6 +818,16 @@ void vvp_queue_string::erase_tail(unsigned idx)
|
|||
queue.resize(idx);
|
||||
}
|
||||
|
||||
void vvp_queue_real::reverse_elems(void)
|
||||
{
|
||||
std::reverse(queue.begin(), queue.end());
|
||||
}
|
||||
|
||||
void vvp_queue_string::reverse_elems(void)
|
||||
{
|
||||
std::reverse(queue.begin(), queue.end());
|
||||
}
|
||||
|
||||
void vvp_queue_vec4::copy_elems(vvp_object_t src, unsigned max_size)
|
||||
{
|
||||
if (vvp_queue*src_queue = src.peek<vvp_queue>())
|
||||
|
|
@ -876,3 +935,8 @@ void vvp_queue_vec4::erase_tail(unsigned idx)
|
|||
if (queue.size() > idx)
|
||||
queue.resize(idx);
|
||||
}
|
||||
|
||||
void vvp_queue_vec4::reverse_elems(void)
|
||||
{
|
||||
std::reverse(queue.begin(), queue.end());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,6 +46,9 @@ class vvp_darray : public vvp_object {
|
|||
virtual void get_word(unsigned adr, vvp_object_t&value);
|
||||
|
||||
virtual vvp_vector4_t get_bitstream(bool as_vec4);
|
||||
|
||||
/* In-place element order reversal (dynamic arrays and queues). */
|
||||
virtual void reverse_elems(void);
|
||||
};
|
||||
|
||||
template <class TYPE> class vvp_darray_atom : public vvp_darray {
|
||||
|
|
@ -55,6 +58,7 @@ template <class TYPE> class vvp_darray_atom : public vvp_darray {
|
|||
~vvp_darray_atom() override;
|
||||
|
||||
size_t get_size(void) const override;
|
||||
void reverse_elems(void) override;
|
||||
void set_word(unsigned adr, const vvp_vector4_t&value) override;
|
||||
void get_word(unsigned adr, vvp_vector4_t&value) override;
|
||||
void shallow_copy(const vvp_object*obj) override;
|
||||
|
|
@ -78,6 +82,7 @@ class vvp_darray_vec4 : public vvp_darray {
|
|||
void shallow_copy(const vvp_object*obj) override;
|
||||
vvp_object* duplicate(void) const override;
|
||||
vvp_vector4_t get_bitstream(bool as_vec4) override;
|
||||
void reverse_elems(void) override;
|
||||
|
||||
private:
|
||||
std::vector<vvp_vector4_t> array_;
|
||||
|
|
@ -92,6 +97,7 @@ class vvp_darray_vec2 : public vvp_darray {
|
|||
~vvp_darray_vec2() override;
|
||||
|
||||
size_t get_size(void) const override;
|
||||
void reverse_elems(void) override;
|
||||
void set_word(unsigned adr, const vvp_vector4_t&value) override;
|
||||
void get_word(unsigned adr, vvp_vector4_t&value) override;
|
||||
void shallow_copy(const vvp_object*obj) override;
|
||||
|
|
@ -114,6 +120,7 @@ class vvp_darray_real : public vvp_darray {
|
|||
void shallow_copy(const vvp_object*obj) override;
|
||||
vvp_object* duplicate(void) const override;
|
||||
vvp_vector4_t get_bitstream(bool as_vec4) override;
|
||||
void reverse_elems(void) override;
|
||||
|
||||
private:
|
||||
std::vector<double> array_;
|
||||
|
|
@ -130,6 +137,7 @@ class vvp_darray_string : public vvp_darray {
|
|||
void get_word(unsigned adr, std::string&value) override;
|
||||
void shallow_copy(const vvp_object*obj) override;
|
||||
vvp_object* duplicate(void) const override;
|
||||
void reverse_elems(void) override;
|
||||
|
||||
private:
|
||||
std::vector<std::string> array_;
|
||||
|
|
@ -142,6 +150,7 @@ class vvp_darray_object : public vvp_darray {
|
|||
~vvp_darray_object() override;
|
||||
|
||||
size_t get_size(void) const override;
|
||||
void reverse_elems(void) override;
|
||||
void set_word(unsigned adr, const vvp_object_t&value) override;
|
||||
void get_word(unsigned adr, vvp_object_t&value) override;
|
||||
void shallow_copy(const vvp_object*obj) override;
|
||||
|
|
@ -196,6 +205,7 @@ class vvp_queue_real : public vvp_queue {
|
|||
void pop_front(void) override { queue.pop_front(); };
|
||||
void erase(unsigned idx) override;
|
||||
void erase_tail(unsigned idx) override;
|
||||
void reverse_elems(void) override;
|
||||
|
||||
private:
|
||||
std::deque<double> queue;
|
||||
|
|
@ -216,6 +226,7 @@ class vvp_queue_string : public vvp_queue {
|
|||
void pop_front(void) override { queue.pop_front(); };
|
||||
void erase(unsigned idx) override;
|
||||
void erase_tail(unsigned idx) override;
|
||||
void reverse_elems(void) override;
|
||||
|
||||
private:
|
||||
std::deque<std::string> queue;
|
||||
|
|
@ -236,6 +247,7 @@ class vvp_queue_vec4 : public vvp_queue {
|
|||
void pop_front(void) override { queue.pop_front(); };
|
||||
void erase(unsigned idx) override;
|
||||
void erase_tail(unsigned idx) override;
|
||||
void reverse_elems(void) override;
|
||||
|
||||
private:
|
||||
std::deque<vvp_vector4_t> queue;
|
||||
|
|
|
|||
Loading…
Reference in New Issue