From 62d7c081dcead2bf7312eb9127ceb2e6b77fd388 Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Fri, 13 Jun 2008 19:47:48 -0700 Subject: [PATCH] Sign extend signed vectors when getting vpiIntVal. When getting values using vpi_get_value, the vpiIntVal is the integer value and should be sign-extended if the source value is signed. --- vvp/vpi_signal.cc | 24 ++++++++---------------- vvp/vvp_net.cc | 28 ++++++++++++++++++++++++++++ vvp/vvp_net.h | 1 + 3 files changed, 37 insertions(+), 16 deletions(-) diff --git a/vvp/vpi_signal.cc b/vvp/vpi_signal.cc index 8388aa420..8d53076d6 100644 --- a/vvp/vpi_signal.cc +++ b/vvp/vpi_signal.cc @@ -294,21 +294,13 @@ static void format_vpiDecStrVal(vvp_fun_signal_vec*sig, int base, unsigned wid, } static void format_vpiIntVal(vvp_fun_signal_vec*sig, int base, unsigned wid, - s_vpi_value*vp) + int signed_flag, s_vpi_value*vp) { - unsigned iwid = 8 * sizeof(vp->value.integer); - long ssize = (signed)sig->size(); - - if (wid > iwid) wid = iwid; - long end = base + (signed)wid; - if (end > ssize) end = ssize; - - vp->value.integer = 0; - for (long idx = (base < 0) ? 0 : base ; idx < end ; idx += 1) { - if (sig->value(idx) == BIT4_1) { - vp->value.integer |= 1<<(idx-base); - } - } + vvp_vector4_t sub = sig->vec4_value().subvalue(base, wid); + long val = 0; + bool flag = vector4_to_value(sub, val, signed_flag); + if (! flag) val = 0; + vp->value.integer = val; } static void format_vpiRealVal(vvp_fun_signal_vec*sig, int base, unsigned wid, @@ -653,7 +645,7 @@ static void signal_get_value(vpiHandle ref, s_vpi_value*vp) switch (vp->format) { case vpiIntVal: - format_vpiIntVal(vsig, 0, wid, vp); + format_vpiIntVal(vsig, 0, wid, rfp->signed_flag, vp); break; case vpiScalarVal: @@ -1036,7 +1028,7 @@ static void PV_get_value(vpiHandle ref, p_vpi_value vp) switch (vp->format) { case vpiIntVal: - format_vpiIntVal(sig, PV_get_base(rfp), rfp->width, vp); + format_vpiIntVal(sig, PV_get_base(rfp), rfp->width, 0, vp); break; case vpiBinStrVal: diff --git a/vvp/vvp_net.cc b/vvp/vvp_net.cc index 662d9b058..01393d105 100644 --- a/vvp/vvp_net.cc +++ b/vvp/vvp_net.cc @@ -1078,6 +1078,34 @@ vvp_vector4_t double_to_vector4(double val, unsigned wid) return res; } +bool vector4_to_value(const vvp_vector4_t&vec, long&val, bool is_signed) +{ + long res = 0; + long msk = 1; + + for (unsigned idx = 0 ; idx < vec.size() ; idx += 1) { + switch (vec.value(idx)) { + case BIT4_0: + break; + case BIT4_1: + res |= msk; + break; + default: + return false; + } + + msk <<= 1L; + } + + if (is_signed && vec.value(vec.size()-1) == BIT4_1) { + if (vec.size() < 8*sizeof(val)) + res |= (-1L) << vec.size(); + } + + val = res; + return true; +} + bool vector4_to_value(const vvp_vector4_t&vec, unsigned long&val) { unsigned long res = 0; diff --git a/vvp/vvp_net.h b/vvp/vvp_net.h index 0caa36887..928bfb3a9 100644 --- a/vvp/vvp_net.h +++ b/vvp/vvp_net.h @@ -379,6 +379,7 @@ extern vvp_vector4_t double_to_vector4(double val, unsigned wid); * to real and integers) and the return value becomes false to * indicate an error. */ +extern bool vector4_to_value(const vvp_vector4_t&a, long&val, bool is_signed); extern bool vector4_to_value(const vvp_vector4_t&a, unsigned long&val); extern bool vector4_to_value(const vvp_vector4_t&a, double&val, bool is_signed);