Get parameter ranges as far as the netlist form.

The pform is now translated/elaborated into NetScope objects. All that
remains is to check the parameter values against the ranges. This is
to be done in the evaluate_parameters() method.
This commit is contained in:
Stephen Williams 2008-05-13 21:22:52 -07:00
parent 2172c8a503
commit 48f934abf7
8 changed files with 106 additions and 32 deletions

View File

@ -79,9 +79,11 @@ class Module : public PScope, public LineInfo {
// True if this is an exclude
bool exclude_flag;
// lower bound
// If low_open_flag is false and low_expr=0, then use -inf
bool low_open_flag;
PExpr*low_expr;
// upper bound
// If high_open_flag is false and high_expr=0, then use +inf
bool high_open_flag;
PExpr*high_expr;
// Next range description in list

View File

@ -966,8 +966,37 @@ void NetScope::dump(ostream&o) const
o << "[" << *(*pp).second.msb
<< ":" << *(*pp).second.lsb << "] ";
o << (*pp).first << " = " <<
*(*pp).second.expr << ";" << endl;
o << (*pp).first << " = " << *(*pp).second.expr;
for (range_t*ran = (*pp).second.range ; ran ; ran = ran->next) {
if (ran->exclude_flag)
o << " exclude ";
else
o << " from ";
if (ran->low_open_flag)
o << "(";
else
o << "[";
if (ran->low_expr)
o << *ran->low_expr;
else if (ran->low_open_flag==false)
o << "-inf";
else
o << "<?>";
if (ran->high_expr)
o << ":" << *ran->high_expr;
else if (ran->high_open_flag==false)
o << ":inf";
else
o << ":<?>";
if (ran->high_open_flag)
o << ")";
else
o << "]";
}
o << ";" << endl;
}
for (pp = localparams.begin()

View File

@ -43,6 +43,7 @@
# include "util.h"
# include <typeinfo>
# include <assert.h>
# include "ivl_assert.h"
void Module::elaborate_parm_item_(perm_string name, const param_expr_t&cur,
Design*des, NetScope*scope)
@ -80,8 +81,28 @@ void Module::elaborate_parm_item_(perm_string name, const param_expr_t&cur,
signed_flag = val->has_sign();
}
val = scope->set_parameter(name, val, msb, lsb, signed_flag,
cur.get_file(), cur.get_lineno());
NetScope::range_t*range_list = 0;
for (Module::range_t*range = cur.range ; range ; range = range->next) {
NetScope::range_t*tmp = new NetScope::range_t;
tmp->exclude_flag = range->exclude_flag;
tmp->low_open_flag = range->low_open_flag;
tmp->high_open_flag = range->high_open_flag;
if (range->low_expr) {
tmp->low_expr = elab_and_eval(des, scope, range->low_expr, -1);
ivl_assert(*range->low_expr, tmp->low_expr);
}
if (range->high_expr) {
tmp->high_expr = elab_and_eval(des, scope, range->high_expr, -1);
ivl_assert(*range->high_expr, tmp->high_expr);
}
tmp->next = range_list;
range_list = tmp;
}
val = scope->set_parameter(name, val, msb, lsb, signed_flag, range_list, cur);
assert(val);
delete val;
}
@ -119,9 +140,7 @@ bool Module::elaborate_scope(Design*des, NetScope*scope,
tmp->set_line(*((*cur).second.expr));
tmp->cast_signed( (*cur).second.signed_flag );
scope->set_parameter((*cur).first, tmp, 0, 0, false,
(*cur).second.get_file(),
(*cur).second.get_lineno());
scope->set_parameter((*cur).first, tmp, 0, 0, false, 0, (*cur).second);
}
for (mparm_it_t cur = localparams.begin()
@ -132,9 +151,7 @@ bool Module::elaborate_scope(Design*des, NetScope*scope,
if ((*cur).second.msb)
tmp->cast_signed( (*cur).second.signed_flag );
scope->set_parameter((*cur).first, tmp, 0, 0, false,
(*cur).second.get_file(),
(*cur).second.get_lineno());
scope->set_parameter((*cur).first, tmp, 0, 0, false, 0, (*cur).second);
}
@ -420,9 +437,7 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
genvar_verinum);
// The file and line information should really come
// from the genvar statement, not the for loop.
scope->set_localparam(loop_index, gp, get_file(),
get_lineno());
scope->set_localparam(loop_index, gp, *this);
if (debug_scopes)
cerr << get_fileline() << ": debug: "
<< "Create implicit localparam "

View File

@ -23,6 +23,7 @@
# include "netlist.h"
# include <cstring>
# include <sstream>
# include "ivl_assert.h"
/*
* The NetScope class keeps a scope tree organized. Each node of the
@ -105,7 +106,8 @@ void NetScope::set_line(perm_string file, perm_string def_file,
NetExpr* NetScope::set_parameter(perm_string key, NetExpr*expr,
NetExpr*msb, NetExpr*lsb, bool signed_flag,
perm_string file, unsigned lineno)
NetScope::range_t*range_list,
const LineInfo&file_line)
{
param_expr_t&ref = parameters[key];
NetExpr* res = ref.expr;
@ -113,8 +115,9 @@ NetExpr* NetScope::set_parameter(perm_string key, NetExpr*expr,
ref.msb = msb;
ref.lsb = lsb;
ref.signed_flag = signed_flag;
ref.file = file;
ref.lineno = lineno;
ivl_assert(file_line, ref.range == 0);
ref.range = range_list;
ref.set_line(file_line);
return res;
}
@ -160,7 +163,7 @@ bool NetScope::replace_parameter(perm_string key, NetExpr*expr)
* used to add a genver to the local parameter list.
*/
NetExpr* NetScope::set_localparam(perm_string key, NetExpr*expr,
perm_string file, unsigned lineno)
const LineInfo&file_line)
{
param_expr_t&ref = localparams[key];
NetExpr* res = ref.expr;
@ -168,8 +171,7 @@ NetExpr* NetScope::set_localparam(perm_string key, NetExpr*expr,
ref.msb = 0;
ref.lsb = 0;
ref.signed_flag = false;
ref.file = file;
ref.lineno = lineno;
ref.set_line(file_line);
return res;
}

View File

@ -3314,11 +3314,13 @@ class NetScope : public Attrib {
the scope. The return value from set_parameter is the
previous expression, if there was one. */
struct range_t;
NetExpr* set_parameter(perm_string name, NetExpr*val,
NetExpr*msb, NetExpr*lsb, bool signed_flag,
perm_string file, unsigned lineno);
NetScope::range_t*range_list,
const LineInfo&file_line);
NetExpr* set_localparam(perm_string name, NetExpr*val,
perm_string file, unsigned lineno);
const LineInfo&file_line);
const NetExpr*get_parameter(const char* name,
const NetExpr*&msb,
@ -3427,15 +3429,30 @@ class NetScope : public Attrib {
map<pform_name_t,NetExpr*>defparams;
public:
struct range_t {
bool exclude_flag;
// Lower bound
bool low_open_flag;
NetExpr*low_expr;
// Upper bound
bool high_open_flag;
NetExpr*high_expr;
// Link to the next range specification
struct range_t*next;
};
/* After everything is all set up, the code generators like
access to these things to make up the parameter lists. */
struct param_expr_t {
NetExpr*expr;
struct param_expr_t : public LineInfo {
param_expr_t() : range(0) { }
// Type information
bool signed_flag;
NetExpr*msb;
NetExpr*lsb;
perm_string file;
unsigned lineno;
bool signed_flag;
// range constraints
struct range_t*range;
// Expression value
NetExpr*expr;
};
map<perm_string,param_expr_t>parameters;
map<perm_string,param_expr_t>localparams;

View File

@ -1638,6 +1638,11 @@ Module::range_t* pform_parameter_value_range(bool exclude_flag,
bool low_open, PExpr*low_expr,
bool hig_open, PExpr*hig_expr)
{
// Detect +-inf and make the the *_open flags false to force
// the range interpretation as inf.
if (low_expr == 0) low_open = false;
if (hig_expr == 0) hig_open = false;
Module::range_t*tmp = new Module::range_t;
tmp->exclude_flag = exclude_flag;
tmp->low_open_flag = low_open;

View File

@ -1017,13 +1017,17 @@ void Module::dump(ostream&out) const
out << "[";
if (tmp->low_expr)
out << *(tmp->low_expr);
else if (tmp->low_open_flag==false)
out << "-inf";
else
out << "<>";
out << "<nil>";
out << ":";
if (tmp->high_expr)
out << *(tmp->high_expr);
else if (tmp->high_open_flag==false)
out << "inf";
else
out << "<>";
out << "<nil>";
if (tmp->high_open_flag)
out << ")";
else

View File

@ -470,8 +470,8 @@ void dll_target::make_scope_parameters(ivl_scope_t scope, const NetScope*net)
ivl_parameter_t cur_par = scope->param_ + idx;
cur_par->basename = (*cur_pit).first;
cur_par->scope = scope;
cur_par->file = (*cur_pit).second.file;
cur_par->lineno = (*cur_pit).second.lineno;
cur_par->file = (*cur_pit).second.get_file();
cur_par->lineno = (*cur_pit).second.get_lineno();
NetExpr*etmp = (*cur_pit).second.expr;
make_scope_param_expr(cur_par, etmp);
@ -484,8 +484,8 @@ void dll_target::make_scope_parameters(ivl_scope_t scope, const NetScope*net)
ivl_parameter_t cur_par = scope->param_ + idx;
cur_par->basename = (*cur_pit).first;
cur_par->scope = scope;
cur_par->file = (*cur_pit).second.file;
cur_par->lineno = (*cur_pit).second.lineno;
cur_par->file = (*cur_pit).second.get_file();
cur_par->lineno = (*cur_pit).second.get_lineno();
NetExpr*etmp = (*cur_pit).second.expr;
make_scope_param_expr(cur_par, etmp);