Generate array word names with new array VPI functionality
Use the new array VPI functionality (vpiIndex, vpiParent, vpiArray) to dynamically generate array word names. The old patch to implement was mostly reverted.
This commit is contained in:
parent
1782175c52
commit
78b2eb5026
31
vvp/array.cc
31
vvp/array.cc
|
|
@ -75,22 +75,6 @@ struct __vpiArrayIndex {
|
|||
unsigned done;
|
||||
};
|
||||
|
||||
const char *get_array_name(char*label)
|
||||
{
|
||||
vvp_array_t array = array_find(label);
|
||||
if (array == 0)
|
||||
return 0;
|
||||
return array->name;
|
||||
}
|
||||
|
||||
const int get_array_base(char*label)
|
||||
{
|
||||
vvp_array_t array = array_find(label);
|
||||
if (array == 0)
|
||||
return 0;
|
||||
return array->first_addr.value;
|
||||
}
|
||||
|
||||
static int vpi_array_get(int code, vpiHandle ref);
|
||||
static char*vpi_array_get_str(int code, vpiHandle ref);
|
||||
static vpiHandle vpi_array_get_handle(int code, vpiHandle ref);
|
||||
|
|
@ -392,7 +376,7 @@ void array_attach_word(vvp_array_t array, unsigned long addr, vpiHandle word)
|
|||
assert(fun);
|
||||
fun->attach_as_word(array, addr);
|
||||
sig->parent = &array->base;
|
||||
sig->index = vpip_make_dec_const(addr + array->first_addr.value);
|
||||
sig->id.index = vpip_make_dec_const(addr + array->first_addr.value);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -420,13 +404,8 @@ void compile_var_array(char*label, char*name, int last, int first,
|
|||
/* Make the words. */
|
||||
for (unsigned idx = 0 ; idx < arr->array_count ; idx += 1) {
|
||||
char buf[64];
|
||||
unsigned len = strlen(name) + 32;
|
||||
char *nbuf = (char *)malloc(len);
|
||||
snprintf(buf, sizeof buf, "%s_%u", label, idx);
|
||||
snprintf(nbuf, len, "%s[%d]", name, idx + arr->first_addr.value);
|
||||
compile_variablew(strdup(buf), strdup(nbuf), array, idx, msb, lsb,
|
||||
signed_flag);
|
||||
free(nbuf);
|
||||
compile_variablew(strdup(buf), array, idx, msb, lsb, signed_flag);
|
||||
}
|
||||
|
||||
free(label);
|
||||
|
|
@ -444,12 +423,8 @@ void compile_real_array(char*label, char*name, int last, int first,
|
|||
/* Make the words. */
|
||||
for (unsigned idx = 0 ; idx < arr->array_count ; idx += 1) {
|
||||
char buf[64];
|
||||
unsigned len = strlen(name) + 32;
|
||||
char *nbuf = (char *)malloc(len);
|
||||
snprintf(buf, sizeof buf, "%s_%u", label, idx);
|
||||
snprintf(nbuf, len, "%s[%u]", name, idx + arr->first_addr.value);
|
||||
compile_varw_real(strdup(buf), strdup(nbuf), array, idx, msb, lsb);
|
||||
free(nbuf);
|
||||
compile_varw_real(strdup(buf), array, idx, msb, lsb);
|
||||
}
|
||||
|
||||
free(label);
|
||||
|
|
|
|||
|
|
@ -32,8 +32,6 @@ typedef struct __vpiArray* vvp_array_t;
|
|||
* table of all the arrays in the design.
|
||||
*/
|
||||
extern vvp_array_t array_find(char*label);
|
||||
extern const char *get_array_name(char*label);
|
||||
extern const int get_array_base(char*label);
|
||||
extern vpiHandle array_index_iterate(int code, vpiHandle ref);
|
||||
|
||||
extern void array_word_change(vvp_array_t array, unsigned long addr);
|
||||
|
|
@ -47,10 +45,10 @@ extern void array_set_word(vvp_array_t arr,
|
|||
|
||||
extern vvp_vector4_t array_get_word(vvp_array_t array, unsigned adddress);
|
||||
|
||||
extern void compile_variablew(char*label, char*name, vvp_array_t array,
|
||||
extern void compile_variablew(char*label, vvp_array_t array,
|
||||
unsigned long array_addr,
|
||||
int msb, int lsb, char signed_flag);
|
||||
extern void compile_varw_real(char*label, char*name, vvp_array_t array,
|
||||
extern void compile_varw_real(char*label, vvp_array_t array,
|
||||
unsigned long array_addr,
|
||||
int msb, int lsb);
|
||||
#endif
|
||||
|
|
|
|||
12
vvp/stop.cc
12
vvp/stop.cc
|
|
@ -258,10 +258,12 @@ static void cmd_list(unsigned, char*[])
|
|||
case vpiReg:
|
||||
sig = (struct __vpiSignal*) table[idx];
|
||||
if ((sig->msb == 0) && (sig->lsb == 0))
|
||||
printf("reg : %s%s\n", sig->name,
|
||||
printf("reg : %s%s\n",
|
||||
vpi_get_str(vpiName, table[idx]),
|
||||
sig->signed_flag? "signed " : "");
|
||||
else
|
||||
printf("reg : %s%s[%d:%d]\n", sig->name,
|
||||
printf("reg : %s%s[%d:%d]\n",
|
||||
vpi_get_str(vpiName, table[idx]),
|
||||
sig->signed_flag? "signed " : "",
|
||||
sig->msb, sig->lsb);
|
||||
break;
|
||||
|
|
@ -269,10 +271,12 @@ static void cmd_list(unsigned, char*[])
|
|||
case vpiNet:
|
||||
sig = (struct __vpiSignal*) table[idx];
|
||||
if ((sig->msb == 0) && (sig->lsb == 0))
|
||||
printf("net : %s%s\n", sig->name,
|
||||
printf("net : %s%s\n",
|
||||
vpi_get_str(vpiName, table[idx]),
|
||||
sig->signed_flag? "signed " : "");
|
||||
else
|
||||
printf("net : %s%s[%d:%d]\n", sig->name,
|
||||
printf("net : %s%s[%d:%d]\n",
|
||||
vpi_get_str(vpiName, table[idx]),
|
||||
sig->signed_flag? "signed " : "",
|
||||
sig->msb, sig->lsb);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -191,10 +191,12 @@ extern void vpip_make_root_iterator(struct __vpiHandle**&table,
|
|||
struct __vpiSignal {
|
||||
struct __vpiHandle base;
|
||||
vpiHandle parent;
|
||||
vpiHandle index;
|
||||
struct __vpiScope* scope;
|
||||
/* The name of this reg/net, or <name>[<index>] for array words. */
|
||||
const char*name;
|
||||
/* The name of this reg/net, or the index for array words. */
|
||||
union {
|
||||
const char*name;
|
||||
vpiHandle index;
|
||||
} id;
|
||||
/* The indices that define the width and access offset. */
|
||||
int msb, lsb;
|
||||
/* Flags */
|
||||
|
|
@ -322,9 +324,12 @@ extern void vpip_run_memory_value_change(vpiHandle ref, unsigned adr);
|
|||
struct __vpiRealVar {
|
||||
struct __vpiHandle base;
|
||||
vpiHandle parent;
|
||||
vpiHandle index;
|
||||
struct __vpiScope* scope;
|
||||
const char*name;
|
||||
/* The name of this variable, or the index for array words. */
|
||||
union {
|
||||
const char*name;
|
||||
vpiHandle index;
|
||||
} id;
|
||||
vvp_net_t*net;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -49,26 +49,37 @@ static char* real_var_get_str(int code, vpiHandle ref)
|
|||
|
||||
struct __vpiRealVar*rfp = (struct __vpiRealVar*)ref;
|
||||
char *bn = strdup(vpi_get_str(vpiFullName, &rfp->scope->base));
|
||||
char *rbuf = need_result_buf(strlen(bn)+strlen(rfp->name) + 2,
|
||||
RBUF_STR);
|
||||
char *nm;
|
||||
if (rfp->parent) {
|
||||
s_vpi_value vp;
|
||||
nm = strdup(vpi_get_str(vpiName, rfp->parent));
|
||||
strcat(nm, "[");
|
||||
vp.format = vpiDecStrVal;
|
||||
vpi_get_value(rfp->id.index, &vp);
|
||||
strcat(nm, vp.value.str);
|
||||
strcat(nm, "]");
|
||||
} else {
|
||||
nm = strdup(rfp->id.name);
|
||||
}
|
||||
char *rbuf = need_result_buf(strlen(bn)+strlen(nm) + 2, RBUF_STR);
|
||||
|
||||
switch (code) {
|
||||
|
||||
case vpiFullName:
|
||||
sprintf(rbuf, "%s.%s", bn, rfp->name);
|
||||
sprintf(rbuf, "%s.%s", bn, nm);
|
||||
free(bn);
|
||||
free(nm);
|
||||
return rbuf;
|
||||
|
||||
case vpiName:
|
||||
strcpy(rbuf, rfp->name);
|
||||
strcpy(rbuf, nm);
|
||||
free(bn);
|
||||
free(nm);
|
||||
return rbuf;
|
||||
|
||||
default:
|
||||
free(bn);
|
||||
return 0;
|
||||
}
|
||||
|
||||
free(bn);
|
||||
free(nm);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -84,7 +95,7 @@ static vpiHandle real_var_get_handle(int code, vpiHandle ref)
|
|||
return rfp->parent;
|
||||
|
||||
case vpiIndex:
|
||||
return rfp->index;
|
||||
return rfp->parent ? rfp->id.index : 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
@ -97,7 +108,8 @@ static vpiHandle real_var_iterate(int code, vpiHandle ref)
|
|||
struct __vpiRealVar*rfp = (struct __vpiRealVar*)ref;
|
||||
|
||||
if (code == vpiIndex) {
|
||||
return (rfp->index->vpi_type->iterate_)(code, rfp->index);
|
||||
return rfp->parent ? (rfp->id.index->vpi_type->iterate_)
|
||||
(code, rfp->id.index) : 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
@ -170,6 +182,11 @@ void vpip_real_value_change(struct __vpiCallback*cbh,
|
|||
fun->add_vpi_callback(cbh);
|
||||
}
|
||||
|
||||
/*
|
||||
* Since reals do not currently support arrays none of the array code
|
||||
* has been tested! Though it should work since it is a copy of the
|
||||
* signal code.
|
||||
*/
|
||||
vpiHandle vpip_make_real_var(const char*name, vvp_net_t*net)
|
||||
{
|
||||
struct __vpiRealVar*obj = (struct __vpiRealVar*)
|
||||
|
|
@ -177,8 +194,7 @@ vpiHandle vpip_make_real_var(const char*name, vvp_net_t*net)
|
|||
|
||||
obj->base.vpi_type = &vpip_real_var_rt;
|
||||
obj->parent = 0;
|
||||
obj->index = 0;
|
||||
obj->name = vpip_name_string(name);
|
||||
obj->id.name = vpip_name_string(name);
|
||||
obj->net = net;
|
||||
|
||||
obj->scope = vpip_peek_current_scope();
|
||||
|
|
|
|||
|
|
@ -135,8 +135,18 @@ static char* signal_get_str(int code, vpiHandle ref)
|
|||
struct __vpiSignal*rfp = (struct __vpiSignal*)ref;
|
||||
|
||||
char *bn = strdup(vpi_get_str(vpiFullName, &rfp->scope->base));
|
||||
char *nm = (char*)rfp->name;
|
||||
|
||||
char *nm;
|
||||
if (rfp->parent) {
|
||||
s_vpi_value vp;
|
||||
nm = strdup(vpi_get_str(vpiName, rfp->parent));
|
||||
strcat(nm, "[");
|
||||
vp.format = vpiDecStrVal;
|
||||
vpi_get_value(rfp->id.index, &vp);
|
||||
strcat(nm, vp.value.str);
|
||||
strcat(nm, "]");
|
||||
} else {
|
||||
nm = strdup(rfp->id.name);
|
||||
}
|
||||
char *rbuf = need_result_buf(strlen(bn) + strlen(nm) + 2, RBUF_STR);
|
||||
|
||||
switch (code) {
|
||||
|
|
@ -144,15 +154,18 @@ static char* signal_get_str(int code, vpiHandle ref)
|
|||
case vpiFullName:
|
||||
sprintf(rbuf, "%s.%s", bn, nm);
|
||||
free(bn);
|
||||
free(nm);
|
||||
return rbuf;
|
||||
|
||||
case vpiName:
|
||||
strcpy(rbuf, nm);
|
||||
free(bn);
|
||||
free(nm);
|
||||
return rbuf;
|
||||
}
|
||||
|
||||
free(bn);
|
||||
free(nm);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -169,7 +182,7 @@ static vpiHandle signal_get_handle(int code, vpiHandle ref)
|
|||
return rfp->parent;
|
||||
|
||||
case vpiIndex:
|
||||
return rfp->index;
|
||||
return rfp->parent ? rfp->id.index : 0;
|
||||
|
||||
case vpiScope:
|
||||
return &rfp->scope->base;
|
||||
|
|
@ -195,7 +208,7 @@ static vpiHandle signal_iterate(int code, vpiHandle ref)
|
|||
struct __vpiSignal*rfp = (struct __vpiSignal*)ref;
|
||||
|
||||
if (code == vpiIndex) {
|
||||
return array_index_iterate(code, rfp->index);
|
||||
return rfp->parent ? array_index_iterate(code, rfp->id.index) : 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
@ -521,7 +534,7 @@ static void signal_get_value(vpiHandle ref, s_vpi_value*vp)
|
|||
fprintf(stderr, "vvp internal error: get_value: "
|
||||
"value type %u not implemented."
|
||||
" Signal is %s in scope %s\n",
|
||||
vp->format, rfp->name, rfp->scope->name);
|
||||
vp->format, vpi_get_str(vpiName, ref), rfp->scope->name);
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
|
@ -648,7 +661,7 @@ static vpiHandle signal_put_value(vpiHandle ref, s_vpi_value*vp)
|
|||
fprintf(stderr, "vvp internal error: put_value: "
|
||||
"value type %u not implemented."
|
||||
" Signal is %s in scope %s\n",
|
||||
vp->format, rfp->name, rfp->scope->name);
|
||||
vp->format, vpi_get_str(vpiName, ref), rfp->scope->name);
|
||||
assert(0);
|
||||
|
||||
}
|
||||
|
|
@ -736,8 +749,7 @@ vpiHandle vpip_make_net(const char*name, int msb, int lsb,
|
|||
struct __vpiSignal*obj = allocate_vpiSignal();
|
||||
obj->base.vpi_type = &vpip_net_rt;
|
||||
obj->parent = 0;
|
||||
obj->index = 0;
|
||||
obj->name = name? vpip_name_string(name) : 0;
|
||||
obj->id.name = name? vpip_name_string(name) : 0;
|
||||
obj->msb = msb;
|
||||
obj->lsb = lsb;
|
||||
obj->signed_flag = signed_flag? 1 : 0;
|
||||
|
|
|
|||
25
vvp/words.cc
25
vvp/words.cc
|
|
@ -46,11 +46,13 @@ static void __compile_var_real(char*label, char*name,
|
|||
|
||||
compile_vpi_symbol(label, obj);
|
||||
|
||||
if (!array && name) {
|
||||
if (name) {
|
||||
assert(!array);
|
||||
vpip_attach_to_current_scope(obj);
|
||||
schedule_init_vector(vvp_net_ptr_t(net,0), fun->real_value());
|
||||
}
|
||||
if (array) {
|
||||
assert(!name);
|
||||
array_attach_word(array, array_addr, obj);
|
||||
}
|
||||
free(label);
|
||||
|
|
@ -62,11 +64,11 @@ void compile_var_real(char*label, char*name, int msb, int lsb)
|
|||
__compile_var_real(label, name, 0, 0, msb, lsb);
|
||||
}
|
||||
|
||||
void compile_varw_real(char*label, char*name, vvp_array_t array,
|
||||
void compile_varw_real(char*label, vvp_array_t array,
|
||||
unsigned long addr,
|
||||
int msb, int lsb)
|
||||
{
|
||||
__compile_var_real(label, name, array, addr, msb, lsb);
|
||||
__compile_var_real(label, 0, array, addr, msb, lsb);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -92,13 +94,15 @@ static void __compile_var(char*label, char*name,
|
|||
compile_vpi_symbol(label, obj);
|
||||
// If the signal has a name, then it goes into the current
|
||||
// scope as a signal.
|
||||
if (!array && name) {
|
||||
if (name) {
|
||||
assert(!array);
|
||||
vpip_attach_to_current_scope(obj);
|
||||
schedule_init_vector(vvp_net_ptr_t(node,0), vsig->vec4_value());
|
||||
}
|
||||
// If this is an array word, then it does not have a name, and
|
||||
// it is attached to the addressed array.
|
||||
if (array) {
|
||||
assert(!name);
|
||||
array_attach_word(array, array_addr, obj);
|
||||
}
|
||||
free(label);
|
||||
|
|
@ -119,11 +123,11 @@ void compile_variable(char*label, char*name,
|
|||
* This function is actually used by the compile_array function,
|
||||
* instead of directly by the parser.
|
||||
*/
|
||||
void compile_variablew(char*label, char*name, vvp_array_t array,
|
||||
void compile_variablew(char*label, vvp_array_t array,
|
||||
unsigned long array_addr,
|
||||
int msb, int lsb, char signed_flag)
|
||||
{
|
||||
__compile_var(label, name, array, array_addr, msb, lsb, signed_flag);
|
||||
__compile_var(label, 0, array, array_addr, msb, lsb, signed_flag);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -195,16 +199,9 @@ void compile_netw(char*label, char*array_label, unsigned long array_addr,
|
|||
bool signed_flag, bool net8_flag,
|
||||
unsigned argc, struct symb_s*argv)
|
||||
{
|
||||
/* Get the array name and build the word name. */
|
||||
const char *name = get_array_name(array_label);
|
||||
unsigned len = strlen(name) + 32;
|
||||
char *nbuf = (char *)malloc(len);
|
||||
snprintf(nbuf, len, "%s[%lu]", name, array_addr +
|
||||
get_array_base(array_label));
|
||||
__compile_net(label, strdup(nbuf), array_label, array_addr,
|
||||
__compile_net(label, 0, array_label, array_addr,
|
||||
msb, lsb, signed_flag, net8_flag,
|
||||
argc, argv);
|
||||
free(nbuf);
|
||||
}
|
||||
|
||||
void compile_net_real(char*label, char*name, int msb, int lsb,
|
||||
|
|
|
|||
Loading…
Reference in New Issue