diff --git a/tgt-vvp/stmt_assign.c b/tgt-vvp/stmt_assign.c index 1b504ae96..f87fe8708 100644 --- a/tgt-vvp/stmt_assign.c +++ b/tgt-vvp/stmt_assign.c @@ -1063,6 +1063,11 @@ static int show_stmt_assign_sig_queue(ivl_statement_t net) 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)); + if (ivl_expr_type(rval) == IVL_EX_NULL) { errors += draw_eval_object(rval); fprintf(vvp_out, " %%store/obj v%p_0;\n", var); @@ -1071,20 +1076,20 @@ 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/dar/r v%p_0;\n", var); + fprintf(vvp_out, " %%store/qdar/r v%p_0, %u;\n", var, idx); } else if (mux && ivl_type_base(element_type)==IVL_VT_STRING) { draw_eval_string(rval); /* The %store/dar expects the array index to be in index register 3. */ draw_eval_expr_into_integer(mux, 3); - fprintf(vvp_out, " %%store/dar/str v%p_0;\n", var); + fprintf(vvp_out, " %%store/qdar/str v%p_0, %u;\n", var, idx); } else if (mux) { // What is left must be some form of vector draw_eval_vec4(rval); resize_vec4_wid(rval, ivl_stmt_lwidth(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/dar/vec4 v%p_0;\n", var); + fprintf(vvp_out, " %%store/qdar/vec4 v%p_0, %u;\n", var, idx); } else { fprintf(stderr, "Sorry: I don't know how to handle expr_type=%d " "being assigned to a queue.\n", ivl_expr_type(rval)); @@ -1092,6 +1097,7 @@ static int show_stmt_assign_sig_queue(ivl_statement_t net) "expr_type=%d.\n", ivl_expr_type(rval)); errors += 1; } + clr_word(idx); // FIXME #if 0 static int show_stmt_assign_sig_darray(ivl_statement_t net) diff --git a/tgt-vvp/vvp_process.c b/tgt-vvp/vvp_process.c index 6ffc12e2d..62d6d1c30 100644 --- a/tgt-vvp/vvp_process.c +++ b/tgt-vvp/vvp_process.c @@ -1792,7 +1792,6 @@ static int show_push_frontback_method(ivl_statement_t net, bool is_front) 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)); - fprintf(vvp_out, " %%flag_set/imm 4, 0;\n"); ivl_type_t element_type = ivl_type_element(var_type); diff --git a/vvp/codes.h b/vvp/codes.h index 77a746954..672352966 100644 --- a/vvp/codes.h +++ b/vvp/codes.h @@ -228,6 +228,9 @@ extern bool of_STORE_DAR_VEC4(vthread_t thr, vvp_code_t code); extern bool of_STORE_QB_R(vthread_t thr, vvp_code_t code); extern bool of_STORE_QB_STR(vthread_t thr, vvp_code_t code); extern bool of_STORE_QB_V(vthread_t thr, vvp_code_t code); +extern bool of_STORE_QDAR_R(vthread_t thr, vvp_code_t code); +extern bool of_STORE_QDAR_STR(vthread_t thr, vvp_code_t code); +extern bool of_STORE_QDAR_VEC4(vthread_t thr, vvp_code_t code); extern bool of_STORE_QF_R(vthread_t thr, vvp_code_t code); extern bool of_STORE_QF_STR(vthread_t thr, vvp_code_t code); extern bool of_STORE_QF_V(vthread_t thr, vvp_code_t code); diff --git a/vvp/compile.cc b/vvp/compile.cc index 2a065b222..ed799b0e5 100644 --- a/vvp/compile.cc +++ b/vvp/compile.cc @@ -284,6 +284,9 @@ static const struct opcode_table_s opcode_table[] = { { "%store/qb/r", of_STORE_QB_R, 2, {OA_FUNC_PTR, OA_BIT1, OA_NONE} }, { "%store/qb/str", of_STORE_QB_STR, 2, {OA_FUNC_PTR, OA_BIT1, OA_NONE} }, { "%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/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 370a69348..0701145d8 100644 --- a/vvp/vthread.cc +++ b/vvp/vthread.cc @@ -3720,6 +3720,9 @@ bool of_LOAD_DAR_R(vthread_t thr, vvp_code_t cp) return true; } +/* + * %load/dar/str ; + */ bool of_LOAD_DAR_STR(vthread_t thr, vvp_code_t cp) { int64_t adr = thr->words[3].w_int; @@ -3742,6 +3745,9 @@ bool of_LOAD_DAR_STR(vthread_t thr, vvp_code_t cp) return true; } +/* + * %load/dar/vec4 ; + */ bool of_LOAD_DAR_VEC4(vthread_t thr, vvp_code_t cp) { int64_t adr = thr->words[3].w_int; @@ -5645,15 +5651,12 @@ bool of_SPLIT_VEC4(vthread_t thr, vvp_code_t cp) /* * %store/dar/real - * In this case, is the name of a dynamic array. Signed index - * register 3 contains the index into the dynamic array. */ bool of_STORE_DAR_R(vthread_t thr, vvp_code_t cp) { int64_t adr = thr->words[3].w_int; double value = thr->pop_real(); // Pop the real value to store... vvp_net_t*net = cp->net; - unsigned max_size = 0; // FIXME: Need to get this from the compile and how to pass to set_word() assert(net); vvp_fun_signal_object*obj = dynamic_cast (net->fun); @@ -5669,28 +5672,21 @@ bool of_STORE_DAR_R(vthread_t thr, vvp_code_t cp) << endl; else if (darray) darray->set_word(adr, value); - else { - vvp_queue*queue = get_queue_object(thr, net); - if (queue) - queue->push_front(value, max_size); - else - cerr << "Warning: cannot write to an undefined array." - << endl; - } + else + cerr << "Warning: cannot write to an undefined array." + << endl; + return true; } /* * %store/dar/str - * In this case, is the name of a dynamic array. Signed index - * register 3 contains the index into the dynamic array. */ bool of_STORE_DAR_STR(vthread_t thr, vvp_code_t cp) { int64_t adr = thr->words[3].w_int; string value = thr->pop_str(); // Pop the string to be stored... vvp_net_t*net = cp->net; - unsigned max_size = 0; // FIXME: Need to get this from the compile and how to pass to set_word() assert(net); vvp_fun_signal_object*obj = dynamic_cast (net->fun); @@ -5706,29 +5702,21 @@ bool of_STORE_DAR_STR(vthread_t thr, vvp_code_t cp) << endl; else if (darray) darray->set_word(adr, value); - else { - vvp_queue*queue = get_queue_object(thr, net); - if (queue) - queue->push_front(value, max_size); - else - cerr << "Warning: cannot write to an undefined array." - << endl; - } + else + cerr << "Warning: cannot write to an undefined array." + << endl; + return true; } - /* * %store/dar/vec4 - * In this case, is the name of a dynamic array. Signed index - * register 3 contains the index into the dynamic array. */ bool of_STORE_DAR_VEC4(vthread_t thr, vvp_code_t cp) { int64_t adr = thr->words[3].w_int; - vvp_vector4_t value = thr->pop_vec4(); // Pop the real value to be store... + vvp_vector4_t value = thr->pop_vec4(); // Pop the vector4 value to be store... vvp_net_t*net = cp->net; - unsigned max_size = 0; // FIXME: Need to get this from the compile and how to pass to set_word() assert(net); vvp_fun_signal_object*obj = dynamic_cast (net->fun); @@ -5744,14 +5732,10 @@ bool of_STORE_DAR_VEC4(vthread_t thr, vvp_code_t cp) << value.size() << "]> index." << endl; else if (darray) darray->set_word(adr, value); - else { - vvp_queue*queue = get_queue_object(thr, net); - if (queue) - queue->push_front(value, max_size); - else - cerr << "Warning: cannot write to an undefined array." << endl; - } + else + cerr << "Warning: cannot write to an undefined array." << endl; + return true; } @@ -5890,10 +5874,10 @@ bool of_STORE_QB_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); - assert(dqueue); - dqueue->push_back(value, max_size); + vvp_queue*queue = get_queue_object(thr, net); + assert(queue); + queue->push_back(value, max_size); return true; } @@ -5907,10 +5891,10 @@ bool of_STORE_QB_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); - assert(dqueue); - dqueue->push_back(value, max_size); + vvp_queue*queue = get_queue_object(thr, net); + assert(queue); + queue->push_back(value, max_size); return true; } @@ -5928,13 +5912,80 @@ bool of_STORE_QB_V(vthread_t thr, vvp_code_t cp) assert(value.size() == wid); - vvp_queue*dqueue = get_queue_object(thr, net); - - assert(dqueue); - dqueue->push_back(value, max_size); + vvp_queue*queue = get_queue_object(thr, net); + assert(queue); + queue->push_back(value, max_size); return true; } +/* + * %store/qdar/real , idx + */ +bool of_STORE_QDAR_R(vthread_t thr, vvp_code_t cp) +{ + int64_t adr = thr->words[3].w_int; + double value = thr->pop_real(); // Pop the real value to store... + vvp_net_t*net = cp->net; + unsigned max_size = thr->words[cp->bit_idx[0]].w_int; + + vvp_queue*queue = get_queue_object(thr, net); + assert(queue); + if (adr < 0) + cerr << "Warning: cannot write to a negative queue index (" + << adr << ")." << endl; + else if (thr->flags[4] != BIT4_0) + cerr << "Warning: cannot write to an undefined queue index." + << endl; + else + queue->set_word(adr, value, max_size); + return true; +} + +/* + * %store/qdar/str , idx + */ +bool of_STORE_QDAR_STR(vthread_t thr, vvp_code_t cp) +{ + int64_t adr = thr->words[3].w_int; + string value = thr->pop_str(); // Pop the string to be stored... + vvp_net_t*net = cp->net; + unsigned max_size = thr->words[cp->bit_idx[0]].w_int; + + vvp_queue*queue = get_queue_object(thr, net); + assert(queue); + if (adr < 0) + cerr << "Warning: cannot write to a negative queue index (" + << adr << ")." << endl; + else if (thr->flags[4] != BIT4_0) + cerr << "Warning: cannot write to an undefined queue index." + << endl; + else + queue->set_word(adr, value, max_size); + return true; +} + +/* + * %store/qdar/vec4 , idx + */ +bool of_STORE_QDAR_VEC4(vthread_t thr, vvp_code_t cp) +{ + int64_t adr = thr->words[3].w_int; + 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; + + vvp_queue*queue = get_queue_object(thr, net); + assert(queue); + if (adr < 0) + cerr << "Warning: cannot write to a negative queue index (" << adr << ")." << endl; + else if (thr->flags[4] != BIT4_0) + cerr << "Warning: cannot write to an undefined queue index." << endl; + else + queue->set_word(adr, value, max_size); + return true; +} /* * %store/qf/r , diff --git a/vvp/vvp_darray.cc b/vvp/vvp_darray.cc index 25fde59e4..166459b9e 100644 --- a/vvp/vvp_darray.cc +++ b/vvp/vvp_darray.cc @@ -410,6 +410,11 @@ vvp_queue::~vvp_queue() { } +void vvp_queue::set_word(unsigned, const vvp_vector4_t&, unsigned) +{ + cerr << "XXXX set_word(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; @@ -420,6 +425,11 @@ void vvp_queue::push_front(const vvp_vector4_t&, unsigned) cerr << "XXXX push_front(vvp_vector4_t) not implemented for " << typeid(*this).name() << endl; } +void vvp_queue::set_word(unsigned, double, unsigned) +{ + cerr << "XXXX set_word(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; @@ -430,6 +440,11 @@ void vvp_queue::push_front(double, unsigned) cerr << "XXXX push_front(double) not implemented for " << typeid(*this).name() << endl; } +void vvp_queue::set_word(unsigned, const string&, unsigned) +{ + cerr << "XXXX set_word(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; @@ -444,9 +459,8 @@ vvp_queue_real::~vvp_queue_real() { } -void vvp_queue_real::set_word(unsigned adr, double value) +void vvp_queue_real::set_word(unsigned adr, double value, unsigned max_size) { - unsigned max_size = 0; // FIXME: need to get this from the compiler; bounded queues will fail if (adr < queue.size()) queue[adr] = value; else if (adr == queue.size()) @@ -505,9 +519,8 @@ vvp_queue_string::~vvp_queue_string() { } -void vvp_queue_string::set_word(unsigned adr, const string&value) +void vvp_queue_string::set_word(unsigned adr, const string&value, unsigned max_size) { - unsigned max_size = 0; // FIXME: need to get this from the compiler; bounded queues will fail if (adr < queue.size()) queue[adr] = value; else if (adr == queue.size()) @@ -566,9 +579,8 @@ vvp_queue_vec4::~vvp_queue_vec4() { } -void vvp_queue_vec4::set_word(unsigned adr, const vvp_vector4_t&value) +void vvp_queue_vec4::set_word(unsigned adr, const vvp_vector4_t&value, unsigned max_size) { - unsigned max_size = 0; // FIXME: need to get this from the compiler; bounded queues will fail if (adr < queue.size()) queue[adr] = value; else if (adr == queue.size()) diff --git a/vvp/vvp_darray.h b/vvp/vvp_darray.h index b58322127..015dc6deb 100644 --- a/vvp/vvp_darray.h +++ b/vvp/vvp_darray.h @@ -154,12 +154,15 @@ class vvp_queue : public vvp_darray { inline vvp_queue(void) { } ~vvp_queue(); + virtual void set_word(unsigned adr, 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(unsigned adr, 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(unsigned adr, 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); @@ -174,7 +177,7 @@ class vvp_queue_real : public vvp_queue { ~vvp_queue_real(); size_t get_size(void) const { return queue.size(); }; - void set_word(unsigned adr, double value); + void set_word(unsigned adr, double value, unsigned max_size); void get_word(unsigned adr, double&value); void push_back(double value, unsigned max_size); void push_front(double value, unsigned max_size); @@ -192,7 +195,7 @@ class vvp_queue_string : public vvp_queue { ~vvp_queue_string(); size_t get_size(void) const { return queue.size(); }; - void set_word(unsigned adr, const std::string&value); + void set_word(unsigned adr, const std::string&value, unsigned max_size); void get_word(unsigned adr, std::string&value); void push_back(const std::string&value, unsigned max_size); void push_front(const std::string&value, unsigned max_size); @@ -210,7 +213,7 @@ class vvp_queue_vec4 : public vvp_queue { ~vvp_queue_vec4(); size_t get_size(void) const { return queue.size(); }; - void set_word(unsigned adr, const vvp_vector4_t&value); + void set_word(unsigned adr, const vvp_vector4_t&value, unsigned max_size); void get_word(unsigned adr, vvp_vector4_t&value); void push_back(const vvp_vector4_t&value, unsigned max_size); void push_front(const vvp_vector4_t&value, unsigned max_size);