Keep parameters as a parameters reference for vpi calls.

For most cases just using the value of a parameter is fine, but
a vpi call can access more than the value so we want to use a
parameter reference instead of the value for vpi calls.

Strings were working correctly, integer values need some minor
code generator changes and real values needed to be pushed from
elaboration to the code generators. I also changed the default
real value comment from %g to %#g so that it is more obvious
that the value is a real value.
This commit is contained in:
Cary R 2009-01-16 11:03:03 -08:00 committed by Stephen Williams
parent d2e7ea0b68
commit 6f9ddea07f
6 changed files with 64 additions and 23 deletions

View File

@ -656,7 +656,7 @@ NetExpr* PEBinary::elaborate_expr_base_rshift_(Design*des,
// If this is lossless, then pad the left expression
// enough to cover the right shift.
if (expr_wid == -2 && use_wid+shift > lp->expr_width()) {
if (expr_wid == -2 && use_wid+shift > (long)lp->expr_width()) {
lp = pad_to_width(lp, use_wid + shift, *this);
}
@ -2415,6 +2415,20 @@ NetExpr* PEIdent::elaborate_expr_param_(Design*des,
delete tmp;
tmp = ptmp;
}
NetECReal*rtmp = dynamic_cast<NetECReal*>(tmp);
if (rtmp != 0) {
perm_string name = peek_tail_name(path_);
NetECRealParam*ptmp
= new NetECRealParam(found_in, name, rtmp->value());
if (debug_elaborate)
cerr << get_fileline() << ": debug: "
<< "Elaborate parameter <" << name
<< "> as constant " << *ptmp << endl;
delete tmp;
tmp = ptmp;
}
}
tmp->set_line(*this);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000-2008 Stephen Williams (steve@icarus.com)
* Copyright (c) 2000-2009 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
@ -273,6 +273,21 @@ void dll_target::expr_param(const NetEConstParam*net)
expr_ = par->value;
}
void dll_target::expr_rparam(const NetECRealParam*net)
{
ivl_scope_t scop = find_scope(des_, net->scope());
ivl_parameter_t par = scope_find_param(scop, net->name());
if (par == 0) {
cerr << net->get_fileline() << ": internal error: "
<< "Parameter " << net->name() << " missing from "
<< ivl_scope_name(scop) << endl;
}
assert(par);
assert(par->value);
expr_ = par->value;
}
void dll_target::expr_creal(const NetECReal*net)
{
assert(expr_ == 0);

View File

@ -1,7 +1,7 @@
#ifndef __t_dll_H
#define __t_dll_H
/*
* Copyright (c) 2000-2008 Stephen Williams (steve@icarus.com)
* Copyright (c) 2000-2009 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
@ -134,6 +134,7 @@ struct dll_target : public target_t, public expr_scan_t {
void expr_const(const NetEConst*);
void expr_creal(const NetECReal*);
void expr_param(const NetEConstParam*);
void expr_rparam(const NetECRealParam*);
void expr_event(const NetEEvent*);
void expr_scope(const NetEScope*);
void expr_select(const NetESelect*);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003-2008 Stephen Williams (steve@icarus.com)
* Copyright (c) 2003-2009 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
@ -261,19 +261,23 @@ static void draw_vpi_taskfunc_args(const char*call_string,
continue;
case IVL_EX_NUMBER: {
unsigned bit, wid = ivl_expr_width(expr);
const char*bits = ivl_expr_bits(expr);
char*dp;
if (( par = ivl_expr_parameter(expr) )) {
snprintf(buffer, sizeof buffer, "P_%p", par);
} else {
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;
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:
@ -286,6 +290,14 @@ static void draw_vpi_taskfunc_args(const char*call_string,
args[idx].text = strdup(buffer);
continue;
case IVL_EX_REALNUM:
if (( par = ivl_expr_parameter(expr) )) {
snprintf(buffer, sizeof buffer, "P_%p", par);
args[idx].text = strdup(buffer);
continue;
}
break;
case IVL_EX_EVENT:
snprintf(buffer, sizeof buffer, "E_%p", ivl_expr_event(expr));
args[idx].text = strdup(buffer);
@ -328,7 +340,7 @@ static void draw_vpi_taskfunc_args(const char*call_string,
args[idx].vec.base = draw_eval_real(expr);
args[idx].vec.wid = 0;
snprintf(buffer, sizeof buffer,
"W<%u,r>", args[idx].vec.base);
"W<%u,r>", args[idx].vec.base);
break;
default:
assert(0);
@ -409,4 +421,3 @@ int draw_vpi_rfunc_call(ivl_expr_t fnet)
return res;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003-2008 Stephen Williams (steve@icarus.com)
* Copyright (c) 2003-2009 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
@ -259,7 +259,7 @@ static int draw_realnum_real(ivl_expr_t expr)
assert(vexp < 0x2000);
vexp += sign;
fprintf(vvp_out, " %%loadi/wr %d, %lu, %d; load=%g\n",
fprintf(vvp_out, " %%loadi/wr %d, %lu, %d; load=%#g\n",
res, mant, vexp, ivl_expr_dvalue(expr));
/* Capture the residual bits, if there are any. Note that an
@ -277,7 +277,7 @@ static int draw_realnum_real(ivl_expr_t expr)
if (mant != 0) {
int tmp_word = allocate_word();
fprintf(vvp_out, " %%loadi/wr %d, %lu, %d; load=%g\n",
fprintf(vvp_out, " %%loadi/wr %d, %lu, %d; load=%#g\n",
tmp_word, mant, vexp, ivl_expr_dvalue(expr));
fprintf(vvp_out, " %%add/wr %d, %d;\n", res, tmp_word);
clr_word(tmp_word);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2008 Stephen Williams (steve@icarus.com)
* Copyright (c) 2001-2009 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
@ -1855,7 +1855,7 @@ 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\" %d %d, %s; value=%g\n",
fprintf(vvp_out, "P_%p .param/real \"%s\" %d %d, %s; value=%#g\n",
par, ivl_parameter_basename(par),
ivl_file_table_index(ivl_parameter_file(par)),
ivl_parameter_lineno(par),