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;
|
NetNet* net = 0;
|
||||||
const NetExpr*par = 0;
|
const NetExpr*par = 0;
|
||||||
|
ivl_type_t par_type;
|
||||||
NetEvent* eve = 0;
|
NetEvent* eve = 0;
|
||||||
|
|
||||||
const NetExpr*ex1, *ex2;
|
scope = symbol_search(this, des, scope, path_, net, par, eve, par_type);
|
||||||
|
|
||||||
scope = symbol_search(this, des, scope, path_, net, par, eve, ex1, ex2);
|
|
||||||
|
|
||||||
if (scope)
|
if (scope)
|
||||||
return scope->is_auto();
|
return scope->is_auto();
|
||||||
|
|
|
||||||
19
PExpr.h
19
PExpr.h
|
|
@ -407,10 +407,6 @@ class PEIdent : public PExpr {
|
||||||
// flag is set to *false*.
|
// flag is set to *false*.
|
||||||
bool calculate_parts_(Design*, NetScope*, long&msb, long&lsb, bool&defined) const;
|
bool calculate_parts_(Design*, NetScope*, long&msb, long&lsb, bool&defined) const;
|
||||||
NetExpr* calculate_up_do_base_(Design*, NetScope*, bool need_const) 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;
|
bool calculate_up_do_width_(Design*, NetScope*, unsigned long&wid) const;
|
||||||
|
|
||||||
|
|
@ -450,37 +446,32 @@ class PEIdent : public PExpr {
|
||||||
NetScope*scope,
|
NetScope*scope,
|
||||||
const NetExpr*par,
|
const NetExpr*par,
|
||||||
NetScope*found_in,
|
NetScope*found_in,
|
||||||
const NetExpr*par_msb,
|
ivl_type_t par_type,
|
||||||
const NetExpr*par_lsb,
|
|
||||||
unsigned expr_wid,
|
unsigned expr_wid,
|
||||||
unsigned flags) const;
|
unsigned flags) const;
|
||||||
NetExpr*elaborate_expr_param_bit_(Design*des,
|
NetExpr*elaborate_expr_param_bit_(Design*des,
|
||||||
NetScope*scope,
|
NetScope*scope,
|
||||||
const NetExpr*par,
|
const NetExpr*par,
|
||||||
NetScope*found_in,
|
NetScope*found_in,
|
||||||
const NetExpr*par_msb,
|
ivl_type_t par_type,
|
||||||
const NetExpr*par_lsb,
|
|
||||||
bool need_const) const;
|
bool need_const) const;
|
||||||
NetExpr*elaborate_expr_param_part_(Design*des,
|
NetExpr*elaborate_expr_param_part_(Design*des,
|
||||||
NetScope*scope,
|
NetScope*scope,
|
||||||
const NetExpr*par,
|
const NetExpr*par,
|
||||||
NetScope*found_in,
|
NetScope*found_in,
|
||||||
const NetExpr*par_msb,
|
ivl_type_t par_type,
|
||||||
const NetExpr*par_lsb,
|
|
||||||
unsigned expr_wid) const;
|
unsigned expr_wid) const;
|
||||||
NetExpr*elaborate_expr_param_idx_up_(Design*des,
|
NetExpr*elaborate_expr_param_idx_up_(Design*des,
|
||||||
NetScope*scope,
|
NetScope*scope,
|
||||||
const NetExpr*par,
|
const NetExpr*par,
|
||||||
NetScope*found_in,
|
NetScope*found_in,
|
||||||
const NetExpr*par_msb,
|
ivl_type_t par_type,
|
||||||
const NetExpr*par_lsb,
|
|
||||||
bool need_const) const;
|
bool need_const) const;
|
||||||
NetExpr*elaborate_expr_param_idx_do_(Design*des,
|
NetExpr*elaborate_expr_param_idx_do_(Design*des,
|
||||||
NetScope*scope,
|
NetScope*scope,
|
||||||
const NetExpr*par,
|
const NetExpr*par,
|
||||||
NetScope*found_in,
|
NetScope*found_in,
|
||||||
const NetExpr*par_msb,
|
ivl_type_t par_type,
|
||||||
const NetExpr*par_lsb,
|
|
||||||
bool need_const) const;
|
bool need_const) const;
|
||||||
NetExpr*elaborate_expr_net(Design*des,
|
NetExpr*elaborate_expr_net(Design*des,
|
||||||
NetScope*scope,
|
NetScope*scope,
|
||||||
|
|
|
||||||
9
PScope.h
9
PScope.h
|
|
@ -98,12 +98,9 @@ class LexicalScope {
|
||||||
is elaborated. During parsing, I put the parameters into
|
is elaborated. During parsing, I put the parameters into
|
||||||
this map. */
|
this map. */
|
||||||
struct param_expr_t : public PNamedItem {
|
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) { }
|
inline param_expr_t() : data_type(0), expr(0), range(0) { }
|
||||||
// Type information
|
// Type information.
|
||||||
ivl_variable_type_t type;
|
data_type_t*data_type;
|
||||||
PExpr*msb;
|
|
||||||
PExpr*lsb;
|
|
||||||
bool signed_flag;
|
|
||||||
// Value expression
|
// Value expression
|
||||||
PExpr*expr;
|
PExpr*expr;
|
||||||
// If there are range constraints, list them here
|
// If there are range constraints, list them here
|
||||||
|
|
|
||||||
|
|
@ -1465,14 +1465,8 @@ void NetScope::dump(ostream&o) const
|
||||||
else
|
else
|
||||||
o << " parameter ";
|
o << " parameter ";
|
||||||
|
|
||||||
o << pp->second.type << " ";
|
if (pp->second.ivl_type)
|
||||||
|
pp->second.ivl_type->debug_dump(o);
|
||||||
if ((*pp).second.signed_flag)
|
|
||||||
o << "signed ";
|
|
||||||
|
|
||||||
if ((*pp).second.msb)
|
|
||||||
o << "[" << *(*pp).second.msb
|
|
||||||
<< ":" << *(*pp).second.lsb << "] ";
|
|
||||||
|
|
||||||
o << (*pp).first << " = ";
|
o << (*pp).first << " = ";
|
||||||
if (pp->second.val)
|
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;
|
NetNet *net = 0;
|
||||||
const NetExpr *par;
|
const NetExpr *par;
|
||||||
|
ivl_type_t par_type = 0;
|
||||||
NetEvent *eve;
|
NetEvent *eve;
|
||||||
const NetExpr *ex1, *ex2;
|
|
||||||
|
|
||||||
symbol_search(this, des, scope, use_path,
|
symbol_search(this, des, scope, use_path, net, par, eve, par_type);
|
||||||
net, par, eve, ex1, ex2);
|
|
||||||
|
|
||||||
const netdarray_t*use_darray = 0;
|
const netdarray_t*use_darray = 0;
|
||||||
|
|
||||||
|
|
@ -1354,7 +1353,7 @@ unsigned PECallFunction::test_width_method_(Design*des, NetScope*scope,
|
||||||
|
|
||||||
net = 0;
|
net = 0;
|
||||||
symbol_search(this, des, scope, tmp_path,
|
symbol_search(this, des, scope, tmp_path,
|
||||||
net, par, eve, ex1, ex2);
|
net, par, eve, par_type);
|
||||||
if (net && net->class_type()) {
|
if (net && net->class_type()) {
|
||||||
if (debug_elaborate) {
|
if (debug_elaborate) {
|
||||||
cerr << get_fileline() << ": PECallFunction::test_width_method_: "
|
cerr << get_fileline() << ": PECallFunction::test_width_method_: "
|
||||||
|
|
@ -2647,11 +2646,10 @@ NetExpr* PECallFunction::elaborate_expr_method_(Design*des, NetScope*scope,
|
||||||
|
|
||||||
NetNet *net = 0;
|
NetNet *net = 0;
|
||||||
const NetExpr *par;
|
const NetExpr *par;
|
||||||
|
ivl_type_t par_type;
|
||||||
NetEvent *eve;
|
NetEvent *eve;
|
||||||
const NetExpr *ex1, *ex2;
|
|
||||||
|
|
||||||
symbol_search(this, des, scope, use_path,
|
symbol_search(this, des, scope, use_path, net, par, eve, par_type);
|
||||||
net, par, eve, ex1, ex2);
|
|
||||||
|
|
||||||
if (net == 0)
|
if (net == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -3429,33 +3427,6 @@ NetExpr* PEIdent::calculate_up_do_base_(Design*des, NetScope*scope,
|
||||||
return tmp;
|
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&)
|
unsigned PEIdent::test_width_method_(Design*des, NetScope*scope, width_mode_t&)
|
||||||
{
|
{
|
||||||
if (!gn_system_verilog())
|
if (!gn_system_verilog())
|
||||||
|
|
@ -3475,9 +3446,9 @@ unsigned PEIdent::test_width_method_(Design*des, NetScope*scope, width_mode_t&)
|
||||||
|
|
||||||
NetNet*net = 0;
|
NetNet*net = 0;
|
||||||
const NetExpr*par = 0;
|
const NetExpr*par = 0;
|
||||||
|
ivl_type_t par_type = 0;
|
||||||
NetEvent*eve = 0;
|
NetEvent*eve = 0;
|
||||||
const NetExpr*ex1 = 0, *ex2 = 0;
|
symbol_search(this, des, scope, use_path, net, par, eve, par_type);
|
||||||
symbol_search(this, des, scope, use_path, net, par, eve, ex1, ex2);
|
|
||||||
if (net == 0) {
|
if (net == 0) {
|
||||||
if (debug_elaborate)
|
if (debug_elaborate)
|
||||||
cerr << get_fileline() << ": PEIdent::test_width_method_: "
|
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;
|
NetNet* net = 0;
|
||||||
const NetExpr*par = 0;
|
const NetExpr*par = 0;
|
||||||
|
ivl_type_t par_type = 0;
|
||||||
NetEvent* eve = 0;
|
NetEvent* eve = 0;
|
||||||
|
|
||||||
const NetExpr*ex1, *ex2;
|
|
||||||
|
|
||||||
NetScope*use_scope = scope;
|
NetScope*use_scope = scope;
|
||||||
if (package_) {
|
if (package_) {
|
||||||
use_scope = des->find_package(package_->pscope_name());
|
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_,
|
NetScope*found_in = symbol_search(this, des, use_scope, path_,
|
||||||
net, par, eve,
|
net, par, eve, par_type);
|
||||||
ex1, ex2);
|
|
||||||
|
|
||||||
// If there is a part/bit select expression, then process it
|
// If there is a part/bit select expression, then process it
|
||||||
// here. This constrains the results no matter what kind the
|
// 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();
|
use_path.pop_back();
|
||||||
|
|
||||||
ivl_assert(*this, net == 0);
|
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?
|
// Check to see if we have a net and if so is it a structure?
|
||||||
if (net != 0) {
|
if (net != 0) {
|
||||||
|
|
@ -3775,8 +3744,8 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
|
||||||
|
|
||||||
NetNet* net = 0;
|
NetNet* net = 0;
|
||||||
const NetExpr*par = 0;
|
const NetExpr*par = 0;
|
||||||
|
ivl_type_t par_type = 0;
|
||||||
NetEvent* eve = 0;
|
NetEvent* eve = 0;
|
||||||
const NetExpr*ex1, *ex2;
|
|
||||||
|
|
||||||
NetScope*use_scope = scope;
|
NetScope*use_scope = scope;
|
||||||
if (package_) {
|
if (package_) {
|
||||||
|
|
@ -3788,9 +3757,7 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* NetScope*found_in = */ symbol_search(this, des, use_scope, path_,
|
symbol_search(this, des, use_scope, path_, net, par, eve, par_type);
|
||||||
net, par, eve,
|
|
||||||
ex1, ex2);
|
|
||||||
|
|
||||||
if (net == 0 && gn_system_verilog() && path_.size() >= 2) {
|
if (net == 0 && gn_system_verilog() && path_.size() >= 2) {
|
||||||
// NOTE: this is assuming the member_path is only one
|
// 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();
|
use_path.pop_back();
|
||||||
|
|
||||||
ivl_assert(*this, net == 0);
|
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) {
|
if (net == 0) {
|
||||||
// Nope, no struct/class with member.
|
// Nope, no struct/class with member.
|
||||||
|
|
@ -4051,10 +4018,9 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
|
||||||
|
|
||||||
NetNet* net = 0;
|
NetNet* net = 0;
|
||||||
const NetExpr*par = 0;
|
const NetExpr*par = 0;
|
||||||
|
ivl_type_t par_type = 0;
|
||||||
NetEvent* eve = 0;
|
NetEvent* eve = 0;
|
||||||
|
|
||||||
const NetExpr*ex1, *ex2;
|
|
||||||
|
|
||||||
if (debug_elaborate) {
|
if (debug_elaborate) {
|
||||||
cerr << get_fileline() << ": PEIdent::elaborate_expr: "
|
cerr << get_fileline() << ": PEIdent::elaborate_expr: "
|
||||||
<< "path_=" << path_
|
<< "path_=" << path_
|
||||||
|
|
@ -4112,7 +4078,7 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
|
||||||
NetScope*found_in = 0;
|
NetScope*found_in = 0;
|
||||||
while (net==0 && par==0 && eve==0 && base_path.size()>0) {
|
while (net==0 && par==0 && eve==0 && base_path.size()>0) {
|
||||||
found_in = symbol_search(this, des, use_scope, base_path,
|
found_in = symbol_search(this, des, use_scope, base_path,
|
||||||
net, par, eve, ex1, ex2);
|
net, par, eve, par_type);
|
||||||
if (net) break;
|
if (net) break;
|
||||||
if (par) break;
|
if (par) break;
|
||||||
if (eve) 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,
|
NetExpr*tmp = elaborate_expr_param_(des, scope, par, found_in,
|
||||||
ex1, ex2, expr_wid, flags);
|
par_type, expr_wid, flags);
|
||||||
|
|
||||||
if (!tmp) return 0;
|
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,
|
NetExpr* PEIdent::elaborate_expr_param_bit_(Design*des, NetScope*scope,
|
||||||
const NetExpr*par,
|
const NetExpr*par,
|
||||||
NetScope*found_in,
|
NetScope*found_in,
|
||||||
const NetExpr*par_msb,
|
ivl_type_t par_type,
|
||||||
const NetExpr*par_lsb,
|
|
||||||
bool need_const) const
|
bool need_const) const
|
||||||
{
|
{
|
||||||
const NetEConst*par_ex = dynamic_cast<const NetEConst*> (par);
|
const NetEConst*par_ex = dynamic_cast<const NetEConst*> (par);
|
||||||
ivl_assert(*this, par_ex);
|
ivl_assert(*this, par_ex);
|
||||||
|
|
||||||
long par_msv, par_lsv;
|
long par_msv, par_lsv;
|
||||||
if(! calculate_param_range_(des, scope, par_msb, par_msv,
|
if(! calculate_param_range(*this, par_type, par_msv, par_lsv,
|
||||||
par_lsb, par_lsv,
|
|
||||||
par_ex->value().len())) return 0;
|
par_ex->value().len())) return 0;
|
||||||
|
|
||||||
const name_component_t&name_tail = path_.back();
|
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,
|
NetExpr* PEIdent::elaborate_expr_param_part_(Design*des, NetScope*scope,
|
||||||
const NetExpr*par,
|
const NetExpr*par,
|
||||||
NetScope*,
|
NetScope*,
|
||||||
const NetExpr*par_msb,
|
ivl_type_t par_type,
|
||||||
const NetExpr*par_lsb,
|
|
||||||
unsigned expr_wid) const
|
unsigned expr_wid) const
|
||||||
{
|
{
|
||||||
long msv, lsv;
|
long msv, lsv;
|
||||||
|
|
@ -4574,8 +4537,7 @@ NetExpr* PEIdent::elaborate_expr_param_part_(Design*des, NetScope*scope,
|
||||||
|
|
||||||
|
|
||||||
long par_msv, par_lsv;
|
long par_msv, par_lsv;
|
||||||
if (! calculate_param_range_(des, scope, par_msb, par_msv,
|
if (! calculate_param_range(*this, par_type, par_msv, par_lsv,
|
||||||
par_lsb, par_lsv,
|
|
||||||
par_ex->value().len())) return 0;
|
par_ex->value().len())) return 0;
|
||||||
|
|
||||||
if (! parts_defined_flag) {
|
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,
|
NetExpr* PEIdent::elaborate_expr_param_idx_up_(Design*des, NetScope*scope,
|
||||||
const NetExpr*par,
|
const NetExpr*par,
|
||||||
NetScope*found_in,
|
NetScope*found_in,
|
||||||
const NetExpr*par_msb,
|
ivl_type_t par_type,
|
||||||
const NetExpr*par_lsb,
|
|
||||||
bool need_const) const
|
bool need_const) const
|
||||||
{
|
{
|
||||||
const NetEConst*par_ex = dynamic_cast<const NetEConst*> (par);
|
const NetEConst*par_ex = dynamic_cast<const NetEConst*> (par);
|
||||||
ivl_assert(*this, par_ex);
|
ivl_assert(*this, par_ex);
|
||||||
|
|
||||||
long par_msv, par_lsv;
|
long par_msv, par_lsv;
|
||||||
if(! calculate_param_range_(des, scope, par_msb, par_msv,
|
if(! calculate_param_range(*this, par_type, par_msv, par_lsv,
|
||||||
par_lsb, par_lsv,
|
|
||||||
par_ex->value().len())) return 0;
|
par_ex->value().len())) return 0;
|
||||||
|
|
||||||
NetExpr*base = calculate_up_do_base_(des, scope, need_const);
|
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) {
|
if (warn_ob_select) {
|
||||||
bool defined = true;
|
bool defined = true;
|
||||||
// Check to see if the parameter has a defined range.
|
// Check to see if the parameter has a defined range.
|
||||||
if (par_msb == 0) {
|
if (par_type == 0) {
|
||||||
assert(par_lsb == 0);
|
|
||||||
defined = false;
|
defined = false;
|
||||||
}
|
}
|
||||||
// Get the parameter values width.
|
// 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,
|
NetExpr* PEIdent::elaborate_expr_param_idx_do_(Design*des, NetScope*scope,
|
||||||
const NetExpr*par,
|
const NetExpr*par,
|
||||||
NetScope*found_in,
|
NetScope*found_in,
|
||||||
const NetExpr*par_msb,
|
ivl_type_t par_type,
|
||||||
const NetExpr*par_lsb,
|
|
||||||
bool need_const) const
|
bool need_const) const
|
||||||
{
|
{
|
||||||
const NetEConst*par_ex = dynamic_cast<const NetEConst*> (par);
|
const NetEConst*par_ex = dynamic_cast<const NetEConst*> (par);
|
||||||
ivl_assert(*this, par_ex);
|
ivl_assert(*this, par_ex);
|
||||||
|
|
||||||
long par_msv, par_lsv;
|
long par_msv, par_lsv;
|
||||||
if(! calculate_param_range_(des, scope, par_msb, par_msv,
|
if(! calculate_param_range(*this, par_type, par_msv, par_lsv,
|
||||||
par_lsb, par_lsv,
|
|
||||||
par_ex->value().len())) return 0;
|
par_ex->value().len())) return 0;
|
||||||
|
|
||||||
NetExpr*base = calculate_up_do_base_(des, scope, need_const);
|
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) {
|
if (warn_ob_select) {
|
||||||
bool defined = true;
|
bool defined = true;
|
||||||
// Check to see if the parameter has a defined range.
|
// Check to see if the parameter has a defined range.
|
||||||
if (par_msb == 0) {
|
if (par_type == 0) {
|
||||||
assert(par_lsb == 0);
|
|
||||||
defined = false;
|
defined = false;
|
||||||
}
|
}
|
||||||
// Get the parameter values width.
|
// Get the parameter values width.
|
||||||
|
|
@ -4860,8 +4816,7 @@ NetExpr* PEIdent::elaborate_expr_param_(Design*des,
|
||||||
NetScope*scope,
|
NetScope*scope,
|
||||||
const NetExpr*par,
|
const NetExpr*par,
|
||||||
NetScope*found_in,
|
NetScope*found_in,
|
||||||
const NetExpr*par_msb,
|
ivl_type_t par_type,
|
||||||
const NetExpr*par_lsb,
|
|
||||||
unsigned expr_wid, unsigned flags) const
|
unsigned expr_wid, unsigned flags) const
|
||||||
{
|
{
|
||||||
bool need_const = NEED_CONST & flags;
|
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)
|
if (use_sel == index_component_t::SEL_BIT)
|
||||||
return elaborate_expr_param_bit_(des, scope, par, found_in,
|
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)
|
if (use_sel == index_component_t::SEL_PART)
|
||||||
return elaborate_expr_param_part_(des, scope, par, found_in,
|
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)
|
if (use_sel == index_component_t::SEL_IDX_UP)
|
||||||
return elaborate_expr_param_idx_up_(des, scope, par, found_in,
|
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)
|
if (use_sel == index_component_t::SEL_IDX_DO)
|
||||||
return elaborate_expr_param_idx_do_(des, scope, par, found_in,
|
return elaborate_expr_param_idx_do_(des, scope, par, found_in,
|
||||||
par_msb, par_lsb, need_const);
|
par_type, need_const);
|
||||||
|
|
||||||
NetExpr*tmp = 0;
|
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;
|
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,
|
const LexicalScope::param_expr_t&cur,
|
||||||
bool is_annotatable,
|
bool is_annotatable, bool local_flag)
|
||||||
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;
|
NetScope::range_t*range_list = 0;
|
||||||
for (LexicalScope::range_t*range = cur.range ; range ; range = range->next) {
|
for (LexicalScope::range_t*range = cur.range ; range ; range = range->next) {
|
||||||
NetScope::range_t*tmp = new NetScope::range_t;
|
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;
|
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)
|
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()
|
for (mparm_it_t cur = parameters.begin()
|
||||||
; cur != parameters.end() ; ++ cur ) {
|
; 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)
|
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()
|
for (mparm_it_t cur = localparams.begin()
|
||||||
; cur != localparams.end() ; ++ cur ) {
|
; 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)
|
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()
|
for (mparm_it_t cur = specparams.begin()
|
||||||
; cur != specparams.end() ; ++ cur ) {
|
; 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,
|
static void elaborate_scope_enumerations(Design*des, NetScope*scope,
|
||||||
const set<enum_type_t*>&enum_types)
|
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()
|
for (set<enum_type_t*>::const_iterator cur = enum_types.begin()
|
||||||
; cur != enum_types.end() ; ++ cur) {
|
; cur != enum_types.end() ; ++ cur) {
|
||||||
enum_type_t*curp = *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,
|
static void elaborate_scope_classes(Design*des, NetScope*scope,
|
||||||
const vector<PClass*>&classes)
|
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) {
|
for (size_t idx = 0 ; idx < classes.size() ; idx += 1) {
|
||||||
blend_class_constructors(classes[idx]);
|
blend_class_constructors(classes[idx]);
|
||||||
elaborate_scope_class(des, scope, 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)
|
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()
|
for (Module::replace_t::const_iterator cur = replacements.begin()
|
||||||
; cur != replacements.end() ; ++ cur ) {
|
; cur != replacements.end() ; ++ cur ) {
|
||||||
|
|
||||||
|
|
@ -712,8 +765,8 @@ bool PPackage::elaborate_scope(Design*des, NetScope*scope)
|
||||||
|
|
||||||
scope->add_typedefs(&typedefs);
|
scope->add_typedefs(&typedefs);
|
||||||
|
|
||||||
collect_scope_parameters_(des, scope, parameters);
|
collect_scope_parameters(des, scope, parameters);
|
||||||
collect_scope_localparams_(des, scope, localparams);
|
collect_scope_localparams(des, scope, localparams);
|
||||||
|
|
||||||
if (debug_scopes) {
|
if (debug_scopes) {
|
||||||
cerr << get_fileline() << ": PPackage::elaborate_scope: "
|
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
|
// will be evaluated later, once all parameter overrides for this
|
||||||
// module have been done.
|
// 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
|
// Run parameter replacements that were collected from the
|
||||||
// containing scope and meant for me.
|
// 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);
|
elaborate_scope_enumerations(des, scope, enum_sets);
|
||||||
|
|
||||||
assert(classes.size() == classes_lexical.size());
|
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
|
// we can not do that until defparams are run, so push it off
|
||||||
// into an elaborate work item.
|
// into an elaborate work item.
|
||||||
if (debug_scopes)
|
if (debug_scopes)
|
||||||
cerr << get_fileline() << ": debug: "
|
cerr << get_fileline() << ": " << __func__ << ": "
|
||||||
<< "Schedule generates within " << scope_path(scope)
|
<< "Schedule generates within " << scope_path(scope)
|
||||||
<< " for elaboration after defparams." << endl;
|
<< " 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
|
// needed to evaluate the parameter expressions. The expressions
|
||||||
// will be evaluated later, once all parameter overrides for this
|
// will be evaluated later, once all parameter overrides for this
|
||||||
// module have been done.
|
// 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
|
// Run through the defparams for this scope and save the result
|
||||||
// in a table for later final override.
|
// 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
|
// Scan the parameters in the function, and store the information
|
||||||
// needed to evaluate the parameter expressions.
|
// 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.
|
// Scan through all the named events in this scope.
|
||||||
elaborate_scope_events_(des, scope, events);
|
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
|
// Scan the parameters in the task, and store the information
|
||||||
// needed to evaluate the parameter expressions.
|
// 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.
|
// Scan through all the named events in this scope.
|
||||||
elaborate_scope_events_(des, scope, events);
|
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
|
// Scan the parameters in the scope, and store the information
|
||||||
// needed to evaluate the parameter expressions.
|
// 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.
|
// Scan through all the named events in this scope.
|
||||||
elaborate_scope_events_(des, my_scope, events);
|
elaborate_scope_events_(des, my_scope, events);
|
||||||
|
|
|
||||||
|
|
@ -3780,8 +3780,8 @@ NetProc* PCallTask::elaborate_method_(Design*des, NetScope*scope,
|
||||||
|
|
||||||
NetNet *net;
|
NetNet *net;
|
||||||
const NetExpr *par;
|
const NetExpr *par;
|
||||||
|
ivl_type_t par_type = 0;
|
||||||
NetEvent *eve;
|
NetEvent *eve;
|
||||||
const NetExpr *ex1, *ex2;
|
|
||||||
|
|
||||||
/* Add the implicit this reference when requested. */
|
/* Add the implicit this reference when requested. */
|
||||||
if (add_this_flag) {
|
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
|
// resolve to a class object. Note that the "this" symbol
|
||||||
// (internally represented as "@") is handled by there being a
|
// (internally represented as "@") is handled by there being a
|
||||||
// "this" object in the instance scope.
|
// "this" object in the instance scope.
|
||||||
symbol_search(this, des, scope, use_path,
|
symbol_search(this, des, scope, use_path, net, par, eve, par_type);
|
||||||
net, par, eve, ex1, ex2);
|
|
||||||
|
|
||||||
if (net == 0)
|
if (net == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
167
net_design.cc
167
net_design.cc
|
|
@ -29,6 +29,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
# include "netlist.h"
|
# include "netlist.h"
|
||||||
|
# include "netscalar.h"
|
||||||
|
# include "netvector.h"
|
||||||
# include "util.h"
|
# include "util.h"
|
||||||
# include "compiler.h"
|
# include "compiler.h"
|
||||||
# include "netmisc.h"
|
# include "netmisc.h"
|
||||||
|
|
@ -508,56 +510,71 @@ void Design::evaluate_parameters()
|
||||||
|
|
||||||
void NetScope::evaluate_parameter_logic_(Design*des, param_ref_t cur)
|
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. */
|
/* Evaluate the parameter expression. */
|
||||||
PExpr*val_expr = (*cur).second.val_expr;
|
PExpr*val_expr = (*cur).second.val_expr;
|
||||||
NetScope*val_scope = (*cur).second.val_scope;
|
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;
|
int lv_width = -2;
|
||||||
if (range_flag)
|
if (param_type) {
|
||||||
lv_width = (msb >= lsb) ? 1 + msb - lsb : 1 + lsb - msb;
|
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,
|
NetExpr*expr = elab_and_eval(des, val_scope, val_expr, lv_width, true,
|
||||||
(*cur).second.is_annotatable,
|
cur->second.is_annotatable, use_type);
|
||||||
(*cur).second.type);
|
|
||||||
if (! expr)
|
if (! expr)
|
||||||
return;
|
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()) {
|
switch (expr->expr_type()) {
|
||||||
case IVL_VT_REAL:
|
case IVL_VT_REAL:
|
||||||
if (! dynamic_cast<const NetECReal*>(expr)) {
|
if (! dynamic_cast<const NetECReal*>(expr)) {
|
||||||
|
|
@ -567,6 +584,13 @@ void NetScope::evaluate_parameter_logic_(Design*des, param_ref_t cur)
|
||||||
des->errors += 1;
|
des->errors += 1;
|
||||||
return;
|
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;
|
break;
|
||||||
|
|
||||||
case IVL_VT_LOGIC:
|
case IVL_VT_LOGIC:
|
||||||
|
|
@ -579,17 +603,20 @@ void NetScope::evaluate_parameter_logic_(Design*des, param_ref_t cur)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the parameter has type or range information, then
|
// If the parameter has no type, then infer its type from the
|
||||||
// make sure the type is set right. Note that if the
|
// r-value expression.
|
||||||
// parameter doesn't have an explicit type or range,
|
if (param_type==0) {
|
||||||
// then it will get the signedness from the expression itself.
|
param_type = new netvector_t(expr->expr_type(), expr->expr_width()-1,
|
||||||
if (cur->second.type != IVL_VT_NO_TYPE) {
|
0, expr->has_sign());
|
||||||
expr->cast_signed(cur->second.signed_flag);
|
cur->second.ivl_type = param_type;
|
||||||
} else if (cur->second.signed_flag) {
|
|
||||||
expr->cast_signed(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
expr = pad_to_width(expr, integer_width, *expr);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -597,18 +624,25 @@ void NetScope::evaluate_parameter_logic_(Design*des, param_ref_t cur)
|
||||||
default:
|
default:
|
||||||
cerr << expr->get_fileline()
|
cerr << expr->get_fileline()
|
||||||
<< ": internal error: "
|
<< ": 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;
|
des->errors += 1;
|
||||||
return;
|
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;
|
cur->second.val = expr;
|
||||||
|
|
||||||
// If there are no value ranges to test the value against,
|
// If there are no value ranges to test the value against,
|
||||||
// then we are done.
|
// then we are done.
|
||||||
if ((*cur).second.range == 0) {
|
if ((*cur).second.range == 0)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
NetEConst*val = dynamic_cast<NetEConst*>((*cur).second.val);
|
NetEConst*val = dynamic_cast<NetEConst*>((*cur).second.val);
|
||||||
ivl_assert(*(*cur).second.val, (*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;
|
PExpr*val_expr = (*cur).second.val_expr;
|
||||||
NetScope*val_scope = (*cur).second.val_scope;
|
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,
|
NetExpr*expr = elab_and_eval(des, val_scope, val_expr, -1, true,
|
||||||
(*cur).second.is_annotatable,
|
cur->second.is_annotatable,
|
||||||
(*cur).second.type);
|
param_type->base_type());
|
||||||
if (! expr)
|
if (! expr)
|
||||||
return;
|
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)
|
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 the parameter has already been evaluated, quietly return.
|
||||||
if (cur->second.val_expr == 0)
|
if (cur->second.val_expr == 0)
|
||||||
return;
|
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) {
|
if (cur->second.solving) {
|
||||||
cerr << cur->second.get_fileline() << ": error: "
|
cerr << cur->second.get_fileline() << ": error: "
|
||||||
<< "Recursive parameter reference found involving "
|
<< "Recursive parameter reference found involving "
|
||||||
<< cur->first << "." << endl;
|
<< cur->first << "." << endl;
|
||||||
des->errors += 1;
|
des->errors += 1;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
cur->second.solving = true;
|
cur->second.solving = true;
|
||||||
switch (cur->second.type) {
|
switch (use_type) {
|
||||||
case IVL_VT_NO_TYPE:
|
case IVL_VT_NO_TYPE:
|
||||||
case IVL_VT_BOOL:
|
case IVL_VT_BOOL:
|
||||||
case IVL_VT_LOGIC:
|
case IVL_VT_LOGIC:
|
||||||
|
|
@ -779,7 +834,7 @@ void NetScope::evaluate_parameter_(Design*des, param_ref_t cur)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
cerr << cur->second.get_fileline() << ": internal error: "
|
cerr << cur->second.get_fileline() << ": internal error: "
|
||||||
<< "Unexpected expression type " << cur->second.type
|
<< "Unexpected expression type " << use_type
|
||||||
<< "." << endl;
|
<< "." << endl;
|
||||||
cerr << cur->second.get_fileline() << ": : "
|
cerr << cur->second.get_fileline() << ": : "
|
||||||
<< "Parameter name: " << cur->first << endl;
|
<< "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;
|
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,
|
void NetScope::set_line(perm_string file, perm_string def_file,
|
||||||
unsigned lineno, unsigned def_lineno)
|
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();
|
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,
|
void NetScope::set_parameter(perm_string key, bool is_annotatable,
|
||||||
PExpr*val, ivl_variable_type_t type__,
|
PExpr*val, data_type_t*val_type,
|
||||||
PExpr*msb, PExpr*lsb, bool signed_flag,
|
|
||||||
bool local_flag,
|
bool local_flag,
|
||||||
NetScope::range_t*range_list,
|
NetScope::range_t*range_list,
|
||||||
const LineInfo&file_line)
|
const LineInfo&file_line)
|
||||||
{
|
{
|
||||||
param_expr_t&ref = parameters[key];
|
param_expr_t&ref = parameters[key];
|
||||||
ref.is_annotatable = is_annotatable;
|
ref.is_annotatable = is_annotatable;
|
||||||
ref.msb_expr = msb;
|
|
||||||
ref.lsb_expr = lsb;
|
|
||||||
ref.val_expr = val;
|
ref.val_expr = val;
|
||||||
|
ref.val_type = val_type;
|
||||||
ref.val_scope = this;
|
ref.val_scope = this;
|
||||||
ref.type = type__;
|
|
||||||
ref.msb = 0;
|
|
||||||
ref.lsb = 0;
|
|
||||||
ref.signed_flag = signed_flag;
|
|
||||||
ref.local_flag = local_flag;
|
ref.local_flag = local_flag;
|
||||||
ivl_assert(file_line, ref.range == 0);
|
ivl_assert(file_line, ref.range == 0);
|
||||||
ref.range = range_list;
|
ref.range = range_list;
|
||||||
ref.val = 0;
|
ref.val = 0;
|
||||||
|
ref.ivl_type = 0;
|
||||||
ref.set_line(file_line);
|
ref.set_line(file_line);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -313,14 +330,11 @@ void NetScope::set_parameter(perm_string key, NetExpr*val,
|
||||||
{
|
{
|
||||||
param_expr_t&ref = parameters[key];
|
param_expr_t&ref = parameters[key];
|
||||||
ref.is_annotatable = false;
|
ref.is_annotatable = false;
|
||||||
ref.msb_expr = 0;
|
|
||||||
ref.lsb_expr = 0;
|
|
||||||
ref.val_expr = 0;
|
ref.val_expr = 0;
|
||||||
|
ref.val_type = 0;
|
||||||
ref.val_scope = this;
|
ref.val_scope = this;
|
||||||
ref.type = IVL_VT_BOOL;
|
ref.ivl_type = netvector_t::integer_type();
|
||||||
ref.msb = 0;
|
ivl_assert(file_line, ref.ivl_type);
|
||||||
ref.lsb = 0;
|
|
||||||
ref.signed_flag = false;
|
|
||||||
ref.val = val;
|
ref.val = val;
|
||||||
ref.set_line(file_line);
|
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
|
* perm_string::literal method to fake the compiler into doing the
|
||||||
* compare without actually creating a perm_string.
|
* compare without actually creating a perm_string.
|
||||||
*/
|
*/
|
||||||
const NetExpr* NetScope::get_parameter(Design*des,
|
const NetExpr* NetScope::get_parameter(Design*des, const char* key,
|
||||||
const char* key,
|
ivl_type_t&ivl_type)
|
||||||
const NetExpr*&msb,
|
|
||||||
const NetExpr*&lsb)
|
|
||||||
{
|
{
|
||||||
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,
|
const NetExpr* NetScope::get_parameter(Design*des, perm_string key,
|
||||||
perm_string key,
|
ivl_type_t&ivl_type)
|
||||||
const NetExpr*&msb,
|
|
||||||
const NetExpr*&lsb)
|
|
||||||
{
|
{
|
||||||
map<perm_string,param_expr_t>::iterator idx;
|
map<perm_string,param_expr_t>::iterator idx;
|
||||||
|
|
||||||
|
|
@ -419,13 +429,11 @@ const NetExpr* NetScope::get_parameter(Design*des,
|
||||||
if (idx->second.val_expr)
|
if (idx->second.val_expr)
|
||||||
evaluate_parameter_(des, idx);
|
evaluate_parameter_(des, idx);
|
||||||
|
|
||||||
msb = idx->second.msb;
|
ivl_type = idx->second.ivl_type;
|
||||||
lsb = idx->second.lsb;
|
|
||||||
return idx->second.val;
|
return idx->second.val;
|
||||||
}
|
}
|
||||||
|
|
||||||
msb = 0;
|
ivl_type = 0;
|
||||||
lsb = 0;
|
|
||||||
const NetExpr*tmp = enumeration_expr(key);
|
const NetExpr*tmp = enumeration_expr(key);
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
38
netlist.h
38
netlist.h
|
|
@ -79,6 +79,7 @@ class PExpr;
|
||||||
class PFunction;
|
class PFunction;
|
||||||
class PPackage;
|
class PPackage;
|
||||||
class PTaskFunc;
|
class PTaskFunc;
|
||||||
|
class data_type_t;
|
||||||
struct enum_type_t;
|
struct enum_type_t;
|
||||||
class netclass_t;
|
class netclass_t;
|
||||||
class netdarray_t;
|
class netdarray_t;
|
||||||
|
|
@ -965,22 +966,17 @@ class NetScope : public Definitions, public Attrib {
|
||||||
|
|
||||||
struct range_t;
|
struct range_t;
|
||||||
void set_parameter(perm_string name, bool is_annotatable,
|
void set_parameter(perm_string name, bool is_annotatable,
|
||||||
PExpr*val, ivl_variable_type_t type,
|
PExpr*val, data_type_t*data_type,
|
||||||
PExpr*msb, PExpr*lsb, bool signed_flag,
|
|
||||||
bool local_flag,
|
bool local_flag,
|
||||||
NetScope::range_t*range_list,
|
NetScope::range_t*range_list,
|
||||||
const LineInfo&file_line);
|
const LineInfo&file_line);
|
||||||
void set_parameter(perm_string name, NetExpr*val,
|
void set_parameter(perm_string name, NetExpr*val,
|
||||||
const LineInfo&file_line);
|
const LineInfo&file_line);
|
||||||
|
|
||||||
const NetExpr*get_parameter(Design*des,
|
const NetExpr*get_parameter(Design*des, const char* name,
|
||||||
const char* name,
|
ivl_type_t&ivl_type);
|
||||||
const NetExpr*&msb,
|
const NetExpr*get_parameter(Design*des, perm_string name,
|
||||||
const NetExpr*&lsb);
|
ivl_type_t&ivl_type);
|
||||||
const NetExpr*get_parameter(Design*des,
|
|
||||||
perm_string name,
|
|
||||||
const NetExpr*&msb,
|
|
||||||
const NetExpr*&lsb);
|
|
||||||
|
|
||||||
/* These are used by defparam elaboration to replace the
|
/* These are used by defparam elaboration to replace the
|
||||||
expression with a new expression, without affecting 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_lineno() const { return lineno_; };
|
||||||
unsigned get_def_lineno() const { return def_lineno_; };
|
unsigned get_def_lineno() const { return def_lineno_; };
|
||||||
|
|
||||||
|
std::string get_fileline() const;
|
||||||
|
std::string get_def_fileline() const;
|
||||||
|
|
||||||
bool in_func() const;
|
bool in_func() const;
|
||||||
|
|
||||||
/* Provide a link back to the pform to allow early elaboration of
|
/* 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
|
/* After everything is all set up, the code generators like
|
||||||
access to these things to make up the parameter lists. */
|
access to these things to make up the parameter lists. */
|
||||||
struct param_expr_t : public LineInfo {
|
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),
|
solving(false), is_annotatable(false),
|
||||||
type(IVL_VT_NO_TYPE), signed_flag(false),
|
|
||||||
local_flag(false),
|
local_flag(false),
|
||||||
msb(0), lsb(0), range(0), val(0) { }
|
range(0), val(0), ivl_type(0) { }
|
||||||
// Source expressions
|
// Source expression and data type (before elaboration)
|
||||||
PExpr*msb_expr;
|
|
||||||
PExpr*lsb_expr;
|
|
||||||
PExpr*val_expr;
|
PExpr*val_expr;
|
||||||
|
data_type_t*val_type;
|
||||||
// Scope information
|
// Scope information
|
||||||
NetScope*val_scope;
|
NetScope*val_scope;
|
||||||
// Evaluation status
|
// Evaluation status
|
||||||
bool solving;
|
bool solving;
|
||||||
// specparam status
|
// specparam status
|
||||||
bool is_annotatable;
|
bool is_annotatable;
|
||||||
// Type information
|
// Is this a localparam?
|
||||||
ivl_variable_type_t type;
|
|
||||||
bool signed_flag;
|
|
||||||
bool local_flag;
|
bool local_flag;
|
||||||
NetExpr*msb;
|
|
||||||
NetExpr*lsb;
|
|
||||||
// range constraints
|
// range constraints
|
||||||
struct range_t*range;
|
struct range_t*range;
|
||||||
// Expression value
|
// Expression value and type (elaborated versoins of val_expr/val_type)
|
||||||
NetExpr*val;
|
NetExpr*val;
|
||||||
|
ivl_type_t ivl_type;
|
||||||
};
|
};
|
||||||
map<perm_string,param_expr_t>parameters;
|
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;
|
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 */
|
NetNet*&net, /* net/reg */
|
||||||
const NetExpr*&par,/* parameter/expr */
|
const NetExpr*&par,/* parameter/expr */
|
||||||
NetEvent*&eve, /* named event */
|
NetEvent*&eve, /* named event */
|
||||||
const NetExpr*&ex1, const NetExpr*&ex2);
|
ivl_type_t&par_type);
|
||||||
|
|
||||||
inline NetScope* symbol_search(const LineInfo*li,
|
inline NetScope* symbol_search(const LineInfo*li,
|
||||||
Design*des,
|
Design*des,
|
||||||
|
|
@ -55,8 +55,8 @@ inline NetScope* symbol_search(const LineInfo*li,
|
||||||
const NetExpr*&par,/* parameter/expr */
|
const NetExpr*&par,/* parameter/expr */
|
||||||
NetEvent*&eve /* named event */)
|
NetEvent*&eve /* named event */)
|
||||||
{
|
{
|
||||||
const NetExpr*ex1, *ex2;
|
ivl_type_t par_type;
|
||||||
return symbol_search(li, des, start, path, net, par, eve, ex1, ex2);
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
10
nettypes.h
10
nettypes.h
|
|
@ -27,6 +27,7 @@
|
||||||
# include <cassert>
|
# include <cassert>
|
||||||
|
|
||||||
class netrange_t;
|
class netrange_t;
|
||||||
|
class LineInfo;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is a fully abstract type that is a type that can be attached
|
* 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);
|
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
|
* Take as input a list of packed dimensions and a list of prefix
|
||||||
* indices, and calculate the offset/width of the resulting slice into
|
* 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 "netvector.h"
|
||||||
|
# include "compiler.h"
|
||||||
# include <iostream>
|
# include <iostream>
|
||||||
|
|
||||||
using namespace std;
|
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::atom2s8 (IVL_VT_BOOL, 7, 0, true);
|
||||||
netvector_t netvector_t::atom2u8 (IVL_VT_BOOL, 7, 0, false);
|
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_bool (IVL_VT_BOOL);
|
||||||
netvector_t netvector_t::scalar_logic (IVL_VT_LOGIC);
|
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 atom2u8;
|
||||||
static netvector_t scalar_bool;
|
static netvector_t scalar_bool;
|
||||||
static netvector_t scalar_logic;
|
static netvector_t scalar_logic;
|
||||||
|
static const netvector_t*integer_type();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool test_compatibility(ivl_type_t that) const;
|
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();
|
extern void lex_end_table();
|
||||||
|
|
||||||
static list<pform_range_t>* param_active_range = 0;
|
static data_type_t* param_data_type = 0;
|
||||||
static bool param_active_signed = false;
|
static list<pform_range_t>* specparam_active_range = 0;
|
||||||
static ivl_variable_type_t param_active_type = IVL_VT_LOGIC;
|
|
||||||
|
|
||||||
/* Port declaration lists use this structure for context. */
|
/* Port declaration lists use this structure for context. */
|
||||||
static struct {
|
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 <nettype> net_type net_type_opt
|
||||||
%type <gatetype> gatetype switchtype
|
%type <gatetype> gatetype switchtype
|
||||||
%type <porttype> port_direction port_direction_opt
|
%type <porttype> port_direction port_direction_opt
|
||||||
%type <vartype> bit_logic bit_logic_opt
|
|
||||||
%type <vartype> integer_vector_type
|
%type <vartype> integer_vector_type
|
||||||
%type <parmvalue> parameter_value_opt
|
%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
|
net_type
|
||||||
: K_wire { $$ = NetNet::WIRE; }
|
: K_wire { $$ = NetNet::WIRE; }
|
||||||
| K_tri { $$ = NetNet::TRI; }
|
| K_tri { $$ = NetNet::TRI; }
|
||||||
|
|
@ -5514,42 +5501,12 @@ net_type
|
||||||
| K_uwire { $$ = NetNet::UNRESOLVED_WIRE; }
|
| K_uwire { $$ = NetNet::UNRESOLVED_WIRE; }
|
||||||
;
|
;
|
||||||
|
|
||||||
param_type
|
/* The param_type rule is just the data_type_or_implicit rule wrapped
|
||||||
: bit_logic_opt unsigned_signed_opt dimensions_opt
|
with an assignment to para_data_type with the figured data type.
|
||||||
{ param_active_range = $3;
|
This is used by parameter_assign, which is found to the right of
|
||||||
param_active_signed = $2;
|
the param_type in various rules. */
|
||||||
if (($1 == IVL_VT_NO_TYPE) && ($3 != 0))
|
|
||||||
param_active_type = IVL_VT_LOGIC;
|
param_type : data_type_or_implicit { param_data_type = $1; }
|
||||||
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;
|
|
||||||
}
|
|
||||||
;
|
|
||||||
|
|
||||||
/* parameter and localparam assignment lists are broken into
|
/* parameter and localparam assignment lists are broken into
|
||||||
separate BNF so that I can call slightly different parameter
|
separate BNF so that I can call slightly different parameter
|
||||||
|
|
@ -5569,8 +5526,7 @@ localparam_assign_list
|
||||||
parameter_assign
|
parameter_assign
|
||||||
: IDENTIFIER '=' expression parameter_value_ranges_opt
|
: IDENTIFIER '=' expression parameter_value_ranges_opt
|
||||||
{ PExpr*tmp = $3;
|
{ PExpr*tmp = $3;
|
||||||
pform_set_parameter(@1, lex_strings.make($1), param_active_type,
|
pform_set_parameter(@1, lex_strings.make($1), param_data_type, tmp, $4);
|
||||||
param_active_signed, param_active_range, tmp, $4);
|
|
||||||
delete[]$1;
|
delete[]$1;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
@ -5578,8 +5534,7 @@ parameter_assign
|
||||||
localparam_assign
|
localparam_assign
|
||||||
: IDENTIFIER '=' expression
|
: IDENTIFIER '=' expression
|
||||||
{ PExpr*tmp = $3;
|
{ PExpr*tmp = $3;
|
||||||
pform_set_localparam(@1, lex_strings.make($1), param_active_type,
|
pform_set_localparam(@1, lex_strings.make($1), param_data_type, tmp);
|
||||||
param_active_signed, param_active_range, tmp);
|
|
||||||
delete[]$1;
|
delete[]$1;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
@ -6305,7 +6260,7 @@ specparam
|
||||||
: IDENTIFIER '=' expression
|
: IDENTIFIER '=' expression
|
||||||
{ PExpr*tmp = $3;
|
{ PExpr*tmp = $3;
|
||||||
pform_set_specparam(@1, lex_strings.make($1),
|
pform_set_specparam(@1, lex_strings.make($1),
|
||||||
param_active_range, tmp);
|
specparam_active_range, tmp);
|
||||||
delete[]$1;
|
delete[]$1;
|
||||||
}
|
}
|
||||||
| IDENTIFIER '=' expression ':' expression ':' expression
|
| IDENTIFIER '=' expression ':' expression ':' expression
|
||||||
|
|
@ -6344,7 +6299,7 @@ specparam
|
||||||
min_typ_max_warn -= 1;
|
min_typ_max_warn -= 1;
|
||||||
}
|
}
|
||||||
pform_set_specparam(@1, lex_strings.make($1),
|
pform_set_specparam(@1, lex_strings.make($1),
|
||||||
param_active_range, tmp);
|
specparam_active_range, tmp);
|
||||||
delete[]$1;
|
delete[]$1;
|
||||||
}
|
}
|
||||||
| PATHPULSE_IDENTIFIER '=' expression
|
| PATHPULSE_IDENTIFIER '=' expression
|
||||||
|
|
@ -6366,9 +6321,9 @@ specparam_list
|
||||||
specparam_decl
|
specparam_decl
|
||||||
: specparam_list
|
: specparam_list
|
||||||
| dimensions
|
| dimensions
|
||||||
{ param_active_range = $1; }
|
{ specparam_active_range = $1; }
|
||||||
specparam_list
|
specparam_list
|
||||||
{ param_active_range = 0; }
|
{ specparam_active_range = 0; }
|
||||||
;
|
;
|
||||||
|
|
||||||
spec_polarity
|
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,
|
void pform_set_parameter(const struct vlltype&loc,
|
||||||
perm_string name, ivl_variable_type_t type,
|
perm_string name, data_type_t*data_type, PExpr*expr,
|
||||||
bool signed_flag, list<pform_range_t>*range, PExpr*expr,
|
|
||||||
LexicalScope::range_t*value_range)
|
LexicalScope::range_t*value_range)
|
||||||
{
|
{
|
||||||
LexicalScope*scope = lexical_scope;
|
LexicalScope*scope = lexical_scope;
|
||||||
|
|
@ -3190,20 +3189,7 @@ void pform_set_parameter(const struct vlltype&loc,
|
||||||
scope->parameters[name] = parm;
|
scope->parameters[name] = parm;
|
||||||
|
|
||||||
parm->expr = expr;
|
parm->expr = expr;
|
||||||
|
parm->data_type = data_type;
|
||||||
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->range = value_range;
|
parm->range = value_range;
|
||||||
|
|
||||||
// Only a Module keeps the position of the parameter.
|
// 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,
|
void pform_set_localparam(const struct vlltype&loc,
|
||||||
perm_string name, ivl_variable_type_t type,
|
perm_string name, data_type_t*data_type, PExpr*expr)
|
||||||
bool signed_flag, list<pform_range_t>*range, PExpr*expr)
|
|
||||||
{
|
{
|
||||||
LexicalScope*scope = lexical_scope;
|
LexicalScope*scope = lexical_scope;
|
||||||
if (is_compilation_unit(scope) && !gn_system_verilog()) {
|
if (is_compilation_unit(scope) && !gn_system_verilog()) {
|
||||||
|
|
@ -3229,20 +3214,7 @@ void pform_set_localparam(const struct vlltype&loc,
|
||||||
scope->localparams[name] = parm;
|
scope->localparams[name] = parm;
|
||||||
|
|
||||||
parm->expr = expr;
|
parm->expr = expr;
|
||||||
|
parm->data_type = data_type;
|
||||||
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->range = 0;
|
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;
|
pform_cur_module.front()->specparams[name] = parm;
|
||||||
|
|
||||||
parm->expr = expr;
|
parm->expr = expr;
|
||||||
|
parm->range = 0;
|
||||||
|
|
||||||
if (range) {
|
if (range) {
|
||||||
assert(range->size() == 1);
|
assert(range->size() == 1);
|
||||||
pform_range_t&rng = range->front();
|
parm->data_type = new vector_type_t(IVL_VT_LOGIC, false, range);
|
||||||
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->range = 0;
|
parm->range = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void pform_set_defparam(const pform_name_t&name, PExpr*expr)
|
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,
|
extern void pform_set_parameter(const struct vlltype&loc,
|
||||||
perm_string name,
|
perm_string name,
|
||||||
ivl_variable_type_t type,
|
data_type_t*data_type,
|
||||||
bool signed_flag,
|
|
||||||
list<pform_range_t>*range,
|
|
||||||
PExpr*expr, LexicalScope::range_t*value_range);
|
PExpr*expr, LexicalScope::range_t*value_range);
|
||||||
extern void pform_set_localparam(const struct vlltype&loc,
|
extern void pform_set_localparam(const struct vlltype&loc,
|
||||||
perm_string name,
|
perm_string name,
|
||||||
ivl_variable_type_t type,
|
data_type_t*data_type,
|
||||||
bool signed_flag,
|
|
||||||
list<pform_range_t>*range,
|
|
||||||
PExpr*expr);
|
PExpr*expr);
|
||||||
extern void pform_set_specparam(const struct vlltype&loc,
|
extern void pform_set_specparam(const struct vlltype&loc,
|
||||||
perm_string name,
|
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;
|
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
|
void void_type_t::pform_dump(ostream&out, unsigned indent) const
|
||||||
{
|
{
|
||||||
out << setw(indent) << "" << "void" << endl;
|
out << setw(indent) << "" << "void" << endl;
|
||||||
|
|
@ -213,6 +219,25 @@ void vector_type_t::pform_dump(ostream&fd, unsigned indent) const
|
||||||
fd << endl;
|
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
|
void class_type_t::pform_dump(ostream&out, unsigned indent) const
|
||||||
{
|
{
|
||||||
out << setw(indent) << "" << "class " << name;
|
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;
|
typedef map<perm_string,param_expr_t*>::const_iterator parm_iter_t;
|
||||||
for (parm_iter_t cur = parameters.begin()
|
for (parm_iter_t cur = parameters.begin()
|
||||||
; cur != parameters.end() ; ++ cur ) {
|
; cur != parameters.end() ; ++ cur ) {
|
||||||
out << setw(indent) << "" << "parameter "
|
out << setw(indent) << "" << "parameter ";
|
||||||
<< (*cur).second->type << " ";
|
if (cur->second->data_type)
|
||||||
if ((*cur).second->signed_flag)
|
cur->second->data_type->debug_dump(out);
|
||||||
out << "signed ";
|
else
|
||||||
if ((*cur).second->msb)
|
out << "(nil type)";
|
||||||
out << "[" << *(*cur).second->msb << ":"
|
out << " " << (*cur).first << " = ";
|
||||||
<< *(*cur).second->lsb << "] ";
|
|
||||||
out << (*cur).first << " = ";
|
|
||||||
if ((*cur).second->expr)
|
if ((*cur).second->expr)
|
||||||
out << *(*cur).second->expr;
|
out << *(*cur).second->expr;
|
||||||
else
|
else
|
||||||
|
|
@ -1439,9 +1462,10 @@ void LexicalScope::dump_localparams_(ostream&out, unsigned indent) const
|
||||||
for (parm_iter_t cur = localparams.begin()
|
for (parm_iter_t cur = localparams.begin()
|
||||||
; cur != localparams.end() ; ++ cur ) {
|
; cur != localparams.end() ; ++ cur ) {
|
||||||
out << setw(indent) << "" << "localparam ";
|
out << setw(indent) << "" << "localparam ";
|
||||||
if ((*cur).second->msb)
|
if (cur->second->data_type) {
|
||||||
out << "[" << *(*cur).second->msb << ":"
|
cur->second->data_type->debug_dump(out);
|
||||||
<< *(*cur).second->lsb << "] ";
|
out << " ";
|
||||||
|
}
|
||||||
out << (*cur).first << " = ";
|
out << (*cur).first << " = ";
|
||||||
if ((*cur).second->expr)
|
if ((*cur).second->expr)
|
||||||
out << *(*cur).second->expr << ";" << endl;
|
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()
|
for (parm_iter_t cur = specparams.begin()
|
||||||
; cur != specparams.end() ; ++ cur ) {
|
; cur != specparams.end() ; ++ cur ) {
|
||||||
out << setw(indent) << "" << "specparam ";
|
out << setw(indent) << "" << "specparam ";
|
||||||
if ((*cur).second->msb)
|
if (cur->second->data_type)
|
||||||
out << "[" << *(*cur).second->msb << ":"
|
cur->second->data_type->debug_dump(out);
|
||||||
<< *(*cur).second->lsb << "] ";
|
else
|
||||||
|
out << "(nil type)";
|
||||||
|
|
||||||
out << (*cur).first << " = ";
|
out << (*cur).first << " = ";
|
||||||
if ((*cur).second->expr)
|
if ((*cur).second->expr)
|
||||||
out << *(*cur).second->expr << ";" << endl;
|
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
|
// 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.
|
// compound object. Return IVL_VT_NO_TYPE if the type is not packed.
|
||||||
virtual ivl_variable_type_t figure_packed_base_type(void)const;
|
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 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);
|
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) { }
|
: 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 ivl_variable_type_t figure_packed_base_type(void)const;
|
||||||
virtual void pform_dump(std::ostream&out, unsigned indent) 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_type_s* elaborate_type_raw(Design*des, NetScope*scope) const;
|
||||||
|
|
||||||
ivl_variable_type_t base_type;
|
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 SUPER_TOKEN "#"
|
||||||
# define THIS_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 pform_name_t&);
|
||||||
extern std::ostream& operator<< (std::ostream&out, const name_component_t&that);
|
extern std::ostream& operator<< (std::ostream&out, const name_component_t&that);
|
||||||
extern std::ostream& operator<< (std::ostream&out, const index_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;
|
scope = 0;
|
||||||
net = 0;
|
net = 0;
|
||||||
par_val = 0;
|
par_val = 0;
|
||||||
par_msb = 0;
|
par_type = 0;
|
||||||
par_lsb = 0;
|
|
||||||
eve = 0;
|
eve = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -52,8 +51,7 @@ struct symbol_search_results {
|
||||||
// If this was a parameter, the value expression and the
|
// If this was a parameter, the value expression and the
|
||||||
// optional value dimensions.
|
// optional value dimensions.
|
||||||
const NetExpr*par_val;
|
const NetExpr*par_val;
|
||||||
const NetExpr*par_msb;
|
ivl_type_t par_type;
|
||||||
const NetExpr*par_lsb;
|
|
||||||
// If this is a named event, ...
|
// If this is a named event, ...
|
||||||
NetEvent*eve;
|
NetEvent*eve;
|
||||||
};
|
};
|
||||||
|
|
@ -129,7 +127,7 @@ static bool symbol_search(const LineInfo*li, Design*des, NetScope*scope,
|
||||||
return true;
|
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->scope = scope;
|
||||||
res->par_val = par;
|
res->par_val = par;
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -191,14 +189,13 @@ NetScope*symbol_search(const LineInfo*li, Design*des, NetScope*scope,
|
||||||
NetNet*&net,
|
NetNet*&net,
|
||||||
const NetExpr*&par,
|
const NetExpr*&par,
|
||||||
NetEvent*&eve,
|
NetEvent*&eve,
|
||||||
const NetExpr*&ex1, const NetExpr*&ex2)
|
ivl_type_t&par_type)
|
||||||
{
|
{
|
||||||
symbol_search_results recurse;
|
symbol_search_results recurse;
|
||||||
bool flag = symbol_search(li, des, scope, path, &recurse);
|
bool flag = symbol_search(li, des, scope, path, &recurse);
|
||||||
net = recurse.net;
|
net = recurse.net;
|
||||||
par = recurse.par_val;
|
par = recurse.par_val;
|
||||||
ex1 = recurse.par_msb;
|
par_type = recurse.par_type;
|
||||||
ex2 = recurse.par_lsb;
|
|
||||||
eve = recurse.eve;
|
eve = recurse.eve;
|
||||||
if (! flag) {
|
if (! flag) {
|
||||||
return 0;
|
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];
|
ivl_parameter_t cur_par = &scop->param[idx];
|
||||||
cur_par->basename = cur_pit->first;
|
cur_par->basename = cur_pit->first;
|
||||||
cur_par->local = cur_pit->second.local_flag;
|
cur_par->local = cur_pit->second.local_flag;
|
||||||
/* Either both the MSB and LSB expressions are provided or
|
calculate_param_range(cur_pit->second,
|
||||||
* neither are provided. */
|
cur_pit->second.ivl_type,
|
||||||
if (cur_pit->second.msb) {
|
cur_par->msb, cur_par->lsb,
|
||||||
assert(cur_pit->second.lsb);
|
cur_pit->second.val->expr_width());
|
||||||
/* The MSB and LSB expressions must be integral constants. */
|
|
||||||
const NetEConst *msbc =
|
if (cur_pit->second.ivl_type == 0) {
|
||||||
dynamic_cast<const NetEConst*>(cur_pit->second.msb);
|
cerr << "?:?: internal error: "
|
||||||
const NetEConst *lsbc =
|
<< "No type for parameter " << cur_pit->first
|
||||||
dynamic_cast<const NetEConst*>(cur_pit->second.lsb);
|
<< " in scope " << net->fullname() << "?" << endl;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
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;
|
cur_par->scope = scop;
|
||||||
FILE_NAME(cur_par, &(cur_pit->second));
|
FILE_NAME(cur_par, &(cur_pit->second));
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue