From 2851b9bd9a131c7c71723c9f8716278c323579a7 Mon Sep 17 00:00:00 2001 From: Cary R Date: Tue, 20 Nov 2007 16:34:00 -0800 Subject: [PATCH] Add the ability to dump array words This patch adds the ability to dump array words. The words are only dumped if they appear in a $dumpvars() statement (they are not dumped by default). The name used for the word is [], so you can get unexpected name conflicts. There is also a slight increase in the memory requirements since each array word now keeps its own name information. In the future we would like to change this, but that is a much larger rewrite of the array code in vvp. This patch also needs the "Prefix escaped identifier ..." patch to work correctly (the array word name is an escaped identifier). --- vvp/array.cc | 29 +++++++++++++++++++++++++++-- vvp/array.h | 17 ++++------------- vvp/vpi_priv.h | 2 +- vvp/vpi_signal.cc | 4 ++-- vvp/words.cc | 27 ++++++++++++++++----------- 5 files changed, 50 insertions(+), 29 deletions(-) diff --git a/vvp/array.cc b/vvp/array.cc index ca19b942e..6f8c8f74a 100644 --- a/vvp/array.cc +++ b/vvp/array.cc @@ -69,6 +69,22 @@ struct __vpiArrayIterator { unsigned next; }; +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); @@ -339,8 +355,13 @@ 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); - compile_variablew(strdup(buf), array, idx, msb, lsb, signed_flag); + 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); } free(label); @@ -358,8 +379,12 @@ 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); - compile_varw_real(strdup(buf), array, idx, msb, lsb); + snprintf(nbuf, len, "%s[%u]", name, idx + arr->first_addr.value); + compile_varw_real(strdup(buf), strdup(nbuf), array, idx, msb, lsb); + free(nbuf); } free(label); diff --git a/vvp/array.h b/vvp/array.h index 6a76f663e..02fb8b9c4 100644 --- a/vvp/array.h +++ b/vvp/array.h @@ -32,6 +32,8 @@ 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 void array_word_change(vvp_array_t array, unsigned long addr); @@ -44,21 +46,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, vvp_array_t array, +extern void compile_variablew(char*label, char*name, vvp_array_t array, unsigned long array_addr, int msb, int lsb, char signed_flag); -extern void compile_varw_real(char*label, vvp_array_t array, +extern void compile_varw_real(char*label, char*name, vvp_array_t array, unsigned long array_addr, int msb, int lsb); - -/* - * $Log: array.h,v $ - * Revision 1.2 2007/04/10 01:26:16 steve - * variable arrays generated without writing a record for each word. - * - * Revision 1.1 2007/01/18 00:24:10 steve - * Add missing array source files to CVS. - * - */ - #endif diff --git a/vvp/vpi_priv.h b/vvp/vpi_priv.h index 8cecc64da..48a84d891 100644 --- a/vvp/vpi_priv.h +++ b/vvp/vpi_priv.h @@ -191,7 +191,7 @@ extern void vpip_make_root_iterator(struct __vpiHandle**&table, struct __vpiSignal { struct __vpiHandle base; struct __vpiScope* scope; - /* The name of this reg/net, or nil if this is an array word. */ + /* The name of this reg/net, or [] for array words. */ const char*name; /* The indices that define the width and access offset. */ int msb, lsb; diff --git a/vvp/vpi_signal.cc b/vvp/vpi_signal.cc index 7cd6aee75..e49262ac0 100644 --- a/vvp/vpi_signal.cc +++ b/vvp/vpi_signal.cc @@ -702,8 +702,8 @@ static struct __vpiSignal* allocate_vpiSignal(void) * Construct a vpiNet object. Give the object specified dimensions, * and point to the specified functor for the lsb. * - * The name is the PLI name for the object. If it is nil, then this is - * actually the word of an array and has no name of its own. + * The name is the PLI name for the object. If it is an array it is + * []. */ vpiHandle vpip_make_net(const char*name, int msb, int lsb, bool signed_flag, vvp_net_t*node) diff --git a/vvp/words.cc b/vvp/words.cc index 0cff6da08..8de251d27 100644 --- a/vvp/words.cc +++ b/vvp/words.cc @@ -46,13 +46,11 @@ static void __compile_var_real(char*label, char*name, compile_vpi_symbol(label, obj); - if (name) { - assert(!array); + if (!array && name) { 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); @@ -64,11 +62,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, vvp_array_t array, +void compile_varw_real(char*label, char*name, vvp_array_t array, unsigned long addr, int msb, int lsb) { - __compile_var_real(label, 0, array, addr, msb, lsb); + __compile_var_real(label, name, array, addr, msb, lsb); } /* @@ -94,15 +92,13 @@ 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 (name) { - assert(!array); + if (!array && name) { 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); @@ -123,10 +119,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, vvp_array_t array, unsigned long array_addr, +void compile_variablew(char*label, char*name, vvp_array_t array, + unsigned long array_addr, int msb, int lsb, char signed_flag) { - __compile_var(label, 0, array, array_addr, msb, lsb, signed_flag); + __compile_var(label, name, array, array_addr, msb, lsb, signed_flag); } /* @@ -198,9 +195,16 @@ void compile_netw(char*label, char*array_label, unsigned long array_addr, bool signed_flag, bool net8_flag, unsigned argc, struct symb_s*argv) { - __compile_net(label, 0, array_label, array_addr, + /* 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[%d]", name, array_addr + + get_array_base(array_label)); + __compile_net(label, strdup(nbuf), 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, @@ -272,3 +276,4 @@ void compile_alias_real(char*label, char*name, int msb, int lsb, free(argv[0].text); free(argv); } +