From b75f02c88901ba318fc3e5c95f796671dd49dc1b Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Tue, 15 Sep 2009 21:28:21 -0700 Subject: [PATCH] Handle automatic real variables like automatic logic vectors. --- vvp/vpi_callback.cc | 24 +++++++++---- vvp/vpi_real.cc | 6 ++-- vvp/vvp_net_sig.cc | 88 +++++++++++++++++++++++++++++---------------- vvp/vvp_net_sig.h | 38 +++++++++++++------- vvp/words.cc | 38 ++++++++++---------- 5 files changed, 121 insertions(+), 73 deletions(-) diff --git a/vvp/vpi_callback.cc b/vvp/vpi_callback.cc index 0f06887fe..95f7045c8 100644 --- a/vvp/vpi_callback.cc +++ b/vvp/vpi_callback.cc @@ -614,7 +614,7 @@ void vvp_signal_value::get_signal_value(struct t_vpi_value*vp) } } -void vvp_wire_real::get_signal_value(struct t_vpi_value*vp) +static void real_signal_value(struct t_vpi_value*vp, double rval) { char*rbuf = need_result_buf(64 + 1, RBUF_VAL); @@ -623,25 +623,25 @@ void vvp_wire_real::get_signal_value(struct t_vpi_value*vp) vp->format = vpiRealVal; case vpiRealVal: - vp->value.real = real_value(); + vp->value.real = rval; break; case vpiIntVal: - vp->value.integer = (int)(real_value() + 0.5); + vp->value.integer = (int)(rval + 0.5); break; case vpiDecStrVal: - sprintf(rbuf, "%0.0f", real_value()); + sprintf(rbuf, "%0.0f", rval); vp->value.str = rbuf; break; case vpiHexStrVal: - sprintf(rbuf, "%lx", (long)real_value()); + sprintf(rbuf, "%lx", (long)rval); vp->value.str = rbuf; break; case vpiBinStrVal: { - unsigned long val = (unsigned long)real_value(); + unsigned long val = (unsigned long)rval; unsigned len = 0; while (val > 0) { @@ -649,7 +649,7 @@ void vvp_wire_real::get_signal_value(struct t_vpi_value*vp) val /= 2; } - val = (unsigned long)real_value(); + val = (unsigned long)rval; for (unsigned idx = 0 ; idx < len ; idx += 1) { rbuf[len-idx-1] = (val & 1)? '1' : '0'; val /= 2; @@ -674,6 +674,16 @@ void vvp_wire_real::get_signal_value(struct t_vpi_value*vp) } } +void vvp_fun_signal_real_aa::get_signal_value(struct t_vpi_value*vp) +{ + real_signal_value(vp, real_value()); +} + +void vvp_wire_real::get_signal_value(struct t_vpi_value*vp) +{ + real_signal_value(vp, real_value()); +} + void vvp_wire_vec4::get_value(struct t_vpi_value*value) { get_signal_value(value); diff --git a/vvp/vpi_real.cc b/vvp/vpi_real.cc index f6b1d4a28..1b210c1db 100644 --- a/vvp/vpi_real.cc +++ b/vvp/vpi_real.cc @@ -132,10 +132,10 @@ static void real_var_get_value(vpiHandle ref, s_vpi_value*vp) struct __vpiRealVar*rfp = (struct __vpiRealVar*)ref; - vvp_wire_real*fil - = dynamic_cast(rfp->net->fil); + vvp_signal_value*fil + = dynamic_cast(rfp->net->fil); - fil->get_value(vp); + fil->get_signal_value(vp); } static vpiHandle real_var_put_value(vpiHandle ref, p_vpi_value vp, int) diff --git a/vvp/vvp_net_sig.cc b/vvp/vvp_net_sig.cc index 1c235a147..55e64511f 100644 --- a/vvp/vvp_net_sig.cc +++ b/vvp/vvp_net_sig.cc @@ -252,6 +252,37 @@ void vvp_fun_signal_base::deassign_pv(unsigned base, unsigned wid) } } +void automatic_signal_base::release(vvp_net_ptr_t,bool) +{ + assert(0); +} + +void automatic_signal_base::release_pv(vvp_net_ptr_t,unsigned,unsigned,bool) +{ + assert(0); +} + +unsigned automatic_signal_base::filter_size() const +{ + assert(0); +} +void automatic_signal_base::force_fil_vec4(const vvp_vector4_t&, vvp_vector2_t) +{ + assert(0); +} +void automatic_signal_base::force_fil_vec8(const vvp_vector8_t&, vvp_vector2_t) +{ + assert(0); +} +void automatic_signal_base::force_fil_real(double, vvp_vector2_t) +{ + assert(0); +} +void automatic_signal_base::get_value(struct t_vpi_value*) +{ + assert(0); +} + vvp_vector4_t vvp_fun_signal4_sa::vec4_unfiltered_value() const { return bits4_; @@ -357,37 +388,6 @@ vvp_vector4_t vvp_fun_signal4_aa::vec4_unfiltered_value() const return vec4_value(); } -void vvp_fun_signal4_aa::release(vvp_net_ptr_t,bool) -{ - assert(0); -} - -void vvp_fun_signal4_aa::release_pv(vvp_net_ptr_t,unsigned,unsigned,bool) -{ - assert(0); -} - -unsigned vvp_fun_signal4_aa::filter_size() const -{ - assert(0); -} -void vvp_fun_signal4_aa::force_fil_vec4(const vvp_vector4_t&, vvp_vector2_t) -{ - assert(0); -} -void vvp_fun_signal4_aa::force_fil_vec8(const vvp_vector8_t&, vvp_vector2_t) -{ - assert(0); -} -void vvp_fun_signal4_aa::force_fil_real(double, vvp_vector2_t) -{ - assert(0); -} -void vvp_fun_signal4_aa::get_value(struct t_vpi_value*) -{ - assert(0); -} - vvp_fun_signal8::vvp_fun_signal8(unsigned wid) : bits8_(wid) { @@ -546,6 +546,11 @@ double vvp_fun_signal_real_aa::real_unfiltered_value() const return *bits; } +double vvp_fun_signal_real_aa::real_value() const +{ + return real_unfiltered_value(); +} + void vvp_fun_signal_real_aa::recv_real(vvp_net_ptr_t ptr, double bit, vvp_context_t context) { @@ -561,6 +566,27 @@ void vvp_fun_signal_real_aa::recv_real(vvp_net_ptr_t ptr, double bit, } } +unsigned vvp_fun_signal_real_aa::value_size() const +{ + assert(0); + return 1; +} + +vvp_bit4_t vvp_fun_signal_real_aa::value(unsigned idx) const +{ + assert(0); +} + +vvp_scalar_t vvp_fun_signal_real_aa::scalar_value(unsigned idx) const +{ + assert(0); +} + +vvp_vector4_t vvp_fun_signal_real_aa::vec4_value() const +{ + assert(0); +} + vvp_fun_force::vvp_fun_force() { } diff --git a/vvp/vvp_net_sig.h b/vvp/vvp_net_sig.h index 738ce4db8..3739df303 100644 --- a/vvp/vvp_net_sig.h +++ b/vvp/vvp_net_sig.h @@ -114,6 +114,21 @@ class vvp_fun_signal_vec : public vvp_fun_signal_base { virtual vvp_vector4_t vec4_unfiltered_value() const =0; }; +class automatic_signal_base : public vvp_signal_value, public vvp_net_fil_t { + + public: + // Automatic variables cannot be forced or released. Provide + // stubs that assert. + virtual void release(vvp_net_ptr_t ptr, bool net_flag); + virtual void release_pv(vvp_net_ptr_t ptr, unsigned base, unsigned wid, bool net_flag); + + virtual unsigned filter_size() const; + virtual void force_fil_vec4(const vvp_vector4_t&val, vvp_vector2_t mask); + virtual void force_fil_vec8(const vvp_vector8_t&val, vvp_vector2_t mask); + virtual void force_fil_real(double val, vvp_vector2_t mask); + virtual void get_value(struct t_vpi_value*value); +}; + /* * Statically allocated vvp_fun_signal4. */ @@ -143,7 +158,7 @@ class vvp_fun_signal4_sa : public vvp_fun_signal_vec { /* * Automatically allocated vvp_fun_signal4. */ -class vvp_fun_signal4_aa : public vvp_fun_signal_vec, public vvp_signal_value, public vvp_net_fil_t, public automatic_hooks_s { +class vvp_fun_signal4_aa : public vvp_fun_signal_vec, public automatic_signal_base, public automatic_hooks_s { public: explicit vvp_fun_signal4_aa(unsigned wid, vvp_bit4_t init=BIT4_X); @@ -169,17 +184,6 @@ class vvp_fun_signal4_aa : public vvp_fun_signal_vec, public vvp_signal_value, p vvp_vector4_t vec4_value() const; vvp_vector4_t vec4_unfiltered_value() const; - // Automatic variables cannot be forced or released. Provide - // stubs that assert. - virtual void release(vvp_net_ptr_t ptr, bool net_flag); - virtual void release_pv(vvp_net_ptr_t ptr, unsigned base, unsigned wid, bool net_flag); - - virtual unsigned filter_size() const; - virtual void force_fil_vec4(const vvp_vector4_t&val, vvp_vector2_t mask); - virtual void force_fil_vec8(const vvp_vector8_t&val, vvp_vector2_t mask); - virtual void force_fil_real(double val, vvp_vector2_t mask); - virtual void get_value(struct t_vpi_value*value); - private: unsigned context_idx_; unsigned size_; @@ -237,7 +241,7 @@ class vvp_fun_signal_real_sa : public vvp_fun_signal_real { /* * Automatically allocated vvp_fun_signal_real. */ -class vvp_fun_signal_real_aa : public vvp_fun_signal_real, public automatic_hooks_s { +class vvp_fun_signal_real_aa : public vvp_fun_signal_real, public automatic_signal_base, public automatic_hooks_s { public: explicit vvp_fun_signal_real_aa(); @@ -254,6 +258,14 @@ class vvp_fun_signal_real_aa : public vvp_fun_signal_real, public automatic_hook // Get information about the vector value. double real_unfiltered_value() const; + // Get information about the vector value. + unsigned value_size() const; + vvp_bit4_t value(unsigned idx) const; + vvp_scalar_t scalar_value(unsigned idx) const; + vvp_vector4_t vec4_value() const; + double real_value() const; + void get_signal_value(struct t_vpi_value*vp); + private: unsigned context_idx_; }; diff --git a/vvp/words.cc b/vvp/words.cc index 78f429238..20c2f0700 100644 --- a/vvp/words.cc +++ b/vvp/words.cc @@ -36,16 +36,16 @@ static void __compile_var_real(char*label, char*name, vvp_array_t array, unsigned long array_addr, int msb, int lsb) { - vvp_fun_signal_real*fun; - vvp_wire_real*fil = new vvp_wire_real; - if (vpip_peek_current_scope()->is_automatic) { - fun = new vvp_fun_signal_real_aa; - } else { - fun = new vvp_fun_signal_real_sa; - } vvp_net_t*net = new vvp_net_t; - net->fun = fun; - net->fil = fil; + + if (vpip_peek_current_scope()->is_automatic) { + vvp_fun_signal_real_aa*tmp = new vvp_fun_signal_real_aa; + net->fil = tmp; + net->fun = tmp; + } else { + net->fil = new vvp_wire_real; + net->fun = new vvp_fun_signal_real_sa; + } define_functor_symbol(label, net); @@ -88,26 +88,26 @@ static void __compile_var(char*label, char*name, { unsigned wid = ((msb > lsb)? msb-lsb : lsb-msb) + 1; - vvp_net_t*node = new vvp_net_t; + vvp_net_t*net = new vvp_net_t; if (vpip_peek_current_scope()->is_automatic) { vvp_fun_signal4_aa*tmp = new vvp_fun_signal4_aa(wid); - node->fil = tmp; - node->fun = tmp; + net->fil = tmp; + net->fun = tmp; } else { - node->fil = new vvp_wire_vec4(wid, BIT4_X); - node->fun = new vvp_fun_signal4_sa(wid); + net->fil = new vvp_wire_vec4(wid, BIT4_X); + net->fun = new vvp_fun_signal4_sa(wid); } - vvp_signal_value*vfil = dynamic_cast(node->fil); + vvp_signal_value*vfil = dynamic_cast(net->fil); - define_functor_symbol(label, node); + define_functor_symbol(label, net); vpiHandle obj = 0; if (! local_flag && !array) { /* Make the vpiHandle for the reg. */ obj = (signed_flag > 1) ? - vpip_make_int(name, msb, lsb, node) : - vpip_make_reg(name, msb, lsb, signed_flag!=0, node); + vpip_make_int(name, msb, lsb, net) : + vpip_make_reg(name, msb, lsb, signed_flag!=0, net); compile_vpi_symbol(label, obj); } // If the signal has a name, then it goes into the current @@ -116,7 +116,7 @@ static void __compile_var(char*label, char*name, assert(!array); if (obj) vpip_attach_to_current_scope(obj); if (!vpip_peek_current_scope()->is_automatic) - schedule_init_vector(vvp_net_ptr_t(node,0), vfil->vec4_value()); + schedule_init_vector(vvp_net_ptr_t(net,0), vfil->vec4_value()); } // If this is an array word, then it does not have a name, and // it is attached to the addressed array.