Add support for non-constant delays in delay statements,

Support evaluating ! in constant expressions, and
 move some code from netlist.cc to net_proc.cc.
This commit is contained in:
steve 2000-07-07 04:53:53 +00:00
parent cdb3eb7e6b
commit 18eb34921f
10 changed files with 248 additions and 59 deletions

View File

@ -18,7 +18,7 @@
# 59 Temple Place - Suite 330
# Boston, MA 02111-1307, USA
#
#ident "$Id: Makefile.in,v 1.58 2000/06/25 19:59:41 steve Exp $"
#ident "$Id: Makefile.in,v 1.59 2000/07/07 04:53:53 steve Exp $"
#
#
SHELL = /bin/sh
@ -73,7 +73,8 @@ O = main.o cprop.o design_dump.o dup_expr.o elaborate.o elab_expr.o \
elab_net.o elab_pexpr.o elab_scope.o elab_sig.o emit.o eval.o eval_tree.o \
expr_synth.o functor.o lexor.o lexor_keyword.o link_const.o \
mangle.o netlist.o \
net_design.o net_event.o net_force.o net_link.o net_scope.o net_udp.o \
net_design.o net_event.o net_force.o net_link.o net_proc.o net_scope.o \
net_udp.o \
pad_to_width.o \
parse.o parse_misc.o pform.o pform_dump.o \
set_width.o \

View File

@ -331,11 +331,6 @@ current state of support for Verilog.
- System functions are supported, but the compiler presumes that
they return 32 bits. This is the typical case.
- non-constant delay expressions, i.e.:
reg [7:0] del;
always #(reg) $display($time,,"del = %d", del); // sorry
- Specify blocks are parsed but ignored in general.

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: design_dump.cc,v 1.88 2000/06/25 19:59:42 steve Exp $"
#ident "$Id: design_dump.cc,v 1.89 2000/07/07 04:53:53 steve Exp $"
#endif
/*
@ -626,7 +626,13 @@ void NetFuncDef::dump(ostream&o, unsigned ind) const
void NetPDelay::dump(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "#" << delay_;
if (expr_) {
o << setw(ind) << "" << "#" << *expr_;
} else {
o << setw(ind) << "" << "#" << delay_;
}
if (statement_) {
o << endl;
statement_->dump(o, ind+2);
@ -967,6 +973,11 @@ void Design::dump(ostream&o) const
/*
* $Log: design_dump.cc,v $
* Revision 1.89 2000/07/07 04:53:53 steve
* Add support for non-constant delays in delay statements,
* Support evaluating ! in constant expressions, and
* move some code from netlist.cc to net_proc.cc.
*
* Revision 1.88 2000/06/25 19:59:42 steve
* Redesign Links to include the Nexus class that
* carries properties of the connected set of links.

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.176 2000/06/13 03:24:48 steve Exp $"
#ident "$Id: elaborate.cc,v 1.177 2000/07/07 04:53:54 steve Exp $"
#endif
/*
@ -1573,21 +1573,44 @@ NetDeassign* PDeassign::elaborate(Design*des, const string&path) const
return dev;
}
/*
* Elaborate the delay statment (of the form #<expr> <statement>) as a
* NetPDelay object. If the expression is constant, evaluate it now
* and make a constant delay. If not, then pass an elaborated
* expression to the constructor of NetPDelay so that the code
* generator knows to evaluate the expression at run time.
*/
NetProc* PDelayStatement::elaborate(Design*des, const string&path) const
{
NetScope*scope = des->find_scope(path);
assert(scope);
verinum*num = delay_->eval_const(des, path);
if (num == 0) {
cerr << get_line() << ": sorry: delay expression "
"must be constant." << endl;
return 0;
/* Ah, the delay is not constant. OK, elaborate the
expression and let the run-time handle it. */
NetExpr*dex = delay_->elaborate_expr(des, scope);
if (statement_)
return new NetPDelay(dex, statement_->elaborate(des, path));
else
return new NetPDelay(dex, 0);
}
assert(num);
/* If there is a statement, then elaborate it and create a
NetPDelay statement to contain it. Note that we create a
NetPDelay statement even if the value is 0 because #0 does
in fact have a well defined meaning in Verilog. */
unsigned long val = num->as_ulong();
if (statement_)
return new NetPDelay(val, statement_->elaborate(des, path));
else
if (statement_) {
NetProc*stmt = statement_->elaborate(des, path);
return new NetPDelay(val, stmt);
} else {
return new NetPDelay(val, 0);
}
}
/*
@ -2435,6 +2458,11 @@ Design* elaborate(const map<string,Module*>&modules,
/*
* $Log: elaborate.cc,v $
* Revision 1.177 2000/07/07 04:53:54 steve
* Add support for non-constant delays in delay statements,
* Support evaluating ! in constant expressions, and
* move some code from netlist.cc to net_proc.cc.
*
* Revision 1.176 2000/06/13 03:24:48 steve
* Index in memory assign should be a NetExpr.
*

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: eval_tree.cc,v 1.10 2000/04/28 18:43:23 steve Exp $"
#ident "$Id: eval_tree.cc,v 1.11 2000/07/07 04:53:54 steve Exp $"
#endif
# include "netlist.h"
@ -273,8 +273,55 @@ NetExpr* NetEParam::eval_tree()
return res->dup_expr();
}
NetEConst* NetEUnary::eval_tree()
{
NetExpr*oper = expr_->eval_tree();
NetEConst*rval = dynamic_cast<NetEConst*>(oper);
if (rval == 0)
return 0;
verinum val = rval->value();
switch (op_) {
case '!': {
/* Evaluate the unary logical not by first scanning
the operand value for V1 and Vx bits. If we find
any V1 bits we know that the value is TRUE, so
the result of ! is V0. If there are no V1 bits
but there are some Vx/Vz bits, the result is
unknown. Otherwise, the result is V1. */
unsigned v1 = 0, vx = 0;
for (unsigned idx = 0 ; idx < val.len() ; idx += 1) {
switch (val.get(idx)) {
case verinum::V0:
break;
case verinum::V1:
v1 += 1;
break;
default:
vx += 1;
break;
}
}
verinum out(v1? verinum::V0 : (vx? verinum::Vx : verinum::V1));
return new NetEConst(out);
}
default:
delete rval;
return 0;
}
}
/*
* $Log: eval_tree.cc,v $
* Revision 1.11 2000/07/07 04:53:54 steve
* Add support for non-constant delays in delay statements,
* Support evaluating ! in constant expressions, and
* move some code from netlist.cc to net_proc.cc.
*
* Revision 1.10 2000/04/28 18:43:23 steve
* integer division in expressions properly get width.
*

88
net_proc.cc Normal file
View File

@ -0,0 +1,88 @@
/*
* Copyright (c) 2000 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) && !defined(macintosh)
#ident "$Id: net_proc.cc,v 1.1 2000/07/07 04:53:54 steve Exp $"
#endif
# include "netlist.h"
# include <assert.h>
NetForever::NetForever(NetProc*p)
: statement_(p)
{
}
NetForever::~NetForever()
{
delete statement_;
}
NetPDelay::NetPDelay(unsigned long d, NetProc*st)
: delay_(d), expr_(0), statement_(st)
{
}
NetPDelay::NetPDelay(NetExpr*d, NetProc*st)
: delay_(0), expr_(d), statement_(st)
{
}
NetPDelay::~NetPDelay()
{
if (expr_) delete expr_;
}
unsigned long NetPDelay::delay() const
{
assert(expr_ == 0);
return delay_;
}
const NetExpr* NetPDelay::expr() const
{
return expr_;
}
NetRepeat::NetRepeat(NetExpr*e, NetProc*p)
: expr_(e), statement_(p)
{
}
NetRepeat::~NetRepeat()
{
delete expr_;
delete statement_;
}
const NetExpr* NetRepeat::expr() const
{
return expr_;
}
/*
* $Log: net_proc.cc,v $
* Revision 1.1 2000/07/07 04:53:54 steve
* Add support for non-constant delays in delay statements,
* Support evaluating ! in constant expressions, and
* move some code from netlist.cc to net_proc.cc.
*
*/

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: netlist.cc,v 1.131 2000/06/25 19:59:42 steve Exp $"
#ident "$Id: netlist.cc,v 1.132 2000/07/07 04:53:54 steve Exp $"
#endif
# include <cassert>
@ -2241,16 +2241,6 @@ NetEUBits::~NetEUBits()
{
}
NetForever::NetForever(NetProc*p)
: statement_(p)
{
}
NetForever::~NetForever()
{
delete statement_;
}
NetLogic::NetLogic(const string&n, unsigned pins, TYPE t)
: NetNode(n, pins), type_(t)
{
@ -2262,22 +2252,6 @@ NetLogic::NetLogic(const string&n, unsigned pins, TYPE t)
}
}
NetRepeat::NetRepeat(NetExpr*e, NetProc*p)
: expr_(e), statement_(p)
{
}
NetRepeat::~NetRepeat()
{
delete expr_;
delete statement_;
}
const NetExpr* NetRepeat::expr() const
{
return expr_;
}
NetTaskDef::NetTaskDef(const string&n, const svector<NetNet*>&po)
: name_(n), proc_(0), ports_(po)
{
@ -2464,6 +2438,11 @@ bool NetUDP::sequ_glob_(string input, char output)
/*
* $Log: netlist.cc,v $
* Revision 1.132 2000/07/07 04:53:54 steve
* Add support for non-constant delays in delay statements,
* Support evaluating ! in constant expressions, and
* move some code from netlist.cc to net_proc.cc.
*
* Revision 1.131 2000/06/25 19:59:42 steve
* Redesign Links to include the Nexus class that
* carries properties of the connected set of links.

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.143 2000/06/25 19:59:42 steve Exp $"
#ident "$Id: netlist.h,v 1.144 2000/07/07 04:53:54 steve Exp $"
#endif
/*
@ -1626,13 +1626,29 @@ class NetFuncDef {
svector<NetNet*>ports_;
};
/*
* This class represents delay statements of the form:
*
* #<expr> <statement>
*
* Where the statement may be null. The delay is evaluated at
* elaboration time to make a constant unsigned long that is the delay
* in simulation ticks.
*
* If the delay expression is non-constant, construct the NetPDelay
* object with a NetExpr* instead of the d value, and use th expr()
* method to get the expression. If expr() returns 0, use the delay()
* method to get the constant delay.
*/
class NetPDelay : public NetProc {
public:
NetPDelay(unsigned long d, NetProc*st)
: delay_(d), statement_(st) { }
NetPDelay(unsigned long d, NetProc*st);
NetPDelay(NetExpr* d, NetProc*st);
~NetPDelay();
unsigned long delay() const { return delay_; }
unsigned long delay() const;
const NetExpr*expr() const;
virtual bool emit_proc(ostream&, struct target_t*) const;
virtual void dump(ostream&, unsigned ind) const;
@ -1641,6 +1657,7 @@ class NetPDelay : public NetProc {
private:
unsigned long delay_;
NetExpr*expr_;
NetProc*statement_;
};
@ -2242,6 +2259,7 @@ class NetEUnary : public NetExpr {
virtual bool set_width(unsigned w);
virtual NetEUnary* dup_expr() const;
virtual NetEConst* eval_tree();
virtual void expr_scan(struct expr_scan_t*) const;
virtual void dump(ostream&) const;
@ -2630,6 +2648,11 @@ extern ostream& operator << (ostream&, NetNet::Type);
/*
* $Log: netlist.h,v $
* Revision 1.144 2000/07/07 04:53:54 steve
* Add support for non-constant delays in delay statements,
* Support evaluating ! in constant expressions, and
* move some code from netlist.cc to net_proc.cc.
*
* Revision 1.143 2000/06/25 19:59:42 steve
* Redesign Links to include the Nexus class that
* carries properties of the connected set of links.

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: parse.y,v 1.101 2000/06/30 15:50:20 steve Exp $"
#ident "$Id: parse.y,v 1.102 2000/07/07 04:53:54 steve Exp $"
#endif
# include "parse_misc.h"
@ -344,9 +344,6 @@ delay3_opt
delay_value
: expression
{ PExpr*tmp = $1;
if (! pform_expression_is_constant(tmp))
yyerror(@1, "error: delay expression must "
"be constant.");
$$ = tmp;
}
| expression ':' expression ':' expression

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: t-vvm.cc,v 1.160 2000/06/25 19:59:42 steve Exp $"
#ident "$Id: t-vvm.cc,v 1.161 2000/07/07 04:53:54 steve Exp $"
#endif
# include <iostream>
@ -3025,16 +3025,31 @@ void target_vvm::proc_while(ostream&os, const NetWhile*net)
/*
* A delay suspends the thread for a period of time.
* A delay suspends the thread for a period of time. If the delay
* is an expression expresion, evaluate it at run time and use the
* unsigned interpretation of it as the actual delay.
*/
void target_vvm::proc_delay(ostream&os, const NetPDelay*proc)
{
thread_step_ += 1;
defn << " thr->step_ = &" << thread_class_ << "_step_"
<< thread_step_ << "_;" << endl;
defn << " thr->thread_yield(" << proc->delay() << ");" << endl;
defn << " return false;" << endl;
defn << "}" << endl;
if (proc->expr()) {
string rval = emit_proc_rval(this, proc->expr());
defn << " thr->step_ = &" << thread_class_ << "_step_"
<< thread_step_ << "_;" << endl;
defn << " thr->thread_yield(" << rval << ".as_unsigned());"
<< endl;
defn << " return false;" << endl;
defn << "}" << endl;
} else {
defn << " thr->step_ = &" << thread_class_ << "_step_"
<< thread_step_ << "_;" << endl;
defn << " thr->thread_yield(" << proc->delay() << ");"
<< endl;
defn << " return false;" << endl;
defn << "}" << endl;
}
os << "static bool " << thread_class_ << "_step_"
<< thread_step_ << "_(vvm_thread*thr);" << endl;
@ -3068,6 +3083,11 @@ extern const struct target tgt_vvm = {
};
/*
* $Log: t-vvm.cc,v $
* Revision 1.161 2000/07/07 04:53:54 steve
* Add support for non-constant delays in delay statements,
* Support evaluating ! in constant expressions, and
* move some code from netlist.cc to net_proc.cc.
*
* Revision 1.160 2000/06/25 19:59:42 steve
* Redesign Links to include the Nexus class that
* carries properties of the connected set of links.