Implement vpi_handle(vpiLeft/RightRange, ...) for signals.

This returns a constant object that can be treated like an
expression, so following the letter of the LRM.
This commit is contained in:
Stephen Williams 2014-06-19 15:39:24 -07:00
parent 515137c8c7
commit b991a991a7
7 changed files with 81 additions and 63 deletions

View File

@ -9,6 +9,6 @@
# #
# NOTE: DO NOT INSTALL THIS FILE. # NOTE: DO NOT INSTALL THIS FILE.
./ivl -v -Ctgt-stub/stub.conf -C./scripts/devel-stub.conf -Pa.pf -Na.net -fDLL=tgt-stub/stub.tgt foo.vl |& tee foo.log ./ivl -v -Ctgt-stub/stub-s.conf -C./scripts/devel-stub.conf -Pa.pf -Na.net -fDLL=tgt-stub/stub.tgt foo.vl |& tee foo.log
echo "*** ivl command completed" echo "*** ivl command completed"

View File

@ -396,7 +396,7 @@ vpiHandle __vpiArray::vpi_iterate(int code)
*/ */
vpiHandle __vpiArray::vpi_index(int index) vpiHandle __vpiArray::vpi_index(int index)
{ {
index -= first_addr.value; index -= first_addr.get_value();
if (index >= (long)array_count) if (index >= (long)array_count)
return 0; return 0;
if (index < 0) if (index < 0)
@ -609,10 +609,10 @@ static int vpi_array_var_word_get(int code, vpiHandle ref)
} }
case vpiLeftRange: case vpiLeftRange:
return parent->msb.value; return parent->msb.get_value();
case vpiRightRange: case vpiRightRange:
return parent->lsb.value; return parent->lsb.get_value();
case vpiAutomatic: case vpiAutomatic:
return (int) parent->scope->is_automatic; return (int) parent->scope->is_automatic;
@ -640,7 +640,7 @@ static char*vpi_array_var_word_get_str(int code, vpiHandle ref)
} }
char sidx [64]; char sidx [64];
snprintf(sidx, 63, "%d", (int)index + parent->first_addr.value); snprintf(sidx, 63, "%d", (int)index + parent->first_addr.get_value());
return generic_get_str(code, parent->scope, parent->name, sidx); return generic_get_str(code, parent->scope, parent->name, sidx);
} }
@ -756,13 +756,13 @@ static int vpi_array_vthr_A_get(int code, vpiHandle ref)
return get_array_word_size(parent); return get_array_word_size(parent);
case vpiLeftRange: case vpiLeftRange:
return parent->msb.value; return parent->msb.get_value();
case vpiRightRange: case vpiRightRange:
return parent->lsb.value; return parent->lsb.get_value();
case vpiIndex: case vpiIndex:
return (int)obj->get_address() + parent->first_addr.value; return (int)obj->get_address() + parent->first_addr.get_value();
case vpiAutomatic: case vpiAutomatic:
return (int) parent->scope->is_automatic; return (int) parent->scope->is_automatic;
@ -796,7 +796,7 @@ static char*vpi_array_vthr_A_get_str(int code, vpiHandle ref)
} }
char sidx [64]; char sidx [64];
snprintf(sidx, 63, "%d", (int)obj->get_address() + parent->first_addr.value); snprintf(sidx, 63, "%d", (int)obj->get_address() + parent->first_addr.get_value());
return generic_get_str(code, parent->scope, parent->name, sidx); return generic_get_str(code, parent->scope, parent->name, sidx);
} }
@ -924,10 +924,10 @@ static int vpi_array_vthr_APV_get(int code, vpiHandle ref)
return obj->part_wid; return obj->part_wid;
case vpiLeftRange: case vpiLeftRange:
return parent->msb.value; return parent->msb.get_value();
case vpiRightRange: case vpiRightRange:
return parent->lsb.value; return parent->lsb.get_value();
case vpiIndex: case vpiIndex:
return (int)obj->word_sel; return (int)obj->word_sel;
@ -959,7 +959,7 @@ static char*vpi_array_vthr_APV_get_str(int code, vpiHandle ref)
} }
char sidx [64]; char sidx [64];
snprintf(sidx, 63, "%u", obj->word_sel + parent->first_addr.value); snprintf(sidx, 63, "%u", obj->word_sel + parent->first_addr.get_value());
return generic_get_str(code, parent->scope, parent->name, sidx); return generic_get_str(code, parent->scope, parent->name, sidx);
} }
@ -1176,8 +1176,8 @@ static vpiHandle vpip_make_array(char*label, const char*name,
obj->name = vpip_name_string(name); obj->name = vpip_name_string(name);
obj->array_count = array_count; obj->array_count = array_count;
obj->first_addr.value = first_addr; obj->first_addr.set_value(first_addr);
obj->last_addr.value = last_addr; obj->last_addr .set_value(last_addr);
// Start off now knowing if we are nets or variables. // Start off now knowing if we are nets or variables.
obj->nets = 0; obj->nets = 0;
@ -1211,8 +1211,8 @@ static vpiHandle vpip_make_array(char*label, const char*name,
void array_alias_word(vvp_array_t array, unsigned long addr, vpiHandle word, void array_alias_word(vvp_array_t array, unsigned long addr, vpiHandle word,
int msb, int lsb) int msb, int lsb)
{ {
assert(array->msb.value == msb); assert(array->msb.get_value() == msb);
assert(array->lsb.value == lsb); assert(array->lsb.get_value() == lsb);
assert(addr < array->array_count); assert(addr < array->array_count);
assert(array->nets); assert(array->nets);
array->nets[addr] = word; array->nets[addr] = word;
@ -1232,7 +1232,7 @@ void array_attach_word(vvp_array_t array, unsigned addr, vpiHandle word)
fun->attach_as_word(array, addr); fun->attach_as_word(array, addr);
sig->is_netarray = 1; sig->is_netarray = 1;
sig->within.parent = array; sig->within.parent = array;
sig->id.index = new __vpiDecConst(addr + array->first_addr.value); sig->id.index = new __vpiDecConst(addr + array->first_addr.get_value());
// Now we know the data type, update the array signed_flag. // Now we know the data type, update the array signed_flag.
array->signed_flag = sig->signed_flag; array->signed_flag = sig->signed_flag;
return; return;
@ -1246,7 +1246,7 @@ void array_attach_word(vvp_array_t array, unsigned addr, vpiHandle word)
fun->attach_as_word(array, addr); fun->attach_as_word(array, addr);
sig->is_netarray = 1; sig->is_netarray = 1;
sig->within.parent = array; sig->within.parent = array;
sig->id.index = new __vpiDecConst(addr + array->first_addr.value); sig->id.index = new __vpiDecConst(addr + array->first_addr.get_value());
// Now we know the data type, update the array signed_flag. // Now we know the data type, update the array signed_flag.
array->signed_flag = true; array->signed_flag = true;
return; return;
@ -1270,8 +1270,8 @@ void compile_var_array(char*label, char*name, int last, int first,
arr->vals4 = new vvp_vector4array_sa(arr->vals_width, arr->vals4 = new vvp_vector4array_sa(arr->vals_width,
arr->array_count); arr->array_count);
} }
arr->msb.value = msb; arr->msb.set_value(msb);
arr->lsb.value = lsb; arr->lsb.set_value(lsb);
count_var_arrays += 1; count_var_arrays += 1;
count_var_array_words += arr->array_count; count_var_array_words += arr->array_count;
@ -1288,8 +1288,8 @@ void compile_var2_array(char*label, char*name, int last, int first,
struct __vpiArray*arr = dynamic_cast<__vpiArray*>(obj); struct __vpiArray*arr = dynamic_cast<__vpiArray*>(obj);
/* Make the words. */ /* Make the words. */
arr->msb.value = msb; arr->msb.set_value(msb);
arr->lsb.value = lsb; arr->lsb.set_value(lsb);
arr->vals_width = labs(msb-lsb) + 1; arr->vals_width = labs(msb-lsb) + 1;
assert(! arr->nets); assert(! arr->nets);
@ -1653,7 +1653,7 @@ void array_word_change(vvp_array_t array, unsigned long addr)
// For whole array callbacks we need to set the index. // For whole array callbacks we need to set the index.
if (cur->word_addr == -1) { if (cur->word_addr == -1) {
cur->cb_data.index = (PLI_INT32) ((int)addr + cur->cb_data.index = (PLI_INT32) ((int)addr +
array->first_addr.value); array->first_addr.get_value());
} }
if (cur->cb_data.cb_rtn != 0) { if (cur->cb_data.cb_rtn != 0) {
@ -1889,12 +1889,12 @@ void compile_array_alias(char*label, char*name, char*src)
obj->signed_flag = mem->signed_flag; obj->signed_flag = mem->signed_flag;
// Need to set an accurate range of addresses. // Need to set an accurate range of addresses.
obj->first_addr.value = mem->first_addr.value; obj->first_addr = mem->first_addr;
obj->last_addr.value = mem->last_addr.value; obj->last_addr = mem->last_addr;
obj->swap_addr = mem->swap_addr; obj->swap_addr = mem->swap_addr;
obj->msb.value = mem->msb.value; obj->msb = mem->msb;
obj->lsb.value = mem->lsb.value; obj->lsb = mem->lsb;
// Share the words with the source array. // Share the words with the source array.
obj->nets = mem->nets; obj->nets = mem->nets;

View File

@ -268,7 +268,7 @@ static void cmd_list(unsigned, char*[])
case vpiReg: case vpiReg:
sig = dynamic_cast<__vpiSignal*>(table[idx]); sig = dynamic_cast<__vpiSignal*>(table[idx]);
if ((sig->msb == 0) && (sig->lsb == 0)) if ((sig->msb.get_value() == 0) && (sig->lsb.get_value() == 0))
printf("reg : %s%s\n", printf("reg : %s%s\n",
vpi_get_str(vpiName, table[idx]), vpi_get_str(vpiName, table[idx]),
sig->signed_flag? "signed " : ""); sig->signed_flag? "signed " : "");
@ -276,12 +276,12 @@ static void cmd_list(unsigned, char*[])
printf("reg : %s%s[%d:%d]\n", printf("reg : %s%s[%d:%d]\n",
vpi_get_str(vpiName, table[idx]), vpi_get_str(vpiName, table[idx]),
sig->signed_flag? "signed " : "", sig->signed_flag? "signed " : "",
sig->msb, sig->lsb); sig->msb.get_value(), sig->lsb.get_value());
break; break;
case vpiNet: case vpiNet:
sig = dynamic_cast<__vpiSignal*>(table[idx]); sig = dynamic_cast<__vpiSignal*>(table[idx]);
if ((sig->msb == 0) && (sig->lsb == 0)) if ((sig->msb.get_value() == 0) && (sig->lsb.get_value() == 0))
printf("net : %s%s\n", printf("net : %s%s\n",
vpi_get_str(vpiName, table[idx]), vpi_get_str(vpiName, table[idx]),
sig->signed_flag? "signed " : ""); sig->signed_flag? "signed " : "");
@ -289,7 +289,7 @@ static void cmd_list(unsigned, char*[])
printf("net : %s%s[%d:%d]\n", printf("net : %s%s[%d:%d]\n",
vpi_get_str(vpiName, table[idx]), vpi_get_str(vpiName, table[idx]),
sig->signed_flag? "signed " : "", sig->signed_flag? "signed " : "",
sig->msb, sig->lsb); sig->msb.get_value(), sig->lsb.get_value());
break; break;
default: default:

View File

@ -537,6 +537,12 @@ __vpiDecConst::__vpiDecConst(int val)
value = val; value = val;
} }
__vpiDecConst::__vpiDecConst(const __vpiDecConst&that)
: value(that.value)
{
}
int __vpiDecConst::get_type_code(void) const int __vpiDecConst::get_type_code(void) const
{ return vpiConstant; } { return vpiConstant; }

View File

@ -105,7 +105,7 @@ struct vpip_string_chunk {
unsigned vpip_size(__vpiSignal *sig) unsigned vpip_size(__vpiSignal *sig)
{ {
return abs(sig->msb - sig->lsb) + 1; return abs(sig->msb.get_value() - sig->lsb.get_value()) + 1;
} }
struct __vpiScope* vpip_scope(__vpiSignal*sig) struct __vpiScope* vpip_scope(__vpiSignal*sig)

View File

@ -146,6 +146,22 @@ struct __vpiIterator : public __vpiHandle {
extern vpiHandle vpip_make_iterator(unsigned nargs, vpiHandle*args, extern vpiHandle vpip_make_iterator(unsigned nargs, vpiHandle*args,
bool free_args_flag); bool free_args_flag);
class __vpiDecConst : public __vpiHandle {
public:
__vpiDecConst(int val =0);
__vpiDecConst(const __vpiDecConst&that);
int get_type_code(void) const;
int vpi_get(int code);
void vpi_get_value(p_vpi_value val);
public:
inline int get_value() const { return value; }
inline void set_value(int val) { value = val; }
private:
int value;
};
/* /*
* This represents callback handles. There are some private types that * This represents callback handles. There are some private types that
* are defined and used in vpi_callback.cc. The __vpiCallback are * are defined and used in vpi_callback.cc. The __vpiCallback are
@ -281,6 +297,10 @@ struct __vpiSignal : public __vpiHandle {
vpiHandle vpi_iterate(int code); vpiHandle vpi_iterate(int code);
vpiHandle vpi_index(int idx); vpiHandle vpi_index(int idx);
public:
unsigned width() const;
public:
union { // The scope or parent array that contains me. union { // The scope or parent array that contains me.
vpiHandle parent; vpiHandle parent;
struct __vpiScope* scope; struct __vpiScope* scope;
@ -290,7 +310,7 @@ struct __vpiSignal : public __vpiHandle {
vpiHandle index; vpiHandle index;
} id; } id;
/* The indices that define the width and access offset. */ /* The indices that define the width and access offset. */
int msb, lsb; __vpiDecConst msb, lsb;
/* Flags */ /* Flags */
unsigned signed_flag : 1; unsigned signed_flag : 1;
unsigned is_netarray : 1; // This is word of a net array unsigned is_netarray : 1; // This is word of a net array
@ -626,16 +646,6 @@ vpiHandle vpip_make_binary_param(char*name, const vvp_vector4_t&bits,
bool signed_flag, bool local_flag, bool signed_flag, bool local_flag,
long file_idx, long lineno); long file_idx, long lineno);
class __vpiDecConst : public __vpiHandle {
public:
__vpiDecConst(int val =0);
int get_type_code(void) const;
int vpi_get(int code);
void vpi_get_value(p_vpi_value val);
int value;
};
class __vpiRealConst : public __vpiHandle { class __vpiRealConst : public __vpiHandle {
public: public:
__vpiRealConst(double); __vpiRealConst(double);

View File

@ -550,10 +550,7 @@ static int signal_get(int code, vpiHandle ref)
} }
case vpiSize: case vpiSize:
if (rfp->msb >= rfp->lsb) return rfp->width();
return rfp->msb - rfp->lsb + 1;
else
return rfp->lsb - rfp->msb + 1;
case vpiNetType: case vpiNetType:
if (ref->get_type_code()==vpiNet) if (ref->get_type_code()==vpiNet)
@ -562,15 +559,15 @@ static int signal_get(int code, vpiHandle ref)
return vpiUndefined; return vpiUndefined;
case vpiLeftRange: case vpiLeftRange:
return rfp->msb; return rfp->msb.get_value();
case vpiRightRange: case vpiRightRange:
return rfp->lsb; return rfp->lsb.get_value();
case vpiScalar: case vpiScalar:
return (rfp->msb == 0 && rfp->lsb == 0); return (rfp->msb.get_value() == 0 && rfp->lsb.get_value() == 0);
case vpiVector: case vpiVector:
return (rfp->msb != rfp->lsb); return (rfp->msb.get_value() != rfp->lsb.get_value());
case vpiAutomatic: case vpiAutomatic:
return (int) vpip_scope(rfp)->is_automatic; return (int) vpip_scope(rfp)->is_automatic;
@ -582,7 +579,7 @@ static int signal_get(int code, vpiHandle ref)
// This private property must return zero when undefined. // This private property must return zero when undefined.
case _vpiNexusId: case _vpiNexusId:
if (rfp->msb == rfp->lsb) if (rfp->msb.get_value() == rfp->lsb.get_value())
return (int) (unsigned long) rfp->node; return (int) (unsigned long) rfp->node;
else else
return 0; return 0;
@ -636,6 +633,11 @@ static vpiHandle signal_get_handle(int code, vpiHandle ref)
case vpiIndex: case vpiIndex:
return rfp->is_netarray? rfp->id.index : 0; return rfp->is_netarray? rfp->id.index : 0;
case vpiLeftRange:
return &rfp->msb;
case vpiRightRange:
return &rfp->lsb;
case vpiScope: case vpiScope:
return vpip_scope(rfp); return vpip_scope(rfp);
@ -663,10 +665,10 @@ static vpiHandle signal_index(int idx, vpiHandle ref)
struct __vpiSignal*rfp = dynamic_cast<__vpiSignal*>(ref); struct __vpiSignal*rfp = dynamic_cast<__vpiSignal*>(ref);
assert(rfp); assert(rfp);
/* Check to see if the index is in range. */ /* Check to see if the index is in range. */
if (rfp->msb >= rfp->lsb) { if (rfp->msb.get_value() >= rfp->lsb.get_value()) {
if ((idx > rfp->msb) || (idx < rfp->lsb)) return 0; if ((idx > rfp->msb.get_value()) || (idx < rfp->lsb.get_value())) return 0;
} else { } else {
if ((idx < rfp->msb) || (idx > rfp->lsb)) return 0; if ((idx < rfp->msb.get_value()) || (idx > rfp->lsb.get_value())) return 0;
} }
/* Return a handle for the individual bit. */ /* Return a handle for the individual bit. */
cerr << "Sorry: Icarus does not currently support " cerr << "Sorry: Icarus does not currently support "
@ -676,11 +678,11 @@ static vpiHandle signal_index(int idx, vpiHandle ref)
return 0; return 0;
} }
static unsigned signal_width(const struct __vpiSignal*rfp) unsigned __vpiSignal::width(void) const
{ {
unsigned wid = (rfp->msb >= rfp->lsb) unsigned wid = (msb.get_value() >= lsb.get_value())
? (rfp->msb - rfp->lsb + 1) ? (msb.get_value() - lsb.get_value() + 1)
: (rfp->lsb - rfp->msb + 1); : (lsb.get_value() - msb.get_value() + 1);
return wid; return wid;
} }
@ -695,7 +697,7 @@ static void signal_get_value(vpiHandle ref, s_vpi_value*vp)
struct __vpiSignal*rfp = dynamic_cast<__vpiSignal*>(ref); struct __vpiSignal*rfp = dynamic_cast<__vpiSignal*>(ref);
assert(rfp); assert(rfp);
unsigned wid = signal_width(rfp); unsigned wid = rfp->width();
vvp_signal_value*vsig = dynamic_cast<vvp_signal_value*>(rfp->node->fil); vvp_signal_value*vsig = dynamic_cast<vvp_signal_value*>(rfp->node->fil);
assert(vsig); assert(vsig);
@ -817,9 +819,9 @@ static vpiHandle signal_put_value(vpiHandle ref, s_vpi_value*vp, int flags)
/* Make a vvp_vector4_t vector to receive the translated value /* Make a vvp_vector4_t vector to receive the translated value
that we are going to poke. This will get populated that we are going to poke. This will get populated
differently depending on the format. */ differently depending on the format. */
wid = (rfp->msb >= rfp->lsb) wid = (rfp->msb.get_value() >= rfp->lsb.get_value())
? (rfp->msb - rfp->lsb + 1) ? (rfp->msb.get_value() - rfp->lsb.get_value() + 1)
: (rfp->lsb - rfp->msb + 1); : (rfp->lsb.get_value() - rfp->msb.get_value() + 1);
vvp_vector4_t val = vec4_from_vpi_value(vp, wid); vvp_vector4_t val = vec4_from_vpi_value(vp, wid);