From 047ee137ed8fb89fe90d4221f390460e3c965172 Mon Sep 17 00:00:00 2001 From: Cary R Date: Tue, 25 Aug 2009 09:40:30 -0700 Subject: [PATCH] Add vvp support for out of bound variable part selects. This patch adds support for variable part selects with out of bound and 'bx index values. (cherry picked from commit 1306a6db81fdb1a25bc5e7fc1111a0774400fea7) --- vvp/part.cc | 21 ++++++++++++--------- vvp/part.h | 4 ++-- vvp/vpi_signal.cc | 14 +++++++++++++- 3 files changed, 27 insertions(+), 12 deletions(-) diff --git a/vvp/part.cc b/vvp/part.cc index 7261cff1e..a14551205 100644 --- a/vvp/part.cc +++ b/vvp/part.cc @@ -239,17 +239,20 @@ vvp_fun_part_var::~vvp_fun_part_var() } bool vvp_fun_part_var::recv_vec4_(vvp_net_ptr_t port, const vvp_vector4_t&bit, - unsigned&base, vvp_vector4_t&source, + long&base, vvp_vector4_t&source, vvp_vector4_t&ref) { - unsigned long tmp; + long tmp; switch (port.port()) { case 0: source = bit; break; case 1: - tmp = ULONG_MAX; - vector4_to_value(bit, tmp); + // LONG_MIN is before the vector and is used to + // represent a 'bx value on the select input. + tmp = LONG_MIN; + // We need a new &PV<> that knows if the index is signed. + vector4_to_value(bit, tmp, false); if (tmp == base) return false; base = tmp; break; @@ -262,11 +265,11 @@ bool vvp_fun_part_var::recv_vec4_(vvp_net_ptr_t port, const vvp_vector4_t&bit, vvp_vector4_t res (wid_); for (unsigned idx = 0 ; idx < wid_ ; idx += 1) { - unsigned adr = base+idx; - if (adr >= source.size()) - break; + long adr = base+idx; + if (adr < 0) continue; + if ((unsigned)adr >= source.size()) break; - res.set_bit(idx, source.value(adr)); + res.set_bit(idx, source.value((unsigned)adr)); } if (! ref.eeq(res)) { @@ -311,7 +314,7 @@ void vvp_fun_part_var_sa::recv_vec4_pv(vvp_net_ptr_t port, const vvp_vector4_t&b struct vvp_fun_part_var_state_s { vvp_fun_part_var_state_s() : base(0) { } - unsigned base; + long base; vvp_vector4_t source; vvp_vector4_t ref; }; diff --git a/vvp/part.h b/vvp/part.h index 687b76063..f42dc6cd3 100644 --- a/vvp/part.h +++ b/vvp/part.h @@ -130,7 +130,7 @@ class vvp_fun_part_var : public vvp_net_fun_t { protected: bool recv_vec4_(vvp_net_ptr_t port, const vvp_vector4_t&bit, - unsigned&base, vvp_vector4_t&source, + long&base, vvp_vector4_t&source, vvp_vector4_t&ref); unsigned wid_; @@ -154,7 +154,7 @@ class vvp_fun_part_var_sa : public vvp_fun_part_var { vvp_context_t); private: - unsigned base_; + long base_; vvp_vector4_t source_; // Save the last output, for detecting change. vvp_vector4_t ref_; diff --git a/vvp/vpi_signal.cc b/vvp/vpi_signal.cc index 6f5ec8d36..dfe454d9c 100644 --- a/vvp/vpi_signal.cc +++ b/vvp/vpi_signal.cc @@ -997,12 +997,24 @@ static int PV_get_base(struct __vpiPV*rfp) /* If the width is zero then tbase is the constant. */ if (rfp->twid == 0) return rfp->tbase; + /* Get the value from thread space. */ int tval = 0; for (unsigned idx = 0 ; idx < rfp->twid ; idx += 1) { vvp_bit4_t bit = vthread_get_bit(vpip_current_vthread, rfp->tbase + idx); - if (bit == BIT4_1) { + switch (bit) { + case BIT4_X: + case BIT4_Z: + /* We use INT_MIN to indicate an X base. */ + return INT_MIN; + break; + + case BIT4_1: tval |= 1<