Evaluate VHDL <name>'length attribute at compile time.

This commit is contained in:
Stephen Williams 2011-09-18 17:45:06 -07:00
parent 677a22d353
commit 873a447b5c
2 changed files with 33 additions and 2 deletions

View File

@ -256,6 +256,17 @@ int ExpArithmetic::elaborate_expr(Entity*ent, Architecture*arc, const VType*ltyp
return errors;
}
const VType* ExpAttribute::probe_type(Entity*ent, Architecture*arc) const
{
base_->probe_type(ent, arc);
if (name_ == "length") {
return primitive_INTEGER;
}
return 0;
}
int ExpAttribute::elaborate_expr(Entity*ent, Architecture*arc, const VType*)
{
int errors = 0;
@ -377,6 +388,7 @@ const VType* ExpName::probe_type(Entity*ent, Architecture*arc) const
int ExpName::elaborate_expr(Entity*, Architecture*, const VType*ltype)
{
ivl_assert(*this, ltype != 0);
set_type(ltype);
return 0;
}

View File

@ -148,6 +148,20 @@ int ExpAttribute::emit(ostream&out, Entity*ent, Architecture*arc)
return errors;
}
/* Special Case: The length attribute can be calculated all
the down to a literal integer at compile time, and all it
needs is the type of the base expression. (The base
expression doesn't even need to be evaluated.) */
if (name_ == "length") {
int64_t val;
bool rc = evaluate(arc, val);
out << val;
if (rc)
return errors;
else
return errors + 1;
}
out << "$ivl_attribute(";
errors += base_->emit(out, ent, arc);
out << ", \"" << name_ << "\")";
@ -339,9 +353,14 @@ int ExpFunc::emit(ostream&out, Entity*ent, Architecture*arc)
out << "(";
errors += argv_[0]->emit(out, ent, arc);
out << ")";
} else {
cerr << get_fileline() << ": sorry: Don't know how to emit function '" << name_ << "'" << endl;
errors += 1;
out << "\\" << name_ << " (";
for (size_t idx = 0; idx < argv_.size() ; idx += 1) {
if (idx > 0) out << ", ";
errors += argv_[idx]->emit(out, ent, arc);
}
out << ")";
}
return errors;