diff --git a/tgt-vvp/eval_vec4.c b/tgt-vvp/eval_vec4.c index 2dc4d461b..233bd627d 100644 --- a/tgt-vvp/eval_vec4.c +++ b/tgt-vvp/eval_vec4.c @@ -738,7 +738,8 @@ static void draw_select_vec4(ivl_expr_t expr) if (ivl_expr_value(subexpr)==IVL_VT_DARRAY) { ivl_signal_t sig = ivl_expr_signal(subexpr); assert(sig); - assert(ivl_signal_data_type(sig)==IVL_VT_DARRAY); + assert( (ivl_signal_data_type(sig)==IVL_VT_DARRAY) + || (ivl_signal_data_type(sig)==IVL_VT_QUEUE) ); assert(base); draw_eval_expr_into_integer(base, 3); @@ -773,6 +774,27 @@ static void draw_select_pad_vec4(ivl_expr_t expr, int stuff_ok_flag) fprintf(vvp_out, " %%pad/u %u;\n", wid); } +/* + * This function handles the speical case of a call to the internal + * functions $ivl_darray_method$pop_back et al. The first (and only) + * argument is the signal that represents a dynamic queue. Generate a + * %qpop instruction to pop a value and push it to the vec4 stack. + */ +static void draw_darray_pop(ivl_expr_t expr) +{ + const char*fb; + + if (strcmp(ivl_expr_name(expr), "$ivl_darray_method$pop_back")==0) + fb = "b"; + else + fb = "f"; + + ivl_expr_t arg = ivl_expr_parm(expr, 0); + assert(ivl_expr_type(arg) == IVL_EX_SIGNAL); + + fprintf(vvp_out, " %%qpop/%s/v v%p_0;\n", fb, ivl_expr_signal(arg)); +} + static void draw_sfunc_vec4(ivl_expr_t expr) { unsigned parm_count = ivl_expr_parms(expr); @@ -790,6 +812,15 @@ static void draw_sfunc_vec4(ivl_expr_t expr) return; } + if (strcmp(ivl_expr_name(expr), "$ivl_darray_method$pop_back")==0) { + draw_darray_pop(expr); + return; + } + if (strcmp(ivl_expr_name(expr),"$ivl_darray_method$pop_front")==0) { + draw_darray_pop(expr); + return; + } + draw_vpi_func_call(expr); } diff --git a/tgt-vvp/vvp_process.c b/tgt-vvp/vvp_process.c index 7f0b5bfa8..cac3e19a0 100644 --- a/tgt-vvp/vvp_process.c +++ b/tgt-vvp/vvp_process.c @@ -1823,7 +1823,6 @@ static int show_push_frontback_method(ivl_statement_t net) ivl_type_t element_type = ivl_type_element(var_type); ivl_expr_t parm1 = ivl_stmt_parm(net,1); - struct vector_info vec; switch (ivl_type_base(element_type)) { case IVL_VT_REAL: draw_eval_real(parm1); @@ -1834,10 +1833,9 @@ static int show_push_frontback_method(ivl_statement_t net) fprintf(vvp_out, " %%store/%s/str v%p_0;\n", type_code, var); break; default: - vec = draw_eval_expr_wid(parm1, width_of_packed_type(element_type), STUFF_OK_RO); - fprintf(vvp_out, " %%set/%s v%p_0, %u, %u;\n", - type_code, var, vec.base, vec.wid); - if (vec.base >= 4) clr_vector(vec); + draw_eval_vec4(parm1, STUFF_OK_XZ); + fprintf(vvp_out, " %%store/%s/v v%p_0, %u;\n", + type_code, var, width_of_packed_type(element_type)); break; } diff --git a/vvp/codes.h b/vvp/codes.h index 38735fcae..e61356385 100644 --- a/vvp/codes.h +++ b/vvp/codes.h @@ -186,10 +186,10 @@ 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_QPOP_B(vthread_t thr, vvp_code_t code); -extern bool of_QPOP_F(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); extern bool of_QPOP_F_STR(vthread_t thr, vvp_code_t code); +extern bool of_QPOP_F_V(vthread_t thr, vvp_code_t code); extern bool of_PROP_OBJ(vthread_t thr, vvp_code_t code); extern bool of_PROP_R(vthread_t thr, vvp_code_t code); extern bool of_PROP_STR(vthread_t thr, vvp_code_t code); @@ -223,8 +223,10 @@ extern bool of_STORE_DAR_STR(vthread_t thr, vvp_code_t code); 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_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); extern bool of_STORE_OBJ(vthread_t thr, vvp_code_t code); extern bool of_STORE_OBJA(vthread_t thr, vvp_code_t code); extern bool of_STORE_PROP_OBJ(vthread_t thr, vvp_code_t code); diff --git a/vvp/compile.cc b/vvp/compile.cc index b03af1878..08207ddae 100644 --- a/vvp/compile.cc +++ b/vvp/compile.cc @@ -243,10 +243,10 @@ 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, 2, {OA_BIT1,OA_BIT2, OA_NONE} }, { "%putc/str/vec4",of_PUTC_STR_VEC4,2,{OA_FUNC_PTR,OA_BIT1,OA_NONE} }, - { "%qpop/b", of_QPOP_B, 3,{OA_FUNC_PTR,OA_BIT1, OA_BIT2} }, { "%qpop/b/str",of_QPOP_B_STR,1,{OA_FUNC_PTR,OA_NONE, OA_NONE} }, - { "%qpop/f", of_QPOP_F, 3,{OA_FUNC_PTR,OA_BIT1, OA_BIT2} }, + { "%qpop/b/v", of_QPOP_B_V, 1,{OA_FUNC_PTR,OA_NONE, OA_BIT2} }, { "%qpop/f/str",of_QPOP_F_STR,1,{OA_FUNC_PTR,OA_NONE, OA_NONE} }, + { "%qpop/f/v", of_QPOP_F_V, 1,{OA_FUNC_PTR,OA_NONE, OA_BIT2} }, { "%release/net",of_RELEASE_NET,3,{OA_FUNC_PTR,OA_BIT1,OA_BIT2} }, { "%release/reg",of_RELEASE_REG,3,{OA_FUNC_PTR,OA_BIT1,OA_BIT2} }, { "%release/wr", of_RELEASE_WR, 2,{OA_FUNC_PTR,OA_BIT1,OA_NONE} }, @@ -276,8 +276,10 @@ static const struct opcode_table_s opcode_table[] = { { "%store/prop/v", of_STORE_PROP_V, 2, {OA_NUMBER, OA_BIT1, OA_NONE} }, { "%store/qb/r", of_STORE_QB_R, 1, {OA_FUNC_PTR, OA_NONE, OA_NONE} }, { "%store/qb/str", of_STORE_QB_STR, 1, {OA_FUNC_PTR, OA_NONE, OA_NONE} }, + { "%store/qb/v", of_STORE_QB_V, 2, {OA_FUNC_PTR, OA_BIT1, OA_NONE} }, { "%store/qf/r", of_STORE_QF_R, 1, {OA_FUNC_PTR, OA_NONE, OA_NONE} }, { "%store/qf/str", of_STORE_QF_STR, 1, {OA_FUNC_PTR, OA_NONE, OA_NONE} }, + { "%store/qf/v", of_STORE_QF_V, 2, {OA_FUNC_PTR, OA_BIT1, OA_NONE} }, { "%store/real", of_STORE_REAL, 1, {OA_FUNC_PTR,OA_NONE, OA_NONE} }, { "%store/reala", of_STORE_REALA, 2, {OA_ARR_PTR, OA_BIT1, OA_NONE} }, { "%store/str", of_STORE_STR, 1, {OA_FUNC_PTR,OA_NONE, OA_NONE} }, diff --git a/vvp/opcodes.txt b/vvp/opcodes.txt index 1be613dd8..fb22b4a40 100644 --- a/vvp/opcodes.txt +++ b/vvp/opcodes.txt @@ -1102,6 +1102,11 @@ character of the string variable at . This is basically an implementation of .putc(, ) where is the 8bit vector popped from the stack. +* %qpop/b/v +* %qpop/f/v + +Pop values from a dynamic queue object. + * %release/net , , * %release/reg , , @@ -1266,8 +1271,10 @@ index in the index register * %store/dar/vec4 * %store/qf/r * %store/qf/str +* %store/qf/v , * %store/qb/r * %store/qb/str +* %store/qf/v , The %store/str instruction pops the top of the string stack and writes it to the string variable. diff --git a/vvp/vthread.cc b/vvp/vthread.cc index 4ee00bab1..484b6e581 100644 --- a/vvp/vthread.cc +++ b/vvp/vthread.cc @@ -388,6 +388,30 @@ const vvp_vector4_t& vthread_get_vec4_stack(struct vthread_s*thr, unsigned depth return thr->peek_vec4(depth); } +/* + * This is a function to get a vvp_queue handle from the variable + * referenced by "net". If the queue is nil, then allocated it and + * assign the value to the net. Note that this function is + * parameterized by the queue type so that we can create the right + * derived type of queue object. + */ +template static vvp_queue*get_queue_object(vthread_t thr, vvp_net_t*net) +{ + vvp_fun_signal_object*obj = dynamic_cast (net->fun); + assert(obj); + + vvp_queue*dqueue = obj->get_object().peek(); + if (dqueue == 0) { + assert(obj->get_object().test_nil()); + dqueue = new VVP_QUEUE; + vvp_object_t val (dqueue); + vvp_net_ptr_t ptr (net, 0); + vvp_send_object(ptr, val, thr->wt_context); + } + + return dqueue; +} + template T coerce_to_width(const T&that, unsigned width) { if (that.size() == width) @@ -5441,75 +5465,11 @@ bool of_PUTC_STR_VEC4(vthread_t thr, vvp_code_t cp) return true; } -/* - * %qpop/b , , - */ -bool of_QPOP_B(vthread_t thr, vvp_code_t cp) -{ - unsigned bit = cp->bit_idx[0]; - unsigned wid = cp->bit_idx[1]; - - vvp_net_t*net = cp->net; - vvp_fun_signal_object*obj = dynamic_cast (net->fun); - assert(obj); - - vvp_queue*dqueue = obj->get_object().peek(); - assert(dqueue); - - size_t size = dqueue->get_size(); - assert(size > 0); - - vvp_vector4_t value; - dqueue->get_word(size-1, value); - dqueue->pop_back(); - - assert(value.size() == wid); -#if 0 - thr->bits4.set_vec(bit, value); -#else - fprintf(stderr, "%%qpop/b