Merge branch 'master' into vvp-net-out-rework

Conflicts:
	vvp/vpi_signal.cc
This commit is contained in:
Stephen Williams 2009-09-13 12:31:17 -07:00
commit 3d5d312786
18 changed files with 123 additions and 28 deletions

View File

@ -88,6 +88,11 @@ extern bool warn_ob_select;
/* Warn about structures that may have infinite loops. */
extern bool warn_inf_loop;
/* Warn about always @* statements where a part or word select causes
sensitivity to an entire vector or array. */
extern bool warn_sens_entire_vec;
extern bool warn_sens_entire_arr;
/* This is true if verbose output is requested. */
extern bool verbose_flag;

View File

@ -259,8 +259,8 @@ after a \fB-Wall\fP argument to suppress isolated warning types.
.TP 8
.B all
This enables the implicit, portbind, select-range and timescale warning
categories.
This enables the implicit, portbind, select-range, timescale, and
sensitivity-entire-array warning categories.
.TP 8
.B implicit
@ -303,6 +303,22 @@ verified. It is expected that many of the warnings will be false
positives, since the code treats the value of all variables and signals
as indeterminate.
.TP 8
.B sensitivity-entire-vector
This enables warnings for when a part select within an "always @*"
statement results in the entire vector being added to the implicit
sensitivity list. Although this behaviour is prescribed by the IEEE
standard, it is not what might be expected and can have performance
implications if the vector is large.
.TP 8
.B sensitivity-entire-array
This enables warnings for when a word select within an "always @*"
statement results in the entire array being added to the implicit
sensitivity list. Although this behaviour is prescribed by the IEEE
standard, it is not what might be expected and can have performance
implications if the array is large.
.SH "SYSTEM FUNCTION TABLE FILES"
If the source file name as a \fB.sft\fP suffix, then it is taken to be
a system function table file. A System function table file is used to

View File

@ -477,6 +477,7 @@ static void process_warning_switch(const char*name)
process_warning_switch("portbind");
process_warning_switch("select-range");
process_warning_switch("timescale");
process_warning_switch("sensitivity-entire-array");
} else if (strcmp(name,"implicit") == 0) {
if (! strchr(warning_flags, 'i'))
strcat(warning_flags, "i");
@ -494,6 +495,12 @@ static void process_warning_switch(const char*name)
} else if (strcmp(name,"infloop") == 0) {
if (! strchr(warning_flags, 'l'))
strcat(warning_flags, "l");
} else if (strcmp(name,"sensitivity-entire-vector") == 0) {
if (! strchr(warning_flags, 'v'))
strcat(warning_flags, "v");
} else if (strcmp(name,"sensitivity-entire-array") == 0) {
if (! strchr(warning_flags, 'a'))
strcat(warning_flags, "a");
} else if (strcmp(name,"no-implicit") == 0) {
char*cp = strchr(warning_flags, 'i');
if (cp) while (*cp) {
@ -518,6 +525,18 @@ static void process_warning_switch(const char*name)
cp[0] = cp[1];
cp += 1;
}
} else if (strcmp(name,"no-sensitivity-entire-vector") == 0) {
char*cp = strchr(warning_flags, 'v');
if (cp) while (*cp) {
cp[0] = cp[1];
cp += 1;
}
} else if (strcmp(name,"no-sensitivity-entire-array") == 0) {
char*cp = strchr(warning_flags, 'a');
if (cp) while (*cp) {
cp[0] = cp[1];
cp += 1;
}
}
}

View File

@ -1488,6 +1488,12 @@ NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope,
def->port(idx)->data_type(),
def->port(idx)->vector_width(),
tmp);
if (NetEEvent*evt = dynamic_cast<NetEEvent*> (parms[idx])) {
cerr << evt->get_fileline() << ": error: An event '"
<< evt->event()->name() << "' can not be a user "
"function argument." << endl;
des->errors += 1;
}
if (debug_elaborate)
cerr << get_fileline() << ": debug:"
<< " function " << path_

View File

@ -2644,6 +2644,13 @@ NetProc* PCallTask::elaborate_usr(Design*des, NetScope*scope) const
ivl_variable_type_t lv_type = lv->expr_type();
NetExpr*rv = elaborate_rval_expr(des, scope, lv_type, wid, parms_[idx]);
if (NetEEvent*evt = dynamic_cast<NetEEvent*> (rv)) {
cerr << evt->get_fileline() << ": error: An event '"
<< evt->event()->name() << "' can not be a user "
"task argument." << endl;
des->errors += 1;
continue;
}
if (wid > rv->expr_width()) {
rv->set_width(wid);
rv = pad_to_width(rv, wid, *this);

View File

@ -1369,6 +1369,10 @@ NetNet* NetEUFunc::synthesize(Design*des, NetScope*scope, NetExpr*root)
/* Synthesize the arguments. */
bool errors = false;
for (unsigned idx = 0; idx < eparms.count(); idx += 1) {
if (dynamic_cast<NetEEvent*> (parms_[idx])) {
errors = true;
continue;
}
NetNet*tmp = parms_[idx]->synthesize(des, scope, root);
if (tmp == 0) {
cerr << get_fileline() << ": error: Unable to synthesize "

View File

@ -53,6 +53,8 @@ PLI_INT32 tf_igetp(PLI_INT32 n, void *obj)
{
value.format = vpiStringVal;
vpi_get_value(arg_h, &value);
/* The following may generate a compilation warning, but this
* functionality is required by some versions of the standard. */
rtn = (int) value.value.str; /* Oh my */
} else {
value.format = vpiIntVal;

View File

@ -116,6 +116,8 @@ bool warn_timescale = false;
bool warn_portbinding = false;
bool warn_inf_loop = false;
bool warn_ob_select = false;
bool warn_sens_entire_vec = false;
bool warn_sens_entire_arr = false;
bool error_implicit = false;
@ -501,6 +503,12 @@ static void read_iconfig_file(const char*ipath)
case 't':
warn_timescale = true;
break;
case 'v':
warn_sens_entire_vec = true;
break;
case 'a':
warn_sens_entire_arr = true;
break;
default:
break;
}

View File

@ -23,6 +23,7 @@
# include <cassert>
# include <typeinfo>
# include "compiler.h"
# include "netlist.h"
# include "netmisc.h"
@ -115,7 +116,7 @@ NexusSet* NetESelect::nex_input(bool rem_out)
result->add(*tmp);
delete tmp;
/* See the comment for NetESignal below. */
if (base_) {
if (base_ && warn_sens_entire_vec) {
cerr << get_fileline() << ": warning: @* is sensitive to all "
"bits in '" << *expr_ << "'." << endl;
}
@ -151,9 +152,11 @@ NexusSet* NetESignal::nex_input(bool rem_out)
tmp = word_->nex_input(rem_out);
result->add(*tmp);
delete tmp;
cerr << get_fileline() << ": warning: @* is sensitive to all "
<< net_->array_count() << " words in array '"
<< name() << "'." << endl;
if (warn_sens_entire_arr) {
cerr << get_fileline() << ": warning: @* is sensitive to all "
<< net_->array_count() << " words in array '"
<< name() << "'." << endl;
}
}
for (unsigned idx = 0 ; idx < net_->pin_count() ; idx += 1)
result->add(net_->pin(idx).nexus());

View File

@ -308,6 +308,7 @@ void dll_target::expr_event(const NetEEvent*net)
assert(expr_);
expr_->type_ = IVL_EX_EVENT;
FILE_NAME(expr_, net);
expr_->value_= IVL_VT_VOID;
/* Locate the event by name. Save the ivl_event_t in the

View File

@ -217,7 +217,7 @@ static int get_vpi_taskfunc_signal_arg(struct args_info *result,
(ivl_expr_width(bexpr) < 8*sizeof(int))) {
fprintf(stderr, "%s:%u: tgt-vvp warning: V0.9 may give "
"incorrect results for a select with a "
"signed index less than %d bits.\n",
"signed index less than %zu bits.\n",
ivl_expr_file(expr),
ivl_expr_lineno(expr),
8*sizeof(int));

View File

@ -2983,6 +2983,12 @@ struct vector_info draw_eval_expr_wid(ivl_expr_t exp, unsigned wid,
res.base = 0;
res.wid = 0;
break;
case IVL_EX_EVENT:
fprintf(stderr, "%s:%u: vvp-tgt error: A named event is not "
"handled in this context (expression).\n",
ivl_expr_file(exp), ivl_expr_lineno(exp));
exit(1);
break;
case IVL_EX_STRING:
res = draw_string_expr(exp, wid);

View File

@ -214,7 +214,6 @@ static PLI_INT32 sys_fclose_calltf(PLI_BYTE8*name)
vpiHandle fd = vpi_scan(argv);
s_vpi_value val;
PLI_UINT32 fd_mcd;
char *str = ""; /* This prevents the compiler from complaining. */
errno = 0;
vpi_free_object(argv);
@ -225,7 +224,7 @@ static PLI_INT32 sys_fclose_calltf(PLI_BYTE8*name)
fd_mcd = val.value.integer;
if ((! IS_MCD(fd_mcd) && vpi_get_file(fd_mcd) == NULL) ||
( IS_MCD(fd_mcd) && vpi_mcd_printf(fd_mcd, str) == EOF) ||
( IS_MCD(fd_mcd) && vpi_mcd_printf(fd_mcd, "%s", "") == EOF) ||
(! fd_mcd)) {
vpi_printf("WARNING: %s:%d: ", vpi_get_str(vpiFile, callh),
(int)vpi_get(vpiLineNo, callh));
@ -254,7 +253,6 @@ static PLI_INT32 sys_fflush_calltf(PLI_BYTE8*name)
s_vpi_value val;
PLI_UINT32 fd_mcd;
FILE *fp;
char *str = ""; /* This prevents the compiler from complaining. */
errno = 0;
/* If we have no argument then flush all the streams. */
@ -274,7 +272,7 @@ static PLI_INT32 sys_fflush_calltf(PLI_BYTE8*name)
if (fd_mcd == 0) return 0;
if ((! IS_MCD(fd_mcd) && vpi_get_file(fd_mcd) == NULL) ||
( IS_MCD(fd_mcd) && vpi_mcd_printf(fd_mcd, str) == EOF) ||
( IS_MCD(fd_mcd) && vpi_mcd_printf(fd_mcd, "%s", "") == EOF) ||
(! fd_mcd)) {
vpi_printf("WARNING: %s:%d: ", vpi_get_str(vpiFile, callh),
(int)vpi_get(vpiLineNo, callh));

View File

@ -31,6 +31,7 @@
#endif
# include <stdlib.h>
# include <string.h>
# include <limits.h>
# include <iostream>
# include "compile.h"
# include <assert.h>
@ -133,6 +134,15 @@ struct __vpiArrayVthrA {
{
if (address_handle) {
s_vpi_value vp;
/* Check to see if the value is defined. */
vp.format = vpiVectorVal;
vpi_get_value(address_handle, &vp);
int words = (vpi_get(vpiSize, address_handle)-1)/32 + 1;
for(int idx = 0; idx < words; idx += 1) {
/* Return UINT_MAX to indicate an X base. */
if (vp.value.vector[idx].bval != 0) return UINT_MAX;
}
/* The value is defined so get and return it. */
vp.format = vpiIntVal;
vpi_get_value(address_handle, &vp);
return vp.value.integer;
@ -146,7 +156,7 @@ struct __vpiArrayVthrA {
vvp_bit4_t bit = vthread_get_bit(vpip_current_vthread, address+idx);
tmp.set_bit(idx, bit);
}
unsigned long val;
unsigned long val = ULONG_MAX;
vector4_to_value(tmp, val);
return val;
}

View File

@ -238,7 +238,7 @@ vvp_fun_part_var::~vvp_fun_part_var()
}
bool vvp_fun_part_var::recv_vec4_(vvp_net_ptr_t port, const vvp_vector4_t&bit,
long&base, vvp_vector4_t&source,
int&base, vvp_vector4_t&source,
vvp_vector4_t&ref)
{
long tmp;
@ -247,12 +247,13 @@ bool vvp_fun_part_var::recv_vec4_(vvp_net_ptr_t port, const vvp_vector4_t&bit,
source = bit;
break;
case 1:
// LONG_MIN is before the vector and is used to
// INT_MIN is before the vector and is used to
// represent a 'bx value on the select input.
tmp = LONG_MIN;
// We need a new &PV<> that knows if the index is signed.
tmp = INT_MIN;
// We need a new .part/v that knows if the index is signed.
// For now this will work for a normal integer value.
vector4_to_value(bit, tmp, false);
if (tmp == base) return false;
if ((int)tmp == base) return false;
base = tmp;
break;
default:
@ -264,7 +265,7 @@ bool vvp_fun_part_var::recv_vec4_(vvp_net_ptr_t port, const vvp_vector4_t&bit,
vvp_vector4_t res (wid_);
for (unsigned idx = 0 ; idx < wid_ ; idx += 1) {
long adr = base+idx;
int adr = base+idx;
if (adr < 0) continue;
if ((unsigned)adr >= source.size()) break;
@ -313,7 +314,7 @@ void vvp_fun_part_var_sa::recv_vec4_pv(vvp_net_ptr_t port, const vvp_vector4_t&b
struct vvp_fun_part_var_state_s {
vvp_fun_part_var_state_s() : base(0) { }
long base;
int base;
vvp_vector4_t source;
vvp_vector4_t ref;
};

View File

@ -130,7 +130,7 @@ class vvp_fun_part_var : public vvp_net_fun_t {
protected:
bool recv_vec4_(vvp_net_ptr_t port, const vvp_vector4_t&bit,
long&base, vvp_vector4_t&source,
int&base, vvp_vector4_t&source,
vvp_vector4_t&ref);
unsigned wid_;
@ -154,7 +154,7 @@ class vvp_fun_part_var_sa : public vvp_fun_part_var {
vvp_context_t);
private:
long base_;
int base_;
vvp_vector4_t source_;
// Save the last output, for detecting change.
vvp_vector4_t ref_;

View File

@ -139,8 +139,8 @@ static void format_vpiBinStrVal(vvp_signal_value*sig, int base, unsigned wid,
s_vpi_value*vp)
{
char *rbuf = need_result_buf(wid+1, RBUF_VAL);
long offset = wid - 1 + base;
long end = base + (signed)wid;
long offset = end - 1;
long ssize = (signed)sig->value_size();
for (long idx = base ; idx < end ; idx += 1) {
@ -993,6 +993,15 @@ static int PV_get_base(struct __vpiPV*rfp)
/* We return from the symbol base if it is defined. */
if (rfp->sbase != 0) {
s_vpi_value val;
/* Check to see if the value is defined. */
val.format = vpiVectorVal;
vpi_get_value(rfp->sbase, &val);
int words = (vpi_get(vpiSize, rfp->sbase)-1)/32 + 1;
for(int idx = 0; idx < words; idx += 1) {
/* Return INT_MIN to indicate an X base. */
if (val.value.vector[idx].bval != 0) return INT_MIN;
}
/* The value is defined so get and return it. */
val.format = vpiIntVal;
vpi_get_value(rfp->sbase, &val);
return val.value.integer;

View File

@ -1300,8 +1300,8 @@ vvp_vector4_t& vvp_vector4_t::operator |= (const vvp_vector4_t&that)
if (size_ <= BITS_PER_WORD) {
unsigned long tmp = abits_val_ | bbits_val_ |
that.abits_val_ | that.bbits_val_;
bbits_val_ = (~abits_val_ | bbits_val_) & that.bbits_val_ |
(~that.abits_val_ | that.bbits_val_) & bbits_val_;
bbits_val_ = ((~abits_val_ | bbits_val_) & that.bbits_val_) |
((~that.abits_val_ | that.bbits_val_) & bbits_val_);
abits_val_ = tmp;
} else {
@ -1309,10 +1309,10 @@ vvp_vector4_t& vvp_vector4_t::operator |= (const vvp_vector4_t&that)
for (unsigned idx = 0; idx < words ; idx += 1) {
unsigned long tmp = abits_ptr_[idx] | bbits_ptr_[idx] |
that.abits_ptr_[idx] | that.bbits_ptr_[idx];
bbits_ptr_[idx] = (~abits_ptr_[idx] | bbits_ptr_[idx]) &
that.bbits_ptr_[idx] |
(~that.abits_ptr_[idx] |
that.bbits_ptr_[idx]) & bbits_ptr_[idx];
bbits_ptr_[idx] = ((~abits_ptr_[idx] | bbits_ptr_[idx]) &
that.bbits_ptr_[idx]) |
((~that.abits_ptr_[idx] |
that.bbits_ptr_[idx]) & bbits_ptr_[idx]);
abits_ptr_[idx] = tmp;
}
}