From a2dc1e0a29450da69d2f8998b194e1ed0ace9773 Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Sun, 8 Jun 2008 21:38:35 -0700 Subject: [PATCH] Add means for &A<> to index using a calculated index. This is not a solution to all the problems, but is a better catch-all then what is currently there. Allow the index field to be a T<> that accesses the thread to get the address index. Note that the lexor.lex currently returns the T<> as a T_SYMBOL, and the users of T_SYMBOL objects need to interpret the meaning. This is probably not the best idea, in light of all the other *<> formats that now exist. --- tgt-vvp/draw_vpi.c | 15 ++++++++--- vvp/README.txt | 41 ++++++++++++++++++++++++++++ vvp/array.cc | 66 +++++++++++++++++++++++++++++++++++----------- vvp/parse.y | 2 ++ vvp/vpi_priv.h | 1 + 5 files changed, 106 insertions(+), 19 deletions(-) diff --git a/tgt-vvp/draw_vpi.c b/tgt-vvp/draw_vpi.c index 2930c6a21..5ea34554f 100644 --- a/tgt-vvp/draw_vpi.c +++ b/tgt-vvp/draw_vpi.c @@ -285,10 +285,17 @@ static void draw_vpi_taskfunc_args(const char*call_string, word_ex = 0; } } - if (word_ex) - break; - - snprintf(buffer, sizeof buffer, "&A", sig, use_word); + if (word_ex) { + struct vector_info av; + av = draw_eval_expr(word_ex, STUFF_OK_XZ); + snprintf(buffer, sizeof buffer, + "&A>", sig, av.base, av.wid); + args[idx].vec = av; + args[idx].vec_flag = 1; + } else { + snprintf(buffer, sizeof buffer, + "&A", sig, use_word); + } args[idx].text = strdup(buffer); continue; } diff --git a/vvp/README.txt b/vvp/README.txt index ec2c6dd58..2577a9d17 100644 --- a/vvp/README.txt +++ b/vvp/README.txt @@ -754,6 +754,47 @@ by the fork atomically joins that scope. Once the transient thread joins the scope, it stays there until it ends. Threads never change scopes, not even transient threads. +VPI TASK/FUNCTION CALLS + +Threads call vpi tasks with the %vpi_call or %vpi_func +instructions. The formats are: + + %vpi_call , ... ; + %vpi_func , ... ; + %vpi_func/r , ... ; + +The is an index into the string table. The indexed string +is the source code file name where this call appears. The is +the line number from the source code where this task/function appears. + +The is a string that is the name of the system +task/function. For example, "$display", $strobe", etc. This name is +looked up and compared with the registered system tasks/functions. + +The ... is a comma (",") separated list of arguments. These are +made available to the VPI code as vpi handles. + +* The &A<> argument + +The &A<> argument is a reference to the word of a variable array. The +syntax is: + + &A '<' , '>' + +The is the label for a variable array, and the is +the cannonical word index as an unsigned integer. + +* The T<> argument + +This is the catch-all for arguments that are not otherwise +handled. This references the bits directly in the thread. The format +is: + + T '<' , , '>' + +The and are the base of a vector value in the thread and +the width of the vector. The is 's' or 'u' for signed or unsigned. + TRUTH TABLES The logic that a functor represents is expressed as a truth table. The diff --git a/vvp/array.cc b/vvp/array.cc index 2296a486c..8143f2c23 100644 --- a/vvp/array.cc +++ b/vvp/array.cc @@ -83,7 +83,25 @@ struct __vpiArrayIndex { struct __vpiArrayVthrA { struct __vpiHandle base; struct __vpiArray*array; + // If wid==0, then address is the address into the array. unsigned address; + // If wid >0, then the address is the base and wid the vector + // width of the index to pull from the thread. + unsigned wid; + + unsigned get_address() const + { + if (wid == 0) + return address; + vvp_vector4_t tmp (wid); + for (unsigned idx = 0 ; idx < wid ; idx += 1) { + vvp_bit4_t bit = vthread_get_bit(vpip_current_vthread, address+idx); + tmp.set_bit(idx, bit); + } + unsigned long val; + vector4_to_value(tmp, val); + return val; + } }; /* @@ -516,7 +534,6 @@ static int vpi_array_vthr_A_get(int code, vpiHandle ref) return 0; // Not implemented for now! case vpiSize: - assert(parent->vals); return parent->vals_width; case vpiLeftRange: @@ -546,7 +563,7 @@ static char*vpi_array_vthr_A_get_str(int code, vpiHandle ref) } char sidx [64]; - snprintf(sidx, 63, "%d", (int)obj->address + parent->first_addr.value); + snprintf(sidx, 63, "%d", (int)obj->get_address() + parent->first_addr.value); return generic_get_str(code, &parent->scope->base, parent->name, sidx); } @@ -557,18 +574,10 @@ static void vpi_array_vthr_A_get_value(vpiHandle ref, p_vpi_value value) struct __vpiArray*parent = obj->array; assert(parent); - assert(parent->vals); - assert(obj->address < parent->array_count); - unsigned index = obj->address; - unsigned width = parent->vals_width; - - /* If we don't have a value yet just return X. */ - if (parent->vals[index].size() == 0) { - vpip_vec4_get_value(vvp_vector4_t(width), width, false, value); - } else { - vpip_vec4_get_value(parent->vals[index], width, false, value); - } + unsigned index = obj->get_address(); + vvp_vector4_t tmp = array_get_word(parent, index); + vpip_vec4_get_value(tmp, parent->vals_width, false, value); } static vpiHandle vpi_array_vthr_A_put_value(vpiHandle ref, p_vpi_value vp, int) @@ -577,10 +586,10 @@ static vpiHandle vpi_array_vthr_A_put_value(vpiHandle ref, p_vpi_value vp, int) assert(obj); struct __vpiArray*parent = obj->array; - unsigned index = obj->address; + unsigned index = obj->get_address(); assert(parent); - assert(obj->address < parent->array_count); + assert(index < parent->array_count); vvp_vector4_t val = vec4_from_vpi_value(vp, parent->vals_width); array_set_word(parent, index, 0, val); @@ -1053,13 +1062,40 @@ vpiHandle vpip_make_vthr_A(char*label, unsigned addr) obj->array = array_find(label); assert(obj->array); + free(label); obj->address = addr; + obj->wid = 0; assert(addr < obj->array->array_count); return &(obj->base); } +vpiHandle vpip_make_vthr_A(char*label, char*symbol) +{ + struct __vpiArrayVthrA*obj = (struct __vpiArrayVthrA*) + malloc(sizeof (struct __vpiArrayVthrA)); + + obj->base.vpi_type = &vpip_array_vthr_A_rt; + + obj->array = array_find(label); + assert(obj->array); + free(label); + + unsigned base; + unsigned wid; + char sflag; + int rc = sscanf(symbol, "T<%u,%u,%c>", &base, &wid, &sflag); + assert(rc == 3); + free(symbol); + + obj->address = base; + obj->wid = wid; + assert(sflag == 'u'); + + return &(obj->base); +} + void compile_array_cleanup(void) { if (array_table) { diff --git a/vvp/parse.y b/vvp/parse.y index 1bce45a2d..8fb6e57e8 100644 --- a/vvp/parse.y +++ b/vvp/parse.y @@ -817,6 +817,8 @@ argument } | K_A '<' T_SYMBOL ',' T_NUMBER '>' { $$ = vpip_make_vthr_A($3, $5); } + | K_A '<' T_SYMBOL ',' T_SYMBOL '>' + { $$ = vpip_make_vthr_A($3, $5); } | K_PV '<' T_SYMBOL ',' T_NUMBER ',' T_NUMBER '>' { $$ = vpip_make_PV($3, $5, $7); } | K_PV '<' T_SYMBOL ',' '-' T_NUMBER ',' T_NUMBER '>' diff --git a/vvp/vpi_priv.h b/vvp/vpi_priv.h index be3f42bef..4d7b3791e 100644 --- a/vvp/vpi_priv.h +++ b/vvp/vpi_priv.h @@ -446,6 +446,7 @@ vpiHandle vpip_make_vthr_vector(unsigned base, unsigned wid, bool signed_flag); vpiHandle vpip_make_vthr_word(unsigned base, const char*type); vpiHandle vpip_make_vthr_A(char*symbol, unsigned index); +vpiHandle vpip_make_vthr_A(char*symbol, char*symbol); /* * This function is called before any compilation to load VPI