2001-05-10 02:26:53 +02:00
|
|
|
/*
|
|
|
|
|
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
|
|
|
|
|
* Copyright (c) 2001 Stephan Boettcher <stephan@nevis.columbia.edu>
|
|
|
|
|
*
|
|
|
|
|
* This source code is free software; you can redistribute it
|
|
|
|
|
* and/or modify it in source code form under the terms of the GNU
|
|
|
|
|
* General Public License as published by the Free Software
|
|
|
|
|
* Foundation; either version 2 of the License, or (at your option)
|
|
|
|
|
* any later version.
|
|
|
|
|
*
|
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
|
*
|
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
|
|
|
|
*/
|
2002-08-12 03:34:58 +02:00
|
|
|
#ifdef HAVE_CVS_IDENT
|
2003-05-28 05:10:52 +02:00
|
|
|
#ident "$Id: vpi_vthr_vector.cc,v 1.15 2003/05/28 03:10:52 steve Exp $"
|
2001-05-10 02:26:53 +02:00
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* vpiReg handles are handled here. These objects represent vectors of
|
|
|
|
|
* .var objects that can be manipulated by the VPI module.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
# include "vpi_priv.h"
|
|
|
|
|
# include "vthread.h"
|
|
|
|
|
# include <stdio.h>
|
2001-09-15 20:27:04 +02:00
|
|
|
#ifdef HAVE_MALLOC_H
|
2001-05-10 02:26:53 +02:00
|
|
|
# include <malloc.h>
|
2001-09-15 20:27:04 +02:00
|
|
|
#endif
|
|
|
|
|
# include <stdlib.h>
|
2001-05-10 02:26:53 +02:00
|
|
|
# include <assert.h>
|
|
|
|
|
|
|
|
|
|
struct __vpiVThrVec {
|
|
|
|
|
struct __vpiHandle base;
|
|
|
|
|
unsigned short bas;
|
|
|
|
|
unsigned short wid;
|
2002-04-14 04:56:19 +02:00
|
|
|
unsigned signed_flag : 1;
|
2001-05-10 02:26:53 +02:00
|
|
|
char *name;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
inline static
|
|
|
|
|
unsigned 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, unsigned bit)
|
|
|
|
|
{
|
|
|
|
|
return vthread_put_bit(vpip_current_vthread, rfp->bas+idx, bit);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* 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
|
|
|
|
|
* bits. So, although it is possible to write a function that
|
|
|
|
|
* generates a correct character for 4*4-value bits, it is easier to
|
|
|
|
|
* just perform the lookup in a table. This only takes 256 bytes,
|
|
|
|
|
* which is not many executable instructions:-)
|
|
|
|
|
*
|
|
|
|
|
* 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[256];
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* vpi_get
|
|
|
|
|
*/
|
|
|
|
|
static int vthr_vec_get(int code, vpiHandle ref)
|
|
|
|
|
{
|
|
|
|
|
assert((ref->vpi_type->type_code==vpiNet)
|
|
|
|
|
|| (ref->vpi_type->type_code==vpiReg)
|
|
|
|
|
|| (ref->vpi_type->type_code==vpiConstant));
|
|
|
|
|
|
|
|
|
|
struct __vpiVThrVec*rfp = (struct __vpiVThrVec*)ref;
|
|
|
|
|
|
|
|
|
|
switch (code) {
|
|
|
|
|
|
|
|
|
|
case vpiSigned:
|
2002-04-14 04:56:19 +02:00
|
|
|
return rfp->signed_flag;
|
2001-05-10 02:26:53 +02:00
|
|
|
|
|
|
|
|
case vpiSize:
|
|
|
|
|
return rfp->wid;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static char* vthr_vec_get_str(int code, vpiHandle ref)
|
|
|
|
|
{
|
|
|
|
|
assert((ref->vpi_type->type_code==vpiNet)
|
|
|
|
|
|| (ref->vpi_type->type_code==vpiReg));
|
|
|
|
|
|
|
|
|
|
struct __vpiVThrVec*rfp = (struct __vpiVThrVec*)ref;
|
|
|
|
|
|
|
|
|
|
switch (code) {
|
|
|
|
|
|
|
|
|
|
case vpiFullName:
|
|
|
|
|
return (char*)rfp->name;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void vthr_vec_DecStrVal(struct __vpiVThrVec*rfp, s_vpi_value*vp)
|
|
|
|
|
{
|
2002-04-14 04:56:19 +02:00
|
|
|
unsigned char*bits = new unsigned char[rfp->wid];
|
2003-03-13 05:59:21 +01:00
|
|
|
char *rbuf = need_result_buf((rfp->wid+2)/3 + 1, RBUF_VAL);
|
|
|
|
|
|
2002-04-14 04:56:19 +02:00
|
|
|
for (unsigned idx = 0 ; idx < rfp->wid ; idx += 1)
|
|
|
|
|
bits[idx] = get_bit(rfp, idx);
|
2001-05-10 02:26:53 +02:00
|
|
|
|
2003-03-13 05:59:21 +01:00
|
|
|
vpip_bits_to_dec_str(bits, rfp->wid, rbuf, rfp->wid+1, rfp->signed_flag);
|
|
|
|
|
vp->value.str = rbuf;
|
|
|
|
|
|
|
|
|
|
return;
|
2001-05-10 02:26:53 +02:00
|
|
|
}
|
|
|
|
|
|
2001-12-30 22:31:38 +01:00
|
|
|
static void vthr_vec_StringVal(struct __vpiVThrVec*rfp, s_vpi_value*vp)
|
|
|
|
|
{
|
2002-01-10 02:54:04 +01:00
|
|
|
char tmp = 0;
|
2003-03-13 05:59:21 +01:00
|
|
|
char *rbuf = need_result_buf((rfp->wid / 8) + 1, RBUF_VAL);
|
|
|
|
|
char *cp = rbuf;
|
2001-12-30 22:31:38 +01:00
|
|
|
|
2002-01-10 02:54:04 +01:00
|
|
|
for(int bitnr=rfp->wid-1; bitnr>=0; bitnr--){
|
|
|
|
|
tmp <<= 1;
|
2001-12-30 22:31:38 +01:00
|
|
|
|
2002-01-10 02:54:04 +01:00
|
|
|
switch(get_bit(rfp, bitnr)){
|
|
|
|
|
case 0:
|
|
|
|
|
break;
|
|
|
|
|
case 1:
|
|
|
|
|
tmp |= 1;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((bitnr&7)==0){
|
|
|
|
|
*cp++ = tmp? tmp : ' ';
|
|
|
|
|
tmp = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
*cp++ = 0;
|
2003-03-13 05:59:21 +01:00
|
|
|
vp->value.str = rbuf;
|
2002-01-10 02:54:04 +01:00
|
|
|
return;
|
2001-12-30 22:31:38 +01:00
|
|
|
}
|
|
|
|
|
|
2001-05-10 02:26:53 +02:00
|
|
|
/*
|
|
|
|
|
* 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)
|
|
|
|
|
{
|
|
|
|
|
assert((ref->vpi_type->type_code==vpiNet)
|
|
|
|
|
|| (ref->vpi_type->type_code==vpiReg)
|
|
|
|
|
|| (ref->vpi_type->type_code==vpiConstant));
|
|
|
|
|
|
|
|
|
|
struct __vpiVThrVec*rfp = (struct __vpiVThrVec*)ref;
|
2003-03-13 05:59:21 +01:00
|
|
|
char *rbuf;
|
2001-05-10 02:26:53 +02:00
|
|
|
|
|
|
|
|
unsigned wid = rfp->wid;
|
|
|
|
|
|
|
|
|
|
switch (vp->format) {
|
|
|
|
|
|
|
|
|
|
case vpiBinStrVal:
|
2003-03-13 05:59:21 +01:00
|
|
|
rbuf = need_result_buf(wid+1, RBUF_VAL);
|
2001-05-10 02:26:53 +02:00
|
|
|
for (unsigned idx = 0 ; idx < wid ; idx += 1) {
|
2003-03-13 05:59:21 +01:00
|
|
|
rbuf[wid-idx-1] = "01xz"[get_bit(rfp, idx)];
|
2001-05-10 02:26:53 +02:00
|
|
|
}
|
2003-03-13 05:59:21 +01:00
|
|
|
rbuf[wid] = 0;
|
|
|
|
|
vp->value.str = rbuf;
|
2001-05-10 02:26:53 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case vpiHexStrVal: {
|
|
|
|
|
unsigned hval, hwid;
|
|
|
|
|
hwid = (wid + 3) / 4;
|
2003-03-13 05:59:21 +01:00
|
|
|
rbuf = need_result_buf(hwid+1, RBUF_VAL);
|
|
|
|
|
rbuf[hwid] = 0;
|
2001-05-10 02:26:53 +02:00
|
|
|
hval = 0;
|
|
|
|
|
for (unsigned idx = 0 ; idx < wid ; idx += 1) {
|
|
|
|
|
hval = hval | (get_bit(rfp, idx) << 2*(idx % 4));
|
|
|
|
|
|
|
|
|
|
if (idx%4 == 3) {
|
|
|
|
|
hwid -= 1;
|
2003-03-13 05:59:21 +01:00
|
|
|
rbuf[hwid] = hex_digits[hval];
|
2001-05-10 02:26:53 +02:00
|
|
|
hval = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (hwid > 0) {
|
|
|
|
|
hwid -= 1;
|
2003-03-13 05:59:21 +01:00
|
|
|
rbuf[hwid] = hex_digits[hval];
|
2001-05-10 02:26:53 +02:00
|
|
|
hval = 0;
|
|
|
|
|
}
|
2003-03-13 05:59:21 +01:00
|
|
|
vp->value.str = rbuf;
|
2001-05-10 02:26:53 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case vpiOctStrVal: {
|
|
|
|
|
unsigned hval, hwid;
|
|
|
|
|
hwid = (wid + 2) / 3;
|
2003-03-13 05:59:21 +01:00
|
|
|
rbuf = need_result_buf(hwid+1, RBUF_VAL);
|
|
|
|
|
rbuf[hwid] = 0;
|
2001-05-10 02:26:53 +02:00
|
|
|
hval = 0;
|
|
|
|
|
for (unsigned idx = 0 ; idx < wid ; idx += 1) {
|
|
|
|
|
hval = hval | (get_bit(rfp,idx) << 2*(idx % 3));
|
|
|
|
|
|
|
|
|
|
if (idx%3 == 2) {
|
|
|
|
|
hwid -= 1;
|
2003-03-13 05:59:21 +01:00
|
|
|
rbuf[hwid] = oct_digits[hval];
|
2001-05-10 02:26:53 +02:00
|
|
|
hval = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (hwid > 0) {
|
|
|
|
|
hwid -= 1;
|
2003-03-13 05:59:21 +01:00
|
|
|
rbuf[hwid] = oct_digits[hval];
|
2001-05-10 02:26:53 +02:00
|
|
|
hval = 0;
|
|
|
|
|
}
|
2003-03-13 05:59:21 +01:00
|
|
|
vp->value.str = rbuf;
|
2001-05-10 02:26:53 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case vpiDecStrVal:
|
|
|
|
|
vthr_vec_DecStrVal(rfp, vp);
|
|
|
|
|
break;
|
|
|
|
|
|
2001-12-30 22:31:38 +01:00
|
|
|
case vpiStringVal:
|
|
|
|
|
vthr_vec_StringVal(rfp, vp);
|
|
|
|
|
break;
|
|
|
|
|
|
2002-05-12 02:32:21 +02:00
|
|
|
case vpiIntVal:
|
|
|
|
|
vp->value.integer = 0;
|
|
|
|
|
for (unsigned idx = 0 ; idx < wid ; idx += 1) {
|
|
|
|
|
switch (get_bit(rfp, idx)) {
|
|
|
|
|
case 0:
|
|
|
|
|
break;
|
|
|
|
|
case 1:
|
|
|
|
|
vp->value.integer |= 1 << idx;
|
|
|
|
|
break;
|
|
|
|
|
case 2:
|
|
|
|
|
case 3:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
2001-05-10 02:26:53 +02:00
|
|
|
default:
|
|
|
|
|
/* XXXX Not implemented yet. */
|
|
|
|
|
assert(0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* The put_value method writes the value into the vector.
|
|
|
|
|
*/
|
|
|
|
|
static vpiHandle vthr_vec_put_value(vpiHandle ref, s_vpi_value*vp,
|
|
|
|
|
p_vpi_time when, int flags)
|
|
|
|
|
{
|
|
|
|
|
assert((ref->vpi_type->type_code==vpiNet)
|
|
|
|
|
|| (ref->vpi_type->type_code==vpiReg));
|
|
|
|
|
|
|
|
|
|
struct __vpiVThrVec*rfp = (struct __vpiVThrVec*)ref;
|
|
|
|
|
|
|
|
|
|
/* XXXX delays are not yet supported. */
|
|
|
|
|
assert(flags == vpiNoDelay);
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
val >>= 1;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case vpiScalarVal:
|
|
|
|
|
switch (vp->value.scalar) {
|
|
|
|
|
case vpi0:
|
|
|
|
|
set_bit(rfp, 0, 0);
|
|
|
|
|
break;
|
|
|
|
|
case vpi1:
|
|
|
|
|
set_bit(rfp, 0, 1);
|
|
|
|
|
break;
|
|
|
|
|
case vpiX:
|
|
|
|
|
set_bit(rfp, 0, 2);
|
|
|
|
|
break;
|
|
|
|
|
case vpiZ:
|
|
|
|
|
set_bit(rfp, 0, 3);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
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);
|
|
|
|
|
set_bit(rfp, idx, bit);
|
|
|
|
|
aval >>= 1;
|
|
|
|
|
bval >>= 1;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
assert(0);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ref;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// The code fully supports vpiReg, vpi_Net, but we do not
|
2003-02-10 00:33:26 +01:00
|
|
|
// create such things, yet. Lacking a name, for example.
|
2001-05-10 02:26:53 +02:00
|
|
|
|
|
|
|
|
static const struct __vpirt vpip_vthr_const_rt = {
|
|
|
|
|
vpiConstant,
|
|
|
|
|
vthr_vec_get,
|
|
|
|
|
vthr_vec_get_str,
|
|
|
|
|
vthr_vec_get_value,
|
|
|
|
|
vthr_vec_put_value,
|
|
|
|
|
0,
|
|
|
|
|
0
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Construct a vpiReg object. Give the object specified dimensions,
|
|
|
|
|
* and point to the specified functor for the lsb.
|
|
|
|
|
*/
|
2002-04-14 04:56:19 +02:00
|
|
|
vpiHandle vpip_make_vthr_vector(unsigned base, unsigned wid, bool signed_flag)
|
2001-05-10 02:26:53 +02:00
|
|
|
{
|
|
|
|
|
struct __vpiVThrVec*obj = (struct __vpiVThrVec*)
|
|
|
|
|
malloc(sizeof(struct __vpiVThrVec));
|
|
|
|
|
obj->base.vpi_type = &vpip_vthr_const_rt;
|
2003-05-28 05:10:52 +02:00
|
|
|
assert(base < 65536);
|
2001-05-10 02:26:53 +02:00
|
|
|
obj->bas = base;
|
2003-05-28 05:10:52 +02:00
|
|
|
assert(wid < 65536);
|
2001-05-10 02:26:53 +02:00
|
|
|
obj->wid = wid;
|
2002-04-14 04:56:19 +02:00
|
|
|
obj->signed_flag = signed_flag? 1 : 0;
|
2001-05-10 02:26:53 +02:00
|
|
|
obj->name = "T<>";
|
|
|
|
|
|
|
|
|
|
return &obj->base;
|
|
|
|
|
}
|
|
|
|
|
|
2003-01-26 19:16:22 +01:00
|
|
|
struct __vpiVThrWord {
|
|
|
|
|
struct __vpiHandle base;
|
|
|
|
|
char* name;
|
|
|
|
|
int subtype;
|
|
|
|
|
unsigned short index;
|
|
|
|
|
};
|
|
|
|
|
|
2003-02-06 18:41:33 +01:00
|
|
|
static int vthr_word_get(int code, vpiHandle ref)
|
|
|
|
|
{
|
|
|
|
|
assert(ref->vpi_type->type_code==vpiConstant);
|
|
|
|
|
|
|
|
|
|
struct __vpiVThrWord*rfp = (struct __vpiVThrWord*)ref;
|
|
|
|
|
|
|
|
|
|
switch (code) {
|
|
|
|
|
|
|
|
|
|
case vpiConstType:
|
|
|
|
|
return rfp->subtype;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2003-01-26 19:16:22 +01:00
|
|
|
static void vthr_real_get_value(vpiHandle ref, s_vpi_value*vp)
|
|
|
|
|
{
|
|
|
|
|
assert(ref->vpi_type->type_code==vpiConstant);
|
|
|
|
|
|
|
|
|
|
struct __vpiVThrWord*obj = (struct __vpiVThrWord*)ref;
|
2003-03-13 05:59:21 +01:00
|
|
|
char *rbuf = need_result_buf(66, RBUF_VAL);
|
2003-03-01 01:46:13 +01:00
|
|
|
|
|
|
|
|
double val = 0.0;
|
|
|
|
|
|
|
|
|
|
/* Get the actual value from the index. It is possible, by the
|
|
|
|
|
way, that the vpi_get_value is called from compiletf. If
|
|
|
|
|
that's the case, there will be no current thread, and this
|
|
|
|
|
will not have access to the proper value. Punt and return a
|
|
|
|
|
0.0 value instead. */
|
|
|
|
|
if (vpip_current_vthread)
|
|
|
|
|
val = vthread_get_real(vpip_current_vthread, obj->index);
|
2003-01-26 19:16:22 +01:00
|
|
|
|
|
|
|
|
switch (vp->format) {
|
|
|
|
|
|
|
|
|
|
case vpiObjTypeVal:
|
|
|
|
|
vp->format = vpiRealVal;
|
|
|
|
|
case vpiRealVal:
|
|
|
|
|
vp->value.real = val;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case vpiDecStrVal:
|
2003-03-13 05:59:21 +01:00
|
|
|
sprintf(rbuf, "%0.0f", val);
|
|
|
|
|
vp->value.str = rbuf;
|
2003-01-26 19:16:22 +01:00
|
|
|
break;
|
|
|
|
|
|
2003-02-04 05:03:40 +01:00
|
|
|
case vpiHexStrVal:
|
2003-03-13 05:59:21 +01:00
|
|
|
sprintf(rbuf, "%lx", (long)val);
|
|
|
|
|
vp->value.str = rbuf;
|
2003-02-04 05:03:40 +01:00
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case vpiBinStrVal: {
|
|
|
|
|
unsigned long vali = (unsigned long)val;
|
|
|
|
|
unsigned len = 0;
|
|
|
|
|
|
|
|
|
|
while (vali > 0) {
|
|
|
|
|
len += 1;
|
|
|
|
|
vali /= 2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
vali = (unsigned long)val;
|
|
|
|
|
for (unsigned idx = 0 ; idx < len ; idx += 1) {
|
2003-03-13 05:59:21 +01:00
|
|
|
rbuf[len-idx-1] = (vali & 1)? '1' : '0';
|
2003-02-04 05:03:40 +01:00
|
|
|
vali /= 2;
|
|
|
|
|
}
|
|
|
|
|
|
2003-03-13 05:59:21 +01:00
|
|
|
rbuf[len] = 0;
|
2003-02-04 05:03:40 +01:00
|
|
|
if (len == 0) {
|
2003-03-13 05:59:21 +01:00
|
|
|
rbuf[0] = '0';
|
|
|
|
|
rbuf[1] = 0;
|
2003-02-04 05:03:40 +01:00
|
|
|
}
|
2003-03-13 05:59:21 +01:00
|
|
|
vp->value.str = rbuf;
|
2003-02-04 05:03:40 +01:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2003-01-26 19:16:22 +01:00
|
|
|
default:
|
|
|
|
|
vp->format = vpiSuppressVal;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static const struct __vpirt vpip_vthr_const_real_rt = {
|
|
|
|
|
vpiConstant,
|
2003-02-06 18:41:33 +01:00
|
|
|
vthr_word_get,
|
2003-01-26 19:16:22 +01:00
|
|
|
0,
|
|
|
|
|
vthr_real_get_value,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
0
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
vpiHandle vpip_make_vthr_word(unsigned base, const char*type)
|
|
|
|
|
{
|
|
|
|
|
struct __vpiVThrWord*obj = (struct __vpiVThrWord*)
|
|
|
|
|
malloc(sizeof(struct __vpiVThrWord));
|
|
|
|
|
|
|
|
|
|
assert(type[0] == 'r');
|
|
|
|
|
|
|
|
|
|
obj->base.vpi_type = &vpip_vthr_const_real_rt;
|
|
|
|
|
obj->name = "W<>";
|
|
|
|
|
obj->subtype = vpiRealConst;
|
2003-05-28 05:10:52 +02:00
|
|
|
assert(base < 65536);
|
2003-01-26 19:16:22 +01:00
|
|
|
obj->index = base;
|
|
|
|
|
|
|
|
|
|
return &obj->base;
|
|
|
|
|
}
|
2001-05-10 02:26:53 +02:00
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* $Log: vpi_vthr_vector.cc,v $
|
2003-05-28 05:10:52 +02:00
|
|
|
* Revision 1.15 2003/05/28 03:10:52 steve
|
|
|
|
|
* Some asserts that check for thread vector overflow.
|
|
|
|
|
*
|
2003-03-13 05:59:21 +01:00
|
|
|
* Revision 1.14 2003/03/13 04:59:21 steve
|
|
|
|
|
* Use rbufs instead of static buffers.
|
|
|
|
|
*
|
2003-03-01 01:46:13 +01:00
|
|
|
* Revision 1.13 2003/03/01 00:46:13 steve
|
|
|
|
|
* Careful about compiletf calls.
|
|
|
|
|
*
|
2003-02-10 00:33:26 +01:00
|
|
|
* Revision 1.12 2003/02/09 23:33:26 steve
|
|
|
|
|
* Spelling fixes.
|
|
|
|
|
*
|
2003-02-06 18:41:33 +01:00
|
|
|
* Revision 1.11 2003/02/06 17:41:33 steve
|
|
|
|
|
* Support constant types for thread words.
|
|
|
|
|
*
|
2003-02-04 05:03:40 +01:00
|
|
|
* Revision 1.10 2003/02/04 04:03:40 steve
|
|
|
|
|
* Add hex and binary formatting of real values.
|
|
|
|
|
*
|
2003-01-26 19:16:22 +01:00
|
|
|
* Revision 1.9 2003/01/26 18:16:22 steve
|
|
|
|
|
* Add %cvt/ir and %cvt/ri instructions, and support
|
|
|
|
|
* real values passed as arguments to VPI tasks.
|
|
|
|
|
*
|
2002-08-12 03:34:58 +02:00
|
|
|
* Revision 1.8 2002/08/12 01:35:09 steve
|
|
|
|
|
* conditional ident string using autoconfig.
|
|
|
|
|
*
|
2002-05-12 02:32:21 +02:00
|
|
|
* Revision 1.7 2002/05/12 00:32:21 steve
|
|
|
|
|
* Get thread vectors by vpiIntVal.
|
|
|
|
|
*
|
2002-04-14 04:56:19 +02:00
|
|
|
* Revision 1.6 2002/04/14 02:56:19 steve
|
|
|
|
|
* Support signed expressions through to VPI.
|
|
|
|
|
*
|
2002-01-10 02:54:04 +01:00
|
|
|
* Revision 1.5 2002/01/10 01:54:04 steve
|
|
|
|
|
* odd width thread vectors as strings.
|
|
|
|
|
*
|
2001-12-30 22:31:38 +01:00
|
|
|
* Revision 1.4 2001/12/30 21:31:38 steve
|
|
|
|
|
* Support vpiStringVal in vhtread vectors.
|
|
|
|
|
*
|
2001-09-15 20:27:04 +02:00
|
|
|
* Revision 1.3 2001/09/15 18:27:05 steve
|
|
|
|
|
* Make configure detect malloc.h
|
|
|
|
|
*
|
2001-05-20 02:40:12 +02:00
|
|
|
* Revision 1.2 2001/05/20 00:40:12 steve
|
|
|
|
|
* Get bit ordering right when making decimal strings.
|
|
|
|
|
*
|
2001-05-10 02:26:53 +02:00
|
|
|
* Revision 1.1 2001/05/10 00:26:53 steve
|
|
|
|
|
* VVP support for memories in expressions,
|
|
|
|
|
* including general support for thread bit
|
|
|
|
|
* vectors as system task parameters.
|
|
|
|
|
* (Stephan Boettcher)
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
|