Update the symbol search to find class properties

This commit is contained in:
Cary R 2021-02-16 23:45:27 -08:00
parent 18e7406dd0
commit 753bf516d6
7 changed files with 71 additions and 23 deletions

View File

@ -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();

View File

@ -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;

View File

@ -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 "

View File

@ -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;

View File

@ -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().

View File

@ -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);
}
/*

View File

@ -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;