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
|
||||
{
|
||||
NetNet* net = 0;
|
||||
ivl_type_t cls_val;
|
||||
const NetExpr*par = 0;
|
||||
ivl_type_t par_type;
|
||||
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)
|
||||
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 'E': /* === */
|
||||
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) &&
|
||||
l_type != r_type) {
|
||||
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;
|
||||
des->errors += 1;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
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;
|
||||
ivl_type_t cls_val = 0;
|
||||
const NetExpr*par = 0;
|
||||
ivl_type_t par_type = 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 (debug_elaborate)
|
||||
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)
|
||||
{
|
||||
NetNet* net = 0;
|
||||
ivl_type_t cls_val = 0;
|
||||
const NetExpr*par = 0;
|
||||
ivl_type_t par_type = 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_,
|
||||
net, par, eve, par_type);
|
||||
net, par, eve, par_type, cls_val);
|
||||
|
||||
// If there is a part/bit select expression, then process it
|
||||
// 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_;
|
||||
}
|
||||
|
||||
// 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) {
|
||||
expr_type_ = IVL_VT_LOGIC; // Assume bit/parts selects are logic
|
||||
expr_width_ = use_width;
|
||||
|
|
@ -4161,7 +4168,7 @@ unsigned PEIdent::test_width(Design*des, NetScope*scope, width_mode_t&mode)
|
|||
use_path.pop_back();
|
||||
|
||||
ivl_assert(*this, net == 0);
|
||||
symbol_search(this, des, scope, use_path, net, par, eve, 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?
|
||||
if (net != 0) {
|
||||
|
|
@ -4222,6 +4229,7 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
|
|||
bool need_const = NEED_CONST & flags;
|
||||
|
||||
NetNet* net = 0;
|
||||
ivl_type_t cls_val = 0;
|
||||
const NetExpr*par = 0;
|
||||
ivl_type_t par_type = 0;
|
||||
NetEvent* eve = 0;
|
||||
|
|
@ -4236,7 +4244,7 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
|
|||
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) {
|
||||
// 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();
|
||||
|
||||
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) {
|
||||
// Nope, no struct/class with member.
|
||||
|
|
@ -4501,6 +4510,7 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
|
|||
assert(scope);
|
||||
|
||||
NetNet* net = 0;
|
||||
ivl_type_t cls_val = 0;
|
||||
const NetExpr*par = 0;
|
||||
ivl_type_t par_type = 0;
|
||||
NetEvent* eve = 0;
|
||||
|
|
@ -4562,7 +4572,7 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
|
|||
NetScope*found_in = 0;
|
||||
while (net==0 && par==0 && eve==0 && !base_path.empty()) {
|
||||
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 (par) 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)
|
||||
*
|
||||
* 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.
|
||||
if (ports_->at(idx).defe != 0) {
|
||||
if (tmp->port_type() == NetNet::PINPUT) {
|
||||
tmp_def = elab_and_eval(des, scope, ports_->at(idx).defe,
|
||||
-1, scope->need_const_func());
|
||||
// Elaborate a class port default in the context of
|
||||
// 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) {
|
||||
cerr << get_fileline()
|
||||
<< ": error: Unable to evaluate "
|
||||
|
|
|
|||
|
|
@ -3770,6 +3770,7 @@ NetProc* PCallTask::elaborate_method_(Design*des, NetScope*scope,
|
|||
use_path.pop_back();
|
||||
|
||||
NetNet *net;
|
||||
ivl_type_t cls_val = 0;
|
||||
const NetExpr *par;
|
||||
ivl_type_t par_type = 0;
|
||||
NetEvent *eve;
|
||||
|
|
@ -3787,7 +3788,7 @@ NetProc* PCallTask::elaborate_method_(Design*des, NetScope*scope,
|
|||
// resolve to a class object. Note that the "this" symbol
|
||||
// (internally represented as "@") is handled by there being a
|
||||
// "this" object in the instance scope.
|
||||
symbol_search(this, des, scope, use_path, net, par, eve, par_type);
|
||||
symbol_search(this, des, scope, use_path, net, par, eve, par_type, cls_val);
|
||||
|
||||
if (net == 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
|
||||
* 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);
|
||||
|
||||
// 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) {
|
||||
cerr << pe->get_fileline() << ": Error: "
|
||||
<< "Class/null r-value not allowed in this context." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Get the final expression width. If the expression is unsized,
|
||||
// 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() {
|
||||
scope = 0;
|
||||
net = 0;
|
||||
cls_val = 0;
|
||||
par_val = 0;
|
||||
par_type = 0;
|
||||
eve = 0;
|
||||
|
|
@ -54,6 +55,7 @@ struct symbol_search_results {
|
|||
inline bool is_scope() const {
|
||||
if (net) return false;
|
||||
if (eve) return false;
|
||||
if (cls_val) return false;
|
||||
if (par_val) return false;
|
||||
if (scope) return true;
|
||||
return false;
|
||||
|
|
@ -62,6 +64,7 @@ struct symbol_search_results {
|
|||
inline bool is_found() const {
|
||||
if (net) return true;
|
||||
if (eve) return true;
|
||||
if (cls_val) return true;
|
||||
if (par_val) return true;
|
||||
if (scope) return true;
|
||||
return false;
|
||||
|
|
@ -72,6 +75,8 @@ struct symbol_search_results {
|
|||
NetScope*scope;
|
||||
// If this was a net, the signal itself.
|
||||
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
|
||||
// optional value dimensions.
|
||||
const NetExpr*par_val;
|
||||
|
|
@ -132,7 +137,8 @@ extern NetScope* symbol_search(const LineInfo*li,
|
|||
NetNet*&net, /* net/reg */
|
||||
const NetExpr*&par,/* parameter/expr */
|
||||
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,
|
||||
Design*des,
|
||||
|
|
@ -143,7 +149,9 @@ inline NetScope* symbol_search(const LineInfo*li,
|
|||
NetEvent*&eve /* named event */)
|
||||
{
|
||||
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 "netclass.h"
|
||||
# include "netparray.h"
|
||||
# include "netmisc.h"
|
||||
# include "compiler.h"
|
||||
# include "ivl_assert.h"
|
||||
|
|
@ -168,6 +170,21 @@ bool symbol_search(const LineInfo*li, Design*des, NetScope*scope,
|
|||
res->path_item = path_tail;
|
||||
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)) {
|
||||
|
|
@ -275,12 +292,14 @@ NetScope*symbol_search(const LineInfo*li, Design*des, NetScope*scope,
|
|||
NetNet*&net,
|
||||
const NetExpr*&par,
|
||||
NetEvent*&eve,
|
||||
ivl_type_t&par_type)
|
||||
ivl_type_t&par_type,
|
||||
ivl_type_t&cls_val)
|
||||
{
|
||||
symbol_search_results recurse;
|
||||
bool flag = symbol_search(li, des, scope, path, &recurse);
|
||||
|
||||
net = 0;
|
||||
cls_val = 0;
|
||||
par = 0;
|
||||
par_type = 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.
|
||||
net = recurse.net;
|
||||
cls_val = recurse.cls_val;
|
||||
par = recurse.par_val;
|
||||
par_type = recurse.par_type;
|
||||
eve = recurse.eve;
|
||||
|
|
|
|||
Loading…
Reference in New Issue