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:
parent
515137c8c7
commit
b991a991a7
|
|
@ -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"
|
||||
|
|
|
|||
52
vvp/array.cc
52
vvp/array.cc
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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; }
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Reference in New Issue