WRap up vec4 support for system function calls.
This commit is contained in:
parent
660d59a7a9
commit
c6c697bdb7
243
vvp/vpi_tasks.cc
243
vvp/vpi_tasks.cc
|
|
@ -150,140 +150,6 @@ struct systask_def : public __vpiSysTaskCall {
|
||||||
vpiHandle vpi_iterate(int code){ return systask_iter(code, this); }
|
vpiHandle vpi_iterate(int code){ return systask_iter(code, this); }
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
* A value *can* be put to a vpiSysFuncCall object. This is how the
|
|
||||||
* return value is set. The value that is given should be converted to
|
|
||||||
* bits and set into the thread space bits that were selected at
|
|
||||||
* compile time.
|
|
||||||
*/
|
|
||||||
static vpiHandle sysfunc_put_value(vpiHandle ref, p_vpi_value vp, int)
|
|
||||||
{
|
|
||||||
struct __vpiSysTaskCall*rfp = dynamic_cast<__vpiSysTaskCall*>(ref);
|
|
||||||
assert(rfp);
|
|
||||||
|
|
||||||
rfp->put_value = true;
|
|
||||||
|
|
||||||
assert(rfp->vbit >= 4);
|
|
||||||
|
|
||||||
switch (vp->format) {
|
|
||||||
|
|
||||||
case vpiIntVal: {
|
|
||||||
long val = vp->value.integer;
|
|
||||||
for (int idx = 0 ; idx < rfp->vwid ; idx += 1) {
|
|
||||||
vthread_put_bit(vpip_current_vthread,
|
|
||||||
rfp->vbit+idx, (val&1)? BIT4_1 :BIT4_0);
|
|
||||||
val >>= 1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case vpiTimeVal:
|
|
||||||
for (int idx = 0 ; idx < rfp->vwid ; idx += 1) {
|
|
||||||
PLI_INT32 word;
|
|
||||||
if (idx >= 32)
|
|
||||||
word = vp->value.time->high;
|
|
||||||
else
|
|
||||||
word = vp->value.time->low;
|
|
||||||
|
|
||||||
word >>= idx % 32;
|
|
||||||
|
|
||||||
vthread_put_bit(vpip_current_vthread,
|
|
||||||
rfp->vbit+idx, (word&1)? BIT4_1 :BIT4_0);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case vpiScalarVal:
|
|
||||||
switch (vp->value.scalar) {
|
|
||||||
case vpi0:
|
|
||||||
vthread_put_bit(vpip_current_vthread, rfp->vbit, BIT4_0);
|
|
||||||
break;
|
|
||||||
case vpi1:
|
|
||||||
vthread_put_bit(vpip_current_vthread, rfp->vbit, BIT4_1);
|
|
||||||
break;
|
|
||||||
case vpiX:
|
|
||||||
vthread_put_bit(vpip_current_vthread, rfp->vbit, BIT4_X);
|
|
||||||
break;
|
|
||||||
case vpiZ:
|
|
||||||
vthread_put_bit(vpip_current_vthread, rfp->vbit, BIT4_Z);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
fprintf(stderr, "Unsupported value %d.\n",
|
|
||||||
(int)vp->value.scalar);
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case vpiStringVal: {
|
|
||||||
unsigned len = strlen(vp->value.str) - 1;
|
|
||||||
assert(len*8 <= (unsigned)rfp->vwid);
|
|
||||||
for (unsigned wdx = 0 ; wdx < (unsigned)rfp->vwid ; wdx += 8) {
|
|
||||||
unsigned word = wdx / 8;
|
|
||||||
char bits;
|
|
||||||
if (word <= len) {
|
|
||||||
bits = vp->value.str[len-word];
|
|
||||||
} else {
|
|
||||||
bits = 0;
|
|
||||||
}
|
|
||||||
for (unsigned idx = 0 ; (wdx+idx) < (unsigned)rfp->vwid &&
|
|
||||||
idx < 8; idx += 1) {
|
|
||||||
vvp_bit4_t bit4 = BIT4_0;
|
|
||||||
if (bits & 1) bit4 = BIT4_1;
|
|
||||||
vthread_put_bit(vpip_current_vthread,
|
|
||||||
rfp->vbit+wdx+idx, bit4);
|
|
||||||
bits >>= 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case vpiVectorVal:
|
|
||||||
|
|
||||||
for (unsigned wdx = 0 ; wdx < (unsigned)rfp->vwid ; wdx += 32) {
|
|
||||||
unsigned word = wdx / 32;
|
|
||||||
unsigned long aval = vp->value.vector[word].aval;
|
|
||||||
unsigned long bval = vp->value.vector[word].bval;
|
|
||||||
|
|
||||||
for (unsigned idx = 0 ; (wdx+idx) < (unsigned)rfp->vwid &&
|
|
||||||
idx < 32; idx += 1)
|
|
||||||
{
|
|
||||||
int bit = (aval&1) | ((bval<<1)&2);
|
|
||||||
vvp_bit4_t bit4;
|
|
||||||
|
|
||||||
switch (bit) {
|
|
||||||
case 0:
|
|
||||||
bit4 = BIT4_0;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
bit4 = BIT4_1;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
bit4 = BIT4_Z;
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
bit4 = BIT4_X;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
bit4 = BIT4_X;
|
|
||||||
fprintf(stderr, "Unsupported bit value %d.\n",
|
|
||||||
bit);
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
vthread_put_bit(vpip_current_vthread,
|
|
||||||
rfp->vbit+wdx+idx, bit4);
|
|
||||||
|
|
||||||
aval >>= 1;
|
|
||||||
bval >>= 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
fprintf(stderr, "Unsupported format %d.\n", (int)vp->format);
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static vpiHandle sysfunc_put_4net_value(vpiHandle ref, p_vpi_value vp, int)
|
static vpiHandle sysfunc_put_4net_value(vpiHandle ref, p_vpi_value vp, int)
|
||||||
{
|
{
|
||||||
|
|
@ -417,19 +283,6 @@ static vpiHandle sysfunc_put_no_value(vpiHandle, p_vpi_value, int)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct sysfunc_def : public __vpiSysTaskCall {
|
|
||||||
inline sysfunc_def() { }
|
|
||||||
int get_type_code(void) const { return vpiSysFuncCall; }
|
|
||||||
int vpi_get(int code) { return sysfunc_get(code, this); }
|
|
||||||
char* vpi_get_str(int code) { return systask_get_str(code, this); }
|
|
||||||
vpiHandle vpi_put_value(p_vpi_value val, int flags)
|
|
||||||
{ return sysfunc_put_value(this, val, flags); }
|
|
||||||
vpiHandle vpi_handle(int code)
|
|
||||||
{ return systask_handle(code, this); }
|
|
||||||
vpiHandle vpi_iterate(int code)
|
|
||||||
{ return systask_iter(code, this); }
|
|
||||||
};
|
|
||||||
|
|
||||||
struct sysfunc_real : public __vpiSysTaskCall {
|
struct sysfunc_real : public __vpiSysTaskCall {
|
||||||
inline sysfunc_real() { }
|
inline sysfunc_real() { }
|
||||||
int get_type_code(void) const { return vpiSysFuncCall; }
|
int get_type_code(void) const { return vpiSysFuncCall; }
|
||||||
|
|
@ -476,13 +329,38 @@ class sysfunc_vec4 : public __vpiSysTaskCall {
|
||||||
inline const vvp_vector4_t& return_value() const { return return_value_; }
|
inline const vvp_vector4_t& return_value() const { return return_value_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
vpiHandle put_value_scalar_(p_vpi_value vp);
|
||||||
vpiHandle put_value_int_(p_vpi_value vp);
|
vpiHandle put_value_int_(p_vpi_value vp);
|
||||||
|
vpiHandle put_value_string_(p_vpi_value vp);
|
||||||
|
vpiHandle put_value_vector_(p_vpi_value vp);
|
||||||
vpiHandle put_value_time_(p_vpi_value vp);
|
vpiHandle put_value_time_(p_vpi_value vp);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
vvp_vector4_t return_value_;
|
vvp_vector4_t return_value_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
vpiHandle sysfunc_vec4::put_value_scalar_(p_vpi_value vp)
|
||||||
|
{
|
||||||
|
switch (vp->value.scalar) {
|
||||||
|
case vpi0:
|
||||||
|
return_value_.set_bit(0, BIT4_0);
|
||||||
|
break;
|
||||||
|
case vpi1:
|
||||||
|
return_value_.set_bit(0, BIT4_1);
|
||||||
|
break;
|
||||||
|
case vpiX:
|
||||||
|
return_value_.set_bit(0, BIT4_X);
|
||||||
|
break;
|
||||||
|
case vpiZ:
|
||||||
|
return_value_.set_bit(0, BIT4_Z);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fprintf(stderr, "Unsupported value %d.\n", (int)vp->value.scalar);
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
vpiHandle sysfunc_vec4::put_value_int_(p_vpi_value vp)
|
vpiHandle sysfunc_vec4::put_value_int_(p_vpi_value vp)
|
||||||
{
|
{
|
||||||
long tmp = vp->value.integer;
|
long tmp = vp->value.integer;
|
||||||
|
|
@ -495,6 +373,66 @@ vpiHandle sysfunc_vec4::put_value_int_(p_vpi_value vp)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vpiHandle sysfunc_vec4::put_value_string_(p_vpi_value vp)
|
||||||
|
{
|
||||||
|
size_t slen = strlen(vp->value.str);
|
||||||
|
unsigned wid = return_value_.size();
|
||||||
|
|
||||||
|
for (unsigned idx = 0 ; idx < wid ; idx += 1) {
|
||||||
|
unsigned cidx = idx / 8;
|
||||||
|
// If wider then the string, then pad with zero.
|
||||||
|
if (cidx >= slen) {
|
||||||
|
return_value_.set_bit(idx, BIT4_0);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Put the end of the string in the LSB of the vector
|
||||||
|
char use_char = vp->value.str[slen - 1 - cidx];
|
||||||
|
|
||||||
|
if ((use_char >> (idx % 8)) & 1)
|
||||||
|
return_value_.set_bit(idx, BIT4_1);
|
||||||
|
else
|
||||||
|
return_value_.set_bit(idx, BIT4_0);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
vpiHandle sysfunc_vec4::put_value_vector_(p_vpi_value vp)
|
||||||
|
{
|
||||||
|
unsigned width = return_value_.size();
|
||||||
|
for (unsigned idx = 0 ; idx < width ; idx += 1) {
|
||||||
|
unsigned word = idx / 32;
|
||||||
|
unsigned bidx = idx % 32;
|
||||||
|
|
||||||
|
unsigned long aval = vp->value.vector[word].aval >> bidx;
|
||||||
|
unsigned long bval = vp->value.vector[word].bval >> bidx;
|
||||||
|
|
||||||
|
int bit = (aval&1) | ((bval<<1)&2);
|
||||||
|
vvp_bit4_t bit4;
|
||||||
|
|
||||||
|
switch (bit) {
|
||||||
|
case 0:
|
||||||
|
bit4 = BIT4_0;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
bit4 = BIT4_1;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
bit4 = BIT4_Z;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
bit4 = BIT4_X;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
bit4 = BIT4_X;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return_value_.set_bit(idx, bit4);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
vpiHandle sysfunc_vec4::put_value_time_(p_vpi_value vp)
|
vpiHandle sysfunc_vec4::put_value_time_(p_vpi_value vp)
|
||||||
{
|
{
|
||||||
unsigned width = return_value_.size();
|
unsigned width = return_value_.size();
|
||||||
|
|
@ -518,12 +456,18 @@ vpiHandle sysfunc_vec4::vpi_put_value(p_vpi_value vp, int)
|
||||||
put_value = true;
|
put_value = true;
|
||||||
|
|
||||||
switch (vp->format) {
|
switch (vp->format) {
|
||||||
|
case vpiScalarVal:
|
||||||
|
return put_value_scalar_(vp);
|
||||||
case vpiIntVal:
|
case vpiIntVal:
|
||||||
return put_value_int_(vp);
|
return put_value_int_(vp);
|
||||||
|
case vpiStringVal:
|
||||||
|
return put_value_string_(vp);
|
||||||
|
case vpiVectorVal:
|
||||||
|
return put_value_vector_(vp);
|
||||||
case vpiTimeVal:
|
case vpiTimeVal:
|
||||||
return put_value_time_(vp);
|
return put_value_time_(vp);
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "Unsupported format %d seting sysfunc vec4 value.\n", (int)vp->format);
|
fprintf(stderr, "Unsupported format %d setting sysfunc vec4 value.\n", (int)vp->format);
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -870,9 +814,6 @@ vpiHandle vpip_build_vpi_call(const char*name, int val_code, unsigned return_wid
|
||||||
} else if (val_code == -vpiVectorVal) {
|
} else if (val_code == -vpiVectorVal) {
|
||||||
obj = new sysfunc_vec4(return_width);
|
obj = new sysfunc_vec4(return_width);
|
||||||
|
|
||||||
} else if (val_code > 0) { // XXXX should not happen?
|
|
||||||
obj = new sysfunc_def;
|
|
||||||
|
|
||||||
} else if (val_code == 0 && fnet == 0) {
|
} else if (val_code == 0 && fnet == 0) {
|
||||||
obj = new sysfunc_no;
|
obj = new sysfunc_no;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue