SV: reverse(), sort(), rsort(), shuffle() for queues/darrays
Add ordering methods for queues and dynamic arrays. Update ivtest gold files for always_*_warn, br1005, and br_gh710b LXT per review. Split from steveicarus/iverilog#1330 (part 06/6).
This commit is contained in:
parent
f0b6d3addc
commit
afe849249c
98
elaborate.cc
98
elaborate.cc
|
|
@ -4385,6 +4385,34 @@ 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_property_method_(des, scope, net, pidx,
|
||||
method_name,
|
||||
"$ivl_darray_method$reverse",
|
||||
parm_names);
|
||||
}
|
||||
if (method_name == "sort") {
|
||||
static const std::vector<perm_string> parm_names;
|
||||
return elaborate_sys_task_property_method_(des, scope, net, pidx,
|
||||
method_name,
|
||||
"$ivl_darray_method$sort",
|
||||
parm_names);
|
||||
}
|
||||
if (method_name == "rsort") {
|
||||
static const std::vector<perm_string> parm_names;
|
||||
return elaborate_sys_task_property_method_(des, scope, net, pidx,
|
||||
method_name,
|
||||
"$ivl_darray_method$rsort",
|
||||
parm_names);
|
||||
}
|
||||
if (method_name == "shuffle") {
|
||||
static const std::vector<perm_string> parm_names;
|
||||
return elaborate_sys_task_property_method_(des, scope, net, pidx,
|
||||
method_name,
|
||||
"$ivl_darray_method$shuffle",
|
||||
parm_names);
|
||||
}
|
||||
} else if (ptype && ptype->base_type() == IVL_VT_DARRAY) {
|
||||
if (method_name == "delete") {
|
||||
static const std::vector<perm_string> parm_names = {
|
||||
|
|
@ -4400,6 +4428,34 @@ 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_property_method_(des, scope, net, pidx,
|
||||
method_name,
|
||||
"$ivl_darray_method$reverse",
|
||||
parm_names);
|
||||
}
|
||||
if (method_name == "sort") {
|
||||
static const std::vector<perm_string> parm_names;
|
||||
return elaborate_sys_task_property_method_(des, scope, net, pidx,
|
||||
method_name,
|
||||
"$ivl_darray_method$sort",
|
||||
parm_names);
|
||||
}
|
||||
if (method_name == "rsort") {
|
||||
static const std::vector<perm_string> parm_names;
|
||||
return elaborate_sys_task_property_method_(des, scope, net, pidx,
|
||||
method_name,
|
||||
"$ivl_darray_method$rsort",
|
||||
parm_names);
|
||||
}
|
||||
if (method_name == "shuffle") {
|
||||
static const std::vector<perm_string> parm_names;
|
||||
return elaborate_sys_task_property_method_(des, scope, net, pidx,
|
||||
method_name,
|
||||
"$ivl_darray_method$shuffle",
|
||||
parm_names);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4460,29 +4516,25 @@ 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;
|
||||
} else if (method_name=="sort") {
|
||||
cerr << get_fileline() << ": sorry: 'sort()' "
|
||||
"array sorting method is not currently supported."
|
||||
<< endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
} else if (method_name=="rsort") {
|
||||
cerr << get_fileline() << ": sorry: 'rsort()' "
|
||||
"array sorting method is not currently supported."
|
||||
<< endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
} else if (method_name=="shuffle") {
|
||||
cerr << get_fileline() << ": sorry: 'shuffle()' "
|
||||
"array sorting method is not currently supported."
|
||||
<< endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
static const std::vector<perm_string> parm_names;
|
||||
return elaborate_sys_task_method_(des, scope, net, method_name,
|
||||
"$ivl_darray_method$reverse",
|
||||
parm_names);
|
||||
} else if (method_name == "sort") {
|
||||
static const std::vector<perm_string> parm_names;
|
||||
return elaborate_sys_task_method_(des, scope, net, method_name,
|
||||
"$ivl_darray_method$sort",
|
||||
parm_names);
|
||||
} else if (method_name == "rsort") {
|
||||
static const std::vector<perm_string> parm_names;
|
||||
return elaborate_sys_task_method_(des, scope, net, method_name,
|
||||
"$ivl_darray_method$rsort",
|
||||
parm_names);
|
||||
} else if (method_name == "shuffle") {
|
||||
static const std::vector<perm_string> parm_names;
|
||||
return elaborate_sys_task_method_(des, scope, net, method_name,
|
||||
"$ivl_darray_method$shuffle",
|
||||
parm_names);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
./ivltests/always_comb_warn.v:32: warning: A for statement step must be a simple binary +/- to be synthesized in an always_comb process.
|
||||
./ivltests/always_comb_warn.v:32: warning: System task ($display) cannot be synthesized in an always_comb process.
|
||||
./ivltests/always_comb_warn.v:33: warning: System task ($display) cannot be synthesized in an always_comb process.
|
||||
./ivltests/always_comb_warn.v:34: warning: Dynamic array delete method cannot be synthesized in an always_comb process.
|
||||
./ivltests/always_comb_warn.v:34: warning: Dynamic array ordering/delete method cannot be synthesized in an always_comb process.
|
||||
./ivltests/always_comb_warn.v:35: warning: System task ($display) cannot be synthesized in an always_comb process.
|
||||
./ivltests/always_comb_warn.v:14: warning: An event (tevt) cannot be synthesized in an always_comb process.
|
||||
./ivltests/always_comb_warn.v:13: warning: A non-integral variable (trl) cannot be synthesized in an always_comb process.
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
./ivltests/always_ff_warn.v:33: warning: A for statement step must be a simple binary +/- to be synthesized in an always_ff process.
|
||||
./ivltests/always_ff_warn.v:33: warning: System task ($display) cannot be synthesized in an always_ff process.
|
||||
./ivltests/always_ff_warn.v:34: warning: System task ($display) cannot be synthesized in an always_ff process.
|
||||
./ivltests/always_ff_warn.v:35: warning: Dynamic array delete method cannot be synthesized in an always_ff process.
|
||||
./ivltests/always_ff_warn.v:35: warning: Dynamic array ordering/delete method cannot be synthesized in an always_ff process.
|
||||
./ivltests/always_ff_warn.v:36: warning: System task ($display) cannot be synthesized in an always_ff process.
|
||||
./ivltests/always_ff_warn.v:15: warning: An event (tevt) cannot be synthesized in an always_ff process.
|
||||
./ivltests/always_ff_warn.v:14: warning: A non-integral variable (trl) cannot be synthesized in an always_ff process.
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
./ivltests/always_latch_warn.v:32: warning: A for statement step must be a simple binary +/- to be synthesized in an always_latch process.
|
||||
./ivltests/always_latch_warn.v:32: warning: System task ($display) cannot be synthesized in an always_latch process.
|
||||
./ivltests/always_latch_warn.v:33: warning: System task ($display) cannot be synthesized in an always_latch process.
|
||||
./ivltests/always_latch_warn.v:34: warning: Dynamic array delete method cannot be synthesized in an always_latch process.
|
||||
./ivltests/always_latch_warn.v:34: warning: Dynamic array ordering/delete method cannot be synthesized in an always_latch process.
|
||||
./ivltests/always_latch_warn.v:35: warning: System task ($display) cannot be synthesized in an always_latch process.
|
||||
./ivltests/always_latch_warn.v:14: warning: An event (tevt) cannot be synthesized in an always_latch process.
|
||||
./ivltests/always_latch_warn.v:13: warning: A non-integral variable (trl) cannot be synthesized in an always_latch process.
|
||||
|
|
|
|||
|
|
@ -59,6 +59,20 @@ module test;
|
|||
|
||||
c.d = '{2, 3, 4};
|
||||
`check(c.d.product(), 24);
|
||||
`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);
|
||||
|
||||
c.d = '{3, 1, 2};
|
||||
c.d.sort();
|
||||
`check(c.d[0], 1);
|
||||
`check(c.d[1], 2);
|
||||
`check(c.d[2], 3);
|
||||
|
||||
if (!failed)
|
||||
$display("PASSED");
|
||||
|
|
|
|||
|
|
@ -51,6 +51,20 @@ module test;
|
|||
|
||||
c.q = '{2, 3, 4};
|
||||
`check(c.q.product(), 24);
|
||||
`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);
|
||||
|
||||
c.q = '{3, 1, 2};
|
||||
c.q.sort();
|
||||
`check(c.q[0], 1);
|
||||
`check(c.q[1], 2);
|
||||
`check(c.q[2], 3);
|
||||
|
||||
if (!failed)
|
||||
$display("PASSED");
|
||||
|
|
|
|||
|
|
@ -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,33 @@
|
|||
// Regression: dynamic array sort(), rsort(), shuffle().
|
||||
|
||||
module top;
|
||||
|
||||
bit failed = 0;
|
||||
|
||||
`define CHK(cond) \
|
||||
if (!(cond)) begin \
|
||||
$display("FAILED line %0d", `__LINE__); \
|
||||
failed = 1; \
|
||||
end
|
||||
|
||||
int a[];
|
||||
int sum0;
|
||||
|
||||
initial begin
|
||||
a = '{3, 1, 4, 1, 5};
|
||||
a.sort();
|
||||
`CHK(a[0] === 1 && a[1] === 1 && a[2] === 3 && a[3] === 4 && a[4] === 5);
|
||||
|
||||
a = '{3, 1, 4};
|
||||
a.rsort();
|
||||
`CHK(a[0] === 4 && a[1] === 3 && a[2] === 1);
|
||||
|
||||
a = '{10, -2, 7};
|
||||
sum0 = a.sum();
|
||||
a.shuffle();
|
||||
`CHK(a.sum() === sum0);
|
||||
|
||||
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
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
// Regression: queue sort(), rsort(), shuffle().
|
||||
|
||||
module top;
|
||||
|
||||
bit failed = 0;
|
||||
|
||||
`define CHK(cond) \
|
||||
if (!(cond)) begin \
|
||||
$display("FAILED line %0d", `__LINE__); \
|
||||
failed = 1; \
|
||||
end
|
||||
|
||||
int q[$];
|
||||
int sum0;
|
||||
|
||||
initial begin
|
||||
q = '{3, 1, 4, 1, 5};
|
||||
q.sort();
|
||||
`CHK(q[0] === 1 && q[1] === 1 && q[2] === 3 && q[3] === 4 && q[4] === 5);
|
||||
|
||||
q = '{3, 1, 4};
|
||||
q.rsort();
|
||||
`CHK(q[0] === 4 && q[1] === 3 && q[2] === 1);
|
||||
|
||||
q = '{10, -2, 7};
|
||||
sum0 = q.sum();
|
||||
q.shuffle();
|
||||
`CHK(q.sum() === sum0);
|
||||
|
||||
if (!failed)
|
||||
$display("PASSED");
|
||||
end
|
||||
endmodule
|
||||
|
|
@ -319,6 +319,8 @@ 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_sort vvp_tests/sv_darray_sort.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
|
||||
|
|
@ -422,6 +424,8 @@ 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_sort vvp_tests/sv_queue_sort.json
|
||||
sv_queue_sum vvp_tests/sv_queue_sum.json
|
||||
sv_queue_sum_with vvp_tests/sv_queue_sum_with.json
|
||||
sv_queue_unique vvp_tests/sv_queue_unique.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_darray_sort.v",
|
||||
"iverilog-args" : [ "-g2005-sv" ],
|
||||
"vlog95" : {
|
||||
"__comment" : "SystemVerilog dynamic array sort/rsort/shuffle",
|
||||
"type" : "CE"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"type" : "normal",
|
||||
"source" : "sv_queue_reverse.v",
|
||||
"iverilog-args" : [ "-g2005-sv" ],
|
||||
"vlog95" : {
|
||||
"__comment" : "SystemVerilog queue reverse()",
|
||||
"type" : "CE"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"type" : "normal",
|
||||
"source" : "sv_queue_sort.v",
|
||||
"iverilog-args" : [ "-g2005-sv" ],
|
||||
"vlog95" : {
|
||||
"__comment" : "SystemVerilog queue sort/rsort/shuffle",
|
||||
"type" : "CE"
|
||||
}
|
||||
}
|
||||
|
|
@ -3461,9 +3461,13 @@ 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 ||
|
||||
strcmp(name(), "$ivl_darray_method$sort") == 0 ||
|
||||
strcmp(name(), "$ivl_darray_method$rsort") == 0 ||
|
||||
strcmp(name(), "$ivl_darray_method$shuffle") == 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,68 @@ 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_array_order_method(ivl_statement_t net, const char*descr,
|
||||
const char*op_signal, const char*op_prop)
|
||||
{
|
||||
show_stmt_file_line(net, descr);
|
||||
|
||||
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, " %s %u;\n", op_prop, 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, " %s v%p_0;\n", op_signal, var);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int show_insert_method(ivl_statement_t net)
|
||||
{
|
||||
show_stmt_file_line(net, "queue: insert");
|
||||
|
|
@ -1881,6 +1938,21 @@ 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_darray_method$sort") == 0)
|
||||
return show_array_order_method(net, "sort dynamic array or queue",
|
||||
"%sort/obj", "%sort/prop/obj");
|
||||
|
||||
if (strcmp(stmt_name,"$ivl_darray_method$rsort") == 0)
|
||||
return show_array_order_method(net, "rsort dynamic array or queue",
|
||||
"%rsort/obj", "%rsort/prop/obj");
|
||||
|
||||
if (strcmp(stmt_name,"$ivl_darray_method$shuffle") == 0)
|
||||
return show_array_order_method(net, "shuffle dynamic array or queue",
|
||||
"%shuffle/obj", "%shuffle/prop/obj");
|
||||
|
||||
if (strcmp(stmt_name,"$ivl_queue_method$insert") == 0)
|
||||
return show_insert_method(net);
|
||||
|
||||
|
|
|
|||
|
|
@ -214,6 +214,14 @@ 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_RSORT_OBJ(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_RSORT_PROP_OBJ(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_SHUFFLE_OBJ(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_SHUFFLE_PROP_OBJ(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_SORT_OBJ(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_SORT_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);
|
||||
|
|
|
|||
|
|
@ -324,6 +324,10 @@ 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} },
|
||||
{ "%rsort/obj", of_RSORT_OBJ, 1, {OA_FUNC_PTR, OA_NONE, OA_NONE} },
|
||||
{ "%rsort/prop/obj", of_RSORT_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} },
|
||||
|
|
@ -331,6 +335,10 @@ static const struct opcode_table_s opcode_table[] = {
|
|||
{ "%shiftl", of_SHIFTL, 1, {OA_NUMBER, OA_NONE, OA_NONE} },
|
||||
{ "%shiftr", of_SHIFTR, 1, {OA_NUMBER, OA_NONE, OA_NONE} },
|
||||
{ "%shiftr/s", of_SHIFTR_S, 1, {OA_NUMBER, OA_NONE, OA_NONE} },
|
||||
{ "%shuffle/obj", of_SHUFFLE_OBJ, 1, {OA_FUNC_PTR, OA_NONE, OA_NONE} },
|
||||
{ "%shuffle/prop/obj", of_SHUFFLE_PROP_OBJ, 1, {OA_NUMBER, OA_NONE, OA_NONE} },
|
||||
{ "%sort/obj", of_SORT_OBJ, 1, {OA_FUNC_PTR, OA_NONE, OA_NONE} },
|
||||
{ "%sort/prop/obj", of_SORT_PROP_OBJ, 1, {OA_NUMBER, OA_NONE, OA_NONE} },
|
||||
{ "%split/vec4", of_SPLIT_VEC4, 1,{OA_NUMBER, OA_NONE, OA_NONE} },
|
||||
{ "%store/dar/r", of_STORE_DAR_R, 1,{OA_FUNC_PTR, OA_NONE, OA_NONE} },
|
||||
{ "%store/dar/str", of_STORE_DAR_STR, 1,{OA_FUNC_PTR, OA_NONE, OA_NONE} },
|
||||
|
|
|
|||
198
vvp/vthread.cc
198
vvp/vthread.cc
|
|
@ -2610,6 +2610,204 @@ 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;
|
||||
}
|
||||
|
||||
/* %sort/obj — ascending sort */
|
||||
bool of_SORT_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;
|
||||
|
||||
if (vvp_queue* queue = stor.peek<vvp_queue>()) {
|
||||
queue->sort_elems(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
vvp_darray*darray = stor.peek<vvp_darray>();
|
||||
assert(darray);
|
||||
darray->sort_elems(true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* %sort/prop/obj */
|
||||
bool of_SORT_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->sort_elems(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
vvp_darray*darray = arr_obj.peek<vvp_darray>();
|
||||
assert(darray);
|
||||
darray->sort_elems(true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* %rsort/obj — descending sort */
|
||||
bool of_RSORT_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;
|
||||
|
||||
if (vvp_queue* queue = stor.peek<vvp_queue>()) {
|
||||
queue->sort_elems(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
vvp_darray*darray = stor.peek<vvp_darray>();
|
||||
assert(darray);
|
||||
darray->sort_elems(false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* %rsort/prop/obj */
|
||||
bool of_RSORT_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->sort_elems(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
vvp_darray*darray = arr_obj.peek<vvp_darray>();
|
||||
assert(darray);
|
||||
darray->sort_elems(false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* %shuffle/obj */
|
||||
bool of_SHUFFLE_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;
|
||||
|
||||
if (vvp_queue* queue = stor.peek<vvp_queue>()) {
|
||||
queue->shuffle_elems();
|
||||
return true;
|
||||
}
|
||||
|
||||
vvp_darray*darray = stor.peek<vvp_darray>();
|
||||
assert(darray);
|
||||
darray->shuffle_elems();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* %shuffle/prop/obj */
|
||||
bool of_SHUFFLE_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->shuffle_elems();
|
||||
return true;
|
||||
}
|
||||
|
||||
vvp_darray*darray = arr_obj.peek<vvp_darray>();
|
||||
assert(darray);
|
||||
darray->shuffle_elems();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* %delete/tail <label>, idx
|
||||
*
|
||||
* Remove all elements after the one specified.
|
||||
|
|
|
|||
|
|
@ -18,15 +18,54 @@
|
|||
*/
|
||||
|
||||
# include "vvp_darray.h"
|
||||
# include <algorithm>
|
||||
# include <functional>
|
||||
# include <iostream>
|
||||
# include <random>
|
||||
# include <typeinfo>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace {
|
||||
|
||||
static std::mt19937& shuffle_rng(void)
|
||||
{
|
||||
static std::mt19937 rng(std::random_device{}());
|
||||
return rng;
|
||||
}
|
||||
|
||||
static bool vec4_lt_unsigned(const vvp_vector4_t&a, const vvp_vector4_t&b)
|
||||
{
|
||||
if (a.eeq(b)) return false;
|
||||
vvp_bit4_t gt = compare_gtge(b, a, BIT4_1);
|
||||
if (gt == BIT4_X) return false;
|
||||
return gt == BIT4_1;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
vvp_darray::~vvp_darray()
|
||||
{
|
||||
}
|
||||
|
||||
void vvp_darray::reverse_elems(void)
|
||||
{
|
||||
cerr << "XXXX reverse_elems() not implemented for "
|
||||
<< typeid(*this).name() << endl;
|
||||
}
|
||||
|
||||
void vvp_darray::sort_elems(bool /*ascending*/)
|
||||
{
|
||||
cerr << "XXXX sort_elems() not implemented for "
|
||||
<< typeid(*this).name() << endl;
|
||||
}
|
||||
|
||||
void vvp_darray::shuffle_elems(void)
|
||||
{
|
||||
cerr << "XXXX shuffle_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 +121,24 @@ 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>::sort_elems(bool ascending)
|
||||
{
|
||||
if (ascending) std::sort(array_.begin(), array_.end());
|
||||
else std::sort(array_.begin(), array_.end(), std::greater<TYPE>());
|
||||
}
|
||||
|
||||
template <class TYPE> void vvp_darray_atom<TYPE>::shuffle_elems(void)
|
||||
{
|
||||
std::shuffle(array_.begin(), array_.end(), shuffle_rng());
|
||||
}
|
||||
|
||||
template <class TYPE> void vvp_darray_atom<TYPE>::set_word(unsigned adr, const vvp_vector4_t&value)
|
||||
{
|
||||
if (adr >= array_.size())
|
||||
|
|
@ -225,6 +282,56 @@ 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_vec4::sort_elems(bool ascending)
|
||||
{
|
||||
if (ascending) {
|
||||
std::sort(array_.begin(), array_.end(), vec4_lt_unsigned);
|
||||
} else {
|
||||
std::sort(array_.begin(), array_.end(),
|
||||
[](const vvp_vector4_t&a, const vvp_vector4_t&b) {
|
||||
if (a.eeq(b))
|
||||
return false;
|
||||
return vec4_lt_unsigned(b, a);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void vvp_darray_vec4::shuffle_elems(void)
|
||||
{
|
||||
std::shuffle(array_.begin(), array_.end(), shuffle_rng());
|
||||
}
|
||||
|
||||
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]);
|
||||
}
|
||||
|
||||
void vvp_darray_vec2::sort_elems(bool ascending)
|
||||
{
|
||||
if (ascending) {
|
||||
std::sort(array_.begin(), array_.end());
|
||||
} else {
|
||||
std::sort(array_.begin(), array_.end(),
|
||||
[](const vvp_vector2_t&a, const vvp_vector2_t&b) {
|
||||
return b < a;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void vvp_darray_vec2::shuffle_elems(void)
|
||||
{
|
||||
std::shuffle(array_.begin(), array_.end(), shuffle_rng());
|
||||
}
|
||||
|
||||
vvp_darray_vec2::~vvp_darray_vec2()
|
||||
{
|
||||
}
|
||||
|
|
@ -322,6 +429,33 @@ 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]);
|
||||
}
|
||||
|
||||
void vvp_darray_object::sort_elems(bool ascending)
|
||||
{
|
||||
if (ascending) {
|
||||
std::sort(array_.begin(), array_.end(),
|
||||
[](const vvp_object_t&a, const vvp_object_t&b) {
|
||||
return a.sort_order_key() < b.sort_order_key();
|
||||
});
|
||||
} else {
|
||||
std::sort(array_.begin(), array_.end(),
|
||||
[](const vvp_object_t&a, const vvp_object_t&b) {
|
||||
return a.sort_order_key() > b.sort_order_key();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void vvp_darray_object::shuffle_elems(void)
|
||||
{
|
||||
std::shuffle(array_.begin(), array_.end(), shuffle_rng());
|
||||
}
|
||||
|
||||
vvp_darray_real::~vvp_darray_real()
|
||||
{
|
||||
}
|
||||
|
|
@ -358,6 +492,24 @@ 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]);
|
||||
}
|
||||
|
||||
void vvp_darray_real::sort_elems(bool ascending)
|
||||
{
|
||||
if (ascending) std::sort(array_.begin(), array_.end());
|
||||
else std::sort(array_.begin(), array_.end(), std::greater<double>());
|
||||
}
|
||||
|
||||
void vvp_darray_real::shuffle_elems(void)
|
||||
{
|
||||
std::shuffle(array_.begin(), array_.end(), shuffle_rng());
|
||||
}
|
||||
|
||||
vvp_object* vvp_darray_real::duplicate(void) const
|
||||
{
|
||||
vvp_darray_real*that = new vvp_darray_real(array_.size());
|
||||
|
|
@ -430,6 +582,24 @@ 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]);
|
||||
}
|
||||
|
||||
void vvp_darray_string::sort_elems(bool ascending)
|
||||
{
|
||||
if (ascending) std::sort(array_.begin(), array_.end());
|
||||
else std::sort(array_.begin(), array_.end(), std::greater<string>());
|
||||
}
|
||||
|
||||
void vvp_darray_string::shuffle_elems(void)
|
||||
{
|
||||
std::shuffle(array_.begin(), array_.end(), shuffle_rng());
|
||||
}
|
||||
|
||||
vvp_object* vvp_darray_string::duplicate(void) const
|
||||
{
|
||||
vvp_darray_string*that = new vvp_darray_string(array_.size());
|
||||
|
|
@ -769,6 +939,38 @@ 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_real::sort_elems(bool ascending)
|
||||
{
|
||||
if (ascending) std::sort(queue.begin(), queue.end());
|
||||
else std::sort(queue.begin(), queue.end(), std::greater<double>());
|
||||
}
|
||||
|
||||
void vvp_queue_real::shuffle_elems(void)
|
||||
{
|
||||
std::shuffle(queue.begin(), queue.end(), shuffle_rng());
|
||||
}
|
||||
|
||||
void vvp_queue_string::sort_elems(bool ascending)
|
||||
{
|
||||
if (ascending) std::sort(queue.begin(), queue.end());
|
||||
else std::sort(queue.begin(), queue.end(), std::greater<string>());
|
||||
}
|
||||
|
||||
void vvp_queue_string::shuffle_elems(void)
|
||||
{
|
||||
std::shuffle(queue.begin(), queue.end(), shuffle_rng());
|
||||
}
|
||||
|
||||
void vvp_queue_vec4::copy_elems(vvp_object_t src, unsigned max_size)
|
||||
{
|
||||
if (vvp_queue*src_queue = src.peek<vvp_queue>())
|
||||
|
|
@ -876,3 +1078,27 @@ 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());
|
||||
}
|
||||
|
||||
void vvp_queue_vec4::sort_elems(bool ascending)
|
||||
{
|
||||
if (ascending) {
|
||||
std::sort(queue.begin(), queue.end(), vec4_lt_unsigned);
|
||||
} else {
|
||||
std::sort(queue.begin(), queue.end(),
|
||||
[](const vvp_vector4_t&a, const vvp_vector4_t&b) {
|
||||
if (a.eeq(b))
|
||||
return false;
|
||||
return vec4_lt_unsigned(b, a);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void vvp_queue_vec4::shuffle_elems(void)
|
||||
{
|
||||
std::shuffle(queue.begin(), queue.end(), shuffle_rng());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,6 +46,13 @@ 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);
|
||||
|
||||
/* sort: ascending if true, descending if false; shuffle randomizes. */
|
||||
virtual void sort_elems(bool ascending);
|
||||
virtual void shuffle_elems(void);
|
||||
};
|
||||
|
||||
template <class TYPE> class vvp_darray_atom : public vvp_darray {
|
||||
|
|
@ -55,6 +62,9 @@ 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 sort_elems(bool ascending) override;
|
||||
void shuffle_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 +88,9 @@ 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;
|
||||
void sort_elems(bool ascending) override;
|
||||
void shuffle_elems(void) override;
|
||||
|
||||
private:
|
||||
std::vector<vvp_vector4_t> array_;
|
||||
|
|
@ -92,6 +105,9 @@ class vvp_darray_vec2 : public vvp_darray {
|
|||
~vvp_darray_vec2() override;
|
||||
|
||||
size_t get_size(void) const override;
|
||||
void reverse_elems(void) override;
|
||||
void sort_elems(bool ascending) override;
|
||||
void shuffle_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 +130,9 @@ 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;
|
||||
void sort_elems(bool ascending) override;
|
||||
void shuffle_elems(void) override;
|
||||
|
||||
private:
|
||||
std::vector<double> array_;
|
||||
|
|
@ -130,6 +149,9 @@ 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;
|
||||
void sort_elems(bool ascending) override;
|
||||
void shuffle_elems(void) override;
|
||||
|
||||
private:
|
||||
std::vector<std::string> array_;
|
||||
|
|
@ -142,6 +164,9 @@ class vvp_darray_object : public vvp_darray {
|
|||
~vvp_darray_object() override;
|
||||
|
||||
size_t get_size(void) const override;
|
||||
void reverse_elems(void) override;
|
||||
void sort_elems(bool ascending) override;
|
||||
void shuffle_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 +221,9 @@ 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;
|
||||
void sort_elems(bool ascending) override;
|
||||
void shuffle_elems(void) override;
|
||||
|
||||
private:
|
||||
std::deque<double> queue;
|
||||
|
|
@ -216,6 +244,9 @@ 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;
|
||||
void sort_elems(bool ascending) override;
|
||||
void shuffle_elems(void) override;
|
||||
|
||||
private:
|
||||
std::deque<std::string> queue;
|
||||
|
|
@ -236,6 +267,9 @@ 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;
|
||||
void sort_elems(bool ascending) override;
|
||||
void shuffle_elems(void) override;
|
||||
|
||||
private:
|
||||
std::deque<vvp_vector4_t> queue;
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include <cstdint>
|
||||
# include <stdlib.h>
|
||||
|
||||
/*
|
||||
|
|
@ -69,6 +70,12 @@ class vvp_object_t {
|
|||
|
||||
template <class T> T*peek(void) const;
|
||||
|
||||
/* Stable ordering for array-of-handle sort (object identity). */
|
||||
uintptr_t sort_order_key(void) const
|
||||
{
|
||||
return reinterpret_cast<uintptr_t>(ref_);
|
||||
}
|
||||
|
||||
private:
|
||||
class vvp_object*ref_;
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue