Elaborate size method of darray/queue objects.
This commit is contained in:
parent
d891285326
commit
a730572e37
6
PExpr.h
6
PExpr.h
|
|
@ -516,6 +516,12 @@ class PEIdent : public PExpr {
|
||||||
unsigned expr_wid,
|
unsigned expr_wid,
|
||||||
unsigned flags) const;
|
unsigned flags) const;
|
||||||
|
|
||||||
|
unsigned test_width_method_(Design*des, NetScope*scope, width_mode_t&mode);
|
||||||
|
NetExpr*elaborate_expr_method_(Design*des,
|
||||||
|
NetScope*scope,
|
||||||
|
unsigned expr_wid,
|
||||||
|
unsigned flags) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
NetNet* elaborate_lnet_common_(Design*des, NetScope*scope,
|
NetNet* elaborate_lnet_common_(Design*des, NetScope*scope,
|
||||||
bool bidirectional_flag) const;
|
bool bidirectional_flag) const;
|
||||||
|
|
|
||||||
104
elab_expr.cc
104
elab_expr.cc
|
|
@ -106,6 +106,7 @@ NetExpr* elaborate_rval_expr(Design*des, NetScope*scope, ivl_type_t lv_net_type,
|
||||||
int context_wid = -1;
|
int context_wid = -1;
|
||||||
switch (lv_type) {
|
switch (lv_type) {
|
||||||
case IVL_VT_DARRAY:
|
case IVL_VT_DARRAY:
|
||||||
|
case IVL_VT_QUEUE:
|
||||||
// For these types, use a different elab_and_eval that
|
// For these types, use a different elab_and_eval that
|
||||||
// uses the lv_net_type. We should eventually transition
|
// uses the lv_net_type. We should eventually transition
|
||||||
// all the types to this new form.
|
// all the types to this new form.
|
||||||
|
|
@ -2782,6 +2783,48 @@ bool PEIdent::calculate_param_range_(Design*, NetScope*,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned PEIdent::test_width_method_(Design*des, NetScope*scope, width_mode_t&mode)
|
||||||
|
{
|
||||||
|
if (!gn_system_verilog())
|
||||||
|
return 0;
|
||||||
|
if (path_.size() < 2)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
pform_name_t use_path = path_;
|
||||||
|
perm_string member_name = peek_tail_name(path_);
|
||||||
|
use_path.pop_back();
|
||||||
|
|
||||||
|
if (debug_elaborate) {
|
||||||
|
cerr << get_fileline() << ": PEIdent::test_width_method_: "
|
||||||
|
<< "Try to find method=" << member_name
|
||||||
|
<< " of signal " << use_path << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
NetNet*net = 0;
|
||||||
|
const NetExpr*par = 0;
|
||||||
|
NetEvent*eve = 0;
|
||||||
|
const NetExpr*ex1 = 0, *ex2 = 0;
|
||||||
|
symbol_search(this, des, scope, use_path, net, par, eve, ex1, ex2);
|
||||||
|
if (net == 0) {
|
||||||
|
if (debug_elaborate)
|
||||||
|
cerr << get_fileline() << ": PEIdent::test_width_method_: "
|
||||||
|
<< "Only nets can have methods, so give up here." << endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (const netdarray_t*dtype = net->darray_type()) {
|
||||||
|
if (member_name == "size") {
|
||||||
|
expr_type_ = IVL_VT_BOOL;
|
||||||
|
expr_width_ = 32;
|
||||||
|
min_width_ = 32;
|
||||||
|
signed_flag_= true;
|
||||||
|
return 32;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
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;
|
||||||
|
|
@ -2796,6 +2839,10 @@ unsigned PEIdent::test_width(Design*des, NetScope*scope, width_mode_t&mode)
|
||||||
ivl_assert(*this, use_scope);
|
ivl_assert(*this, use_scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (unsigned tmp = test_width_method_(des, scope, mode)) {
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
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,
|
||||||
ex1, ex2);
|
ex1, ex2);
|
||||||
|
|
@ -3167,6 +3214,55 @@ NetExpr* PEIdent::elaborate_expr_class_member_(Design*des, NetScope*scope,
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NetExpr* PEIdent::elaborate_expr_method_(Design*des, NetScope*scope,
|
||||||
|
unsigned expr_wid, unsigned flags) const
|
||||||
|
{
|
||||||
|
if (!gn_system_verilog())
|
||||||
|
return 0;
|
||||||
|
if (path_.size() < 2)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
pform_name_t use_path = path_;
|
||||||
|
perm_string member_name = peek_tail_name(path_);
|
||||||
|
use_path.pop_back();
|
||||||
|
|
||||||
|
if (debug_elaborate) {
|
||||||
|
cerr << get_fileline() << ": PEIdent::elaborate_expr_method_: "
|
||||||
|
<< "Try to find method=" << member_name
|
||||||
|
<< " of signal " << use_path << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
NetNet*net = 0;
|
||||||
|
const NetExpr*par = 0;
|
||||||
|
NetEvent*eve = 0;
|
||||||
|
const NetExpr*ex1 = 0, *ex2 = 0;
|
||||||
|
symbol_search(this, des, scope, use_path, net, par, eve, ex1, ex2);
|
||||||
|
if (net == 0) {
|
||||||
|
if (debug_elaborate)
|
||||||
|
cerr << get_fileline() << ": PEIdent::elaborate_expr_method_: "
|
||||||
|
<< "Only nets can have methods, so give up here." << endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (const netdarray_t*dtype = net->darray_type()) {
|
||||||
|
if (member_name == "size") {
|
||||||
|
NetESFunc*fun = new NetESFunc("$ivl_queue_method$size",
|
||||||
|
expr_type_, expr_width_, 1);
|
||||||
|
fun->set_line(*this);
|
||||||
|
|
||||||
|
NetESignal*arg = new NetESignal(net);
|
||||||
|
arg->set_line(*net);
|
||||||
|
|
||||||
|
fun->parm(0, arg);
|
||||||
|
return fun;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Elaborate an identifier in an expression. The identifier can be a
|
* Elaborate an identifier in an expression. The identifier can be a
|
||||||
* parameter name, a signal name or a memory name. It can also be a
|
* parameter name, a signal name or a memory name. It can also be a
|
||||||
|
|
@ -3227,6 +3323,14 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
|
||||||
ivl_assert(*this, use_scope);
|
ivl_assert(*this, use_scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Special case: Detect the special situation that the name is
|
||||||
|
// a method of an object (including built-in methods) that has
|
||||||
|
// no arguments. For example, "foo.size" is the call to the
|
||||||
|
// size() method if foo is an array type.
|
||||||
|
if (NetExpr*tmp = elaborate_expr_method_(des, scope, expr_wid, flags)) {
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
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,
|
||||||
ex1, ex2);
|
ex1, ex2);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue