From dd8daf40dff66a29ad29839cf2291af5c5d6d4f6 Mon Sep 17 00:00:00 2001 From: steve Date: Sun, 1 Aug 1999 21:18:55 +0000 Subject: [PATCH] elaborate rise/fall/decay for continuous assign. --- PExpr.h | 40 +++++++++++++++++----- PGate.cc | 58 +++++++++++++++++++++++++++++--- PGate.h | 10 ++++-- elaborate.cc | 95 +++++++++++++++++++++++++--------------------------- 4 files changed, 138 insertions(+), 65 deletions(-) diff --git a/PExpr.h b/PExpr.h index b1f65365e..a303bc849 100644 --- a/PExpr.h +++ b/PExpr.h @@ -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 @@ -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) * diff --git a/PGate.cc b/PGate.cc index fa88101b5..a419bff11 100644 --- a/PGate.cc +++ b/PGate.cc @@ -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 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*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 diff --git a/PGate.h b/PGate.h index 47ecb4a07..61f4e713e 100644 --- a/PGate.h +++ b/PGate.h @@ -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 diff --git a/elaborate.cc b/elaborate.cc index 2f1d0144d..5da67712b 100644 --- a/elaborate.cc +++ b/elaborate.cc @@ -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(lsig)) delete tmp; if (NetTmp*tmp = dynamic_cast(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 { svectornets (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(sub_sig)) delete tmp; @@ -2052,6 +2044,9 @@ Design* elaborate(const map&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