Merge branch 'master' into vec4-stack

Conflicts:
	vvp/vthread.cc
This commit is contained in:
Stephen Williams 2014-02-21 18:04:16 -08:00
commit 91b7c6ab55
5 changed files with 81 additions and 56 deletions

View File

@ -358,6 +358,10 @@ NetEConst* NetEBComp::eval_less_(const NetExpr*le, const NetExpr*re) const
NetEConst* NetEBComp::must_be_leeq_(const NetExpr*le, const verinum&rv, bool eq_flag) const
{
// The following optimization is not valid if le can contain 'x'
// or 'z' values.
if (le->expr_type() == IVL_VT_LOGIC) return 0;
assert(le->expr_width() > 0);
verinum lv (verinum::V1, le->expr_width());
if (le->has_sign() && rv.has_sign()) {

View File

@ -1011,8 +1011,18 @@ static void force_link_rval(ivl_statement_t net, ivl_expr_t rval)
ivl_expr_t lword_idx, rword_idx;
unsigned long use_lword = 0, use_rword = 0;
if (ivl_expr_type(rval) != IVL_EX_SIGNAL)
if (ivl_expr_type(rval) != IVL_EX_SIGNAL) {
if (ivl_expr_type(rval) == IVL_EX_NUMBER ||
ivl_expr_type(rval) == IVL_EX_REALNUM)
return;
fprintf(stderr, "%s:%u: tgt-vvp sorry: procedural continuous "
"assignments are not yet fully supported. The RHS of "
"this assignment will only be evaluated once, at the "
"time the assignment statement is executed.\n",
ivl_stmt_file(net), ivl_stmt_lineno(net));
return;
}
switch (ivl_statement_type(net)) {
case IVL_ST_CASSIGN:

View File

@ -453,35 +453,37 @@ void vvp_arith_pow::recv_vec4(vvp_net_ptr_t ptr, const vvp_vector4_t&bit,
{
dispatch_operand_(ptr, bit);
vvp_vector4_t res4;
if (signed_flag_) {
if (op_a_.has_xz() || op_b_.has_xz()) {
ptr.ptr()->send_vec4(x_val_, 0);
return;
}
vvp_vector2_t a2 (op_a_, true);
vvp_vector2_t b2 (op_b_, true);
double ad, bd, resd;
vector4_to_value(op_a_, ad, true);
vector4_to_value(op_b_, bd, true);
/* 2**-1 and -2**-1 are defined to be zero. */
if ((bd == -1) && (fabs(ad) == 2.0)) resd = 0.0;
else resd = pow(ad, bd);
res4 = vvp_vector4_t(wid_, resd);
} else {
vvp_vector2_t a2 (op_a_, true);
vvp_vector2_t b2 (op_b_, true);
if (a2.is_NaN() || b2.is_NaN()) {
ptr.ptr()->send_vec4(x_val_, 0);
return;
}
vvp_vector2_t result = pow(a2, b2);
res4 = vector2_to_vector4(result, wid_);
// If we have an X or Z in the arguments return X.
if (a2.is_NaN() || b2.is_NaN()) {
ptr.ptr()->send_vec4(x_val_, 0);
return;
}
ptr.ptr()->send_vec4(res4, 0);
// Is the exponent negative? If so, table 5-6 in IEEE1364-2005
// defines what value is returned.
if (signed_flag_ && b2.value(b2.size()-1)) {
int a_val;
double r_val = 0.0;
if (vector2_to_value(a2, a_val, true)) {
if (a_val == 0) {
ptr.ptr()->send_vec4(x_val_, 0);
return;
}
if (a_val == 1) {
r_val = 1.0;
}
if (a_val == -1) {
r_val = b2.value(0) ? -1.0 : 1.0;
}
}
ptr.ptr()->send_vec4(vvp_vector4_t(wid_, r_val), 0);
return;
}
ptr.ptr()->send_vec4(vector2_to_vector4(pow(a2, b2), wid_), 0);
}

View File

@ -5058,7 +5058,7 @@ bool of_POP_VEC4(vthread_t thr, vvp_code_t cp)
/*
* %pow
*/
bool of_POW(vthread_t thr, vvp_code_t)
static bool of_POW_base(vthread_t thr, vvp_code_t cp, bool signed_flag)
{
vvp_vector4_t valb = thr->pop_vec4();
vvp_vector4_t vala = thr->pop_vec4();
@ -5076,6 +5076,32 @@ bool of_POW(vthread_t thr, vvp_code_t)
return true;
}
// Is the exponent negative? If so, table 5-6 in IEEE1364-2005
// defines what value is returned.
if (signed_flag && yv2.value(yv2.size()-1)) {
int a_val;
vvp_bit4_t pad = BIT4_0, lsb = BIT4_0;
if (vector2_to_value(xv2, a_val, true)) {
if (a_val == 0) {
pad = BIT4_X; lsb = BIT4_X;
}
if (a_val == 1) {
pad = BIT4_0; lsb = BIT4_1;
}
if (a_val == -1) {
if (yv2.value(0)) {
pad = BIT4_1; lsb = BIT4_1;
} else {
pad = BIT4_0; lsb = BIT4_1;
}
}
}
vvp_vector4_t tmp (wid, pad);
tmp.set_bit(0, lsb);
thr->push_vec4(tmp);
return true;
}
vvp_vector2_t result = pow(xv2, yv2);
/* Copy only what we need of the result. If the result is too
@ -5091,35 +5117,14 @@ bool of_POW(vthread_t thr, vvp_code_t)
return true;
}
/*
* %pow/s
*/
bool of_POW_S(vthread_t thr, vvp_code_t)
bool of_POW(vthread_t thr, vvp_code_t cp)
{
vvp_vector4_t yv = thr->pop_vec4();
vvp_vector4_t xv = thr->pop_vec4();
return of_POW_base(thr, cp, false);
}
assert(xv.size()==yv.size());
unsigned wid = xv.size();
/* If we have an X or Z in the arguments return X. */
if (xv.has_xz() || yv.has_xz()) {
vvp_vector4_t tmp (wid, BIT4_X);
thr->push_vec4(tmp);
return true;
}
/* Calculate the result using the double pow() function. */
double xd, yd, resd;
vector4_to_value(xv, xd, true);
vector4_to_value(yv, yd, true);
/* 2**-1 and -2**-1 are defined to be zero. */
if ((yd == -1.0) && (fabs(xd) == 2.0)) resd = 0.0;
else resd = pow(xd, yd);
vvp_vector4_t res = vvp_vector4_t(wid, resd);
thr->push_vec4(res);
return true;
bool of_POW_S(vthread_t thr, vvp_code_t cp)
{
return of_POW_base(thr, cp, true);
}
bool of_POW_WR(vthread_t thr, vvp_code_t)

View File

@ -200,7 +200,11 @@ void vvp_fun_signal4_sa::recv_vec4(vvp_net_ptr_t ptr, const vvp_vector4_t&bit,
break;
case 1: // Continuous assign value
bits4_ = bit;
// Handle the simple case of the linked source being wider
// than this signal. Note we don't yet support the case of
// the linked source being narrower than this signal, or
// the case of an expression being assigned.
bits4_ = coerce_to_width(bit, bits4_.size());
assign_mask_ = vvp_vector2_t(vvp_vector2_t::FILL1, bits4_.size());
ptr.ptr()->send_vec4(bits4_, 0);
break;