Merge branch 'master' of git://icarus.com/~steve-icarus/verilog into vhdl
This commit is contained in:
commit
f49a4e4336
7
PExpr.h
7
PExpr.h
|
|
@ -66,7 +66,7 @@ class PExpr : public LineInfo {
|
|||
// The expr_type is an output argument that gives the
|
||||
// calculated type for the expression.
|
||||
//
|
||||
// The unsigned_flag is set to true if the expression is
|
||||
// The unsized_flag is set to true if the expression is
|
||||
// unsized and therefore expandable. This happens if a
|
||||
// sub-expression is an unsized literal. Some expressions make
|
||||
// special use of that.
|
||||
|
|
@ -156,6 +156,11 @@ class PEConcat : public PExpr {
|
|||
virtual verinum* eval_const(Design*des, NetScope*sc) const;
|
||||
virtual void dump(ostream&) const;
|
||||
|
||||
virtual unsigned test_width(Design*des, NetScope*scope,
|
||||
unsigned min, unsigned lval,
|
||||
ivl_variable_type_t&expr_type,
|
||||
bool&unsized_flag);
|
||||
|
||||
virtual bool elaborate_sig(Design*des, NetScope*scope) const;
|
||||
virtual NetNet* elaborate_lnet(Design*des, NetScope*scope) const;
|
||||
virtual NetNet* elaborate_bi_net(Design*des, NetScope*scope) const;
|
||||
|
|
|
|||
54
cprop.cc
54
cprop.cc
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1998-2005 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1998-2008 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
|
||||
|
|
@ -739,7 +739,8 @@ v }
|
|||
}
|
||||
}
|
||||
|
||||
static void replace_with_bufif(Design*des, NetMux*obj, NetLogic::TYPE type)
|
||||
#if 0
|
||||
static void replace_with_mos(Design*des, NetMux*obj, NetLogic::TYPE type)
|
||||
{
|
||||
NetScope*scope = obj->scope();
|
||||
NetLogic*tmp = new NetLogic(obj->scope(),
|
||||
|
|
@ -749,7 +750,7 @@ static void replace_with_bufif(Design*des, NetMux*obj, NetLogic::TYPE type)
|
|||
des->add_node(tmp);
|
||||
|
||||
connect(obj->pin_Result(), tmp->pin(0));
|
||||
connect(obj->pin_Data(type==NetLogic::BUFIF0? 0 : 1), tmp->pin(1));
|
||||
connect(obj->pin_Data(type==NetLogic::PMOS? 0 : 1), tmp->pin(1));
|
||||
|
||||
if (obj->width() == 1) {
|
||||
/* Special case that the expression is 1 bit
|
||||
|
|
@ -780,10 +781,11 @@ static void replace_with_bufif(Design*des, NetMux*obj, NetLogic::TYPE type)
|
|||
|
||||
delete obj;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This detects the case where the mux selects between a value and
|
||||
* Vz. In this case, replace the device with a bufif with the sel
|
||||
* Vz. In this case, replace the device with a mos with the sel
|
||||
* input used to enable the output.
|
||||
*/
|
||||
void cprop_functor::lpm_mux(Design*des, NetMux*obj)
|
||||
|
|
@ -793,45 +795,34 @@ void cprop_functor::lpm_mux(Design*des, NetMux*obj)
|
|||
if (obj->sel_width() != 1)
|
||||
return;
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* This is slower than the actual MUXZ so we are skipping this for now.
|
||||
* If we had a half mux functor this could be faster and more compact
|
||||
* so I'm leaving the code for future reference.
|
||||
*/
|
||||
/* If the first input is all constant Vz, then replace the
|
||||
NetMux with an array of BUFIF1 devices, with the enable
|
||||
NetMux with an array of NMOS devices, with the enable
|
||||
connected to the select input. */
|
||||
bool flag = true;
|
||||
|
||||
if (! obj->pin_Data(0).nexus()->drivers_constant()) {
|
||||
flag = false;
|
||||
}
|
||||
|
||||
if (flag && obj->pin_Data(0).nexus()->driven_value() != verinum::Vz) {
|
||||
flag = false;
|
||||
}
|
||||
|
||||
if (flag) {
|
||||
replace_with_bufif(des, obj, NetLogic::BUFIF1);
|
||||
if (obj->pin_Data(0).nexus()->drivers_constant() &&
|
||||
obj->pin_Data(0).nexus()->driven_value() == verinum::Vz) {
|
||||
replace_with_mos(des, obj, NetLogic::NMOS);
|
||||
count += 1;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* If instead the second input is all constant Vz, replace the
|
||||
NetMux with an array of BUFIF0 devices. */
|
||||
flag = true;
|
||||
if (! obj->pin_Data(1).nexus()->drivers_constant()) {
|
||||
flag = false;
|
||||
}
|
||||
|
||||
if (flag && obj->pin_Data(1).nexus()->driven_value() != verinum::Vz) {
|
||||
flag = false;
|
||||
}
|
||||
|
||||
if (flag) {
|
||||
replace_with_bufif(des, obj, NetLogic::BUFIF0);
|
||||
NetMux with an array of PMOS devices. */
|
||||
if (obj->pin_Data(1).nexus()->drivers_constant() &&
|
||||
obj->pin_Data(1).nexus()->driven_value() == verinum::Vz) {
|
||||
replace_with_mos(des, obj, NetLogic::PMOS);
|
||||
count += 1;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* If the select input is constant, then replace with a BUFZ */
|
||||
flag = obj->pin_Sel().nexus()->drivers_constant();
|
||||
bool flag = obj->pin_Sel().nexus()->drivers_constant();
|
||||
verinum::V sel_val = flag? obj->pin_Sel().nexus()->driven_value() : verinum::Vx;
|
||||
if ((sel_val != verinum::Vz) && (sel_val != verinum::Vx)) {
|
||||
NetBUFZ*tmp = new NetBUFZ(obj->scope(), obj->name(), obj->width());
|
||||
|
|
@ -974,4 +965,3 @@ void cprop(Design*des)
|
|||
cprop_dc_functor dc;
|
||||
des->functor(&dc);
|
||||
}
|
||||
|
||||
|
|
|
|||
181
elab_expr.cc
181
elab_expr.cc
|
|
@ -112,7 +112,7 @@ NetExpr* PExpr::elaborate_expr(Design*des, NetScope*, int, bool) const
|
|||
|
||||
unsigned PEBinary::test_width(Design*des, NetScope*scope,
|
||||
unsigned min, unsigned lval,
|
||||
ivl_variable_type_t&expr_type,
|
||||
ivl_variable_type_t&expr_type__,
|
||||
bool&unsized_flag)
|
||||
{
|
||||
ivl_variable_type_t expr_type_left = IVL_VT_NO_TYPE;
|
||||
|
|
@ -155,7 +155,7 @@ unsigned PEBinary::test_width(Design*des, NetScope*scope,
|
|||
break;
|
||||
|
||||
case '*':
|
||||
if (unsized_flag && type_is_vectorable(expr_type)) {
|
||||
if (unsized_flag && type_is_vectorable(expr_type_)) {
|
||||
unsigned use_wid = wid_left + wid_right;
|
||||
if (use_wid > integer_width)
|
||||
use_wid = integer_width;
|
||||
|
|
@ -191,7 +191,7 @@ unsigned PEBinary::test_width(Design*des, NetScope*scope,
|
|||
else
|
||||
expr_width_ = 1;
|
||||
|
||||
expr_type = expr_type_;
|
||||
expr_type__ = expr_type_;
|
||||
return expr_width_;
|
||||
}
|
||||
|
||||
|
|
@ -502,7 +502,7 @@ NetExpr* PEBinary::elaborate_expr_base_lshift_(Design*des,
|
|||
|
||||
} else if (NetEConst*rpc = dynamic_cast<NetEConst*> (rp)) {
|
||||
long shift = rpc->value().as_long();
|
||||
long use_wid = lp->expr_width();
|
||||
use_wid = lp->expr_width();
|
||||
if (expr_wid > 0)
|
||||
use_wid = expr_wid;
|
||||
|
||||
|
|
@ -734,15 +734,17 @@ NetExpr* PEBinary::elaborate_expr_base_add_(Design*des,
|
|||
}
|
||||
|
||||
unsigned PEBComp::test_width(Design*, NetScope*,unsigned, unsigned,
|
||||
ivl_variable_type_t&expr_type,
|
||||
ivl_variable_type_t&expr_type__,
|
||||
bool&)
|
||||
{
|
||||
expr_type = IVL_VT_LOGIC;
|
||||
expr_type_ = IVL_VT_LOGIC;
|
||||
expr_type__ = expr_type_;
|
||||
expr_width_ = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
NetExpr* PEBComp::elaborate_expr(Design*des, NetScope*scope,
|
||||
int expr_width, bool sys_task_arg) const
|
||||
int expr_width_dummy, bool sys_task_arg) const
|
||||
{
|
||||
assert(left_);
|
||||
assert(right_);
|
||||
|
|
@ -793,10 +795,10 @@ NetExpr* PEBComp::elaborate_expr(Design*des, NetScope*scope,
|
|||
|
||||
unsigned PEBShift::test_width(Design*des, NetScope*scope,
|
||||
unsigned min, unsigned lval,
|
||||
ivl_variable_type_t&expr_type,
|
||||
ivl_variable_type_t&expr_type__,
|
||||
bool&unsized_flag)
|
||||
{
|
||||
unsigned wid_left = left_->test_width(des,scope,min, 0, expr_type, unsized_flag);
|
||||
unsigned wid_left = left_->test_width(des,scope,min, 0, expr_type__, unsized_flag);
|
||||
|
||||
// The right expression is self-determined and has no impact
|
||||
// on the expression size that is generated.
|
||||
|
|
@ -816,7 +818,22 @@ unsigned PEBShift::test_width(Design*des, NetScope*scope,
|
|||
<< endl;
|
||||
}
|
||||
|
||||
return wid_left;
|
||||
expr_type_ = expr_type__;
|
||||
expr_width_ = wid_left;
|
||||
|
||||
// Run a test-width on the shift amount so that its types are
|
||||
// worked out for elaboration later on. We don't need the
|
||||
// value now.
|
||||
ivl_variable_type_t rtype = IVL_VT_NO_TYPE;
|
||||
bool rflag = false;
|
||||
unsigned wid_right = right_->test_width(des, scope, 0, 0, rtype, rflag);
|
||||
if (debug_elaborate)
|
||||
cerr << get_fileline() << ": debug: "
|
||||
<< "Test width of shift amount of shift expression "
|
||||
<< "returns wid=" << wid_right << ", type=" << rtype
|
||||
<< ", flag=" << rflag << endl;
|
||||
|
||||
return expr_width_;
|
||||
}
|
||||
|
||||
NetExpr*PEBShift::elaborate_expr(Design*des, NetScope*scope,
|
||||
|
|
@ -839,7 +856,7 @@ NetExpr*PEBShift::elaborate_expr(Design*des, NetScope*scope,
|
|||
|
||||
unsigned PECallFunction::test_width_sfunc_(Design*des, NetScope*scope,
|
||||
unsigned min, unsigned lval,
|
||||
ivl_variable_type_t&expr_type,
|
||||
ivl_variable_type_t&expr_type__,
|
||||
bool&unsized_flag)
|
||||
{
|
||||
perm_string name = peek_tail_name(path_);
|
||||
|
|
@ -848,12 +865,15 @@ unsigned PECallFunction::test_width_sfunc_(Design*des, NetScope*scope,
|
|||
PExpr*expr = parms_[0];
|
||||
if (expr == 0)
|
||||
return 0;
|
||||
unsigned wid = expr->test_width(des, scope, min, lval, expr_type, unsized_flag);
|
||||
|
||||
expr_width_ = expr->test_width(des, scope, min, lval, expr_type__, unsized_flag);
|
||||
expr_type_ = expr_type__;
|
||||
|
||||
if (debug_elaborate)
|
||||
cerr << get_fileline() << ": debug: test_width"
|
||||
<< " of $signed/$unsigned returns test_width"
|
||||
<< " of subexpression." << endl;
|
||||
return wid;
|
||||
return expr_width_;
|
||||
}
|
||||
|
||||
// Run through the arguments of the system function and make
|
||||
|
|
@ -880,7 +900,7 @@ unsigned PECallFunction::test_width_sfunc_(Design*des, NetScope*scope,
|
|||
expr_type_ = IVL_VT_BOOL;
|
||||
expr_width_= integer_width;
|
||||
|
||||
expr_type = expr_type_;
|
||||
expr_type__ = expr_type_;
|
||||
return expr_width_;
|
||||
}
|
||||
|
||||
|
|
@ -892,7 +912,7 @@ unsigned PECallFunction::test_width_sfunc_(Design*des, NetScope*scope,
|
|||
|
||||
expr_type_ = IVL_VT_BOOL;
|
||||
expr_width_ = 1;
|
||||
expr_type = expr_type_;
|
||||
expr_type__ = expr_type_;
|
||||
return expr_width_;
|
||||
}
|
||||
|
||||
|
|
@ -904,7 +924,7 @@ unsigned PECallFunction::test_width_sfunc_(Design*des, NetScope*scope,
|
|||
expr_type_ = sfunc_info->type;
|
||||
expr_width_ = sfunc_info->wid;
|
||||
|
||||
expr_type = expr_type_;
|
||||
expr_type__ = expr_type_;
|
||||
|
||||
if (debug_elaborate)
|
||||
cerr << get_fileline() << ": debug: test_width "
|
||||
|
|
@ -917,11 +937,11 @@ unsigned PECallFunction::test_width_sfunc_(Design*des, NetScope*scope,
|
|||
|
||||
unsigned PECallFunction::test_width(Design*des, NetScope*scope,
|
||||
unsigned min, unsigned lval,
|
||||
ivl_variable_type_t&expr_type,
|
||||
ivl_variable_type_t&expr_type__,
|
||||
bool&unsized_flag)
|
||||
{
|
||||
if (peek_tail_name(path_)[0] == '$')
|
||||
return test_width_sfunc_(des, scope, min, lval, expr_type, unsized_flag);
|
||||
return test_width_sfunc_(des, scope, min, lval, expr_type__, unsized_flag);
|
||||
|
||||
// The width of user defined functions depends only on the
|
||||
// width of the return value. The arguments are entirely
|
||||
|
|
@ -939,17 +959,19 @@ unsigned PECallFunction::test_width(Design*des, NetScope*scope,
|
|||
assert(dscope);
|
||||
|
||||
if (NetNet*res = dscope->find_signal(dscope->basename())) {
|
||||
expr_type = res->data_type();
|
||||
expr_type_ = res->data_type();
|
||||
if (debug_elaborate)
|
||||
cerr << get_fileline() << ": debug: test_width "
|
||||
<< "of function returns width " << res->vector_width()
|
||||
<< ", type=" << expr_type
|
||||
<< ", type=" << expr_type_
|
||||
<< "." << endl;
|
||||
|
||||
if (! type_is_vectorable(expr_type))
|
||||
if (! type_is_vectorable(expr_type__))
|
||||
unsized_flag = true;
|
||||
|
||||
return res->vector_width();
|
||||
expr_width_ = res->vector_width();
|
||||
expr_type__ = expr_type_;
|
||||
return expr_width_;
|
||||
}
|
||||
|
||||
ivl_assert(*this, 0);
|
||||
|
|
@ -1265,6 +1287,21 @@ NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope,
|
|||
return 0;
|
||||
}
|
||||
|
||||
unsigned PEConcat::test_width(Design*des, NetScope*scope,
|
||||
unsigned min, unsigned lval,
|
||||
ivl_variable_type_t&expr_type__,
|
||||
bool&unsized_flag)
|
||||
{
|
||||
expr_type_ = IVL_VT_LOGIC;
|
||||
|
||||
if (debug_elaborate)
|
||||
cerr << get_fileline() << ": debug: CONCAT MISSING TEST_WIDTH!" << endl;
|
||||
|
||||
expr_type__ = expr_type_;
|
||||
unsized_flag = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Keep track of the concatenation/repeat depth.
|
||||
static int concat_depth = 0;
|
||||
|
||||
|
|
@ -1379,14 +1416,14 @@ NetExpr* PEConcat::elaborate_expr(Design*des, NetScope*scope,
|
|||
*/
|
||||
unsigned PEFNumber::test_width(Design*des, NetScope*scope,
|
||||
unsigned min, unsigned lval,
|
||||
ivl_variable_type_t&expr_type,
|
||||
ivl_variable_type_t&expr_type__,
|
||||
bool&unsized_flag)
|
||||
{
|
||||
expr_type_ = IVL_VT_REAL;
|
||||
expr_width_ = 1;
|
||||
unsized_flag = true;
|
||||
|
||||
expr_type = expr_type_;
|
||||
expr_type__ = expr_type_;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -1540,7 +1577,7 @@ bool PEIdent::calculate_param_range_(Design*des, NetScope*scope,
|
|||
|
||||
unsigned PEIdent::test_width(Design*des, NetScope*scope,
|
||||
unsigned min, unsigned lval,
|
||||
ivl_variable_type_t&expr_type,
|
||||
ivl_variable_type_t&expr_type__,
|
||||
bool&unsized_flag)
|
||||
{
|
||||
NetNet* net = 0;
|
||||
|
|
@ -1551,11 +1588,6 @@ unsigned PEIdent::test_width(Design*des, NetScope*scope,
|
|||
|
||||
symbol_search(des, scope, path_, net, par, eve, ex1, ex2);
|
||||
|
||||
if (net != 0)
|
||||
expr_type_ = net->data_type();
|
||||
|
||||
expr_type = expr_type;
|
||||
|
||||
// If there is a part/bit select expression, then process it
|
||||
// here. This constrains the results no matter what kind the
|
||||
// name is.
|
||||
|
|
@ -1591,14 +1623,18 @@ unsigned PEIdent::test_width(Design*des, NetScope*scope,
|
|||
ivl_assert(*this, 0);
|
||||
}
|
||||
|
||||
if (use_width != UINT_MAX)
|
||||
return max(use_width, min);
|
||||
if (use_width != UINT_MAX) {
|
||||
expr_type_ = IVL_VT_LOGIC; // Assume bit/parts selects are logic
|
||||
expr_width_ = max(use_width, min);
|
||||
expr_type__ = expr_type_;
|
||||
return expr_width_;
|
||||
}
|
||||
|
||||
// The width of a signal expression is the width of the signal.
|
||||
if (net != 0) {
|
||||
expr_type_ = net->data_type();
|
||||
expr_width_= max(net->vector_width(), (unsigned long)min);
|
||||
expr_type = expr_type_;
|
||||
expr_type__ = expr_type_;
|
||||
return expr_width_;
|
||||
}
|
||||
|
||||
|
|
@ -1607,7 +1643,7 @@ unsigned PEIdent::test_width(Design*des, NetScope*scope,
|
|||
// width is undefined.
|
||||
if (par != 0) {
|
||||
expr_type_ = par->expr_type();
|
||||
expr_type = expr_type_;
|
||||
expr_type__ = expr_type_;
|
||||
if (ex1) {
|
||||
ivl_assert(*this, ex2);
|
||||
const NetEConst*ex1_const = dynamic_cast<const NetEConst*> (ex1);
|
||||
|
|
@ -1624,7 +1660,7 @@ unsigned PEIdent::test_width(Design*des, NetScope*scope,
|
|||
}
|
||||
|
||||
// This is a parameter. If it is sized (meaning it was
|
||||
// declared with range expresions) then the range
|
||||
// declared with range expressions) then the range
|
||||
// expressions would have been caught above. So if we
|
||||
// got there there we know this is an unsized constant.
|
||||
expr_width_ = par->expr_width();
|
||||
|
|
@ -1632,7 +1668,12 @@ unsigned PEIdent::test_width(Design*des, NetScope*scope,
|
|||
return expr_width_;
|
||||
}
|
||||
|
||||
// Not a net, and not a parameter? Give up on the type, but
|
||||
// set the width that we collected.
|
||||
expr_type_ = IVL_VT_NO_TYPE;
|
||||
expr_width_ = min;
|
||||
|
||||
expr_type__ = expr_type_;
|
||||
return min;
|
||||
}
|
||||
|
||||
|
|
@ -2070,10 +2111,10 @@ NetExpr* PEIdent::elaborate_expr_param_(Design*des,
|
|||
rb = verinum::V0;
|
||||
}
|
||||
|
||||
NetEConst*re = new NetEConst(verinum(rb, 1));
|
||||
NetEConst*re2 = new NetEConst(verinum(rb, 1));
|
||||
delete tmp;
|
||||
delete mtmp;
|
||||
tmp = re;
|
||||
tmp = re2;
|
||||
|
||||
} else {
|
||||
|
||||
|
|
@ -2487,7 +2528,7 @@ NetExpr* PEIdent::elaborate_expr_net(Design*des, NetScope*scope,
|
|||
|
||||
unsigned PENumber::test_width(Design*, NetScope*,
|
||||
unsigned min, unsigned lval,
|
||||
ivl_variable_type_t&expr_type,
|
||||
ivl_variable_type_t&expr_type__,
|
||||
bool&unsized_flag)
|
||||
{
|
||||
expr_type_ = IVL_VT_LOGIC;
|
||||
|
|
@ -2501,13 +2542,13 @@ unsigned PENumber::test_width(Design*, NetScope*,
|
|||
if (lval > 0 && lval < use_wid)
|
||||
use_wid = lval;
|
||||
|
||||
expr_type = expr_type_;
|
||||
expr_type__ = expr_type_;
|
||||
expr_width_ = use_wid;
|
||||
return use_wid;
|
||||
}
|
||||
|
||||
NetEConst* PENumber::elaborate_expr(Design*des, NetScope*,
|
||||
int expr_width, bool) const
|
||||
int expr_width__, bool) const
|
||||
{
|
||||
assert(value_);
|
||||
verinum tvalue = *value_;
|
||||
|
|
@ -2516,10 +2557,10 @@ NetEConst* PENumber::elaborate_expr(Design*des, NetScope*,
|
|||
// specific size (for example this is part of the r-values of
|
||||
// an assignment) so we pad to the desired width and ignore
|
||||
// the self-determined size.
|
||||
if (expr_width > 0) {
|
||||
tvalue = pad_to_width(tvalue, expr_width);
|
||||
if (tvalue.len() > (unsigned)expr_width) {
|
||||
verinum tmp (tvalue, expr_width);
|
||||
if (expr_width__ > 0) {
|
||||
tvalue = pad_to_width(tvalue, expr_width__);
|
||||
if (tvalue.len() > (unsigned)expr_width__) {
|
||||
verinum tmp (tvalue, expr_width__);
|
||||
tmp.has_sign(tvalue.has_sign());
|
||||
tvalue = tmp;
|
||||
}
|
||||
|
|
@ -2532,19 +2573,20 @@ NetEConst* PENumber::elaborate_expr(Design*des, NetScope*,
|
|||
|
||||
unsigned PEString::test_width(Design*des, NetScope*scope,
|
||||
unsigned min, unsigned lval,
|
||||
ivl_variable_type_t&expr_type,
|
||||
ivl_variable_type_t&expr_type__,
|
||||
bool&unsized_flag)
|
||||
{
|
||||
expr_type = IVL_VT_BOOL;
|
||||
unsigned use_wid = text_? 8*strlen(text_) : 0;
|
||||
if (min > use_wid)
|
||||
use_wid = min;
|
||||
expr_type_ = IVL_VT_BOOL;
|
||||
expr_width_ = text_? 8*strlen(text_) : 0;
|
||||
if (min > expr_width_)
|
||||
expr_width_ = min;
|
||||
|
||||
return use_wid;
|
||||
expr_type__ = expr_type_;
|
||||
return expr_width_;
|
||||
}
|
||||
|
||||
NetEConst* PEString::elaborate_expr(Design*des, NetScope*,
|
||||
int expr_width, bool) const
|
||||
int expr_width_dummy, bool) const
|
||||
{
|
||||
NetEConst*tmp = new NetEConst(value());
|
||||
tmp->set_line(*this);
|
||||
|
|
@ -2553,9 +2595,15 @@ NetEConst* PEString::elaborate_expr(Design*des, NetScope*,
|
|||
|
||||
unsigned PETernary::test_width(Design*des, NetScope*scope,
|
||||
unsigned min, unsigned lval,
|
||||
ivl_variable_type_t&expr_type,
|
||||
ivl_variable_type_t&expr_type__,
|
||||
bool&flag)
|
||||
{
|
||||
// The condition of the ternary is self-determined, but we
|
||||
// test its width to force its type to be calculated.
|
||||
ivl_variable_type_t con_type = IVL_VT_NO_TYPE;
|
||||
bool con_flag = false;
|
||||
expr_->test_width(des, scope, 0, 0, con_type, con_flag);
|
||||
|
||||
ivl_variable_type_t tru_type = IVL_VT_NO_TYPE;
|
||||
unsigned tru_wid = tru_->test_width(des, scope, min, lval, tru_type,flag);
|
||||
|
||||
|
|
@ -2583,7 +2631,7 @@ unsigned PETernary::test_width(Design*des, NetScope*scope,
|
|||
|
||||
expr_width_ = max(tru_wid,fal_wid);
|
||||
|
||||
expr_type = expr_type_;
|
||||
expr_type__ = expr_type_;
|
||||
return expr_width_;
|
||||
}
|
||||
|
||||
|
|
@ -2626,7 +2674,9 @@ NetExpr*PETernary::elaborate_expr(Design*des, NetScope*scope,
|
|||
cerr << get_fileline() << ": debug: "
|
||||
<< "Self-sized ternary chooses wid="<< use_wid
|
||||
<< ", type=" << expr_type()
|
||||
<< ", expr=" << *this
|
||||
<< endl;
|
||||
|
||||
ivl_assert(*this, use_wid > 0);
|
||||
}
|
||||
|
||||
|
|
@ -2711,22 +2761,31 @@ NetExpr*PETernary::elaborate_expr(Design*des, NetScope*scope,
|
|||
|
||||
unsigned PEUnary::test_width(Design*des, NetScope*scope,
|
||||
unsigned min, unsigned lval,
|
||||
ivl_variable_type_t&expr_type,
|
||||
ivl_variable_type_t&expr_type__,
|
||||
bool&unsized_flag)
|
||||
{
|
||||
switch (op_) {
|
||||
case '!':
|
||||
case '&':
|
||||
case '&': // Reduction AND
|
||||
case '|': // Reduction OR
|
||||
case '^': // Reduction XOR
|
||||
case 'A': // Reduction NAND (~&)
|
||||
case 'N': // Reduction NOR (~|)
|
||||
case 'X': // Reduction NXOR (~^)
|
||||
expr_type = IVL_VT_LOGIC;
|
||||
return 1;
|
||||
{
|
||||
ivl_variable_type_t sub_type = IVL_VT_NO_TYPE;
|
||||
bool flag = false;
|
||||
expr_->test_width(des, scope, 0, 0, sub_type, flag);
|
||||
expr_type_ = sub_type;
|
||||
ivl_assert(*expr_, expr_type_ != IVL_VT_NO_TYPE);
|
||||
}
|
||||
expr_width_ = 1;
|
||||
|
||||
expr_type__ = expr_type_;
|
||||
return expr_width_;
|
||||
}
|
||||
|
||||
unsigned test_wid = expr_->test_width(des, scope, min, lval, expr_type, unsized_flag);
|
||||
unsigned test_wid = expr_->test_width(des, scope, min, lval, expr_type__, unsized_flag);
|
||||
switch (op_) {
|
||||
// For these operators, the act of padding to the
|
||||
// minimum width can have an important impact on the
|
||||
|
|
@ -2740,6 +2799,8 @@ unsigned PEUnary::test_width(Design*des, NetScope*scope,
|
|||
break;
|
||||
}
|
||||
|
||||
expr_type_ = expr_type__;
|
||||
expr_width_ = test_wid;
|
||||
return test_wid;
|
||||
}
|
||||
|
||||
|
|
@ -2803,11 +2864,11 @@ NetExpr* PEUnary::elaborate_expr(Design*des, NetScope*scope,
|
|||
tmp->set_line(*this);
|
||||
delete ip;
|
||||
|
||||
} else if (NetECReal*ipc = dynamic_cast<NetECReal*>(ip)) {
|
||||
} else if (NetECReal*ipr = dynamic_cast<NetECReal*>(ip)) {
|
||||
|
||||
/* When taking the - of a real, fold this into the
|
||||
constant value. */
|
||||
verireal val = - ipc->value();
|
||||
verireal val = - ipr->value();
|
||||
tmp = new NetECReal(val);
|
||||
tmp->set_line( *ip );
|
||||
delete ip;
|
||||
|
|
|
|||
54
elab_net.cc
54
elab_net.cc
|
|
@ -251,6 +251,27 @@ bool PEIdent::eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
|
|||
lidx = tmpx;
|
||||
}
|
||||
|
||||
/* Warn about an indexed part select that is out of range. */
|
||||
if (midx >= (long)sig->vector_width() || lidx < 0) {
|
||||
cerr << get_fileline() << ": warning: Indexed part "
|
||||
"select " << sig->name();
|
||||
if (sig->array_dimensions() > 0) {
|
||||
cerr << "[]";
|
||||
}
|
||||
cerr << "[" << midx_val;
|
||||
if (index_tail.sel == index_component_t::SEL_IDX_UP) {
|
||||
cerr << "+:";
|
||||
} else {
|
||||
cerr << "-:";
|
||||
}
|
||||
cerr << wid << "] is out of range." << endl;
|
||||
}
|
||||
|
||||
/* This is completely out side the signal so just skip it. */
|
||||
if (lidx >= (long)sig->vector_width() || midx < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -275,16 +296,24 @@ bool PEIdent::eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
|
|||
des->errors += 1;
|
||||
}
|
||||
|
||||
/* Detect a part select out of range. */
|
||||
/* Warn about a part select that is out of range. */
|
||||
if (midx_tmp >= (long)sig->vector_width() || lidx_tmp < 0) {
|
||||
cerr << get_fileline() << ": warning: Part select "
|
||||
<< sig->name() << "[" << msb << ":"
|
||||
<< lsb << "] out of range." << endl;
|
||||
<< sig->name();
|
||||
if (sig->array_dimensions() > 0) {
|
||||
cerr << "[]";
|
||||
}
|
||||
cerr << "[" << msb << ":" << lsb
|
||||
<< "] is out of range." << endl;
|
||||
#if 0
|
||||
midx_tmp = sig->vector_width() - 1;
|
||||
lidx_tmp = 0;
|
||||
des->errors += 1;
|
||||
#endif
|
||||
}
|
||||
/* This is completely out side the signal so just skip it. */
|
||||
if (lidx_tmp >= (long)sig->vector_width() || midx_tmp < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
midx = midx_tmp;
|
||||
|
|
@ -311,7 +340,7 @@ bool PEIdent::eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
|
|||
midx = sig->sb_to_idx(mval->as_long());
|
||||
if (midx >= (long)sig->vector_width()) {
|
||||
cerr << get_fileline() << ": error: Index " << sig->name()
|
||||
<< "[" << mval->as_long() << "] out of range."
|
||||
<< "[" << mval->as_long() << "] is out of range."
|
||||
<< endl;
|
||||
des->errors += 1;
|
||||
midx = 0;
|
||||
|
|
@ -428,7 +457,14 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
|
|||
long midx_tmp, lidx_tmp;
|
||||
if (! eval_part_select_(des, scope, sig, midx_tmp, lidx_tmp))
|
||||
return 0;
|
||||
ivl_assert(*this, lidx_tmp >= 0);
|
||||
|
||||
if (lidx_tmp < 0) {
|
||||
cerr << get_fileline() << ": sorry: part selects "
|
||||
"straddling the start of signal (" << path_
|
||||
<< ") are not currently supported." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
midx = midx_tmp;
|
||||
lidx = lidx_tmp;
|
||||
}
|
||||
|
|
@ -437,7 +473,13 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
|
|||
if (! eval_part_select_(des, scope, sig, midx_tmp, lidx_tmp))
|
||||
return 0;
|
||||
|
||||
ivl_assert(*this, lidx_tmp >= 0);
|
||||
if (lidx_tmp < 0) {
|
||||
cerr << get_fileline() << ": sorry: part selects "
|
||||
"straddling the start of signal (" << path_
|
||||
<< ") are not currently supported." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
midx = midx_tmp;
|
||||
lidx = lidx_tmp;
|
||||
}
|
||||
|
|
|
|||
52
elaborate.cc
52
elaborate.cc
|
|
@ -1295,7 +1295,25 @@ v NOTE that this also handles the case that the
|
|||
if ((instance.count() == 1)
|
||||
&& (prts_vector_width != sig->vector_width())) {
|
||||
const char *tmp3 = rmod->ports[idx]->name.str();
|
||||
bool as_signed = false;
|
||||
|
||||
if (tmp3 == 0) tmp3 = "???";
|
||||
|
||||
switch (prts[0]->port_type()) {
|
||||
case NetNet::POUTPUT:
|
||||
as_signed = prts[0]->get_signed();
|
||||
break;
|
||||
case NetNet::PINPUT:
|
||||
as_signed = sig->get_signed();
|
||||
break;
|
||||
case NetNet::PINOUT:
|
||||
/* This may not be correct! */
|
||||
as_signed = prts[0]->get_signed() && sig->get_signed();
|
||||
break;
|
||||
default:
|
||||
ivl_assert(*this, 0);
|
||||
}
|
||||
|
||||
cerr << get_fileline() << ": warning: Port " << (idx+1)
|
||||
<< " (" << tmp3 << ") of "
|
||||
<< type_ << " expects " << prts_vector_width <<
|
||||
|
|
@ -1316,21 +1334,21 @@ v NOTE that this also handles the case that the
|
|||
}
|
||||
// Keep the if, but delete the "} else" when fixed.
|
||||
} else if (prts_vector_width > sig->vector_width()) {
|
||||
cerr << get_fileline() << ": : Padding "
|
||||
<< (prts_vector_width-sig->vector_width())
|
||||
cerr << get_fileline() << ": : Padding ";
|
||||
if (as_signed) cerr << "(signed) ";
|
||||
cerr << (prts_vector_width-sig->vector_width())
|
||||
<< " high bits of the port."
|
||||
<< endl;
|
||||
} else {
|
||||
cerr << get_fileline() << ": : Padding "
|
||||
<< (sig->vector_width()-prts_vector_width)
|
||||
cerr << get_fileline() << ": : Padding ";
|
||||
if (as_signed) cerr << "(signed) ";
|
||||
cerr << (sig->vector_width()-prts_vector_width)
|
||||
<< " high bits of the expression."
|
||||
<< endl;
|
||||
}
|
||||
|
||||
sig = resize_net_to_port_(des, scope, sig, prts_vector_width,
|
||||
prts[0]->port_type(),
|
||||
prts[0]->get_signed() &&
|
||||
sig->get_signed());
|
||||
prts[0]->port_type(), as_signed);
|
||||
}
|
||||
|
||||
// Connect the sig expression that is the context of the
|
||||
|
|
@ -2220,6 +2238,16 @@ NetProc* PCondit::elaborate(Design*des, NetScope*scope) const
|
|||
cerr << get_fileline() << ": debug: Elaborate condition statement"
|
||||
<< " with conditional: " << *expr_ << endl;
|
||||
|
||||
// Run a test-width on the condition so that its types are
|
||||
// worked out for elaboration later on.
|
||||
ivl_variable_type_t rtype = IVL_VT_NO_TYPE;
|
||||
bool rflag = false;
|
||||
unsigned expr_wid = expr_->test_width(des, scope, 0, 0, rtype, rflag);
|
||||
if (debug_elaborate)
|
||||
cerr << get_fileline() << ": debug: Test width of condition expression"
|
||||
<< " returns wid=" << expr_wid << ", type=" << rtype
|
||||
<< ", flag=" << rflag << endl;
|
||||
|
||||
// Elaborate and try to evaluate the conditional expression.
|
||||
NetExpr*expr = elab_and_eval(des, scope, expr_, -1);
|
||||
if (expr == 0) {
|
||||
|
|
@ -2232,7 +2260,7 @@ NetProc* PCondit::elaborate(Design*des, NetScope*scope) const
|
|||
// If the condition of the conditional statement is constant,
|
||||
// then look at the value and elaborate either the if statement
|
||||
// or the else statement. I don't need both. If there is no
|
||||
// else_ statement, the use an empty block as a noop.
|
||||
// else_ statement, then use an empty block as a noop.
|
||||
if (NetEConst*ce = dynamic_cast<NetEConst*>(expr)) {
|
||||
verinum val = ce->value();
|
||||
if (debug_elaborate) {
|
||||
|
|
@ -2432,9 +2460,9 @@ NetProc* PCallTask::elaborate_usr(Design*des, NetScope*scope) const
|
|||
|
||||
NetUTask*cur;
|
||||
|
||||
/* Handle tasks with no parameters specially. There is no need
|
||||
to make a sequential block to hold the generated code. */
|
||||
if (nparms() == 0) {
|
||||
/* Handle non-automatic tasks with no parameters specially. There is
|
||||
no need to make a sequential block to hold the generated code. */
|
||||
if ((nparms() == 0) && !task->is_auto()) {
|
||||
cur = new NetUTask(task);
|
||||
cur->set_line(*this);
|
||||
return cur;
|
||||
|
|
@ -2825,7 +2853,7 @@ NetProc* PEventStatement::elaborate_st(Design*des, NetScope*scope,
|
|||
assert(expr_[idx]->expr());
|
||||
|
||||
/* If the expression is an identifier that matches a
|
||||
named event, then handle this case all at once at
|
||||
named event, then handle this case all at once and
|
||||
skip the rest of the expression handling. */
|
||||
|
||||
if (PEIdent*id = dynamic_cast<PEIdent*>(expr_[idx]->expr())) {
|
||||
|
|
|
|||
|
|
@ -254,7 +254,7 @@ NetNet* NetEBComp::synthesize(Design*des, NetScope*scope)
|
|||
//
|
||||
// Note 2: The operand expressions may be signed even if the
|
||||
// sig that comes out of synthesis is unsigned. The $signed()
|
||||
// function markes the expression but doesn't change the
|
||||
// function marks the expression but doesn't change the
|
||||
// underlying signals.
|
||||
bool signed_compare = left_->has_sign() && right_->has_sign();
|
||||
if (debug_elaborate) {
|
||||
|
|
@ -945,7 +945,7 @@ NetNet* NetEUReduce::synthesize(Design*des, NetScope*scope)
|
|||
* for us:
|
||||
*
|
||||
* - Expression elaboration already converted the offset expression into
|
||||
* cannonical form, so we don't have to worry about that here.
|
||||
* canonical form, so we don't have to worry about that here.
|
||||
*/
|
||||
NetNet* NetESelect::synthesize(Design *des, NetScope*scope)
|
||||
{
|
||||
|
|
|
|||
4
parse.y
4
parse.y
|
|
@ -2309,9 +2309,9 @@ generate_case_items
|
|||
;
|
||||
|
||||
generate_case_item
|
||||
: expression ':' { pform_generate_case_item(@1, $1); } generate_block
|
||||
: expression ':' { pform_generate_case_item(@1, $1); } generate_block_opt
|
||||
{ pform_endgenerate(); }
|
||||
| K_default ':' { pform_generate_case_item(@1, 0); } generate_block
|
||||
| K_default ':' { pform_generate_case_item(@1, 0); } generate_block_opt
|
||||
{ pform_endgenerate(); }
|
||||
;
|
||||
|
||||
|
|
|
|||
|
|
@ -257,13 +257,13 @@ void dll_target::expr_const(const NetEConst*net)
|
|||
|
||||
void dll_target::expr_param(const NetEConstParam*net)
|
||||
{
|
||||
ivl_scope_t scope = find_scope(des_, net->scope());
|
||||
ivl_parameter_t par = scope_find_param(scope, net->name());
|
||||
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(scope) << endl;
|
||||
<< ivl_scope_name(scop) << endl;
|
||||
}
|
||||
assert(par);
|
||||
assert(par->value);
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ bool dll_target::process(const NetProcTop*net)
|
|||
|
||||
void dll_target::task_def(const NetScope*net)
|
||||
{
|
||||
ivl_scope_t scope = lookup_scope_(net);
|
||||
ivl_scope_t scop = lookup_scope_(net);
|
||||
const NetTaskDef*def = net->task_def();
|
||||
|
||||
assert(stmt_cur_ == 0);
|
||||
|
|
@ -94,14 +94,14 @@ void dll_target::task_def(const NetScope*net)
|
|||
def->proc()->emit_proc(this);
|
||||
|
||||
assert(stmt_cur_);
|
||||
scope->def = stmt_cur_;
|
||||
scop->def = stmt_cur_;
|
||||
stmt_cur_ = 0;
|
||||
|
||||
}
|
||||
|
||||
bool dll_target::func_def(const NetScope*net)
|
||||
{
|
||||
ivl_scope_t scope = lookup_scope_(net);
|
||||
ivl_scope_t scop = lookup_scope_(net);
|
||||
const NetFuncDef*def = net->func_def();
|
||||
|
||||
assert(stmt_cur_ == 0);
|
||||
|
|
@ -110,14 +110,14 @@ bool dll_target::func_def(const NetScope*net)
|
|||
def->proc()->emit_proc(this);
|
||||
|
||||
assert(stmt_cur_);
|
||||
scope->def = stmt_cur_;
|
||||
scop->def = stmt_cur_;
|
||||
stmt_cur_ = 0;
|
||||
|
||||
scope->ports = def->port_count() + 1;
|
||||
if (scope->ports > 0) {
|
||||
scope->port = new ivl_signal_t[scope->ports];
|
||||
for (unsigned idx = 1 ; idx < scope->ports ; idx += 1)
|
||||
scope->port[idx] = find_signal(des_, def->port(idx-1));
|
||||
scop->ports = def->port_count() + 1;
|
||||
if (scop->ports > 0) {
|
||||
scop->port = new ivl_signal_t[scop->ports];
|
||||
for (unsigned idx = 1 ; idx < scop->ports ; idx += 1)
|
||||
scop->port[idx] = find_signal(des_, def->port(idx-1));
|
||||
}
|
||||
|
||||
/* FIXME: the ivl_target API expects port-0 to be the output
|
||||
|
|
@ -126,7 +126,7 @@ bool dll_target::func_def(const NetScope*net)
|
|||
this, but that will break code generators that use this
|
||||
result. */
|
||||
if (const NetNet*ret_sig = def->return_sig()) {
|
||||
scope->port[0] = find_signal(des_, ret_sig);
|
||||
scop->port[0] = find_signal(des_, ret_sig);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
160
t-dll.cc
160
t-dll.cc
|
|
@ -469,15 +469,15 @@ ivl_parameter_t dll_target::scope_find_param(ivl_scope_t scope,
|
|||
* ivl_parameter_t objects. This involves saving the name and scanning
|
||||
* the expression value.
|
||||
*/
|
||||
void dll_target::make_scope_parameters(ivl_scope_t scope, const NetScope*net)
|
||||
void dll_target::make_scope_parameters(ivl_scope_t scop, const NetScope*net)
|
||||
{
|
||||
scope->nparam_ = net->parameters.size() + net->localparams.size();
|
||||
if (scope->nparam_ == 0) {
|
||||
scope->param_ = 0;
|
||||
scop->nparam_ = net->parameters.size() + net->localparams.size();
|
||||
if (scop->nparam_ == 0) {
|
||||
scop->param_ = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
scope->param_ = new struct ivl_parameter_s [scope->nparam_];
|
||||
scop->param_ = new struct ivl_parameter_s [scop->nparam_];
|
||||
|
||||
unsigned idx = 0;
|
||||
typedef map<perm_string,NetScope::param_expr_t>::const_iterator pit_t;
|
||||
|
|
@ -485,10 +485,10 @@ void dll_target::make_scope_parameters(ivl_scope_t scope, const NetScope*net)
|
|||
for (pit_t cur_pit = net->parameters.begin()
|
||||
; cur_pit != net->parameters.end() ; cur_pit ++) {
|
||||
|
||||
assert(idx < scope->nparam_);
|
||||
ivl_parameter_t cur_par = scope->param_ + idx;
|
||||
assert(idx < scop->nparam_);
|
||||
ivl_parameter_t cur_par = scop->param_ + idx;
|
||||
cur_par->basename = (*cur_pit).first;
|
||||
cur_par->scope = scope;
|
||||
cur_par->scope = scop;
|
||||
cur_par->file = (*cur_pit).second.get_file();
|
||||
cur_par->lineno = (*cur_pit).second.get_lineno();
|
||||
|
||||
|
|
@ -499,10 +499,10 @@ void dll_target::make_scope_parameters(ivl_scope_t scope, const NetScope*net)
|
|||
for (pit_t cur_pit = net->localparams.begin()
|
||||
; cur_pit != net->localparams.end() ; cur_pit ++) {
|
||||
|
||||
assert(idx < scope->nparam_);
|
||||
ivl_parameter_t cur_par = scope->param_ + idx;
|
||||
assert(idx < scop->nparam_);
|
||||
ivl_parameter_t cur_par = scop->param_ + idx;
|
||||
cur_par->basename = (*cur_pit).first;
|
||||
cur_par->scope = scope;
|
||||
cur_par->scope = scop;
|
||||
cur_par->file = (*cur_pit).second.get_file();
|
||||
cur_par->lineno = (*cur_pit).second.get_lineno();
|
||||
|
||||
|
|
@ -530,9 +530,9 @@ void dll_target::make_scope_param_expr(ivl_parameter_t cur_par, NetExpr*etmp)
|
|||
assert(0);
|
||||
}
|
||||
|
||||
} else if (const NetECReal*e = dynamic_cast<const NetECReal*>(etmp)) {
|
||||
} else if (const NetECReal*er = dynamic_cast<const NetECReal*>(etmp)) {
|
||||
|
||||
expr_creal(e);
|
||||
expr_creal(er);
|
||||
assert(expr_);
|
||||
assert(expr_->type_ == IVL_EX_REALNUM);
|
||||
expr_->u_.real_.parameter = cur_par;
|
||||
|
|
@ -550,7 +550,7 @@ void dll_target::make_scope_param_expr(ivl_parameter_t cur_par, NetExpr*etmp)
|
|||
expr_ = 0;
|
||||
}
|
||||
|
||||
void dll_target::add_root(ivl_design_s &des_, const NetScope *s)
|
||||
void dll_target::add_root(ivl_design_s &des__, const NetScope *s)
|
||||
{
|
||||
ivl_scope_t root_ = new struct ivl_scope_s;
|
||||
perm_string name = s->basename();
|
||||
|
|
@ -577,12 +577,12 @@ void dll_target::add_root(ivl_design_s &des_, const NetScope *s)
|
|||
root_->attr = fill_in_attributes(s);
|
||||
root_->is_auto = 0;
|
||||
|
||||
des_.nroots_++;
|
||||
if (des_.roots_)
|
||||
des_.roots_ = (ivl_scope_t *)realloc(des_.roots_, des_.nroots_ * sizeof(ivl_scope_t));
|
||||
des__.nroots_++;
|
||||
if (des__.roots_)
|
||||
des__.roots_ = (ivl_scope_t *)realloc(des__.roots_, des__.nroots_ * sizeof(ivl_scope_t));
|
||||
else
|
||||
des_.roots_ = (ivl_scope_t *)malloc(des_.nroots_ * sizeof(ivl_scope_t));
|
||||
des_.roots_[des_.nroots_ - 1] = root_;
|
||||
des__.roots_ = (ivl_scope_t *)malloc(des__.nroots_ * sizeof(ivl_scope_t));
|
||||
des__.roots_[des__.nroots_ - 1] = root_;
|
||||
}
|
||||
|
||||
bool dll_target::start_design(const Design*des)
|
||||
|
|
@ -615,9 +615,9 @@ bool dll_target::start_design(const Design*des)
|
|||
des_.roots_ = NULL;
|
||||
|
||||
root_scopes = des->find_root_scopes();
|
||||
for (list<NetScope*>::const_iterator scope = root_scopes.begin();
|
||||
scope != root_scopes.end(); scope++)
|
||||
add_root(des_, *scope);
|
||||
for (list<NetScope*>::const_iterator scop = root_scopes.begin();
|
||||
scop != root_scopes.end(); scop++)
|
||||
add_root(des_, *scop);
|
||||
|
||||
des_.consts = (ivl_net_const_t*)
|
||||
malloc(sizeof(ivl_net_const_t));
|
||||
|
|
@ -848,17 +848,17 @@ bool dll_target::bufz(const NetBUFZ*net)
|
|||
/* Attach the logic device to the scope that contains it. */
|
||||
|
||||
assert(net->scope());
|
||||
ivl_scope_t scope = find_scope(des_, net->scope());
|
||||
assert(scope);
|
||||
ivl_scope_t scop = find_scope(des_, net->scope());
|
||||
assert(scop);
|
||||
|
||||
obj->scope_ = scope;
|
||||
obj->scope_ = scop;
|
||||
|
||||
obj->name_ = net->name();
|
||||
logic_attributes(obj, net);
|
||||
|
||||
make_logic_delays_(obj, net);
|
||||
|
||||
scope_add_logic(scope, obj);
|
||||
scope_add_logic(scop, obj);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -867,10 +867,10 @@ void dll_target::event(const NetEvent*net)
|
|||
{
|
||||
struct ivl_event_s *obj = new struct ivl_event_s;
|
||||
|
||||
ivl_scope_t scope = find_scope(des_, net->scope());
|
||||
ivl_scope_t scop = find_scope(des_, net->scope());
|
||||
obj->name = net->name();
|
||||
obj->scope = scope;
|
||||
scope_add_event(scope, obj);
|
||||
obj->scope = scop;
|
||||
scope_add_event(scop, obj);
|
||||
|
||||
obj->nany = 0;
|
||||
obj->nneg = 0;
|
||||
|
|
@ -1029,17 +1029,17 @@ void dll_target::logic(const NetLogic*net)
|
|||
}
|
||||
|
||||
assert(net->scope());
|
||||
ivl_scope_t scope = find_scope(des_, net->scope());
|
||||
assert(scope);
|
||||
ivl_scope_t scop = find_scope(des_, net->scope());
|
||||
assert(scop);
|
||||
|
||||
obj->scope_= scope;
|
||||
obj->scope_= scop;
|
||||
obj->name_ = net->name();
|
||||
|
||||
logic_attributes(obj, net);
|
||||
|
||||
make_logic_delays_(obj, net);
|
||||
|
||||
scope_add_logic(scope, obj);
|
||||
scope_add_logic(scop, obj);
|
||||
}
|
||||
|
||||
bool dll_target::tran(const NetTran*net)
|
||||
|
|
@ -1377,10 +1377,10 @@ void dll_target::udp(const NetUDP*net)
|
|||
}
|
||||
|
||||
assert(net->scope());
|
||||
ivl_scope_t scope = find_scope(des_, net->scope());
|
||||
assert(scope);
|
||||
ivl_scope_t scop = find_scope(des_, net->scope());
|
||||
assert(scop);
|
||||
|
||||
obj->scope_= scope;
|
||||
obj->scope_= scop;
|
||||
obj->name_ = net->name();
|
||||
|
||||
make_logic_delays_(obj, net);
|
||||
|
|
@ -1388,7 +1388,7 @@ void dll_target::udp(const NetUDP*net)
|
|||
obj->nattr = 0;
|
||||
obj->attr = 0;
|
||||
|
||||
scope_add_logic(scope, obj);
|
||||
scope_add_logic(scop, obj);
|
||||
}
|
||||
|
||||
void dll_target::lpm_abs(const NetAbs*net)
|
||||
|
|
@ -2293,81 +2293,81 @@ void dll_target::net_probe(const NetEvProbe*net)
|
|||
|
||||
void dll_target::scope(const NetScope*net)
|
||||
{
|
||||
ivl_scope_t scope;
|
||||
ivl_scope_t scop;
|
||||
|
||||
if (net->parent() == 0) {
|
||||
unsigned i;
|
||||
scope = NULL;
|
||||
for (i = 0; i < des_.nroots_ && scope == NULL; i++) {
|
||||
scop = NULL;
|
||||
for (i = 0; i < des_.nroots_ && scop == NULL; i++) {
|
||||
if (strcmp(des_.roots_[i]->name_, net->basename()) == 0)
|
||||
scope = des_.roots_[i];
|
||||
scop = des_.roots_[i];
|
||||
}
|
||||
assert(scope);
|
||||
assert(scop);
|
||||
|
||||
} else {
|
||||
perm_string sname = make_scope_name(net->fullname());
|
||||
scope = new struct ivl_scope_s;
|
||||
scope->name_ = sname;
|
||||
FILE_NAME(scope, net);
|
||||
scope->child_ = 0;
|
||||
scope->sibling_ = 0;
|
||||
scope->parent = find_scope(des_, net->parent());
|
||||
assert(scope->parent);
|
||||
scope->nsigs_ = 0;
|
||||
scope->sigs_ = 0;
|
||||
scope->nlog_ = 0;
|
||||
scope->log_ = 0;
|
||||
scope->nevent_ = 0;
|
||||
scope->event_ = 0;
|
||||
scope->nlpm_ = 0;
|
||||
scope->lpm_ = 0;
|
||||
scope->def = 0;
|
||||
make_scope_parameters(scope, net);
|
||||
scope->time_precision = net->time_precision();
|
||||
scope->time_units = net->time_unit();
|
||||
scope->nattr = net->attr_cnt();
|
||||
scope->attr = fill_in_attributes(net);
|
||||
scope->is_auto = net->is_auto();
|
||||
scop = new struct ivl_scope_s;
|
||||
scop->name_ = sname;
|
||||
FILE_NAME(scop, net);
|
||||
scop->child_ = 0;
|
||||
scop->sibling_ = 0;
|
||||
scop->parent = find_scope(des_, net->parent());
|
||||
assert(scop->parent);
|
||||
scop->nsigs_ = 0;
|
||||
scop->sigs_ = 0;
|
||||
scop->nlog_ = 0;
|
||||
scop->log_ = 0;
|
||||
scop->nevent_ = 0;
|
||||
scop->event_ = 0;
|
||||
scop->nlpm_ = 0;
|
||||
scop->lpm_ = 0;
|
||||
scop->def = 0;
|
||||
make_scope_parameters(scop, net);
|
||||
scop->time_precision = net->time_precision();
|
||||
scop->time_units = net->time_unit();
|
||||
scop->nattr = net->attr_cnt();
|
||||
scop->attr = fill_in_attributes(net);
|
||||
scop->is_auto = net->is_auto();
|
||||
|
||||
switch (net->type()) {
|
||||
case NetScope::MODULE:
|
||||
scope->type_ = IVL_SCT_MODULE;
|
||||
scope->tname_ = net->module_name();
|
||||
scop->type_ = IVL_SCT_MODULE;
|
||||
scop->tname_ = net->module_name();
|
||||
break;
|
||||
case NetScope::TASK: {
|
||||
const NetTaskDef*def = net->task_def();
|
||||
if (def == 0) {
|
||||
cerr << "?:?" << ": internal error: "
|
||||
<< "task " << scope->name_
|
||||
<< "task " << scop->name_
|
||||
<< " has no definition." << endl;
|
||||
}
|
||||
assert(def);
|
||||
scope->type_ = IVL_SCT_TASK;
|
||||
scope->tname_ = def->scope()->basename();
|
||||
scop->type_ = IVL_SCT_TASK;
|
||||
scop->tname_ = def->scope()->basename();
|
||||
break;
|
||||
}
|
||||
case NetScope::FUNC:
|
||||
scope->type_ = IVL_SCT_FUNCTION;
|
||||
scope->tname_ = net->func_def()->scope()->basename();
|
||||
scop->type_ = IVL_SCT_FUNCTION;
|
||||
scop->tname_ = net->func_def()->scope()->basename();
|
||||
break;
|
||||
case NetScope::BEGIN_END:
|
||||
scope->type_ = IVL_SCT_BEGIN;
|
||||
scope->tname_ = scope->name_;
|
||||
scop->type_ = IVL_SCT_BEGIN;
|
||||
scop->tname_ = scop->name_;
|
||||
break;
|
||||
case NetScope::FORK_JOIN:
|
||||
scope->type_ = IVL_SCT_FORK;
|
||||
scope->tname_ = scope->name_;
|
||||
scop->type_ = IVL_SCT_FORK;
|
||||
scop->tname_ = scop->name_;
|
||||
break;
|
||||
case NetScope::GENBLOCK:
|
||||
scope->type_ = IVL_SCT_GENERATE;
|
||||
scope->tname_ = scope->name_;
|
||||
scop->type_ = IVL_SCT_GENERATE;
|
||||
scop->tname_ = scop->name_;
|
||||
break;
|
||||
}
|
||||
|
||||
assert(scope->parent != 0);
|
||||
assert(scop->parent != 0);
|
||||
|
||||
scope->sibling_= scope->parent->child_;
|
||||
scope->parent->child_ = scope;
|
||||
scop->sibling_= scop->parent->child_;
|
||||
scop->parent->child_ = scop;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -407,8 +407,8 @@ bits.
|
|||
5: (reserved)
|
||||
6: (reserved)
|
||||
|
||||
* %ix/getv <functor-label>, <bit>
|
||||
* %ix/getv/s <functor-label>, <bit>
|
||||
* %ix/getv <idx>, <functor-label>
|
||||
* %ix/getv/s <idx>, <functor-label>
|
||||
|
||||
These instructions are like the %ix/get instructions, except that they
|
||||
read directly from a functor label instead of from thread bits. They
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2001-2007 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2001-2008 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
|
||||
|
|
@ -49,7 +49,7 @@ void resolv_functor::recv_vec4_pv(vvp_net_ptr_t port, const vvp_vector4_t&bit,
|
|||
for (unsigned idx = 0 ; idx < base ; idx += 1)
|
||||
res.set_bit(idx, BIT4_Z);
|
||||
|
||||
for (unsigned idx = 0 ; idx < wid ; idx += 1)
|
||||
for (unsigned idx = 0 ; idx < wid && idx+base < vwid; idx += 1)
|
||||
res.set_bit(idx+base, bit.value(idx));
|
||||
|
||||
for (unsigned idx = base+wid ; idx < vwid ; idx += 1)
|
||||
|
|
@ -106,7 +106,7 @@ void resolv_functor::recv_vec8_pv(vvp_net_ptr_t port, const vvp_vector8_t&bit,
|
|||
for (unsigned idx = 0 ; idx < base ; idx += 1)
|
||||
res.set_bit(idx, vvp_scalar_t());
|
||||
|
||||
for (unsigned idx = 0 ; idx < wid ; idx += 1)
|
||||
for (unsigned idx = 0 ; idx < wid && idx+base < vwid; idx += 1)
|
||||
res.set_bit(idx+base, bit.value(idx));
|
||||
|
||||
for (unsigned idx = base+wid ; idx < vwid ; idx += 1)
|
||||
|
|
|
|||
Loading…
Reference in New Issue