diff --git a/vvp/vpi_callback.cc b/vvp/vpi_callback.cc index eb05dc8e3..71ddcb924 100644 --- a/vvp/vpi_callback.cc +++ b/vvp/vpi_callback.cc @@ -614,6 +614,66 @@ void vvp_signal_value::get_signal_value(struct t_vpi_value*vp) } } +void vvp_wire_real::get_signal_value(struct t_vpi_value*vp) +{ + char*rbuf = need_result_buf(64 + 1, RBUF_VAL); + + switch (vp->format) { + case vpiObjTypeVal: + vp->format = vpiRealVal; + + case vpiRealVal: + vp->value.real = real_value(); + break; + + case vpiIntVal: + vp->value.integer = (int)(real_value() + 0.5); + break; + + case vpiDecStrVal: + sprintf(rbuf, "%0.0f", real_value()); + vp->value.str = rbuf; + break; + + case vpiHexStrVal: + sprintf(rbuf, "%lx", (long)real_value()); + vp->value.str = rbuf; + break; + + case vpiBinStrVal: { + unsigned long val = (unsigned long)real_value(); + unsigned len = 0; + + while (val > 0) { + len += 1; + val /= 2; + } + + val = (unsigned long)real_value(); + for (unsigned idx = 0 ; idx < len ; idx += 1) { + rbuf[len-idx-1] = (val & 1)? '1' : '0'; + val /= 2; + } + + rbuf[len] = 0; + if (len == 0) { + rbuf[0] = '0'; + rbuf[1] = 0; + } + vp->value.str = rbuf; + break; + } + + case vpiSuppressVal: + break; + + default: + fprintf(stderr, "vpi_callback: value " + "format %d not supported (fun_signal_real)\n", + vp->format); + } +} + void vvp_fun_signal4::get_value(struct t_vpi_value*vp) { get_signal_value(vp); @@ -703,3 +763,8 @@ void vvp_wire_vec8::get_value(struct t_vpi_value*value) { assert(0); } + +void vvp_wire_real::get_value(struct t_vpi_value*value) +{ + get_signal_value(value); +} diff --git a/vvp/vpi_real.cc b/vvp/vpi_real.cc index 447c1a7b6..f6b1d4a28 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_fun_signal_real*fun - = dynamic_cast(rfp->net->fun); + vvp_wire_real*fil + = dynamic_cast(rfp->net->fil); - fun->get_value(vp); + fil->get_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 50f0ef2fe..b46f26c32 100644 --- a/vvp/vvp_net_sig.cc +++ b/vvp/vvp_net_sig.cc @@ -69,6 +69,12 @@ vvp_signal_value::~vvp_signal_value() { } +double vvp_signal_value::real_value() const +{ + assert(0); + return 0; +} + #if 0 const vvp_vector4_t* vvp_fun_signal4::filter_vec4(const vvp_vector4_t&val) { @@ -1054,3 +1060,90 @@ vvp_vector4_t vvp_wire_vec8::vec4_value() const { assert(0); } + +vvp_wire_real::vvp_wire_real() +{ +} + +bool vvp_wire_real::filter_real(double&bit) +{ + bit_ = bit; + if (test_force_mask(0)) { + bit = force_; + return false; + } + return true; +} + +unsigned vvp_wire_real::filter_size() const +{ + assert(0); + return 0; +} + +void vvp_wire_real::force_fil_vec4(const vvp_vector4_t&val, vvp_vector2_t mask) +{ + assert(0); +} + +void vvp_wire_real::force_fil_vec8(const vvp_vector8_t&val, vvp_vector2_t mask) +{ + assert(0); +} + +void vvp_wire_real::force_fil_real(double val, vvp_vector2_t mask) +{ + assert(0); +} + +void vvp_wire_real::release(vvp_net_ptr_t ptr, bool net) +{ + assert(net); + + // Wires revert to their unforced value after release. + vvp_vector2_t mask (vvp_vector2_t::FILL1, 1); + release_mask(mask); + assert(0); +} + +void vvp_wire_real::release_pv(vvp_net_ptr_t ptr, bool net, + unsigned base, unsigned wid) +{ + assert(net); + + vvp_vector2_t mask (vvp_vector2_t::FILL0, 1); + for (unsigned idx = 0 ; idx < wid ; idx += 1) + mask.set_bit(base+idx, 1); + + release_mask(mask); + assert(0); +} + +unsigned vvp_wire_real::value_size() const +{ + assert(0); + return 1; +} + +vvp_bit4_t vvp_wire_real::value(unsigned idx) const +{ + assert(0); +} + +vvp_scalar_t vvp_wire_real::scalar_value(unsigned idx) const +{ + assert(0); +} + +vvp_vector4_t vvp_wire_real::vec4_value() const +{ + assert(0); +} + +double vvp_wire_real::real_value() const +{ + if (test_force_mask(0)) + return force_; + else + return bit_; +} diff --git a/vvp/vvp_net_sig.h b/vvp/vvp_net_sig.h index ea5328ed5..64662edfa 100644 --- a/vvp/vvp_net_sig.h +++ b/vvp/vvp_net_sig.h @@ -100,6 +100,7 @@ class vvp_signal_value { virtual vvp_bit4_t value(unsigned idx) const =0; virtual vvp_scalar_t scalar_value(unsigned idx) const =0; virtual vvp_vector4_t vec4_value() const =0; + virtual double real_value() const; virtual void get_signal_value(struct t_vpi_value*vp); }; @@ -349,11 +350,6 @@ class vvp_wire_base : public vvp_net_fil_t, public vvp_signal_value { public: vvp_wire_base(); ~vvp_wire_base(); - - // The main filter behavior for this class - const vvp_vector4_t* filter_vec4(const vvp_vector4_t&bit) =0; - const vvp_vector8_t* filter_vec8(const vvp_vector8_t&val) =0; - }; class vvp_wire_vec4 : public vvp_wire_base { @@ -426,4 +422,36 @@ class vvp_wire_vec8 : public vvp_wire_base { vvp_vector8_t filter8_; // scratch space for filter_mask_ function. }; +class vvp_wire_real : public vvp_wire_base { + + public: + explicit vvp_wire_real(); + + // The main filter behavior for this class + bool filter_real(double&bit); + + // Abstract methods from vvp_vpi_callback + void get_value(struct t_vpi_value*value); + // Abstract methods from vvp_net_fit_t + unsigned filter_size() const; + void force_fil_vec4(const vvp_vector4_t&val, vvp_vector2_t mask); + void force_fil_vec8(const vvp_vector8_t&val, vvp_vector2_t mask); + void force_fil_real(double val, vvp_vector2_t mask); + void release(vvp_net_ptr_t ptr, bool net); + void release_pv(vvp_net_ptr_t ptr, bool net, unsigned base, unsigned wid); + + // Implementation of vvp_signal_value methods + 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: + double bit_; + double force_; +}; + #endif diff --git a/vvp/words.cc b/vvp/words.cc index bfe6c34e5..e5a5a4b98 100644 --- a/vvp/words.cc +++ b/vvp/words.cc @@ -37,6 +37,7 @@ static void __compile_var_real(char*label, char*name, 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 { @@ -44,7 +45,7 @@ static void __compile_var_real(char*label, char*name, } vvp_net_t*net = new vvp_net_t; net->fun = fun; - assert(0 /* XXXX */); // Need to create a net_fil_t! net->fil = fun; + net->fil = fil; define_functor_symbol(label, net); @@ -55,7 +56,7 @@ static void __compile_var_real(char*label, char*name, assert(!array); vpip_attach_to_current_scope(obj); if (!vpip_peek_current_scope()->is_automatic) - schedule_init_vector(vvp_net_ptr_t(net,0), fun->real_value()); + schedule_init_vector(vvp_net_ptr_t(net,0), 0.0); } if (array) { assert(!name);