Merge branch 'master' into vec4-stack
Conflicts: vvp/vthread.cc
This commit is contained in:
commit
91b7c6ab55
|
|
@ -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()) {
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
54
vvp/arith.cc
54
vvp/arith.cc
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue