Support full set of constant expressions in attributes

There are currently two different systems to evaluate constant expressions
in iverilog.

The PExpr based system using the eval_const() method and the NetExpr based
system using the eval_tree() method. The latter is more complete while the
former only implements the bare minimum and also has some minor bugs.

The PExpr based system is only used to evaluate expressions within
attributes.

Switch attribute expression evaluation over to elab_and_eval(). This
enables to use the full  set of constant expressions for attributes, maybe
most importantly constant functions and system math functions.

It also allows to remove the PExpr based system since there are no more
users.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
This commit is contained in:
Lars-Peter Clausen 2021-12-23 14:17:13 +01:00
parent 771d02bee1
commit 30ff2aa5d1
1 changed files with 15 additions and 12 deletions

View File

@ -21,6 +21,7 @@
# include "util.h"
# include "PExpr.h"
# include "netlist.h"
# include "netmisc.h"
# include <iostream>
# include <cassert>
@ -52,23 +53,25 @@ attrib_list_t* evaluate_attributes(const map<perm_string,PExpr*>&att,
/* If the attribute value is given in the source, then
evaluate it as a constant. If the value is not
given, then assume the value is 1. */
verinum*tmp = 0;
if (exp) {
tmp = exp->eval_const(des, scope);
if (tmp == 0) {
NetExpr *tmp = elab_and_eval(des, scope, exp, -1, true);
if (!tmp)
continue;
if (NetEConst *ce = dynamic_cast<NetEConst*>(tmp)) {
table[idx].val = ce->value();
} else if (NetECReal *cer = dynamic_cast<NetECReal*>(tmp)) {
table[idx].val = verinum(cer->value().as_long());
} else {
cerr << exp->get_fileline() << ": error: ``"
<< *exp << "'' is not a constant expression."
<< endl;
des->errors += 1;
}
}
if (tmp == 0)
tmp = new verinum(1);
assert(tmp);
table[idx].val = *tmp;
delete tmp;
} else {
table[idx].val = verinum(1);
}
}
assert(idx == natt);