Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Add support for passing variable indexed part select type information

This patch modifies the compiler and the ivl interface to pass the
type of indexed part select that is being represented (up/down) in
a procedural L-value or R-value. This is needed by any back end that
wants to correctly denormalize the (zero based) base expression.
  • Loading branch information...
commit a6220fe562555ccedd519e2a8611d7515379bfb6 1 parent 026fe92
@caryr caryr authored steveicarus committed
View
4 dup_expr.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999-2010 Stephen Williams (steve@icarus.com)
+ * Copyright (c) 1999-2011 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
@@ -95,7 +95,7 @@ NetESelect* NetESelect::dup_expr() const
{
NetESelect*tmp = new NetESelect(expr_->dup_expr(),
base_? base_->dup_expr() : 0,
- expr_width());
+ expr_width(), sel_type_);
assert(tmp);
tmp->set_line(*this);
return tmp;
View
10 elab_expr.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999-2010 Stephen Williams (steve@icarus.com)
+ * Copyright (c) 1999-2011 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
@@ -2587,7 +2587,7 @@ NetExpr* PEIdent::elaborate_expr_param_idx_up_(Design*des, NetScope*scope,
base = normalize_variable_base(base, par_msv, par_lsv, wid, true);
NetExpr*tmp = par->dup_expr();
- tmp = new NetESelect(tmp, base, wid);
+ tmp = new NetESelect(tmp, base, wid, IVL_SEL_IDX_UP);
tmp->set_line(*this);
return tmp;
}
@@ -2667,7 +2667,7 @@ NetExpr* PEIdent::elaborate_expr_param_idx_do_(Design*des, NetScope*scope,
base = normalize_variable_base(base, par_msv, par_lsv, wid, false);
NetExpr*tmp = par->dup_expr();
- tmp = new NetESelect(tmp, base, wid);
+ tmp = new NetESelect(tmp, base, wid, IVL_SEL_IDX_DOWN);
tmp->set_line(*this);
return tmp;
}
@@ -3176,7 +3176,7 @@ NetExpr* PEIdent::elaborate_expr_net_idx_up_(Design*des, NetScope*scope,
base = normalize_variable_base(base, net->msi(), net->lsi(), wid, true);
- NetESelect*ss = new NetESelect(net, base, wid);
+ NetESelect*ss = new NetESelect(net, base, wid, IVL_SEL_IDX_UP);
ss->set_line(*this);
if (debug_elaborate) {
@@ -3263,7 +3263,7 @@ NetExpr* PEIdent::elaborate_expr_net_idx_do_(Design*des, NetScope*scope,
base = normalize_variable_base(base, net->msi(), net->lsi(), wid, false);
- NetESelect*ss = new NetESelect(net, base, wid);
+ NetESelect*ss = new NetESelect(net, base, wid, IVL_SEL_IDX_DOWN);
ss->set_line(*this);
if (debug_elaborate) {
View
5 elab_lval.cc
@@ -470,6 +470,7 @@ bool PEIdent::elaborate_lval_net_idx_(Design*des,
expr_type_tmp, unsized_flag_tmp);
NetExpr*base = elab_and_eval(des, scope, index_tail.msb, -1);
+ ivl_select_type_t sel_type = IVL_SEL_OTHER;
// Handle the special case that the base is constant. For this
// case we can reduce the expression.
@@ -532,10 +533,12 @@ bool PEIdent::elaborate_lval_net_idx_(Design*des,
if (use_sel == index_component_t::SEL_IDX_UP) {
base = normalize_variable_base(base, reg->msb(), reg->lsb(),
wid, true);
+ sel_type = IVL_SEL_IDX_UP;
} else {
// This is assumed to be a SEL_IDX_DO.
base = normalize_variable_base(base, reg->msb(), reg->lsb(),
wid, false);
+ sel_type = IVL_SEL_IDX_DOWN;
}
}
@@ -543,7 +546,7 @@ bool PEIdent::elaborate_lval_net_idx_(Design*des,
cerr << get_fileline() << ": debug: Set part select width="
<< wid << ", base=" << *base << endl;
- lv->set_part(base, wid);
+ lv->set_part(base, wid, sel_type);
return true;
}
View
2  ivl.def
@@ -68,6 +68,7 @@ ivl_expr_parm
ivl_expr_parms
ivl_expr_repeat
ivl_expr_scope
+ivl_expr_sel_type
ivl_expr_signal
ivl_expr_signed
ivl_expr_sized
@@ -134,6 +135,7 @@ ivl_lpm_width
ivl_lval_idx
ivl_lval_mux
ivl_lval_part_off
+ivl_lval_sel_type
ivl_lval_sig
ivl_lval_width
View
9 ivl_target.h
@@ -229,6 +229,12 @@ typedef enum ivl_expr_type_e {
IVL_EX_UNARY = 14
} ivl_expr_type_t;
+typedef enum ivl_select_type_e {
+ IVL_SEL_OTHER = 0,
+ IVL_SEL_IDX_UP = 1,
+ IVL_SEL_IDX_DOWN = 2
+} ivl_select_type_t;
+
/* This is the type code for an ivl_net_logic_t object. */
typedef enum ivl_logic_e {
IVL_LO_NONE = 0,
@@ -844,6 +850,8 @@ extern ivl_expr_t ivl_expr_parm(ivl_expr_t net, unsigned idx);
extern unsigned ivl_expr_parms(ivl_expr_t net);
/* IVL_EX_CONCAT */
extern unsigned ivl_expr_repeat(ivl_expr_t net);
+ /* IVL_EX_SELECT */
+extern ivl_select_type_t ivl_expr_sel_type(ivl_expr_t net);
/* IVL_EX_EVENT */
extern ivl_event_t ivl_expr_event(ivl_expr_t net);
/* IVL_EX_SCOPE */
@@ -1409,6 +1417,7 @@ extern unsigned ivl_lval_width(ivl_lval_t net);
extern ivl_expr_t ivl_lval_mux(ivl_lval_t net); /* XXXX Obsolete? */
extern ivl_expr_t ivl_lval_idx(ivl_lval_t net);
extern ivl_expr_t ivl_lval_part_off(ivl_lval_t net);
+extern ivl_select_type_t ivl_lval_sel_type(ivl_lval_t net);
extern ivl_signal_t ivl_lval_sig(ivl_lval_t net);
View
9 net_assign.cc
@@ -77,6 +77,11 @@ const NetExpr* NetAssign_::get_base() const
return base_;
}
+ivl_select_type_t NetAssign_::select_type() const
+{
+ return sel_type_;
+}
+
unsigned NetAssign_::lwidth() const
{
return lwid_;
@@ -120,10 +125,12 @@ NetNet* NetAssign_::sig() const
return sig_;
}
-void NetAssign_::set_part(NetExpr*base, unsigned wid)
+void NetAssign_::set_part(NetExpr*base, unsigned wid,
+ ivl_select_type_t sel_type)
{
base_ = base;
lwid_ = wid;
+ sel_type_ = sel_type;
}
/*
View
10 net_expr.cc
@@ -524,8 +524,9 @@ netenum_t* NetENetenum::netenum() const
return netenum_;
}
-NetESelect::NetESelect(NetExpr*exp, NetExpr*base, unsigned wid)
-: expr_(exp), base_(base)
+NetESelect::NetESelect(NetExpr*exp, NetExpr*base, unsigned wid,
+ ivl_select_type_t sel_type)
+: expr_(exp), base_(base), sel_type_(sel_type)
{
expr_width(wid);
}
@@ -546,6 +547,11 @@ const NetExpr*NetESelect::select() const
return base_;
}
+ivl_select_type_t NetESelect::select_type() const
+{
+ return sel_type_;
+}
+
bool NetESelect::has_width() const
{
return true;
View
10 netlist.h
@@ -2301,9 +2301,11 @@ class NetAssign_ {
// Get the base index of the part select, or 0 if there is no
// part select.
const NetExpr* get_base() const;
+ ivl_select_type_t select_type() const;
void set_word(NetExpr*);
- void set_part(NetExpr* loff, unsigned wid);
+ void set_part(NetExpr* loff, unsigned wid,
+ ivl_select_type_t = IVL_SEL_OTHER);
// Get the width of the r-value that this node expects. This
// method accounts for the presence of the mux, so it is not
@@ -2345,6 +2347,7 @@ class NetAssign_ {
// indexed part select base
NetExpr*base_;
unsigned lwid_;
+ ivl_select_type_t sel_type_;
};
class NetAssignBase : public NetProc {
@@ -3644,11 +3647,13 @@ class NetEConcat : public NetExpr {
class NetESelect : public NetExpr {
public:
- NetESelect(NetExpr*exp, NetExpr*base, unsigned wid);
+ NetESelect(NetExpr*exp, NetExpr*base, unsigned wid,
+ ivl_select_type_t sel_type = IVL_SEL_OTHER);
~NetESelect();
const NetExpr*sub_expr() const;
const NetExpr*select() const;
+ ivl_select_type_t select_type() const;
virtual NexusSet* nex_input(bool rem_out = true);
virtual bool set_width(unsigned w, bool last_chance =false);
@@ -3662,6 +3667,7 @@ class NetESelect : public NetExpr {
private:
NetExpr*expr_;
NetExpr*base_;
+ ivl_select_type_t sel_type_;
};
/*
View
21 t-dll-api.cc
@@ -436,9 +436,11 @@ extern "C" ivl_expr_t ivl_expr_oper1(ivl_expr_t net)
assert(net);
switch (net->type_) {
case IVL_EX_BINARY:
- case IVL_EX_SELECT:
return net->u_.binary_.lef_;
+ case IVL_EX_SELECT:
+ return net->u_.select_.expr_;
+
case IVL_EX_UNARY:
return net->u_.unary_.sub_;
@@ -463,9 +465,11 @@ extern "C" ivl_expr_t ivl_expr_oper2(ivl_expr_t net)
assert(net);
switch (net->type_) {
case IVL_EX_BINARY:
- case IVL_EX_SELECT:
return net->u_.binary_.rig_;
+ case IVL_EX_SELECT:
+ return net->u_.select_.base_;
+
case IVL_EX_TERNARY:
return net->u_.ternary_.true_e;
@@ -569,6 +573,13 @@ extern "C" ivl_scope_t ivl_expr_scope(ivl_expr_t net)
return net->u_.scope_.scope;
}
+extern "C" ivl_select_type_t ivl_expr_sel_type(ivl_expr_t net)
+{
+ assert(net);
+ assert(net->type_ == IVL_EX_SELECT);
+ return net->u_.select_.sel_type_;
+}
+
extern "C" ivl_signal_t ivl_expr_signal(ivl_expr_t net)
{
assert(net);
@@ -1467,6 +1478,12 @@ extern "C" ivl_expr_t ivl_lval_part_off(ivl_lval_t net)
return net->loff;
}
+extern "C" ivl_select_type_t ivl_lval_sel_type(ivl_lval_t net)
+{
+ assert(net);
+ return net->sel_type;
+}
+
extern "C" unsigned ivl_lval_width(ivl_lval_t net)
{
assert(net);
View
9 t-dll-expr.cc
@@ -359,13 +359,13 @@ void dll_target::expr_select(const NetESelect*net)
assert(expr_ == 0);
net->sub_expr()->expr_scan(this);
- ivl_expr_t left = expr_;
+ ivl_expr_t expr = expr_;
expr_ = 0;
if (net->select())
net->select()->expr_scan(this);
- ivl_expr_t rght = expr_;
+ ivl_expr_t base = expr_;
expr_ = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s));
@@ -376,8 +376,9 @@ void dll_target::expr_select(const NetESelect*net)
expr_->sized_= 1;
FILE_NAME(expr_, net);
- expr_->u_.binary_.lef_ = left;
- expr_->u_.binary_.rig_ = rght;
+ expr_->u_.select_.sel_type_ = net->select_type();
+ expr_->u_.select_.expr_ = expr;
+ expr_->u_.select_.base_ = base;
}
void dll_target::expr_sfunc(const NetESFunc*net)
View
2  t-dll-proc.cc
@@ -153,9 +153,11 @@ void dll_target::make_assign_lvals_(const NetAssignBase*net)
if (loff == 0) {
cur->loff = 0;
+ cur->sel_type = IVL_SEL_OTHER;
} else {
loff->expr_scan(this);
cur->loff = expr_;
+ cur->sel_type = asn->select_type();
expr_ = 0;
}
View
7 t-dll.h
@@ -232,6 +232,12 @@ struct ivl_expr_s {
} binary_;
struct {
+ ivl_select_type_t sel_type_;
+ ivl_expr_t expr_;
+ ivl_expr_t base_;
+ } select_;
+
+ struct {
ivl_branch_t branch;
ivl_nature_t nature;
} branch_;
@@ -427,6 +433,7 @@ enum ivl_lval_type_t {
struct ivl_lval_s {
ivl_expr_t loff;
+ ivl_select_type_t sel_type;
ivl_expr_t idx;
unsigned width_;
unsigned type_ : 8;
Please sign in to comment.
Something went wrong with that request. Please try again.