elaborate rise/fall/decay for continuous assign.

This commit is contained in:
steve 1999-08-01 21:18:55 +00:00
parent 71d35f32b2
commit dd8daf40df
4 changed files with 138 additions and 65 deletions

40
PExpr.h
View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: PExpr.h,v 1.16 1999/07/31 19:14:47 steve Exp $"
#ident "$Id: PExpr.h,v 1.17 1999/08/01 21:18:55 steve Exp $"
#endif
# include <string>
@ -47,7 +47,10 @@ class PExpr : public LineInfo {
virtual ~PExpr();
virtual void dump(ostream&) const;
virtual NetNet* elaborate_net(Design*des, const string&path) const;
virtual NetNet* elaborate_net(Design*des, const string&path,
unsigned long rise =0,
unsigned long fall =0,
unsigned long decay =0) const;
virtual NetExpr*elaborate_expr(Design*des, const string&path) const;
// This attempts to evaluate a constant expression, and return
@ -77,7 +80,10 @@ class PEConcat : public PExpr {
~PEConcat();
virtual void dump(ostream&) const;
virtual NetNet* elaborate_net(Design*des, const string&path) const;
virtual NetNet* elaborate_net(Design*des, const string&path,
unsigned long rise =0,
unsigned long fall =0,
unsigned long decay =0) const;
virtual NetExpr*elaborate_expr(Design*des, const string&path) const;
virtual bool is_constant(Module*) const;
@ -110,7 +116,10 @@ class PEIdent : public PExpr {
: text_(s), msb_(0), lsb_(0), idx_(0) { }
virtual void dump(ostream&) const;
virtual NetNet* elaborate_net(Design*des, const string&path) const;
virtual NetNet* elaborate_net(Design*des, const string&path,
unsigned long rise =0,
unsigned long fall =0,
unsigned long decay =0) const;
virtual NetExpr*elaborate_expr(Design*des, const string&path) const;
virtual bool is_constant(Module*) const;
verinum* eval_const(const Design*des, const string&path) const;
@ -141,7 +150,10 @@ class PENumber : public PExpr {
const verinum& value() const { return *value_; }
virtual void dump(ostream&) const;
virtual NetNet* elaborate_net(Design*des, const string&path) const;
virtual NetNet* elaborate_net(Design*des, const string&path,
unsigned long rise =0,
unsigned long fall =0,
unsigned long decay =0) const;
virtual NetExpr*elaborate_expr(Design*des, const string&path) const;
virtual verinum* eval_const(const Design*des, const string&path) const;
@ -175,7 +187,10 @@ class PEUnary : public PExpr {
: op_(op), expr_(ex) { }
virtual void dump(ostream&out) const;
virtual NetNet* elaborate_net(Design*des, const string&path) const;
virtual NetNet* elaborate_net(Design*des, const string&path,
unsigned long rise =0,
unsigned long fall =0,
unsigned long decay =0) const;
virtual NetExpr*elaborate_expr(Design*des, const string&path) const;
private:
@ -192,7 +207,10 @@ class PEBinary : public PExpr {
virtual bool is_constant(Module*) const;
virtual void dump(ostream&out) const;
virtual NetNet* elaborate_net(Design*des, const string&path) const;
virtual NetNet* elaborate_net(Design*des, const string&path,
unsigned long rise =0,
unsigned long fall =0,
unsigned long decay =0) const;
virtual NetExpr*elaborate_expr(Design*des, const string&path) const;
virtual verinum* eval_const(const Design*des, const string&path) const;
@ -215,7 +233,10 @@ class PETernary : public PExpr {
virtual bool is_constant(Module*) const;
virtual void dump(ostream&out) const;
virtual NetNet* elaborate_net(Design*des, const string&path) const;
virtual NetNet* elaborate_net(Design*des, const string&path,
unsigned long rise =0,
unsigned long fall =0,
unsigned long decay =0) const;
virtual NetExpr*elaborate_expr(Design*des, const string&path) const;
virtual verinum* eval_const(const Design*des, const string&path) const;
@ -241,6 +262,9 @@ class PECallFunction : public PExpr {
/*
* $Log: PExpr.h,v $
* Revision 1.17 1999/08/01 21:18:55 steve
* elaborate rise/fall/decay for continuous assign.
*
* Revision 1.16 1999/07/31 19:14:47 steve
* Add functions up to elaboration (Ed Carter)
*

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1999 Stephen Williams (steve@picturel.com)
* Copyright (c) 1999 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
@ -17,11 +17,12 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: PGate.cc,v 1.2 1999/08/01 16:34:50 steve Exp $"
#ident "$Id: PGate.cc,v 1.3 1999/08/01 21:18:55 steve Exp $"
#endif
# include "PGate.h"
# include "PExpr.h"
# include "verinum.h"
# include <assert.h>
PGate::PGate(const string&name,
@ -63,10 +64,54 @@ PGate::~PGate()
delete delay_[idx];
}
const PExpr* PGate::get_delay(unsigned idx) const
/*
* This method is used during elaboration to calculate the
* rise/fall/decay times for the gate. These values were set in pform
* by the constructor, so here I evaluate the expression in the given
* design context and save the calculated delays into the output
* parameters. This method understands how to handle the different
* numbers of expressions.
*/
void PGate::eval_delays(Design*des, const string&path,
unsigned long&rise_time,
unsigned long&fall_time,
unsigned long&decay_time) const
{
assert(idx < 3);
return delay_[idx];
verinum*dv;
if (delay_[0]) {
dv = delay_[0]->eval_const(des, path);
assert(dv);
rise_time = dv->as_ulong();
delete dv;
if (delay_[1]) {
dv = delay_[1]->eval_const(des, path);
assert(dv);
fall_time = dv->as_ulong();
delete dv;
if (delay_[2]) {
dv = delay_[2]->eval_const(des, path);
assert(dv);
decay_time = dv->as_ulong();
delete dv;
} else {
if (rise_time < fall_time)
decay_time = rise_time;
else
decay_time = fall_time;
}
} else {
assert(delay_[2] == 0);
fall_time = rise_time;
decay_time = rise_time;
}
} else {
rise_time = 0;
fall_time = 0;
decay_time = 0;
}
}
PGAssign::PGAssign(svector<PExpr*>*pins)
@ -115,6 +160,9 @@ void PGBuiltin::set_range(PExpr*msb, PExpr*lsb)
/*
* $Log: PGate.cc,v $
* Revision 1.3 1999/08/01 21:18:55 steve
* elaborate rise/fall/decay for continuous assign.
*
* Revision 1.2 1999/08/01 16:34:50 steve
* Parse and elaborate rise/fall/decay times
* for gates, and handle the rules for partial

10
PGate.h
View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: PGate.h,v 1.7 1999/08/01 16:34:50 steve Exp $"
#ident "$Id: PGate.h,v 1.8 1999/08/01 21:18:55 steve Exp $"
#endif
# include "svector.h"
@ -53,7 +53,10 @@ class PGate : public LineInfo {
const string& get_name() const { return name_; }
const PExpr* get_delay(unsigned idx) const;
void eval_delays(Design*des, const string&path,
unsigned long&rise_time,
unsigned long&fall_time,
unsigned long&decay_time) const;
unsigned pin_count() const { return pins_? pins_->count() : 0; }
const PExpr*pin(unsigned idx) const { return (*pins_)[idx]; }
@ -175,6 +178,9 @@ class PGModule : public PGate {
/*
* $Log: PGate.h,v $
* Revision 1.8 1999/08/01 21:18:55 steve
* elaborate rise/fall/decay for continuous assign.
*
* Revision 1.7 1999/08/01 16:34:50 steve
* Parse and elaborate rise/fall/decay times
* for gates, and handle the rules for partial

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: elaborate.cc,v 1.63 1999/08/01 16:34:50 steve Exp $"
#ident "$Id: elaborate.cc,v 1.64 1999/08/01 21:18:55 steve Exp $"
#endif
/*
@ -200,10 +200,14 @@ void PGate::elaborate(Design*des, const string&path) const
assign.) Elaborate the lvalue and rvalue, and do the assignment. */
void PGAssign::elaborate(Design*des, const string&path) const
{
unsigned long rise_time, fall_time, decay_time;
eval_delays(des, path, rise_time, fall_time, decay_time);
assert(pin(0));
assert(pin(1));
NetNet*lval = pin(0)->elaborate_net(des, path);
NetNet*rval = pin(1)->elaborate_net(des, path);
NetNet*rval = pin(1)->elaborate_net(des, path, rise_time,
fall_time, decay_time);
if (lval == 0) {
cerr << get_line() << ": Unable to elaborate l-value: " <<
@ -233,11 +237,6 @@ void PGAssign::elaborate(Design*des, const string&path) const
do_assign(des, path, lval, rval);
if (get_delay(0)) {
cerr << get_line() << ": Sorry, elaboration does not support"
" delayed continuous assignments." << endl;
des->errors += 1;
}
}
/*
@ -300,42 +299,8 @@ void PGBuiltin::elaborate(Design*des, const string&path) const
of the rise and fall times. Finally, if all three
values are given, they are taken as specified. */
verinum*dv;
unsigned long rise_time, fall_time, decay_time;
if (get_delay(0)) {
dv = get_delay(0)->eval_const(des, path);
assert(dv);
rise_time = dv->as_ulong();
delete dv;
if (get_delay(1)) {
dv = get_delay(1)->eval_const(des, path);
assert(dv);
fall_time = dv->as_ulong();
delete dv;
if (get_delay(2)) {
dv = get_delay(2)->eval_const(des, path);
assert(dv);
decay_time = dv->as_ulong();
delete dv;
} else {
if (rise_time < fall_time)
decay_time = rise_time;
else
decay_time = fall_time;
}
} else {
assert(get_delay(2) == 0);
fall_time = rise_time;
decay_time = rise_time;
}
} else {
rise_time = 0;
fall_time = 0;
decay_time = 0;
}
eval_delays(des, path, rise_time, fall_time, decay_time);
/* Now make as many gates as the bit count dictates. Give each
a unique name, and set the delay times. */
@ -642,7 +607,10 @@ void PGModule::elaborate(Design*des, const string&path) const
cerr << get_line() << ": Unknown module: " << type_ << endl;
}
NetNet* PExpr::elaborate_net(Design*des, const string&path) const
NetNet* PExpr::elaborate_net(Design*des, const string&path,
unsigned long,
unsigned long,
unsigned long) const
{
cerr << "Don't know how to elaborate `" << *this << "' as gates." << endl;
return 0;
@ -653,7 +621,10 @@ NetNet* PExpr::elaborate_net(Design*des, const string&path) const
* left and right expressions, then making an output wire and
* connecting the lot together with the right kind of gate.
*/
NetNet* PEBinary::elaborate_net(Design*des, const string&path) const
NetNet* PEBinary::elaborate_net(Design*des, const string&path,
unsigned long rise,
unsigned long fall,
unsigned long decay) const
{
NetNet*lsig = left_->elaborate_net(des, path),
*rsig = right_->elaborate_net(des, path);
@ -747,6 +718,10 @@ NetNet* PEBinary::elaborate_net(Design*des, const string&path) const
osig = 0;
}
gate->rise_time(rise);
gate->fall_time(fall);
gate->decay_time(decay);
if (NetTmp*tmp = dynamic_cast<NetTmp*>(lsig))
delete tmp;
if (NetTmp*tmp = dynamic_cast<NetTmp*>(rsig))
@ -759,7 +734,10 @@ NetNet* PEBinary::elaborate_net(Design*des, const string&path) const
* The concatenation operator, as a net, is a wide signal that is
* connected to all the pins of the elaborated expression nets.
*/
NetNet* PEConcat::elaborate_net(Design*des, const string&path) const
NetNet* PEConcat::elaborate_net(Design*des, const string&path,
unsigned long rise,
unsigned long fall,
unsigned long decay) const
{
svector<NetNet*>nets (parms_.count());
unsigned pins = 0;
@ -773,7 +751,7 @@ NetNet* PEConcat::elaborate_net(Design*des, const string&path) const
/* Elaborate the operands of the concatenation. */
for (unsigned idx = 0 ; idx < nets.count() ; idx += 1) {
nets[idx] = parms_[idx]->elaborate_net(des, path);
nets[idx] = parms_[idx]->elaborate_net(des, path, rise,fall,decay);
if (nets[idx] == 0)
errors += 1;
else
@ -810,7 +788,10 @@ NetNet* PEConcat::elaborate_net(Design*des, const string&path) const
return osig;
}
NetNet* PEIdent::elaborate_net(Design*des, const string&path) const
NetNet* PEIdent::elaborate_net(Design*des, const string&path,
unsigned long rise,
unsigned long fall,
unsigned long decay) const
{
NetNet*sig = des->find_signal(path, text_);
if (sig == 0) {
@ -866,7 +847,10 @@ NetNet* PEIdent::elaborate_net(Design*des, const string&path) const
/*
*/
NetNet* PENumber::elaborate_net(Design*des, const string&path) const
NetNet* PENumber::elaborate_net(Design*des, const string&path,
unsigned long rise,
unsigned long fall,
unsigned long decay) const
{
unsigned width = value_->len();
NetNet*net = new NetNet(des->local_symbol(path),
@ -883,7 +867,8 @@ NetNet* PENumber::elaborate_net(Design*des, const string&path) const
return net;
}
NetNet* PETernary::elaborate_net(Design*des, const string&) const
NetNet* PETernary::elaborate_net(Design*des, const string&, unsigned long,
unsigned long, unsigned long) const
{
cerr << get_line() << ": Sorry, I cannot elaborate ?: as a net."
<< endl;
@ -901,7 +886,10 @@ NetExpr*PETernary::elaborate_expr(Design*des, const string&path) const
return res;
}
NetNet* PEUnary::elaborate_net(Design*des, const string&path) const
NetNet* PEUnary::elaborate_net(Design*des, const string&path,
unsigned long rise,
unsigned long fall,
unsigned long decay) const
{
NetNet* sub_sig = expr_->elaborate_net(des, path);
if (sub_sig == 0) {
@ -943,6 +931,10 @@ NetNet* PEUnary::elaborate_net(Design*des, const string&path) const
sig = 0;
}
gate->rise_time(rise);
gate->fall_time(fall);
gate->decay_time(decay);
if (NetTmp*tmp = dynamic_cast<NetTmp*>(sub_sig))
delete tmp;
@ -2052,6 +2044,9 @@ Design* elaborate(const map<string,Module*>&modules,
/*
* $Log: elaborate.cc,v $
* Revision 1.64 1999/08/01 21:18:55 steve
* elaborate rise/fall/decay for continuous assign.
*
* Revision 1.63 1999/08/01 16:34:50 steve
* Parse and elaborate rise/fall/decay times
* for gates, and handle the rules for partial