Add support for delayed non-blocking assignments.

This commit is contained in:
steve 1999-09-04 19:11:45 +00:00
parent 555d447180
commit 8f68a07476
11 changed files with 258 additions and 101 deletions

View File

@ -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)

103
PDelays.cc Normal file
View File

@ -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<PExpr*>*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.
*
*/

67
PDelays.h Normal file
View File

@ -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 <string>
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<PExpr*>*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

View File

@ -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<PExpr*>*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<PExpr*>*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<PExpr*>*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.
*

View File

@ -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<PExpr*>*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.

View File

@ -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.
*

View File

@ -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 <string>
# 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.
*

View File

@ -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.
*

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.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<string,Module*>&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.
*

View File

@ -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.
*

View File

@ -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 <iostream>
@ -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.
*