Remove eval_const()
There are no more users of the eval_const() system. Lets remove it. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
This commit is contained in:
parent
30ff2aa5d1
commit
497c98bf9b
|
|
@ -106,7 +106,7 @@ FF = cprop.o exposenodes.o nodangle.o synth.o synth2.o syn-rules.o
|
||||||
O = main.o async.o design_dump.o discipline.o dup_expr.o elaborate.o \
|
O = main.o async.o design_dump.o discipline.o dup_expr.o elaborate.o \
|
||||||
elab_expr.o elaborate_analog.o elab_lval.o elab_net.o \
|
elab_expr.o elaborate_analog.o elab_lval.o elab_net.o \
|
||||||
elab_scope.o elab_sig.o elab_sig_analog.o elab_type.o \
|
elab_scope.o elab_sig.o elab_sig_analog.o elab_type.o \
|
||||||
emit.o eval.o eval_attrib.o \
|
emit.o eval_attrib.o \
|
||||||
eval_tree.o expr_synth.o functor.o lexor.o lexor_keyword.o link_const.o \
|
eval_tree.o expr_synth.o functor.o lexor.o lexor_keyword.o link_const.o \
|
||||||
load_module.o netlist.o netmisc.o nettypes.o net_analog.o net_assign.o \
|
load_module.o netlist.o netmisc.o nettypes.o net_analog.o net_assign.o \
|
||||||
net_design.o netclass.o netdarray.o \
|
net_design.o netclass.o netdarray.o \
|
||||||
|
|
|
||||||
19
PExpr.h
19
PExpr.h
|
|
@ -173,11 +173,6 @@ class PExpr : public LineInfo {
|
||||||
bool is_cassign,
|
bool is_cassign,
|
||||||
bool is_force) const;
|
bool is_force) const;
|
||||||
|
|
||||||
// This attempts to evaluate a constant expression, and return
|
|
||||||
// a verinum as a result. If the expression cannot be
|
|
||||||
// evaluated, return 0.
|
|
||||||
virtual verinum* eval_const(Design*des, NetScope*sc) const;
|
|
||||||
|
|
||||||
// This method returns true if the expression represents a
|
// This method returns true if the expression represents a
|
||||||
// structural net that can have multiple drivers. This is
|
// structural net that can have multiple drivers. This is
|
||||||
// used to test whether an input port connection can be
|
// used to test whether an input port connection can be
|
||||||
|
|
@ -235,7 +230,6 @@ class PEConcat : public PExpr {
|
||||||
explicit PEConcat(const std::list<PExpr*>&p, PExpr*r =0);
|
explicit PEConcat(const std::list<PExpr*>&p, PExpr*r =0);
|
||||||
~PEConcat();
|
~PEConcat();
|
||||||
|
|
||||||
virtual verinum* eval_const(Design*des, NetScope*sc) const;
|
|
||||||
virtual void dump(std::ostream&) const;
|
virtual void dump(std::ostream&) const;
|
||||||
|
|
||||||
virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type);
|
virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type);
|
||||||
|
|
@ -312,11 +306,6 @@ class PEFNumber : public PExpr {
|
||||||
|
|
||||||
const verireal& value() const;
|
const verireal& value() const;
|
||||||
|
|
||||||
/* The eval_const method as applied to a floating point number
|
|
||||||
gets the *integer* value of the number. This accounts for
|
|
||||||
any rounding that is needed to get the value. */
|
|
||||||
virtual verinum* eval_const(Design*des, NetScope*sc) const;
|
|
||||||
|
|
||||||
virtual unsigned test_width(Design*des, NetScope*scope,
|
virtual unsigned test_width(Design*des, NetScope*scope,
|
||||||
width_mode_t&mode);
|
width_mode_t&mode);
|
||||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
|
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
|
||||||
|
|
@ -378,8 +367,6 @@ class PEIdent : public PExpr {
|
||||||
// expressions can can be unpacked arrays.
|
// expressions can can be unpacked arrays.
|
||||||
NetNet* elaborate_unpacked_net(Design*des, NetScope*sc) const;
|
NetNet* elaborate_unpacked_net(Design*des, NetScope*sc) const;
|
||||||
|
|
||||||
verinum* eval_const(Design*des, NetScope*sc) const;
|
|
||||||
|
|
||||||
virtual bool is_collapsible_net(Design*des, NetScope*scope,
|
virtual bool is_collapsible_net(Design*des, NetScope*scope,
|
||||||
NetNet::PortType port_type) const;
|
NetNet::PortType port_type) const;
|
||||||
|
|
||||||
|
|
@ -635,8 +622,6 @@ class PENumber : public PExpr {
|
||||||
bool is_cassign,
|
bool is_cassign,
|
||||||
bool is_force) const;
|
bool is_force) const;
|
||||||
|
|
||||||
virtual verinum* eval_const(Design*des, NetScope*sc) const;
|
|
||||||
|
|
||||||
virtual bool is_the_same(const PExpr*that) const;
|
virtual bool is_the_same(const PExpr*that) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
@ -667,7 +652,6 @@ class PEString : public PExpr {
|
||||||
|
|
||||||
virtual NetEConst*elaborate_expr(Design*des, NetScope*,
|
virtual NetEConst*elaborate_expr(Design*des, NetScope*,
|
||||||
unsigned expr_wid, unsigned) const;
|
unsigned expr_wid, unsigned) const;
|
||||||
verinum* eval_const(Design*, NetScope*) const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
char*text_;
|
char*text_;
|
||||||
|
|
@ -708,7 +692,6 @@ class PEUnary : public PExpr {
|
||||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
|
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
|
||||||
unsigned expr_wid,
|
unsigned expr_wid,
|
||||||
unsigned flags) const;
|
unsigned flags) const;
|
||||||
virtual verinum* eval_const(Design*des, NetScope*sc) const;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
inline char get_op() const { return op_; }
|
inline char get_op() const { return op_; }
|
||||||
|
|
@ -740,7 +723,6 @@ class PEBinary : public PExpr {
|
||||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
|
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
|
||||||
unsigned expr_wid,
|
unsigned expr_wid,
|
||||||
unsigned flags) const;
|
unsigned flags) const;
|
||||||
virtual verinum* eval_const(Design*des, NetScope*sc) const;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
char op_;
|
char op_;
|
||||||
|
|
@ -865,7 +847,6 @@ class PETernary : public PExpr {
|
||||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
|
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
|
||||||
unsigned expr_wid,
|
unsigned expr_wid,
|
||||||
unsigned flags) const;
|
unsigned flags) const;
|
||||||
virtual verinum* eval_const(Design*des, NetScope*sc) const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
NetExpr* elab_and_eval_alternative_(Design*des, NetScope*scope,
|
NetExpr* elab_and_eval_alternative_(Design*des, NetScope*scope,
|
||||||
|
|
|
||||||
282
eval.cc
282
eval.cc
|
|
@ -1,282 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 1998-2021 Stephen Williams (steve@icarus.com)
|
|
||||||
*
|
|
||||||
* This source code is free software; you can redistribute it
|
|
||||||
* and/or modify it in source code form under the terms of the GNU
|
|
||||||
* General Public License as published by the Free Software
|
|
||||||
* Foundation; either version 2 of the License, or (at your option)
|
|
||||||
* any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
# include "config.h"
|
|
||||||
|
|
||||||
# include <cstring>
|
|
||||||
# include <iostream>
|
|
||||||
|
|
||||||
# include "PExpr.h"
|
|
||||||
# include "netlist.h"
|
|
||||||
# include "netmisc.h"
|
|
||||||
# include "compiler.h"
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
verinum* PExpr::eval_const(Design*, NetScope*) const
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
verinum* PEBinary::eval_const(Design*des, NetScope*scope) const
|
|
||||||
{
|
|
||||||
verinum*l = left_->eval_const(des, scope);
|
|
||||||
if (l == 0) return 0;
|
|
||||||
verinum*r = right_->eval_const(des, scope);
|
|
||||||
if (r == 0) {
|
|
||||||
delete l;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
verinum*res;
|
|
||||||
|
|
||||||
switch (op_) {
|
|
||||||
case 'p': {
|
|
||||||
if (l->is_defined() && r->is_defined()) {
|
|
||||||
res = new verinum(pow(*l, *r));
|
|
||||||
} else {
|
|
||||||
res = new verinum(verinum::Vx, l->len());
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case '+': {
|
|
||||||
if (l->is_defined() && r->is_defined()) {
|
|
||||||
res = new verinum(*l + *r);
|
|
||||||
} else {
|
|
||||||
res = new verinum(verinum::Vx, l->len());
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case '-': {
|
|
||||||
if (l->is_defined() && r->is_defined()) {
|
|
||||||
res = new verinum(*l - *r);
|
|
||||||
} else {
|
|
||||||
res = new verinum(verinum::Vx, l->len());
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case '*': {
|
|
||||||
if (l->is_defined() && r->is_defined()) {
|
|
||||||
res = new verinum(*l * *r);
|
|
||||||
} else {
|
|
||||||
res = new verinum(verinum::Vx, l->len());
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case '/': {
|
|
||||||
if (l->is_defined() && r->is_defined()) {
|
|
||||||
long lv = l->as_long();
|
|
||||||
long rv = r->as_long();
|
|
||||||
res = new verinum(lv / rv, l->len());
|
|
||||||
} else {
|
|
||||||
res = new verinum(verinum::Vx, l->len());
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case '%': {
|
|
||||||
if (l->is_defined() && r->is_defined()) {
|
|
||||||
long lv = l->as_long();
|
|
||||||
long rv = r->as_long();
|
|
||||||
res = new verinum(lv % rv, l->len());
|
|
||||||
} else {
|
|
||||||
res = new verinum(verinum::Vx, l->len());
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case '>': {
|
|
||||||
if (l->is_defined() && r->is_defined()) {
|
|
||||||
long lv = l->as_long();
|
|
||||||
long rv = r->as_long();
|
|
||||||
res = new verinum(lv > rv, l->len());
|
|
||||||
} else {
|
|
||||||
res = new verinum(verinum::Vx, l->len());
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case '<': {
|
|
||||||
if (l->is_defined() && r->is_defined()) {
|
|
||||||
long lv = l->as_long();
|
|
||||||
long rv = r->as_long();
|
|
||||||
res = new verinum(lv < rv, l->len());
|
|
||||||
} else {
|
|
||||||
res = new verinum(verinum::Vx, l->len());
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'l': { // left shift (<<)
|
|
||||||
assert(r->is_defined());
|
|
||||||
unsigned long rv = r->as_ulong();
|
|
||||||
res = new verinum(verinum::V0, l->len());
|
|
||||||
if (rv < res->len()) {
|
|
||||||
unsigned cnt = res->len() - rv;
|
|
||||||
for (unsigned idx = 0 ; idx < cnt ; idx += 1)
|
|
||||||
res->set(idx+rv, l->get(idx));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'r': { // right shift (>>)
|
|
||||||
assert(r->is_defined());
|
|
||||||
unsigned long rv = r->as_ulong();
|
|
||||||
res = new verinum(verinum::V0, l->len());
|
|
||||||
if (rv < res->len()) {
|
|
||||||
unsigned cnt = res->len() - rv;
|
|
||||||
for (unsigned idx = 0 ; idx < cnt ; idx += 1)
|
|
||||||
res->set(idx, l->get(idx+rv));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
delete l;
|
|
||||||
delete r;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
delete l;
|
|
||||||
delete r;
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
verinum* PEConcat::eval_const(Design*des, NetScope*scope) const
|
|
||||||
{
|
|
||||||
verinum*accum = parms_[0]->eval_const(des, scope);
|
|
||||||
if (accum == 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
for (unsigned idx = 1 ; idx < parms_.size() ; idx += 1) {
|
|
||||||
|
|
||||||
verinum*tmp = parms_[idx]->eval_const(des, scope);
|
|
||||||
if (tmp == 0) {
|
|
||||||
delete accum;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
assert(tmp);
|
|
||||||
|
|
||||||
*accum = concat(*accum, *tmp);
|
|
||||||
delete tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
return accum;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Evaluate an identifier as a constant expression. This is only
|
|
||||||
* possible if the identifier is that of a parameter.
|
|
||||||
*/
|
|
||||||
verinum* PEIdent::eval_const(Design*des, NetScope*scope) const
|
|
||||||
{
|
|
||||||
assert(scope);
|
|
||||||
NetNet*net;
|
|
||||||
NetEvent*eve;
|
|
||||||
const NetExpr*expr;
|
|
||||||
|
|
||||||
const name_component_t&name_tail = path_.back();
|
|
||||||
|
|
||||||
// Handle the special case that this ident is a genvar
|
|
||||||
// variable name. In that case, the genvar meaning preempts
|
|
||||||
// everything and we just return that value immediately.
|
|
||||||
if (scope->genvar_tmp
|
|
||||||
&& strcmp(name_tail.name,scope->genvar_tmp) == 0) {
|
|
||||||
return new verinum(scope->genvar_tmp_val);
|
|
||||||
}
|
|
||||||
|
|
||||||
symbol_search(this, des, scope, path_, net, expr, eve);
|
|
||||||
|
|
||||||
if (expr == 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
const NetEConst*eval = dynamic_cast<const NetEConst*>(expr);
|
|
||||||
if (eval == 0) {
|
|
||||||
cerr << get_fileline() << ": internal error: Unable to evaluate "
|
|
||||||
<< "constant expression (parameter=" << path_
|
|
||||||
<< "): " << *expr << endl;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(eval);
|
|
||||||
|
|
||||||
if (!name_tail.index.empty())
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
|
|
||||||
return new verinum(eval->value());
|
|
||||||
}
|
|
||||||
|
|
||||||
verinum* PEFNumber::eval_const(Design*, NetScope*) const
|
|
||||||
{
|
|
||||||
long val = value_->as_long();
|
|
||||||
return new verinum(val);
|
|
||||||
}
|
|
||||||
|
|
||||||
verinum* PENumber::eval_const(Design*, NetScope*) const
|
|
||||||
{
|
|
||||||
return new verinum(value());
|
|
||||||
}
|
|
||||||
|
|
||||||
verinum* PEString::eval_const(Design*, NetScope*) const
|
|
||||||
{
|
|
||||||
return new verinum(string(text_));
|
|
||||||
}
|
|
||||||
|
|
||||||
verinum* PETernary::eval_const(Design*des, NetScope*scope) const
|
|
||||||
{
|
|
||||||
verinum*test = expr_->eval_const(des, scope);
|
|
||||||
if (test == 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
verinum::V bit = test->get(0);
|
|
||||||
delete test;
|
|
||||||
switch (bit) {
|
|
||||||
case verinum::V0:
|
|
||||||
return fal_->eval_const(des, scope);
|
|
||||||
case verinum::V1:
|
|
||||||
return tru_->eval_const(des, scope);
|
|
||||||
default:
|
|
||||||
return 0;
|
|
||||||
// XXXX It is possible to handle this case if both fal_
|
|
||||||
// and tru_ are constant. Someday...
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
verinum* PEUnary::eval_const(Design*des, NetScope*scope) const
|
|
||||||
{
|
|
||||||
verinum*val = expr_->eval_const(des, scope);
|
|
||||||
if (val == 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
switch (op_) {
|
|
||||||
case '+':
|
|
||||||
return val;
|
|
||||||
|
|
||||||
case '-': {
|
|
||||||
/* We need to expand the value a bit if we are
|
|
||||||
taking the 2's complement so that we are
|
|
||||||
guaranteed to not overflow. */
|
|
||||||
verinum tmp ((uint64_t)0, val->len()+1);
|
|
||||||
for (unsigned idx = 0 ; idx < val->len() ; idx += 1)
|
|
||||||
tmp.set(idx, val->get(idx));
|
|
||||||
|
|
||||||
*val = -tmp;
|
|
||||||
val->has_sign(true);
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
delete val;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue