WRap up vec4 support for system function calls.

This commit is contained in:
Stephen Williams 2014-01-14 09:22:23 -08:00
parent 660d59a7a9
commit c6c697bdb7
1 changed files with 92 additions and 151 deletions

View File

@ -150,140 +150,6 @@ struct systask_def : public __vpiSysTaskCall {
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)
{
@ -417,19 +283,6 @@ static vpiHandle sysfunc_put_no_value(vpiHandle, p_vpi_value, int)
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 {
inline sysfunc_real() { }
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_; }
private:
vpiHandle put_value_scalar_(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);
private:
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)
{
long tmp = vp->value.integer;
@ -495,6 +373,66 @@ vpiHandle sysfunc_vec4::put_value_int_(p_vpi_value vp)
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)
{
unsigned width = return_value_.size();
@ -518,12 +456,18 @@ vpiHandle sysfunc_vec4::vpi_put_value(p_vpi_value vp, int)
put_value = true;
switch (vp->format) {
case vpiScalarVal:
return put_value_scalar_(vp);
case vpiIntVal:
return put_value_int_(vp);
case vpiStringVal:
return put_value_string_(vp);
case vpiVectorVal:
return put_value_vector_(vp);
case vpiTimeVal:
return put_value_time_(vp);
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);
}
@ -870,9 +814,6 @@ vpiHandle vpip_build_vpi_call(const char*name, int val_code, unsigned return_wid
} else if (val_code == -vpiVectorVal) {
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) {
obj = new sysfunc_no;