From 8f68a0747655c66f82c13804abc43941c387da13 Mon Sep 17 00:00:00 2001 From: steve Date: Sat, 4 Sep 1999 19:11:45 +0000 Subject: [PATCH] Add support for delayed non-blocking assignments. --- Makefile.in | 4 +- PDelays.cc | 103 +++++++++++++++++++++++++++++++++++++++++++++++++ PDelays.h | 67 ++++++++++++++++++++++++++++++++ PGate.cc | 59 ++++------------------------ PGate.h | 8 +++- Statement.cc | 9 +++-- Statement.h | 12 +++--- design_dump.cc | 16 ++++++-- elaborate.cc | 31 +++++++-------- pform_dump.cc | 28 +++++++++----- t-vvm.cc | 22 +++++++---- 11 files changed, 258 insertions(+), 101 deletions(-) create mode 100644 PDelays.cc create mode 100644 PDelays.h diff --git a/Makefile.in b/Makefile.in index c978f7f22..147e93ff4 100644 --- a/Makefile.in +++ b/Makefile.in @@ -18,7 +18,7 @@ # 59 Temple Place - Suite 330 # Boston, MA 02111-1307, USA # -#ident "$Id: Makefile.in,v 1.15 1999/08/31 22:34:25 steve Exp $" +#ident "$Id: Makefile.in,v 1.16 1999/09/04 19:11:45 steve Exp $" # # SHELL = /bin/sh @@ -62,7 +62,7 @@ FF = nobufz.o propinit.o sigfold.o xnfio.o xnfsyn.o O = main.o cprop.o design_dump.o elaborate.o emit.o eval.o functor.o \ lexor.o mangle.o netlist.o parse.o parse_misc.o pform.o pform_dump.o \ -verinum.o verireal.o target.o targets.o Module.o PExpr.o PGate.o \ +verinum.o verireal.o target.o targets.o Module.o PDelays.o PExpr.o PGate.o \ PTask.o PFunction.o PWire.o Statement.o \ $(FF) $(TT) diff --git a/PDelays.cc b/PDelays.cc new file mode 100644 index 000000000..e293cf3c4 --- /dev/null +++ b/PDelays.cc @@ -0,0 +1,103 @@ +/* + * 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 + * General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ +#if !defined(WINNT) +#ident "$Id: PDelays.cc,v 1.1 1999/09/04 19:11:46 steve Exp $" +#endif + +# include "PDelays.h" +# include "PExpr.h" +# include "verinum.h" + +PDelays::PDelays() +{ + for (unsigned idx = 0 ; idx < 3 ; idx += 1) + delay_[idx] = 0; +} + +PDelays::~PDelays() +{ + for (unsigned idx = 0 ; idx < 3 ; idx += 1) + delete delay_[idx]; +} + +void PDelays::set_delay(PExpr*del) +{ + assert(del); + assert(delay_[0] == 0); + delay_[0] = del; +} + + +void PDelays::set_delays(const svector*del) +{ + assert(del); + assert(del->count() <= 3); + for (unsigned idx = 0 ; idx < del->count() ; idx += 1) + delay_[idx] = (*del)[idx]; +} + +void PDelays::eval_delays(Design*des, const string&path, + unsigned long&rise_time, + unsigned long&fall_time, + unsigned long&decay_time) const +{ + 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; + } +} + +/* + * $Log: PDelays.cc,v $ + * Revision 1.1 1999/09/04 19:11:46 steve + * Add support for delayed non-blocking assignments. + * + */ + diff --git a/PDelays.h b/PDelays.h new file mode 100644 index 000000000..e564baa89 --- /dev/null +++ b/PDelays.h @@ -0,0 +1,67 @@ +#ifndef __PDelays_H +#define __PDelays_H +/* + * 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 + * General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ +#if !defined(WINNT) +#ident "$Id: PDelays.h,v 1.1 1999/09/04 19:11:46 steve Exp $" +#endif + +# include "svector.h" +# include +class Design; +class PExpr; +class ostream; + +/* + * Various PForm objects can carry delays. These delays include rise, + * fall and decay times. This class arranges to carry the triplet. + */ +class PDelays { + + public: + PDelays(); + ~PDelays(); + + void set_delay(PExpr*); + void set_delays(const svector*del); + + void eval_delays(Design*des, const string&path, + unsigned long&rise_time, + unsigned long&fall_time, + unsigned long&decay_time) const; + + void dump_delays(ostream&out) const; + + private: + PExpr* delay_[3]; + + private: // not implemented + PDelays(const PDelays&); + PDelays& operator= (const PDelays&); +}; + +ostream& operator << (ostream&o, const PDelays&); + +/* + * $Log: PDelays.h,v $ + * Revision 1.1 1999/09/04 19:11:46 steve + * Add support for delayed non-blocking assignments. + * + */ +#endif diff --git a/PGate.cc b/PGate.cc index a419bff11..3697a7706 100644 --- a/PGate.cc +++ b/PGate.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: PGate.cc,v 1.3 1999/08/01 21:18:55 steve Exp $" +#ident "$Id: PGate.cc,v 1.4 1999/09/04 19:11:46 steve Exp $" #endif # include "PGate.h" @@ -30,14 +30,7 @@ PGate::PGate(const string&name, const svector*del) : name_(name), pins_(pins) { - for (unsigned idx = 0 ; idx < 3 ; idx += 1) - delay_[idx] = 0; - - if (del) { - assert(del->count() <= 3); - for (unsigned idx = 0 ; idx < del->count() ; idx += 1) - delay_[idx] = (*del)[idx]; - } + delay_.set_delays(del); } PGate::PGate(const string&name, @@ -45,23 +38,16 @@ PGate::PGate(const string&name, PExpr*del) : name_(name), pins_(pins) { - delay_[0] = del; - delay_[1] = 0; - delay_[2] = 0; + delay_.set_delay(del); } PGate::PGate(const string&name, svector*pins) : name_(name), pins_(pins) { - delay_[0] = 0; - delay_[1] = 0; - delay_[2] = 0; } PGate::~PGate() { - for (unsigned idx = 0 ; idx < 3 ; idx += 1) - delete delay_[idx]; } /* @@ -77,41 +63,7 @@ void PGate::eval_delays(Design*des, const string&path, unsigned long&fall_time, unsigned long&decay_time) const { - 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; - } + delay_.eval_delays(des, path, rise_time, fall_time, decay_time); } PGAssign::PGAssign(svector*pins) @@ -160,6 +112,9 @@ void PGBuiltin::set_range(PExpr*msb, PExpr*lsb) /* * $Log: PGate.cc,v $ + * Revision 1.4 1999/09/04 19:11:46 steve + * Add support for delayed non-blocking assignments. + * * Revision 1.3 1999/08/01 21:18:55 steve * elaborate rise/fall/decay for continuous assign. * diff --git a/PGate.h b/PGate.h index 376a9c08b..359a76ad0 100644 --- a/PGate.h +++ b/PGate.h @@ -19,11 +19,12 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: PGate.h,v 1.9 1999/08/23 16:48:39 steve Exp $" +#ident "$Id: PGate.h,v 1.10 1999/09/04 19:11:46 steve Exp $" #endif # include "svector.h" # include "LineInfo.h" +# include "PDelays.h" class PExpr; class PUdp; class Design; @@ -72,7 +73,7 @@ class PGate : public LineInfo { private: const string name_; - PExpr* delay_[3]; + PDelays delay_; svector*pins_; private: // not implemented @@ -179,6 +180,9 @@ class PGModule : public PGate { /* * $Log: PGate.h,v $ + * Revision 1.10 1999/09/04 19:11:46 steve + * Add support for delayed non-blocking assignments. + * * Revision 1.9 1999/08/23 16:48:39 steve * Parameter overrides support from Peter Monta * AND and XOR support wide expressions. diff --git a/Statement.cc b/Statement.cc index 8f2ed9e15..ea26ccc3b 100644 --- a/Statement.cc +++ b/Statement.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: Statement.cc,v 1.13 1999/09/02 01:59:27 steve Exp $" +#ident "$Id: Statement.cc,v 1.14 1999/09/04 19:11:46 steve Exp $" #endif # include "Statement.h" @@ -28,14 +28,14 @@ Statement::~Statement() } PAssign_::PAssign_(PExpr*lval, PExpr*de, PExpr*ex) -: lval_(lval), delay_(de), rval_(ex) +: lval_(lval), rval_(ex) { + if (de) delay_.set_delay(de); } PAssign_::~PAssign_() { delete lval_; - delete delay_; delete rval_; } @@ -148,6 +148,9 @@ PWhile::~PWhile() /* * $Log: Statement.cc,v $ + * Revision 1.14 1999/09/04 19:11:46 steve + * Add support for delayed non-blocking assignments. + * * Revision 1.13 1999/09/02 01:59:27 steve * Parse non-blocking assignment delays. * diff --git a/Statement.h b/Statement.h index 515bd580b..9206289a9 100644 --- a/Statement.h +++ b/Statement.h @@ -19,11 +19,12 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: Statement.h,v 1.16 1999/09/02 01:59:27 steve Exp $" +#ident "$Id: Statement.h,v 1.17 1999/09/04 19:11:46 steve Exp $" #endif # include # include "svector.h" +# include "PDelays.h" # include "PExpr.h" # include "LineInfo.h" class PExpr; @@ -81,7 +82,6 @@ class PAssign_ : public Statement { virtual ~PAssign_() =0; const PExpr* lval() const { return lval_; } - const PExpr* delay() const { return delay_; } const PExpr* rval() const { return rval_; } protected: @@ -89,9 +89,10 @@ class PAssign_ : public Statement { unsigned&lsb, unsigned&msb, NetExpr*&mux) const; + PDelays delay_; + private: PExpr* lval_; - PExpr* delay_; PExpr* rval_; }; @@ -119,8 +120,6 @@ class PAssignNB : public PAssign_ { virtual void dump(ostream&out, unsigned ind) const; virtual NetProc* elaborate(Design*des, const string&path) const; - - private: }; /* @@ -334,6 +333,9 @@ class PWhile : public Statement { /* * $Log: Statement.h,v $ + * Revision 1.17 1999/09/04 19:11:46 steve + * Add support for delayed non-blocking assignments. + * * Revision 1.16 1999/09/02 01:59:27 steve * Parse non-blocking assignment delays. * diff --git a/design_dump.cc b/design_dump.cc index bac6235ca..7c8f25771 100644 --- a/design_dump.cc +++ b/design_dump.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: design_dump.cc,v 1.38 1999/09/03 04:28:38 steve Exp $" +#ident "$Id: design_dump.cc,v 1.39 1999/09/04 19:11:46 steve Exp $" #endif /* @@ -351,11 +351,16 @@ void NetAssignNB::dump(ostream&o, unsigned ind) const o << setw(ind) << ""; if (bmux_) { - o << name() << "[" << *bmux_ << "] <= " << *rval_ << ";" << - endl; + o << name() << "[" << *bmux_ << "] <= "; + if (rise_time()) + o << "#" << rise_time() << " "; + o << *rval_ << ";" << endl; } else { - o << name() << " <= " << *rval_ << ";" << endl; + o << name() << " <= "; + if (rise_time()) + o << "#" << rise_time() << " "; + o << *rval_ << ";" << endl; } } @@ -728,6 +733,9 @@ void Design::dump(ostream&o) const /* * $Log: design_dump.cc,v $ + * Revision 1.39 1999/09/04 19:11:46 steve + * Add support for delayed non-blocking assignments. + * * Revision 1.38 1999/09/03 04:28:38 steve * elaborate the binary plus operator. * diff --git a/elaborate.cc b/elaborate.cc index 3bba075a6..57f153d25 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.77 1999/09/03 04:28:38 steve Exp $" +#ident "$Id: elaborate.cc,v 1.78 1999/09/04 19:11:46 steve Exp $" #endif /* @@ -1343,7 +1343,8 @@ NetProc* PAssign::elaborate(Design*des, const string&path) const if (reg == 0) return 0; /* If there is a delay expression, elaborate it. */ - verinum*dex = delay() ? delay()->eval_const(des, path) : 0; + unsigned long rise_time, fall_time, decay_time; + delay_.eval_delays(des, path, rise_time, fall_time, decay_time); /* Elaborate the r-value expression. */ @@ -1370,7 +1371,7 @@ NetProc* PAssign::elaborate(Design*des, const string&path) const actually and literally represent the delayed assign in the netlist. The compound statement is exactly equivalent. */ - if (dex) { + if (rise_time) { string n = des->local_symbol(path); unsigned wid = msb - lsb + 1; @@ -1404,13 +1405,12 @@ NetProc* PAssign::elaborate(Design*des, const string&path) const for (unsigned idx = 0 ; idx < wid ; idx += 1) connect(a2->pin(idx), reg->pin(idx+lsb)); - NetPDelay*de = new NetPDelay(dex->as_ulong(), a2); + NetPDelay*de = new NetPDelay(rise_time, a2); NetBlock*bl = new NetBlock(NetBlock::SEQU); bl->append(a1); bl->append(de); - delete dex; return bl; } @@ -1462,12 +1462,6 @@ NetProc* PAssignNB::elaborate(Design*des, const string&path) const assert(rval()); - if (delay()) { - cerr << get_line() << ": sorry, cannot elaborate delays" - " is non-blocking assignments." << endl; - return 0; - } - /* Elaborate the r-value expression. This generates a procedural expression that I attach to the assignment. */ NetExpr*rv = rval()->elaborate_expr(des, path); @@ -1478,12 +1472,6 @@ NetProc* PAssignNB::elaborate(Design*des, const string&path) const } assert(rv); - if (delay()) { - cerr << delay()->get_line() << ": Sorry, I cannot elaborate " - "assignment delay expressions." << endl; - des->errors += 1; - } - NetAssignNB*cur; if (mux == 0) { unsigned wid = msb - lsb + 1; @@ -1497,6 +1485,12 @@ NetProc* PAssignNB::elaborate(Design*des, const string&path) const connect(cur->pin(0), reg->pin(0)); } + unsigned long rise_time, fall_time, decay_time; + delay_.eval_delays(des, path, rise_time, fall_time, decay_time); + cur->rise_time(rise_time); + cur->fall_time(fall_time); + cur->decay_time(decay_time); + /* All done with this node. mark its line number and check it in. */ cur->set_line(*this); @@ -2192,6 +2186,9 @@ Design* elaborate(const map&modules, /* * $Log: elaborate.cc,v $ + * Revision 1.78 1999/09/04 19:11:46 steve + * Add support for delayed non-blocking assignments. + * * Revision 1.77 1999/09/03 04:28:38 steve * elaborate the binary plus operator. * diff --git a/pform_dump.cc b/pform_dump.cc index 5d81cca7a..67b7d47c9 100644 --- a/pform_dump.cc +++ b/pform_dump.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: pform_dump.cc,v 1.36 1999/08/25 22:22:41 steve Exp $" +#ident "$Id: pform_dump.cc,v 1.37 1999/09/04 19:11:46 steve Exp $" #endif /* @@ -37,6 +37,12 @@ ostream& operator << (ostream&out, const PExpr&obj) return out; } +ostream& operator << (ostream&o, const PDelays&d) +{ + d.dump_delays(o); + return o; +} + void PExpr::dump(ostream&out) const { out << typeid(*this).name(); @@ -209,7 +215,7 @@ void PGate::dump_pins(ostream&out) const } } -void PGate::dump_delays(ostream&out) const +void PDelays::dump_delays(ostream&out) const { if (delay_[0] && delay_[1] && delay_[2]) out << "#(" << *delay_[0] << "," << *delay_[1] << "," << @@ -221,10 +227,15 @@ void PGate::dump_delays(ostream&out) const } +void PGate::dump_delays(ostream&out) const +{ + delay_.dump_delays(out); +} + void PGate::dump(ostream&out) const { out << " " << typeid(*this).name() << " "; - dump_delays(out); + delay_.dump_delays(out); out << " " << get_name() << "("; dump_pins(out); out << ");" << endl; @@ -303,18 +314,14 @@ void Statement::dump(ostream&out, unsigned ind) const void PAssign::dump(ostream&out, unsigned ind) const { out << setw(ind) << ""; - out << *lval() << " = "; - if (delay()) out << "#" << *delay() << " "; - out << *rval() << ";"; + out << *lval() << " = " << delay_ << " " << *rval() << ";"; out << " /* " << get_line() << " */" << endl; } void PAssignNB::dump(ostream&out, unsigned ind) const { out << setw(ind) << ""; - out << *lval() << " <= "; - if (delay()) out << "#" << *delay() << " "; - out << *rval() << ";"; + out << *lval() << " <= " << delay_ << " " << *rval() << ";"; out << " /* " << get_line() << " */" << endl; } @@ -629,6 +636,9 @@ void PUdp::dump(ostream&out) const /* * $Log: pform_dump.cc,v $ + * Revision 1.37 1999/09/04 19:11:46 steve + * Add support for delayed non-blocking assignments. + * * Revision 1.36 1999/08/25 22:22:41 steve * elaborate some aspects of functions. * diff --git a/t-vvm.cc b/t-vvm.cc index bb9ba3d71..7a0ee273d 100644 --- a/t-vvm.cc +++ b/t-vvm.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: t-vvm.cc,v 1.38 1999/09/04 01:57:15 steve Exp $" +#ident "$Id: t-vvm.cc,v 1.39 1999/09/04 19:11:46 steve Exp $" #endif # include @@ -285,6 +285,10 @@ void vvm_proc_rval::expr_binary(const NetEBinary*expr) os_ << setw(indent_) << "" << "vvm_bitset_t<" << expr->expr_width() << ">" << result << ";" << endl; switch (expr->op()) { + case 'a': // logical and (&&) + os_ << setw(indent_) << "" << result << " = vvm_binop_land(" + << lres << "," << rres << ");" << endl; + break; case 'E': // === os_ << setw(indent_) << "" << result << " = vvm_binop_eeq(" << lres << "," << rres << ");" << endl; @@ -305,7 +309,7 @@ void vvm_proc_rval::expr_binary(const NetEBinary*expr) os_ << setw(indent_) << "" << result << " = vvm_binop_lt(" << lres << "," << rres << ");" << endl; break; - case 'o': + case 'o': // logical or (||) os_ << setw(indent_) << "" << result << " = vvm_binop_lor(" << lres << "," << rres << ");" << endl; break; @@ -1036,13 +1040,14 @@ void target_vvm::proc_assign_nb(ostream&os, const NetAssignNB*net) if (net->bmux()) { string bval = emit_proc_rval(os, 8, net->bmux()); - os << " sim_->insert_event(0, new " << - mangle(net->name()) << "(sim_, " << rval << ", " << bval - << ".as_unsigned()));" << endl; + os << " sim_->insert_event(" << net->rise_time() + << ", new " << mangle(net->name()) << "(sim_, " << rval + << ", " << bval << ".as_unsigned()));" << endl; } else { - os << " sim_->insert_event(0, new " << - mangle(net->name()) << "(sim_, " << rval << "));" << endl; + os << " sim_->insert_event(" << net->rise_time() + << ", new " << mangle(net->name()) << "(sim_, " << rval + << "));" << endl; } } @@ -1411,6 +1416,9 @@ extern const struct target tgt_vvm = { }; /* * $Log: t-vvm.cc,v $ + * Revision 1.39 1999/09/04 19:11:46 steve + * Add support for delayed non-blocking assignments. + * * Revision 1.38 1999/09/04 01:57:15 steve * Generate fake adder code in vvm. *