Add support for concatenation operations in constant functions.
Also fix a compiler crash when attempting to evaluate a function which has no valid statement(s) (due to earlier compilation errors).
This commit is contained in:
parent
5abd939655
commit
89244e0f70
24
eval_tree.cc
24
eval_tree.cc
|
|
@ -1090,14 +1090,8 @@ NetEConst* NetEBShift::eval_arguments_(const NetExpr*l, const NetExpr*r) const
|
||||||
|
|
||||||
NetEConst* NetEConcat::eval_tree()
|
NetEConst* NetEConcat::eval_tree()
|
||||||
{
|
{
|
||||||
unsigned repeat_val = repeat();
|
|
||||||
unsigned local_errors = 0;
|
unsigned local_errors = 0;
|
||||||
|
|
||||||
if (debug_eval_tree) {
|
|
||||||
cerr << get_fileline() << ": debug: Evaluating expression:"
|
|
||||||
<< *this << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned gap = 0;
|
unsigned gap = 0;
|
||||||
for (unsigned idx = 0 ; idx < parms_.size() ; idx += 1) {
|
for (unsigned idx = 0 ; idx < parms_.size() ; idx += 1) {
|
||||||
|
|
||||||
|
|
@ -1141,6 +1135,14 @@ NetEConst* NetEConcat::eval_tree()
|
||||||
|
|
||||||
if (local_errors > 0) return 0;
|
if (local_errors > 0) return 0;
|
||||||
|
|
||||||
|
return eval_arguments_(parms_, gap);
|
||||||
|
}
|
||||||
|
|
||||||
|
NetEConst* NetEConcat::eval_arguments_(const vector<NetExpr*>&vals,
|
||||||
|
unsigned gap) const
|
||||||
|
{
|
||||||
|
unsigned repeat_val = repeat();
|
||||||
|
|
||||||
// At this point, the "gap" is the width of a single repeat of
|
// At this point, the "gap" is the width of a single repeat of
|
||||||
// the concatenation. The total width of the result is the gap
|
// the concatenation. The total width of the result is the gap
|
||||||
// times the repeat count.
|
// times the repeat count.
|
||||||
|
|
@ -1150,8 +1152,8 @@ NetEConst* NetEConcat::eval_tree()
|
||||||
|
|
||||||
unsigned cur = 0;
|
unsigned cur = 0;
|
||||||
bool is_string_flag = true;
|
bool is_string_flag = true;
|
||||||
for (unsigned idx = parms_.size() ; idx > 0 ; idx -= 1) {
|
for (unsigned idx = vals.size() ; idx > 0 ; idx -= 1) {
|
||||||
NetEConst*expr = dynamic_cast<NetEConst*>(parms_[idx-1]);
|
const NetEConst*expr = dynamic_cast<NetEConst*>(vals[idx-1]);
|
||||||
if (expr == 0)
|
if (expr == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
@ -1176,6 +1178,12 @@ NetEConst* NetEConcat::eval_tree()
|
||||||
val.has_sign( this->has_sign() );
|
val.has_sign( this->has_sign() );
|
||||||
|
|
||||||
NetEConst*res = new NetEConst(val);
|
NetEConst*res = new NetEConst(val);
|
||||||
|
ivl_assert(*this, res);
|
||||||
|
res->set_line(*this);
|
||||||
|
if (debug_eval_tree) {
|
||||||
|
cerr << get_fileline() << ": debug: Evaluated: "
|
||||||
|
<< *this << " --> " << *res << endl;
|
||||||
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -55,8 +55,10 @@ NetExpr* NetFuncDef::evaluate_function(const LineInfo&loc, const std::vector<Net
|
||||||
// fills in the context_map with local variables held by the scope.
|
// fills in the context_map with local variables held by the scope.
|
||||||
scope_->evaluate_function_find_locals(loc, context_map);
|
scope_->evaluate_function_find_locals(loc, context_map);
|
||||||
|
|
||||||
// Perform the evaluation
|
// Perform the evaluation. Note that if there were errors
|
||||||
bool flag = statement_->evaluate_function(loc, context_map);
|
// when compiling the function definition, we may not have
|
||||||
|
// a valid statement.
|
||||||
|
bool flag = statement_ && statement_->evaluate_function(loc, context_map);
|
||||||
|
|
||||||
// Extract the result...
|
// Extract the result...
|
||||||
ptr = context_map.find(scope_->basename());
|
ptr = context_map.find(scope_->basename());
|
||||||
|
|
@ -295,6 +297,33 @@ NetExpr* NetEBinary::evaluate_function(const LineInfo&loc,
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NetExpr* NetEConcat::evaluate_function(const LineInfo&loc,
|
||||||
|
map<perm_string,NetExpr*>&context_map) const
|
||||||
|
{
|
||||||
|
vector<NetExpr*>vals(parms_.size());
|
||||||
|
unsigned gap = 0;
|
||||||
|
|
||||||
|
unsigned valid_vals = 0;
|
||||||
|
for (unsigned idx = 0 ; idx < parms_.size() ; idx += 1) {
|
||||||
|
ivl_assert(*this, parms_[idx]);
|
||||||
|
vals[idx] = parms_[idx]->evaluate_function(loc, context_map);
|
||||||
|
if (vals[idx] == 0) continue;
|
||||||
|
|
||||||
|
gap += vals[idx]->expr_width();
|
||||||
|
|
||||||
|
valid_vals += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
NetExpr*res = 0;
|
||||||
|
if (valid_vals == parms_.size()) {
|
||||||
|
res = eval_arguments_(vals, gap);
|
||||||
|
}
|
||||||
|
for (unsigned idx = 0 ; idx < vals.size() ; idx += 1) {
|
||||||
|
delete vals[idx];
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
NetExpr* NetEConst::evaluate_function(const LineInfo&,
|
NetExpr* NetEConst::evaluate_function(const LineInfo&,
|
||||||
map<perm_string,NetExpr*>&) const
|
map<perm_string,NetExpr*>&) const
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -3789,6 +3789,8 @@ class NetEConcat : public NetExpr {
|
||||||
virtual bool has_width() const;
|
virtual bool has_width() const;
|
||||||
virtual NetEConcat* dup_expr() const;
|
virtual NetEConcat* dup_expr() const;
|
||||||
virtual NetEConst* eval_tree();
|
virtual NetEConst* eval_tree();
|
||||||
|
virtual NetExpr* evaluate_function(const LineInfo&loc,
|
||||||
|
std::map<perm_string,NetExpr*>&ctx) const;
|
||||||
virtual NetNet*synthesize(Design*, NetScope*scope, NetExpr*root);
|
virtual NetNet*synthesize(Design*, NetScope*scope, NetExpr*root);
|
||||||
virtual void expr_scan(struct expr_scan_t*) const;
|
virtual void expr_scan(struct expr_scan_t*) const;
|
||||||
virtual void dump(ostream&) const;
|
virtual void dump(ostream&) const;
|
||||||
|
|
@ -3797,6 +3799,8 @@ class NetEConcat : public NetExpr {
|
||||||
std::vector<NetExpr*>parms_;
|
std::vector<NetExpr*>parms_;
|
||||||
unsigned repeat_;
|
unsigned repeat_;
|
||||||
ivl_variable_type_t expr_type_;
|
ivl_variable_type_t expr_type_;
|
||||||
|
|
||||||
|
NetEConst* eval_arguments_(const vector<NetExpr*>&vals, unsigned gap) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue