Merge branch 'master' into vvp-net-out-rework
Conflicts: vvp/vpi_signal.cc
This commit is contained in:
commit
3d5d312786
|
|
@ -88,6 +88,11 @@ extern bool warn_ob_select;
|
||||||
/* Warn about structures that may have infinite loops. */
|
/* Warn about structures that may have infinite loops. */
|
||||||
extern bool warn_inf_loop;
|
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. */
|
/* This is true if verbose output is requested. */
|
||||||
extern bool verbose_flag;
|
extern bool verbose_flag;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -259,8 +259,8 @@ after a \fB-Wall\fP argument to suppress isolated warning types.
|
||||||
|
|
||||||
.TP 8
|
.TP 8
|
||||||
.B all
|
.B all
|
||||||
This enables the implicit, portbind, select-range and timescale warning
|
This enables the implicit, portbind, select-range, timescale, and
|
||||||
categories.
|
sensitivity-entire-array warning categories.
|
||||||
|
|
||||||
.TP 8
|
.TP 8
|
||||||
.B implicit
|
.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
|
positives, since the code treats the value of all variables and signals
|
||||||
as indeterminate.
|
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"
|
.SH "SYSTEM FUNCTION TABLE FILES"
|
||||||
If the source file name as a \fB.sft\fP suffix, then it is taken to be
|
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
|
a system function table file. A System function table file is used to
|
||||||
|
|
|
||||||
|
|
@ -477,6 +477,7 @@ static void process_warning_switch(const char*name)
|
||||||
process_warning_switch("portbind");
|
process_warning_switch("portbind");
|
||||||
process_warning_switch("select-range");
|
process_warning_switch("select-range");
|
||||||
process_warning_switch("timescale");
|
process_warning_switch("timescale");
|
||||||
|
process_warning_switch("sensitivity-entire-array");
|
||||||
} else if (strcmp(name,"implicit") == 0) {
|
} else if (strcmp(name,"implicit") == 0) {
|
||||||
if (! strchr(warning_flags, 'i'))
|
if (! strchr(warning_flags, 'i'))
|
||||||
strcat(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) {
|
} else if (strcmp(name,"infloop") == 0) {
|
||||||
if (! strchr(warning_flags, 'l'))
|
if (! strchr(warning_flags, 'l'))
|
||||||
strcat(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) {
|
} else if (strcmp(name,"no-implicit") == 0) {
|
||||||
char*cp = strchr(warning_flags, 'i');
|
char*cp = strchr(warning_flags, 'i');
|
||||||
if (cp) while (*cp) {
|
if (cp) while (*cp) {
|
||||||
|
|
@ -518,6 +525,18 @@ static void process_warning_switch(const char*name)
|
||||||
cp[0] = cp[1];
|
cp[0] = cp[1];
|
||||||
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1488,6 +1488,12 @@ NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope,
|
||||||
def->port(idx)->data_type(),
|
def->port(idx)->data_type(),
|
||||||
def->port(idx)->vector_width(),
|
def->port(idx)->vector_width(),
|
||||||
tmp);
|
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)
|
if (debug_elaborate)
|
||||||
cerr << get_fileline() << ": debug:"
|
cerr << get_fileline() << ": debug:"
|
||||||
<< " function " << path_
|
<< " function " << path_
|
||||||
|
|
|
||||||
|
|
@ -2644,6 +2644,13 @@ NetProc* PCallTask::elaborate_usr(Design*des, NetScope*scope) const
|
||||||
ivl_variable_type_t lv_type = lv->expr_type();
|
ivl_variable_type_t lv_type = lv->expr_type();
|
||||||
|
|
||||||
NetExpr*rv = elaborate_rval_expr(des, scope, lv_type, wid, parms_[idx]);
|
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()) {
|
if (wid > rv->expr_width()) {
|
||||||
rv->set_width(wid);
|
rv->set_width(wid);
|
||||||
rv = pad_to_width(rv, wid, *this);
|
rv = pad_to_width(rv, wid, *this);
|
||||||
|
|
|
||||||
|
|
@ -1369,6 +1369,10 @@ NetNet* NetEUFunc::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
||||||
/* Synthesize the arguments. */
|
/* Synthesize the arguments. */
|
||||||
bool errors = false;
|
bool errors = false;
|
||||||
for (unsigned idx = 0; idx < eparms.count(); idx += 1) {
|
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);
|
NetNet*tmp = parms_[idx]->synthesize(des, scope, root);
|
||||||
if (tmp == 0) {
|
if (tmp == 0) {
|
||||||
cerr << get_fileline() << ": error: Unable to synthesize "
|
cerr << get_fileline() << ": error: Unable to synthesize "
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,8 @@ PLI_INT32 tf_igetp(PLI_INT32 n, void *obj)
|
||||||
{
|
{
|
||||||
value.format = vpiStringVal;
|
value.format = vpiStringVal;
|
||||||
vpi_get_value(arg_h, &value);
|
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 */
|
rtn = (int) value.value.str; /* Oh my */
|
||||||
} else {
|
} else {
|
||||||
value.format = vpiIntVal;
|
value.format = vpiIntVal;
|
||||||
|
|
|
||||||
8
main.cc
8
main.cc
|
|
@ -116,6 +116,8 @@ bool warn_timescale = false;
|
||||||
bool warn_portbinding = false;
|
bool warn_portbinding = false;
|
||||||
bool warn_inf_loop = false;
|
bool warn_inf_loop = false;
|
||||||
bool warn_ob_select = false;
|
bool warn_ob_select = false;
|
||||||
|
bool warn_sens_entire_vec = false;
|
||||||
|
bool warn_sens_entire_arr = false;
|
||||||
|
|
||||||
bool error_implicit = false;
|
bool error_implicit = false;
|
||||||
|
|
||||||
|
|
@ -501,6 +503,12 @@ static void read_iconfig_file(const char*ipath)
|
||||||
case 't':
|
case 't':
|
||||||
warn_timescale = true;
|
warn_timescale = true;
|
||||||
break;
|
break;
|
||||||
|
case 'v':
|
||||||
|
warn_sens_entire_vec = true;
|
||||||
|
break;
|
||||||
|
case 'a':
|
||||||
|
warn_sens_entire_arr = true;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@
|
||||||
|
|
||||||
# include <cassert>
|
# include <cassert>
|
||||||
# include <typeinfo>
|
# include <typeinfo>
|
||||||
|
# include "compiler.h"
|
||||||
# include "netlist.h"
|
# include "netlist.h"
|
||||||
# include "netmisc.h"
|
# include "netmisc.h"
|
||||||
|
|
||||||
|
|
@ -115,7 +116,7 @@ NexusSet* NetESelect::nex_input(bool rem_out)
|
||||||
result->add(*tmp);
|
result->add(*tmp);
|
||||||
delete tmp;
|
delete tmp;
|
||||||
/* See the comment for NetESignal below. */
|
/* See the comment for NetESignal below. */
|
||||||
if (base_) {
|
if (base_ && warn_sens_entire_vec) {
|
||||||
cerr << get_fileline() << ": warning: @* is sensitive to all "
|
cerr << get_fileline() << ": warning: @* is sensitive to all "
|
||||||
"bits in '" << *expr_ << "'." << endl;
|
"bits in '" << *expr_ << "'." << endl;
|
||||||
}
|
}
|
||||||
|
|
@ -151,9 +152,11 @@ NexusSet* NetESignal::nex_input(bool rem_out)
|
||||||
tmp = word_->nex_input(rem_out);
|
tmp = word_->nex_input(rem_out);
|
||||||
result->add(*tmp);
|
result->add(*tmp);
|
||||||
delete tmp;
|
delete tmp;
|
||||||
cerr << get_fileline() << ": warning: @* is sensitive to all "
|
if (warn_sens_entire_arr) {
|
||||||
<< net_->array_count() << " words in array '"
|
cerr << get_fileline() << ": warning: @* is sensitive to all "
|
||||||
<< name() << "'." << endl;
|
<< net_->array_count() << " words in array '"
|
||||||
|
<< name() << "'." << endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for (unsigned idx = 0 ; idx < net_->pin_count() ; idx += 1)
|
for (unsigned idx = 0 ; idx < net_->pin_count() ; idx += 1)
|
||||||
result->add(net_->pin(idx).nexus());
|
result->add(net_->pin(idx).nexus());
|
||||||
|
|
|
||||||
|
|
@ -308,6 +308,7 @@ void dll_target::expr_event(const NetEEvent*net)
|
||||||
assert(expr_);
|
assert(expr_);
|
||||||
|
|
||||||
expr_->type_ = IVL_EX_EVENT;
|
expr_->type_ = IVL_EX_EVENT;
|
||||||
|
FILE_NAME(expr_, net);
|
||||||
expr_->value_= IVL_VT_VOID;
|
expr_->value_= IVL_VT_VOID;
|
||||||
|
|
||||||
/* Locate the event by name. Save the ivl_event_t in the
|
/* Locate the event by name. Save the ivl_event_t in the
|
||||||
|
|
|
||||||
|
|
@ -217,7 +217,7 @@ static int get_vpi_taskfunc_signal_arg(struct args_info *result,
|
||||||
(ivl_expr_width(bexpr) < 8*sizeof(int))) {
|
(ivl_expr_width(bexpr) < 8*sizeof(int))) {
|
||||||
fprintf(stderr, "%s:%u: tgt-vvp warning: V0.9 may give "
|
fprintf(stderr, "%s:%u: tgt-vvp warning: V0.9 may give "
|
||||||
"incorrect results for a select with a "
|
"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_file(expr),
|
||||||
ivl_expr_lineno(expr),
|
ivl_expr_lineno(expr),
|
||||||
8*sizeof(int));
|
8*sizeof(int));
|
||||||
|
|
|
||||||
|
|
@ -2983,6 +2983,12 @@ struct vector_info draw_eval_expr_wid(ivl_expr_t exp, unsigned wid,
|
||||||
res.base = 0;
|
res.base = 0;
|
||||||
res.wid = 0;
|
res.wid = 0;
|
||||||
break;
|
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:
|
case IVL_EX_STRING:
|
||||||
res = draw_string_expr(exp, wid);
|
res = draw_string_expr(exp, wid);
|
||||||
|
|
|
||||||
|
|
@ -214,7 +214,6 @@ static PLI_INT32 sys_fclose_calltf(PLI_BYTE8*name)
|
||||||
vpiHandle fd = vpi_scan(argv);
|
vpiHandle fd = vpi_scan(argv);
|
||||||
s_vpi_value val;
|
s_vpi_value val;
|
||||||
PLI_UINT32 fd_mcd;
|
PLI_UINT32 fd_mcd;
|
||||||
char *str = ""; /* This prevents the compiler from complaining. */
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
|
|
||||||
vpi_free_object(argv);
|
vpi_free_object(argv);
|
||||||
|
|
@ -225,7 +224,7 @@ static PLI_INT32 sys_fclose_calltf(PLI_BYTE8*name)
|
||||||
fd_mcd = val.value.integer;
|
fd_mcd = val.value.integer;
|
||||||
|
|
||||||
if ((! IS_MCD(fd_mcd) && vpi_get_file(fd_mcd) == NULL) ||
|
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)) {
|
(! fd_mcd)) {
|
||||||
vpi_printf("WARNING: %s:%d: ", vpi_get_str(vpiFile, callh),
|
vpi_printf("WARNING: %s:%d: ", vpi_get_str(vpiFile, callh),
|
||||||
(int)vpi_get(vpiLineNo, callh));
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
|
|
@ -254,7 +253,6 @@ static PLI_INT32 sys_fflush_calltf(PLI_BYTE8*name)
|
||||||
s_vpi_value val;
|
s_vpi_value val;
|
||||||
PLI_UINT32 fd_mcd;
|
PLI_UINT32 fd_mcd;
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
char *str = ""; /* This prevents the compiler from complaining. */
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
|
|
||||||
/* If we have no argument then flush all the streams. */
|
/* 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 (fd_mcd == 0) return 0;
|
||||||
|
|
||||||
if ((! IS_MCD(fd_mcd) && vpi_get_file(fd_mcd) == NULL) ||
|
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)) {
|
(! fd_mcd)) {
|
||||||
vpi_printf("WARNING: %s:%d: ", vpi_get_str(vpiFile, callh),
|
vpi_printf("WARNING: %s:%d: ", vpi_get_str(vpiFile, callh),
|
||||||
(int)vpi_get(vpiLineNo, callh));
|
(int)vpi_get(vpiLineNo, callh));
|
||||||
|
|
|
||||||
12
vvp/array.cc
12
vvp/array.cc
|
|
@ -31,6 +31,7 @@
|
||||||
#endif
|
#endif
|
||||||
# include <stdlib.h>
|
# include <stdlib.h>
|
||||||
# include <string.h>
|
# include <string.h>
|
||||||
|
# include <limits.h>
|
||||||
# include <iostream>
|
# include <iostream>
|
||||||
# include "compile.h"
|
# include "compile.h"
|
||||||
# include <assert.h>
|
# include <assert.h>
|
||||||
|
|
@ -133,6 +134,15 @@ struct __vpiArrayVthrA {
|
||||||
{
|
{
|
||||||
if (address_handle) {
|
if (address_handle) {
|
||||||
s_vpi_value vp;
|
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;
|
vp.format = vpiIntVal;
|
||||||
vpi_get_value(address_handle, &vp);
|
vpi_get_value(address_handle, &vp);
|
||||||
return vp.value.integer;
|
return vp.value.integer;
|
||||||
|
|
@ -146,7 +156,7 @@ struct __vpiArrayVthrA {
|
||||||
vvp_bit4_t bit = vthread_get_bit(vpip_current_vthread, address+idx);
|
vvp_bit4_t bit = vthread_get_bit(vpip_current_vthread, address+idx);
|
||||||
tmp.set_bit(idx, bit);
|
tmp.set_bit(idx, bit);
|
||||||
}
|
}
|
||||||
unsigned long val;
|
unsigned long val = ULONG_MAX;
|
||||||
vector4_to_value(tmp, val);
|
vector4_to_value(tmp, val);
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
15
vvp/part.cc
15
vvp/part.cc
|
|
@ -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,
|
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)
|
vvp_vector4_t&ref)
|
||||||
{
|
{
|
||||||
long tmp;
|
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;
|
source = bit;
|
||||||
break;
|
break;
|
||||||
case 1:
|
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.
|
// represent a 'bx value on the select input.
|
||||||
tmp = LONG_MIN;
|
tmp = INT_MIN;
|
||||||
// We need a new &PV<> that knows if the index is signed.
|
// 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);
|
vector4_to_value(bit, tmp, false);
|
||||||
if (tmp == base) return false;
|
if ((int)tmp == base) return false;
|
||||||
base = tmp;
|
base = tmp;
|
||||||
break;
|
break;
|
||||||
default:
|
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_);
|
vvp_vector4_t res (wid_);
|
||||||
|
|
||||||
for (unsigned idx = 0 ; idx < wid_ ; idx += 1) {
|
for (unsigned idx = 0 ; idx < wid_ ; idx += 1) {
|
||||||
long adr = base+idx;
|
int adr = base+idx;
|
||||||
if (adr < 0) continue;
|
if (adr < 0) continue;
|
||||||
if ((unsigned)adr >= source.size()) break;
|
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 {
|
struct vvp_fun_part_var_state_s {
|
||||||
vvp_fun_part_var_state_s() : base(0) { }
|
vvp_fun_part_var_state_s() : base(0) { }
|
||||||
|
|
||||||
long base;
|
int base;
|
||||||
vvp_vector4_t source;
|
vvp_vector4_t source;
|
||||||
vvp_vector4_t ref;
|
vvp_vector4_t ref;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -130,7 +130,7 @@ class vvp_fun_part_var : public vvp_net_fun_t {
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool recv_vec4_(vvp_net_ptr_t port, const vvp_vector4_t&bit,
|
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);
|
vvp_vector4_t&ref);
|
||||||
|
|
||||||
unsigned wid_;
|
unsigned wid_;
|
||||||
|
|
@ -154,7 +154,7 @@ class vvp_fun_part_var_sa : public vvp_fun_part_var {
|
||||||
vvp_context_t);
|
vvp_context_t);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
long base_;
|
int base_;
|
||||||
vvp_vector4_t source_;
|
vvp_vector4_t source_;
|
||||||
// Save the last output, for detecting change.
|
// Save the last output, for detecting change.
|
||||||
vvp_vector4_t ref_;
|
vvp_vector4_t ref_;
|
||||||
|
|
|
||||||
|
|
@ -139,8 +139,8 @@ static void format_vpiBinStrVal(vvp_signal_value*sig, int base, unsigned wid,
|
||||||
s_vpi_value*vp)
|
s_vpi_value*vp)
|
||||||
{
|
{
|
||||||
char *rbuf = need_result_buf(wid+1, RBUF_VAL);
|
char *rbuf = need_result_buf(wid+1, RBUF_VAL);
|
||||||
long offset = wid - 1 + base;
|
|
||||||
long end = base + (signed)wid;
|
long end = base + (signed)wid;
|
||||||
|
long offset = end - 1;
|
||||||
long ssize = (signed)sig->value_size();
|
long ssize = (signed)sig->value_size();
|
||||||
|
|
||||||
for (long idx = base ; idx < end ; idx += 1) {
|
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. */
|
/* We return from the symbol base if it is defined. */
|
||||||
if (rfp->sbase != 0) {
|
if (rfp->sbase != 0) {
|
||||||
s_vpi_value val;
|
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;
|
val.format = vpiIntVal;
|
||||||
vpi_get_value(rfp->sbase, &val);
|
vpi_get_value(rfp->sbase, &val);
|
||||||
return val.value.integer;
|
return val.value.integer;
|
||||||
|
|
|
||||||
|
|
@ -1300,8 +1300,8 @@ vvp_vector4_t& vvp_vector4_t::operator |= (const vvp_vector4_t&that)
|
||||||
if (size_ <= BITS_PER_WORD) {
|
if (size_ <= BITS_PER_WORD) {
|
||||||
unsigned long tmp = abits_val_ | bbits_val_ |
|
unsigned long tmp = abits_val_ | bbits_val_ |
|
||||||
that.abits_val_ | that.bbits_val_;
|
that.abits_val_ | that.bbits_val_;
|
||||||
bbits_val_ = (~abits_val_ | bbits_val_) & that.bbits_val_ |
|
bbits_val_ = ((~abits_val_ | bbits_val_) & that.bbits_val_) |
|
||||||
(~that.abits_val_ | that.bbits_val_) & bbits_val_;
|
((~that.abits_val_ | that.bbits_val_) & bbits_val_);
|
||||||
abits_val_ = tmp;
|
abits_val_ = tmp;
|
||||||
|
|
||||||
} else {
|
} 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) {
|
for (unsigned idx = 0; idx < words ; idx += 1) {
|
||||||
unsigned long tmp = abits_ptr_[idx] | bbits_ptr_[idx] |
|
unsigned long tmp = abits_ptr_[idx] | bbits_ptr_[idx] |
|
||||||
that.abits_ptr_[idx] | that.bbits_ptr_[idx];
|
that.abits_ptr_[idx] | that.bbits_ptr_[idx];
|
||||||
bbits_ptr_[idx] = (~abits_ptr_[idx] | bbits_ptr_[idx]) &
|
bbits_ptr_[idx] = ((~abits_ptr_[idx] | bbits_ptr_[idx]) &
|
||||||
that.bbits_ptr_[idx] |
|
that.bbits_ptr_[idx]) |
|
||||||
(~that.abits_ptr_[idx] |
|
((~that.abits_ptr_[idx] |
|
||||||
that.bbits_ptr_[idx]) & bbits_ptr_[idx];
|
that.bbits_ptr_[idx]) & bbits_ptr_[idx]);
|
||||||
abits_ptr_[idx] = tmp;
|
abits_ptr_[idx] = tmp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue