Handle class-type identifier expressions.
This commit is contained in:
parent
79903ecadd
commit
f7033ca19a
2
PExpr.h
2
PExpr.h
|
|
@ -312,6 +312,8 @@ class PEIdent : public PExpr {
|
|||
NetScope*scope,
|
||||
bool is_force) const;
|
||||
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
|
||||
ivl_type_t type, unsigned flags) const;
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
|
||||
unsigned expr_wid,
|
||||
unsigned flags) const;
|
||||
|
|
|
|||
46
elab_expr.cc
46
elab_expr.cc
|
|
@ -2501,6 +2501,52 @@ unsigned PEIdent::test_width(Design*des, NetScope*scope, width_mode_t&mode)
|
|||
return expr_width_;
|
||||
}
|
||||
|
||||
|
||||
NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
|
||||
ivl_type_t ntype, unsigned) const
|
||||
{
|
||||
NetNet* net = 0;
|
||||
const NetExpr*par = 0;
|
||||
NetEvent* eve = 0;
|
||||
const NetExpr*ex1, *ex2;
|
||||
|
||||
NetScope*found_in = symbol_search(this, des, scope, path_,
|
||||
net, par, eve,
|
||||
ex1, ex2);
|
||||
|
||||
if (net == 0) {
|
||||
cerr << get_fileline() << ": internal error: "
|
||||
<< "Expecting idents wtih ntype to be signals." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (net->net_type() != ntype) {
|
||||
cerr << get_fileline() << ": internal_error: "
|
||||
<< "net type doesn't match context type." << endl;
|
||||
|
||||
cerr << get_fileline() << ": : "
|
||||
<< "net type=";
|
||||
if (net->net_type())
|
||||
net->net_type()->debug_dump(cerr);
|
||||
else
|
||||
cerr << "<nil>";
|
||||
cerr << endl;
|
||||
|
||||
cerr << get_fileline() << ": : "
|
||||
<< "context type=";
|
||||
ivl_assert(*this, ntype);
|
||||
ntype->debug_dump(cerr);
|
||||
cerr << endl;
|
||||
}
|
||||
ivl_assert(*this, net->net_type() == ntype);
|
||||
|
||||
NetESignal*tmp = new NetESignal(net);
|
||||
tmp->set_line(*this);
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
|
|
|
|||
24
elaborate.cc
24
elaborate.cc
|
|
@ -36,6 +36,8 @@
|
|||
# include "PSpec.h"
|
||||
# include "netlist.h"
|
||||
# include "netvector.h"
|
||||
# include "netdarray.h"
|
||||
# include "netclass.h"
|
||||
# include "netmisc.h"
|
||||
# include "util.h"
|
||||
# include "parse_api.h"
|
||||
|
|
@ -2377,20 +2379,18 @@ NetProc* PAssign::elaborate(Design*des, NetScope*scope) const
|
|||
delay = elaborate_delay_expr(delay_, des, scope);
|
||||
|
||||
NetExpr*rv;
|
||||
if (lv->more==0 && dynamic_cast<const PENew*> (rval())) {
|
||||
/* Special case: The l-value is a single signal, and the
|
||||
r-value expression is a "new" expression. The l-value
|
||||
has a new form of type, and the PENew expression
|
||||
requires the extra information that it contains. So
|
||||
handle it with this code instead. */
|
||||
rv = elaborate_rval_(des, scope, lv->sig()->net_type());
|
||||
const ivl_type_s*lv_net_type = lv->net_type();
|
||||
|
||||
} else if (lv->more==0 && dynamic_cast<const PENull*> (rval())) {
|
||||
rv = elaborate_rval_(des, scope, lv->sig()->net_type());
|
||||
/* If the l-value is a compound type of some sort, then use
|
||||
the newer net_type form of the elaborate_rval_ method to
|
||||
handle the new types. */
|
||||
if (dynamic_cast<const netclass_t*> (lv_net_type)) {
|
||||
ivl_assert(*this, lv->more==0);
|
||||
rv = elaborate_rval_(des, scope, lv_net_type);
|
||||
|
||||
} else if (lv->more==0 && dynamic_cast<const PENewClass*> (rval())) {
|
||||
|
||||
rv = elaborate_rval_(des, scope, lv->sig()->net_type());
|
||||
} else if (dynamic_cast<const netdarray_t*> (lv_net_type)) {
|
||||
ivl_assert(*this, lv->more==0);
|
||||
rv = elaborate_rval_(des, scope, lv_net_type);
|
||||
|
||||
} else {
|
||||
/* Elaborate the r-value expression, then try to evaluate it. */
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
# include "config.h"
|
||||
|
||||
# include "netlist.h"
|
||||
# include "netclass.h"
|
||||
# include "netdarray.h"
|
||||
|
||||
/*
|
||||
|
|
@ -107,6 +108,21 @@ ivl_variable_type_t NetAssign_::expr_type() const
|
|||
return sig_->data_type();
|
||||
}
|
||||
|
||||
const ivl_type_s* NetAssign_::net_type() const
|
||||
{
|
||||
if (dynamic_cast<const netclass_t*> (sig_->net_type()))
|
||||
return sig_->net_type();
|
||||
|
||||
if (dynamic_cast<const netdarray_t*> (sig_->net_type())) {
|
||||
if (word_ == 0)
|
||||
return sig_->net_type();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
netenum_t*NetAssign_::enumeration() const
|
||||
{
|
||||
netenum_t*tmp = 0;
|
||||
|
|
|
|||
|
|
@ -2453,6 +2453,11 @@ class NetAssign_ {
|
|||
unsigned lwidth() const;
|
||||
ivl_variable_type_t expr_type() const;
|
||||
|
||||
// Get the expression type of the l-value. This may be
|
||||
// different from the type of the contained signal if for
|
||||
// example a darray is indexed.
|
||||
const ivl_type_s* net_type() const;
|
||||
|
||||
// Return the enumeration type of this l-value, or nil if it's
|
||||
// not an enumeration.
|
||||
netenum_t*enumeration() const;
|
||||
|
|
|
|||
|
|
@ -79,6 +79,13 @@ static int eval_object_null(ivl_expr_t ex)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int eval_object_signal(ivl_expr_t ex)
|
||||
{
|
||||
ivl_signal_t sig = ivl_expr_signal(ex);
|
||||
fprintf(vvp_out, " %%load/obj v%p_0;\n", sig);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int draw_eval_object(ivl_expr_t ex)
|
||||
{
|
||||
switch (ivl_expr_type(ex)) {
|
||||
|
|
@ -90,7 +97,7 @@ int draw_eval_object(ivl_expr_t ex)
|
|||
case IVL_VT_DARRAY:
|
||||
return eval_darray_new(ex);
|
||||
default:
|
||||
fprintf(vvp_out, "; ERROR: Invalid type (%d) for <new>\n",
|
||||
fprintf(vvp_out, "; ERROR: draw_eval_object: Invalid type (%d) for <new>\n",
|
||||
ivl_expr_value(ex));
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -98,8 +105,11 @@ int draw_eval_object(ivl_expr_t ex)
|
|||
case IVL_EX_NULL:
|
||||
return eval_object_null(ex);
|
||||
|
||||
case IVL_EX_SIGNAL:
|
||||
return eval_object_signal(ex);
|
||||
|
||||
default:
|
||||
fprintf(vvp_out, "; ERROR: Invalid expression type %u\n", ivl_expr_type(ex));
|
||||
fprintf(vvp_out, "; ERROR: draw_eval_object: Invalid expression type %u\n", ivl_expr_type(ex));
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -130,6 +130,7 @@ extern bool of_LOAD_DAR(vthread_t thr, vvp_code_t code);
|
|||
extern bool of_LOAD_REAL(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_LOAD_DAR_R(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_LOAD_DAR_STR(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_LOAD_OBJ(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_LOAD_STR(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_LOAD_VEC(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_LOAD_VP0(vthread_t thr, vvp_code_t code);
|
||||
|
|
|
|||
|
|
@ -177,6 +177,7 @@ static const struct opcode_table_s opcode_table[] = {
|
|||
{ "%load/dar",of_LOAD_DAR,3,{OA_BIT1, OA_FUNC_PTR, OA_BIT2} },
|
||||
{ "%load/dar/r", of_LOAD_DAR_R, 1, {OA_FUNC_PTR, OA_NONE, OA_NONE}},
|
||||
{ "%load/dar/str",of_LOAD_DAR_STR, 1, {OA_FUNC_PTR, OA_NONE, OA_NONE} },
|
||||
{ "%load/obj", of_LOAD_OBJ, 1,{OA_FUNC_PTR,OA_NONE, OA_NONE} },
|
||||
{ "%load/real", of_LOAD_REAL,1,{OA_VPI_PTR, OA_NONE, OA_NONE} },
|
||||
{ "%load/str", of_LOAD_STR, 1,{OA_FUNC_PTR,OA_NONE, OA_NONE} },
|
||||
{ "%load/v", of_LOAD_VEC,3, {OA_BIT1, OA_FUNC_PTR, OA_BIT2} },
|
||||
|
|
|
|||
|
|
@ -630,6 +630,14 @@ The dar/r variant reads a real-value into a real-valued register.
|
|||
|
||||
(See also %set/dar)
|
||||
|
||||
* %load/obj <var-label>
|
||||
|
||||
This instruction loads an object handle and pushes it to the top of
|
||||
the object handle stack.
|
||||
|
||||
See also %store/obj.
|
||||
|
||||
|
||||
* %load/real <vpi-label>
|
||||
|
||||
The %load/real instruction reads a real value from the vpi-like object
|
||||
|
|
@ -979,6 +987,8 @@ For a negative shift %shiftr/i0 will pad the value with 'bx.
|
|||
This pops the top of the object stack and writes it to the object
|
||||
variable given by the label.
|
||||
|
||||
See also %load/obj.
|
||||
|
||||
* %store/real <var-label>
|
||||
* %store/reala <var-label> <index>
|
||||
|
||||
|
|
|
|||
|
|
@ -3382,6 +3382,21 @@ bool of_LOAD_AVX_P(vthread_t thr, vvp_code_t cp)
|
|||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* %load/obj <var-label>
|
||||
*/
|
||||
bool of_LOAD_OBJ(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
vvp_net_t*net = cp->net;
|
||||
vvp_fun_signal_object*fun = dynamic_cast<vvp_fun_signal_object*> (net->fun);
|
||||
assert(fun);
|
||||
|
||||
vvp_object_t val = fun->get_object();
|
||||
thr->push_object(val);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* %load/real <var-label>
|
||||
*/
|
||||
|
|
|
|||
Loading…
Reference in New Issue