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()
|
||||
{
|
||||
unsigned repeat_val = repeat();
|
||||
unsigned local_errors = 0;
|
||||
|
||||
if (debug_eval_tree) {
|
||||
cerr << get_fileline() << ": debug: Evaluating expression:"
|
||||
<< *this << endl;
|
||||
}
|
||||
|
||||
unsigned gap = 0;
|
||||
for (unsigned idx = 0 ; idx < parms_.size() ; idx += 1) {
|
||||
|
||||
|
|
@ -1141,6 +1135,14 @@ NetEConst* NetEConcat::eval_tree()
|
|||
|
||||
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
|
||||
// the concatenation. The total width of the result is the gap
|
||||
// times the repeat count.
|
||||
|
|
@ -1150,8 +1152,8 @@ NetEConst* NetEConcat::eval_tree()
|
|||
|
||||
unsigned cur = 0;
|
||||
bool is_string_flag = true;
|
||||
for (unsigned idx = parms_.size() ; idx > 0 ; idx -= 1) {
|
||||
NetEConst*expr = dynamic_cast<NetEConst*>(parms_[idx-1]);
|
||||
for (unsigned idx = vals.size() ; idx > 0 ; idx -= 1) {
|
||||
const NetEConst*expr = dynamic_cast<NetEConst*>(vals[idx-1]);
|
||||
if (expr == 0)
|
||||
return 0;
|
||||
|
||||
|
|
@ -1176,6 +1178,12 @@ NetEConst* NetEConcat::eval_tree()
|
|||
val.has_sign( this->has_sign() );
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
scope_->evaluate_function_find_locals(loc, context_map);
|
||||
|
||||
// Perform the evaluation
|
||||
bool flag = statement_->evaluate_function(loc, context_map);
|
||||
// Perform the evaluation. Note that if there were errors
|
||||
// when compiling the function definition, we may not have
|
||||
// a valid statement.
|
||||
bool flag = statement_ && statement_->evaluate_function(loc, context_map);
|
||||
|
||||
// Extract the result...
|
||||
ptr = context_map.find(scope_->basename());
|
||||
|
|
@ -295,6 +297,33 @@ NetExpr* NetEBinary::evaluate_function(const LineInfo&loc,
|
|||
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&,
|
||||
map<perm_string,NetExpr*>&) const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -3789,6 +3789,8 @@ class NetEConcat : public NetExpr {
|
|||
virtual bool has_width() const;
|
||||
virtual NetEConcat* dup_expr() const;
|
||||
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 void expr_scan(struct expr_scan_t*) const;
|
||||
virtual void dump(ostream&) const;
|
||||
|
|
@ -3797,6 +3799,8 @@ class NetEConcat : public NetExpr {
|
|||
std::vector<NetExpr*>parms_;
|
||||
unsigned repeat_;
|
||||
ivl_variable_type_t expr_type_;
|
||||
|
||||
NetEConst* eval_arguments_(const vector<NetExpr*>&vals, unsigned gap) const;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue