Add better constant user functions are not supported messages.
This patch adds messages in various places to warn that constant user functions are not supported. It uses a global variable to indicate when we are in a constant context. This is a bit of a kludge, but works well without needing to change a bunch of code. It is interesting to note that ports are elaborated late enough that if we had the constant function evaluation code they would evaluate correctly. This also applies to the function return range, the concatenation repeat, specparams and initial values. Signal definitions are early enough that elaboration is what is failing because the function body is not available (has not been elaborated). The same thing applies to both parameters and localparms.
This commit is contained in:
parent
82805b9351
commit
d143597996
16
elab_expr.cc
16
elab_expr.cc
|
|
@ -1462,8 +1462,16 @@ NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope,
|
||||||
if (access_nature)
|
if (access_nature)
|
||||||
return elaborate_access_func_(des, scope, access_nature);
|
return elaborate_access_func_(des, scope, access_nature);
|
||||||
|
|
||||||
cerr << get_fileline() << ": error: No function " << path_ <<
|
// We do not currently support constant user function and
|
||||||
" in this context (" << scope_path(scope) << ")." << endl;
|
// this is where things fail because of that, though we
|
||||||
|
// don't know for sure so we need to display both messages.
|
||||||
|
if (need_constant_expr) {
|
||||||
|
cerr << get_fileline() << ": sorry: constant user "
|
||||||
|
"functions are not currently supported: "
|
||||||
|
<< path_ << "()." << endl << " or" << endl;
|
||||||
|
}
|
||||||
|
cerr << get_fileline() << ": error: No function " << path_
|
||||||
|
<< " in this context (" << scope_path(scope) << ")." << endl;
|
||||||
des->errors += 1;
|
des->errors += 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -1611,13 +1619,17 @@ NetExpr* PEConcat::elaborate_expr(Design*des, NetScope*scope,
|
||||||
if (repeat_expr_ == 0) {
|
if (repeat_expr_ == 0) {
|
||||||
// If the expression has not yet been elaborated,
|
// If the expression has not yet been elaborated,
|
||||||
// then try now.
|
// then try now.
|
||||||
|
need_constant_expr = true;
|
||||||
tmp = elab_and_eval(des, scope, repeat_, -1);
|
tmp = elab_and_eval(des, scope, repeat_, -1);
|
||||||
|
need_constant_expr = false;
|
||||||
assert(tmp);
|
assert(tmp);
|
||||||
} else {
|
} else {
|
||||||
// If it has been elaborated, make sure it is
|
// If it has been elaborated, make sure it is
|
||||||
// fully evaluated.
|
// fully evaluated.
|
||||||
tmp = repeat_expr_;
|
tmp = repeat_expr_;
|
||||||
|
need_constant_expr = true;
|
||||||
eval_expr(tmp);
|
eval_expr(tmp);
|
||||||
|
need_constant_expr = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tmp->expr_type() == IVL_VT_REAL) {
|
if (tmp->expr_type() == IVL_VT_REAL) {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2000-2008 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 2000-2009 Stephen Williams (steve@icarus.com)
|
||||||
*
|
*
|
||||||
* This source code is free software; you can redistribute it
|
* This source code is free software; you can redistribute it
|
||||||
* and/or modify it in source code form under the terms of the GNU
|
* and/or modify it in source code form under the terms of the GNU
|
||||||
|
|
@ -438,15 +438,15 @@ NetExpr* PECallFunction::elaborate_pexpr(Design*des, NetScope*scope) const
|
||||||
return rtn;
|
return rtn;
|
||||||
}
|
}
|
||||||
|
|
||||||
cerr << get_fileline() << ": error: this is not a constant "
|
cerr << get_fileline() << ": error: " << nm << "() is not a "
|
||||||
"system function (" << *this << ")." << endl;
|
"constant system function." << endl;
|
||||||
des->errors += 1;
|
des->errors += 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Constant user function code goes here. */
|
/* Constant user function code goes here. */
|
||||||
cerr << get_fileline() << ": sorry: constant user functions are not "
|
cerr << get_fileline() << ": sorry: constant user functions are not "
|
||||||
"currently supported." << endl;
|
"currently supported: " << nm << "()." << endl;
|
||||||
des->errors += 1;
|
des->errors += 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
26
elab_sig.cc
26
elab_sig.cc
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2000-2008 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 2000-2009 Stephen Williams (steve@icarus.com)
|
||||||
*
|
*
|
||||||
* This source code is free software; you can redistribute it
|
* This source code is free software; you can redistribute it
|
||||||
* and/or modify it in source code form under the terms of the GNU
|
* and/or modify it in source code form under the terms of the GNU
|
||||||
|
|
@ -35,6 +35,14 @@
|
||||||
# include "util.h"
|
# include "util.h"
|
||||||
# include "ivl_assert.h"
|
# include "ivl_assert.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set the following to true when you need to process an expression
|
||||||
|
* that is being done in a constant context. This allows the
|
||||||
|
* elaboration to explicitly say we do not currently support constant
|
||||||
|
* user functions when the function is not found.
|
||||||
|
*/
|
||||||
|
bool need_constant_expr = false;
|
||||||
|
|
||||||
static bool get_const_argument(NetExpr*exp, verinum&res)
|
static bool get_const_argument(NetExpr*exp, verinum&res)
|
||||||
{
|
{
|
||||||
switch (exp->expr_type()) {
|
switch (exp->expr_type()) {
|
||||||
|
|
@ -562,12 +570,14 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const
|
||||||
probe_expr_width(des, scope, (*return_type_.range)[0]);
|
probe_expr_width(des, scope, (*return_type_.range)[0]);
|
||||||
probe_expr_width(des, scope, (*return_type_.range)[1]);
|
probe_expr_width(des, scope, (*return_type_.range)[1]);
|
||||||
|
|
||||||
|
need_constant_expr = true;
|
||||||
NetExpr*me = elab_and_eval(des, scope,
|
NetExpr*me = elab_and_eval(des, scope,
|
||||||
(*return_type_.range)[0], -1);
|
(*return_type_.range)[0], -1);
|
||||||
assert(me);
|
assert(me);
|
||||||
NetExpr*le = elab_and_eval(des, scope,
|
NetExpr*le = elab_and_eval(des, scope,
|
||||||
(*return_type_.range)[1], -1);
|
(*return_type_.range)[1], -1);
|
||||||
assert(le);
|
assert(le);
|
||||||
|
need_constant_expr = false;
|
||||||
|
|
||||||
long mnum = 0, lnum = 0;
|
long mnum = 0, lnum = 0;
|
||||||
if (NetEConst*tmp = dynamic_cast<NetEConst*>(me)) {
|
if (NetEConst*tmp = dynamic_cast<NetEConst*>(me)) {
|
||||||
|
|
@ -856,7 +866,10 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||||
/* If they exist get the port definition MSB and LSB */
|
/* If they exist get the port definition MSB and LSB */
|
||||||
if (port_set_ && port_msb_ != 0) {
|
if (port_set_ && port_msb_ != 0) {
|
||||||
probe_expr_width(des, scope, port_msb_);
|
probe_expr_width(des, scope, port_msb_);
|
||||||
|
/* We do not currently support constant user function. */
|
||||||
|
need_constant_expr = true;
|
||||||
NetExpr*texpr = elab_and_eval(des, scope, port_msb_, -1);
|
NetExpr*texpr = elab_and_eval(des, scope, port_msb_, -1);
|
||||||
|
need_constant_expr = false;
|
||||||
|
|
||||||
if (! eval_as_long(pmsb, texpr)) {
|
if (! eval_as_long(pmsb, texpr)) {
|
||||||
cerr << port_msb_->get_fileline() << ": error: "
|
cerr << port_msb_->get_fileline() << ": error: "
|
||||||
|
|
@ -871,7 +884,10 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||||
delete texpr;
|
delete texpr;
|
||||||
|
|
||||||
probe_expr_width(des, scope, port_lsb_);
|
probe_expr_width(des, scope, port_lsb_);
|
||||||
|
/* We do not currently support constant user function. */
|
||||||
|
need_constant_expr = true;
|
||||||
texpr = elab_and_eval(des, scope, port_lsb_, -1);
|
texpr = elab_and_eval(des, scope, port_lsb_, -1);
|
||||||
|
need_constant_expr = false;
|
||||||
|
|
||||||
if (! eval_as_long(plsb, texpr)) {
|
if (! eval_as_long(plsb, texpr)) {
|
||||||
cerr << port_lsb_->get_fileline() << ": error: "
|
cerr << port_lsb_->get_fileline() << ": error: "
|
||||||
|
|
@ -894,7 +910,10 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||||
/* If they exist get the net/etc. definition MSB and LSB */
|
/* If they exist get the net/etc. definition MSB and LSB */
|
||||||
if (net_set_ && net_msb_ != 0 && !bad_msb && !bad_lsb) {
|
if (net_set_ && net_msb_ != 0 && !bad_msb && !bad_lsb) {
|
||||||
probe_expr_width(des, scope, net_msb_);
|
probe_expr_width(des, scope, net_msb_);
|
||||||
|
/* We do not currently support constant user function. */
|
||||||
|
need_constant_expr = true;
|
||||||
NetExpr*texpr = elab_and_eval(des, scope, net_msb_, -1);
|
NetExpr*texpr = elab_and_eval(des, scope, net_msb_, -1);
|
||||||
|
need_constant_expr = false;
|
||||||
|
|
||||||
if (! eval_as_long(nmsb, texpr)) {
|
if (! eval_as_long(nmsb, texpr)) {
|
||||||
cerr << net_msb_->get_fileline() << ": error: "
|
cerr << net_msb_->get_fileline() << ": error: "
|
||||||
|
|
@ -909,7 +928,10 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||||
delete texpr;
|
delete texpr;
|
||||||
|
|
||||||
probe_expr_width(des, scope, net_lsb_);
|
probe_expr_width(des, scope, net_lsb_);
|
||||||
|
/* We do not currently support constant user function. */
|
||||||
|
need_constant_expr = true;
|
||||||
texpr = elab_and_eval(des, scope, net_lsb_, -1);
|
texpr = elab_and_eval(des, scope, net_lsb_, -1);
|
||||||
|
need_constant_expr = false;
|
||||||
|
|
||||||
if (! eval_as_long(nlsb, texpr)) {
|
if (! eval_as_long(nlsb, texpr)) {
|
||||||
cerr << net_lsb_->get_fileline() << ": error: "
|
cerr << net_lsb_->get_fileline() << ": error: "
|
||||||
|
|
@ -1003,8 +1025,10 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||||
probe_expr_width(des, scope, lidx_);
|
probe_expr_width(des, scope, lidx_);
|
||||||
probe_expr_width(des, scope, ridx_);
|
probe_expr_width(des, scope, ridx_);
|
||||||
|
|
||||||
|
need_constant_expr = true;
|
||||||
NetExpr*lexp = elab_and_eval(des, scope, lidx_, -1);
|
NetExpr*lexp = elab_and_eval(des, scope, lidx_, -1);
|
||||||
NetExpr*rexp = elab_and_eval(des, scope, ridx_, -1);
|
NetExpr*rexp = elab_and_eval(des, scope, ridx_, -1);
|
||||||
|
need_constant_expr = false;
|
||||||
|
|
||||||
if ((lexp == 0) || (rexp == 0)) {
|
if ((lexp == 0) || (rexp == 0)) {
|
||||||
cerr << get_fileline() << ": internal error: There is "
|
cerr << get_fileline() << ": internal error: There is "
|
||||||
|
|
|
||||||
|
|
@ -1787,7 +1787,9 @@ NetExpr* PAssign_::elaborate_rval_(Design*des, NetScope*scope,
|
||||||
{
|
{
|
||||||
ivl_assert(*this, rval_);
|
ivl_assert(*this, rval_);
|
||||||
|
|
||||||
|
need_constant_expr = is_constant_;
|
||||||
NetExpr*rv = elaborate_rval_expr(des, scope, lv_type, lv_width, rval());
|
NetExpr*rv = elaborate_rval_expr(des, scope, lv_type, lv_width, rval());
|
||||||
|
need_constant_expr = false;
|
||||||
|
|
||||||
if (!is_constant_ || !rv) return rv;
|
if (!is_constant_ || !rv) return rv;
|
||||||
|
|
||||||
|
|
@ -3925,7 +3927,9 @@ bool Module::elaborate(Design*des, NetScope*scope) const
|
||||||
for (specparam_it_t cur = specparams.begin()
|
for (specparam_it_t cur = specparams.begin()
|
||||||
; cur != specparams.end() ; cur ++ ) {
|
; cur != specparams.end() ; cur ++ ) {
|
||||||
|
|
||||||
|
need_constant_expr = true;
|
||||||
NetExpr*val = elab_and_eval(des, scope, (*cur).second, -1);
|
NetExpr*val = elab_and_eval(des, scope, (*cur).second, -1);
|
||||||
|
need_constant_expr = false;
|
||||||
NetScope::spec_val_t value;
|
NetScope::spec_val_t value;
|
||||||
|
|
||||||
if (NetECReal*val_cr = dynamic_cast<NetECReal*> (val)) {
|
if (NetECReal*val_cr = dynamic_cast<NetECReal*> (val)) {
|
||||||
|
|
|
||||||
12
eval_tree.cc
12
eval_tree.cc
|
|
@ -1973,3 +1973,15 @@ NetExpr* NetESFunc::eval_tree(int prune_to_width)
|
||||||
|
|
||||||
return rtn;
|
return rtn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NetExpr* NetEUFunc::eval_tree(int prune_to_width)
|
||||||
|
{
|
||||||
|
if (need_constant_expr) {
|
||||||
|
cerr << get_fileline() << ": sorry: constant user "
|
||||||
|
"functions are not currently supported: "
|
||||||
|
<< func_->basename() << "()." << endl;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -3014,6 +3014,7 @@ class NetEUFunc : public NetExpr {
|
||||||
virtual void expr_scan(struct expr_scan_t*) const;
|
virtual void expr_scan(struct expr_scan_t*) const;
|
||||||
virtual NetEUFunc*dup_expr() const;
|
virtual NetEUFunc*dup_expr() const;
|
||||||
virtual NexusSet* nex_input(bool rem_out = true);
|
virtual NexusSet* nex_input(bool rem_out = true);
|
||||||
|
virtual NetExpr* eval_tree(int prune_to_width = -1);
|
||||||
virtual NetNet* synthesize(Design*des, NetScope*scope, NetExpr*root);
|
virtual NetNet* synthesize(Design*des, NetScope*scope, NetExpr*root);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
||||||
|
|
@ -318,7 +318,7 @@ bool eval_as_long(long&value, NetExpr*expr)
|
||||||
bool eval_as_double(double&value, NetExpr*expr)
|
bool eval_as_double(double&value, NetExpr*expr)
|
||||||
{
|
{
|
||||||
if (NetEConst*tmp = dynamic_cast<NetEConst*>(expr) ) {
|
if (NetEConst*tmp = dynamic_cast<NetEConst*>(expr) ) {
|
||||||
value = tmp->value().as_long();
|
value = tmp->value().as_double();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -134,6 +134,12 @@ extern NetNet* make_const_x(Design*des, NetScope*scope, unsigned long wid);
|
||||||
*/
|
*/
|
||||||
extern unsigned count_lval_width(const class NetAssign_*first);
|
extern unsigned count_lval_width(const class NetAssign_*first);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is temporarily used to indicate that a user function elaboration
|
||||||
|
* fail is likely the result of missing constant user function support.
|
||||||
|
*/
|
||||||
|
extern bool need_constant_expr;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function elaborates an expression, and tries to evaluate it
|
* This function elaborates an expression, and tries to evaluate it
|
||||||
* right away. If the expression can be evaluated, this returns a
|
* right away. If the expression can be evaluated, this returns a
|
||||||
|
|
@ -150,6 +156,7 @@ extern unsigned count_lval_width(const class NetAssign_*first);
|
||||||
* bound to the destination.
|
* bound to the destination.
|
||||||
*/
|
*/
|
||||||
class PExpr;
|
class PExpr;
|
||||||
|
|
||||||
extern NetExpr* elab_and_eval(Design*des, NetScope*scope,
|
extern NetExpr* elab_and_eval(Design*des, NetScope*scope,
|
||||||
const PExpr*pe, int expr_wid,
|
const PExpr*pe, int expr_wid,
|
||||||
int prune_width =-1);
|
int prune_width =-1);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue