diff --git a/elaborate.cc b/elaborate.cc index a374a9ce0..81d4174b2 100644 --- a/elaborate.cc +++ b/elaborate.cc @@ -3640,12 +3640,20 @@ NetProc* PCallTask::elaborate_queue_method_(Design*des, NetScope*scope, sig->set_line(*this); unsigned nparms = parms_.size(); - if ((nparms == 0) || (nparms > 1)) { + // insert() requires two arguments. + if ((method_name == "insert") && (nparms != 2)) { + cerr << get_fileline() << ": error: " << method_name + << "() method requires two arguments." << endl; + des->errors += 1; + } + // push_front() and push_back() require one argument. + if ((method_name != "insert") && (nparms != 1)) { cerr << get_fileline() << ": error: " << method_name << "() method requires a single argument." << endl; des->errors += 1; } + // Get the context width if this is a logic type. ivl_variable_type_t base_type = net->darray_type()->element_base_type(); int context_width = -1; switch (base_type) { @@ -3657,13 +3665,35 @@ NetProc* PCallTask::elaborate_queue_method_(Design*des, NetScope*scope, break; } - vectorargv (2); + vectorargv (nparms+1); argv[0] = sig; - if (parms_[0] == 0) { - argv[1] = 0; + if (method_name != "insert") { + if ((nparms == 0) || (parms_[0] == 0)) { + argv[1] = 0; + cerr << get_fileline() << ": error: " << method_name + << "() methods first argument is missing." << endl; + des->errors += 1; + } else + argv[1] = elab_and_eval(des, scope, parms_[0], context_width, + false, false, base_type); } else { - argv[1] = elab_and_eval(des, scope, parms_[0], context_width, - false, false, base_type); + if ((nparms == 0) || (parms_[0] == 0)) { + argv[1] = 0; + cerr << get_fileline() << ": error: " << method_name + << "() methods first argument is missing." << endl; + des->errors += 1; + } else + argv[1] = elab_and_eval(des, scope, parms_[0], 32, + false, false, IVL_VT_LOGIC); + + if ((nparms < 2) || (parms_[1] == 0)) { + argv[2] = 0; + cerr << get_fileline() << ": error: " << method_name + << "() methods second argument is missing." << endl; + des->errors += 1; + } else + argv[2] = elab_and_eval(des, scope, parms_[1], context_width, + false, false, base_type); } NetSTask*sys = new NetSTask(sys_task_name, IVL_SFUNC_AS_TASK_IGNORE, argv); @@ -3709,12 +3739,15 @@ NetProc* PCallTask::elaborate_method_(Design*des, NetScope*scope, } if (net->queue_type()) { - if (method_name=="push_back") + if (method_name == "push_back") return elaborate_queue_method_(des, scope, net, method_name, "$ivl_queue_method$push_back"); - if (method_name=="push_front") + else if (method_name == "push_front") return elaborate_queue_method_(des, scope, net, method_name, "$ivl_queue_method$push_front"); + else if (method_name == "insert") + return elaborate_queue_method_(des, scope, net, method_name, + "$ivl_queue_method$insert"); } if (const netclass_t*class_type = net->class_type()) { diff --git a/tgt-vvp/stmt_assign.c b/tgt-vvp/stmt_assign.c index f87fe8708..bbba82d3b 100644 --- a/tgt-vvp/stmt_assign.c +++ b/tgt-vvp/stmt_assign.c @@ -1089,7 +1089,8 @@ static int show_stmt_assign_sig_queue(ivl_statement_t net) /* The %store/dar expects the array index to be in index register 3. */ draw_eval_expr_into_integer(mux, 3); - fprintf(vvp_out, " %%store/qdar/vec4 v%p_0, %u;\n", var, idx); + fprintf(vvp_out, " %%store/qdar/vec4 v%p_0, %u, %u;\n", var, idx, + width_of_packed_type(element_type)); } else { fprintf(stderr, "Sorry: I don't know how to handle expr_type=%d " "being assigned to a queue.\n", ivl_expr_type(rval)); diff --git a/tgt-vvp/vvp_process.c b/tgt-vvp/vvp_process.c index 62d6d1c30..d4469eec5 100644 --- a/tgt-vvp/vvp_process.c +++ b/tgt-vvp/vvp_process.c @@ -1767,6 +1767,52 @@ static int show_delete_method(ivl_statement_t net) return 0; } +static int show_insert_method(ivl_statement_t net) +{ + show_stmt_file_line(net, "queue: insert"); + + unsigned parm_count = ivl_stmt_parm_count(net); + if (parm_count != 3) + return 1; + + ivl_expr_t parm0 = ivl_stmt_parm(net,0); + assert(ivl_expr_type(parm0) == IVL_EX_SIGNAL); + ivl_signal_t var = ivl_expr_signal(parm0); + ivl_type_t var_type = ivl_signal_net_type(var); + assert(ivl_type_base(var_type) == IVL_VT_QUEUE); + + int idx = allocate_word(); + assert(idx >= 0); + /* Save the queue maximum index value to an integer register. */ + fprintf(vvp_out, " %%ix/load %u, %u, 0;\n", idx, ivl_signal_array_count(var)); + + ivl_type_t element_type = ivl_type_element(var_type); + + ivl_expr_t parm1 = ivl_stmt_parm(net,1); + /* The %qinsert expects the array index to be in index register 3. */ + draw_eval_expr_into_integer(parm1, 3); + ivl_expr_t parm2 = ivl_stmt_parm(net,2); + switch (ivl_type_base(element_type)) { + case IVL_VT_REAL: + draw_eval_real(parm2); + fprintf(vvp_out, " %%qinsert/real v%p_0, %u;\n", + var, idx); + break; + case IVL_VT_STRING: + draw_eval_string(parm2); + fprintf(vvp_out, " %%qinsert/str v%p_0, %u;\n", + var, idx); + break; + default: + draw_eval_vec4(parm2); + fprintf(vvp_out, " %%qinsert/v v%p_0, %u, %u;\n", + var, idx, + width_of_packed_type(element_type)); + break; + } + return 0; +} + static int show_push_frontback_method(ivl_statement_t net, bool is_front) { const char*type_code; @@ -1826,6 +1872,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_queue_method$insert") == 0) + return show_insert_method(net); + if (strcmp(stmt_name,"$ivl_queue_method$push_front") == 0) return show_push_frontback_method(net, true); diff --git a/vvp/codes.h b/vvp/codes.h index 672352966..a1a71b9a7 100644 --- a/vvp/codes.h +++ b/vvp/codes.h @@ -188,6 +188,9 @@ extern bool of_POP_VEC4(vthread_t thr, vvp_code_t code); extern bool of_POW(vthread_t thr, vvp_code_t code); extern bool of_POW_S(vthread_t thr, vvp_code_t code); extern bool of_POW_WR(vthread_t thr, vvp_code_t code); +extern bool of_QINSERT_REAL(vthread_t thr, vvp_code_t code); +extern bool of_QINSERT_STR(vthread_t thr, vvp_code_t code); +extern bool of_QINSERT_V(vthread_t thr, vvp_code_t code); extern bool of_QPOP_B_REAL(vthread_t thr, vvp_code_t code); extern bool of_QPOP_B_STR(vthread_t thr, vvp_code_t code); extern bool of_QPOP_B_V(vthread_t thr, vvp_code_t code); diff --git a/vvp/compile.cc b/vvp/compile.cc index ed799b0e5..a89312d88 100644 --- a/vvp/compile.cc +++ b/vvp/compile.cc @@ -248,6 +248,9 @@ static const struct opcode_table_s opcode_table[] = { { "%pushi/vec4",of_PUSHI_VEC4,3,{OA_BIT1, OA_BIT2, OA_NUMBER} }, { "%pushv/str", of_PUSHV_STR, 0,{OA_NONE, OA_NONE, OA_NONE} }, { "%putc/str/vec4",of_PUTC_STR_VEC4,2,{OA_FUNC_PTR,OA_BIT1,OA_NONE} }, + { "%qinsert/real",of_QINSERT_REAL,2,{OA_FUNC_PTR,OA_BIT1,OA_NONE} }, + { "%qinsert/str", of_QINSERT_STR, 2,{OA_FUNC_PTR,OA_BIT1,OA_NONE} }, + { "%qinsert/v", of_QINSERT_V, 3,{OA_FUNC_PTR,OA_BIT1,OA_BIT2} }, { "%qpop/b/real",of_QPOP_B_REAL,1,{OA_FUNC_PTR,OA_NONE,OA_NONE} }, { "%qpop/b/str", of_QPOP_B_STR, 1,{OA_FUNC_PTR,OA_NONE,OA_NONE} }, { "%qpop/b/v", of_QPOP_B_V, 2,{OA_FUNC_PTR,OA_BIT1,OA_NONE} }, @@ -286,7 +289,7 @@ static const struct opcode_table_s opcode_table[] = { { "%store/qb/v", of_STORE_QB_V, 3, {OA_FUNC_PTR, OA_BIT1, OA_BIT2} }, { "%store/qdar/r", of_STORE_QDAR_R, 2,{OA_FUNC_PTR,OA_BIT1,OA_NONE} }, { "%store/qdar/str", of_STORE_QDAR_STR, 2,{OA_FUNC_PTR,OA_BIT1,OA_NONE} }, - { "%store/qdar/vec4",of_STORE_QDAR_VEC4,2,{OA_FUNC_PTR,OA_BIT1,OA_NONE} }, + { "%store/qdar/vec4",of_STORE_QDAR_VEC4,3,{OA_FUNC_PTR,OA_BIT1,OA_BIT2} }, { "%store/qf/r", of_STORE_QF_R, 2, {OA_FUNC_PTR, OA_BIT1, OA_NONE} }, { "%store/qf/str", of_STORE_QF_STR, 2, {OA_FUNC_PTR, OA_BIT1, OA_NONE} }, { "%store/qf/v", of_STORE_QF_V, 3, {OA_FUNC_PTR, OA_BIT1, OA_BIT2} }, diff --git a/vvp/vthread.cc b/vvp/vthread.cc index 6adc182e3..c2a3cddf2 100644 --- a/vvp/vthread.cc +++ b/vvp/vthread.cc @@ -5064,6 +5064,80 @@ bool of_PUTC_STR_VEC4(vthread_t thr, vvp_code_t cp) return true; } +/* + * %qinsert/real + */ +bool of_QINSERT_REAL(vthread_t thr, vvp_code_t cp) +{ + int64_t idx = thr->words[3].w_int; + vvp_net_t*net = cp->net; + double value = thr->pop_real(); // Pop the real value to be inserted. + unsigned max_size = thr->words[cp->bit_idx[0]].w_int; + + vvp_queue*queue = get_queue_object(thr, net); + assert(queue); + if (idx < 0) + cerr << "Warning: cannot insert at a negative queue index (" + << idx << "). " << value << " was not added." << endl; + else if (thr->flags[4] != BIT4_0) + cerr << "Warning: cannot insert at an undefined queue index. " + << value << " was not added." << endl; + else + queue->insert(idx, value, max_size); + return true; +} + +/* + * %qinsert/str + */ +bool of_QINSERT_STR(vthread_t thr, vvp_code_t cp) +{ + int64_t idx = thr->words[3].w_int; + vvp_net_t*net = cp->net; + string value = thr->pop_str(); // Pop the string to be stored... + unsigned max_size = thr->words[cp->bit_idx[0]].w_int; + + vvp_queue*queue = get_queue_object(thr, net); + assert(queue); + if (idx < 0) + cerr << "Warning: cannot insert at a negative queue index (" + << idx << "). \"" << value << "\" was not added." << endl; + else if (thr->flags[4] != BIT4_0) + cerr << "Warning: cannot insert at an undefined queue index. \"" + << value << "\" was not added." << endl; + else + queue->insert(idx, value, max_size); + return true; +} + +/* + * %qinsert/v + */ +bool of_QINSERT_V(vthread_t thr, vvp_code_t cp) +{ + int64_t idx = thr->words[3].w_int; + vvp_net_t*net = cp->net; + vvp_vector4_t value = thr->pop_vec4(); // Pop the vector4 value to be store... + unsigned max_size = thr->words[cp->bit_idx[0]].w_int; + unsigned wid = cp->bit_idx[1]; + + assert(value.size() == wid); + + vvp_queue*queue = get_queue_object(thr, net); + assert(queue); + if (idx < 0) + cerr << "Warning: cannot insert at a negative queue index (" << idx << "). " << value + << " was not added." << endl; + else if (thr->flags[4] != BIT4_0) + cerr << "Warning: cannot insert at an undefined queue index. " << value + << " was not added." << endl; + else + queue->insert(idx, value, max_size); + return true; +} + /* * %qpop/b/real */ @@ -5911,7 +5985,6 @@ bool of_STORE_QB_V(vthread_t thr, vvp_code_t cp) unsigned wid = cp->bit_idx[1]; assert(value.size() == wid); - vvp_queue*queue = get_queue_object(thr, net); assert(queue); queue->push_back(value, max_size); @@ -5931,11 +6004,11 @@ bool of_STORE_QDAR_R(vthread_t thr, vvp_code_t cp) vvp_queue*queue = get_queue_object(thr, net); assert(queue); if (adr < 0) - cerr << "Warning: cannot write to a negative queue index (" - << adr << ")." << endl; + cerr << "Warning: cannot assign negative queue index (" + << adr << "). " << value << " was not added." << endl; else if (thr->flags[4] != BIT4_0) - cerr << "Warning: cannot write to an undefined queue index." - << endl; + cerr << "Warning: cannot assign undefined queue index. " + << value << " was not added." << endl; else queue->set_word_max(adr, value, max_size); return true; @@ -5954,11 +6027,11 @@ bool of_STORE_QDAR_STR(vthread_t thr, vvp_code_t cp) vvp_queue*queue = get_queue_object(thr, net); assert(queue); if (adr < 0) - cerr << "Warning: cannot write to a negative queue index (" - << adr << ")." << endl; + cerr << "Warning: cannot assign to a negative queue index (" + << adr << "). \"" << value << "\" was not added." << endl; else if (thr->flags[4] != BIT4_0) - cerr << "Warning: cannot write to an undefined queue index." - << endl; + cerr << "Warning: cannot assign to an undefined queue index. \"" + << value << "\" was not added." << endl; else queue->set_word_max(adr, value, max_size); return true; @@ -5973,15 +6046,19 @@ bool of_STORE_QDAR_VEC4(vthread_t thr, vvp_code_t cp) vvp_vector4_t value = thr->pop_vec4(); // Pop the vector4 value to be store... vvp_net_t*net = cp->net; unsigned max_size = thr->words[cp->bit_idx[0]].w_int; + unsigned wid = cp->bit_idx[1]; + assert(value.size() == wid); vvp_queue*queue = get_queue_object(thr, net); assert(queue); if (adr < 0) - cerr << "Warning: cannot write to a negative queue index (" << adr << ")." << endl; + cerr << "Warning: cannot assign to a negative queue index (" << adr << "). " << value + << " was not added." << endl; else if (thr->flags[4] != BIT4_0) - cerr << "Warning: cannot write to an undefined queue index." << endl; + cerr << "Warning: cannot assign to an undefined queue index. " << value + << " was not added." << endl; else queue->set_word_max(adr, value, max_size); return true; @@ -5997,8 +6074,8 @@ bool of_STORE_QF_R(vthread_t thr, vvp_code_t cp) vvp_net_t*net = cp->net; unsigned max_size = thr->words[cp->bit_idx[0]].w_int; - vvp_queue*dqueue = get_queue_object(thr, net); + vvp_queue*dqueue = get_queue_object(thr, net); assert(dqueue); dqueue->push_front(value, max_size); return true; @@ -6014,8 +6091,8 @@ bool of_STORE_QF_STR(vthread_t thr, vvp_code_t cp) vvp_net_t*net = cp->net; unsigned max_size = thr->words[cp->bit_idx[0]].w_int; - vvp_queue*dqueue = get_queue_object(thr, net); + vvp_queue*dqueue = get_queue_object(thr, net); assert(dqueue); dqueue->push_front(value, max_size); return true; @@ -6033,9 +6110,8 @@ bool of_STORE_QF_V(vthread_t thr, vvp_code_t cp) unsigned max_size = thr->words[cp->bit_idx[0]].w_int; unsigned wid = cp->bit_idx[1]; - vvp_queue*dqueue = get_queue_object(thr, net); - assert(value.size() == wid); + vvp_queue*dqueue = get_queue_object(thr, net); assert(dqueue); dqueue->push_front(value, max_size); return true; diff --git a/vvp/vvp_darray.cc b/vvp/vvp_darray.cc index e626ff2e2..4f7a7d92d 100644 --- a/vvp/vvp_darray.cc +++ b/vvp/vvp_darray.cc @@ -415,6 +415,11 @@ void vvp_queue::set_word_max(unsigned, const vvp_vector4_t&, unsigned) cerr << "XXXX set_word_max(vvp_vector4_t) not implemented for " << typeid(*this).name() << endl; } +void vvp_queue::insert(unsigned, const vvp_vector4_t&, unsigned) +{ + cerr << "XXXX insert(vvp_vector4_t) not implemented for " << typeid(*this).name() << endl; +} + void vvp_queue::push_back(const vvp_vector4_t&, unsigned) { cerr << "XXXX push_back(vvp_vector4_t) not implemented for " << typeid(*this).name() << endl; @@ -430,6 +435,11 @@ void vvp_queue::set_word_max(unsigned, double, unsigned) cerr << "XXXX set_word_max(double) not implemented for " << typeid(*this).name() << endl; } +void vvp_queue::insert(unsigned, double, unsigned) +{ + cerr << "XXXX set_word_max(double) not implemented for " << typeid(*this).name() << endl; +} + void vvp_queue::push_back(double, unsigned) { cerr << "XXXX push_back(double) not implemented for " << typeid(*this).name() << endl; @@ -445,6 +455,11 @@ void vvp_queue::set_word_max(unsigned, const string&, unsigned) cerr << "XXXX set_word_max(string) not implemented for " << typeid(*this).name() << endl; } +void vvp_queue::insert(unsigned, const string&, unsigned) +{ + cerr << "XXXX set_word_max(string) not implemented for " << typeid(*this).name() << endl; +} + void vvp_queue::push_back(const string&, unsigned) { cerr << "XXXX push_back(string) not implemented for " << typeid(*this).name() << endl; @@ -490,6 +505,47 @@ void vvp_queue_real::get_word(unsigned adr, double&value) value = queue[adr]; } +void vvp_queue_real::insert(unsigned idx, double value, unsigned max_size) +{ + // Inserting past the end of the queue + if (idx > queue.size()) + cerr << "Warning: inserting to queue[" << idx << "] is " + "outside of size (" << queue.size() << "). " << value + << " was not added." << endl; + // Inserting at the end + else if (idx == queue.size()) + if (!max_size || (queue.size() < max_size)) + queue.push_back(value); + else + cerr << "Warning: inserting to queue[" << idx << "] is" + " outside bound (" << max_size << "). " << value + << " was not added." << endl; + else { + if (max_size && (queue.size() == max_size)) { + cerr << "Warning: insert("<< idx << ", " << value << ") removed " + << queue.back() << " from already full bounded queue [" + << max_size << "]." << endl; + queue.pop_back(); + } + // Inserting at the beginning + if (idx == 0) + queue.push_front(value); + // Inserting in the middle + else { + std::deque::iterator pos; + unsigned middle = queue.size()/2; + if (idx < middle) { + pos = queue.begin(); + for (unsigned count = 0; count < idx; ++count) ++pos; + } else { + pos = queue.end(); + for (unsigned count = queue.size(); count > idx; --count) --pos; + } + queue.insert(pos, value); + } + } +} + void vvp_queue_real::push_back(double value, unsigned max_size) { if (!max_size || (queue.size() < max_size)) @@ -537,8 +593,8 @@ void vvp_queue_string::set_word_max(unsigned adr, const string&value, unsigned m queue.push_back(value); else cerr << "Warning: assigning to queue[" << adr << "] is" - " outside bound (" << max_size << "). " << value - << " was not added." << endl; + " outside bound (" << max_size << "). \"" << value + << "\" was not added." << endl; else set_word(adr, value); } @@ -549,8 +605,8 @@ void vvp_queue_string::set_word(unsigned adr, const string&value) queue[adr] = value; else cerr << "Warning: assigning to queue[" << adr << "] is outside " - "of size (" << queue.size() << "). " << value - << " was not added." << endl; + "of size (" << queue.size() << "). \"" << value + << "\" was not added." << endl; } void vvp_queue_string::get_word(unsigned adr, string&value) @@ -561,6 +617,47 @@ void vvp_queue_string::get_word(unsigned adr, string&value) value = queue[adr]; } +void vvp_queue_string::insert(unsigned idx, const string&value, unsigned max_size) +{ + // Inserting past the end of the queue + if (idx > queue.size()) + cerr << "Warning: inserting to queue[" << idx << "] is " + "outside of size (" << queue.size() << "). \"" << value + << "\" was not added." << endl; + // Inserting at the end + else if (idx == queue.size()) + if (!max_size || (queue.size() < max_size)) + queue.push_back(value); + else + cerr << "Warning: inserting to queue[" << idx << "] is" + " outside bound (" << max_size << "). \"" << value + << "\" was not added." << endl; + else { + if (max_size && (queue.size() == max_size)) { + cerr << "Warning: insert("<< idx << ", \"" << value << "\") removed \"" + << queue.back() << "\" from already full bounded queue [" + << max_size << "]." << endl; + queue.pop_back(); + } + // Inserting at the beginning + if (idx == 0) + queue.push_front(value); + // Inserting in the middle + else { + std::deque::iterator pos; + unsigned middle = queue.size()/2; + if (idx < middle) { + pos = queue.begin(); + for (unsigned count = 0; count < idx; ++count) ++pos; + } else { + pos = queue.end(); + for (unsigned count = queue.size(); count > idx; --count) --pos; + } + queue.insert(pos, value); + } + } +} + void vvp_queue_string::push_back(const string&value, unsigned max_size) { if (!max_size || (queue.size() < max_size)) @@ -632,6 +729,47 @@ void vvp_queue_vec4::get_word(unsigned adr, vvp_vector4_t&value) value = queue[adr]; } +void vvp_queue_vec4::insert(unsigned idx, const vvp_vector4_t&value, unsigned max_size) +{ + // Inserting past the end of the queue + if (idx > queue.size()) + cerr << "Warning: inserting to queue[" << idx << "] is outside of size (" << queue.size() + << "). " << value << " was not added." << endl; + // Inserting at the end + else if (idx == queue.size()) + if (!max_size || (queue.size() < max_size)) + queue.push_back(value); + else + cerr << "Warning: inserting to queue[" << idx << "] is outside bound (" << max_size + << "). " << value << " was not added." << endl; + else { + if (max_size && (queue.size() == max_size)) { + cerr << "Warning: insert("<< idx << ", " << value << ") removed " + << queue.back() << " from already full bounded queue [" << max_size << "]." << endl; + queue.pop_back(); + } + // Inserting at the beginning + if (idx == 0) + queue.push_front(value); + // Inserting in the middle + else { + std::deque::iterator pos; + unsigned middle = queue.size()/2; + if (idx < middle) { + pos = queue.begin(); + for (unsigned count = 0; count < idx; ++count) ++pos; + } else { + pos = queue.end(); + for (unsigned count = queue.size(); count > idx; --count) --pos; + } + queue.insert(pos, value); + } + } +} + void vvp_queue_vec4::push_back(const vvp_vector4_t&value, unsigned max_size) { if (!max_size || (queue.size() < max_size)) diff --git a/vvp/vvp_darray.h b/vvp/vvp_darray.h index bb6e1e193..d0d40e9b1 100644 --- a/vvp/vvp_darray.h +++ b/vvp/vvp_darray.h @@ -155,14 +155,17 @@ class vvp_queue : public vvp_darray { ~vvp_queue(); virtual void set_word_max(unsigned adr, const vvp_vector4_t&value, unsigned max_size); + virtual void insert(unsigned idx, const vvp_vector4_t&value, unsigned max_size); virtual void push_back(const vvp_vector4_t&value, unsigned max_size); virtual void push_front(const vvp_vector4_t&value, unsigned max_size); virtual void set_word_max(unsigned adr, double value, unsigned max_size); + virtual void insert(unsigned idx, double value, unsigned max_size); virtual void push_back(double value, unsigned max_size); virtual void push_front(double value, unsigned max_size); virtual void set_word_max(unsigned adr, const std::string&value, unsigned max_size); + virtual void insert(unsigned idx, const std::string&value, unsigned max_size); virtual void push_back(const std::string&value, unsigned max_size); virtual void push_front(const std::string&value, unsigned max_size); @@ -180,6 +183,7 @@ class vvp_queue_real : public vvp_queue { void set_word_max(unsigned adr, double value, unsigned max_size); void set_word(unsigned adr, double value); void get_word(unsigned adr, double&value); + void insert(unsigned idx, double value, unsigned max_size); void push_back(double value, unsigned max_size); void push_front(double value, unsigned max_size); void pop_back(void) { queue.pop_back(); }; @@ -199,6 +203,7 @@ class vvp_queue_string : public vvp_queue { void set_word_max(unsigned adr, const std::string&value, unsigned max_size); void set_word(unsigned adr, const std::string&value); void get_word(unsigned adr, std::string&value); + void insert(unsigned idx, const std::string&value, unsigned max_size); void push_back(const std::string&value, unsigned max_size); void push_front(const std::string&value, unsigned max_size); void pop_back(void) { queue.pop_back(); }; @@ -218,6 +223,7 @@ class vvp_queue_vec4 : public vvp_queue { void set_word_max(unsigned adr, const vvp_vector4_t&value, unsigned max_size); void set_word(unsigned adr, const vvp_vector4_t&value); void get_word(unsigned adr, vvp_vector4_t&value); + void insert(unsigned idx, const vvp_vector4_t&value, unsigned max_size); void push_back(const vvp_vector4_t&value, unsigned max_size); void push_front(const vvp_vector4_t&value, unsigned max_size); void pop_back(void) { queue.pop_back(); };