From 30ff2aa5d1136201bcebee19ec29f21475a8a334 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Thu, 23 Dec 2021 14:17:13 +0100 Subject: [PATCH] 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 --- eval_attrib.cc | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/eval_attrib.cc b/eval_attrib.cc index 2c0d7b3c7..527df43ad 100644 --- a/eval_attrib.cc +++ b/eval_attrib.cc @@ -21,6 +21,7 @@ # include "util.h" # include "PExpr.h" # include "netlist.h" +# include "netmisc.h" # include # include @@ -52,23 +53,25 @@ attrib_list_t* evaluate_attributes(const map&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(tmp)) { + table[idx].val = ce->value(); + } else if (NetECReal *cer = dynamic_cast(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; + } + delete tmp; + } else { + table[idx].val = verinum(1); + } } assert(idx == natt);