Add support for passing array words to system tasks.
Array words don't have a vpiHandle with a label, so the %vpi_call needs a special syntac for arguments that reference array words. This syntax creates an array word reference that persists and can be used at a VPI object by system tasks.
This commit is contained in:
parent
d71a1cb9c1
commit
2dcb1514a2
|
|
@ -72,9 +72,14 @@ static void draw_vpi_taskfunc_args(const char*call_string,
|
||||||
unsigned parm_count = tnet
|
unsigned parm_count = tnet
|
||||||
? ivl_stmt_parm_count(tnet)
|
? ivl_stmt_parm_count(tnet)
|
||||||
: ivl_expr_parms(fnet);
|
: ivl_expr_parms(fnet);
|
||||||
struct vector_info *vec = 0x0;
|
|
||||||
unsigned int vecs= 0;
|
struct args_info {
|
||||||
unsigned int veci= 0;
|
char*text;
|
||||||
|
int vec_flag; /* True if the vec must be released. */
|
||||||
|
struct vector_info vec;
|
||||||
|
} *args = calloc(parm_count, sizeof(struct args_info));
|
||||||
|
|
||||||
|
char buffer[4096];
|
||||||
|
|
||||||
ivl_parameter_t par;
|
ivl_parameter_t par;
|
||||||
|
|
||||||
|
|
@ -92,17 +97,56 @@ static void draw_vpi_taskfunc_args(const char*call_string,
|
||||||
with VPI handles of their own. Therefore, skip
|
with VPI handles of their own. Therefore, skip
|
||||||
them in the process of evaluating expressions. */
|
them in the process of evaluating expressions. */
|
||||||
case IVL_EX_NONE:
|
case IVL_EX_NONE:
|
||||||
|
args[idx].text = strdup("\" \"");
|
||||||
|
continue;
|
||||||
|
|
||||||
case IVL_EX_ARRAY:
|
case IVL_EX_ARRAY:
|
||||||
case IVL_EX_NUMBER:
|
snprintf(buffer, sizeof buffer,
|
||||||
|
"v%p", ivl_expr_signal(expr));
|
||||||
|
args[idx].text = strdup(buffer);
|
||||||
|
continue;
|
||||||
|
|
||||||
|
case IVL_EX_NUMBER: {
|
||||||
|
unsigned bit, wid = ivl_expr_width(expr);
|
||||||
|
const char*bits = ivl_expr_bits(expr);
|
||||||
|
char*dp;
|
||||||
|
|
||||||
|
snprintf(buffer, sizeof buffer,
|
||||||
|
"%u'%sb", wid, ivl_expr_signed(expr)? "s" : "");
|
||||||
|
dp = buffer + strlen(buffer);
|
||||||
|
for (bit = wid ; bit > 0 ; bit -= 1)
|
||||||
|
*dp++ = bits[bit-1];
|
||||||
|
*dp++ = 0;
|
||||||
|
assert(dp - buffer <= sizeof buffer);
|
||||||
|
args[idx].text = strdup(buffer);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
case IVL_EX_STRING:
|
case IVL_EX_STRING:
|
||||||
|
if (( par = ivl_expr_parameter(expr) )) {
|
||||||
|
snprintf(buffer, sizeof buffer, "P_%p", par);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
snprintf(buffer, sizeof buffer, "\"%s\"", ivl_expr_string(expr));
|
||||||
|
}
|
||||||
|
args[idx].text = strdup(buffer);
|
||||||
|
continue;
|
||||||
|
|
||||||
case IVL_EX_EVENT:
|
case IVL_EX_EVENT:
|
||||||
|
snprintf(buffer, sizeof buffer, "E_%p", ivl_expr_event(expr));
|
||||||
|
args[idx].text = strdup(buffer);
|
||||||
|
continue;
|
||||||
case IVL_EX_SCOPE:
|
case IVL_EX_SCOPE:
|
||||||
|
snprintf(buffer, sizeof buffer, "S_%p", ivl_expr_scope(expr));
|
||||||
|
args[idx].text = strdup(buffer);
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case IVL_EX_SFUNC:
|
case IVL_EX_SFUNC:
|
||||||
if (is_magic_sfunc(ivl_expr_name(expr)))
|
if (is_magic_sfunc(ivl_expr_name(expr))) {
|
||||||
|
snprintf(buffer, sizeof buffer, "%s", ivl_expr_name(expr));
|
||||||
|
args[idx].text = strdup(buffer);
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IVL_EX_SIGNAL:
|
case IVL_EX_SIGNAL:
|
||||||
|
|
@ -125,21 +169,47 @@ static void draw_vpi_taskfunc_args(const char*call_string,
|
||||||
} else if (ivl_expr_signed(expr) !=
|
} else if (ivl_expr_signed(expr) !=
|
||||||
ivl_signal_signed(ivl_expr_signal(expr))) {
|
ivl_signal_signed(ivl_expr_signal(expr))) {
|
||||||
break;
|
break;
|
||||||
} else if (! is_fixed_memory_word(expr)){
|
} else if (is_fixed_memory_word(expr)) {
|
||||||
break;
|
/* This is a word of a non-array, or a word
|
||||||
} else {
|
of a net array, so we can address the
|
||||||
/* Some array selects need to be evaluated. */
|
word directly. */
|
||||||
|
ivl_signal_t sig = ivl_expr_signal(expr);
|
||||||
|
unsigned use_word = 0;
|
||||||
ivl_expr_t word_ex = ivl_expr_oper1(expr);
|
ivl_expr_t word_ex = ivl_expr_oper1(expr);
|
||||||
if (word_ex && !number_is_immediate(word_ex,
|
if (word_ex) {
|
||||||
8*sizeof(unsigned))) {
|
/* Some array select have been evaluated. */
|
||||||
|
if (number_is_immediate(word_ex, 8*sizeof(unsigned))) {
|
||||||
|
use_word = get_number_immediate(word_ex);
|
||||||
|
word_ex = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (word_ex)
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
assert(word_ex == 0);
|
||||||
|
snprintf(buffer, sizeof buffer, "v%p_%u", sig, use_word);
|
||||||
|
args[idx].text = strdup(buffer);
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
/* What's left, this is the work of a var
|
||||||
|
array. Create the right code to handle
|
||||||
|
it. */
|
||||||
|
ivl_signal_t sig = ivl_expr_signal(expr);
|
||||||
|
unsigned use_word = 0;
|
||||||
|
ivl_expr_t word_ex = ivl_expr_oper1(expr);
|
||||||
|
if (word_ex) {
|
||||||
|
/* Some array select have been evaluated. */
|
||||||
|
if (number_is_immediate(word_ex, 8*sizeof(unsigned))) {
|
||||||
|
use_word = get_number_immediate(word_ex);
|
||||||
|
word_ex = 0;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (word_ex)
|
||||||
|
break;
|
||||||
|
|
||||||
|
snprintf(buffer, sizeof buffer, "&A<v%p, %u>", sig, use_word);
|
||||||
case IVL_EX_MEMORY:
|
args[idx].text = strdup(buffer);
|
||||||
if (!ivl_expr_oper1(expr)) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -149,143 +219,43 @@ static void draw_vpi_taskfunc_args(const char*call_string,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
vec = (struct vector_info *)
|
|
||||||
realloc(vec, (vecs+1)*sizeof(struct vector_info));
|
|
||||||
|
|
||||||
switch (ivl_expr_value(expr)) {
|
switch (ivl_expr_value(expr)) {
|
||||||
case IVL_VT_LOGIC:
|
case IVL_VT_LOGIC:
|
||||||
case IVL_VT_BOOL:
|
case IVL_VT_BOOL:
|
||||||
vec[vecs] = draw_eval_expr(expr, 0);
|
args[idx].vec_flag = 1;
|
||||||
|
args[idx].vec = draw_eval_expr(expr, 0);
|
||||||
|
snprintf(buffer, sizeof buffer,
|
||||||
|
"T<%u,%u,%s>", args[idx].vec.base, args[idx].vec.wid,
|
||||||
|
ivl_expr_signed(expr)? "s" : "u");
|
||||||
break;
|
break;
|
||||||
case IVL_VT_REAL:
|
case IVL_VT_REAL:
|
||||||
vec[vecs].base = draw_eval_real(expr);
|
args[idx].vec_flag = 1;
|
||||||
vec[vecs].wid = 0;
|
args[idx].vec.base = draw_eval_real(expr);
|
||||||
|
args[idx].vec.wid = 0;
|
||||||
|
snprintf(buffer, sizeof buffer,
|
||||||
|
"W<%u,r>", args[idx].vec.base);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
vecs++;
|
args[idx].text = strdup(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(vvp_out, "%s", call_string);
|
fprintf(vvp_out, "%s", call_string);
|
||||||
|
|
||||||
for (idx = 0 ; idx < parm_count ; idx += 1) {
|
for (idx = 0 ; idx < parm_count ; idx += 1) {
|
||||||
ivl_expr_t expr = tnet
|
|
||||||
? ivl_stmt_parm(tnet, idx)
|
|
||||||
: ivl_expr_parm(fnet, idx);
|
|
||||||
|
|
||||||
switch (ivl_expr_type(expr)) {
|
fprintf(vvp_out, ", %s", args[idx].text);
|
||||||
case IVL_EX_NONE:
|
free(args[idx].text);
|
||||||
fprintf(vvp_out, ", \" \"");
|
if (args[idx].vec_flag) {
|
||||||
continue;
|
if (args[idx].vec.wid > 0)
|
||||||
|
clr_vector(args[idx].vec);
|
||||||
case IVL_EX_ARRAY:
|
else
|
||||||
fprintf(vvp_out, ", v%p", ivl_expr_signal(expr));
|
clr_word(args[idx].vec.base);
|
||||||
continue;
|
}
|
||||||
|
|
||||||
case IVL_EX_NUMBER: {
|
|
||||||
unsigned bit, wid = ivl_expr_width(expr);
|
|
||||||
const char*bits = ivl_expr_bits(expr);
|
|
||||||
|
|
||||||
fprintf(vvp_out, ", %u'%sb", wid,
|
|
||||||
ivl_expr_signed(expr)? "s" : "");
|
|
||||||
for (bit = wid ; bit > 0 ; bit -= 1)
|
|
||||||
fputc(bits[bit-1], vvp_out);
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case IVL_EX_SIGNAL:
|
free(args);
|
||||||
/* If this is a part select, then the value was
|
|
||||||
calculated above. Otherwise, just pass the
|
|
||||||
signal. */
|
|
||||||
if (ivl_expr_width(expr) !=
|
|
||||||
ivl_signal_width(ivl_expr_signal(expr))) {
|
|
||||||
break;
|
|
||||||
|
|
||||||
} else if (ivl_expr_signed(expr) !=
|
|
||||||
ivl_signal_signed(ivl_expr_signal(expr))) {
|
|
||||||
break;
|
|
||||||
|
|
||||||
} else if (! is_fixed_memory_word(expr)){
|
|
||||||
break;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
ivl_signal_t sig = ivl_expr_signal(expr);
|
|
||||||
unsigned use_word = 0;
|
|
||||||
ivl_expr_t word_ex = ivl_expr_oper1(expr);
|
|
||||||
if (word_ex) {
|
|
||||||
/* Some array select have been evaluated. */
|
|
||||||
if (!number_is_immediate(word_ex,
|
|
||||||
8*sizeof(unsigned))) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
use_word = get_number_immediate(word_ex);
|
|
||||||
}
|
|
||||||
fprintf(vvp_out, ", v%p_%u", sig, use_word);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
assert(0);
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case IVL_EX_STRING:
|
|
||||||
if (( par = ivl_expr_parameter(expr) )) {
|
|
||||||
fprintf(vvp_out, ", P_%p", par);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
fprintf(vvp_out, ", \"%s\"",
|
|
||||||
ivl_expr_string(expr));
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case IVL_EX_EVENT:
|
|
||||||
fprintf(vvp_out, ", E_%p", ivl_expr_event(expr));
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case IVL_EX_SCOPE:
|
|
||||||
fprintf(vvp_out, ", S_%p", ivl_expr_scope(expr));
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case IVL_EX_SFUNC:
|
|
||||||
if (is_magic_sfunc(ivl_expr_name(expr))) {
|
|
||||||
fprintf(vvp_out, ", %s", ivl_expr_name(expr));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
assert(veci < vecs);
|
|
||||||
|
|
||||||
switch (ivl_expr_value(expr)) {
|
|
||||||
|
|
||||||
case IVL_VT_LOGIC:
|
|
||||||
case IVL_VT_BOOL:
|
|
||||||
fprintf(vvp_out, ", T<%u,%u,%s>", vec[veci].base,
|
|
||||||
vec[veci].wid, ivl_expr_signed(expr)? "s" : "u");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case IVL_VT_REAL:
|
|
||||||
fprintf(vvp_out, ", W<%u,r>", vec[veci].base);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
veci++;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(veci == vecs);
|
|
||||||
|
|
||||||
if (vecs) {
|
|
||||||
for (idx = 0; idx < vecs; idx++) {
|
|
||||||
if (vec[idx].wid > 0)
|
|
||||||
clr_vector(vec[idx]);
|
|
||||||
else if (vec[idx].wid == 0)
|
|
||||||
clr_word(vec[idx].base);
|
|
||||||
}
|
|
||||||
free(vec);
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf(vvp_out, ";\n");
|
fprintf(vvp_out, ";\n");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
88
vvp/array.cc
88
vvp/array.cc
|
|
@ -77,6 +77,12 @@ struct __vpiArrayIndex {
|
||||||
unsigned done;
|
unsigned done;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct __vpiArrayVthrA {
|
||||||
|
struct __vpiHandle base;
|
||||||
|
struct __vpiArray*array;
|
||||||
|
unsigned address;
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The vpiArrayWord is magic. It is used as the handle to return when
|
* The vpiArrayWord is magic. It is used as the handle to return when
|
||||||
* vpi code tries to index or scan an array of variable words. The
|
* vpi code tries to index or scan an array of variable words. The
|
||||||
|
|
@ -117,6 +123,10 @@ static int vpi_array_var_word_get(int code, vpiHandle);
|
||||||
static void vpi_array_var_word_get_value(vpiHandle, p_vpi_value);
|
static void vpi_array_var_word_get_value(vpiHandle, p_vpi_value);
|
||||||
static vpiHandle vpi_array_var_word_put_value(vpiHandle, p_vpi_value, int);
|
static vpiHandle vpi_array_var_word_put_value(vpiHandle, p_vpi_value, int);
|
||||||
|
|
||||||
|
static int vpi_array_vthr_A_get(int code, vpiHandle);
|
||||||
|
static void vpi_array_vthr_A_get_value(vpiHandle, p_vpi_value);
|
||||||
|
static vpiHandle vpi_array_vthr_A_put_value(vpiHandle, p_vpi_value, int);
|
||||||
|
|
||||||
static const struct __vpirt vpip_arraymem_rt = {
|
static const struct __vpirt vpip_arraymem_rt = {
|
||||||
vpiMemory,
|
vpiMemory,
|
||||||
vpi_array_get,
|
vpi_array_get,
|
||||||
|
|
@ -167,12 +177,27 @@ static const struct __vpirt vpip_array_var_word_rt = {
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct __vpirt vpip_array_vthr_A_rt = {
|
||||||
|
vpiMemoryWord,
|
||||||
|
&vpi_array_vthr_A_get,
|
||||||
|
0,
|
||||||
|
&vpi_array_vthr_A_get_value,
|
||||||
|
&vpi_array_vthr_A_put_value,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
};
|
||||||
|
|
||||||
# define ARRAY_HANDLE(ref) (assert(ref->vpi_type->type_code==vpiMemory), \
|
# define ARRAY_HANDLE(ref) (assert(ref->vpi_type->type_code==vpiMemory), \
|
||||||
(struct __vpiArray*)ref)
|
(struct __vpiArray*)ref)
|
||||||
|
|
||||||
# define ARRAY_VAR_WORD(ref) (assert(ref->vpi_type->type_code==vpiMemoryWord), \
|
# define ARRAY_VAR_WORD(ref) (assert(ref->vpi_type->type_code==vpiMemoryWord), \
|
||||||
(struct __vpiArrayWord*)ref)
|
(struct __vpiArrayWord*)ref)
|
||||||
|
|
||||||
|
# define ARRAY_VTHR_A_HANDLE(ref) (assert(ref->vpi_type->type_code==vpiMemoryWord), \
|
||||||
|
(struct __vpiArrayVthrA*)ref)
|
||||||
|
|
||||||
static void array_make_vals_words(struct __vpiArray*parent)
|
static void array_make_vals_words(struct __vpiArray*parent)
|
||||||
{
|
{
|
||||||
assert(parent->vals_words == 0);
|
assert(parent->vals_words == 0);
|
||||||
|
|
@ -399,6 +424,53 @@ static int array_index_free_object(vpiHandle ref)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int vpi_array_vthr_A_get(int code, vpiHandle ref)
|
||||||
|
{
|
||||||
|
struct __vpiArrayVthrA*obj = ARRAY_VTHR_A_HANDLE(ref);
|
||||||
|
struct __vpiArray*parent = obj->array;
|
||||||
|
|
||||||
|
switch (code) {
|
||||||
|
case vpiLineNo:
|
||||||
|
return 0; // Not implemented for now!
|
||||||
|
|
||||||
|
case vpiSize:
|
||||||
|
assert(parent->vals);
|
||||||
|
return parent->vals_width;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static void vpi_array_vthr_A_get_value(vpiHandle ref, p_vpi_value value)
|
||||||
|
{
|
||||||
|
struct __vpiArrayVthrA*obj = ARRAY_VTHR_A_HANDLE(ref);
|
||||||
|
struct __vpiArray*parent = obj->array;
|
||||||
|
|
||||||
|
assert(parent);
|
||||||
|
assert(parent->vals);
|
||||||
|
assert(obj->address < parent->array_count);
|
||||||
|
|
||||||
|
vpip_vec4_get_value(parent->vals[obj->address],
|
||||||
|
parent->vals_width, false, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static vpiHandle vpi_array_vthr_A_put_value(vpiHandle ref, p_vpi_value vp, int)
|
||||||
|
{
|
||||||
|
struct __vpiArrayVthrA*obj = ARRAY_VTHR_A_HANDLE(ref);
|
||||||
|
struct __vpiArray*parent = obj->array;
|
||||||
|
|
||||||
|
unsigned index = obj->address;
|
||||||
|
|
||||||
|
assert(parent);
|
||||||
|
assert(obj->address < parent->array_count);
|
||||||
|
|
||||||
|
vvp_vector4_t val = vec4_from_vpi_value(vp, parent->vals_width);
|
||||||
|
array_set_word(parent, index, 0, val);
|
||||||
|
|
||||||
|
return ref;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void array_set_word(vvp_array_t arr,
|
void array_set_word(vvp_array_t arr,
|
||||||
unsigned address,
|
unsigned address,
|
||||||
unsigned part_off,
|
unsigned part_off,
|
||||||
|
|
@ -773,3 +845,19 @@ void compile_array_alias(char*label, char*name, char*src)
|
||||||
free(name);
|
free(name);
|
||||||
free(src);
|
free(src);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vpiHandle vpip_make_vthr_A(char*label, unsigned addr)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
|
||||||
|
obj->address = addr;
|
||||||
|
assert(addr < obj->array->array_count);
|
||||||
|
|
||||||
|
return &(obj->base);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -190,6 +190,7 @@
|
||||||
return T_NUMBER; }
|
return T_NUMBER; }
|
||||||
|
|
||||||
|
|
||||||
|
"&A" { return K_A; }
|
||||||
|
|
||||||
/* Handle some specialized constant/literals as symbols. */
|
/* Handle some specialized constant/literals as symbols. */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -65,7 +65,7 @@ static struct __vpiModPath*modpath_dst = 0;
|
||||||
vvp_delay_t*cdelay;
|
vvp_delay_t*cdelay;
|
||||||
};
|
};
|
||||||
|
|
||||||
%token K_ALIAS K_ALIAS_S K_ALIAS_R
|
%token K_A K_ALIAS K_ALIAS_S K_ALIAS_R
|
||||||
%token K_ARITH_ABS K_ARITH_DIV K_ARITH_DIV_R K_ARITH_DIV_S K_ARITH_MOD
|
%token K_ARITH_ABS K_ARITH_DIV K_ARITH_DIV_R K_ARITH_DIV_S K_ARITH_MOD
|
||||||
%token K_ARITH_MOD_R
|
%token K_ARITH_MOD_R
|
||||||
%token K_ARITH_MULT K_ARITH_MULT_R K_ARITH_SUB K_ARITH_SUB_R
|
%token K_ARITH_MULT K_ARITH_MULT_R K_ARITH_SUB K_ARITH_SUB_R
|
||||||
|
|
@ -797,6 +797,8 @@ argument
|
||||||
{ $$ = vpip_make_binary_const($1.idx, $1.text);
|
{ $$ = vpip_make_binary_const($1.idx, $1.text);
|
||||||
free($1.text);
|
free($1.text);
|
||||||
}
|
}
|
||||||
|
| K_A '<' T_SYMBOL ',' T_NUMBER '>'
|
||||||
|
{ $$ = vpip_make_vthr_A($3, $5); }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -433,6 +433,8 @@ 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_word(unsigned base, const char*type);
|
||||||
|
|
||||||
|
vpiHandle vpip_make_vthr_A(char*symbol, unsigned index);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function is called before any compilation to load VPI
|
* This function is called before any compilation to load VPI
|
||||||
* modules. This gives the modules a chance to announce their
|
* modules. This gives the modules a chance to announce their
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue