Parse/elaborate some array-patterns down to the ivl_target API.

This commit is contained in:
Stephen Williams 2013-10-09 20:15:10 -07:00
parent cd85a42acc
commit 2030e06988
20 changed files with 206 additions and 31 deletions

View File

@ -436,12 +436,12 @@ bool PEIdent::has_aa_term(Design*des, NetScope*scope) const
return false;
}
PENew::PENew(PExpr*size_expr)
: size_(size_expr)
PENewArray::PENewArray(PExpr*size_expr, PExpr*init_expr)
: size_(size_expr), init_(init_expr)
{
}
PENew::~PENew()
PENewArray::~PENewArray()
{
delete size_;
}

10
PExpr.h
View File

@ -209,6 +209,9 @@ class PEAssignPattern : public PExpr {
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
unsigned expr_wid,
unsigned flags) const;
private:
NetExpr* elaborate_expr_darray_(Design*des, NetScope*scope,
ivl_type_t type, unsigned flags) const;
private:
std::vector<PExpr*>parms_;
@ -499,11 +502,11 @@ class PEIdent : public PExpr {
long&midx, long&lidx) const;
};
class PENew : public PExpr {
class PENewArray : public PExpr {
public:
explicit PENew (PExpr*s);
~PENew();
explicit PENewArray (PExpr*s, PExpr*i);
~PENewArray();
virtual void dump(ostream&) const;
virtual unsigned test_width(Design*des, NetScope*scope,
@ -516,6 +519,7 @@ class PENew : public PExpr {
private:
PExpr*size_;
PExpr*init_;
};
class PENewClass : public PExpr {

View File

@ -105,8 +105,9 @@ class PAssign_ : public Statement {
protected:
NetAssign_* elaborate_lval(Design*, NetScope*scope) const;
NetExpr* elaborate_rval_(Design*, NetScope*, unsigned lv_width,
ivl_variable_type_t type) const;
NetExpr* elaborate_rval_(Design*, NetScope*, ivl_type_t lv_net_type,
ivl_variable_type_t lv_type,
unsigned lv_width) const;
NetExpr* elaborate_rval_(Design*, NetScope*, ivl_type_t ntype) const;
NetExpr* elaborate_rval_obj_(Design*, NetScope*,

View File

@ -1410,6 +1410,19 @@ void NetEAccess::dump(ostream&o) const
o << ")";
}
void NetEArrayPattern::dump(ostream&fd) const
{
fd << "'{";
if (items_.size() >= 1) {
if (items_[0]) fd << *items_[0];
}
for (size_t idx = 1 ; idx < items_.size() ; idx += 1) {
fd << ", ";
if (items_[idx]) fd << *items_[idx];
}
fd << "}";
}
void NetEBinary::dump(ostream&o) const
{
if (op_ == 'm' || op_ == 'M') {

View File

@ -32,6 +32,17 @@ NetEAccess* NetEAccess::dup_expr() const
return tmp;
}
NetEArrayPattern*NetEArrayPattern::dup_expr() const
{
vector<NetExpr*>tmp (items_.size());
for (size_t idx = 0 ; idx < tmp.size() ; idx += 1)
tmp[idx] = items_[idx]->dup_expr();
NetEArrayPattern*res = new NetEArrayPattern(net_type(), tmp);
res->set_line(*this);
return res;
}
NetEBinary* NetEBinary::dup_expr() const
{
ivl_assert(*this, 0);

View File

@ -210,6 +210,9 @@ NetExpr*PEAssignPattern::elaborate_expr(Design*des, NetScope*scope,
return tmp;
}
if (ntype->base_type()==IVL_VT_DARRAY)
return elaborate_expr_darray_(des, scope, ntype, flags);
cerr << get_fileline() << ": sorry: I don't know how to elaborate "
<< "assignment_pattern expressions yet." << endl;
cerr << get_fileline() << ": : Expression is: " << *this
@ -218,6 +221,27 @@ NetExpr*PEAssignPattern::elaborate_expr(Design*des, NetScope*scope,
return 0;
}
NetExpr*PEAssignPattern::elaborate_expr_darray_(Design*des, NetScope*scope,
ivl_type_t ntype, unsigned flags) const
{
const netdarray_t*array_type = dynamic_cast<const netdarray_t*> (ntype);
ivl_assert(*this, array_type);
// This is an array pattern, so run through the elements of
// the expression and elaborate each as if they are
// element_type expressions.
ivl_type_t elem_type = array_type->element_type();
vector<NetExpr*> elem_exprs (parms_.size());
for (size_t idx = 0 ; idx < parms_.size() ; idx += 1) {
NetExpr*tmp = parms_[idx]->elaborate_expr(des, scope, elem_type, flags);
elem_exprs[idx] = tmp;
}
NetEArrayPattern*res = new NetEArrayPattern(array_type, elem_exprs);
res->set_line(*this);
return res;
}
NetExpr* PEAssignPattern::elaborate_expr(Design*des, NetScope*, unsigned, unsigned) const
{
cerr << get_fileline() << ": sorry: I do not know how to"
@ -4578,7 +4602,7 @@ NetExpr* PEIdent::elaborate_expr_net(Design*des, NetScope*scope,
return node;
}
unsigned PENew::test_width(Design*, NetScope*, width_mode_t&)
unsigned PENewArray::test_width(Design*, NetScope*, width_mode_t&)
{
expr_type_ = IVL_VT_DARRAY;
expr_width_ = 1;
@ -4587,8 +4611,8 @@ unsigned PENew::test_width(Design*, NetScope*, width_mode_t&)
return 1;
}
NetExpr* PENew::elaborate_expr(Design*des, NetScope*scope,
ivl_type_t ntype, unsigned flags) const
NetExpr* PENewArray::elaborate_expr(Design*des, NetScope*scope,
ivl_type_t ntype, unsigned flags) const
{
// Elaborate the size expression.
width_mode_t mode = LOSSLESS;
@ -4597,13 +4621,20 @@ NetExpr* PENew::elaborate_expr(Design*des, NetScope*scope,
NetENew*tmp = new NetENew(ntype, size);
tmp->set_line(*this);
if (init_) {
cerr << get_fileline() << ": sorry: Dynamic array initialization expressions "
<< "not supported yet." << endl;
des->errors += 1;
}
return tmp;
}
/*
* This method should never actually be called.
*/
NetExpr* PENew::elaborate_expr(Design*, NetScope*, unsigned, unsigned) const
NetExpr* PENewArray::elaborate_expr(Design*, NetScope*, unsigned, unsigned) const
{
ivl_assert(*this, 0);
return 0;

View File

@ -2245,8 +2245,9 @@ NetExpr* PAssign_::elaborate_rval_(Design*des, NetScope*scope,
}
NetExpr* PAssign_::elaborate_rval_(Design*des, NetScope*scope,
unsigned lv_width,
ivl_variable_type_t lv_type) const
ivl_type_t lv_net_type,
ivl_variable_type_t lv_type,
unsigned lv_width) const
{
ivl_assert(*this, rval_);
@ -2254,8 +2255,8 @@ NetExpr* PAssign_::elaborate_rval_(Design*des, NetScope*scope,
// 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_);
NetExpr*rv = elaborate_rval_expr(des, scope, lv_net_type, lv_type, lv_width,
rval(), is_constant_);
if (!is_constant_ || !rv) return rv;
@ -2373,7 +2374,7 @@ NetProc* PAssign::elaborate_compressed_(Design*des, NetScope*scope) const
NetAssign_*lv = elaborate_lval(des, scope);
if (lv == 0) return 0;
NetExpr*rv = elaborate_rval_(des, scope, count_lval_width(lv), lv->expr_type());
NetExpr*rv = elaborate_rval_(des, scope, 0, lv->expr_type(), count_lval_width(lv));
if (rv == 0) return 0;
NetAssign*cur = new NetAssign(lv, op_, rv);
@ -2461,7 +2462,7 @@ NetProc* PAssign::elaborate(Design*des, NetScope*scope) const
} else {
/* Elaborate the r-value expression, then try to evaluate it. */
rv = elaborate_rval_(des, scope, count_lval_width(lv), lv->expr_type());
rv = elaborate_rval_(des, scope, lv_net_type, lv->expr_type(), count_lval_width(lv));
}
if (rv == 0) return 0;
@ -2653,7 +2654,7 @@ NetProc* PAssignNB::elaborate(Design*des, NetScope*scope) const
// because it would necessarily trigger other errors.
}
NetExpr*rv = elaborate_rval_(des, scope, count_lval_width(lv), lv->expr_type());
NetExpr*rv = elaborate_rval_(des, scope, 0, lv->expr_type(), count_lval_width(lv));
if (rv == 0) return 0;
NetExpr*delay = 0;

View File

@ -546,6 +546,11 @@ void NetEAccess::expr_scan(struct expr_scan_t*tgt) const
tgt->expr_access_func(this);
}
void NetEArrayPattern::expr_scan(struct expr_scan_t*tgt) const
{
tgt->expr_array_pattern(this);
}
void NetEBinary::expr_scan(struct expr_scan_t*tgt) const
{
tgt->expr_binary(this);

View File

@ -228,6 +228,7 @@ typedef enum ivl_expr_type_e {
IVL_EX_NEW = 23,
IVL_EX_NULL = 22,
IVL_EX_NUMBER = 5,
IVL_EX_ARRAY_PATTERN = 26,
IVL_EX_PROPERTY = 24,
IVL_EX_REALNUM = 16,
IVL_EX_SCOPE = 6,
@ -903,9 +904,9 @@ extern ivl_expr_t ivl_expr_oper2(ivl_expr_t net);
extern ivl_expr_t ivl_expr_oper3(ivl_expr_t net);
/* and expression */
extern ivl_parameter_t ivl_expr_parameter(ivl_expr_t net);
/* IVL_EX_CONCAT IVL_EX_UFUNC */
/* IVL_EX_ARRAY_PATTERN IVL_EX_CONCAT IVL_EX_UFUNC */
extern ivl_expr_t ivl_expr_parm(ivl_expr_t net, unsigned idx);
/* IVL_EX_CONCAT IVL_EX_SFUNC IVL_EX_UFUNC */
/* IVL_EX_ARRAY_PATTERN IVL_EX_CONCAT IVL_EX_SFUNC IVL_EX_UFUNC */
extern unsigned ivl_expr_parms(ivl_expr_t net);
/* IVL_EX_CONCAT */
extern unsigned ivl_expr_repeat(ivl_expr_t net);

View File

@ -61,7 +61,10 @@ bool NetExpr::has_width() const
*/
ivl_variable_type_t NetExpr::expr_type() const
{
return IVL_VT_LOGIC;
if (net_type_)
return net_type_->base_type();
else
return IVL_VT_LOGIC;
}
const netenum_t*NetExpr::enumeration() const
@ -69,6 +72,17 @@ const netenum_t*NetExpr::enumeration() const
return 0;
}
NetEArrayPattern::NetEArrayPattern(ivl_type_t lv_type, vector<NetExpr*>&items)
: NetExpr(lv_type), items_(items)
{
}
NetEArrayPattern::~NetEArrayPattern()
{
for (size_t idx = 0 ; idx < items_.size() ; idx += 1)
delete items_[idx];
}
/*
* Create an add/sub node from the two operands.
*/

View File

@ -43,6 +43,21 @@ NexusSet* NetProc::nex_input(bool)
return 0;
}
NexusSet* NetEArrayPattern::nex_input(bool rem_out)
{
NexusSet*result = new NexusSet;
for (size_t idx = 0 ; idx < items_.size() ; idx += 1) {
if (items_[idx]==0) continue;
NexusSet*tmp = items_[idx]->nex_input(rem_out);
if (tmp == 0) continue;
result->add(*tmp);
delete tmp;
}
return result;
}
NexusSet* NetEBinary::nex_input(bool rem_out)
{
NexusSet*result = left_->nex_input(rem_out);

View File

@ -1914,6 +1914,25 @@ class NetExpr : public LineInfo {
NetExpr& operator=(const NetExpr&);
};
class NetEArrayPattern : public NetExpr {
public:
NetEArrayPattern(ivl_type_t lv_type, std::vector<NetExpr*>&items);
~NetEArrayPattern();
inline size_t item_size() const { return items_.size(); }
const NetExpr* item(size_t idx) const { return items_[idx]; }
void expr_scan(struct expr_scan_t*) const;
void dump(ostream&) const;
NetEArrayPattern* dup_expr() const;
NexusSet* nex_input(bool rem_out =true);
private:
std::vector<NetExpr*> items_;
};
/*
* The expression constant is slightly special, and is sometimes
* returned from other classes that can be evaluated at compile

15
parse.y
View File

@ -1069,13 +1069,11 @@ endnew_opt : ':' K_new | ;
dynamic_array_new /* IEEE1800-2005: A.2.4 */
: K_new '[' expression ']'
{ $$ = new PENew($3);
{ $$ = new PENewArray($3, 0);
FILE_NAME($$, @1);
}
| K_new '[' expression ']' '(' expression ')'
{ yyerror(@1, "sorry: Dynamic array new expression with initializer not supported.");
delete $6;
$$ = new PENew($3);
{ $$ = new PENewArray($3, $6);
FILE_NAME($$, @1);
}
;
@ -5075,11 +5073,12 @@ register_variable
pform_set_reg_idx(name, $2);
$$ = $1;
}
| IDENTIFIER '=' expression
{ perm_string ident_name = lex_strings.make($1);
pform_makewire(@1, ident_name, NetNet::REG,
| IDENTIFIER dimensions_opt '=' expression
{ perm_string name = lex_strings.make($1);
pform_makewire(@1, name, NetNet::REG,
NetNet::NOT_A_PORT, IVL_VT_NO_TYPE, 0);
pform_make_reginit(@1, ident_name, $3);
pform_set_reg_idx(name, $2);
pform_make_reginit(@1, name, $4);
$$ = $1;
}
;

View File

@ -312,9 +312,11 @@ void PEFNumber::dump(ostream &out) const
out << value();
}
void PENew::dump(ostream&out) const
void PENewArray::dump(ostream&out) const
{
out << "new [" << *size_ << "]";
if (init_)
out << "(" << *init_ << ")";
}
void PENewClass::dump(ostream&out) const

View File

@ -570,6 +570,10 @@ extern "C" ivl_expr_t ivl_expr_parm(ivl_expr_t net, unsigned idx)
assert(net);
switch (net->type_) {
case IVL_EX_ARRAY_PATTERN:
assert(idx < net->u_.array_pattern_.parms);
return net->u_.array_pattern_.parm[idx];
case IVL_EX_CONCAT:
assert(idx < net->u_.concat_.parms);
return net->u_.concat_.parm[idx];
@ -593,6 +597,9 @@ extern "C" unsigned ivl_expr_parms(ivl_expr_t net)
assert(net);
switch (net->type_) {
case IVL_EX_ARRAY_PATTERN:
return net->u_.array_pattern_.parms;
case IVL_EX_CONCAT:
return net->u_.concat_.parms;

View File

@ -175,6 +175,31 @@ void dll_target::expr_access_func(const NetEAccess*net)
expr_->u_.branch_.nature = net->get_nature();
}
void dll_target::expr_array_pattern(const NetEArrayPattern*net)
{
assert(expr_ == 0);
ivl_expr_t expr_tmp = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s));
expr_tmp->type_ = IVL_EX_ARRAY_PATTERN;
expr_tmp->value_= net->expr_type();
expr_tmp->net_type = net->net_type();
expr_tmp->width_ = 1;
expr_tmp->signed_ = 0;
expr_tmp->sized_ = 0;
FILE_NAME(expr_tmp, net);
expr_tmp->u_.array_pattern_.parms = net->item_size();
expr_tmp->u_.array_pattern_.parm = new ivl_expr_t [net->item_size()];
for (size_t idx = 0 ; idx < net->item_size() ; idx += 1) {
const NetExpr*tmp = net->item(idx);
tmp->expr_scan(this);
expr_tmp->u_.array_pattern_.parm[idx] = expr_;
expr_ = 0;
}
expr_ = expr_tmp;
}
void dll_target::expr_binary(const NetEBinary*net)
{
assert(expr_ == 0);

View File

@ -135,6 +135,7 @@ struct dll_target : public target_t, public expr_scan_t {
struct ivl_expr_s*expr_;
void expr_access_func(const NetEAccess*);
void expr_array_pattern(const NetEArrayPattern*);
void expr_binary(const NetEBinary*);
void expr_concat(const NetEConcat*);
void expr_const(const NetEConst*);
@ -239,6 +240,11 @@ struct ivl_expr_s {
ivl_expr_t rig_;
} binary_;
struct {
size_t parms;
ivl_expr_t*parm;
} array_pattern_;
struct {
ivl_select_type_t sel_type_;
ivl_expr_t expr_;

View File

@ -452,6 +452,12 @@ void expr_scan_t::expr_access_func(const NetEAccess*)
"unhandled expr_access_func." << endl;
}
void expr_scan_t::expr_array_pattern(const NetEArrayPattern*)
{
cerr << "expr_scan_t (" << typeid(*this).name() << "): "
"unhandled expr_array_pattern." << endl;
}
void expr_scan_t::expr_const(const NetEConst*)
{
cerr << "expr_scan_t (" << typeid(*this).name() << "): "

View File

@ -152,6 +152,7 @@ struct target_t {
struct expr_scan_t {
virtual ~expr_scan_t();
virtual void expr_access_func(const NetEAccess*);
virtual void expr_array_pattern(const NetEArrayPattern*);
virtual void expr_const(const NetEConst*);
virtual void expr_new(const NetENew*);
virtual void expr_null(const NetENull*);

View File

@ -40,6 +40,16 @@ static void show_array_expression(ivl_expr_t net, unsigned ind)
ivl_signal_dimensions(sig), width, vt);
}
static void show_array_pattern_expression(ivl_expr_t net, unsigned ind)
{
size_t idx;
fprintf(out, "%*sArrayPattern (%s): %u expressions\n",
ind, "", vt_type_string(net), ivl_expr_parms(net));
for (idx = 0 ; idx < ivl_expr_parms(net) ; idx += 1) {
show_expression(ivl_expr_parm(net,idx), ind+4);
}
}
static void show_branch_access_expression(ivl_expr_t net, unsigned ind)
{
ivl_branch_t bra = ivl_expr_branch(net);
@ -408,6 +418,10 @@ void show_expression(ivl_expr_t net, unsigned ind)
show_array_expression(net, ind);
break;
case IVL_EX_ARRAY_PATTERN:
show_array_pattern_expression(net, ind);
break;
case IVL_EX_BACCESS:
show_branch_access_expression(net, ind);
break;