Redo handling of assignment internal delays.

Leave it possible for them to be calculated
 at run time.
This commit is contained in:
steve 2002-04-21 22:31:02 +00:00
parent 52ea13819a
commit 5882c6a481
7 changed files with 178 additions and 79 deletions

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: Statement.cc,v 1.26 2002/04/21 04:59:07 steve Exp $"
#ident "$Id: Statement.cc,v 1.27 2002/04/21 22:31:02 steve Exp $"
#endif
# include "config.h"
@ -32,17 +32,19 @@ Statement::~Statement()
PAssign_::PAssign_(PExpr*lval, PExpr*ex)
: event_(0), lval_(lval), rval_(ex)
{
delay_ = 0;
}
PAssign_::PAssign_(PExpr*lval, PExpr*de, PExpr*ex)
: event_(0), lval_(lval), rval_(ex)
{
if (de) delay_.set_delay(de);
delay_ = de;
}
PAssign_::PAssign_(PExpr*lval, PEventStatement*ev, PExpr*ex)
: event_(ev), lval_(lval), rval_(ex)
{
delay_ = 0;
}
PAssign_::~PAssign_()
@ -293,6 +295,11 @@ PWhile::~PWhile()
/*
* $Log: Statement.cc,v $
* Revision 1.27 2002/04/21 22:31:02 steve
* Redo handling of assignment internal delays.
* Leave it possible for them to be calculated
* at run time.
*
* Revision 1.26 2002/04/21 04:59:07 steve
* Add support for conbinational events by finding
* the inputs to expressions and some statements.

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: Statement.h,v 1.32 2002/04/21 04:59:07 steve Exp $"
#ident "$Id: Statement.h,v 1.33 2002/04/21 22:31:02 steve Exp $"
#endif
# include <string>
@ -97,7 +97,7 @@ class PAssign_ : public Statement {
protected:
NetAssign_* elaborate_lval(Design*, NetScope*scope) const;
PDelays delay_;
PExpr* delay_;
PEventStatement*event_;
private:
@ -453,6 +453,11 @@ class PWhile : public Statement {
/*
* $Log: Statement.h,v $
* Revision 1.33 2002/04/21 22:31:02 steve
* Redo handling of assignment internal delays.
* Leave it possible for them to be calculated
* at run time.
*
* Revision 1.32 2002/04/21 04:59:07 steve
* Add support for conbinational events by finding
* the inputs to expressions and some statements.

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: elaborate.cc,v 1.243 2002/04/21 04:59:07 steve Exp $"
#ident "$Id: elaborate.cc,v 1.244 2002/04/21 22:31:02 steve Exp $"
#endif
# include "config.h"
@ -875,6 +875,57 @@ NetAssign_* PAssign_::elaborate_lval(Design*des, NetScope*scope) const
return lval_->elaborate_lval(des, scope);
}
/*
* This function elaborates delay expressions. This is a little
* different from normal elaboration because the result may need to be
* scaled.
*/
static NetExpr*elaborate_delay_expr(PExpr*expr, Design*des, NetScope*scope)
{
if (verireal*dr = expr->eval_rconst(des, scope)) {
int shift = scope->time_unit() - des->get_precision();
long val = dr->as_long(shift);
delete dr;
return new NetEConst(verinum(val));
}
if (verinum*dv = expr->eval_const(des, scope)) {
unsigned long val = dv->as_ulong();
val = des->scale_to_precision(val, scope);
return new NetEConst(verinum(val));
}
NetExpr*delay = expr->elaborate_expr(des, scope);
int shift = scope->time_unit() - des->get_precision();
if (shift > 0) {
unsigned long scale = 1;
while (shift > 0) {
scale *= 10;
shift -= 1;
}
NetExpr*scal_val = new NetEConst(verinum(scale));
delay = new NetEBMult('*', delay, scal_val);
}
if (shift < 0) {
unsigned long scale = 1;
while (shift < 0) {
scale *= 10;
shift += 1;
}
NetExpr*scal_val = new NetEConst(verinum(scale));
delay = new NetEBDiv('/', delay, scal_val);
}
return delay;
}
NetProc* PAssign::elaborate(Design*des, NetScope*scope) const
{
assert(scope);
@ -900,9 +951,10 @@ NetProc* PAssign::elaborate(Design*des, NetScope*scope) const
NetAssign_*lv = elaborate_lval(des, scope);
if (lv == 0) return 0;
/* If there is a delay expression, elaborate it. */
unsigned long rise_time, fall_time, decay_time;
delay_.eval_delays(des, scope, rise_time, fall_time, decay_time);
/* If there is an internal delay expression, elaborate it. */
NetExpr*delay = 0;
if (delay_ != 0)
delay = elaborate_delay_expr(delay_, des, scope);
/* Elaborate the r-value expression. */
@ -947,7 +999,7 @@ NetProc* PAssign::elaborate(Design*des, NetScope*scope) const
actually and literally represent the delayed assign in the
netlist. The compound statement is exactly equivalent. */
if (rise_time || event_) {
if (delay || event_) {
string n = scope->local_hsymbol();
unsigned wid = lv->lwidth();
@ -995,7 +1047,7 @@ NetProc* PAssign::elaborate(Design*des, NetScope*scope) const
assert(st);
} else {
NetPDelay*de = new NetPDelay(rise_time, a2);
NetPDelay*de = new NetPDelay(delay, a2);
st = de;
}
@ -1091,15 +1143,13 @@ NetProc* PAssignNB::elaborate(Design*des, NetScope*scope) const
rv = pad_to_width(rv, wid);
}
unsigned long rise_time, fall_time, decay_time;
delay_.eval_delays(des, scope, rise_time, fall_time, decay_time);
NetExpr*delay = 0;
if (delay_ != 0)
delay = elaborate_delay_expr(delay_, des, scope);
/* All done with this node. mark its line number and check it in. */
NetAssignNB*cur = new NetAssignNB(lv, rv);
cur->rise_time(rise_time);
cur->fall_time(fall_time);
cur->decay_time(decay_time);
cur->set_delay(delay);
cur->set_line(*this);
return cur;
}
@ -2454,6 +2504,11 @@ Design* elaborate(list<const char*>roots)
/*
* $Log: elaborate.cc,v $
* Revision 1.244 2002/04/21 22:31:02 steve
* Redo handling of assignment internal delays.
* Leave it possible for them to be calculated
* at run time.
*
* Revision 1.243 2002/04/21 04:59:07 steve
* Add support for conbinational events by finding
* the inputs to expressions and some statements.

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: net_assign.cc,v 1.8 2001/08/25 23:50:03 steve Exp $"
#ident "$Id: net_assign.cc,v 1.9 2002/04/21 22:31:02 steve Exp $"
#endif
# include "config.h"
@ -99,7 +99,7 @@ unsigned NetAssign_::get_loff() const
}
NetAssignBase::NetAssignBase(NetAssign_*lv, NetExpr*rv)
: lval_(lv), rval_(rv)
: lval_(lv), rval_(rv), delay_(0)
{
}
@ -180,6 +180,15 @@ unsigned NetAssignBase::lwidth() const
return sum;
}
void NetAssignBase::set_delay(NetExpr*expr)
{
delay_ = expr;
}
const NetExpr* NetAssignBase::get_delay() const
{
return delay_;
}
NetAssign::NetAssign(NetAssign_*lv, NetExpr*rv)
: NetAssignBase(lv, rv)
@ -193,47 +202,19 @@ NetAssign::~NetAssign()
NetAssignNB::NetAssignNB(NetAssign_*lv, NetExpr*rv)
: NetAssignBase(lv, rv)
{
rise_time_ = 0;
fall_time_ = 0;
decay_time_ = 0;
}
NetAssignNB::~NetAssignNB()
{
}
void NetAssignNB::rise_time(unsigned t)
{
rise_time_ = t;
}
void NetAssignNB::fall_time(unsigned t)
{
fall_time_ = t;
}
void NetAssignNB::decay_time(unsigned t)
{
decay_time_ = t;
}
unsigned NetAssignNB::rise_time() const
{
return rise_time_;
}
unsigned NetAssignNB::fall_time() const
{
return fall_time_;
}
unsigned NetAssignNB::decay_time() const
{
return decay_time_;
}
/*
* $Log: net_assign.cc,v $
* Revision 1.9 2002/04/21 22:31:02 steve
* Redo handling of assignment internal delays.
* Leave it possible for them to be calculated
* at run time.
*
* Revision 1.8 2001/08/25 23:50:03 steve
* Change the NetAssign_ class to refer to the signal
* instead of link into the netlist. This is faster

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: netlist.h,v 1.234 2002/04/21 17:43:13 steve Exp $"
#ident "$Id: netlist.h,v 1.235 2002/04/21 22:31:02 steve Exp $"
#endif
/*
@ -1281,6 +1281,9 @@ class NetAssignBase : public NetProc {
const NetAssign_* l_val(unsigned) const;
unsigned l_val_count() const;
void set_delay(NetExpr*);
const NetExpr* get_delay() const;
virtual NexusSet* nex_input();
// This returns the total width of the accumulated l-value. It
@ -1293,6 +1296,7 @@ class NetAssignBase : public NetProc {
private:
NetAssign_*lval_;
NetExpr *rval_;
NetExpr *delay_;
};
class NetAssign : public NetAssignBase {
@ -1313,23 +1317,12 @@ class NetAssignNB : public NetAssignBase {
explicit NetAssignNB(NetAssign_*lv, NetExpr*rv);
~NetAssignNB();
void rise_time(unsigned);
void fall_time(unsigned);
void decay_time(unsigned);
unsigned rise_time() const;
unsigned fall_time() const;
unsigned decay_time() const;
virtual bool emit_proc(struct target_t*) const;
virtual int match_proc(struct proc_match_t*);
virtual void dump(ostream&, unsigned ind) const;
private:
unsigned rise_time_;
unsigned fall_time_;
unsigned decay_time_;
};
/*
@ -2984,6 +2977,11 @@ extern ostream& operator << (ostream&, NetNet::Type);
/*
* $Log: netlist.h,v $
* Revision 1.235 2002/04/21 22:31:02 steve
* Redo handling of assignment internal delays.
* Leave it possible for them to be calculated
* at run time.
*
* Revision 1.234 2002/04/21 17:43:13 steve
* implement nex_input for behavioral statements.
*

View File

@ -18,7 +18,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: t-dll-proc.cc,v 1.41 2002/01/19 19:02:08 steve Exp $"
#ident "$Id: t-dll-proc.cc,v 1.42 2002/04/21 22:31:02 steve Exp $"
#endif
# include "config.h"
@ -157,6 +157,13 @@ void dll_target::proc_assign(const NetAssign*net)
net->rval()->expr_scan(this);
stmt_cur_->u_.assign_.rval_ = expr_;
expr_ = 0;
const NetExpr*del = net->get_delay();
if (del) {
del->expr_scan(this);
stmt_cur_->u_.assign_.delay = expr_;
expr_ = 0;
}
}
@ -164,7 +171,7 @@ void dll_target::proc_assign_nb(const NetAssignNB*net)
{
unsigned cnt = net->l_val_count();
unsigned long delay_val = net->rise_time();
const NetExpr* delay_exp = net->get_delay();
assert(stmt_cur_);
assert(stmt_cur_->type_ == IVL_ST_NONE);
@ -198,13 +205,19 @@ void dll_target::proc_assign_nb(const NetAssignNB*net)
stmt_cur_->u_.assign_.rval_ = expr_;
expr_ = 0;
if (delay_val > 0) {
if (const NetEConst*delay_num = dynamic_cast<const NetEConst*>(delay_exp)) {
verinum val = delay_num->value();
ivl_expr_t de = new struct ivl_expr_s;
de->type_ = IVL_EX_ULONG;
de->width_ = 8 * sizeof(unsigned long);
de->signed_ = 0;
de->u_.ulong_.value = delay_val;
de->u_.ulong_.value = val.as_ulong();
stmt_cur_->u_.assign_.delay = de;
} else if (delay_exp != 0) {
delay_exp->expr_scan(this);
stmt_cur_->u_.assign_.delay = expr_;
expr_ = 0;
}
}
@ -793,6 +806,11 @@ void dll_target::proc_while(const NetWhile*net)
/*
* $Log: t-dll-proc.cc,v $
* Revision 1.42 2002/04/21 22:31:02 steve
* Redo handling of assignment internal delays.
* Leave it possible for them to be calculated
* at run time.
*
* Revision 1.41 2002/01/19 19:02:08 steve
* Pass back target errors processing conditionals.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: vvp_process.c,v 1.55 2002/04/14 19:19:21 steve Exp $"
#ident "$Id: vvp_process.c,v 1.56 2002/04/21 22:31:02 steve Exp $"
#endif
# include "vvp_priv.h"
@ -97,16 +97,21 @@ static void set_to_memory(ivl_memory_t mem, unsigned idx, unsigned bit)
* a calculated assign.
*/
static void assign_to_lvariable(ivl_lval_t lval, unsigned idx,
unsigned bit, unsigned delay)
unsigned bit, unsigned delay,
int delay_in_index_flag)
{
ivl_signal_t sig = ivl_lval_sig(lval);
unsigned part_off = ivl_lval_part_off(lval);
char *delay_suffix = delay_in_index_flag? "/d" : "";
if (ivl_lval_mux(lval))
fprintf(vvp_out, " %%assign/x0 V_%s, %u, %u;\n",
fprintf(vvp_out, " %%assign/x0%s V_%s, %u, %u;\n",
delay_suffix,
vvp_mangle_id(ivl_signal_name(sig)), delay, bit);
else
fprintf(vvp_out, " %%assign V_%s[%u], %u, %u;\n",
fprintf(vvp_out, " %%assign%s V_%s[%u], %u, %u;\n",
delay_suffix,
vvp_mangle_id(ivl_signal_name(sig)),
idx+part_off, delay, bit);
}
@ -127,6 +132,13 @@ static void calculate_into_x0(ivl_expr_t expr)
clr_vector(vec);
}
static void calculate_into_x1(ivl_expr_t expr)
{
struct vector_info vec = draw_eval_expr(expr);
fprintf(vvp_out, " %%ix/get 1, %u, %u;\n", vec.base, vec.wid);
clr_vector(vec);
}
static int show_stmt_assign(ivl_statement_t net)
{
ivl_lval_t lval;
@ -239,10 +251,9 @@ static int show_stmt_assign_nb(ivl_statement_t net)
ivl_memory_t mem;
unsigned long delay = 0;
if (del != 0) {
/* XXXX Only support constant values. */
assert(ivl_expr_type(del) == IVL_EX_ULONG);
if (del && (ivl_expr_type(del) == IVL_EX_ULONG)) {
delay = ivl_expr_uvalue(del);
del = 0;
}
/* Handle the special case that the r-value is a constant. We
@ -255,6 +266,9 @@ static int show_stmt_assign_nb(ivl_statement_t net)
unsigned wid = ivl_expr_width(rval);
unsigned cur_rbit = 0;
if (del != 0)
calculate_into_x1(del);
for (lidx = 0 ; lidx < ivl_stmt_lvals(net) ; lidx += 1) {
unsigned idx;
unsigned bit_limit = wid - cur_rbit;
@ -277,19 +291,26 @@ static int show_stmt_assign_nb(ivl_statement_t net)
assign_to_memory(mem, idx,
bitchar_to_idx(bits[cur_rbit]),
delay);
else if (del != 0)
assign_to_lvariable(lval, idx,
bitchar_to_idx(bits[cur_rbit]),
1, 1);
else
assign_to_lvariable(lval, idx,
bitchar_to_idx(bits[cur_rbit]),
delay);
delay, 0);
cur_rbit += 1;
}
for (idx = bit_limit; idx < ivl_lval_pins(lval); idx += 1)
if (mem)
assign_to_memory(mem, idx, 0, delay);
else if (del != 0)
assign_to_lvariable(lval, idx, 0,
1, 1);
else
assign_to_lvariable(lval, idx, 0, delay);
assign_to_lvariable(lval, idx, 0,
delay, 0);
}
return 0;
@ -301,6 +322,9 @@ static int show_stmt_assign_nb(ivl_statement_t net)
unsigned lidx;
unsigned cur_rbit = 0;
if (del != 0)
calculate_into_x1(del);
for (lidx = 0 ; lidx < ivl_stmt_lvals(net) ; lidx += 1) {
unsigned idx;
unsigned bit_limit = wid - cur_rbit;
@ -325,8 +349,12 @@ static int show_stmt_assign_nb(ivl_statement_t net)
: (res.base+cur_rbit);
if (mem)
assign_to_memory(mem, idx, bidx, delay);
else if (del != 0)
assign_to_lvariable(lval, idx, bidx,
1, 1);
else
assign_to_lvariable(lval, idx, bidx, delay);
assign_to_lvariable(lval, idx, bidx,
delay, 0);
cur_rbit += 1;
}
@ -334,8 +362,10 @@ static int show_stmt_assign_nb(ivl_statement_t net)
for (idx = bit_limit ; idx < ivl_lval_pins(lval) ; idx += 1)
if (mem)
assign_to_memory(mem, idx, 0, delay);
else if (del != 0)
assign_to_lvariable(lval, idx, 0, 1, 1);
else
assign_to_lvariable(lval, idx, 0, delay);
assign_to_lvariable(lval, idx, 0, delay, 0);
}
@ -1105,6 +1135,11 @@ int draw_func_definition(ivl_scope_t scope)
/*
* $Log: vvp_process.c,v $
* Revision 1.56 2002/04/21 22:31:02 steve
* Redo handling of assignment internal delays.
* Leave it possible for them to be calculated
* at run time.
*
* Revision 1.55 2002/04/14 19:19:21 steve
* Handle empty true case of conditional statements.
*