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.
./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"

View File

@ -396,7 +396,7 @@ vpiHandle __vpiArray::vpi_iterate(int code)
*/
vpiHandle __vpiArray::vpi_index(int index)
{
index -= first_addr.value;
index -= first_addr.get_value();
if (index >= (long)array_count)
return 0;
if (index < 0)
@ -609,10 +609,10 @@ static int vpi_array_var_word_get(int code, vpiHandle ref)
}
case vpiLeftRange:
return parent->msb.value;
return parent->msb.get_value();
case vpiRightRange:
return parent->lsb.value;
return parent->lsb.get_value();
case vpiAutomatic:
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];
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);
}
@ -756,13 +756,13 @@ static int vpi_array_vthr_A_get(int code, vpiHandle ref)
return get_array_word_size(parent);
case vpiLeftRange:
return parent->msb.value;
return parent->msb.get_value();
case vpiRightRange:
return parent->lsb.value;
return parent->lsb.get_value();
case vpiIndex:
return (int)obj->get_address() + parent->first_addr.value;
return (int)obj->get_address() + parent->first_addr.get_value();
case vpiAutomatic:
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];
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);
}
@ -924,10 +924,10 @@ static int vpi_array_vthr_APV_get(int code, vpiHandle ref)
return obj->part_wid;
case vpiLeftRange:
return parent->msb.value;
return parent->msb.get_value();
case vpiRightRange:
return parent->lsb.value;
return parent->lsb.get_value();
case vpiIndex:
return (int)obj->word_sel;
@ -959,7 +959,7 @@ static char*vpi_array_vthr_APV_get_str(int code, vpiHandle ref)
}
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);
}
@ -1176,8 +1176,8 @@ static vpiHandle vpip_make_array(char*label, const char*name,
obj->name = vpip_name_string(name);
obj->array_count = array_count;
obj->first_addr.value = first_addr;
obj->last_addr.value = last_addr;
obj->first_addr.set_value(first_addr);
obj->last_addr .set_value(last_addr);
// Start off now knowing if we are nets or variables.
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,
int msb, int lsb)
{
assert(array->msb.value == msb);
assert(array->lsb.value == lsb);
assert(array->msb.get_value() == msb);
assert(array->lsb.get_value() == lsb);
assert(addr < array->array_count);
assert(array->nets);
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);
sig->is_netarray = 1;
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.
array->signed_flag = sig->signed_flag;
return;
@ -1246,7 +1246,7 @@ void array_attach_word(vvp_array_t array, unsigned addr, vpiHandle word)
fun->attach_as_word(array, addr);
sig->is_netarray = 1;
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.
array->signed_flag = true;
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->array_count);
}
arr->msb.value = msb;
arr->lsb.value = lsb;
arr->msb.set_value(msb);
arr->lsb.set_value(lsb);
count_var_arrays += 1;
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);
/* Make the words. */
arr->msb.value = msb;
arr->lsb.value = lsb;
arr->msb.set_value(msb);
arr->lsb.set_value(lsb);
arr->vals_width = labs(msb-lsb) + 1;
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.
if (cur->word_addr == -1) {
cur->cb_data.index = (PLI_INT32) ((int)addr +
array->first_addr.value);
array->first_addr.get_value());
}
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;
// Need to set an accurate range of addresses.
obj->first_addr.value = mem->first_addr.value;
obj->last_addr.value = mem->last_addr.value;
obj->first_addr = mem->first_addr;
obj->last_addr = mem->last_addr;
obj->swap_addr = mem->swap_addr;
obj->msb.value = mem->msb.value;
obj->lsb.value = mem->lsb.value;
obj->msb = mem->msb;
obj->lsb = mem->lsb;
// Share the words with the source array.
obj->nets = mem->nets;

View File

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

View File

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

View File

@ -105,7 +105,7 @@ struct vpip_string_chunk {
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)

View File

@ -146,6 +146,22 @@ struct __vpiIterator : public __vpiHandle {
extern vpiHandle vpip_make_iterator(unsigned nargs, vpiHandle*args,
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
* 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_index(int idx);
public:
unsigned width() const;
public:
union { // The scope or parent array that contains me.
vpiHandle parent;
struct __vpiScope* scope;
@ -290,7 +310,7 @@ struct __vpiSignal : public __vpiHandle {
vpiHandle index;
} id;
/* The indices that define the width and access offset. */
int msb, lsb;
__vpiDecConst msb, lsb;
/* Flags */
unsigned signed_flag : 1;
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,
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 {
public:
__vpiRealConst(double);

View File

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