Merge pull request #620 from larsclausen/class-localparams
Support non-overridable parameters in classes
This commit is contained in:
commit
83f1ea60b7
24
PExpr.h
24
PExpr.h
|
|
@ -430,35 +430,42 @@ class PEIdent : public PExpr {
|
|||
NetAssign_*) const;
|
||||
|
||||
private:
|
||||
NetExpr*elaborate_expr_param_or_specparam_(Design*des,
|
||||
NetScope*scope,
|
||||
const NetExpr*par,
|
||||
NetScope*found_in,
|
||||
ivl_type_t par_type,
|
||||
unsigned expr_wid,
|
||||
unsigned flags) const;
|
||||
NetExpr*elaborate_expr_param_(Design*des,
|
||||
NetScope*scope,
|
||||
const NetExpr*par,
|
||||
NetScope*found_in,
|
||||
const NetScope*found_in,
|
||||
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 NetScope*found_in,
|
||||
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 NetScope*found_in,
|
||||
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 NetScope*found_in,
|
||||
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 NetScope*found_in,
|
||||
ivl_type_t par_type,
|
||||
bool need_const) const;
|
||||
NetExpr*elaborate_expr_net(Design*des,
|
||||
|
|
@ -504,8 +511,15 @@ class PEIdent : public PExpr {
|
|||
unsigned expr_wid,
|
||||
unsigned flags) const;
|
||||
|
||||
NetExpr *elaborate_expr_class_field_(Design*des, NetScope*scope,
|
||||
NetNet*net,
|
||||
const name_component_t&comp,
|
||||
unsigned expr_wid,
|
||||
unsigned flags) const;
|
||||
|
||||
unsigned test_width_method_(Design*des, NetScope*scope, width_mode_t&mode);
|
||||
|
||||
unsigned test_width_parameter_(const NetExpr *par, width_mode_t&mode);
|
||||
|
||||
private:
|
||||
NetNet* elaborate_lnet_common_(Design*des, NetScope*scope,
|
||||
|
|
|
|||
157
elab_expr.cc
157
elab_expr.cc
|
|
@ -2516,15 +2516,24 @@ static NetExpr* class_static_property_expression(const LineInfo*li,
|
|||
return expr;
|
||||
}
|
||||
|
||||
static NetExpr* check_for_class_property(const LineInfo*li,
|
||||
Design*des, NetScope*scope,
|
||||
NetNet*net,
|
||||
const name_component_t&comp)
|
||||
NetExpr* PEIdent::elaborate_expr_class_field_(Design*des, NetScope*scope,
|
||||
NetNet*net,
|
||||
const name_component_t&comp,
|
||||
unsigned expr_wid,
|
||||
unsigned flags) const
|
||||
{
|
||||
const netclass_t*class_type = net->class_type();
|
||||
|
||||
ivl_type_t par_type;
|
||||
const NetExpr *par_val = class_type->get_parameter(des, comp.name, par_type);
|
||||
if (par_val)
|
||||
return elaborate_expr_param_(des, scope, par_val,
|
||||
class_type->class_scope(), par_type,
|
||||
expr_wid, flags);
|
||||
|
||||
int pidx = class_type->property_idx_from_name(comp.name);
|
||||
if (pidx < 0) {
|
||||
cerr << li->get_fileline() << ": error: "
|
||||
cerr << get_fileline() << ": error: "
|
||||
<< "Class " << class_type->get_name()
|
||||
<< " has no property " << comp.name << "." << endl;
|
||||
des->errors += 1;
|
||||
|
|
@ -2532,7 +2541,7 @@ static NetExpr* check_for_class_property(const LineInfo*li,
|
|||
}
|
||||
|
||||
if (debug_elaborate) {
|
||||
cerr << li->get_fileline() << ": check_for_class_property: "
|
||||
cerr << get_fileline() << ": check_for_class_property: "
|
||||
<< "Property " << comp.name
|
||||
<< " of net " << net->name()
|
||||
<< ", context scope=" << scope_path(scope)
|
||||
|
|
@ -2541,7 +2550,7 @@ static NetExpr* check_for_class_property(const LineInfo*li,
|
|||
|
||||
property_qualifier_t qual = class_type->get_prop_qual(pidx);
|
||||
if (qual.test_local() && ! class_type->test_scope_is_method(scope)) {
|
||||
cerr << li->get_fileline() << ": error: "
|
||||
cerr << get_fileline() << ": error: "
|
||||
<< "Local property " << class_type->get_prop_name(pidx)
|
||||
<< " is not accessible in this context."
|
||||
<< " (scope=" << scope_path(scope) << ")" << endl;
|
||||
|
|
@ -2550,12 +2559,12 @@ static NetExpr* check_for_class_property(const LineInfo*li,
|
|||
|
||||
if (qual.test_static()) {
|
||||
perm_string prop_name = lex_strings.make(class_type->get_prop_name(pidx));
|
||||
return class_static_property_expression(li, class_type,
|
||||
return class_static_property_expression(this, class_type,
|
||||
prop_name);
|
||||
}
|
||||
|
||||
NetEProperty*tmp = new NetEProperty(net, comp.name);
|
||||
tmp->set_line(*li);
|
||||
tmp->set_line(*this);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
|
@ -3977,6 +3986,33 @@ unsigned PEIdent::test_width_method_(Design*des, NetScope*scope, width_mode_t&)
|
|||
return 0;
|
||||
}
|
||||
|
||||
unsigned PEIdent::test_width_parameter_(const NetExpr *par, width_mode_t&mode)
|
||||
{
|
||||
// The width of an enumeration literal is the width of the
|
||||
// enumeration base.
|
||||
if (const NetEConstEnum*par_enum = dynamic_cast<const NetEConstEnum*> (par)) {
|
||||
const netenum_t*use_enum = par_enum->enumeration();
|
||||
ivl_assert(*this, use_enum != 0);
|
||||
|
||||
expr_type_ = use_enum->base_type();
|
||||
expr_width_ = use_enum->packed_width();
|
||||
min_width_ = expr_width_;
|
||||
signed_flag_ = par_enum->has_sign();
|
||||
|
||||
return expr_width_;
|
||||
}
|
||||
|
||||
expr_type_ = par->expr_type();
|
||||
expr_width_ = par->expr_width();
|
||||
min_width_ = expr_width_;
|
||||
signed_flag_ = par->has_sign();
|
||||
|
||||
if (!par->has_width() && (mode < LOSSLESS))
|
||||
mode = LOSSLESS;
|
||||
|
||||
return expr_width_;
|
||||
}
|
||||
|
||||
unsigned PEIdent::test_width(Design*des, NetScope*scope, width_mode_t&mode)
|
||||
{
|
||||
NetScope*use_scope = scope;
|
||||
|
|
@ -4128,6 +4164,11 @@ unsigned PEIdent::test_width(Design*des, NetScope*scope, width_mode_t&mode)
|
|||
if (sr.net->class_type() != 0 && !sr.path_tail.empty()) {
|
||||
const netclass_t*class_type = sr.net->class_type();
|
||||
perm_string pname = peek_tail_name(sr.path_tail);
|
||||
ivl_type_t par_type;
|
||||
const NetExpr *par = class_type->get_parameter(des, pname, par_type);
|
||||
if (par)
|
||||
return test_width_parameter_(par, mode);
|
||||
|
||||
int pidx = class_type->property_idx_from_name(pname);
|
||||
if (pidx >= 0) {
|
||||
ivl_type_t ptype = class_type->get_prop_type(pidx);
|
||||
|
|
@ -4172,33 +4213,10 @@ unsigned PEIdent::test_width(Design*des, NetScope*scope, width_mode_t&mode)
|
|||
return expr_width_;
|
||||
}
|
||||
|
||||
// The width of an enumeration literal is the width of the
|
||||
// enumeration base.
|
||||
if (const NetEConstEnum*par_enum = dynamic_cast<const NetEConstEnum*> (sr.par_val)) {
|
||||
const netenum_t*use_enum = par_enum->enumeration();
|
||||
ivl_assert(*this, use_enum != 0);
|
||||
|
||||
expr_type_ = use_enum->base_type();
|
||||
expr_width_ = use_enum->packed_width();
|
||||
min_width_ = expr_width_;
|
||||
signed_flag_ = par_enum->has_sign();
|
||||
|
||||
return expr_width_;
|
||||
}
|
||||
|
||||
// The width of a parameter is the width of the parameter value
|
||||
// (as evaluated earlier).
|
||||
if (sr.par_val != 0) {
|
||||
expr_type_ = sr.par_val->expr_type();
|
||||
expr_width_ = sr.par_val->expr_width();
|
||||
min_width_ = expr_width_;
|
||||
signed_flag_ = sr.par_val->has_sign();
|
||||
|
||||
if (!sr.par_val->has_width() && (mode < LOSSLESS))
|
||||
mode = LOSSLESS;
|
||||
|
||||
return expr_width_;
|
||||
}
|
||||
if (sr.par_val != 0)
|
||||
return test_width_parameter_(sr.par_val, mode);
|
||||
|
||||
if (path_.size() == 1
|
||||
&& scope->genvar_tmp.str()
|
||||
|
|
@ -4283,8 +4301,8 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
|
|||
<< " look for property " << member_comp << endl;
|
||||
}
|
||||
|
||||
return check_for_class_property(this, des, scope,
|
||||
net, member_comp);
|
||||
return elaborate_expr_class_field_(des, scope, net,
|
||||
member_comp, 0, flags);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -4578,8 +4596,9 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
|
|||
des->errors += 1;
|
||||
}
|
||||
|
||||
NetExpr*tmp = elaborate_expr_param_(des, scope, sr.par_val, sr.scope,
|
||||
sr.par_type, expr_wid, flags);
|
||||
NetExpr*tmp = elaborate_expr_param_or_specparam_(des, scope, sr.par_val,
|
||||
sr.scope, sr.par_type,
|
||||
expr_wid, flags);
|
||||
|
||||
if (!tmp) return 0;
|
||||
|
||||
|
|
@ -4808,8 +4827,9 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
|
|||
|
||||
ivl_assert(*this, sr.path_tail.size() == 1);
|
||||
const name_component_t member_comp = sr.path_tail.front();
|
||||
return check_for_class_property(this, des, use_scope,
|
||||
sr.net, member_comp);
|
||||
return elaborate_expr_class_field_(des, use_scope,
|
||||
sr.net, member_comp,
|
||||
expr_wid, flags);
|
||||
}
|
||||
|
||||
if (sr.net->enumeration() && !sr.path_tail.empty()) {
|
||||
|
|
@ -5007,7 +5027,7 @@ 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 NetScope*found_in,
|
||||
ivl_type_t par_type,
|
||||
bool need_const) const
|
||||
{
|
||||
|
|
@ -5091,8 +5111,7 @@ NetExpr* PEIdent::elaborate_expr_param_bit_(Design*des, NetScope*scope,
|
|||
|
||||
/* Create a parameter reference for the variable select. */
|
||||
NetEConstParam*ptmp = new NetEConstParam(found_in, name, par_ex->value());
|
||||
NetScope::param_ref_t pref = found_in->find_parameter(name);
|
||||
ptmp->set_line((*pref).second);
|
||||
ptmp->set_line(found_in->get_parameter_line_info(name));
|
||||
|
||||
NetExpr*tmp = new NetESelect(ptmp, sel, 1);
|
||||
tmp->set_line(*this);
|
||||
|
|
@ -5101,7 +5120,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 NetScope*,
|
||||
ivl_type_t par_type,
|
||||
unsigned expr_wid) const
|
||||
{
|
||||
|
|
@ -5227,7 +5246,7 @@ 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 NetScope*found_in,
|
||||
ivl_type_t par_type,
|
||||
bool need_const) const
|
||||
{
|
||||
|
|
@ -5298,8 +5317,7 @@ NetExpr* PEIdent::elaborate_expr_param_idx_up_(Design*des, NetScope*scope,
|
|||
|
||||
/* Create a parameter reference for the variable select. */
|
||||
NetEConstParam*ptmp = new NetEConstParam(found_in, name, par_ex->value());
|
||||
NetScope::param_ref_t pref = found_in->find_parameter(name);
|
||||
ptmp->set_line((*pref).second);
|
||||
ptmp->set_line(found_in->get_parameter_line_info(name));
|
||||
|
||||
NetExpr*tmp = new NetESelect(ptmp, base, wid, IVL_SEL_IDX_UP);
|
||||
tmp->set_line(*this);
|
||||
|
|
@ -5308,7 +5326,7 @@ 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 NetScope*found_in,
|
||||
ivl_type_t par_type,
|
||||
bool need_const) const
|
||||
{
|
||||
|
|
@ -5380,14 +5398,38 @@ NetExpr* PEIdent::elaborate_expr_param_idx_do_(Design*des, NetScope*scope,
|
|||
|
||||
/* Create a parameter reference for the variable select. */
|
||||
NetEConstParam*ptmp = new NetEConstParam(found_in, name, par_ex->value());
|
||||
NetScope::param_ref_t pref = found_in->find_parameter(name);
|
||||
ptmp->set_line((*pref).second);
|
||||
ptmp->set_line(found_in->get_parameter_line_info(name));
|
||||
|
||||
NetExpr*tmp = new NetESelect(ptmp, base, wid, IVL_SEL_IDX_DOWN);
|
||||
tmp->set_line(*this);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
NetExpr* PEIdent::elaborate_expr_param_or_specparam_(Design*des,
|
||||
NetScope*scope,
|
||||
const NetExpr*par,
|
||||
NetScope*found_in,
|
||||
ivl_type_t par_type,
|
||||
unsigned expr_wid,
|
||||
unsigned flags) const
|
||||
{
|
||||
bool need_const = NEED_CONST & flags;
|
||||
|
||||
if (need_const && !(ANNOTATABLE & flags)) {
|
||||
perm_string name = peek_tail_name(path_);
|
||||
if (found_in->make_parameter_unannotatable(name)) {
|
||||
cerr << get_fileline() << ": warning: specparam '" << name
|
||||
<< "' is being used in a constant expression." << endl;
|
||||
cerr << get_fileline() << ": : This will prevent it "
|
||||
"being annotated at run time." << endl;
|
||||
}
|
||||
}
|
||||
|
||||
return elaborate_expr_param_(des, scope, par, found_in, par_type,
|
||||
expr_wid, flags);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Handle the case that the identifier is a parameter reference. The
|
||||
* parameter expression has already been located for us (as the par
|
||||
|
|
@ -5396,7 +5438,7 @@ NetExpr* PEIdent::elaborate_expr_param_idx_do_(Design*des, NetScope*scope,
|
|||
NetExpr* PEIdent::elaborate_expr_param_(Design*des,
|
||||
NetScope*scope,
|
||||
const NetExpr*par,
|
||||
NetScope*found_in,
|
||||
const NetScope*found_in,
|
||||
ivl_type_t par_type,
|
||||
unsigned expr_wid, unsigned flags) const
|
||||
{
|
||||
|
|
@ -5413,16 +5455,6 @@ NetExpr* PEIdent::elaborate_expr_param_(Design*des,
|
|||
<< "par_type: <nil>" << endl;
|
||||
}
|
||||
|
||||
if (need_const && !(ANNOTATABLE & flags)) {
|
||||
perm_string name = peek_tail_name(path_);
|
||||
if (found_in->make_parameter_unannotatable(name)) {
|
||||
cerr << get_fileline() << ": warning: specparam '" << name
|
||||
<< "' is being used in a constant expression." << endl;
|
||||
cerr << get_fileline() << ": : This will prevent it "
|
||||
"being annotated at run time." << endl;
|
||||
}
|
||||
}
|
||||
|
||||
const name_component_t&name_tail = path_.back();
|
||||
index_component_t::ctype_t use_sel = index_component_t::SEL_NONE;
|
||||
if (!name_tail.index.empty())
|
||||
|
|
@ -5500,8 +5532,7 @@ NetExpr* PEIdent::elaborate_expr_param_(Design*des,
|
|||
/* The numeric parameter value needs to have the file and line
|
||||
* information for the actual parameter not the expression. */
|
||||
assert(tmp);
|
||||
NetScope::param_ref_t pref = found_in->find_parameter(name);
|
||||
tmp->set_line((*pref).second);
|
||||
tmp->set_line(found_in->get_parameter_line_info(name));
|
||||
}
|
||||
|
||||
return tmp;
|
||||
|
|
|
|||
|
|
@ -524,6 +524,8 @@ static void elaborate_scope_class(Design*des, NetScope*scope, PClass*pclass)
|
|||
|
||||
class_scope->add_typedefs(&pclass->typedefs);
|
||||
|
||||
collect_scope_parameters(des, class_scope, pclass->parameters);
|
||||
|
||||
// Elaborate enum types declared in the class. We need these
|
||||
// now because enumeration constants can be used during scope
|
||||
// elaboration.
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ initial begin
|
|||
|
||||
// Not yet supported
|
||||
// c.e2 = C::A;
|
||||
// c.e2 = c.A;
|
||||
c.e2 = c.A;
|
||||
|
||||
// Check that they have the numerical value from the right scope
|
||||
if (c.e1 == 1 && c.e2 == 10) begin
|
||||
|
|
|
|||
|
|
@ -0,0 +1,28 @@
|
|||
// Check that it is possible to declare parameters and localparams inside a
|
||||
// class. Both declared parameters that can not be overridden.
|
||||
|
||||
module test;
|
||||
|
||||
class C;
|
||||
// `parameter` is also declaring a local parameter inside a class
|
||||
parameter A = 1;
|
||||
localparam B = 2;
|
||||
|
||||
function bit test();
|
||||
return A == 1 && B == 2;
|
||||
endfunction
|
||||
|
||||
endclass
|
||||
|
||||
initial begin
|
||||
C c;
|
||||
c = new;
|
||||
|
||||
if (c.test() && c.A == 1 && c.B == 2) begin
|
||||
$display("PASSED");
|
||||
end else begin
|
||||
$display("FAILED");
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
@ -436,6 +436,7 @@ sv_class22 normal,-g2009 ivltests
|
|||
sv_class23 normal,-g2009 ivltests
|
||||
sv_class24 normal,-g2009 ivltests
|
||||
sv_class_extends_scoped normal,-g2009 ivltests
|
||||
sv_class_localparam normal,-g2009 ivltests
|
||||
sv_class_new_init normal,-g2009 ivltests
|
||||
sv_darray1 normal,-g2009 ivltests
|
||||
sv_darray2 normal,-g2009 ivltests
|
||||
|
|
|
|||
|
|
@ -364,6 +364,7 @@ sv_class22 CE,-g2009 ivltests
|
|||
sv_class23 CE,-g2009 ivltests
|
||||
sv_class24 CE,-g2009 ivltests
|
||||
sv_class_extends_scoped CE,-g2009 ivltests
|
||||
sv_class_localparam CE,-g2009 ivltests
|
||||
sv_class_new_init CE,-g2009 ivltests
|
||||
sv_end_label CE,-g2009 ivltests # Also generate
|
||||
sv_foreach2 CE,-g2009,-pallowsigned=1 ivltests
|
||||
|
|
|
|||
|
|
@ -304,7 +304,7 @@ ivl_variable_type_t NetECReal::expr_type() const
|
|||
return IVL_VT_REAL;
|
||||
}
|
||||
|
||||
NetECRealParam::NetECRealParam(NetScope*s, perm_string n, const verireal&v)
|
||||
NetECRealParam::NetECRealParam(const NetScope*s, perm_string n, const verireal&v)
|
||||
: NetECReal(v), scope_(s), name_(n)
|
||||
{
|
||||
}
|
||||
|
|
|
|||
|
|
@ -460,18 +460,18 @@ const NetExpr* NetScope::get_parameter(Design*des, perm_string key,
|
|||
return tmp;
|
||||
}
|
||||
|
||||
NetScope::param_ref_t NetScope::find_parameter(perm_string key)
|
||||
LineInfo NetScope::get_parameter_line_info(perm_string key) const
|
||||
{
|
||||
map<perm_string,param_expr_t>::iterator idx;
|
||||
map<perm_string,param_expr_t>::const_iterator idx;
|
||||
|
||||
idx = parameters.find(key);
|
||||
if (idx != parameters.end()) return idx;
|
||||
if (idx != parameters.end()) return idx->second;
|
||||
|
||||
// To get here the parameter must already exist, so we should
|
||||
// never get here.
|
||||
assert(0);
|
||||
// But return something to avoid a compiler warning.
|
||||
return idx;
|
||||
return LineInfo();
|
||||
}
|
||||
|
||||
void NetScope::print_type(ostream&stream) const
|
||||
|
|
|
|||
|
|
@ -188,3 +188,9 @@ bool netclass_t::test_scope_is_method(const NetScope*scope) const
|
|||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
const NetExpr* netclass_t::get_parameter(Design *des, perm_string name,
|
||||
ivl_type_t &par_type) const
|
||||
{
|
||||
return class_scope_->get_parameter(des, name, par_type);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
# include <map>
|
||||
|
||||
class Design;
|
||||
class NetExpr;
|
||||
class NetNet;
|
||||
class NetScope;
|
||||
class PClass;
|
||||
|
|
@ -112,6 +113,9 @@ class netclass_t : public ivl_type_s {
|
|||
std::ostream& debug_dump(std::ostream&fd) const;
|
||||
void dump_scope(std::ostream&fd) const;
|
||||
|
||||
const NetExpr* get_parameter(Design *des, perm_string name,
|
||||
ivl_type_t &par_type) const;
|
||||
|
||||
private:
|
||||
perm_string name_;
|
||||
// If this is derived from another base class, point to it
|
||||
|
|
|
|||
|
|
@ -2391,7 +2391,7 @@ void NetEConst::trim()
|
|||
expr_width(value_.len());
|
||||
}
|
||||
|
||||
NetEConstParam::NetEConstParam(NetScope*s, perm_string n, const verinum&v)
|
||||
NetEConstParam::NetEConstParam(const NetScope*s, perm_string n, const verinum&v)
|
||||
: NetEConst(v), scope_(s), name_(n)
|
||||
{
|
||||
cast_signed_base_(v.has_sign());
|
||||
|
|
|
|||
10
netlist.h
10
netlist.h
|
|
@ -1239,7 +1239,7 @@ class NetScope : public Definitions, public Attrib {
|
|||
|
||||
typedef std::map<perm_string,param_expr_t>::iterator param_ref_t;
|
||||
|
||||
param_ref_t find_parameter(perm_string name);
|
||||
LineInfo get_parameter_line_info(perm_string name) const;
|
||||
|
||||
/* Module instance arrays are collected here for access during
|
||||
the multiple elaboration passes. */
|
||||
|
|
@ -2175,7 +2175,7 @@ class NetEConstEnum : public NetEConst {
|
|||
class NetEConstParam : public NetEConst {
|
||||
|
||||
public:
|
||||
explicit NetEConstParam(NetScope*scope, perm_string name,
|
||||
explicit NetEConstParam(const NetScope*scope, perm_string name,
|
||||
const verinum&val);
|
||||
~NetEConstParam();
|
||||
|
||||
|
|
@ -2188,7 +2188,7 @@ class NetEConstParam : public NetEConst {
|
|||
virtual NetEConstParam* dup_expr() const;
|
||||
|
||||
private:
|
||||
NetScope*scope_;
|
||||
const NetScope*scope_;
|
||||
perm_string name_;
|
||||
};
|
||||
|
||||
|
|
@ -2236,7 +2236,7 @@ class NetECString : public NetEConst {
|
|||
class NetECRealParam : public NetECReal {
|
||||
|
||||
public:
|
||||
explicit NetECRealParam(NetScope*scope, perm_string name,
|
||||
explicit NetECRealParam(const NetScope*scope, perm_string name,
|
||||
const verireal&val);
|
||||
~NetECRealParam();
|
||||
|
||||
|
|
@ -2249,7 +2249,7 @@ class NetECRealParam : public NetECReal {
|
|||
virtual NetECRealParam* dup_expr() const;
|
||||
|
||||
private:
|
||||
NetScope*scope_;
|
||||
const NetScope*scope_;
|
||||
perm_string name_;
|
||||
};
|
||||
|
||||
|
|
|
|||
9
parse.y
9
parse.y
|
|
@ -978,6 +978,8 @@ class_item /* IEEE1800-2005: A.1.8 */
|
|||
yyerrok;
|
||||
}
|
||||
|
||||
| parameter_declaration
|
||||
|
||||
| error ';'
|
||||
{ yyerror(@2, "error: invalid class item.");
|
||||
yyerrok;
|
||||
|
|
@ -2016,7 +2018,7 @@ package_import_item_list
|
|||
|
||||
package_item /* IEEE1800-2005 A.1.10 */
|
||||
: timeunits_declaration
|
||||
| parameter_or_localparam param_type parameter_assign_list ';'
|
||||
| parameter_declaration
|
||||
| type_declaration
|
||||
| function_declaration
|
||||
| task_declaration
|
||||
|
|
@ -2697,7 +2699,7 @@ block_item_decl
|
|||
{ if ($2) pform_make_events($2, @1.text, @1.first_line);
|
||||
}
|
||||
|
||||
| parameter_or_localparam param_type parameter_assign_list ';'
|
||||
| parameter_declaration
|
||||
|
||||
/* Blocks can have type declarations. */
|
||||
|
||||
|
|
@ -5570,6 +5572,9 @@ param_type : data_type_or_implicit { param_data_type = $1; }
|
|||
parameter : K_parameter { param_is_local = false; };
|
||||
localparam : K_localparam { param_is_local = true; };
|
||||
|
||||
parameter_declaration
|
||||
: parameter_or_localparam param_type parameter_assign_list ';'
|
||||
|
||||
parameter_or_localparam
|
||||
: parameter
|
||||
| localparam
|
||||
|
|
|
|||
3
pform.cc
3
pform.cc
|
|
@ -3213,6 +3213,9 @@ void pform_set_parameter(const struct vlltype&loc,
|
|||
scope->has_parameter_port_list)
|
||||
overridable = false;
|
||||
|
||||
if (pform_in_class())
|
||||
overridable = false;
|
||||
|
||||
Module::param_expr_t*parm = new Module::param_expr_t();
|
||||
FILE_NAME(parm, loc);
|
||||
|
||||
|
|
|
|||
1
pform.h
1
pform.h
|
|
@ -202,6 +202,7 @@ extern void pform_set_this_class(const struct vlltype&loc, PTaskFunc*net);
|
|||
extern void pform_set_constructor_return(PFunction*net);
|
||||
|
||||
extern void pform_end_class_declaration(const struct vlltype&loc);
|
||||
extern bool pform_in_class();
|
||||
|
||||
extern void pform_make_udp(perm_string name, std::list<perm_string>*parms,
|
||||
std::vector<PWire*>*decl, std::list<std::string>*table,
|
||||
|
|
|
|||
|
|
@ -164,3 +164,8 @@ void pform_end_class_declaration(const struct vlltype&loc)
|
|||
pform_cur_class = 0;
|
||||
pform_pop_scope();
|
||||
}
|
||||
|
||||
bool pform_in_class()
|
||||
{
|
||||
return pform_cur_class != 0;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue