diff --git a/tgt-vvp/draw_vpi.c b/tgt-vvp/draw_vpi.c index e96be23ae..d326dcf19 100644 --- a/tgt-vvp/draw_vpi.c +++ b/tgt-vvp/draw_vpi.c @@ -37,6 +37,8 @@ struct args_info { char real_flag; /* Stack position if this argument is a calculated value. */ unsigned stack; + /* Expression width: Only used of vec_flag is true. */ + unsigned vec_wid; struct args_info *child; /* Arguments can be nested. */ }; @@ -390,6 +392,7 @@ static void draw_vpi_taskfunc_args(const char*call_string, args[idx].str_flag = 0; args[idx].real_flag = 0; args[idx].stack = vec4_stack_need; + args[idx].vec_wid = ivl_expr_width(expr); vec4_stack_need += 1; buffer[0] = 0; break; @@ -440,7 +443,8 @@ static void draw_vpi_taskfunc_args(const char*call_string, } else if (args[idx].vec_flag) { unsigned pos = vec4_stack_need - args[idx].stack - 1; char sign_flag = args[idx].vec_flag; - fprintf(vvp_out, ", S<%u,vec4,%c>",pos, sign_flag); + unsigned wid = args[idx].vec_wid; + fprintf(vvp_out, ", S<%u,vec4,%c%u>",pos, sign_flag, wid); } else { fprintf(vvp_out, ", %s", args[idx].text); } diff --git a/vvp/compile.cc b/vvp/compile.cc index 5dfedc31a..b8f4255c8 100644 --- a/vvp/compile.cc +++ b/vvp/compile.cc @@ -575,7 +575,7 @@ bool vpi_handle_resolv_list_s::resolve(bool mes) val.ptr = vpip_make_vthr_str_stack(base); sym_set_value(sym_vpi, label(), val); - } else if (2 == sscanf(label(), "S<%u,vec4,%[su]>%n", &base, ss, &n) + } else if (3 == sscanf(label(), "S<%u,vec4,%[su]%u>%n", &base, ss, &wid, &n) && n == strlen(label())) { bool signed_flag = false; @@ -589,7 +589,7 @@ bool vpi_handle_resolv_list_s::resolve(bool mes) default: break; } - val.ptr = vpip_make_vthr_vec4_stack(base, signed_flag); + val.ptr = vpip_make_vthr_vec4_stack(base, signed_flag, wid); sym_set_value(sym_vpi, label(), val); } diff --git a/vvp/lexor.lex b/vvp/lexor.lex index 228e91bb3..6588a19cb 100644 --- a/vvp/lexor.lex +++ b/vvp/lexor.lex @@ -269,7 +269,7 @@ static char* strdupnew(char const *str) assert(yylval.text); return T_SYMBOL; } -"S<"[0-9]*",vec4,"[us]">" { +"S<"[0-9]*",vec4,"[us][0-9]+">" { yylval.text = strdup(yytext); assert(yylval.text); return T_SYMBOL; } diff --git a/vvp/vpi_priv.h b/vvp/vpi_priv.h index 87a077bf3..9a20ce168 100644 --- a/vvp/vpi_priv.h +++ b/vvp/vpi_priv.h @@ -589,6 +589,7 @@ struct __vpiSysTaskCall : public __vpiHandle { protected: inline __vpiSysTaskCall() { + vec4_stack = 0; real_stack = 0; string_stack = 0; } @@ -656,13 +657,9 @@ vpiHandle vpip_make_real_param(char*name, double value, bool local_flag, * thread. */ -#if 0 -vpiHandle vpip_make_vthr_vector(unsigned base, unsigned wid, bool signed_flag); -#endif - vpiHandle vpip_make_vthr_word(unsigned base, const char*type); vpiHandle vpip_make_vthr_str_stack(unsigned depth); -vpiHandle vpip_make_vthr_vec4_stack(unsigned depth, bool signed_flag); +vpiHandle vpip_make_vthr_vec4_stack(unsigned depth, bool signed_flag, unsigned wid); vpiHandle vpip_make_vthr_A(char*label, unsigned index); vpiHandle vpip_make_vthr_A(char*label, char*symbol); diff --git a/vvp/vpi_tasks.cc b/vvp/vpi_tasks.cc index 6efc00a7d..5b8fe5d27 100644 --- a/vvp/vpi_tasks.cc +++ b/vvp/vpi_tasks.cc @@ -318,7 +318,7 @@ class sysfunc_vec4 : public __vpiSysTaskCall { public: inline sysfunc_vec4(unsigned wid): return_value_(wid, BIT4_X) { } int get_type_code(void) const { return vpiSysFuncCall; } - int vpi_get(int code) { return sysfunc_get(code, this); } + int vpi_get(int code); char* vpi_get_str(int code) { return systask_get_str(code, this); } vpiHandle vpi_put_value(p_vpi_value val, int flags); vpiHandle vpi_handle(int code) @@ -339,6 +339,23 @@ class sysfunc_vec4 : public __vpiSysTaskCall { vvp_vector4_t return_value_; }; +int sysfunc_vec4::vpi_get(int code) +{ + switch (code) { + case vpiSize: + return return_value_.size(); + + case vpiLineNo: + return lineno; + + case vpiUserDefn: + return defn->is_user_defn; + + default: + return vpiUndefined; + } +} + vpiHandle sysfunc_vec4::put_value_scalar_(p_vpi_value vp) { switch (vp->value.scalar) { diff --git a/vvp/vpi_vthr_vector.cc b/vvp/vpi_vthr_vector.cc index c01625202..21e1596f2 100644 --- a/vvp/vpi_vthr_vector.cc +++ b/vvp/vpi_vthr_vector.cc @@ -35,38 +35,6 @@ # include # include "ivl_alloc.h" -extern const char hex_digits[256]; -extern const char oct_digits[64]; - -#if 0 -struct __vpiVThrVec : public __vpiHandle { - __vpiVThrVec(); - int get_type_code(void) const; - int vpi_get(int code); - char* vpi_get_str(int code); - void vpi_get_value(p_vpi_value val); - vpiHandle vpi_put_value(p_vpi_value val, int flags); - - unsigned bas; - unsigned wid; - unsigned signed_flag : 1; - const char *name; -}; -#endif -#if 0 -inline static -vvp_bit4_t get_bit(struct __vpiVThrVec *rfp, unsigned idx) -{ - return vthread_get_bit(vpip_current_vthread, rfp->bas+idx); -} - -inline static -void set_bit(struct __vpiVThrVec *rfp, unsigned idx, vvp_bit4_t bit) -{ - return vthread_put_bit(vpip_current_vthread, rfp->bas+idx, bit); -} -#endif - /* * Hex digits that represent 4-value bits of Verilog are not as * trivially obvious to display as if the bits were the usual 2-value @@ -78,415 +46,10 @@ void set_bit(struct __vpiVThrVec *rfp, unsigned idx, vvp_bit4_t bit) * The table is calculated as compile time, therefore, by the * draw_tt.c program. */ - extern const char hex_digits[256]; - extern const char oct_digits[64]; -#if 0 -/* - * vpi_get - */ -static int vthr_vec_get(int code, vpiHandle ref) -{ - struct __vpiVThrVec*rfp = dynamic_cast<__vpiVThrVec*>(ref); - assert(rfp); - switch (code) { - - case vpiSigned: - return rfp->signed_flag; - - case vpiConstType: - return vpiBinaryConst; // If this is a constant it is Binary. - - case vpiSize: - return rfp->wid; - -#if defined(CHECK_WITH_VALGRIND) || defined(BR916_STOPGAP_FIX) - case _vpiFromThr: - return _vpiVThr; -#endif - - default: - return 0; - } -} -#endif -#if 0 -static char* vthr_vec_get_str(int code, vpiHandle ref) -{ - struct __vpiVThrVec*rfp = dynamic_cast<__vpiVThrVec*>(ref); - assert(rfp); - - switch (code) { - - case vpiFullName: /* should this be vpiName? */ - return simple_set_rbuf_str(rfp->name); - } - - return 0; -} -#endif -#if 0 -static void vthr_vec_DecStrVal(struct __vpiVThrVec*rfp, s_vpi_value*vp) -{ - int nbuf = (rfp->wid+2)/3 + 1; - char *rbuf = need_result_buf(nbuf, RBUF_VAL); - - vvp_vector4_t tmp (rfp->wid); - for (unsigned idx = 0 ; idx < rfp->wid ; idx += 1) - tmp.set_bit(idx, get_bit(rfp, idx)); - - vpip_vec4_to_dec_str(tmp, rbuf, nbuf, rfp->signed_flag); - vp->value.str = rbuf; - - return; -} -#endif -#if 0 -static void vthr_vec_StringVal(struct __vpiVThrVec*rfp, s_vpi_value*vp) -{ - char tmp = 0; - char *rbuf = need_result_buf((rfp->wid / 8) + 1, RBUF_VAL); - char *cp = rbuf; - - for(int bitnr=rfp->wid-1; bitnr>=0; bitnr--){ - tmp <<= 1; - - switch(get_bit(rfp, bitnr)){ - case BIT4_0: - break; - case BIT4_1: - tmp |= 1; - break; - default: - break; - } - - if ((bitnr&7)==0){ - // Don't including leading nulls - if (tmp == 0 && cp == rbuf) - continue; - - // Translated embedded nulls to space. - *cp++ = tmp? tmp : ' '; - tmp = 0; - } - } - *cp++ = 0; - vp->value.str = rbuf; - return; -} -#endif -#if 0 -/* - * The get_value method reads the values of the functors and returns - * the vector to the caller. This causes no side-effect, and reads the - * variables like a %load would. - */ -static void vthr_vec_get_value(vpiHandle ref, s_vpi_value*vp) -{ - struct __vpiVThrVec*rfp = dynamic_cast<__vpiVThrVec*>(ref); - assert(rfp); - char *rbuf; - - unsigned wid = rfp->wid; - - switch (vp->format) { - - case vpiBinStrVal: - rbuf = need_result_buf(wid+1, RBUF_VAL); - for (unsigned idx = 0 ; idx < wid ; idx += 1) { - rbuf[wid-idx-1] = vvp_bit4_to_ascii(get_bit(rfp, idx)); - } - rbuf[wid] = 0; - vp->value.str = rbuf; - break; - - case vpiHexStrVal: { - unsigned hval, hwid; - hwid = (wid + 3) / 4; - rbuf = need_result_buf(hwid+1, RBUF_VAL); - rbuf[hwid] = 0; - hval = 0; - for (unsigned idx = 0 ; idx < wid ; idx += 1) { - unsigned tmp = 0; - switch (get_bit(rfp, idx)) { - case BIT4_0: - tmp = 0; - break; - case BIT4_1: - tmp = 1; - break; - case BIT4_X: - tmp = 2; - break; - case BIT4_Z: - tmp = 3; - break; - } - hval = hval | (tmp << 2*(idx % 4)); - - if (idx%4 == 3) { - hwid -= 1; - rbuf[hwid] = hex_digits[hval]; - hval = 0; - } - } - - if (hwid > 0) { - hwid -= 1; - rbuf[hwid] = hex_digits[hval]; - hval = 0; - } - vp->value.str = rbuf; - break; - } - - case vpiOctStrVal: { - unsigned hval, hwid; - hwid = (wid + 2) / 3; - rbuf = need_result_buf(hwid+1, RBUF_VAL); - rbuf[hwid] = 0; - hval = 0; - for (unsigned idx = 0 ; idx < wid ; idx += 1) { - unsigned tmp = 0; - switch (get_bit(rfp, idx)) { - case BIT4_0: - tmp = 0; - break; - case BIT4_1: - tmp = 1; - break; - case BIT4_X: - tmp = 2; - break; - case BIT4_Z: - tmp = 3; - break; - } - hval = hval | (tmp << 2*(idx % 3)); - - if (idx%3 == 2) { - hwid -= 1; - rbuf[hwid] = oct_digits[hval]; - hval = 0; - } - } - - if (hwid > 0) { - hwid -= 1; - rbuf[hwid] = oct_digits[hval]; - hval = 0; - } - vp->value.str = rbuf; - break; - } - - case vpiDecStrVal: - vthr_vec_DecStrVal(rfp, vp); - break; - - case vpiStringVal: - vthr_vec_StringVal(rfp, vp); - break; - - case vpiIntVal: { - long ival = 0; - for (unsigned idx = 0 ; idx < wid ; idx += 1) { - switch (get_bit(rfp, idx)) { - case BIT4_0: - break; - case BIT4_1: - ival |= 1 << idx; - break; - default: - break; - } - } - vp->value.integer = ival; - } - break; - - case vpiRealVal: - vp->value.real = 0; - for (unsigned idx = wid ; idx > 0 ; idx -= 1) { - vp->value.real *= 2.0; - switch (get_bit(rfp, idx-1)) { - case BIT4_0: - break; - case BIT4_1: - vp->value.real += 1.0; - break; - default: - break; - } - } - break; - - case vpiObjTypeVal: - vp->format = vpiVectorVal; - case vpiVectorVal: - vp->value.vector = (s_vpi_vecval*) - need_result_buf((wid+31)/32*sizeof(s_vpi_vecval), RBUF_VAL); - assert(vp->value.vector); - - for (unsigned idx = 0 ; idx < wid ; idx += 1) { - int word = idx/32; - PLI_INT32 mask = 1 << (idx%32); - - switch (get_bit(rfp,idx)) { - case BIT4_0: - vp->value.vector[word].aval &= ~mask; - vp->value.vector[word].bval &= ~mask; - break; - case BIT4_1: - vp->value.vector[word].aval |= mask; - vp->value.vector[word].bval &= ~mask; - break; - case BIT4_X: - vp->value.vector[word].aval |= mask; - vp->value.vector[word].bval |= mask; - break; - case BIT4_Z: - vp->value.vector[word].aval &= ~mask; - vp->value.vector[word].bval |= mask; - break; - } - } - break; - - default: - fprintf(stderr, "internal error: vpi_get_value()" - " not implemented for vthr_vectors.\n", (int)vp->format); - /* XXXX Not implemented yet. */ - assert(0); - } -} -#endif -#if 0 -/* - * The put_value method writes the value into the vector. - */ -static vpiHandle vthr_vec_put_value(vpiHandle ref, s_vpi_value*vp, int) -{ - struct __vpiVThrVec*rfp = dynamic_cast<__vpiVThrVec*>(ref); - assert(rfp); - - unsigned wid = rfp->wid; - - switch (vp->format) { - - case vpiIntVal: { - assert(wid <= sizeof(long)); - - long val = vp->value.integer; - for (unsigned idx = 0 ; idx < wid ; idx += 1) { - set_bit(rfp, idx, (val&1)? BIT4_1 : BIT4_0); - val >>= 1; - } - break; - } - - case vpiScalarVal: - switch (vp->value.scalar) { - case vpi0: - set_bit(rfp, 0, BIT4_0); - break; - case vpi1: - set_bit(rfp, 0, BIT4_1); - break; - case vpiX: - set_bit(rfp, 0, BIT4_X); - break; - case vpiZ: - set_bit(rfp, 0, BIT4_Z); - break; - default: - fprintf(stderr, "Unsupported scalar value %d.\n", - (int)vp->value.scalar); - assert(0); - } - break; - - case vpiVectorVal: { - assert(wid <= sizeof (unsigned long)); - - unsigned long aval = vp->value.vector->aval; - unsigned long bval = vp->value.vector->bval; - for (unsigned idx = 0 ; idx < wid ; idx += 1) { - int bit = (aval&1) | (((bval^aval)<<1)&2); - switch (bit) { - case 0: - set_bit(rfp, idx, BIT4_0); - break; - case 1: - set_bit(rfp, idx, BIT4_1); - break; - case 2: - set_bit(rfp, idx, BIT4_X); - break; - case 3: - set_bit(rfp, idx, BIT4_Z); - break; - } - aval >>= 1; - bval >>= 1; - } - break; - } - - default: - fprintf(stderr, "Unsupported format %d setting vec4 value.\n", (int)vp->format); - assert(0); - - } - - return ref; -} -#endif - -#if 0 -// The code fully supports vpiReg, vpi_Net, but we do not -// create such things, yet. Lacking a name, for example. - -inline __vpiVThrVec::__vpiVThrVec() -{ } - -int __vpiVThrVec::get_type_code(void) const -{ return vpiConstant; } - -int __vpiVThrVec::vpi_get(int code) -{ return vthr_vec_get(code, this); } - -char* __vpiVThrVec::vpi_get_str(int code) -{ return vthr_vec_get_str(code, this); } - -void __vpiVThrVec::vpi_get_value(p_vpi_value val) -{ vthr_vec_get_value(this, val); } - -vpiHandle __vpiVThrVec::vpi_put_value(p_vpi_value val, int flags) -{ return vthr_vec_put_value(this, val, flags); } -#endif -#if 0 -/* - * Construct a vpiReg object. Give the object specified dimensions, - * and point to the specified functor for the lsb. - */ -vpiHandle vpip_make_vthr_vector(unsigned base, unsigned wid, bool signed_flag) -{ - struct __vpiVThrVec*obj = new __vpiVThrVec; - assert(base < 65536); - obj->bas = base; - assert(wid < 65536); - obj->wid = wid; - obj->signed_flag = signed_flag? 1 : 0; - obj->name = vpip_name_string("T<>"); - - return obj; -} -#endif #ifdef CHECK_WITH_VALGRIND static map handle_map; @@ -719,9 +282,10 @@ void __vpiVThrStrStack::vpi_get_value(p_vpi_value vp) class __vpiVThrVec4Stack : public __vpiHandle { public: - __vpiVThrVec4Stack(unsigned depth, bool signed_flag); + __vpiVThrVec4Stack(unsigned depth, bool signed_flag, unsigned wid); int get_type_code(void) const; int vpi_get(int code); + char*vpi_get_str(int code); void vpi_get_value(p_vpi_value val); vpiHandle vpi_put_value(p_vpi_value val, int flags); private: @@ -734,11 +298,14 @@ class __vpiVThrVec4Stack : public __vpiHandle { private: unsigned depth_; bool signed_flag_; + unsigned expect_width_; + const char*name; }; -__vpiVThrVec4Stack::__vpiVThrVec4Stack(unsigned d, bool sf) -: depth_(d), signed_flag_(sf) +__vpiVThrVec4Stack::__vpiVThrVec4Stack(unsigned d, bool sf, unsigned wid) +: depth_(d), signed_flag_(sf), expect_width_(wid) { + name = vpip_name_string("S<,vec4,>"); } int __vpiVThrVec4Stack::get_type_code(void) const @@ -748,8 +315,11 @@ int __vpiVThrVec4Stack::get_type_code(void) const int __vpiVThrVec4Stack::vpi_get(int code) { switch (code) { + case vpiSize: + return expect_width_; + case vpiSigned: - return 0; + return signed_flag_? 1 : 0; case vpiConstType: return vpiBinaryConst; @@ -764,6 +334,17 @@ int __vpiVThrVec4Stack::vpi_get(int code) } } +char*__vpiVThrVec4Stack::vpi_get_str(int code) +{ + switch (code) { + case vpiFullName: + return simple_set_rbuf_str(name); + + default: + return 0; + } +} + void __vpiVThrVec4Stack::vpi_get_value(p_vpi_value vp) { assert(vpip_current_vthread); @@ -956,9 +537,9 @@ vpiHandle vpip_make_vthr_str_stack(unsigned depth) return obj; } -vpiHandle vpip_make_vthr_vec4_stack(unsigned depth, bool signed_flag) +vpiHandle vpip_make_vthr_vec4_stack(unsigned depth, bool signed_flag, unsigned wid) { - class __vpiVThrVec4Stack*obj = new __vpiVThrVec4Stack(depth, signed_flag); + class __vpiVThrVec4Stack*obj = new __vpiVThrVec4Stack(depth, signed_flag, wid); return obj; }