Handle array assignment patters through pform.
This gets us to elaboration. In the process also fix up ivl_type_t type comparisons to do deep type comparison.
This commit is contained in:
parent
2355e1ed8e
commit
18c338ad09
19
PExpr.cc
19
PExpr.cc
|
|
@ -94,6 +94,25 @@ const char* PExpr::width_mode_name(width_mode_t mode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PEAssignPattern::PEAssignPattern()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
PEAssignPattern::PEAssignPattern(const list<PExpr*>&p)
|
||||||
|
: parms_(p.size())
|
||||||
|
{
|
||||||
|
size_t idx = 0;
|
||||||
|
for (list<PExpr*>::const_iterator cur = p.begin()
|
||||||
|
; cur != p.end() ; ++cur) {
|
||||||
|
parms_[idx] = *cur;
|
||||||
|
idx += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PEAssignPattern::~PEAssignPattern()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
PEBinary::PEBinary(char op, PExpr*l, PExpr*r)
|
PEBinary::PEBinary(char op, PExpr*l, PExpr*r)
|
||||||
: op_(op), left_(l), right_(r)
|
: op_(op), left_(l), right_(r)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
20
PExpr.h
20
PExpr.h
|
|
@ -194,6 +194,26 @@ class PExpr : public LineInfo {
|
||||||
|
|
||||||
ostream& operator << (ostream&, const PExpr&);
|
ostream& operator << (ostream&, const PExpr&);
|
||||||
|
|
||||||
|
class PEAssignPattern : public PExpr {
|
||||||
|
public:
|
||||||
|
explicit PEAssignPattern();
|
||||||
|
explicit PEAssignPattern(const std::list<PExpr*>&p);
|
||||||
|
~PEAssignPattern();
|
||||||
|
|
||||||
|
void dump(std::ostream&) const;
|
||||||
|
|
||||||
|
virtual unsigned test_width(Design*des, NetScope*scope, width_mode_t&mode);
|
||||||
|
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
|
||||||
|
ivl_type_t type, unsigned flags) const;
|
||||||
|
|
||||||
|
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
|
||||||
|
unsigned expr_wid,
|
||||||
|
unsigned flags) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<PExpr*>parms_;
|
||||||
|
};
|
||||||
|
|
||||||
class PEConcat : public PExpr {
|
class PEConcat : public PExpr {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
||||||
80
elab_expr.cc
80
elab_expr.cc
|
|
@ -86,15 +86,34 @@ static NetBranch* find_existing_implicit_branch(NetNet*sig, NetNet*gnd)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
NetExpr* elaborate_rval_expr(Design*des, NetScope*scope,
|
NetExpr* elaborate_rval_expr(Design*des, NetScope*scope, ivl_type_t lv_net_type,
|
||||||
ivl_variable_type_t lv_type, unsigned lv_width,
|
ivl_variable_type_t lv_type, unsigned lv_width,
|
||||||
PExpr*expr, bool need_const)
|
PExpr*expr, bool need_const)
|
||||||
{
|
{
|
||||||
|
if (debug_elaborate) {
|
||||||
|
cerr << expr->get_fileline() << ": elaborate_rval_expr: "
|
||||||
|
<< "expr=" << *expr;
|
||||||
|
if (lv_net_type)
|
||||||
|
cerr << ", lv_net_type=" << *lv_net_type;
|
||||||
|
else
|
||||||
|
cerr << ", lv_net_type=<nil>";
|
||||||
|
|
||||||
|
cerr << ", lv_type=" << lv_type
|
||||||
|
<< ", lv_width=" << lv_width
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
|
||||||
int context_wid = -1;
|
int context_wid = -1;
|
||||||
switch (lv_type) {
|
switch (lv_type) {
|
||||||
|
case IVL_VT_DARRAY:
|
||||||
|
// For these types, use a different elab_and_eval that
|
||||||
|
// uses the lv_net_type. We should eventually transition
|
||||||
|
// all the types to this new form.
|
||||||
|
if (lv_net_type)
|
||||||
|
return elab_and_eval(des, scope, expr, lv_net_type, need_const);
|
||||||
|
break;
|
||||||
case IVL_VT_REAL:
|
case IVL_VT_REAL:
|
||||||
case IVL_VT_STRING:
|
case IVL_VT_STRING:
|
||||||
case IVL_VT_DARRAY:
|
|
||||||
break;
|
break;
|
||||||
case IVL_VT_BOOL:
|
case IVL_VT_BOOL:
|
||||||
case IVL_VT_LOGIC:
|
case IVL_VT_LOGIC:
|
||||||
|
|
@ -163,6 +182,42 @@ NetExpr* PExpr::elaborate_expr(Design*des, NetScope*, unsigned, unsigned) const
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For now, assuse that assignment patterns are for dynamic
|
||||||
|
* objects. This is not really true as this expression type, fully
|
||||||
|
* supported, can assign to packed arrays and structs, unpacked arrays
|
||||||
|
* and dynamic arrays.
|
||||||
|
*/
|
||||||
|
unsigned PEAssignPattern::test_width(Design*des, NetScope*scope, width_mode_t&mode)
|
||||||
|
{
|
||||||
|
expr_type_ = IVL_VT_DARRAY;
|
||||||
|
expr_width_ = 1;
|
||||||
|
min_width_ = 1;
|
||||||
|
signed_flag_= false;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
NetExpr*PEAssignPattern::elaborate_expr(Design*des, NetScope*scope,
|
||||||
|
ivl_type_t ntype, unsigned flags) const
|
||||||
|
{
|
||||||
|
cerr << get_fileline() << ": sorry: I don't know how to elaborate "
|
||||||
|
<< "assignment_pattern expressions yet." << endl;
|
||||||
|
cerr << get_fileline() << ": : Expression is: " << *this
|
||||||
|
<< endl;
|
||||||
|
des->errors += 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
NetExpr* PEAssignPattern::elaborate_expr(Design*des, NetScope*, unsigned, unsigned) const
|
||||||
|
{
|
||||||
|
cerr << get_fileline() << ": sorry: I do not know how to"
|
||||||
|
<< " elaborate assignment patterns using old method." << endl;
|
||||||
|
cerr << get_fileline() << ": : Expression is: " << *this
|
||||||
|
<< endl;
|
||||||
|
des->errors += 1;
|
||||||
|
ivl_assert(*this, 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned PEBinary::test_width(Design*des, NetScope*scope, width_mode_t&mode)
|
unsigned PEBinary::test_width(Design*des, NetScope*scope, width_mode_t&mode)
|
||||||
{
|
{
|
||||||
|
|
@ -1524,7 +1579,8 @@ static NetExpr* check_for_enum_methods(const LineInfo*li,
|
||||||
// Process the method argument if it is available.
|
// Process the method argument if it is available.
|
||||||
NetExpr* count = 0;
|
NetExpr* count = 0;
|
||||||
if (args != 0 && parg) {
|
if (args != 0 && parg) {
|
||||||
count = elaborate_rval_expr(des, scope, IVL_VT_BOOL, 32, parg);
|
count = elaborate_rval_expr(des, scope, &netvector_t::atom2u32,
|
||||||
|
IVL_VT_BOOL, 32, parg);
|
||||||
if (count == 0) {
|
if (count == 0) {
|
||||||
cerr << li->get_fileline() << ": error: unable to elaborate "
|
cerr << li->get_fileline() << ": error: unable to elaborate "
|
||||||
"enumeration method argument " << use_path << "."
|
"enumeration method argument " << use_path << "."
|
||||||
|
|
@ -1978,7 +2034,7 @@ NetExpr* PECallFunction::elaborate_base_(Design*des, NetScope*scope, NetScope*ds
|
||||||
if (debug_elaborate) {
|
if (debug_elaborate) {
|
||||||
cerr << get_fileline() << ": PECallFunction::elaborate_base_: "
|
cerr << get_fileline() << ": PECallFunction::elaborate_base_: "
|
||||||
<< "Expecting " << parms_count
|
<< "Expecting " << parms_count
|
||||||
<< " for function " << scope_path(dscope) << "." << endl;
|
<< " argument for function " << scope_path(dscope) << "." << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Elaborate the input expressions for the function. This is
|
/* Elaborate the input expressions for the function. This is
|
||||||
|
|
@ -2061,6 +2117,7 @@ unsigned PECallFunction::elaborate_arguments_(Design*des, NetScope*scope,
|
||||||
PExpr*tmp = parms_[idx];
|
PExpr*tmp = parms_[idx];
|
||||||
if (tmp) {
|
if (tmp) {
|
||||||
parms[pidx] = elaborate_rval_expr(des, scope,
|
parms[pidx] = elaborate_rval_expr(des, scope,
|
||||||
|
def->port(pidx)->net_type(),
|
||||||
def->port(pidx)->data_type(),
|
def->port(pidx)->data_type(),
|
||||||
(unsigned)def->port(pidx)->vector_width(),
|
(unsigned)def->port(pidx)->vector_width(),
|
||||||
tmp, need_const);
|
tmp, need_const);
|
||||||
|
|
@ -2153,12 +2210,12 @@ NetExpr* PECallFunction::elaborate_expr_method_(Design*des, NetScope*scope,
|
||||||
ivl_assert(*this, parms_.size() == 2);
|
ivl_assert(*this, parms_.size() == 2);
|
||||||
NetExpr*tmp;
|
NetExpr*tmp;
|
||||||
|
|
||||||
tmp = elaborate_rval_expr(des, scope, IVL_VT_BOOL,
|
tmp = elaborate_rval_expr(des, scope, &netvector_t::atom2u32,
|
||||||
32, parms_[0], false);
|
IVL_VT_BOOL, 32, parms_[0], false);
|
||||||
sys_expr->parm(1, tmp);
|
sys_expr->parm(1, tmp);
|
||||||
|
|
||||||
tmp = elaborate_rval_expr(des, scope, IVL_VT_BOOL,
|
tmp = elaborate_rval_expr(des, scope, &netvector_t::atom2u32,
|
||||||
32, parms_[1], false);
|
IVL_VT_BOOL, 32, parms_[1], false);
|
||||||
sys_expr->parm(2, tmp);
|
sys_expr->parm(2, tmp);
|
||||||
|
|
||||||
return sys_expr;
|
return sys_expr;
|
||||||
|
|
@ -2902,7 +2959,7 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (net->net_type() != ntype) {
|
if (! ntype->type_compatible(net->net_type())) {
|
||||||
cerr << get_fileline() << ": internal_error: "
|
cerr << get_fileline() << ": internal_error: "
|
||||||
<< "net type doesn't match context type." << endl;
|
<< "net type doesn't match context type." << endl;
|
||||||
|
|
||||||
|
|
@ -2920,7 +2977,7 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
|
||||||
ntype->debug_dump(cerr);
|
ntype->debug_dump(cerr);
|
||||||
cerr << endl;
|
cerr << endl;
|
||||||
}
|
}
|
||||||
ivl_assert(*this, net->net_type() == ntype);
|
ivl_assert(*this, ntype->type_compatible(net->net_type()));
|
||||||
|
|
||||||
NetESignal*tmp = new NetESignal(net);
|
NetESignal*tmp = new NetESignal(net);
|
||||||
tmp->set_line(*this);
|
tmp->set_line(*this);
|
||||||
|
|
@ -4619,7 +4676,8 @@ NetExpr* PENewClass::elaborate_expr(Design*des, NetScope*scope,
|
||||||
// While there are default arguments, check them.
|
// While there are default arguments, check them.
|
||||||
if (idx <= parms_.size() && parms_[idx-1]) {
|
if (idx <= parms_.size() && parms_[idx-1]) {
|
||||||
PExpr*tmp = parms_[idx-1];
|
PExpr*tmp = parms_[idx-1];
|
||||||
parms[idx] = elaborate_rval_expr(des, scope, def->port(idx)->data_type(),
|
parms[idx] = elaborate_rval_expr(des, scope, def->port(idx)->net_type(),
|
||||||
|
def->port(idx)->data_type(),
|
||||||
def->port(idx)->vector_width(),
|
def->port(idx)->vector_width(),
|
||||||
tmp, false);
|
tmp, false);
|
||||||
if (parms[idx] == 0)
|
if (parms[idx] == 0)
|
||||||
|
|
|
||||||
30
elaborate.cc
30
elaborate.cc
|
|
@ -84,7 +84,8 @@ void PGAssign::elaborate(Design*des, NetScope*scope) const
|
||||||
<< " width=" << lval->vector_width() << endl;
|
<< " width=" << lval->vector_width() << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
NetExpr*rval_expr = elaborate_rval_expr(des, scope, lval->data_type(),
|
NetExpr*rval_expr = elaborate_rval_expr(des, scope, lval->net_type(),
|
||||||
|
lval->data_type(),
|
||||||
lval->vector_width(), pin(1));
|
lval->vector_width(), pin(1));
|
||||||
|
|
||||||
if (rval_expr == 0) {
|
if (rval_expr == 0) {
|
||||||
|
|
@ -2249,7 +2250,11 @@ NetExpr* PAssign_::elaborate_rval_(Design*des, NetScope*scope,
|
||||||
{
|
{
|
||||||
ivl_assert(*this, rval_);
|
ivl_assert(*this, rval_);
|
||||||
|
|
||||||
NetExpr*rv = elaborate_rval_expr(des, scope, lv_type, lv_width, rval(),
|
// Don't have a good value for the lv_net_type argument to
|
||||||
|
// elaborate_rval_expr, so punt and pass nil. In the future we
|
||||||
|
// should look into fixing calls to this method to pass a
|
||||||
|
// net_type instead of the separate lv_width/lv_type values.
|
||||||
|
NetExpr*rv = elaborate_rval_expr(des, scope, 0, lv_type, lv_width, rval(),
|
||||||
is_constant_);
|
is_constant_);
|
||||||
|
|
||||||
if (!is_constant_ || !rv) return rv;
|
if (!is_constant_ || !rv) return rv;
|
||||||
|
|
@ -3463,7 +3468,8 @@ NetProc* PCallTask::elaborate_build_call_(Design*des, NetScope*scope,
|
||||||
NetExpr*rv = 0;
|
NetExpr*rv = 0;
|
||||||
|
|
||||||
if (parms_idx<parms_.size() && parms_[parms_idx]) {
|
if (parms_idx<parms_.size() && parms_[parms_idx]) {
|
||||||
rv = elaborate_rval_expr(des, scope, lv_type, wid, parms_ [parms_idx]);
|
rv = elaborate_rval_expr(des, scope, port->net_type(),
|
||||||
|
lv_type, wid, parms_ [parms_idx]);
|
||||||
if (NetEEvent*evt = dynamic_cast<NetEEvent*> (rv)) {
|
if (NetEEvent*evt = dynamic_cast<NetEEvent*> (rv)) {
|
||||||
cerr << evt->get_fileline() << ": error: An event '"
|
cerr << evt->get_fileline() << ": error: An event '"
|
||||||
<< evt->event()->name() << "' can not be a user "
|
<< evt->event()->name() << "' can not be a user "
|
||||||
|
|
@ -3617,7 +3623,11 @@ NetCAssign* PCAssign::elaborate(Design*des, NetScope*scope) const
|
||||||
unsigned lwid = count_lval_width(lval);
|
unsigned lwid = count_lval_width(lval);
|
||||||
ivl_variable_type_t ltype = lval->expr_type();
|
ivl_variable_type_t ltype = lval->expr_type();
|
||||||
|
|
||||||
NetExpr*rexp = elaborate_rval_expr(des, scope, ltype, lwid, expr_);
|
// Need to figure out a better thing to do about the
|
||||||
|
// lv_net_type argument to elaborate_rval_expr here. This
|
||||||
|
// would entail getting the NetAssign_ to give us an
|
||||||
|
// ivl_type_t as needed.
|
||||||
|
NetExpr*rexp = elaborate_rval_expr(des, scope, 0, ltype, lwid, expr_);
|
||||||
if (rexp == 0)
|
if (rexp == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
@ -4295,7 +4305,11 @@ NetForce* PForce::elaborate(Design*des, NetScope*scope) const
|
||||||
unsigned lwid = count_lval_width(lval);
|
unsigned lwid = count_lval_width(lval);
|
||||||
ivl_variable_type_t ltype = lval->expr_type();
|
ivl_variable_type_t ltype = lval->expr_type();
|
||||||
|
|
||||||
NetExpr*rexp = elaborate_rval_expr(des, scope, ltype, lwid, expr_);
|
// Like a variety of other assigns, we need to figure out a
|
||||||
|
// better way to get a reasonable lv_net_type value, and that
|
||||||
|
// probably will involve NetAssign_ having a method for
|
||||||
|
// synthesizing one as needed.
|
||||||
|
NetExpr*rexp = elaborate_rval_expr(des, scope, 0, ltype, lwid, expr_);
|
||||||
if (rexp == 0)
|
if (rexp == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
@ -4351,7 +4365,8 @@ NetProc* PForStatement::elaborate(Design*des, NetScope*scope) const
|
||||||
|
|
||||||
/* Make the r-value of the initial assignment, and size it
|
/* Make the r-value of the initial assignment, and size it
|
||||||
properly. Then use it to build the assignment statement. */
|
properly. Then use it to build the assignment statement. */
|
||||||
etmp = elaborate_rval_expr(des, scope, lv->expr_type(), lv->lwidth(),
|
etmp = elaborate_rval_expr(des, scope, sig->net_type(),
|
||||||
|
lv->expr_type(), lv->lwidth(),
|
||||||
expr1_);
|
expr1_);
|
||||||
|
|
||||||
if (debug_elaborate) {
|
if (debug_elaborate) {
|
||||||
|
|
@ -4566,7 +4581,8 @@ NetProc* PReturn::elaborate(Design*des, NetScope*scope) const
|
||||||
unsigned long wid = res->vector_width();
|
unsigned long wid = res->vector_width();
|
||||||
NetAssign_*lv = new NetAssign_(res);
|
NetAssign_*lv = new NetAssign_(res);
|
||||||
|
|
||||||
NetExpr*val = elaborate_rval_expr(des, scope, lv_type, wid, expr_);
|
NetExpr*val = elaborate_rval_expr(des, scope, res->net_type(),
|
||||||
|
lv_type, wid, expr_);
|
||||||
|
|
||||||
NetBlock*proc = new NetBlock(NetBlock::SEQU, 0);
|
NetBlock*proc = new NetBlock(NetBlock::SEQU, 0);
|
||||||
proc->set_line( *this );
|
proc->set_line( *this );
|
||||||
|
|
|
||||||
10
netdarray.cc
10
netdarray.cc
|
|
@ -18,6 +18,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
# include "netdarray.h"
|
# include "netdarray.h"
|
||||||
|
# include <iostream>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
|
@ -34,3 +35,12 @@ ivl_variable_type_t netdarray_t::base_type(void) const
|
||||||
{
|
{
|
||||||
return IVL_VT_DARRAY;
|
return IVL_VT_DARRAY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool netdarray_t::test_compatibility(ivl_type_t that) const
|
||||||
|
{
|
||||||
|
const netdarray_t*that_da = dynamic_cast<const netdarray_t*>(that);
|
||||||
|
if (that_da == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return element_type()->type_compatible(that_da->element_type());
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,7 @@ class netdarray_t : public netarray_t {
|
||||||
std::ostream& debug_dump(std::ostream&) const;
|
std::ostream& debug_dump(std::ostream&) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool test_compatibility(ivl_type_t that) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
20
netmisc.cc
20
netmisc.cc
|
|
@ -809,6 +809,26 @@ NetExpr* elab_and_eval(Design*des, NetScope*scope, PExpr*pe,
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NetExpr* elab_and_eval(Design*des, NetScope*scope, PExpr*pe,
|
||||||
|
ivl_type_t lv_net_type, bool need_const)
|
||||||
|
{
|
||||||
|
if (debug_elaborate) {
|
||||||
|
cerr << pe->get_fileline() << ": elab_and_eval: "
|
||||||
|
<< "pe=" << *pe
|
||||||
|
<< ", lv_net_type=" << *lv_net_type << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Elaborate the expression using the more general
|
||||||
|
// elaborate_expr method.
|
||||||
|
unsigned flags = PExpr::NO_FLAGS;
|
||||||
|
if (need_const)
|
||||||
|
flags |= PExpr::NEED_CONST;
|
||||||
|
|
||||||
|
NetExpr*tmp = pe->elaborate_expr(des, scope, lv_net_type, flags);
|
||||||
|
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
NetExpr* elab_sys_task_arg(Design*des, NetScope*scope, perm_string name,
|
NetExpr* elab_sys_task_arg(Design*des, NetScope*scope, perm_string name,
|
||||||
unsigned arg_idx, PExpr*pe, bool need_const)
|
unsigned arg_idx, PExpr*pe, bool need_const)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
15
netmisc.h
15
netmisc.h
|
|
@ -244,6 +244,15 @@ extern NetExpr* elab_and_eval(Design*des, NetScope*scope,
|
||||||
bool annotatable =false,
|
bool annotatable =false,
|
||||||
ivl_variable_type_t cast_type =IVL_VT_NO_TYPE);
|
ivl_variable_type_t cast_type =IVL_VT_NO_TYPE);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This form of elab_and_eval uses the ivl_type_t to carry type
|
||||||
|
* information instead of the piecemeal form. We should transition to
|
||||||
|
* this form as we reasonably can.
|
||||||
|
*/
|
||||||
|
extern NetExpr* elab_and_eval(Design*des, NetScope*scope,
|
||||||
|
PExpr*expr, ivl_type_t lv_net_type,
|
||||||
|
bool need_const);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function is a variant of elab_and_eval that elaborates and
|
* This function is a variant of elab_and_eval that elaborates and
|
||||||
* evaluates the arguments of a system task.
|
* evaluates the arguments of a system task.
|
||||||
|
|
@ -256,8 +265,14 @@ extern NetExpr* elab_sys_task_arg(Design*des, NetScope*scope,
|
||||||
* of an assignment, The lv_type and lv_width are the type and width
|
* of an assignment, The lv_type and lv_width are the type and width
|
||||||
* of the l-value, and the expr is the expression to elaborate. The
|
* of the l-value, and the expr is the expression to elaborate. The
|
||||||
* result is the NetExpr elaborated and evaluated. (See elab_expr.cc)
|
* result is the NetExpr elaborated and evaluated. (See elab_expr.cc)
|
||||||
|
*
|
||||||
|
* I would rather that all calls to elaborate_rval_expr use the
|
||||||
|
* lv_net_type argument to express the l-value type, but, for now,
|
||||||
|
* that it not possible. Those cases will be indicated by the
|
||||||
|
* lv_net_type being set to nil.
|
||||||
*/
|
*/
|
||||||
extern NetExpr* elaborate_rval_expr(Design*des, NetScope*scope,
|
extern NetExpr* elaborate_rval_expr(Design*des, NetScope*scope,
|
||||||
|
ivl_type_t lv_net_type,
|
||||||
ivl_variable_type_t lv_type,
|
ivl_variable_type_t lv_type,
|
||||||
unsigned lv_width, PExpr*expr,
|
unsigned lv_width, PExpr*expr,
|
||||||
bool need_const =false);
|
bool need_const =false);
|
||||||
|
|
|
||||||
13
nettypes.cc
13
nettypes.cc
|
|
@ -46,6 +46,19 @@ bool ivl_type_s::get_signed() const
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ivl_type_s::type_compatible(ivl_type_t that) const
|
||||||
|
{
|
||||||
|
if (this == that)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return test_compatibility(that);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ivl_type_s::test_compatibility(const ivl_type_s*that) const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
netarray_t::~netarray_t()
|
netarray_t::~netarray_t()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
||||||
22
nettypes.h
22
nettypes.h
|
|
@ -44,7 +44,17 @@ class ivl_type_s {
|
||||||
virtual ivl_variable_type_t base_type() const;
|
virtual ivl_variable_type_t base_type() const;
|
||||||
virtual bool get_signed() const;
|
virtual bool get_signed() const;
|
||||||
|
|
||||||
|
// Return true if "that" type is compatible with this
|
||||||
|
// type. Compatibile means the types are essentially the same.
|
||||||
|
bool type_compatible(ivl_type_t that) const;
|
||||||
|
|
||||||
virtual std::ostream& debug_dump(std::ostream&) const;
|
virtual std::ostream& debug_dump(std::ostream&) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// The "type_compatibile" method uses this virtual method to
|
||||||
|
// invoke type-specific tests of compatibility. This should
|
||||||
|
// only be called by the type_compatible method above.
|
||||||
|
virtual bool test_compatibility(ivl_type_t that) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -100,6 +110,18 @@ class netrange_t {
|
||||||
inline long get_msb() const { assert(defined()); return msb_; }
|
inline long get_msb() const { assert(defined()); return msb_; }
|
||||||
inline long get_lsb() const { assert(defined()); return lsb_; }
|
inline long get_lsb() const { assert(defined()); return lsb_; }
|
||||||
|
|
||||||
|
inline bool operator == (const netrange_t&that) const
|
||||||
|
{ if (msb_ != that.msb_) return false;
|
||||||
|
if (lsb_ != that.lsb_) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator != (const netrange_t&that) const
|
||||||
|
{ if (msb_ != that.msb_) return true;
|
||||||
|
if (lsb_ != that.lsb_) return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
long msb_;
|
long msb_;
|
||||||
long lsb_;
|
long lsb_;
|
||||||
|
|
|
||||||
20
netvector.cc
20
netvector.cc
|
|
@ -18,6 +18,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
# include "netvector.h"
|
# include "netvector.h"
|
||||||
|
# include <iostream>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
|
@ -62,3 +63,22 @@ vector<netrange_t> netvector_t::slice_dimensions() const
|
||||||
{
|
{
|
||||||
return packed_dims_;
|
return packed_dims_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool netvector_t::test_compatibility(ivl_type_t that) const
|
||||||
|
{
|
||||||
|
const netvector_t*that_st = dynamic_cast<const netvector_t*>(that);
|
||||||
|
if (that_st == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (type_ != that_st->type_)
|
||||||
|
return false;
|
||||||
|
if (packed_dims_.size() != that_st->packed_dims_.size())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (size_t idx = 0 ; idx < packed_dims_.size() ; idx += 1) {
|
||||||
|
if (packed_dims_[idx] != that_st->packed_dims_[idx])
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,9 @@ class netvector_t : public ivl_type_s {
|
||||||
static netvector_t scalar_bool;
|
static netvector_t scalar_bool;
|
||||||
static netvector_t scalar_logic;
|
static netvector_t scalar_logic;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool test_compatibility(ivl_type_t that) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<netrange_t> packed_dims_;
|
std::vector<netrange_t> packed_dims_;
|
||||||
ivl_variable_type_t type_;
|
ivl_variable_type_t type_;
|
||||||
|
|
|
||||||
7
parse.y
7
parse.y
|
|
@ -669,15 +669,14 @@ source_text : description_list | ;
|
||||||
|
|
||||||
assignment_pattern /* IEEE1800-2005: A.6.7.1 */
|
assignment_pattern /* IEEE1800-2005: A.6.7.1 */
|
||||||
: K_LP expression_list_proper '}'
|
: K_LP expression_list_proper '}'
|
||||||
{ PEVoid*tmp = new PEVoid;
|
{ PEAssignPattern*tmp = new PEAssignPattern(*$2);
|
||||||
FILE_NAME(tmp, @1);
|
FILE_NAME(tmp, @1);
|
||||||
yyerror(@1, "sorry: Assignment patterns (array literals) not supported.");
|
delete $2;
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
| K_LP '}'
|
| K_LP '}'
|
||||||
{ PEVoid*tmp = new PEVoid;
|
{ PEAssignPattern*tmp = new PEAssignPattern;
|
||||||
FILE_NAME(tmp, @1);
|
FILE_NAME(tmp, @1);
|
||||||
yyerror(@1, "sorry: Assignment patterns (empty array literals) not supported.");
|
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
|
||||||
|
|
@ -230,6 +230,19 @@ void PExpr::dump(ostream&out) const
|
||||||
out << typeid(*this).name();
|
out << typeid(*this).name();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PEAssignPattern::dump(ostream&out) const
|
||||||
|
{
|
||||||
|
out << "'{";
|
||||||
|
if (parms_.size() > 0) {
|
||||||
|
parms_[0]->dump(out);
|
||||||
|
for (size_t idx = 1 ; idx < parms_.size() ; idx += 1) {
|
||||||
|
out << ", ";
|
||||||
|
parms_[idx]->dump(out);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out << "}";
|
||||||
|
}
|
||||||
|
|
||||||
void PEConcat::dump(ostream&out) const
|
void PEConcat::dump(ostream&out) const
|
||||||
{
|
{
|
||||||
if (repeat_)
|
if (repeat_)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue