Evaluate VHDL <name>'length attribute at compile time.
This commit is contained in:
parent
677a22d353
commit
873a447b5c
|
|
@ -256,6 +256,17 @@ int ExpArithmetic::elaborate_expr(Entity*ent, Architecture*arc, const VType*ltyp
|
||||||
return errors;
|
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 ExpAttribute::elaborate_expr(Entity*ent, Architecture*arc, const VType*)
|
||||||
{
|
{
|
||||||
int errors = 0;
|
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)
|
int ExpName::elaborate_expr(Entity*, Architecture*, const VType*ltype)
|
||||||
{
|
{
|
||||||
ivl_assert(*this, ltype != 0);
|
ivl_assert(*this, ltype != 0);
|
||||||
|
set_type(ltype);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -148,6 +148,20 @@ int ExpAttribute::emit(ostream&out, Entity*ent, Architecture*arc)
|
||||||
return errors;
|
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(";
|
out << "$ivl_attribute(";
|
||||||
errors += base_->emit(out, ent, arc);
|
errors += base_->emit(out, ent, arc);
|
||||||
out << ", \"" << name_ << "\")";
|
out << ", \"" << name_ << "\")";
|
||||||
|
|
@ -339,9 +353,14 @@ int ExpFunc::emit(ostream&out, Entity*ent, Architecture*arc)
|
||||||
out << "(";
|
out << "(";
|
||||||
errors += argv_[0]->emit(out, ent, arc);
|
errors += argv_[0]->emit(out, ent, arc);
|
||||||
out << ")";
|
out << ")";
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
cerr << get_fileline() << ": sorry: Don't know how to emit function '" << name_ << "'" << endl;
|
out << "\\" << name_ << " (";
|
||||||
errors += 1;
|
for (size_t idx = 0; idx < argv_.size() ; idx += 1) {
|
||||||
|
if (idx > 0) out << ", ";
|
||||||
|
errors += argv_[idx]->emit(out, ent, arc);
|
||||||
|
}
|
||||||
|
out << ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
return errors;
|
return errors;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue