From b991a991a75afc9609864c6eee26f52e924329cb Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Thu, 19 Jun 2014 15:39:24 -0700 Subject: [PATCH] Implement vpi_handle(vpiLeft/RightRange, ...) for signals. This returns a constant object that can be treated like an expression, so following the letter of the LRM. --- scripts/devel-stub.sh | 2 +- vvp/array.cc | 52 +++++++++++++++++++++---------------------- vvp/stop.cc | 8 +++---- vvp/vpi_const.cc | 6 +++++ vvp/vpi_priv.cc | 2 +- vvp/vpi_priv.h | 32 +++++++++++++++++--------- vvp/vpi_signal.cc | 42 +++++++++++++++++----------------- 7 files changed, 81 insertions(+), 63 deletions(-) diff --git a/scripts/devel-stub.sh b/scripts/devel-stub.sh index 3f26a56aa..faf2e2262 100644 --- a/scripts/devel-stub.sh +++ b/scripts/devel-stub.sh @@ -9,6 +9,6 @@ # # NOTE: DO NOT INSTALL THIS FILE. -./ivl -v -Ctgt-stub/stub.conf -C./scripts/devel-stub.conf -Pa.pf -Na.net -fDLL=tgt-stub/stub.tgt foo.vl |& tee foo.log +./ivl -v -Ctgt-stub/stub-s.conf -C./scripts/devel-stub.conf -Pa.pf -Na.net -fDLL=tgt-stub/stub.tgt foo.vl |& tee foo.log echo "*** ivl command completed" diff --git a/vvp/array.cc b/vvp/array.cc index 8a7f1fed9..25bfdbf3d 100644 --- a/vvp/array.cc +++ b/vvp/array.cc @@ -396,7 +396,7 @@ vpiHandle __vpiArray::vpi_iterate(int code) */ vpiHandle __vpiArray::vpi_index(int index) { - index -= first_addr.value; + index -= first_addr.get_value(); if (index >= (long)array_count) return 0; if (index < 0) @@ -609,10 +609,10 @@ static int vpi_array_var_word_get(int code, vpiHandle ref) } case vpiLeftRange: - return parent->msb.value; + return parent->msb.get_value(); case vpiRightRange: - return parent->lsb.value; + return parent->lsb.get_value(); case vpiAutomatic: return (int) parent->scope->is_automatic; @@ -640,7 +640,7 @@ static char*vpi_array_var_word_get_str(int code, vpiHandle ref) } char sidx [64]; - snprintf(sidx, 63, "%d", (int)index + parent->first_addr.value); + snprintf(sidx, 63, "%d", (int)index + parent->first_addr.get_value()); return generic_get_str(code, parent->scope, parent->name, sidx); } @@ -756,13 +756,13 @@ static int vpi_array_vthr_A_get(int code, vpiHandle ref) return get_array_word_size(parent); case vpiLeftRange: - return parent->msb.value; + return parent->msb.get_value(); case vpiRightRange: - return parent->lsb.value; + return parent->lsb.get_value(); case vpiIndex: - return (int)obj->get_address() + parent->first_addr.value; + return (int)obj->get_address() + parent->first_addr.get_value(); case vpiAutomatic: return (int) parent->scope->is_automatic; @@ -796,7 +796,7 @@ static char*vpi_array_vthr_A_get_str(int code, vpiHandle ref) } char sidx [64]; - snprintf(sidx, 63, "%d", (int)obj->get_address() + parent->first_addr.value); + snprintf(sidx, 63, "%d", (int)obj->get_address() + parent->first_addr.get_value()); return generic_get_str(code, parent->scope, parent->name, sidx); } @@ -924,10 +924,10 @@ static int vpi_array_vthr_APV_get(int code, vpiHandle ref) return obj->part_wid; case vpiLeftRange: - return parent->msb.value; + return parent->msb.get_value(); case vpiRightRange: - return parent->lsb.value; + return parent->lsb.get_value(); case vpiIndex: return (int)obj->word_sel; @@ -959,7 +959,7 @@ static char*vpi_array_vthr_APV_get_str(int code, vpiHandle ref) } char sidx [64]; - snprintf(sidx, 63, "%u", obj->word_sel + parent->first_addr.value); + snprintf(sidx, 63, "%u", obj->word_sel + parent->first_addr.get_value()); return generic_get_str(code, parent->scope, parent->name, sidx); } @@ -1176,8 +1176,8 @@ static vpiHandle vpip_make_array(char*label, const char*name, obj->name = vpip_name_string(name); obj->array_count = array_count; - obj->first_addr.value = first_addr; - obj->last_addr.value = last_addr; + obj->first_addr.set_value(first_addr); + obj->last_addr .set_value(last_addr); // Start off now knowing if we are nets or variables. obj->nets = 0; @@ -1211,8 +1211,8 @@ static vpiHandle vpip_make_array(char*label, const char*name, void array_alias_word(vvp_array_t array, unsigned long addr, vpiHandle word, int msb, int lsb) { - assert(array->msb.value == msb); - assert(array->lsb.value == lsb); + assert(array->msb.get_value() == msb); + assert(array->lsb.get_value() == lsb); assert(addr < array->array_count); assert(array->nets); array->nets[addr] = word; @@ -1232,7 +1232,7 @@ void array_attach_word(vvp_array_t array, unsigned addr, vpiHandle word) fun->attach_as_word(array, addr); sig->is_netarray = 1; sig->within.parent = array; - sig->id.index = new __vpiDecConst(addr + array->first_addr.value); + sig->id.index = new __vpiDecConst(addr + array->first_addr.get_value()); // Now we know the data type, update the array signed_flag. array->signed_flag = sig->signed_flag; return; @@ -1246,7 +1246,7 @@ void array_attach_word(vvp_array_t array, unsigned addr, vpiHandle word) fun->attach_as_word(array, addr); sig->is_netarray = 1; sig->within.parent = array; - sig->id.index = new __vpiDecConst(addr + array->first_addr.value); + sig->id.index = new __vpiDecConst(addr + array->first_addr.get_value()); // Now we know the data type, update the array signed_flag. array->signed_flag = true; return; @@ -1270,8 +1270,8 @@ void compile_var_array(char*label, char*name, int last, int first, arr->vals4 = new vvp_vector4array_sa(arr->vals_width, arr->array_count); } - arr->msb.value = msb; - arr->lsb.value = lsb; + arr->msb.set_value(msb); + arr->lsb.set_value(lsb); count_var_arrays += 1; count_var_array_words += arr->array_count; @@ -1288,8 +1288,8 @@ void compile_var2_array(char*label, char*name, int last, int first, struct __vpiArray*arr = dynamic_cast<__vpiArray*>(obj); /* Make the words. */ - arr->msb.value = msb; - arr->lsb.value = lsb; + arr->msb.set_value(msb); + arr->lsb.set_value(lsb); arr->vals_width = labs(msb-lsb) + 1; assert(! arr->nets); @@ -1653,7 +1653,7 @@ void array_word_change(vvp_array_t array, unsigned long addr) // For whole array callbacks we need to set the index. if (cur->word_addr == -1) { cur->cb_data.index = (PLI_INT32) ((int)addr + - array->first_addr.value); + array->first_addr.get_value()); } if (cur->cb_data.cb_rtn != 0) { @@ -1889,12 +1889,12 @@ void compile_array_alias(char*label, char*name, char*src) obj->signed_flag = mem->signed_flag; // Need to set an accurate range of addresses. - obj->first_addr.value = mem->first_addr.value; - obj->last_addr.value = mem->last_addr.value; + obj->first_addr = mem->first_addr; + obj->last_addr = mem->last_addr; obj->swap_addr = mem->swap_addr; - obj->msb.value = mem->msb.value; - obj->lsb.value = mem->lsb.value; + obj->msb = mem->msb; + obj->lsb = mem->lsb; // Share the words with the source array. obj->nets = mem->nets; diff --git a/vvp/stop.cc b/vvp/stop.cc index 4f1e67503..f403f9cf7 100644 --- a/vvp/stop.cc +++ b/vvp/stop.cc @@ -268,7 +268,7 @@ static void cmd_list(unsigned, char*[]) case vpiReg: sig = dynamic_cast<__vpiSignal*>(table[idx]); - if ((sig->msb == 0) && (sig->lsb == 0)) + if ((sig->msb.get_value() == 0) && (sig->lsb.get_value() == 0)) printf("reg : %s%s\n", vpi_get_str(vpiName, table[idx]), sig->signed_flag? "signed " : ""); @@ -276,12 +276,12 @@ static void cmd_list(unsigned, char*[]) printf("reg : %s%s[%d:%d]\n", vpi_get_str(vpiName, table[idx]), sig->signed_flag? "signed " : "", - sig->msb, sig->lsb); + sig->msb.get_value(), sig->lsb.get_value()); break; case vpiNet: sig = dynamic_cast<__vpiSignal*>(table[idx]); - if ((sig->msb == 0) && (sig->lsb == 0)) + if ((sig->msb.get_value() == 0) && (sig->lsb.get_value() == 0)) printf("net : %s%s\n", vpi_get_str(vpiName, table[idx]), sig->signed_flag? "signed " : ""); @@ -289,7 +289,7 @@ static void cmd_list(unsigned, char*[]) printf("net : %s%s[%d:%d]\n", vpi_get_str(vpiName, table[idx]), sig->signed_flag? "signed " : "", - sig->msb, sig->lsb); + sig->msb.get_value(), sig->lsb.get_value()); break; default: diff --git a/vvp/vpi_const.cc b/vvp/vpi_const.cc index 438e6cfd8..da278d245 100644 --- a/vvp/vpi_const.cc +++ b/vvp/vpi_const.cc @@ -537,6 +537,12 @@ __vpiDecConst::__vpiDecConst(int val) value = val; } +__vpiDecConst::__vpiDecConst(const __vpiDecConst&that) +: value(that.value) +{ +} + + int __vpiDecConst::get_type_code(void) const { return vpiConstant; } diff --git a/vvp/vpi_priv.cc b/vvp/vpi_priv.cc index bb194e7f1..5b5a787a3 100644 --- a/vvp/vpi_priv.cc +++ b/vvp/vpi_priv.cc @@ -105,7 +105,7 @@ struct vpip_string_chunk { unsigned vpip_size(__vpiSignal *sig) { - return abs(sig->msb - sig->lsb) + 1; + return abs(sig->msb.get_value() - sig->lsb.get_value()) + 1; } struct __vpiScope* vpip_scope(__vpiSignal*sig) diff --git a/vvp/vpi_priv.h b/vvp/vpi_priv.h index 8e6c9b2ad..a57d4dc78 100644 --- a/vvp/vpi_priv.h +++ b/vvp/vpi_priv.h @@ -146,6 +146,22 @@ struct __vpiIterator : public __vpiHandle { extern vpiHandle vpip_make_iterator(unsigned nargs, vpiHandle*args, bool free_args_flag); +class __vpiDecConst : public __vpiHandle { + public: + __vpiDecConst(int val =0); + __vpiDecConst(const __vpiDecConst&that); + int get_type_code(void) const; + int vpi_get(int code); + void vpi_get_value(p_vpi_value val); + + public: + inline int get_value() const { return value; } + inline void set_value(int val) { value = val; } + + private: + int value; +}; + /* * This represents callback handles. There are some private types that * are defined and used in vpi_callback.cc. The __vpiCallback are @@ -281,6 +297,10 @@ struct __vpiSignal : public __vpiHandle { vpiHandle vpi_iterate(int code); vpiHandle vpi_index(int idx); + public: + unsigned width() const; + + public: union { // The scope or parent array that contains me. vpiHandle parent; struct __vpiScope* scope; @@ -290,7 +310,7 @@ struct __vpiSignal : public __vpiHandle { vpiHandle index; } id; /* The indices that define the width and access offset. */ - int msb, lsb; + __vpiDecConst msb, lsb; /* Flags */ unsigned signed_flag : 1; unsigned is_netarray : 1; // This is word of a net array @@ -626,16 +646,6 @@ vpiHandle vpip_make_binary_param(char*name, const vvp_vector4_t&bits, bool signed_flag, bool local_flag, long file_idx, long lineno); -class __vpiDecConst : public __vpiHandle { - public: - __vpiDecConst(int val =0); - int get_type_code(void) const; - int vpi_get(int code); - void vpi_get_value(p_vpi_value val); - - int value; -}; - class __vpiRealConst : public __vpiHandle { public: __vpiRealConst(double); diff --git a/vvp/vpi_signal.cc b/vvp/vpi_signal.cc index 22005b27c..a71fdd262 100644 --- a/vvp/vpi_signal.cc +++ b/vvp/vpi_signal.cc @@ -550,10 +550,7 @@ static int signal_get(int code, vpiHandle ref) } case vpiSize: - if (rfp->msb >= rfp->lsb) - return rfp->msb - rfp->lsb + 1; - else - return rfp->lsb - rfp->msb + 1; + return rfp->width(); case vpiNetType: if (ref->get_type_code()==vpiNet) @@ -562,15 +559,15 @@ static int signal_get(int code, vpiHandle ref) return vpiUndefined; case vpiLeftRange: - return rfp->msb; + return rfp->msb.get_value(); case vpiRightRange: - return rfp->lsb; + return rfp->lsb.get_value(); case vpiScalar: - return (rfp->msb == 0 && rfp->lsb == 0); + return (rfp->msb.get_value() == 0 && rfp->lsb.get_value() == 0); case vpiVector: - return (rfp->msb != rfp->lsb); + return (rfp->msb.get_value() != rfp->lsb.get_value()); case vpiAutomatic: return (int) vpip_scope(rfp)->is_automatic; @@ -582,7 +579,7 @@ static int signal_get(int code, vpiHandle ref) // This private property must return zero when undefined. case _vpiNexusId: - if (rfp->msb == rfp->lsb) + if (rfp->msb.get_value() == rfp->lsb.get_value()) return (int) (unsigned long) rfp->node; else return 0; @@ -636,6 +633,11 @@ static vpiHandle signal_get_handle(int code, vpiHandle ref) case vpiIndex: return rfp->is_netarray? rfp->id.index : 0; + case vpiLeftRange: + return &rfp->msb; + case vpiRightRange: + return &rfp->lsb; + case vpiScope: return vpip_scope(rfp); @@ -663,10 +665,10 @@ static vpiHandle signal_index(int idx, vpiHandle ref) struct __vpiSignal*rfp = dynamic_cast<__vpiSignal*>(ref); assert(rfp); /* Check to see if the index is in range. */ - if (rfp->msb >= rfp->lsb) { - if ((idx > rfp->msb) || (idx < rfp->lsb)) return 0; + if (rfp->msb.get_value() >= rfp->lsb.get_value()) { + if ((idx > rfp->msb.get_value()) || (idx < rfp->lsb.get_value())) return 0; } else { - if ((idx < rfp->msb) || (idx > rfp->lsb)) return 0; + if ((idx < rfp->msb.get_value()) || (idx > rfp->lsb.get_value())) return 0; } /* Return a handle for the individual bit. */ cerr << "Sorry: Icarus does not currently support " @@ -676,11 +678,11 @@ static vpiHandle signal_index(int idx, vpiHandle ref) return 0; } -static unsigned signal_width(const struct __vpiSignal*rfp) +unsigned __vpiSignal::width(void) const { - unsigned wid = (rfp->msb >= rfp->lsb) - ? (rfp->msb - rfp->lsb + 1) - : (rfp->lsb - rfp->msb + 1); + unsigned wid = (msb.get_value() >= lsb.get_value()) + ? (msb.get_value() - lsb.get_value() + 1) + : (lsb.get_value() - msb.get_value() + 1); return wid; } @@ -695,7 +697,7 @@ static void signal_get_value(vpiHandle ref, s_vpi_value*vp) struct __vpiSignal*rfp = dynamic_cast<__vpiSignal*>(ref); assert(rfp); - unsigned wid = signal_width(rfp); + unsigned wid = rfp->width(); vvp_signal_value*vsig = dynamic_cast(rfp->node->fil); assert(vsig); @@ -817,9 +819,9 @@ static vpiHandle signal_put_value(vpiHandle ref, s_vpi_value*vp, int flags) /* Make a vvp_vector4_t vector to receive the translated value that we are going to poke. This will get populated differently depending on the format. */ - wid = (rfp->msb >= rfp->lsb) - ? (rfp->msb - rfp->lsb + 1) - : (rfp->lsb - rfp->msb + 1); + wid = (rfp->msb.get_value() >= rfp->lsb.get_value()) + ? (rfp->msb.get_value() - rfp->lsb.get_value() + 1) + : (rfp->lsb.get_value() - rfp->msb.get_value() + 1); vvp_vector4_t val = vec4_from_vpi_value(vp, wid);