Add support for real parameters in vvp.

vvp did not have the ability to handle real parameters.
This patch fixes that omission. Parameters are only used
by vpi calls to get compile time information.
This commit is contained in:
Cary R 2008-03-21 19:16:19 -07:00 committed by Stephen Williams
parent 259e4294e3
commit 12f8af645f
7 changed files with 138 additions and 38 deletions

View File

@ -469,11 +469,10 @@ static char* draw_C8_to_string(ivl_net_const_t cptr,
return result;
}
static char* draw_Cr_to_string(ivl_net_const_t cptr)
static char* draw_Cr_to_string(double value)
{
char tmp[256];
double value = ivl_const_real(cptr);
uint64_t mant = 0;
if (isinf(value)) {
@ -641,7 +640,7 @@ static char* draw_net_input_drive(ivl_nexus_t nex, ivl_nexus_ptr_t nptr)
break;
case IVL_VT_REAL:
result = draw_Cr_to_string(cptr);
result = draw_Cr_to_string(ivl_const_real(cptr));
break;
default:
@ -2468,6 +2467,12 @@ int draw_scope(ivl_scope_t net, ivl_scope_t parent)
}
fprintf(vvp_out, ">;\n");
break;
case IVL_EX_REALNUM:
fprintf(vvp_out, "P_%p .param/real \"%s\", %s; value=%g\n",
par, ivl_parameter_basename(par),
draw_Cr_to_string(ivl_expr_dvalue(pex)),
ivl_expr_dvalue(pex));
break;
default:
fprintf(vvp_out, "; parameter type %d unsupported\n",
ivl_expr_type(pex));

View File

@ -737,6 +737,47 @@ void compile_vpi_time_precision(long pre)
vpip_set_time_precision(pre);
}
/*
* Convert a Cr string value to double.
*
* The format is broken into mantissa and exponent.
* The exponent in turn includes a sign bit.
*
* The mantissa is a 64bit integer value (encoded in hex).
*
* The exponent included the sign bit (0x4000) and the binary
* exponent offset by 0x1000. The actual exponent is the
* encoded exponent - 0x1000.
*
* The real value is sign * (mant ** exp).
*/
double crstring_to_double(char*label)
{
char*cp = label+3;
assert(*cp == 'm');
cp += 1;
uint64_t mant = strtoull(cp, &cp, 16);
assert(*cp == 'g');
cp += 1;
int exp = strtoul(cp, 0, 16);
double tmp;
if (mant == 0 && exp == 0x3fff) {
tmp = INFINITY;
} else if (mant == 0 && exp == 0x7fff) {
tmp = -INFINITY;
} else if (exp == 0x3fff) {
tmp = nan("");
} else {
double sign = (exp & 0x4000)? -1.0 : 1.0;
exp &= 0x1fff;
tmp = sign * ldexp((double)mant, exp - 0x1000);
}
return tmp;
}
/*
* Run through the arguments looking for the nodes that are
* connected to my input ports. For each source functor that I
@ -819,42 +860,13 @@ void input_connect(vvp_net_t*fdx, unsigned port, char*label)
}
/* Handle the Cr<> constant driver, which is a real-value
driver. The format is broken into mantissa and
exponent. The exponent in turn includes a sign bit.
The mantissa is a 64bit integer value (encoded in hex).
The exponent included the sign bit (0x4000) and the binary
exponent offset by 0x1000. The actual exponent is the
encoded exponent - 0x1000.
The real value is sign * (mant ** exp). */
driver. */
if ((strncmp(label, "Cr<", 3) == 0)
&& ((tp = strchr(label,'>')))
&& (tp[1] == 0)
&& (strspn(label+3, "0123456789abcdefmg")+3 == (unsigned)(tp-label))) {
char*cp = label+3;
assert(*cp == 'm');
cp += 1;
uint64_t mant = strtoull(cp, &cp, 16);
assert(*cp == 'g');
cp += 1;
int exp = strtoul(cp, 0, 16);
double tmp;
if (mant == 0 && exp == 0x3fff) {
tmp = INFINITY;
} else if (mant == 0 && exp == 0x7fff) {
tmp = -INFINITY;
} else if (exp == 0x3fff) {
tmp = nan("");
} else {
double sign = (exp & 0x4000)? -1.0 : 1.0;
exp &= 0x1fff;
tmp = sign * ldexp((double)mant, exp - 0x1000);
}
double tmp = crstring_to_double(label);
schedule_set_vector(ifdx, tmp);
free(label);
@ -1842,3 +1854,14 @@ void compile_param_string(char*label, char*name, char*value)
free(label);
}
void compile_param_real(char*label, char*name, char*value)
{
double dvalue = crstring_to_double(value);
vpiHandle obj = vpip_make_real_param(name, dvalue);
compile_vpi_symbol(label, obj);
vpip_attach_to_current_scope(obj);
free(label);
free(value);
}

View File

@ -234,6 +234,7 @@ extern void compile_vpi_lookup(vpiHandle *objref, char*label);
extern void compile_param_string(char*label, char*name, char*value);
extern void compile_param_logic(char*label, char*name, char*value,
bool signed_flag);
extern void compile_param_real(char*label, char*name, char*value);
/*
* This function schedules a lookup of an indexed label. The ref

View File

@ -133,6 +133,7 @@
".net/s" { return K_NET_S; }
".param/l" { return K_PARAM_L; }
".param/str" { return K_PARAM_STR; }
".param/real" { return K_PARAM_REAL; }
".part" { return K_PART; }
".part/pv" { return K_PART_PV; }
".part/v" { return K_PART_V; }

View File

@ -75,7 +75,7 @@ static struct __vpiModPath*modpath_dst = 0;
%token K_CONCAT K_DEBUG K_DELAY K_DFF
%token K_EVENT K_EVENT_OR K_EXTEND_S K_FUNCTOR K_MODPATH K_NET K_NET_S K_NET_R
%token K_NET8 K_NET8_S
%token K_PARAM_STR K_PARAM_L K_PART K_PART_PV
%token K_PARAM_STR K_PARAM_L K_PARAM_REAL K_PART K_PART_PV
%token K_PART_V K_REDUCE_AND K_REDUCE_OR K_REDUCE_XOR
%token K_REDUCE_NAND K_REDUCE_NOR K_REDUCE_XNOR K_REPEAT
%token K_RESOLV K_SCOPE K_SFUNC K_SHIFTL K_SHIFTR K_SHIFTRS
@ -654,6 +654,9 @@ statement
| T_LABEL K_PARAM_L T_STRING ',' '+' T_SYMBOL ';'
{ compile_param_logic($1, $3, $6, true); }
| T_LABEL K_PARAM_REAL T_STRING ',' T_SYMBOL ';'
{ compile_param_real($1, $3, $5); }
/* Oh and by the way, empty statements are OK as well. */
| ';'

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2007 Stephen Williams (steve@icarus.com)
* Copyright (c) 2001-2008 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -589,6 +589,12 @@ static int real_get(int code, vpiHandle ref)
{
switch (code) {
case vpiLineNo:
return 0; // Not implemented for now!
case vpiSize:
return 1;
case vpiConstType:
return vpiRealConst;
@ -606,7 +612,8 @@ static int real_get(int code, vpiHandle ref)
static void real_value(vpiHandle ref, p_vpi_value vp)
{
struct __vpiRealConst*rfp = (struct __vpiRealConst*)ref;
assert(ref->vpi_type->type_code == vpiConstant);
assert((ref->vpi_type->type_code == vpiConstant) ||
(ref->vpi_type->type_code == vpiParameter));
switch (vp->format) {
case vpiObjTypeVal:
@ -644,3 +651,62 @@ vpiHandle vpip_make_real_const(double value)
return vpip_make_real_const(obj, value);
}
struct __vpiRealParam : public __vpiRealConst {
const char*basename;
struct __vpiScope* scope;
};
static char* real_param_get_str(int code, vpiHandle obj)
{
struct __vpiRealParam*rfp = (struct __vpiRealParam*)obj;
assert(obj->vpi_type->type_code == vpiParameter);
if (code == vpiFile) { // Not implemented for now!
return simple_set_rbuf_str(file_names[0]);
}
return generic_get_str(code, &rfp->scope->base, rfp->basename, NULL);
}
static vpiHandle real_param_handle(int code, vpiHandle obj)
{
struct __vpiRealParam*rfp = (struct __vpiRealParam*)obj;
assert(obj->vpi_type->type_code == vpiParameter);
switch (code) {
case vpiScope:
return &rfp->scope->base;
default:
return 0;
}
}
static const struct __vpirt vpip_real_param_rt = {
vpiParameter,
real_get,
real_param_get_str,
real_value,
0,
real_param_handle,
0,
0,
0
};
vpiHandle vpip_make_real_param(char*name, double value)
{
struct __vpiRealParam*obj;
obj = (struct __vpiRealParam*)
malloc(sizeof (struct __vpiRealParam));
obj->base.vpi_type = &vpip_real_param_rt;
obj->value = value;
obj->basename = name;
obj->scope = vpip_peek_current_scope();
return &obj->base;
}

View File

@ -1,7 +1,7 @@
#ifndef __vpi_priv_H
#define __vpi_priv_H
/*
* Copyright (c) 2001-2007 Stephen Williams (steve@icarus.com)
* Copyright (c) 2001-2008 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -415,6 +415,7 @@ struct __vpiRealConst {
};
vpiHandle vpip_make_real_const(double value);
vpiHandle vpip_make_real_param(char*name, double value);
/*
* This one looks like a constant, but really is a vector in the current