Update the symbol search to find class properties
This commit is contained in:
parent
18e7406dd0
commit
753bf516d6
4
PExpr.cc
4
PExpr.cc
|
|
@ -447,11 +447,13 @@ void PEIdent::declare_implicit_nets(LexicalScope*scope, NetNet::Type type)
|
||||||
bool PEIdent::has_aa_term(Design*des, NetScope*scope) const
|
bool PEIdent::has_aa_term(Design*des, NetScope*scope) const
|
||||||
{
|
{
|
||||||
NetNet* net = 0;
|
NetNet* net = 0;
|
||||||
|
ivl_type_t cls_val;
|
||||||
const NetExpr*par = 0;
|
const NetExpr*par = 0;
|
||||||
ivl_type_t par_type;
|
ivl_type_t par_type;
|
||||||
NetEvent* eve = 0;
|
NetEvent* eve = 0;
|
||||||
|
|
||||||
scope = symbol_search(this, des, scope, path_, net, par, eve, par_type);
|
scope = symbol_search(this, des, scope, path_, net, par, eve,
|
||||||
|
par_type, cls_val);
|
||||||
|
|
||||||
if (scope)
|
if (scope)
|
||||||
return scope->is_auto();
|
return scope->is_auto();
|
||||||
|
|
|
||||||
30
elab_expr.cc
30
elab_expr.cc
|
|
@ -634,9 +634,6 @@ unsigned PEBComp::test_width(Design*des, NetScope*scope, width_mode_t&)
|
||||||
case 'n': /* != */
|
case 'n': /* != */
|
||||||
case 'E': /* === */
|
case 'E': /* === */
|
||||||
case 'N': /* !== */
|
case 'N': /* !== */
|
||||||
// FIXME: A class variable/array inside a class is not
|
|
||||||
// reported correctly so this cannot be used.
|
|
||||||
#if 0
|
|
||||||
if ((l_type == IVL_VT_CLASS || r_type == IVL_VT_CLASS) &&
|
if ((l_type == IVL_VT_CLASS || r_type == IVL_VT_CLASS) &&
|
||||||
l_type != r_type) {
|
l_type != r_type) {
|
||||||
cerr << get_fileline() << ": error: "
|
cerr << get_fileline() << ": error: "
|
||||||
|
|
@ -645,7 +642,6 @@ unsigned PEBComp::test_width(Design*des, NetScope*scope, width_mode_t&)
|
||||||
<< human_readable_op(op_) << "' operator." << endl;
|
<< human_readable_op(op_) << "' operator." << endl;
|
||||||
des->errors += 1;
|
des->errors += 1;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (l_type == IVL_VT_CLASS || r_type == IVL_VT_CLASS) {
|
if (l_type == IVL_VT_CLASS || r_type == IVL_VT_CLASS) {
|
||||||
|
|
@ -3924,10 +3920,11 @@ unsigned PEIdent::test_width_method_(Design*des, NetScope*scope, width_mode_t&)
|
||||||
}
|
}
|
||||||
|
|
||||||
NetNet*net = 0;
|
NetNet*net = 0;
|
||||||
|
ivl_type_t cls_val = 0;
|
||||||
const NetExpr*par = 0;
|
const NetExpr*par = 0;
|
||||||
ivl_type_t par_type = 0;
|
ivl_type_t par_type = 0;
|
||||||
NetEvent*eve = 0;
|
NetEvent*eve = 0;
|
||||||
symbol_search(this, des, scope, use_path, net, par, eve, par_type);
|
symbol_search(this, des, scope, use_path, net, par, eve, par_type, cls_val);
|
||||||
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_: "
|
||||||
|
|
@ -3970,6 +3967,7 @@ unsigned PEIdent::test_width_method_(Design*des, NetScope*scope, width_mode_t&)
|
||||||
unsigned PEIdent::test_width(Design*des, NetScope*scope, width_mode_t&mode)
|
unsigned PEIdent::test_width(Design*des, NetScope*scope, width_mode_t&mode)
|
||||||
{
|
{
|
||||||
NetNet* net = 0;
|
NetNet* net = 0;
|
||||||
|
ivl_type_t cls_val = 0;
|
||||||
const NetExpr*par = 0;
|
const NetExpr*par = 0;
|
||||||
ivl_type_t par_type = 0;
|
ivl_type_t par_type = 0;
|
||||||
NetEvent* eve = 0;
|
NetEvent* eve = 0;
|
||||||
|
|
@ -3985,7 +3983,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, par_type);
|
net, par, eve, par_type, cls_val);
|
||||||
|
|
||||||
// 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
|
||||||
|
|
@ -4063,6 +4061,15 @@ unsigned PEIdent::test_width(Design*des, NetScope*scope, width_mode_t&mode)
|
||||||
return expr_width_;
|
return expr_width_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Look for a class property.
|
||||||
|
if (gn_system_verilog() && cls_val) {
|
||||||
|
expr_type_ = cls_val->base_type();
|
||||||
|
expr_width_ = cls_val->packed_width();
|
||||||
|
min_width_ = expr_width_;
|
||||||
|
signed_flag_ = cls_val->get_signed();
|
||||||
|
return expr_width_;
|
||||||
|
}
|
||||||
|
|
||||||
if (use_width != UINT_MAX) {
|
if (use_width != UINT_MAX) {
|
||||||
expr_type_ = IVL_VT_LOGIC; // Assume bit/parts selects are logic
|
expr_type_ = IVL_VT_LOGIC; // Assume bit/parts selects are logic
|
||||||
expr_width_ = use_width;
|
expr_width_ = use_width;
|
||||||
|
|
@ -4161,7 +4168,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, par_type);
|
symbol_search(this, des, scope, use_path, net, par, eve, par_type, cls_val);
|
||||||
|
|
||||||
// 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) {
|
||||||
|
|
@ -4222,6 +4229,7 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
|
||||||
bool need_const = NEED_CONST & flags;
|
bool need_const = NEED_CONST & flags;
|
||||||
|
|
||||||
NetNet* net = 0;
|
NetNet* net = 0;
|
||||||
|
ivl_type_t cls_val = 0;
|
||||||
const NetExpr*par = 0;
|
const NetExpr*par = 0;
|
||||||
ivl_type_t par_type = 0;
|
ivl_type_t par_type = 0;
|
||||||
NetEvent* eve = 0;
|
NetEvent* eve = 0;
|
||||||
|
|
@ -4236,7 +4244,7 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
symbol_search(this, des, use_scope, path_, net, par, eve, par_type);
|
symbol_search(this, des, use_scope, path_, net, par, eve, par_type, cls_val);
|
||||||
|
|
||||||
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
|
||||||
|
|
@ -4248,7 +4256,8 @@ 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, par_type);
|
symbol_search(this, des, use_scope, use_path, net, par, eve,
|
||||||
|
par_type, cls_val);
|
||||||
|
|
||||||
if (net == 0) {
|
if (net == 0) {
|
||||||
// Nope, no struct/class with member.
|
// Nope, no struct/class with member.
|
||||||
|
|
@ -4501,6 +4510,7 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
|
||||||
assert(scope);
|
assert(scope);
|
||||||
|
|
||||||
NetNet* net = 0;
|
NetNet* net = 0;
|
||||||
|
ivl_type_t cls_val = 0;
|
||||||
const NetExpr*par = 0;
|
const NetExpr*par = 0;
|
||||||
ivl_type_t par_type = 0;
|
ivl_type_t par_type = 0;
|
||||||
NetEvent* eve = 0;
|
NetEvent* eve = 0;
|
||||||
|
|
@ -4562,7 +4572,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.empty()) {
|
while (net==0 && par==0 && eve==0 && !base_path.empty()) {
|
||||||
found_in = symbol_search(this, des, use_scope, base_path,
|
found_in = symbol_search(this, des, use_scope, base_path,
|
||||||
net, par, eve, par_type);
|
net, par, eve, par_type, cls_val);
|
||||||
if (net) break;
|
if (net) break;
|
||||||
if (par) break;
|
if (par) break;
|
||||||
if (eve) break;
|
if (eve) break;
|
||||||
|
|
|
||||||
17
elab_sig.cc
17
elab_sig.cc
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2000-2020 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 2000-2021 Stephen Williams (steve@icarus.com)
|
||||||
* Copyright CERN 2012 / Stephen Williams (steve@icarus.com)
|
* Copyright CERN 2012 / Stephen Williams (steve@icarus.com)
|
||||||
*
|
*
|
||||||
* This source code is free software; you can redistribute it
|
* This source code is free software; you can redistribute it
|
||||||
|
|
@ -720,8 +720,19 @@ void PTaskFunc::elaborate_sig_ports_(Design*des, NetScope*scope,
|
||||||
// that expression here.
|
// that expression here.
|
||||||
if (ports_->at(idx).defe != 0) {
|
if (ports_->at(idx).defe != 0) {
|
||||||
if (tmp->port_type() == NetNet::PINPUT) {
|
if (tmp->port_type() == NetNet::PINPUT) {
|
||||||
tmp_def = elab_and_eval(des, scope, ports_->at(idx).defe,
|
// Elaborate a class port default in the context of
|
||||||
-1, scope->need_const_func());
|
// the class type.
|
||||||
|
if (tmp->data_type() == IVL_VT_CLASS) {
|
||||||
|
tmp_def = elab_and_eval(des, scope,
|
||||||
|
ports_->at(idx).defe,
|
||||||
|
tmp->net_type(),
|
||||||
|
scope->need_const_func());
|
||||||
|
} else {
|
||||||
|
tmp_def = elab_and_eval(des, scope,
|
||||||
|
ports_->at(idx).defe,
|
||||||
|
-1,
|
||||||
|
scope->need_const_func());
|
||||||
|
}
|
||||||
if (tmp_def == 0) {
|
if (tmp_def == 0) {
|
||||||
cerr << get_fileline()
|
cerr << get_fileline()
|
||||||
<< ": error: Unable to evaluate "
|
<< ": error: Unable to evaluate "
|
||||||
|
|
|
||||||
|
|
@ -3770,6 +3770,7 @@ NetProc* PCallTask::elaborate_method_(Design*des, NetScope*scope,
|
||||||
use_path.pop_back();
|
use_path.pop_back();
|
||||||
|
|
||||||
NetNet *net;
|
NetNet *net;
|
||||||
|
ivl_type_t cls_val = 0;
|
||||||
const NetExpr *par;
|
const NetExpr *par;
|
||||||
ivl_type_t par_type = 0;
|
ivl_type_t par_type = 0;
|
||||||
NetEvent *eve;
|
NetEvent *eve;
|
||||||
|
|
@ -3787,7 +3788,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, net, par, eve, par_type);
|
symbol_search(this, des, scope, use_path, net, par, eve, par_type, cls_val);
|
||||||
|
|
||||||
if (net == 0)
|
if (net == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2001-2020 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 2001-2021 Stephen Williams (steve@icarus.com)
|
||||||
*
|
*
|
||||||
* This source code is free software; you can redistribute it
|
* This source code is free software; you can redistribute it
|
||||||
* and/or modify it in source code form under the terms of the GNU
|
* and/or modify it in source code form under the terms of the GNU
|
||||||
|
|
@ -858,16 +858,12 @@ static NetExpr* do_elab_and_eval(Design*des, NetScope*scope, PExpr*pe,
|
||||||
|
|
||||||
pe->test_width(des, scope, mode);
|
pe->test_width(des, scope, mode);
|
||||||
|
|
||||||
// FIXME: A class variable/array inside a class is not
|
|
||||||
// reported correctly so this cannot be used.
|
|
||||||
#if 0
|
|
||||||
if (pe->expr_type() == IVL_VT_CLASS) {
|
if (pe->expr_type() == IVL_VT_CLASS) {
|
||||||
cerr << pe->get_fileline() << ": Error: "
|
cerr << pe->get_fileline() << ": Error: "
|
||||||
<< "Class/null r-value not allowed in this context." << endl;
|
<< "Class/null r-value not allowed in this context." << endl;
|
||||||
des->errors += 1;
|
des->errors += 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
// Get the final expression width. If the expression is unsized,
|
// Get the final expression width. If the expression is unsized,
|
||||||
// this may be different from the value returned by test_width().
|
// this may be different from the value returned by test_width().
|
||||||
|
|
|
||||||
12
netmisc.h
12
netmisc.h
|
|
@ -46,6 +46,7 @@ struct symbol_search_results {
|
||||||
inline symbol_search_results() {
|
inline symbol_search_results() {
|
||||||
scope = 0;
|
scope = 0;
|
||||||
net = 0;
|
net = 0;
|
||||||
|
cls_val = 0;
|
||||||
par_val = 0;
|
par_val = 0;
|
||||||
par_type = 0;
|
par_type = 0;
|
||||||
eve = 0;
|
eve = 0;
|
||||||
|
|
@ -54,6 +55,7 @@ struct symbol_search_results {
|
||||||
inline bool is_scope() const {
|
inline bool is_scope() const {
|
||||||
if (net) return false;
|
if (net) return false;
|
||||||
if (eve) return false;
|
if (eve) return false;
|
||||||
|
if (cls_val) return false;
|
||||||
if (par_val) return false;
|
if (par_val) return false;
|
||||||
if (scope) return true;
|
if (scope) return true;
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -62,6 +64,7 @@ struct symbol_search_results {
|
||||||
inline bool is_found() const {
|
inline bool is_found() const {
|
||||||
if (net) return true;
|
if (net) return true;
|
||||||
if (eve) return true;
|
if (eve) return true;
|
||||||
|
if (cls_val) return true;
|
||||||
if (par_val) return true;
|
if (par_val) return true;
|
||||||
if (scope) return true;
|
if (scope) return true;
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -72,6 +75,8 @@ struct symbol_search_results {
|
||||||
NetScope*scope;
|
NetScope*scope;
|
||||||
// If this was a net, the signal itself.
|
// If this was a net, the signal itself.
|
||||||
NetNet*net;
|
NetNet*net;
|
||||||
|
// For a class property we only have type information.
|
||||||
|
ivl_type_t cls_val;
|
||||||
// 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;
|
||||||
|
|
@ -132,7 +137,8 @@ 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 */
|
||||||
ivl_type_t&par_type);
|
ivl_type_t&par_type,
|
||||||
|
ivl_type_t&cls_val);
|
||||||
|
|
||||||
inline NetScope* symbol_search(const LineInfo*li,
|
inline NetScope* symbol_search(const LineInfo*li,
|
||||||
Design*des,
|
Design*des,
|
||||||
|
|
@ -143,7 +149,9 @@ inline NetScope* symbol_search(const LineInfo*li,
|
||||||
NetEvent*&eve /* named event */)
|
NetEvent*&eve /* named event */)
|
||||||
{
|
{
|
||||||
ivl_type_t par_type;
|
ivl_type_t par_type;
|
||||||
return symbol_search(li, des, start, path, net, par, eve, par_type);
|
ivl_type_t cls_val;
|
||||||
|
return symbol_search(li, des, start, path, net, par, eve,
|
||||||
|
par_type, cls_val);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
# include "netlist.h"
|
# include "netlist.h"
|
||||||
|
# include "netclass.h"
|
||||||
|
# include "netparray.h"
|
||||||
# include "netmisc.h"
|
# include "netmisc.h"
|
||||||
# include "compiler.h"
|
# include "compiler.h"
|
||||||
# include "ivl_assert.h"
|
# include "ivl_assert.h"
|
||||||
|
|
@ -168,6 +170,21 @@ bool symbol_search(const LineInfo*li, Design*des, NetScope*scope,
|
||||||
res->path_item = path_tail;
|
res->path_item = path_tail;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Static items are just normal signals and are found above.
|
||||||
|
if (scope->type() == NetScope::CLASS) {
|
||||||
|
netclass_t*clsnet = scope->find_class(des, scope->basename());
|
||||||
|
int pidx = clsnet->property_idx_from_name(path_tail.name);
|
||||||
|
if (pidx >= 0) {
|
||||||
|
ivl_type_t prop_type = clsnet->get_prop_type(pidx);
|
||||||
|
const netuarray_t*tmp_ua = dynamic_cast<const netuarray_t*>(prop_type);
|
||||||
|
if (tmp_ua) prop_type = tmp_ua->element_type();
|
||||||
|
res->scope = scope;
|
||||||
|
res->cls_val = prop_type;
|
||||||
|
res->path_item = path_tail;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NetScope*import_scope = scope->find_import(des, path_tail.name)) {
|
if (NetScope*import_scope = scope->find_import(des, path_tail.name)) {
|
||||||
|
|
@ -275,12 +292,14 @@ NetScope*symbol_search(const LineInfo*li, Design*des, NetScope*scope,
|
||||||
NetNet*&net,
|
NetNet*&net,
|
||||||
const NetExpr*&par,
|
const NetExpr*&par,
|
||||||
NetEvent*&eve,
|
NetEvent*&eve,
|
||||||
ivl_type_t&par_type)
|
ivl_type_t&par_type,
|
||||||
|
ivl_type_t&cls_val)
|
||||||
{
|
{
|
||||||
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 = 0;
|
net = 0;
|
||||||
|
cls_val = 0;
|
||||||
par = 0;
|
par = 0;
|
||||||
par_type = 0;
|
par_type = 0;
|
||||||
eve = 0;
|
eve = 0;
|
||||||
|
|
@ -297,6 +316,7 @@ NetScope*symbol_search(const LineInfo*li, Design*des, NetScope*scope,
|
||||||
|
|
||||||
// Convert the extended results to the compatible results.
|
// Convert the extended results to the compatible results.
|
||||||
net = recurse.net;
|
net = recurse.net;
|
||||||
|
cls_val = recurse.cls_val;
|
||||||
par = recurse.par_val;
|
par = recurse.par_val;
|
||||||
par_type = recurse.par_type;
|
par_type = recurse.par_type;
|
||||||
eve = recurse.eve;
|
eve = recurse.eve;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue