Rework parsing of parameter types
Use the common data_type_or_implicit rules to support type definitions for parameters. This eliminates a bunch of special rules in parse.y, and opens the door for parameters having more complex types.
This commit is contained in:
parent
51025149a9
commit
16646c547c
5
PExpr.cc
5
PExpr.cc
|
|
@ -434,11 +434,10 @@ bool PEIdent::has_aa_term(Design*des, NetScope*scope) const
|
|||
{
|
||||
NetNet* net = 0;
|
||||
const NetExpr*par = 0;
|
||||
ivl_type_t par_type;
|
||||
NetEvent* eve = 0;
|
||||
|
||||
const NetExpr*ex1, *ex2;
|
||||
|
||||
scope = symbol_search(this, des, scope, path_, net, par, eve, ex1, ex2);
|
||||
scope = symbol_search(this, des, scope, path_, net, par, eve, par_type);
|
||||
|
||||
if (scope)
|
||||
return scope->is_auto();
|
||||
|
|
|
|||
19
PExpr.h
19
PExpr.h
|
|
@ -407,10 +407,6 @@ class PEIdent : public PExpr {
|
|||
// flag is set to *false*.
|
||||
bool calculate_parts_(Design*, NetScope*, long&msb, long&lsb, bool&defined) const;
|
||||
NetExpr* calculate_up_do_base_(Design*, NetScope*, bool need_const) const;
|
||||
bool calculate_param_range_(Design*, NetScope*,
|
||||
const NetExpr*msb_ex, long&msb,
|
||||
const NetExpr*lsb_ex, long&lsb,
|
||||
long length) const;
|
||||
|
||||
bool calculate_up_do_width_(Design*, NetScope*, unsigned long&wid) const;
|
||||
|
||||
|
|
@ -450,37 +446,32 @@ class PEIdent : public PExpr {
|
|||
NetScope*scope,
|
||||
const NetExpr*par,
|
||||
NetScope*found_in,
|
||||
const NetExpr*par_msb,
|
||||
const NetExpr*par_lsb,
|
||||
ivl_type_t par_type,
|
||||
unsigned expr_wid,
|
||||
unsigned flags) const;
|
||||
NetExpr*elaborate_expr_param_bit_(Design*des,
|
||||
NetScope*scope,
|
||||
const NetExpr*par,
|
||||
NetScope*found_in,
|
||||
const NetExpr*par_msb,
|
||||
const NetExpr*par_lsb,
|
||||
ivl_type_t par_type,
|
||||
bool need_const) const;
|
||||
NetExpr*elaborate_expr_param_part_(Design*des,
|
||||
NetScope*scope,
|
||||
const NetExpr*par,
|
||||
NetScope*found_in,
|
||||
const NetExpr*par_msb,
|
||||
const NetExpr*par_lsb,
|
||||
ivl_type_t par_type,
|
||||
unsigned expr_wid) const;
|
||||
NetExpr*elaborate_expr_param_idx_up_(Design*des,
|
||||
NetScope*scope,
|
||||
const NetExpr*par,
|
||||
NetScope*found_in,
|
||||
const NetExpr*par_msb,
|
||||
const NetExpr*par_lsb,
|
||||
ivl_type_t par_type,
|
||||
bool need_const) const;
|
||||
NetExpr*elaborate_expr_param_idx_do_(Design*des,
|
||||
NetScope*scope,
|
||||
const NetExpr*par,
|
||||
NetScope*found_in,
|
||||
const NetExpr*par_msb,
|
||||
const NetExpr*par_lsb,
|
||||
ivl_type_t par_type,
|
||||
bool need_const) const;
|
||||
NetExpr*elaborate_expr_net(Design*des,
|
||||
NetScope*scope,
|
||||
|
|
|
|||
9
PScope.h
9
PScope.h
|
|
@ -98,12 +98,9 @@ class LexicalScope {
|
|||
is elaborated. During parsing, I put the parameters into
|
||||
this map. */
|
||||
struct param_expr_t : public PNamedItem {
|
||||
param_expr_t() : type(IVL_VT_NO_TYPE), msb(0), lsb(0), signed_flag(false), expr(0), range(0) { }
|
||||
// Type information
|
||||
ivl_variable_type_t type;
|
||||
PExpr*msb;
|
||||
PExpr*lsb;
|
||||
bool signed_flag;
|
||||
inline param_expr_t() : data_type(0), expr(0), range(0) { }
|
||||
// Type information.
|
||||
data_type_t*data_type;
|
||||
// Value expression
|
||||
PExpr*expr;
|
||||
// If there are range constraints, list them here
|
||||
|
|
|
|||
|
|
@ -1465,14 +1465,8 @@ void NetScope::dump(ostream&o) const
|
|||
else
|
||||
o << " parameter ";
|
||||
|
||||
o << pp->second.type << " ";
|
||||
|
||||
if ((*pp).second.signed_flag)
|
||||
o << "signed ";
|
||||
|
||||
if ((*pp).second.msb)
|
||||
o << "[" << *(*pp).second.msb
|
||||
<< ":" << *(*pp).second.lsb << "] ";
|
||||
if (pp->second.ivl_type)
|
||||
pp->second.ivl_type->debug_dump(o);
|
||||
|
||||
o << (*pp).first << " = ";
|
||||
if (pp->second.val)
|
||||
|
|
|
|||
107
elab_expr.cc
107
elab_expr.cc
|
|
@ -1333,11 +1333,10 @@ unsigned PECallFunction::test_width_method_(Design*des, NetScope*scope,
|
|||
|
||||
NetNet *net = 0;
|
||||
const NetExpr *par;
|
||||
ivl_type_t par_type = 0;
|
||||
NetEvent *eve;
|
||||
const NetExpr *ex1, *ex2;
|
||||
|
||||
symbol_search(this, des, scope, use_path,
|
||||
net, par, eve, ex1, ex2);
|
||||
symbol_search(this, des, scope, use_path, net, par, eve, par_type);
|
||||
|
||||
const netdarray_t*use_darray = 0;
|
||||
|
||||
|
|
@ -1354,7 +1353,7 @@ unsigned PECallFunction::test_width_method_(Design*des, NetScope*scope,
|
|||
|
||||
net = 0;
|
||||
symbol_search(this, des, scope, tmp_path,
|
||||
net, par, eve, ex1, ex2);
|
||||
net, par, eve, par_type);
|
||||
if (net && net->class_type()) {
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": PECallFunction::test_width_method_: "
|
||||
|
|
@ -2647,11 +2646,10 @@ NetExpr* PECallFunction::elaborate_expr_method_(Design*des, NetScope*scope,
|
|||
|
||||
NetNet *net = 0;
|
||||
const NetExpr *par;
|
||||
ivl_type_t par_type;
|
||||
NetEvent *eve;
|
||||
const NetExpr *ex1, *ex2;
|
||||
|
||||
symbol_search(this, des, scope, use_path,
|
||||
net, par, eve, ex1, ex2);
|
||||
symbol_search(this, des, scope, use_path, net, par, eve, par_type);
|
||||
|
||||
if (net == 0)
|
||||
return 0;
|
||||
|
|
@ -3429,33 +3427,6 @@ NetExpr* PEIdent::calculate_up_do_base_(Design*des, NetScope*scope,
|
|||
return tmp;
|
||||
}
|
||||
|
||||
bool PEIdent::calculate_param_range_(Design*, NetScope*,
|
||||
const NetExpr*par_msb, long&par_msv,
|
||||
const NetExpr*par_lsb, long&par_lsv,
|
||||
long length) const
|
||||
{
|
||||
if (par_msb == 0) {
|
||||
// If the parameter doesn't have an explicit range, then
|
||||
// just return range values of [length-1:0].
|
||||
ivl_assert(*this, par_lsb == 0);
|
||||
par_msv = length-1;
|
||||
par_lsv = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
const NetEConst*tmp = dynamic_cast<const NetEConst*> (par_msb);
|
||||
ivl_assert(*this, tmp);
|
||||
|
||||
par_msv = tmp->value().as_long();
|
||||
|
||||
tmp = dynamic_cast<const NetEConst*> (par_lsb);
|
||||
ivl_assert(*this, tmp);
|
||||
|
||||
par_lsv = tmp->value().as_long();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned PEIdent::test_width_method_(Design*des, NetScope*scope, width_mode_t&)
|
||||
{
|
||||
if (!gn_system_verilog())
|
||||
|
|
@ -3475,9 +3446,9 @@ unsigned PEIdent::test_width_method_(Design*des, NetScope*scope, width_mode_t&)
|
|||
|
||||
NetNet*net = 0;
|
||||
const NetExpr*par = 0;
|
||||
ivl_type_t par_type = 0;
|
||||
NetEvent*eve = 0;
|
||||
const NetExpr*ex1 = 0, *ex2 = 0;
|
||||
symbol_search(this, des, scope, use_path, net, par, eve, ex1, ex2);
|
||||
symbol_search(this, des, scope, use_path, net, par, eve, par_type);
|
||||
if (net == 0) {
|
||||
if (debug_elaborate)
|
||||
cerr << get_fileline() << ": PEIdent::test_width_method_: "
|
||||
|
|
@ -3521,10 +3492,9 @@ unsigned PEIdent::test_width(Design*des, NetScope*scope, width_mode_t&mode)
|
|||
{
|
||||
NetNet* net = 0;
|
||||
const NetExpr*par = 0;
|
||||
ivl_type_t par_type = 0;
|
||||
NetEvent* eve = 0;
|
||||
|
||||
const NetExpr*ex1, *ex2;
|
||||
|
||||
NetScope*use_scope = scope;
|
||||
if (package_) {
|
||||
use_scope = des->find_package(package_->pscope_name());
|
||||
|
|
@ -3536,8 +3506,7 @@ unsigned PEIdent::test_width(Design*des, NetScope*scope, width_mode_t&mode)
|
|||
}
|
||||
|
||||
NetScope*found_in = symbol_search(this, des, use_scope, path_,
|
||||
net, par, eve,
|
||||
ex1, ex2);
|
||||
net, par, eve, par_type);
|
||||
|
||||
// If there is a part/bit select expression, then process it
|
||||
// here. This constrains the results no matter what kind the
|
||||
|
|
@ -3713,7 +3682,7 @@ unsigned PEIdent::test_width(Design*des, NetScope*scope, width_mode_t&mode)
|
|||
use_path.pop_back();
|
||||
|
||||
ivl_assert(*this, net == 0);
|
||||
symbol_search(this, des, scope, use_path, net, par, eve, ex1, ex2);
|
||||
symbol_search(this, des, scope, use_path, net, par, eve, par_type);
|
||||
|
||||
// Check to see if we have a net and if so is it a structure?
|
||||
if (net != 0) {
|
||||
|
|
@ -3775,8 +3744,8 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
|
|||
|
||||
NetNet* net = 0;
|
||||
const NetExpr*par = 0;
|
||||
ivl_type_t par_type = 0;
|
||||
NetEvent* eve = 0;
|
||||
const NetExpr*ex1, *ex2;
|
||||
|
||||
NetScope*use_scope = scope;
|
||||
if (package_) {
|
||||
|
|
@ -3788,9 +3757,7 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
|
|||
return tmp;
|
||||
}
|
||||
|
||||
/* NetScope*found_in = */ symbol_search(this, des, use_scope, path_,
|
||||
net, par, eve,
|
||||
ex1, ex2);
|
||||
symbol_search(this, des, use_scope, path_, net, par, eve, par_type);
|
||||
|
||||
if (net == 0 && gn_system_verilog() && path_.size() >= 2) {
|
||||
// NOTE: this is assuming the member_path is only one
|
||||
|
|
@ -3802,7 +3769,7 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
|
|||
use_path.pop_back();
|
||||
|
||||
ivl_assert(*this, net == 0);
|
||||
symbol_search(this, des, use_scope, use_path, net, par, eve, ex1, ex2);
|
||||
symbol_search(this, des, use_scope, use_path, net, par, eve, par_type);
|
||||
|
||||
if (net == 0) {
|
||||
// Nope, no struct/class with member.
|
||||
|
|
@ -4051,10 +4018,9 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
|
|||
|
||||
NetNet* net = 0;
|
||||
const NetExpr*par = 0;
|
||||
ivl_type_t par_type = 0;
|
||||
NetEvent* eve = 0;
|
||||
|
||||
const NetExpr*ex1, *ex2;
|
||||
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": PEIdent::elaborate_expr: "
|
||||
<< "path_=" << path_
|
||||
|
|
@ -4112,7 +4078,7 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
|
|||
NetScope*found_in = 0;
|
||||
while (net==0 && par==0 && eve==0 && base_path.size()>0) {
|
||||
found_in = symbol_search(this, des, use_scope, base_path,
|
||||
net, par, eve, ex1, ex2);
|
||||
net, par, eve, par_type);
|
||||
if (net) break;
|
||||
if (par) break;
|
||||
if (eve) break;
|
||||
|
|
@ -4144,7 +4110,7 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
|
|||
}
|
||||
|
||||
NetExpr*tmp = elaborate_expr_param_(des, scope, par, found_in,
|
||||
ex1, ex2, expr_wid, flags);
|
||||
par_type, expr_wid, flags);
|
||||
|
||||
if (!tmp) return 0;
|
||||
|
||||
|
|
@ -4463,16 +4429,14 @@ static verinum param_part_select_bits(const verinum&par_val, long wid,
|
|||
NetExpr* PEIdent::elaborate_expr_param_bit_(Design*des, NetScope*scope,
|
||||
const NetExpr*par,
|
||||
NetScope*found_in,
|
||||
const NetExpr*par_msb,
|
||||
const NetExpr*par_lsb,
|
||||
ivl_type_t par_type,
|
||||
bool need_const) const
|
||||
{
|
||||
const NetEConst*par_ex = dynamic_cast<const NetEConst*> (par);
|
||||
ivl_assert(*this, par_ex);
|
||||
|
||||
long par_msv, par_lsv;
|
||||
if(! calculate_param_range_(des, scope, par_msb, par_msv,
|
||||
par_lsb, par_lsv,
|
||||
if(! calculate_param_range(*this, par_type, par_msv, par_lsv,
|
||||
par_ex->value().len())) return 0;
|
||||
|
||||
const name_component_t&name_tail = path_.back();
|
||||
|
|
@ -4559,8 +4523,7 @@ NetExpr* PEIdent::elaborate_expr_param_bit_(Design*des, NetScope*scope,
|
|||
NetExpr* PEIdent::elaborate_expr_param_part_(Design*des, NetScope*scope,
|
||||
const NetExpr*par,
|
||||
NetScope*,
|
||||
const NetExpr*par_msb,
|
||||
const NetExpr*par_lsb,
|
||||
ivl_type_t par_type,
|
||||
unsigned expr_wid) const
|
||||
{
|
||||
long msv, lsv;
|
||||
|
|
@ -4574,8 +4537,7 @@ NetExpr* PEIdent::elaborate_expr_param_part_(Design*des, NetScope*scope,
|
|||
|
||||
|
||||
long par_msv, par_lsv;
|
||||
if (! calculate_param_range_(des, scope, par_msb, par_msv,
|
||||
par_lsb, par_lsv,
|
||||
if (! calculate_param_range(*this, par_type, par_msv, par_lsv,
|
||||
par_ex->value().len())) return 0;
|
||||
|
||||
if (! parts_defined_flag) {
|
||||
|
|
@ -4685,16 +4647,14 @@ static void warn_param_ob(long par_msv, long par_lsv, bool defined,
|
|||
NetExpr* PEIdent::elaborate_expr_param_idx_up_(Design*des, NetScope*scope,
|
||||
const NetExpr*par,
|
||||
NetScope*found_in,
|
||||
const NetExpr*par_msb,
|
||||
const NetExpr*par_lsb,
|
||||
ivl_type_t par_type,
|
||||
bool need_const) const
|
||||
{
|
||||
const NetEConst*par_ex = dynamic_cast<const NetEConst*> (par);
|
||||
ivl_assert(*this, par_ex);
|
||||
|
||||
long par_msv, par_lsv;
|
||||
if(! calculate_param_range_(des, scope, par_msb, par_msv,
|
||||
par_lsb, par_lsv,
|
||||
if(! calculate_param_range(*this, par_type, par_msv, par_lsv,
|
||||
par_ex->value().len())) return 0;
|
||||
|
||||
NetExpr*base = calculate_up_do_base_(des, scope, need_const);
|
||||
|
|
@ -4737,8 +4697,7 @@ NetExpr* PEIdent::elaborate_expr_param_idx_up_(Design*des, NetScope*scope,
|
|||
if (warn_ob_select) {
|
||||
bool defined = true;
|
||||
// Check to see if the parameter has a defined range.
|
||||
if (par_msb == 0) {
|
||||
assert(par_lsb == 0);
|
||||
if (par_type == 0) {
|
||||
defined = false;
|
||||
}
|
||||
// Get the parameter values width.
|
||||
|
|
@ -4769,16 +4728,14 @@ NetExpr* PEIdent::elaborate_expr_param_idx_up_(Design*des, NetScope*scope,
|
|||
NetExpr* PEIdent::elaborate_expr_param_idx_do_(Design*des, NetScope*scope,
|
||||
const NetExpr*par,
|
||||
NetScope*found_in,
|
||||
const NetExpr*par_msb,
|
||||
const NetExpr*par_lsb,
|
||||
ivl_type_t par_type,
|
||||
bool need_const) const
|
||||
{
|
||||
const NetEConst*par_ex = dynamic_cast<const NetEConst*> (par);
|
||||
ivl_assert(*this, par_ex);
|
||||
|
||||
long par_msv, par_lsv;
|
||||
if(! calculate_param_range_(des, scope, par_msb, par_msv,
|
||||
par_lsb, par_lsv,
|
||||
if(! calculate_param_range(*this, par_type, par_msv, par_lsv,
|
||||
par_ex->value().len())) return 0;
|
||||
|
||||
NetExpr*base = calculate_up_do_base_(des, scope, need_const);
|
||||
|
|
@ -4821,8 +4778,7 @@ NetExpr* PEIdent::elaborate_expr_param_idx_do_(Design*des, NetScope*scope,
|
|||
if (warn_ob_select) {
|
||||
bool defined = true;
|
||||
// Check to see if the parameter has a defined range.
|
||||
if (par_msb == 0) {
|
||||
assert(par_lsb == 0);
|
||||
if (par_type == 0) {
|
||||
defined = false;
|
||||
}
|
||||
// Get the parameter values width.
|
||||
|
|
@ -4860,8 +4816,7 @@ NetExpr* PEIdent::elaborate_expr_param_(Design*des,
|
|||
NetScope*scope,
|
||||
const NetExpr*par,
|
||||
NetScope*found_in,
|
||||
const NetExpr*par_msb,
|
||||
const NetExpr*par_lsb,
|
||||
ivl_type_t par_type,
|
||||
unsigned expr_wid, unsigned flags) const
|
||||
{
|
||||
bool need_const = NEED_CONST & flags;
|
||||
|
|
@ -4894,19 +4849,19 @@ NetExpr* PEIdent::elaborate_expr_param_(Design*des,
|
|||
|
||||
if (use_sel == index_component_t::SEL_BIT)
|
||||
return elaborate_expr_param_bit_(des, scope, par, found_in,
|
||||
par_msb, par_lsb, need_const);
|
||||
par_type, need_const);
|
||||
|
||||
if (use_sel == index_component_t::SEL_PART)
|
||||
return elaborate_expr_param_part_(des, scope, par, found_in,
|
||||
par_msb, par_lsb, expr_wid);
|
||||
par_type, expr_wid);
|
||||
|
||||
if (use_sel == index_component_t::SEL_IDX_UP)
|
||||
return elaborate_expr_param_idx_up_(des, scope, par, found_in,
|
||||
par_msb, par_lsb, need_const);
|
||||
par_type, need_const);
|
||||
|
||||
if (use_sel == index_component_t::SEL_IDX_DO)
|
||||
return elaborate_expr_param_idx_do_(des, scope, par, found_in,
|
||||
par_msb, par_lsb, need_const);
|
||||
par_type, need_const);
|
||||
|
||||
NetExpr*tmp = 0;
|
||||
|
||||
|
|
|
|||
111
elab_scope.cc
111
elab_scope.cc
|
|
@ -65,11 +65,26 @@ void set_scope_timescale(Design*des, NetScope*scope, PScope*pscope)
|
|||
|
||||
typedef map<perm_string,LexicalScope::param_expr_t*>::const_iterator mparm_it_t;
|
||||
|
||||
static void collect_parm_item_(Design*des, NetScope*scope, perm_string name,
|
||||
static void collect_parm_item(Design*des, NetScope*scope, perm_string name,
|
||||
const LexicalScope::param_expr_t&cur,
|
||||
bool is_annotatable,
|
||||
bool local_flag)
|
||||
bool is_annotatable, bool local_flag)
|
||||
{
|
||||
if (debug_scopes) {
|
||||
cerr << cur.get_fileline() << ": " << __func__ << ": "
|
||||
<< "parameter " << name << " ";
|
||||
if (cur.data_type)
|
||||
cerr << *cur.data_type;
|
||||
else
|
||||
cerr << "(nil type)";
|
||||
ivl_assert(cur, cur.expr);
|
||||
cerr << " = " << *cur.expr << "; ";
|
||||
if (cur.range)
|
||||
cerr << "with ranges ";
|
||||
else
|
||||
cerr << "without ranges ";
|
||||
cerr << "; in scope " << scope_path(scope) << endl;
|
||||
}
|
||||
|
||||
NetScope::range_t*range_list = 0;
|
||||
for (LexicalScope::range_t*range = cur.range ; range ; range = range->next) {
|
||||
NetScope::range_t*tmp = new NetScope::range_t;
|
||||
|
|
@ -104,38 +119,57 @@ static void collect_parm_item_(Design*des, NetScope*scope, perm_string name,
|
|||
range_list = tmp;
|
||||
}
|
||||
|
||||
// The type of the parameter, if unspecified in the source, will come
|
||||
// from the type of the value assigned to it. Therefore, if the type is
|
||||
// not yet known, don't try to guess here, put the type guess off. Also
|
||||
// don't try to elaborate it here, because there may be references to
|
||||
// other parameters still being located during scope elaboration.
|
||||
scope->set_parameter(name, is_annotatable, cur.expr, cur.data_type, local_flag, range_list, cur);
|
||||
|
||||
scope->set_parameter(name, is_annotatable, cur.expr, cur.type, cur.msb,
|
||||
cur.lsb, cur.signed_flag, local_flag, range_list, cur);
|
||||
}
|
||||
|
||||
static void collect_scope_parameters_(Design*des, NetScope*scope,
|
||||
static void collect_scope_parameters(Design*des, NetScope*scope,
|
||||
const map<perm_string,LexicalScope::param_expr_t*>¶meters)
|
||||
{
|
||||
if (debug_scopes) {
|
||||
cerr << scope->get_fileline() << ": " << __func__ << ": "
|
||||
<< "collect parameters for " << scope_path(scope) << "." << endl;
|
||||
}
|
||||
|
||||
for (mparm_it_t cur = parameters.begin()
|
||||
; cur != parameters.end() ; ++ cur ) {
|
||||
|
||||
collect_parm_item_(des, scope, cur->first, *(cur->second), false, false);
|
||||
collect_parm_item(des, scope, cur->first, *(cur->second), false, false);
|
||||
}
|
||||
}
|
||||
|
||||
static void collect_scope_localparams_(Design*des, NetScope*scope,
|
||||
static void collect_scope_localparams(Design*des, NetScope*scope,
|
||||
const map<perm_string,LexicalScope::param_expr_t*>&localparams)
|
||||
{
|
||||
if (debug_scopes) {
|
||||
cerr << scope->get_fileline() << ": " << __func__ << ": "
|
||||
<< "collect localparams for " << scope_path(scope) << "." << endl;
|
||||
}
|
||||
|
||||
for (mparm_it_t cur = localparams.begin()
|
||||
; cur != localparams.end() ; ++ cur ) {
|
||||
|
||||
collect_parm_item_(des, scope, cur->first, *(cur->second), false, true);
|
||||
collect_parm_item(des, scope, cur->first, *(cur->second), false, true);
|
||||
}
|
||||
}
|
||||
|
||||
static void collect_scope_specparams_(Design*des, NetScope*scope,
|
||||
static void collect_scope_specparams(Design*des, NetScope*scope,
|
||||
const map<perm_string,LexicalScope::param_expr_t*>&specparams)
|
||||
{
|
||||
if (debug_scopes) {
|
||||
cerr << scope->get_fileline() << ": " << __func__ << ": "
|
||||
<< "collect specparams for " << scope_path(scope) << "." << endl;
|
||||
}
|
||||
|
||||
for (mparm_it_t cur = specparams.begin()
|
||||
; cur != specparams.end() ; ++ cur ) {
|
||||
|
||||
collect_parm_item_(des, scope, cur->first, *(cur->second), true, false);
|
||||
collect_parm_item(des, scope, cur->first, *(cur->second), true, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -356,6 +390,13 @@ static void elaborate_scope_enumeration(Design*des, NetScope*scope,
|
|||
static void elaborate_scope_enumerations(Design*des, NetScope*scope,
|
||||
const set<enum_type_t*>&enum_types)
|
||||
{
|
||||
if (debug_scopes) {
|
||||
cerr << scope->get_fileline() << ": " << __func__ << ": "
|
||||
<< "Elaborate " << enum_types.size() << " enumerations"
|
||||
<< " in scope " << scope_path(scope) << "."
|
||||
<< endl;
|
||||
}
|
||||
|
||||
for (set<enum_type_t*>::const_iterator cur = enum_types.begin()
|
||||
; cur != enum_types.end() ; ++ cur) {
|
||||
enum_type_t*curp = *cur;
|
||||
|
|
@ -564,15 +605,27 @@ static void elaborate_scope_class(Design*des, NetScope*scope, PClass*pclass)
|
|||
static void elaborate_scope_classes(Design*des, NetScope*scope,
|
||||
const vector<PClass*>&classes)
|
||||
{
|
||||
if (debug_scopes) {
|
||||
cerr << scope->get_fileline() << ": " << __func__ << ": "
|
||||
<< "Elaborate " << classes.size() << " classes"
|
||||
<< " in scope " << scope_path(scope) << "."
|
||||
<< endl;
|
||||
}
|
||||
|
||||
for (size_t idx = 0 ; idx < classes.size() ; idx += 1) {
|
||||
blend_class_constructors(classes[idx]);
|
||||
elaborate_scope_class(des, scope, classes[idx]);
|
||||
}
|
||||
}
|
||||
|
||||
static void replace_scope_parameters_(NetScope*scope, const LineInfo&loc,
|
||||
static void replace_scope_parameters(NetScope*scope, const LineInfo&loc,
|
||||
const Module::replace_t&replacements)
|
||||
{
|
||||
if (debug_scopes) {
|
||||
cerr << scope->get_fileline() << ": " << __func__ << ": "
|
||||
<< "Replace scope parameters for " << scope_path(scope) << "." << endl;
|
||||
}
|
||||
|
||||
for (Module::replace_t::const_iterator cur = replacements.begin()
|
||||
; cur != replacements.end() ; ++ cur ) {
|
||||
|
||||
|
|
@ -712,8 +765,8 @@ bool PPackage::elaborate_scope(Design*des, NetScope*scope)
|
|||
|
||||
scope->add_typedefs(&typedefs);
|
||||
|
||||
collect_scope_parameters_(des, scope, parameters);
|
||||
collect_scope_localparams_(des, scope, localparams);
|
||||
collect_scope_parameters(des, scope, parameters);
|
||||
collect_scope_localparams(des, scope, localparams);
|
||||
|
||||
if (debug_scopes) {
|
||||
cerr << get_fileline() << ": PPackage::elaborate_scope: "
|
||||
|
|
@ -751,23 +804,17 @@ bool Module::elaborate_scope(Design*des, NetScope*scope,
|
|||
// will be evaluated later, once all parameter overrides for this
|
||||
// module have been done.
|
||||
|
||||
collect_scope_parameters_(des, scope, parameters);
|
||||
collect_scope_parameters(des, scope, parameters);
|
||||
|
||||
collect_scope_localparams_(des, scope, localparams);
|
||||
collect_scope_localparams(des, scope, localparams);
|
||||
|
||||
collect_scope_specparams_(des, scope, specparams);
|
||||
collect_scope_specparams(des, scope, specparams);
|
||||
|
||||
// Run parameter replacements that were collected from the
|
||||
// containing scope and meant for me.
|
||||
|
||||
replace_scope_parameters_(scope, *this, replacements);
|
||||
replace_scope_parameters(scope, *this, replacements);
|
||||
|
||||
if (debug_scopes) {
|
||||
cerr << get_fileline() << ": Module::elaborate_scope: "
|
||||
<< "Elaborate " << enum_sets.size() << " enumerations"
|
||||
<< " in scope " << scope_path(scope) << "."
|
||||
<< endl;
|
||||
}
|
||||
elaborate_scope_enumerations(des, scope, enum_sets);
|
||||
|
||||
assert(classes.size() == classes_lexical.size());
|
||||
|
|
@ -796,7 +843,7 @@ bool Module::elaborate_scope(Design*des, NetScope*scope,
|
|||
// we can not do that until defparams are run, so push it off
|
||||
// into an elaborate work item.
|
||||
if (debug_scopes)
|
||||
cerr << get_fileline() << ": debug: "
|
||||
cerr << get_fileline() << ": " << __func__ << ": "
|
||||
<< "Schedule generates within " << scope_path(scope)
|
||||
<< " for elaboration after defparams." << endl;
|
||||
|
||||
|
|
@ -1216,7 +1263,7 @@ void PGenerate::elaborate_subscope_(Design*des, NetScope*scope)
|
|||
// needed to evaluate the parameter expressions. The expressions
|
||||
// will be evaluated later, once all parameter overrides for this
|
||||
// module have been done.
|
||||
collect_scope_localparams_(des, scope, localparams);
|
||||
collect_scope_localparams(des, scope, localparams);
|
||||
|
||||
// Run through the defparams for this scope and save the result
|
||||
// in a table for later final override.
|
||||
|
|
@ -1564,9 +1611,9 @@ void PFunction::elaborate_scope(Design*des, NetScope*scope) const
|
|||
// Scan the parameters in the function, and store the information
|
||||
// needed to evaluate the parameter expressions.
|
||||
|
||||
collect_scope_parameters_(des, scope, parameters);
|
||||
collect_scope_parameters(des, scope, parameters);
|
||||
|
||||
collect_scope_localparams_(des, scope, localparams);
|
||||
collect_scope_localparams(des, scope, localparams);
|
||||
|
||||
// Scan through all the named events in this scope.
|
||||
elaborate_scope_events_(des, scope, events);
|
||||
|
|
@ -1584,9 +1631,9 @@ void PTask::elaborate_scope(Design*des, NetScope*scope) const
|
|||
// Scan the parameters in the task, and store the information
|
||||
// needed to evaluate the parameter expressions.
|
||||
|
||||
collect_scope_parameters_(des, scope, parameters);
|
||||
collect_scope_parameters(des, scope, parameters);
|
||||
|
||||
collect_scope_localparams_(des, scope, localparams);
|
||||
collect_scope_localparams(des, scope, localparams);
|
||||
|
||||
// Scan through all the named events in this scope.
|
||||
elaborate_scope_events_(des, scope, events);
|
||||
|
|
@ -1634,9 +1681,9 @@ void PBlock::elaborate_scope(Design*des, NetScope*scope) const
|
|||
// Scan the parameters in the scope, and store the information
|
||||
// needed to evaluate the parameter expressions.
|
||||
|
||||
collect_scope_parameters_(des, my_scope, parameters);
|
||||
collect_scope_parameters(des, my_scope, parameters);
|
||||
|
||||
collect_scope_localparams_(des, my_scope, localparams);
|
||||
collect_scope_localparams(des, my_scope, localparams);
|
||||
|
||||
// Scan through all the named events in this scope.
|
||||
elaborate_scope_events_(des, my_scope, events);
|
||||
|
|
|
|||
|
|
@ -3780,8 +3780,8 @@ NetProc* PCallTask::elaborate_method_(Design*des, NetScope*scope,
|
|||
|
||||
NetNet *net;
|
||||
const NetExpr *par;
|
||||
ivl_type_t par_type = 0;
|
||||
NetEvent *eve;
|
||||
const NetExpr *ex1, *ex2;
|
||||
|
||||
/* Add the implicit this reference when requested. */
|
||||
if (add_this_flag) {
|
||||
|
|
@ -3796,8 +3796,7 @@ NetProc* PCallTask::elaborate_method_(Design*des, NetScope*scope,
|
|||
// resolve to a class object. Note that the "this" symbol
|
||||
// (internally represented as "@") is handled by there being a
|
||||
// "this" object in the instance scope.
|
||||
symbol_search(this, des, scope, use_path,
|
||||
net, par, eve, ex1, ex2);
|
||||
symbol_search(this, des, scope, use_path, net, par, eve, par_type);
|
||||
|
||||
if (net == 0)
|
||||
return 0;
|
||||
|
|
|
|||
167
net_design.cc
167
net_design.cc
|
|
@ -29,6 +29,8 @@
|
|||
*/
|
||||
|
||||
# include "netlist.h"
|
||||
# include "netscalar.h"
|
||||
# include "netvector.h"
|
||||
# include "util.h"
|
||||
# include "compiler.h"
|
||||
# include "netmisc.h"
|
||||
|
|
@ -508,56 +510,71 @@ void Design::evaluate_parameters()
|
|||
|
||||
void NetScope::evaluate_parameter_logic_(Design*des, param_ref_t cur)
|
||||
{
|
||||
long msb = 0;
|
||||
long lsb = 0;
|
||||
bool range_flag = false;
|
||||
|
||||
/* Evaluate the msb expression, if it is present. */
|
||||
PExpr*msb_expr = (*cur).second.msb_expr;
|
||||
if (msb_expr) {
|
||||
(*cur).second.msb = elab_and_eval(des, this, msb_expr, -1, true);
|
||||
if (! eval_as_long(msb, (*cur).second.msb)) {
|
||||
cerr << (*cur).second.val->get_fileline()
|
||||
<< ": error: Unable to evaluate msb expression "
|
||||
<< "for parameter " << (*cur).first << ": "
|
||||
<< *(*cur).second.msb << endl;
|
||||
des->errors += 1;
|
||||
return;
|
||||
}
|
||||
|
||||
range_flag = true;
|
||||
}
|
||||
|
||||
/* Evaluate the lsb expression, if it is present. */
|
||||
PExpr*lsb_expr = (*cur).second.lsb_expr;
|
||||
if (lsb_expr) {
|
||||
(*cur).second.lsb = elab_and_eval(des, this, lsb_expr, -1, true);
|
||||
if (! eval_as_long(lsb, (*cur).second.lsb)) {
|
||||
cerr << (*cur).second.val->get_fileline()
|
||||
<< ": error: Unable to evaluate lsb expression "
|
||||
<< "for parameter " << (*cur).first << ": "
|
||||
<< *(*cur).second.lsb << endl;
|
||||
des->errors += 1;
|
||||
return;
|
||||
}
|
||||
|
||||
range_flag = true;
|
||||
}
|
||||
|
||||
/* Evaluate the parameter expression. */
|
||||
PExpr*val_expr = (*cur).second.val_expr;
|
||||
NetScope*val_scope = (*cur).second.val_scope;
|
||||
|
||||
// The param_type may be nil if the parameter has no declared type. In
|
||||
// this case, we'll try to take our type from the r-value.
|
||||
ivl_type_t param_type = cur->second.ivl_type;
|
||||
|
||||
// Most parameter declarations are packed vectors, of the form:
|
||||
// parameter [H:L] foo == bar;
|
||||
// so get the netvector_t. Note that this may also be the special
|
||||
// case of a netvector_t with no dimensions, that exists only to carry
|
||||
// signed-ness, e.g.:
|
||||
// parameter signed foo = bar;
|
||||
// (Scalars are handled differently, not by a netvector_t with no
|
||||
// dimensions.)
|
||||
const netvector_t* param_vect = dynamic_cast<const netvector_t*> (param_type);
|
||||
|
||||
if (debug_elaborate) {
|
||||
cerr << val_expr->get_fileline() << ": " << __func__ << ": "
|
||||
<< "parameter=" << cur->first << endl;
|
||||
if (param_type)
|
||||
cerr << val_expr->get_fileline() << ": " << __func__ << ": "
|
||||
<< "param_type=" << *param_type << endl;
|
||||
else
|
||||
cerr << val_expr->get_fileline() << ": " << __func__ << ": "
|
||||
<< "param_type=(nil)" << endl;
|
||||
cerr << val_expr->get_fileline() << ": " << __func__ << ": "
|
||||
<< "val_expr=" << *val_expr << endl;
|
||||
}
|
||||
|
||||
ivl_variable_type_t use_type;
|
||||
int lv_width = -2;
|
||||
if (range_flag)
|
||||
lv_width = (msb >= lsb) ? 1 + msb - lsb : 1 + lsb - msb;
|
||||
if (param_type) {
|
||||
use_type = param_type->base_type();
|
||||
// Is this a netvector_t with no dimenions?
|
||||
if (param_vect && param_vect->packed_dims().size()==0)
|
||||
lv_width = -2;
|
||||
else if (param_type->packed())
|
||||
lv_width = param_type->packed_width();
|
||||
} else {
|
||||
use_type = val_expr->expr_type();
|
||||
}
|
||||
|
||||
if (debug_elaborate) {
|
||||
cerr << val_expr->get_fileline() << ": " << __func__ << ": "
|
||||
<< "use_type = " << use_type << endl;
|
||||
}
|
||||
|
||||
NetExpr*expr = elab_and_eval(des, val_scope, val_expr, lv_width, true,
|
||||
(*cur).second.is_annotatable,
|
||||
(*cur).second.type);
|
||||
cur->second.is_annotatable, use_type);
|
||||
if (! expr)
|
||||
return;
|
||||
|
||||
// Make sure to carry the signed-ness from a vector type.
|
||||
if (param_vect)
|
||||
expr->cast_signed(param_vect->get_signed());
|
||||
|
||||
if (debug_elaborate) {
|
||||
cerr << val_expr->get_fileline() << ": " << __func__ << ": "
|
||||
<< "expr = " << *expr << endl;
|
||||
cerr << val_expr->get_fileline() << ": " << __func__ << ": "
|
||||
<< "expr type = " << expr->expr_type() << endl;
|
||||
}
|
||||
|
||||
switch (expr->expr_type()) {
|
||||
case IVL_VT_REAL:
|
||||
if (! dynamic_cast<const NetECReal*>(expr)) {
|
||||
|
|
@ -567,6 +584,13 @@ void NetScope::evaluate_parameter_logic_(Design*des, param_ref_t cur)
|
|||
des->errors += 1;
|
||||
return;
|
||||
}
|
||||
|
||||
// If the parameter has no type, then infer its type from the
|
||||
// r-value expression.
|
||||
if (param_type==0) {
|
||||
param_type = &netreal_t::type_real;
|
||||
cur->second.ivl_type = param_type;
|
||||
}
|
||||
break;
|
||||
|
||||
case IVL_VT_LOGIC:
|
||||
|
|
@ -579,17 +603,20 @@ void NetScope::evaluate_parameter_logic_(Design*des, param_ref_t cur)
|
|||
return;
|
||||
}
|
||||
|
||||
// If the parameter has type or range information, then
|
||||
// make sure the type is set right. Note that if the
|
||||
// parameter doesn't have an explicit type or range,
|
||||
// then it will get the signedness from the expression itself.
|
||||
if (cur->second.type != IVL_VT_NO_TYPE) {
|
||||
expr->cast_signed(cur->second.signed_flag);
|
||||
} else if (cur->second.signed_flag) {
|
||||
expr->cast_signed(true);
|
||||
// If the parameter has no type, then infer its type from the
|
||||
// r-value expression.
|
||||
if (param_type==0) {
|
||||
param_type = new netvector_t(expr->expr_type(), expr->expr_width()-1,
|
||||
0, expr->has_sign());
|
||||
cur->second.ivl_type = param_type;
|
||||
}
|
||||
|
||||
if (!range_flag && !expr->has_width()) {
|
||||
if (param_type->base_type() != IVL_VT_NO_TYPE)
|
||||
expr->cast_signed(param_type->get_signed());
|
||||
|
||||
if (!expr->has_width()) {
|
||||
expr = pad_to_width(expr, integer_width, *expr);
|
||||
} else if (param_type->slice_dimensions().size()==0 && !expr->has_width()) {
|
||||
expr = pad_to_width(expr, integer_width, *expr);
|
||||
}
|
||||
break;
|
||||
|
|
@ -597,18 +624,25 @@ void NetScope::evaluate_parameter_logic_(Design*des, param_ref_t cur)
|
|||
default:
|
||||
cerr << expr->get_fileline()
|
||||
<< ": internal error: "
|
||||
<< "Unhandled expression type?" << endl;
|
||||
<< "Unhandled expression type "
|
||||
<< expr->expr_type() << "?" << endl;
|
||||
cerr << expr->get_fileline()
|
||||
<< ": : "
|
||||
<< "param_type: " << *param_type << endl;
|
||||
des->errors += 1;
|
||||
return;
|
||||
}
|
||||
|
||||
// By the time we're done with the above, we should certainly know the
|
||||
// type of the parameter.
|
||||
ivl_assert(*expr, cur->second.ivl_type);
|
||||
|
||||
cur->second.val = expr;
|
||||
|
||||
// If there are no value ranges to test the value against,
|
||||
// then we are done.
|
||||
if ((*cur).second.range == 0) {
|
||||
if ((*cur).second.range == 0)
|
||||
return;
|
||||
}
|
||||
|
||||
NetEConst*val = dynamic_cast<NetEConst*>((*cur).second.val);
|
||||
ivl_assert(*(*cur).second.val, (*cur).second.val);
|
||||
|
|
@ -671,10 +705,12 @@ void NetScope::evaluate_parameter_real_(Design*des, param_ref_t cur)
|
|||
{
|
||||
PExpr*val_expr = (*cur).second.val_expr;
|
||||
NetScope*val_scope = (*cur).second.val_scope;
|
||||
ivl_type_t param_type = cur->second.ivl_type;
|
||||
|
||||
ivl_assert(*val_expr, param_type);
|
||||
NetExpr*expr = elab_and_eval(des, val_scope, val_expr, -1, true,
|
||||
(*cur).second.is_annotatable,
|
||||
(*cur).second.type);
|
||||
cur->second.is_annotatable,
|
||||
param_type->base_type());
|
||||
if (! expr)
|
||||
return;
|
||||
|
||||
|
|
@ -755,18 +791,37 @@ void NetScope::evaluate_parameter_real_(Design*des, param_ref_t cur)
|
|||
|
||||
void NetScope::evaluate_parameter_(Design*des, param_ref_t cur)
|
||||
{
|
||||
ivl_type_t param_type = cur->second.ivl_type;
|
||||
|
||||
// If the parameter type is present, then elaborate it now.
|
||||
if (cur->second.val_type) {
|
||||
param_type = cur->second.val_type->elaborate_type(des, cur->second.val_scope);
|
||||
cur->second.ivl_type = param_type;
|
||||
cur->second.val_type = 0;
|
||||
}
|
||||
|
||||
// If the parameter has already been evaluated, quietly return.
|
||||
if (cur->second.val_expr == 0)
|
||||
return;
|
||||
|
||||
// Guess the varaiable type of the parameter. If the parameter has no
|
||||
// given type, then guess the type from the expression and use that to
|
||||
// evaluate.
|
||||
ivl_variable_type_t use_type;
|
||||
if (param_type)
|
||||
use_type = param_type->base_type();
|
||||
else
|
||||
use_type = cur->second.val_expr->expr_type();
|
||||
|
||||
if (cur->second.solving) {
|
||||
cerr << cur->second.get_fileline() << ": error: "
|
||||
<< "Recursive parameter reference found involving "
|
||||
<< cur->first << "." << endl;
|
||||
des->errors += 1;
|
||||
|
||||
} else {
|
||||
cur->second.solving = true;
|
||||
switch (cur->second.type) {
|
||||
switch (use_type) {
|
||||
case IVL_VT_NO_TYPE:
|
||||
case IVL_VT_BOOL:
|
||||
case IVL_VT_LOGIC:
|
||||
|
|
@ -779,7 +834,7 @@ void NetScope::evaluate_parameter_(Design*des, param_ref_t cur)
|
|||
|
||||
default:
|
||||
cerr << cur->second.get_fileline() << ": internal error: "
|
||||
<< "Unexpected expression type " << cur->second.type
|
||||
<< "Unexpected expression type " << use_type
|
||||
<< "." << endl;
|
||||
cerr << cur->second.get_fileline() << ": : "
|
||||
<< "Parameter name: " << cur->first << endl;
|
||||
|
|
|
|||
62
net_scope.cc
62
net_scope.cc
|
|
@ -198,6 +198,22 @@ void NetScope::set_line(perm_string file, unsigned lineno)
|
|||
def_lineno_ = lineno;
|
||||
}
|
||||
|
||||
string NetScope::get_fileline() const
|
||||
{
|
||||
ostringstream buf;
|
||||
buf << (file_? file_ : "") << ":" << lineno_;
|
||||
string res = buf.str();
|
||||
return res;
|
||||
}
|
||||
|
||||
string NetScope::get_def_fileline() const
|
||||
{
|
||||
ostringstream buf;
|
||||
buf << (def_file_? def_file_ : "") << ":" << def_lineno_;
|
||||
string res = buf.str();
|
||||
return res;
|
||||
}
|
||||
|
||||
void NetScope::set_line(perm_string file, perm_string def_file,
|
||||
unsigned lineno, unsigned def_lineno)
|
||||
{
|
||||
|
|
@ -279,27 +295,28 @@ const netenum_t*NetScope::find_enumeration_for_name(const Design*des, perm_strin
|
|||
return cur_scope->enum_names_[name]->enumeration();
|
||||
}
|
||||
|
||||
/*
|
||||
* Attach to the a parameter name in the scope a value and a type. The value
|
||||
* (val_expr) is the PExpr form that is not yet elaborated. Later, when
|
||||
* elaboration happens, the val_expr is elaborated and written to the val
|
||||
* member.
|
||||
*/
|
||||
void NetScope::set_parameter(perm_string key, bool is_annotatable,
|
||||
PExpr*val, ivl_variable_type_t type__,
|
||||
PExpr*msb, PExpr*lsb, bool signed_flag,
|
||||
PExpr*val, data_type_t*val_type,
|
||||
bool local_flag,
|
||||
NetScope::range_t*range_list,
|
||||
const LineInfo&file_line)
|
||||
{
|
||||
param_expr_t&ref = parameters[key];
|
||||
ref.is_annotatable = is_annotatable;
|
||||
ref.msb_expr = msb;
|
||||
ref.lsb_expr = lsb;
|
||||
ref.val_expr = val;
|
||||
ref.val_type = val_type;
|
||||
ref.val_scope = this;
|
||||
ref.type = type__;
|
||||
ref.msb = 0;
|
||||
ref.lsb = 0;
|
||||
ref.signed_flag = signed_flag;
|
||||
ref.local_flag = local_flag;
|
||||
ivl_assert(file_line, ref.range == 0);
|
||||
ref.range = range_list;
|
||||
ref.val = 0;
|
||||
ref.ivl_type = 0;
|
||||
ref.set_line(file_line);
|
||||
}
|
||||
|
||||
|
|
@ -313,14 +330,11 @@ void NetScope::set_parameter(perm_string key, NetExpr*val,
|
|||
{
|
||||
param_expr_t&ref = parameters[key];
|
||||
ref.is_annotatable = false;
|
||||
ref.msb_expr = 0;
|
||||
ref.lsb_expr = 0;
|
||||
ref.val_expr = 0;
|
||||
ref.val_type = 0;
|
||||
ref.val_scope = this;
|
||||
ref.type = IVL_VT_BOOL;
|
||||
ref.msb = 0;
|
||||
ref.lsb = 0;
|
||||
ref.signed_flag = false;
|
||||
ref.ivl_type = netvector_t::integer_type();
|
||||
ivl_assert(file_line, ref.ivl_type);
|
||||
ref.val = val;
|
||||
ref.set_line(file_line);
|
||||
}
|
||||
|
|
@ -399,18 +413,14 @@ bool NetScope::make_parameter_unannotatable(perm_string key)
|
|||
* perm_string::literal method to fake the compiler into doing the
|
||||
* compare without actually creating a perm_string.
|
||||
*/
|
||||
const NetExpr* NetScope::get_parameter(Design*des,
|
||||
const char* key,
|
||||
const NetExpr*&msb,
|
||||
const NetExpr*&lsb)
|
||||
const NetExpr* NetScope::get_parameter(Design*des, const char* key,
|
||||
ivl_type_t&ivl_type)
|
||||
{
|
||||
return get_parameter(des, perm_string::literal(key), msb, lsb);
|
||||
return get_parameter(des, perm_string::literal(key), ivl_type);
|
||||
}
|
||||
|
||||
const NetExpr* NetScope::get_parameter(Design*des,
|
||||
perm_string key,
|
||||
const NetExpr*&msb,
|
||||
const NetExpr*&lsb)
|
||||
const NetExpr* NetScope::get_parameter(Design*des, perm_string key,
|
||||
ivl_type_t&ivl_type)
|
||||
{
|
||||
map<perm_string,param_expr_t>::iterator idx;
|
||||
|
||||
|
|
@ -419,13 +429,11 @@ const NetExpr* NetScope::get_parameter(Design*des,
|
|||
if (idx->second.val_expr)
|
||||
evaluate_parameter_(des, idx);
|
||||
|
||||
msb = idx->second.msb;
|
||||
lsb = idx->second.lsb;
|
||||
ivl_type = idx->second.ivl_type;
|
||||
return idx->second.val;
|
||||
}
|
||||
|
||||
msb = 0;
|
||||
lsb = 0;
|
||||
ivl_type = 0;
|
||||
const NetExpr*tmp = enumeration_expr(key);
|
||||
return tmp;
|
||||
}
|
||||
|
|
|
|||
38
netlist.h
38
netlist.h
|
|
@ -79,6 +79,7 @@ class PExpr;
|
|||
class PFunction;
|
||||
class PPackage;
|
||||
class PTaskFunc;
|
||||
class data_type_t;
|
||||
struct enum_type_t;
|
||||
class netclass_t;
|
||||
class netdarray_t;
|
||||
|
|
@ -965,22 +966,17 @@ class NetScope : public Definitions, public Attrib {
|
|||
|
||||
struct range_t;
|
||||
void set_parameter(perm_string name, bool is_annotatable,
|
||||
PExpr*val, ivl_variable_type_t type,
|
||||
PExpr*msb, PExpr*lsb, bool signed_flag,
|
||||
PExpr*val, data_type_t*data_type,
|
||||
bool local_flag,
|
||||
NetScope::range_t*range_list,
|
||||
const LineInfo&file_line);
|
||||
void set_parameter(perm_string name, NetExpr*val,
|
||||
const LineInfo&file_line);
|
||||
|
||||
const NetExpr*get_parameter(Design*des,
|
||||
const char* name,
|
||||
const NetExpr*&msb,
|
||||
const NetExpr*&lsb);
|
||||
const NetExpr*get_parameter(Design*des,
|
||||
perm_string name,
|
||||
const NetExpr*&msb,
|
||||
const NetExpr*&lsb);
|
||||
const NetExpr*get_parameter(Design*des, const char* name,
|
||||
ivl_type_t&ivl_type);
|
||||
const NetExpr*get_parameter(Design*des, perm_string name,
|
||||
ivl_type_t&ivl_type);
|
||||
|
||||
/* These are used by defparam elaboration to replace the
|
||||
expression with a new expression, without affecting the
|
||||
|
|
@ -1073,6 +1069,9 @@ class NetScope : public Definitions, public Attrib {
|
|||
unsigned get_lineno() const { return lineno_; };
|
||||
unsigned get_def_lineno() const { return def_lineno_; };
|
||||
|
||||
std::string get_fileline() const;
|
||||
std::string get_def_fileline() const;
|
||||
|
||||
bool in_func() const;
|
||||
|
||||
/* Provide a link back to the pform to allow early elaboration of
|
||||
|
|
@ -1210,31 +1209,26 @@ class NetScope : public Definitions, public Attrib {
|
|||
/* After everything is all set up, the code generators like
|
||||
access to these things to make up the parameter lists. */
|
||||
struct param_expr_t : public LineInfo {
|
||||
param_expr_t() : msb_expr(0), lsb_expr(0), val_expr(0), val_scope(0),
|
||||
param_expr_t() : val_expr(0), val_type(0), val_scope(0),
|
||||
solving(false), is_annotatable(false),
|
||||
type(IVL_VT_NO_TYPE), signed_flag(false),
|
||||
local_flag(false),
|
||||
msb(0), lsb(0), range(0), val(0) { }
|
||||
// Source expressions
|
||||
PExpr*msb_expr;
|
||||
PExpr*lsb_expr;
|
||||
range(0), val(0), ivl_type(0) { }
|
||||
// Source expression and data type (before elaboration)
|
||||
PExpr*val_expr;
|
||||
data_type_t*val_type;
|
||||
// Scope information
|
||||
NetScope*val_scope;
|
||||
// Evaluation status
|
||||
bool solving;
|
||||
// specparam status
|
||||
bool is_annotatable;
|
||||
// Type information
|
||||
ivl_variable_type_t type;
|
||||
bool signed_flag;
|
||||
// Is this a localparam?
|
||||
bool local_flag;
|
||||
NetExpr*msb;
|
||||
NetExpr*lsb;
|
||||
// range constraints
|
||||
struct range_t*range;
|
||||
// Expression value
|
||||
// Expression value and type (elaborated versoins of val_expr/val_type)
|
||||
NetExpr*val;
|
||||
ivl_type_t ivl_type;
|
||||
};
|
||||
map<perm_string,param_expr_t>parameters;
|
||||
|
||||
|
|
|
|||
49
netmisc.cc
49
netmisc.cc
|
|
@ -1809,3 +1809,52 @@ void check_for_inconsistent_delays(NetScope*scope)
|
|||
display_ts_dly_warning = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Calculate the bit vector range for a parameter, from the type of the
|
||||
* parameter. This is expecting that the type is a vector type. The parameter
|
||||
* is presumably declared something like this:
|
||||
*
|
||||
* parameter [4:1] foo = <value>;
|
||||
*
|
||||
* In this case, the par_type is a netvector with a single dimension. The
|
||||
* par_msv gets 4, and par_lsv get 1. The caller uses these values to
|
||||
* interpret things like bit selects.
|
||||
*/
|
||||
bool calculate_param_range(const LineInfo&line, ivl_type_t par_type,
|
||||
long&par_msv, long&par_lsv, long length)
|
||||
{
|
||||
const netvector_t*vector_type = dynamic_cast<const netvector_t*> (par_type);
|
||||
if (vector_type == 0) {
|
||||
// If the parameter doesn't have an explicit range, then
|
||||
// just return range values of [length-1:0].
|
||||
par_msv = length-1;
|
||||
par_lsv = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
ivl_assert(line, vector_type->packed());
|
||||
const std::vector<netrange_t>& packed_dims = vector_type->packed_dims();
|
||||
|
||||
// This is a netvector_t with 0 dimensions, then the parameter was
|
||||
// declared with a statement like this:
|
||||
//
|
||||
// parameter signed foo = <value>;
|
||||
//
|
||||
// The netvector_t is just here to carry the signed-ness, which we don't
|
||||
// even need here. So act like the type is defined by the r-value
|
||||
// length.
|
||||
if (packed_dims.size() == 0) {
|
||||
par_msv = length-1;
|
||||
par_lsv = 0;
|
||||
return true;
|
||||
}
|
||||
ivl_assert(line, packed_dims.size() == 1);
|
||||
|
||||
netrange_t use_range = packed_dims[0];
|
||||
par_msv = use_range.get_msb();
|
||||
par_lsv = use_range.get_lsb();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ extern NetScope* symbol_search(const LineInfo*li,
|
|||
NetNet*&net, /* net/reg */
|
||||
const NetExpr*&par,/* parameter/expr */
|
||||
NetEvent*&eve, /* named event */
|
||||
const NetExpr*&ex1, const NetExpr*&ex2);
|
||||
ivl_type_t&par_type);
|
||||
|
||||
inline NetScope* symbol_search(const LineInfo*li,
|
||||
Design*des,
|
||||
|
|
@ -55,8 +55,8 @@ inline NetScope* symbol_search(const LineInfo*li,
|
|||
const NetExpr*&par,/* parameter/expr */
|
||||
NetEvent*&eve /* named event */)
|
||||
{
|
||||
const NetExpr*ex1, *ex2;
|
||||
return symbol_search(li, des, start, path, net, par, eve, ex1, ex2);
|
||||
ivl_type_t par_type;
|
||||
return symbol_search(li, des, start, path, net, par, eve, par_type);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -160,3 +160,4 @@ bool prefix_to_slice(const std::vector<netrange_t>&dims,
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
10
nettypes.h
10
nettypes.h
|
|
@ -27,6 +27,7 @@
|
|||
# include <cassert>
|
||||
|
||||
class netrange_t;
|
||||
class LineInfo;
|
||||
|
||||
/*
|
||||
* This is a fully abstract type that is a type that can be attached
|
||||
|
|
@ -135,6 +136,15 @@ extern std::ostream&operator << (std::ostream&out, const std::vector<netrange_t>
|
|||
|
||||
extern unsigned long netrange_width(const std::vector<netrange_t>&dims);
|
||||
|
||||
/*
|
||||
* There are a few cases where we need to know about the single-level
|
||||
* dimensions of a parameter declaration, for example:
|
||||
*
|
||||
* parameter [msv:lsv] foo ...;
|
||||
*/
|
||||
extern bool calculate_param_range(const LineInfo&line, ivl_type_t par_type,
|
||||
long&par_msv, long&par_lsv, long length);
|
||||
|
||||
/*
|
||||
* Take as input a list of packed dimensions and a list of prefix
|
||||
* indices, and calculate the offset/width of the resulting slice into
|
||||
|
|
|
|||
12
netvector.cc
12
netvector.cc
|
|
@ -18,6 +18,7 @@
|
|||
*/
|
||||
|
||||
# include "netvector.h"
|
||||
# include "compiler.h"
|
||||
# include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
|
@ -31,6 +32,17 @@ netvector_t netvector_t::atom2u16 (IVL_VT_BOOL, 15, 0, false);
|
|||
netvector_t netvector_t::atom2s8 (IVL_VT_BOOL, 7, 0, true);
|
||||
netvector_t netvector_t::atom2u8 (IVL_VT_BOOL, 7, 0, false);
|
||||
|
||||
static netvector_t* save_integer_type = 0;
|
||||
const netvector_t* netvector_t::integer_type()
|
||||
{
|
||||
if (save_integer_type)
|
||||
return save_integer_type;
|
||||
|
||||
save_integer_type = new netvector_t(IVL_VT_LOGIC, integer_width-1, 0, true);
|
||||
save_integer_type->set_isint(true);
|
||||
return save_integer_type;
|
||||
}
|
||||
|
||||
//netvector_t netvector_t::scalar_bool (IVL_VT_BOOL);
|
||||
netvector_t netvector_t::scalar_logic (IVL_VT_LOGIC);
|
||||
|
||||
|
|
|
|||
|
|
@ -78,6 +78,7 @@ class netvector_t : public ivl_type_s {
|
|||
static netvector_t atom2u8;
|
||||
static netvector_t scalar_bool;
|
||||
static netvector_t scalar_logic;
|
||||
static const netvector_t*integer_type();
|
||||
|
||||
private:
|
||||
bool test_compatibility(ivl_type_t that) const;
|
||||
|
|
|
|||
73
parse.y
73
parse.y
|
|
@ -35,9 +35,8 @@ class PSpecPath;
|
|||
|
||||
extern void lex_end_table();
|
||||
|
||||
static list<pform_range_t>* param_active_range = 0;
|
||||
static bool param_active_signed = false;
|
||||
static ivl_variable_type_t param_active_type = IVL_VT_LOGIC;
|
||||
static data_type_t* param_data_type = 0;
|
||||
static list<pform_range_t>* specparam_active_range = 0;
|
||||
|
||||
/* Port declaration lists use this structure for context. */
|
||||
static struct {
|
||||
|
|
@ -649,7 +648,6 @@ static void current_function_set_statement(const YYLTYPE&loc, vector<Statement*>
|
|||
%type <nettype> net_type net_type_opt
|
||||
%type <gatetype> gatetype switchtype
|
||||
%type <porttype> port_direction port_direction_opt
|
||||
%type <vartype> bit_logic bit_logic_opt
|
||||
%type <vartype> integer_vector_type
|
||||
%type <parmvalue> parameter_value_opt
|
||||
|
||||
|
|
@ -5484,17 +5482,6 @@ net_decl_assigns
|
|||
}
|
||||
;
|
||||
|
||||
bit_logic
|
||||
: K_logic { $$ = IVL_VT_LOGIC; }
|
||||
| K_bool { $$ = IVL_VT_BOOL; /* Icarus misc */}
|
||||
| K_bit { $$ = IVL_VT_BOOL; /* IEEE1800 / IEEE1364-2009 */}
|
||||
;
|
||||
|
||||
bit_logic_opt
|
||||
: bit_logic
|
||||
| { $$ = IVL_VT_NO_TYPE; }
|
||||
;
|
||||
|
||||
net_type
|
||||
: K_wire { $$ = NetNet::WIRE; }
|
||||
| K_tri { $$ = NetNet::TRI; }
|
||||
|
|
@ -5514,42 +5501,12 @@ net_type
|
|||
| K_uwire { $$ = NetNet::UNRESOLVED_WIRE; }
|
||||
;
|
||||
|
||||
param_type
|
||||
: bit_logic_opt unsigned_signed_opt dimensions_opt
|
||||
{ param_active_range = $3;
|
||||
param_active_signed = $2;
|
||||
if (($1 == IVL_VT_NO_TYPE) && ($3 != 0))
|
||||
param_active_type = IVL_VT_LOGIC;
|
||||
else
|
||||
param_active_type = $1;
|
||||
}
|
||||
| K_integer signed_unsigned_opt
|
||||
{ param_active_range = make_range_from_width(integer_width);
|
||||
param_active_signed = $2;
|
||||
param_active_type = IVL_VT_LOGIC;
|
||||
}
|
||||
| K_time unsigned_signed_opt
|
||||
{ param_active_range = make_range_from_width(64);
|
||||
param_active_signed = $2;
|
||||
param_active_type = IVL_VT_LOGIC;
|
||||
}
|
||||
| real_or_realtime
|
||||
{ param_active_range = 0;
|
||||
param_active_signed = true;
|
||||
param_active_type = IVL_VT_REAL;
|
||||
}
|
||||
| atom2_type signed_unsigned_opt
|
||||
{ param_active_range = make_range_from_width($1);
|
||||
param_active_signed = $2;
|
||||
param_active_type = IVL_VT_BOOL;
|
||||
}
|
||||
| TYPE_IDENTIFIER
|
||||
{ pform_set_type_referenced(@1, $1.text);
|
||||
pform_set_param_from_type(@1, $1.type, $1.text, param_active_range,
|
||||
param_active_signed, param_active_type);
|
||||
delete[]$1.text;
|
||||
}
|
||||
;
|
||||
/* The param_type rule is just the data_type_or_implicit rule wrapped
|
||||
with an assignment to para_data_type with the figured data type.
|
||||
This is used by parameter_assign, which is found to the right of
|
||||
the param_type in various rules. */
|
||||
|
||||
param_type : data_type_or_implicit { param_data_type = $1; }
|
||||
|
||||
/* parameter and localparam assignment lists are broken into
|
||||
separate BNF so that I can call slightly different parameter
|
||||
|
|
@ -5569,8 +5526,7 @@ localparam_assign_list
|
|||
parameter_assign
|
||||
: IDENTIFIER '=' expression parameter_value_ranges_opt
|
||||
{ PExpr*tmp = $3;
|
||||
pform_set_parameter(@1, lex_strings.make($1), param_active_type,
|
||||
param_active_signed, param_active_range, tmp, $4);
|
||||
pform_set_parameter(@1, lex_strings.make($1), param_data_type, tmp, $4);
|
||||
delete[]$1;
|
||||
}
|
||||
;
|
||||
|
|
@ -5578,8 +5534,7 @@ parameter_assign
|
|||
localparam_assign
|
||||
: IDENTIFIER '=' expression
|
||||
{ PExpr*tmp = $3;
|
||||
pform_set_localparam(@1, lex_strings.make($1), param_active_type,
|
||||
param_active_signed, param_active_range, tmp);
|
||||
pform_set_localparam(@1, lex_strings.make($1), param_data_type, tmp);
|
||||
delete[]$1;
|
||||
}
|
||||
;
|
||||
|
|
@ -6305,7 +6260,7 @@ specparam
|
|||
: IDENTIFIER '=' expression
|
||||
{ PExpr*tmp = $3;
|
||||
pform_set_specparam(@1, lex_strings.make($1),
|
||||
param_active_range, tmp);
|
||||
specparam_active_range, tmp);
|
||||
delete[]$1;
|
||||
}
|
||||
| IDENTIFIER '=' expression ':' expression ':' expression
|
||||
|
|
@ -6344,7 +6299,7 @@ specparam
|
|||
min_typ_max_warn -= 1;
|
||||
}
|
||||
pform_set_specparam(@1, lex_strings.make($1),
|
||||
param_active_range, tmp);
|
||||
specparam_active_range, tmp);
|
||||
delete[]$1;
|
||||
}
|
||||
| PATHPULSE_IDENTIFIER '=' expression
|
||||
|
|
@ -6366,9 +6321,9 @@ specparam_list
|
|||
specparam_decl
|
||||
: specparam_list
|
||||
| dimensions
|
||||
{ param_active_range = $1; }
|
||||
{ specparam_active_range = $1; }
|
||||
specparam_list
|
||||
{ param_active_range = 0; }
|
||||
{ specparam_active_range = 0; }
|
||||
;
|
||||
|
||||
spec_polarity
|
||||
|
|
|
|||
51
pform.cc
51
pform.cc
|
|
@ -3168,8 +3168,7 @@ LexicalScope::range_t* pform_parameter_value_range(bool exclude_flag,
|
|||
}
|
||||
|
||||
void pform_set_parameter(const struct vlltype&loc,
|
||||
perm_string name, ivl_variable_type_t type,
|
||||
bool signed_flag, list<pform_range_t>*range, PExpr*expr,
|
||||
perm_string name, data_type_t*data_type, PExpr*expr,
|
||||
LexicalScope::range_t*value_range)
|
||||
{
|
||||
LexicalScope*scope = lexical_scope;
|
||||
|
|
@ -3190,20 +3189,7 @@ void pform_set_parameter(const struct vlltype&loc,
|
|||
scope->parameters[name] = parm;
|
||||
|
||||
parm->expr = expr;
|
||||
|
||||
parm->type = type;
|
||||
if (range) {
|
||||
assert(range->size() == 1);
|
||||
pform_range_t&rng = range->front();
|
||||
assert(rng.first);
|
||||
assert(rng.second);
|
||||
parm->msb = rng.first;
|
||||
parm->lsb = rng.second;
|
||||
} else {
|
||||
parm->msb = 0;
|
||||
parm->lsb = 0;
|
||||
}
|
||||
parm->signed_flag = signed_flag;
|
||||
parm->data_type = data_type;
|
||||
parm->range = value_range;
|
||||
|
||||
// Only a Module keeps the position of the parameter.
|
||||
|
|
@ -3212,8 +3198,7 @@ void pform_set_parameter(const struct vlltype&loc,
|
|||
}
|
||||
|
||||
void pform_set_localparam(const struct vlltype&loc,
|
||||
perm_string name, ivl_variable_type_t type,
|
||||
bool signed_flag, list<pform_range_t>*range, PExpr*expr)
|
||||
perm_string name, data_type_t*data_type, PExpr*expr)
|
||||
{
|
||||
LexicalScope*scope = lexical_scope;
|
||||
if (is_compilation_unit(scope) && !gn_system_verilog()) {
|
||||
|
|
@ -3229,20 +3214,7 @@ void pform_set_localparam(const struct vlltype&loc,
|
|||
scope->localparams[name] = parm;
|
||||
|
||||
parm->expr = expr;
|
||||
|
||||
parm->type = type;
|
||||
if (range) {
|
||||
assert(range->size() == 1);
|
||||
pform_range_t&rng = range->front();
|
||||
assert(rng.first);
|
||||
assert(rng.second);
|
||||
parm->msb = rng.first;
|
||||
parm->lsb = rng.second;
|
||||
} else {
|
||||
parm->msb = 0;
|
||||
parm->lsb = 0;
|
||||
}
|
||||
parm->signed_flag = signed_flag;
|
||||
parm->data_type = data_type;
|
||||
parm->range = 0;
|
||||
}
|
||||
|
||||
|
|
@ -3261,22 +3233,13 @@ void pform_set_specparam(const struct vlltype&loc, perm_string name,
|
|||
pform_cur_module.front()->specparams[name] = parm;
|
||||
|
||||
parm->expr = expr;
|
||||
parm->range = 0;
|
||||
|
||||
if (range) {
|
||||
assert(range->size() == 1);
|
||||
pform_range_t&rng = range->front();
|
||||
assert(rng.first);
|
||||
assert(rng.second);
|
||||
parm->type = IVL_VT_LOGIC;
|
||||
parm->msb = rng.first;
|
||||
parm->lsb = rng.second;
|
||||
} else {
|
||||
parm->type = IVL_VT_NO_TYPE;
|
||||
parm->msb = 0;
|
||||
parm->lsb = 0;
|
||||
}
|
||||
parm->signed_flag = false;
|
||||
parm->data_type = new vector_type_t(IVL_VT_LOGIC, false, range);
|
||||
parm->range = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void pform_set_defparam(const pform_name_t&name, PExpr*expr)
|
||||
|
|
|
|||
8
pform.h
8
pform.h
|
|
@ -418,15 +418,11 @@ extern LexicalScope::range_t* pform_parameter_value_range(bool exclude_flag,
|
|||
|
||||
extern void pform_set_parameter(const struct vlltype&loc,
|
||||
perm_string name,
|
||||
ivl_variable_type_t type,
|
||||
bool signed_flag,
|
||||
list<pform_range_t>*range,
|
||||
data_type_t*data_type,
|
||||
PExpr*expr, LexicalScope::range_t*value_range);
|
||||
extern void pform_set_localparam(const struct vlltype&loc,
|
||||
perm_string name,
|
||||
ivl_variable_type_t type,
|
||||
bool signed_flag,
|
||||
list<pform_range_t>*range,
|
||||
data_type_t*data_type,
|
||||
PExpr*expr);
|
||||
extern void pform_set_specparam(const struct vlltype&loc,
|
||||
perm_string name,
|
||||
|
|
|
|||
|
|
@ -165,6 +165,12 @@ void data_type_t::pform_dump(ostream&out, unsigned indent) const
|
|||
out << setw(indent) << "" << typeid(*this).name() << endl;
|
||||
}
|
||||
|
||||
ostream& data_type_t::debug_dump(ostream&out) const
|
||||
{
|
||||
out << typeid(*this).name();
|
||||
return out;
|
||||
}
|
||||
|
||||
void void_type_t::pform_dump(ostream&out, unsigned indent) const
|
||||
{
|
||||
out << setw(indent) << "" << "void" << endl;
|
||||
|
|
@ -213,6 +219,25 @@ void vector_type_t::pform_dump(ostream&fd, unsigned indent) const
|
|||
fd << endl;
|
||||
}
|
||||
|
||||
ostream& vector_type_t::debug_dump(ostream&fd) const
|
||||
{
|
||||
if (signed_flag)
|
||||
fd << "signed ";
|
||||
if (pdims==nullptr) {
|
||||
fd << "/* vector_type_t nil */";
|
||||
return fd;
|
||||
}
|
||||
|
||||
for (list<pform_range_t>::iterator cur = pdims->begin()
|
||||
; cur != pdims->end() ; ++cur) {
|
||||
fd << "[";
|
||||
if (cur->first) fd << *(cur->first);
|
||||
if (cur->second) fd << ":" << *(cur->second);
|
||||
fd << "]";
|
||||
}
|
||||
return fd;
|
||||
}
|
||||
|
||||
void class_type_t::pform_dump(ostream&out, unsigned indent) const
|
||||
{
|
||||
out << setw(indent) << "" << "class " << name;
|
||||
|
|
@ -1389,14 +1414,12 @@ void LexicalScope::dump_parameters_(ostream&out, unsigned indent) const
|
|||
typedef map<perm_string,param_expr_t*>::const_iterator parm_iter_t;
|
||||
for (parm_iter_t cur = parameters.begin()
|
||||
; cur != parameters.end() ; ++ cur ) {
|
||||
out << setw(indent) << "" << "parameter "
|
||||
<< (*cur).second->type << " ";
|
||||
if ((*cur).second->signed_flag)
|
||||
out << "signed ";
|
||||
if ((*cur).second->msb)
|
||||
out << "[" << *(*cur).second->msb << ":"
|
||||
<< *(*cur).second->lsb << "] ";
|
||||
out << (*cur).first << " = ";
|
||||
out << setw(indent) << "" << "parameter ";
|
||||
if (cur->second->data_type)
|
||||
cur->second->data_type->debug_dump(out);
|
||||
else
|
||||
out << "(nil type)";
|
||||
out << " " << (*cur).first << " = ";
|
||||
if ((*cur).second->expr)
|
||||
out << *(*cur).second->expr;
|
||||
else
|
||||
|
|
@ -1439,9 +1462,10 @@ void LexicalScope::dump_localparams_(ostream&out, unsigned indent) const
|
|||
for (parm_iter_t cur = localparams.begin()
|
||||
; cur != localparams.end() ; ++ cur ) {
|
||||
out << setw(indent) << "" << "localparam ";
|
||||
if ((*cur).second->msb)
|
||||
out << "[" << *(*cur).second->msb << ":"
|
||||
<< *(*cur).second->lsb << "] ";
|
||||
if (cur->second->data_type) {
|
||||
cur->second->data_type->debug_dump(out);
|
||||
out << " ";
|
||||
}
|
||||
out << (*cur).first << " = ";
|
||||
if ((*cur).second->expr)
|
||||
out << *(*cur).second->expr << ";" << endl;
|
||||
|
|
@ -1544,9 +1568,11 @@ void Module::dump_specparams_(ostream&out, unsigned indent) const
|
|||
for (parm_iter_t cur = specparams.begin()
|
||||
; cur != specparams.end() ; ++ cur ) {
|
||||
out << setw(indent) << "" << "specparam ";
|
||||
if ((*cur).second->msb)
|
||||
out << "[" << *(*cur).second->msb << ":"
|
||||
<< *(*cur).second->lsb << "] ";
|
||||
if (cur->second->data_type)
|
||||
cur->second->data_type->debug_dump(out);
|
||||
else
|
||||
out << "(nil type)";
|
||||
|
||||
out << (*cur).first << " = ";
|
||||
if ((*cur).second->expr)
|
||||
out << *(*cur).second->expr << ";" << endl;
|
||||
|
|
|
|||
|
|
@ -144,8 +144,11 @@ class data_type_t : public PNamedItem {
|
|||
// This method is used to figure out the base type of a packed
|
||||
// compound object. Return IVL_VT_NO_TYPE if the type is not packed.
|
||||
virtual ivl_variable_type_t figure_packed_base_type(void)const;
|
||||
// This method is used by the pform dumper to diagnostic dump.
|
||||
// This method is used by the pform dumper to diagnostic dump. The
|
||||
// pform_dump dumps type type in pform format, and the debug_dump
|
||||
// prints the output in a linear form.
|
||||
virtual void pform_dump(std::ostream&out, unsigned indent) const;
|
||||
virtual std::ostream& debug_dump(std::ostream&out) const;
|
||||
|
||||
ivl_type_s* elaborate_type(Design*des, NetScope*scope);
|
||||
|
||||
|
|
@ -237,6 +240,7 @@ struct vector_type_t : public data_type_t {
|
|||
: base_type(bt), signed_flag(sf), reg_flag(false), integer_flag(false), implicit_flag(false), pdims(pd) { }
|
||||
virtual ivl_variable_type_t figure_packed_base_type(void)const;
|
||||
virtual void pform_dump(std::ostream&out, unsigned indent) const;
|
||||
virtual std::ostream& debug_dump(std::ostream&out) const;
|
||||
ivl_type_s* elaborate_type_raw(Design*des, NetScope*scope) const;
|
||||
|
||||
ivl_variable_type_t base_type;
|
||||
|
|
@ -389,6 +393,11 @@ inline perm_string peek_tail_name(const pform_name_t&that)
|
|||
# define SUPER_TOKEN "#"
|
||||
# define THIS_TOKEN "@"
|
||||
|
||||
static inline std::ostream& operator<< (std::ostream&out, const data_type_t&that)
|
||||
{
|
||||
return that.debug_dump(out);
|
||||
}
|
||||
|
||||
extern std::ostream& operator<< (std::ostream&out, const pform_name_t&);
|
||||
extern std::ostream& operator<< (std::ostream&out, const name_component_t&that);
|
||||
extern std::ostream& operator<< (std::ostream&out, const index_component_t&that);
|
||||
|
|
|
|||
|
|
@ -31,8 +31,7 @@ struct symbol_search_results {
|
|||
scope = 0;
|
||||
net = 0;
|
||||
par_val = 0;
|
||||
par_msb = 0;
|
||||
par_lsb = 0;
|
||||
par_type = 0;
|
||||
eve = 0;
|
||||
}
|
||||
|
||||
|
|
@ -52,8 +51,7 @@ struct symbol_search_results {
|
|||
// If this was a parameter, the value expression and the
|
||||
// optional value dimensions.
|
||||
const NetExpr*par_val;
|
||||
const NetExpr*par_msb;
|
||||
const NetExpr*par_lsb;
|
||||
ivl_type_t par_type;
|
||||
// If this is a named event, ...
|
||||
NetEvent*eve;
|
||||
};
|
||||
|
|
@ -129,7 +127,7 @@ static bool symbol_search(const LineInfo*li, Design*des, NetScope*scope,
|
|||
return true;
|
||||
}
|
||||
|
||||
if (const NetExpr*par = scope->get_parameter(des, path_tail.name, res->par_msb, res->par_lsb)) {
|
||||
if (const NetExpr*par = scope->get_parameter(des, path_tail.name, res->par_type)) {
|
||||
res->scope = scope;
|
||||
res->par_val = par;
|
||||
return true;
|
||||
|
|
@ -191,14 +189,13 @@ NetScope*symbol_search(const LineInfo*li, Design*des, NetScope*scope,
|
|||
NetNet*&net,
|
||||
const NetExpr*&par,
|
||||
NetEvent*&eve,
|
||||
const NetExpr*&ex1, const NetExpr*&ex2)
|
||||
ivl_type_t&par_type)
|
||||
{
|
||||
symbol_search_results recurse;
|
||||
bool flag = symbol_search(li, des, scope, path, &recurse);
|
||||
net = recurse.net;
|
||||
par = recurse.par_val;
|
||||
ex1 = recurse.par_msb;
|
||||
ex2 = recurse.par_lsb;
|
||||
par_type = recurse.par_type;
|
||||
eve = recurse.eve;
|
||||
if (! flag) {
|
||||
return 0;
|
||||
|
|
|
|||
31
t-dll.cc
31
t-dll.cc
|
|
@ -506,26 +506,19 @@ void dll_target::make_scope_parameters(ivl_scope_t scop, const NetScope*net)
|
|||
ivl_parameter_t cur_par = &scop->param[idx];
|
||||
cur_par->basename = cur_pit->first;
|
||||
cur_par->local = cur_pit->second.local_flag;
|
||||
/* Either both the MSB and LSB expressions are provided or
|
||||
* neither are provided. */
|
||||
if (cur_pit->second.msb) {
|
||||
assert(cur_pit->second.lsb);
|
||||
/* The MSB and LSB expressions must be integral constants. */
|
||||
const NetEConst *msbc =
|
||||
dynamic_cast<const NetEConst*>(cur_pit->second.msb);
|
||||
const NetEConst *lsbc =
|
||||
dynamic_cast<const NetEConst*>(cur_pit->second.lsb);
|
||||
assert(msbc);
|
||||
assert(lsbc);
|
||||
cur_par->msb = msbc->value().as_long();
|
||||
cur_par->lsb = lsbc->value().as_long();
|
||||
} else {
|
||||
assert(! cur_pit->second.lsb);
|
||||
cur_par->msb = cur_pit->second.val->expr_width() - 1;
|
||||
assert(cur_par->msb >= 0);
|
||||
cur_par->lsb = 0;
|
||||
calculate_param_range(cur_pit->second,
|
||||
cur_pit->second.ivl_type,
|
||||
cur_par->msb, cur_par->lsb,
|
||||
cur_pit->second.val->expr_width());
|
||||
|
||||
if (cur_pit->second.ivl_type == 0) {
|
||||
cerr << "?:?: internal error: "
|
||||
<< "No type for parameter " << cur_pit->first
|
||||
<< " in scope " << net->fullname() << "?" << endl;
|
||||
}
|
||||
cur_par->signed_flag = cur_pit->second.signed_flag;
|
||||
assert(cur_pit->second.ivl_type);
|
||||
|
||||
cur_par->signed_flag = cur_pit->second.ivl_type->get_signed();
|
||||
cur_par->scope = scop;
|
||||
FILE_NAME(cur_par, &(cur_pit->second));
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue