diff --git a/vvp/vpi_tasks.cc b/vvp/vpi_tasks.cc index d48bee952..27da387da 100644 --- a/vvp/vpi_tasks.cc +++ b/vvp/vpi_tasks.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001-2014 Stephen Williams (steve@icarus.com) + * Copyright (c) 2001-2020 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU @@ -974,13 +974,13 @@ void vpip_execute_vpi_call(vthread_t thr, vpiHandle ref) /* If the function returns a value, then push the value to the appropriate thread stack. */ if (sysfunc_real*func_real = dynamic_cast(ref)) { - vthread_push_real(thr, func_real->return_value()); + vthread_push(thr, func_real->return_value()); } else if (sysfunc_str*func_string = dynamic_cast(ref)) { - vthread_push_str(thr, func_string->return_value()); + vthread_push(thr, func_string->return_value()); } else if (sysfunc_vec4*func_vec4 = dynamic_cast(ref)) { - vthread_push_vec4(thr, func_vec4->return_value()); + vthread_push(thr, func_vec4->return_value()); } vpip_cur_task = 0; } diff --git a/vvp/vthread.cc b/vvp/vthread.cc index d83dd2320..df3dfc2ca 100644 --- a/vvp/vthread.cc +++ b/vvp/vthread.cc @@ -388,24 +388,19 @@ string get_fileline() return running_thread->get_fileline(); } -void vthread_push_vec4(struct vthread_s*thr, const vvp_vector4_t&val) -{ - thr->push_vec4(val); -} - -void vthread_push_real(struct vthread_s*thr, double val) +void vthread_push(struct vthread_s*thr, double val) { thr->push_real(val); } -void vthread_push_str(struct vthread_s*thr, const string&val) +void vthread_push(struct vthread_s*thr, const string&val) { thr->push_str(val); } -void vthread_pop_vec4(struct vthread_s*thr, unsigned depth) +void vthread_push(struct vthread_s*thr, const vvp_vector4_t&val) { - thr->pop_vec4(depth); + thr->push_vec4(val); } void vthread_pop_real(struct vthread_s*thr, unsigned depth) @@ -418,9 +413,9 @@ void vthread_pop_str(struct vthread_s*thr, unsigned depth) thr->pop_str(depth); } -const string&vthread_get_str_stack(struct vthread_s*thr, unsigned depth) +void vthread_pop_vec4(struct vthread_s*thr, unsigned depth) { - return thr->peek_str(depth); + thr->pop_vec4(depth); } double vthread_get_real_stack(struct vthread_s*thr, unsigned depth) @@ -428,6 +423,11 @@ double vthread_get_real_stack(struct vthread_s*thr, unsigned depth) return thr->peek_real(depth); } +const string&vthread_get_str_stack(struct vthread_s*thr, unsigned depth) +{ + return thr->peek_str(depth); +} + const vvp_vector4_t& vthread_get_vec4_stack(struct vthread_s*thr, unsigned depth) { return thr->peek_vec4(depth); @@ -464,23 +464,22 @@ template static vvp_queue*get_queue_object(vthread_t thr, vvp_ * The following are used to allow a common template to be written for * queue real/string/vec4 operations */ -inline static void pop_value(double&value, vthread_t thr, unsigned) +inline static void pop_value(vthread_t thr, double&value, unsigned) { value = thr->pop_real(); } -inline static void pop_value(string&value, vthread_t thr, unsigned) +inline static void pop_value(vthread_t thr, string&value, unsigned) { value = thr->pop_str(); } -inline static void pop_value(vvp_vector4_t&value, vthread_t thr, unsigned wid) +inline static void pop_value(vthread_t thr, vvp_vector4_t&value, unsigned wid) { value = thr->pop_vec4(); assert(value.size() == wid); } - /* * The following are used to allow the queue templates to print correctly. */ @@ -517,6 +516,25 @@ inline static void print_queue_value(vvp_vector4_t value) cerr << value; } +/* + * The following are used to get a darray/queue default value. + */ +inline static void dq_default(double&value, unsigned) +{ + value = 0.0; +} + +inline static void dq_default(string&value, unsigned) +{ + value = ""; +} + +inline static void dq_default(vvp_vector4_t&value, unsigned wid) +{ + value = vvp_vector4_t(wid); +} + + template T coerce_to_width(const T&that, unsigned width) { if (that.size() == width) @@ -3816,54 +3834,43 @@ bool of_LOAD_AR(vthread_t thr, vvp_code_t cp) return true; } -/* - * %load/dar/r ; - */ -bool of_LOAD_DAR_R(vthread_t thr, vvp_code_t cp) +template +static bool load_dar(vthread_t thr, vvp_code_t cp) { int64_t adr = thr->words[3].w_int; vvp_net_t*net = cp->net; - assert(net); + vvp_fun_signal_object*obj = dynamic_cast (net->fun); assert(obj); vvp_darray*darray = obj->get_object().peek(); - double word; + ELEM word; if (darray && (adr >= 0) && (thr->flags[4] == BIT4_0)) // A defined address >= 0 darray->get_word(adr, word); else - word = 0.0; + dq_default(word, obj->size()); - thr->push_real(word); + vthread_push(thr, word); return true; } +/* + * %load/dar/r ; + */ +bool of_LOAD_DAR_R(vthread_t thr, vvp_code_t cp) +{ + return load_dar(thr, cp); +} + /* * %load/dar/str ; */ bool of_LOAD_DAR_STR(vthread_t thr, vvp_code_t cp) { - int64_t adr = thr->words[3].w_int; - vvp_net_t*net = cp->net; - - assert(net); - vvp_fun_signal_object*obj = dynamic_cast (net->fun); - assert(obj); - - vvp_darray*darray = obj->get_object().peek(); - - string word; - if (darray && - (adr >= 0) && (thr->flags[4] == BIT4_0)) // A defined address >= 0 - darray->get_word(adr, word); - else - word = ""; - - thr->push_str(word); - return true; + return load_dar(thr, cp); } /* @@ -3871,24 +3878,7 @@ bool of_LOAD_DAR_STR(vthread_t thr, vvp_code_t cp) */ bool of_LOAD_DAR_VEC4(vthread_t thr, vvp_code_t cp) { - int64_t adr = thr->words[3].w_int; - vvp_net_t*net = cp->net; - - assert(net); - vvp_fun_signal_object*obj = dynamic_cast (net->fun); - assert(obj); - - vvp_darray*darray = obj->get_object().peek(); - - vvp_vector4_t word; - if (darray && - (adr >= 0) && (thr->flags[4] == BIT4_0)) // A defined address >= 0 - darray->get_word(adr, word); - else - word = vvp_vector4_t(obj->size()); - - thr->push_vec4(word); - return true; + return load_dar(thr, cp); } /* @@ -5193,7 +5183,7 @@ static bool qinsert(vthread_t thr, vvp_code_t cp, unsigned wid=0) ELEM value; vvp_net_t*net = cp->net; unsigned max_size = thr->words[cp->bit_idx[0]].w_int; - pop_value(value, thr, wid); // Pop the value to store. + pop_value(thr, value, wid); // Pop the value to store. vvp_queue*queue = get_queue_object(thr, net); assert(queue); @@ -5242,21 +5232,6 @@ bool of_QINSERT_V(vthread_t thr, vvp_code_t cp) /* * Helper functions used in the queue pop templates */ -inline static void qdefault(double&value, unsigned) -{ - value = 0.0; -} - -inline static void qdefault(string&value, unsigned) -{ - value = ""; -} - -inline static void qdefault(vvp_vector4_t&value, unsigned wid) -{ - value = vvp_vector4_t(wid); -} - inline void push_value(vthread_t thr, double value, unsigned) { thr->push_real(value); @@ -5289,7 +5264,7 @@ static bool q_pop(vthread_t thr, vvp_code_t cp, if (size) { get_val_func(queue, value); } else { - qdefault(value, wid); + dq_default(value, wid); cerr << thr->get_fileline() << "Warning: pop_" << loc << "() on empty " << get_queue_type(value) << "." << endl; @@ -6033,7 +6008,7 @@ static bool store_qb(vthread_t thr, vvp_code_t cp, unsigned wid=0) ELEM value; vvp_net_t*net = cp->net; unsigned max_size = thr->words[cp->bit_idx[0]].w_int; - pop_value(value, thr, wid); // Pop the value to store. + pop_value(thr, value, wid); // Pop the value to store. vvp_queue*queue = get_queue_object(thr, net); assert(queue); @@ -6072,7 +6047,7 @@ static bool store_qdar(vthread_t thr, vvp_code_t cp, unsigned wid=0) ELEM value; vvp_net_t*net = cp->net; unsigned max_size = thr->words[cp->bit_idx[0]].w_int; - pop_value(value, thr, wid); // Pop the value to store. + pop_value(thr, value, wid); // Pop the value to store. vvp_queue*queue = get_queue_object(thr, net); assert(queue); @@ -6124,7 +6099,7 @@ static bool store_qf(vthread_t thr, vvp_code_t cp, unsigned wid=0) ELEM value; vvp_net_t*net = cp->net; unsigned max_size = thr->words[cp->bit_idx[0]].w_int; - pop_value(value, thr, wid); // Pop the value to store. + pop_value(thr, value, wid); // Pop the value to store. vvp_queue*queue = get_queue_object(thr, net); assert(queue); diff --git a/vvp/vthread.h b/vvp/vthread.h index 4df387128..75d7929c8 100644 --- a/vvp/vthread.h +++ b/vvp/vthread.h @@ -1,7 +1,7 @@ #ifndef IVL_vthread_H #define IVL_vthread_H /* - * Copyright (c) 2001-2014 Stephen Williams (steve@icarus.com) + * Copyright (c) 2001-2020 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU @@ -112,9 +112,9 @@ extern vvp_context_item_t vthread_get_rd_context_item(unsigned context_idx); /* * Access value stacks from thread space. */ -extern void vthread_push_vec4(struct vthread_s*thr, const vvp_vector4_t&val); -extern void vthread_push_str(struct vthread_s*thr, const std::string&val); -extern void vthread_push_real(struct vthread_s*thr, double val); +extern void vthread_push(struct vthread_s*thr, const vvp_vector4_t&val); +extern void vthread_push(struct vthread_s*thr, const std::string&val); +extern void vthread_push(struct vthread_s*thr, double val); extern void vthread_pop_vec4(struct vthread_s*thr, unsigned count); extern void vthread_pop_str(struct vthread_s*thr, unsigned count);