Rework expression parsing and elaboration to

accommodate real/realtime values and expressions.
This commit is contained in:
steve 2003-01-26 21:15:58 +00:00
parent 1a9ab8ec84
commit 46253ed873
44 changed files with 1546 additions and 749 deletions

View File

@ -16,7 +16,7 @@
# 59 Temple Place - Suite 330
# Boston, MA 02111-1307, USA
#
#ident "$Id: Makefile.in,v 1.142 2003/01/18 23:56:06 steve Exp $"
#ident "$Id: Makefile.in,v 1.143 2003/01/26 21:15:58 steve Exp $"
#
#
SHELL = /bin/sh
@ -128,11 +128,11 @@ eval_tree.o expr_synth.o functor.o lexor.o lexor_keyword.o link_const.o \
load_module.o netlist.o netmisc.o net_assign.o \
net_design.o net_event.o net_expr.o net_force.o net_func.o \
net_link.o net_modulo.o net_nex_input.o net_nex_output.o \
net_proc.o net_scope.o net_udp.o pad_to_width.o \
net_proc.o net_scope.o net_udp.o net_variable.o pad_to_width.o \
parse.o parse_misc.o pform.o pform_dump.o \
set_width.o sync.o \
verinum.o verireal.o target.o targets.o \
Attrib.o HName.o LineInfo.o Module.o PDelays.o PEvent.o \
Attrib.o HName.o LineInfo.o Module.o PData.o PDelays.o PEvent.o \
PExpr.o PGate.o \
PTask.o PFunction.o PWire.o Statement.o StringHeap.o \
$(FF) $(TT)

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: Module.h,v 1.27 2002/08/19 02:39:16 steve Exp $"
#ident "$Id: Module.h,v 1.28 2003/01/26 21:15:58 steve Exp $"
#endif
# include <list>
@ -29,6 +29,7 @@
# include "named.h"
# include "LineInfo.h"
# include <string>
class PData;
class PEvent;
class PExpr;
class PEIdent;
@ -97,6 +98,9 @@ class Module : public LineInfo {
/* Keep a table of named events declared in the module. */
map<string,PEvent*>events;
/* Keep a table of datum variables declared in the module. */
map<string,PData*>datum;
/* These are the timescale for this module. The default is
set by the `timescale directive. */
int time_unit, time_precision;
@ -151,6 +155,10 @@ class Module : public LineInfo {
/*
* $Log: Module.h,v $
* Revision 1.28 2003/01/26 21:15:58 steve
* Rework expression parsing and elaboration to
* accommodate real/realtime values and expressions.
*
* Revision 1.27 2002/08/19 02:39:16 steve
* Support parameters with defined ranges.
*

46
PData.cc Normal file
View File

@ -0,0 +1,46 @@
/*
* Copyright (c) 2003 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
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: PData.cc,v 1.1 2003/01/26 21:15:58 steve Exp $"
#endif
# include "PData.h"
PData::PData(const hname_t&h)
: hname_(h)
{
}
PData::~PData()
{
}
const hname_t&PData::name() const
{
return hname_;
}
/*
* $Log: PData.cc,v $
* Revision 1.1 2003/01/26 21:15:58 steve
* Rework expression parsing and elaboration to
* accommodate real/realtime values and expressions.
*
*/

63
PData.h Normal file
View File

@ -0,0 +1,63 @@
#ifndef __PData_H
#define __PData_H
/*
* Copyright (c) 2003 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
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: PData.h,v 1.1 2003/01/26 21:15:58 steve Exp $"
#endif
# include "HName.h"
# include "netlist.h"
# include "LineInfo.h"
/*
* The PData object represents declaration of atomic datum such as
* real and realtime variables. These are variables that cannot be bit
* or part selected, but can be used in expressions.
*/
class PData : public LineInfo {
public:
PData(const hname_t&hname);
~PData();
// Return a hierarchical name.
const hname_t&name() const;
void elaborate_scope(Design*des, NetScope*scope) const;
map<string,PExpr*> attributes;
private:
hname_t hname_;
private:
PData(const PData&);
PData& operator= (const PData&);
};
/*
* $Log: PData.h,v $
* Revision 1.1 2003/01/26 21:15:58 steve
* Rework expression parsing and elaboration to
* accommodate real/realtime values and expressions.
*
*/
#endif

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: PWire.h,v 1.14 2002/08/12 01:34:58 steve Exp $"
#ident "$Id: PWire.h,v 1.15 2003/01/26 21:15:58 steve Exp $"
#endif
# include "netlist.h"
@ -53,7 +53,6 @@ class PWire : public LineInfo {
PWire(char*name, NetNet::Type t, NetNet::PortType pt);
// Return a hierarchical name.
//const string name() const;
const hname_t&path() const;
NetNet::Type get_wire_type() const;
@ -101,6 +100,10 @@ class PWire : public LineInfo {
/*
* $Log: PWire.h,v $
* Revision 1.15 2003/01/26 21:15:58 steve
* Rework expression parsing and elaboration to
* accommodate real/realtime values and expressions.
*
* Revision 1.14 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: design_dump.cc,v 1.135 2002/10/23 01:47:17 steve Exp $"
#ident "$Id: design_dump.cc,v 1.136 2003/01/26 21:15:58 steve Exp $"
#endif
# include "config.h"
@ -447,6 +447,8 @@ void NetAssign_::dump_lval(ostream&o) const
if (bmux_) o << *bmux_;
else o << "**oops**";
o << "]";
} else if (var_) {
o << "<real " << var_->basename() << ">";
} else {
o << "";
}
@ -733,6 +735,11 @@ void NetScope::dump(ostream&o) const
}
}
for (NetVariable*cur = vars_ ; cur ; cur = cur->snext_) {
o << " real " << cur->basename() << " // "
<< cur->get_line() << endl;
}
/* Dump the events in this scope. */
for (NetEvent*cur = events_ ; cur ; cur = cur->snext_) {
o << " event " << cur->name() << "; nprobe="
@ -896,6 +903,11 @@ void NetEConst::dump(ostream&o) const
o << value_;
}
void NetECReal::dump(ostream&o) const
{
o << value_;
}
void NetEScope::dump(ostream&o) const
{
o << "<scope=" << scope_->name() << ">";
@ -975,6 +987,11 @@ void NetEUnary::dump(ostream&o) const
o << ")";
}
void NetEVariable::dump(ostream&o) const
{
o << var_->basename();
}
void Design::dump(ostream&o) const
{
o << "DESIGN TIME PRECISION: 10e" << get_precision() << endl;
@ -1004,6 +1021,10 @@ void Design::dump(ostream&o) const
/*
* $Log: design_dump.cc,v $
* Revision 1.136 2003/01/26 21:15:58 steve
* Rework expression parsing and elaboration to
* accommodate real/realtime values and expressions.
*
* Revision 1.135 2002/10/23 01:47:17 steve
* Fix synth2 handling of aset/aclr signals where
* flip-flops are split by begin-end blocks.

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: dup_expr.cc,v 1.9 2002/11/09 00:25:27 steve Exp $"
#ident "$Id: dup_expr.cc,v 1.10 2003/01/26 21:15:58 steve Exp $"
#endif
# include "config.h"
@ -87,8 +87,18 @@ NetEUnary* NetEUnary::dup_expr() const
return tmp;
}
NetEVariable* NetEVariable::dup_expr() const
{
NetEVariable*tmp = new NetEVariable(var_);
return tmp;
}
/*
* $Log: dup_expr.cc,v $
* Revision 1.10 2003/01/26 21:15:58 steve
* Rework expression parsing and elaboration to
* accommodate real/realtime values and expressions.
*
* Revision 1.9 2002/11/09 00:25:27 steve
* Add dup_expr for user defined function calls.
*

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1999-2000 Stephen Williams (steve@icarus.com)
* Copyright (c) 1999-2003 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,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: elab_expr.cc,v 1.67 2002/12/21 00:55:57 steve Exp $"
#ident "$Id: elab_expr.cc,v 1.68 2003/01/26 21:15:58 steve Exp $"
#endif
# include "config.h"
@ -406,8 +406,9 @@ NetExpr* PEConcat::elaborate_expr(Design*des, NetScope*scope, bool) const
NetExpr* PEFNumber::elaborate_expr(Design*des, NetScope*scope, bool) const
{
long val = value_->as_long();
return new NetEConst(verinum(val));
NetECReal*tmp = new NetECReal(*value_);
tmp->set_line(*this);
return tmp;
}
/*
@ -721,6 +722,15 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
return node;
}
// If the identifier names a variable of some sort, then this
// is a variable reference.
if (NetVariable*var = des->find_variable(scope, path_)) {
NetEVariable*node = new NetEVariable(var);
node->set_line(*this);
return node;
}
// Finally, if this is a scope name, then return that. Look
// first to see if this is a name of a local scope. Failing
// that, search globally for a heirarchical name.
@ -812,10 +822,13 @@ NetExpr* PEUnary::elaborate_expr(Design*des, NetScope*scope, bool) const
case '-':
if (NetEConst*ipc = dynamic_cast<NetEConst*>(ip)) {
/* When taking the - of a number, turn it into a
signed expression and extend it one bit to
accommodate a possible sign bit. */
verinum val = ipc->value();
verinum zero (verinum::V0, val.len(), val.has_len());
verinum zero (verinum::V0, val.len()+1, val.has_len());
val = zero - val;
val.has_sign(ipc->has_sign());
val.has_sign(true);
tmp = new NetEConst(val);
delete ip;
} else {
@ -887,6 +900,10 @@ NetExpr* PEUnary::elaborate_expr(Design*des, NetScope*scope, bool) const
/*
* $Log: elab_expr.cc,v $
* Revision 1.68 2003/01/26 21:15:58 steve
* Rework expression parsing and elaboration to
* accommodate real/realtime values and expressions.
*
* Revision 1.67 2002/12/21 00:55:57 steve
* The $time system task returns the integer time
* scaled to the local units. Change the internal

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: elab_lval.cc,v 1.24 2003/01/19 00:35:39 steve Exp $"
#ident "$Id: elab_lval.cc,v 1.25 2003/01/26 21:15:58 steve Exp $"
#endif
# include "config.h"
@ -138,17 +138,24 @@ NetAssign_* PEConcat::elaborate_lval(Design*des, NetScope*scope) const
/*
* Handle the ident as an l-value. This includes bit and part selects
* of that ident.
*
* XXXX FIXME: The search order looks for signals all the way up the
* scope tree, then looks for memories then variables. It should be
* looking for signals, memories and variables in parallel.
*/
NetAssign_* PEIdent::elaborate_lval(Design*des, NetScope*scope) const
{
/* Get the signal referenced by the identifier, and make sure
it is a register. (Wires are not allows in this context. */
NetNet*reg = des->find_signal(scope, path_);
if (reg == 0) {
NetMemory*mem = des->find_memory(scope, path_);
if (mem != 0)
if (NetMemory*mem = des->find_memory(scope, path_)) {
return elaborate_mem_lval_(des, scope, mem);
}
if (NetVariable*var = des->find_variable(scope, path_)) {
NetAssign_*cur = new NetAssign_(var);
return cur;
}
cerr << get_line() << ": error: Could not find variable ``"
<< path_ << "'' in ``" << scope->name() <<
@ -157,8 +164,11 @@ NetAssign_* PEIdent::elaborate_lval(Design*des, NetScope*scope) const
des->errors += 1;
return 0;
}
assert(reg);
/* Get the signal referenced by the identifier, and make sure
it is a register. (Wires are not allows in this context. */
if (reg->type() != NetNet::REG) {
cerr << get_line() << ": error: " << path_ <<
" is not a reg/integer/time in " << scope->name() <<
@ -337,6 +347,10 @@ NetAssign_* PENumber::elaborate_lval(Design*des, NetScope*) const
/*
* $Log: elab_lval.cc,v $
* Revision 1.25 2003/01/26 21:15:58 steve
* Rework expression parsing and elaboration to
* accommodate real/realtime values and expressions.
*
* Revision 1.24 2003/01/19 00:35:39 steve
* Detect null arguments to concatenation operator.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: elab_scope.cc,v 1.17 2002/10/19 22:59:49 steve Exp $"
#ident "$Id: elab_scope.cc,v 1.18 2003/01/26 21:15:58 steve Exp $"
#endif
# include "config.h"
@ -32,6 +32,7 @@
*/
# include "Module.h"
# include "PData.h"
# include "PEvent.h"
# include "PExpr.h"
# include "PGate.h"
@ -40,6 +41,7 @@
# include "Statement.h"
# include "netlist.h"
# include <typeinfo>
# include <assert.h>
bool Module::elaborate_scope(Design*des, NetScope*scope) const
{
@ -217,6 +219,12 @@ bool Module::elaborate_scope(Design*des, NetScope*scope) const
(*et).second->elaborate_scope(des, scope);
}
for (map<string,PData*>::const_iterator cur = datum.begin()
; cur != datum.end() ; cur ++ ) {
(*cur).second->elaborate_scope(des, scope);
}
return des->errors == 0;
}
@ -341,6 +349,14 @@ void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const
}
}
void PData::elaborate_scope(Design*des, NetScope*scope) const
{
assert(hname_.component_count() == 1);
NetVariable*tmp = new NetVariable(hname_.peek_tail_name());
tmp->set_line(*this);
scope->add_variable(tmp);
}
/*
* The isn't really able to create new scopes, but it does create the
* event name in the current scope, so can be done during the
@ -496,6 +512,10 @@ void PWhile::elaborate_scope(Design*des, NetScope*scope) const
/*
* $Log: elab_scope.cc,v $
* Revision 1.18 2003/01/26 21:15:58 steve
* Rework expression parsing and elaboration to
* accommodate real/realtime values and expressions.
*
* Revision 1.17 2002/10/19 22:59:49 steve
* Redo the parameter vector support to allow
* parameter names in range expressions.

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: elaborate.cc,v 1.268 2003/01/14 21:16:18 steve Exp $"
#ident "$Id: elaborate.cc,v 1.269 2003/01/26 21:15:58 steve Exp $"
#endif
# include "config.h"
@ -926,23 +926,12 @@ NetProc* PAssign::elaborate(Design*des, NetScope*scope) const
delay = elaborate_delay_expr(delay_, des, scope);
/* Elaborate the r-value expression. */
/* Elaborate the r-value expression, then try to evaluate it. */
assert(rval());
NetExpr*rv;
if (verinum*val = rval()->eval_const(des, scope)) {
rv = new NetEConst(*val);
delete val;
} else if (rv = rval()->elaborate_expr(des, scope)) {
/* OK, go on. */
} else {
/* Unable to elaborate expression. Retreat. */
NetExpr*rv = rval()->elaborate_expr(des, scope);
if (rv == 0)
return 0;
}
assert(rv);
@ -1028,10 +1017,15 @@ NetProc* PAssign::elaborate(Design*des, NetScope*scope) const
return bl;
}
{ unsigned wid = count_lval_width(lv);
rv->set_width(wid);
rv = pad_to_width(rv, wid);
assert(rv->expr_width() >= wid);
/* Based on the specific type of the l-value, do cleanup
processing on the r-value. */
if (NetVariable*tmp = lv->var()) {
} else {
unsigned wid = count_lval_width(lv);
rv->set_width(wid);
rv = pad_to_width(rv, wid);
assert(rv->expr_width() >= wid);
}
NetAssign*cur = new NetAssign(lv, rv);
@ -2513,6 +2507,10 @@ Design* elaborate(list<const char*>roots)
/*
* $Log: elaborate.cc,v $
* Revision 1.269 2003/01/26 21:15:58 steve
* Rework expression parsing and elaboration to
* accommodate real/realtime values and expressions.
*
* Revision 1.268 2003/01/14 21:16:18 steve
* Move strstream to ostringstream for compatibility.
*

19
emit.cc
View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: emit.cc,v 1.70 2002/11/03 20:36:10 steve Exp $"
#ident "$Id: emit.cc,v 1.71 2003/01/26 21:15:58 steve Exp $"
#endif
# include "config.h"
@ -312,6 +312,9 @@ void NetScope::emit_scope(struct target_t*tgt) const
for (NetEvent*cur = events_ ; cur ; cur = cur->snext_)
tgt->event(cur);
for (NetVariable*cur = vars_ ; cur ; cur = cur->snext_)
tgt->variable(cur);
for (NetScope*cur = sub_ ; cur ; cur = cur->sib_)
cur->emit_scope(tgt);
@ -411,6 +414,11 @@ void NetEConst::expr_scan(struct expr_scan_t*tgt) const
tgt->expr_const(this);
}
void NetECReal::expr_scan(struct expr_scan_t*tgt) const
{
tgt->expr_creal(this);
}
void NetEMemory::expr_scan(struct expr_scan_t*tgt) const
{
tgt->expr_memory(this);
@ -462,6 +470,11 @@ void NetEUnary::expr_scan(struct expr_scan_t*tgt) const
tgt->expr_unary(this);
}
void NetEVariable::expr_scan(struct expr_scan_t*tgt) const
{
tgt->expr_variable(this);
}
bool emit(const Design*des, const char*type)
{
for (unsigned idx = 0 ; target_table[idx] ; idx += 1) {
@ -479,6 +492,10 @@ bool emit(const Design*des, const char*type)
/*
* $Log: emit.cc,v $
* Revision 1.71 2003/01/26 21:15:58 steve
* Rework expression parsing and elaboration to
* accommodate real/realtime values and expressions.
*
* Revision 1.70 2002/11/03 20:36:10 steve
* Error message for mising code generator type.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: expr_synth.cc,v 1.37 2002/11/17 23:37:55 steve Exp $"
#ident "$Id: expr_synth.cc,v 1.38 2003/01/26 21:15:58 steve Exp $"
#endif
# include "config.h"
@ -452,6 +452,14 @@ NetNet* NetEConst::synthesize(Design*des)
return osig;
}
NetNet* NetECReal::synthesize(Design*des)
{
cerr << get_line() << ": error: Real constants are "
<< "not synthesizeable." << endl;
des->errors += 1;
return 0;
}
/*
* The bitwise unary logic operator (there is only one) is turned
* into discrete gates just as easily as the binary ones above.
@ -635,6 +643,10 @@ NetNet* NetESignal::synthesize(Design*des)
/*
* $Log: expr_synth.cc,v $
* Revision 1.38 2003/01/26 21:15:58 steve
* Rework expression parsing and elaboration to
* accommodate real/realtime values and expressions.
*
* Revision 1.37 2002/11/17 23:37:55 steve
* Magnitude compare to 0.
*

View File

@ -1,7 +1,7 @@
#ifndef __ivl_target_H
#define __ivl_target_H
/*
* Copyright (c) 2000 Stephen Williams (steve@icarus.com)
* Copyright (c) 2000-2003 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
@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: ivl_target.h,v 1.109 2002/12/21 00:55:58 steve Exp $"
#ident "$Id: ivl_target.h,v 1.110 2003/01/26 21:15:58 steve Exp $"
#endif
#ifdef __cplusplus
@ -137,6 +137,7 @@ typedef struct ivl_scope_s *ivl_scope_t;
typedef struct ivl_signal_s *ivl_signal_t;
typedef struct ivl_memory_s *ivl_memory_t;
typedef struct ivl_statement_s*ivl_statement_t;
typedef struct ivl_variable_s *ivl_variable_t;
/*
* These are types that are defined as enumerations. These have
@ -171,7 +172,9 @@ typedef enum ivl_expr_type_e {
IVL_EX_TERNARY,
IVL_EX_UFUNC,
IVL_EX_ULONG,
IVL_EX_UNARY
IVL_EX_UNARY,
IVL_EX_VARIABLE,
IVL_EX_REALNUM
} ivl_expr_type_t;
/* This is the type code for an ivl_net_logic_t object. */
@ -292,6 +295,14 @@ typedef enum ivl_statement_type_e {
IVL_ST_WHILE
} ivl_statement_type_t;
/* This is the type of a variable, and also used as the type for an
expression. */
typedef enum ivl_variable_type_e {
IVL_VT_VOID = 0, /* Not used */
IVL_VT_REAL,
IVL_VT_VECTOR
} ivl_variable_type_t;
/* This is the type of the function to apply to a process. */
typedef int (*ivl_process_f)(ivl_process_t net, void*cd);
@ -416,6 +427,10 @@ extern ivl_nexus_t ivl_event_pos(ivl_event_t net, unsigned idx);
* type, which can affect how some of the other expression methods
* operate on the node
*
* ivl_expr_value
* Get the data type of the expression node. This uses the variable
* type enum to express the type of the expression node.
*
* ivl_expr_width
* This method returns the bit width of the expression at this
* node. It can be applied to any expression node, and returns the
@ -430,14 +445,17 @@ extern ivl_nexus_t ivl_event_pos(ivl_event_t net, unsigned idx);
*/
extern ivl_expr_type_t ivl_expr_type(ivl_expr_t net);
extern ivl_variable_type_t ivl_expr_value(ivl_expr_t net);
/* IVL_EX_NUMBER */
extern const char* ivl_expr_bits(ivl_expr_t net);
/* IVL_EX_UFUNC */
extern ivl_scope_t ivl_expr_def(ivl_expr_t net);
/* IVL_EX_REALNUM */
extern double ivl_expr_dvalue(ivl_expr_t net);
/* IVL_EX_SIGNAL */
extern unsigned ivl_expr_lsi(ivl_expr_t net);
/* IVL_EX_SIGNAL, IVL_EX_SFUNC */
/* IVL_EX_SIGNAL, IVL_EX_SFUNC, IVL_EX_VARIABLE */
extern const char* ivl_expr_name(ivl_expr_t net);
/* IVL_EX_BINARY IVL_EX_UNARY */
extern char ivl_expr_opcode(ivl_expr_t net);
@ -463,6 +481,8 @@ extern int ivl_expr_signed(ivl_expr_t net);
extern const char* ivl_expr_string(ivl_expr_t net);
/* IVL_EX_ULONG */
extern unsigned long ivl_expr_uvalue(ivl_expr_t net);
/* IVL_EX_VARIABLE */
extern ivl_variable_t ivl_expr_variable(ivl_expr_t net);
/* any expression */
extern unsigned ivl_expr_width(ivl_expr_t net);
@ -671,6 +691,12 @@ extern ivl_memory_t ivl_lpm_memory(ivl_lpm_t net);
* If the l-value is a variable, this method returns the signal
* object that is the target of the assign.
*
* ivl_lval_var
* If the l-value is a non-signal variable (i.e. a real) this
* method returns the ivl_variable_t object that represents it.
* If the lval is this sort of variable, then the part_off, idx and
* pin methods do not apply.
*
* ivl_lval_part_off
* The part select of the signal is based here. This is the
* canonical index of bit-0 of the part select.
@ -690,6 +716,7 @@ extern ivl_memory_t ivl_lpm_memory(ivl_lpm_t net);
extern ivl_expr_t ivl_lval_mux(ivl_lval_t net);
extern ivl_expr_t ivl_lval_idx(ivl_lval_t net);
extern ivl_memory_t ivl_lval_mem(ivl_lval_t net);
extern ivl_variable_t ivl_lval_var(ivl_lval_t net);
extern unsigned ivl_lval_part_off(ivl_lval_t net);
extern unsigned ivl_lval_pins(ivl_lval_t net);
extern ivl_nexus_t ivl_lval_pin(ivl_lval_t net, unsigned idx);
@ -825,6 +852,10 @@ extern ivl_signal_t ivl_nexus_ptr_sig(ivl_nexus_ptr_t net);
* ivl_scope_events
* Scopes have 0 or more event objects in them.
*
* ivl_scope_var
* ivl_scope_vars
* Scopes have 0 or more variable objects in them.
*
* ivl_scope_log
* ivl_scope_logs
* Scopes have 0 or more logic devices in them. A logic device is
@ -887,6 +918,8 @@ extern unsigned ivl_scope_lpms(ivl_scope_t net);
extern ivl_lpm_t ivl_scope_lpm(ivl_scope_t, unsigned idx);
extern unsigned ivl_scope_mems(ivl_scope_t net);
extern ivl_memory_t ivl_scope_mem(ivl_scope_t net, unsigned idx);
extern unsigned ivl_scope_vars(ivl_scope_t net);
extern ivl_variable_t ivl_scope_var(ivl_scope_t net, unsigned idx);
extern const char* ivl_scope_name(ivl_scope_t net);
extern const char* ivl_scope_basename(ivl_scope_t net);
extern ivl_scope_t ivl_scope_parent(ivl_scope_t net);
@ -1071,6 +1104,19 @@ extern ivl_expr_t ivl_stmt_rval(ivl_statement_t net);
IVL_ST_WAIT, IVL_ST_WHILE */
extern ivl_statement_t ivl_stmt_sub_stmt(ivl_statement_t net);
/*
* These functions manipulate variable objects.
*
* ivl_variable_name
* Return the base name of the variable.
*
* ivl_variable_type
* Return the type of the variable. The ivl_variable_type_t is an
* enumeration that is defined earlier.
*/
extern const char* ivl_variable_name(ivl_variable_t net);
extern ivl_variable_type_t ivl_variable_type(ivl_variable_t net);
#if defined(__MINGW32__) || defined (__CYGWIN32__)
# define DLLEXPORT __declspec(dllexport)
@ -1097,6 +1143,10 @@ _END_DECL
/*
* $Log: ivl_target.h,v $
* Revision 1.110 2003/01/26 21:15:58 steve
* Rework expression parsing and elaboration to
* accommodate real/realtime values and expressions.
*
* Revision 1.109 2002/12/21 00:55:58 steve
* The $time system task returns the integer time
* scaled to the local units. Change the internal

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: lexor.lex,v 1.74 2002/12/04 02:07:00 steve Exp $"
#ident "$Id: lexor.lex,v 1.75 2003/01/26 21:15:58 steve Exp $"
#endif
# include "config.h"
@ -974,7 +974,8 @@ static verinum*make_sized_dec(const char*txt)
static verinum*make_unsized_dec(const char*txt)
{
return make_dec_with_size(INTEGER_WIDTH, false, txt+1);
verinum*tmp = make_dec_with_size(INTEGER_WIDTH, false, txt+1);
tmp->has_sign(true);
}
/*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: net_assign.cc,v 1.15 2002/08/12 01:34:59 steve Exp $"
#ident "$Id: net_assign.cc,v 1.16 2003/01/26 21:15:58 steve Exp $"
#endif
# include "config.h"
@ -39,7 +39,7 @@ unsigned count_lval_width(const NetAssign_*idx)
}
NetAssign_::NetAssign_(NetNet*s)
: sig_(s), mem_(0), bmux_(0)
: sig_(s), mem_(0), var_(0), bmux_(0)
{
loff_ = 0;
lwid_ = sig_->pin_count();
@ -48,13 +48,21 @@ NetAssign_::NetAssign_(NetNet*s)
}
NetAssign_::NetAssign_(NetMemory*s)
: sig_(0), mem_(s), bmux_(0)
: sig_(0), mem_(s), var_(0), bmux_(0)
{
loff_ = 0;
lwid_ = mem_->width();
more = 0;
}
NetAssign_::NetAssign_(NetVariable*s)
: sig_(0), mem_(0), var_(s), bmux_(0)
{
loff_ = 0;
lwid_ = 0;
more = 0;
}
NetAssign_::~NetAssign_()
{
if (sig_) {
@ -111,6 +119,11 @@ NetMemory* NetAssign_::mem() const
return mem_;
}
NetVariable* NetAssign_::var() const
{
return var_;
}
void NetAssign_::set_part(unsigned lo, unsigned lw)
{
@ -241,6 +254,10 @@ NetAssignNB::~NetAssignNB()
/*
* $Log: net_assign.cc,v $
* Revision 1.16 2003/01/26 21:15:58 steve
* Rework expression parsing and elaboration to
* accommodate real/realtime values and expressions.
*
* Revision 1.15 2002/08/12 01:34:59 steve
* conditional ident string using autoconfig.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: net_design.cc,v 1.31 2003/01/14 21:16:18 steve Exp $"
#ident "$Id: net_design.cc,v 1.32 2003/01/26 21:15:58 steve Exp $"
#endif
# include "config.h"
@ -526,6 +526,30 @@ NetEvent* Design::find_event(NetScope*scope, const hname_t&p)
return 0;
}
NetVariable* Design::find_variable(NetScope*scope, const hname_t&p)
{
hname_t path = p;
assert(scope);
char*key = path.remove_tail_name();
if (path.peek_name(0))
scope = find_scope(scope, path);
while (scope) {
if (NetVariable*ev = scope->find_variable(key)) {
delete key;
return ev;
}
if (scope->type() == NetScope::MODULE)
break;
scope = scope->parent();
}
delete key;
return 0;
}
void Design::add_node(NetNode*net)
{
assert(net->design_ == 0);
@ -601,6 +625,10 @@ void Design::delete_process(NetProcTop*top)
/*
* $Log: net_design.cc,v $
* Revision 1.32 2003/01/26 21:15:58 steve
* Rework expression parsing and elaboration to
* accommodate real/realtime values and expressions.
*
* Revision 1.31 2003/01/14 21:16:18 steve
* Move strstream to ostringstream for compatibility.
*

View File

@ -17,13 +17,18 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: net_expr.cc,v 1.10 2002/11/09 01:40:19 steve Exp $"
#ident "$Id: net_expr.cc,v 1.11 2003/01/26 21:15:58 steve Exp $"
#endif
# include "config.h"
# include "netlist.h"
# include <iostream>
NetExpr::TYPE NetExpr::expr_type() const
{
return ET_VECTOR;
}
/*
* Create an add/sub node from the two operands. Make a best guess of
* the
@ -90,6 +95,79 @@ NetEBAdd* NetEBAdd::dup_expr() const
return result;
}
NetExpr::TYPE NetEBAdd::expr_type() const
{
if (left_->expr_type() == ET_REAL)
return ET_REAL;
if (right_->expr_type() == ET_REAL)
return ET_REAL;
return ET_VECTOR;
}
NetEBDiv::NetEBDiv(char op, NetExpr*l, NetExpr*r)
: NetEBinary(op, l, r)
{
unsigned w = l->expr_width();
if (r->expr_width() > w)
w = r->expr_width();
expr_width(w);
cast_signed(l->has_sign() && r->has_sign());
}
NetEBDiv::~NetEBDiv()
{
}
NetEBDiv* NetEBDiv::dup_expr() const
{
NetEBDiv*result = new NetEBDiv(op_, left_->dup_expr(),
right_->dup_expr());
return result;
}
NetExpr::TYPE NetEBDiv::expr_type() const
{
if (left_->expr_type() == ET_REAL)
return ET_REAL;
if (right_->expr_type() == ET_REAL)
return ET_REAL;
return ET_VECTOR;
}
NetEBMult::NetEBMult(char op, NetExpr*l, NetExpr*r)
: NetEBinary(op, l, r)
{
expr_width(l->expr_width() + r->expr_width());
cast_signed(l->has_sign() && r->has_sign());
}
NetEBMult::~NetEBMult()
{
}
NetEBMult* NetEBMult::dup_expr() const
{
NetEBMult*result = new NetEBMult(op_, left_->dup_expr(),
right_->dup_expr());
return result;
}
NetExpr::TYPE NetEBMult::expr_type() const
{
if (left_->expr_type() == ET_REAL)
return ET_REAL;
if (right_->expr_type() == ET_REAL)
return ET_REAL;
return ET_VECTOR;
}
NetEConcat::NetEConcat(unsigned cnt, NetExpr* r)
: parms_(cnt), repeat_(r)
{
@ -181,6 +259,32 @@ unsigned NetEConcat::repeat() const
return repeat_value_;
}
NetECReal::NetECReal(const verireal&val)
: value_(val)
{
}
NetECReal::~NetECReal()
{
}
const verireal& NetECReal::value() const
{
return value_;
}
NetECReal* NetECReal::dup_expr() const
{
NetECReal*tmp = new NetECReal(value_);
tmp->set_line(*this);
return tmp;
}
NetExpr::TYPE NetECReal::expr_type() const
{
return ET_REAL;
}
NetEParam::NetEParam()
: des_(0), scope_(0)
{
@ -242,6 +346,10 @@ bool NetESelect::set_width(unsigned w)
/*
* $Log: net_expr.cc,v $
* Revision 1.11 2003/01/26 21:15:58 steve
* Rework expression parsing and elaboration to
* accommodate real/realtime values and expressions.
*
* Revision 1.10 2002/11/09 01:40:19 steve
* Postpone parameter width check to evaluation.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: net_nex_input.cc,v 1.7 2002/11/16 05:45:41 steve Exp $"
#ident "$Id: net_nex_input.cc,v 1.8 2003/01/26 21:15:58 steve Exp $"
#endif
# include "config.h"
@ -82,6 +82,11 @@ NexusSet* NetEConst::nex_input()
return new NexusSet;
}
NexusSet* NetECReal::nex_input()
{
return new NexusSet;
}
NexusSet* NetEMemory::nex_input()
{
NexusSet*result = idx_->nex_input();
@ -167,6 +172,11 @@ NexusSet* NetEUnary::nex_input()
return expr_->nex_input();
}
NexusSet* NetEVariable::nex_input()
{
return new NexusSet;
}
NexusSet* NetAssignBase::nex_input()
{
NexusSet*result = rval_->nex_input();
@ -362,6 +372,10 @@ NexusSet* NetWhile::nex_input()
/*
* $Log: net_nex_input.cc,v $
* Revision 1.8 2003/01/26 21:15:58 steve
* Rework expression parsing and elaboration to
* accommodate real/realtime values and expressions.
*
* Revision 1.7 2002/11/16 05:45:41 steve
* Handle default: case in net_inputs for NetCase.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: net_scope.cc,v 1.22 2003/01/14 21:16:18 steve Exp $"
#ident "$Id: net_scope.cc,v 1.23 2003/01/26 21:15:58 steve Exp $"
#endif
# include "config.h"
@ -40,6 +40,7 @@ NetScope::NetScope(NetScope*up, const char*n, NetScope::TYPE t)
memories_ = 0;
signals_ = 0;
events_ = 0;
vars_ = 0;
lcounter_ = 0;
if (up) {
@ -264,6 +265,15 @@ NetEvent* NetScope::find_event(const char*name)
return 0;
}
NetVariable* NetScope::find_variable(const char*name)
{
for (NetVariable*cur = vars_; cur ; cur = cur->snext_)
if (strcmp(cur->basename(), name) == 0)
return cur;
return 0;
}
void NetScope::add_signal(NetNet*net)
{
if (signals_ == 0) {
@ -377,6 +387,14 @@ NetMemory* NetScope::find_memory(const string&key)
return 0;
}
void NetScope::add_variable(NetVariable*var)
{
assert(var->scope_ == 0);
var->scope_ = this;
var->snext_ = vars_;
vars_ = var;
}
/*
* This method locates a child scope by name. The name is the simple
* name of the child, no heirarchy is searched.
@ -432,6 +450,10 @@ string NetScope::local_hsymbol()
/*
* $Log: net_scope.cc,v $
* Revision 1.23 2003/01/26 21:15:58 steve
* Rework expression parsing and elaboration to
* accommodate real/realtime values and expressions.
*
* Revision 1.22 2003/01/14 21:16:18 steve
* Move strstream to ostringstream for compatibility.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: netlist.cc,v 1.203 2002/11/09 00:25:27 steve Exp $"
#ident "$Id: netlist.cc,v 1.204 2003/01/26 21:15:59 steve Exp $"
#endif
# include "config.h"
@ -1827,28 +1827,6 @@ NetEBComp* NetEBComp::dup_expr() const
return result;
}
NetEBDiv::NetEBDiv(char op, NetExpr*l, NetExpr*r)
: NetEBinary(op, l, r)
{
unsigned w = l->expr_width();
if (r->expr_width() > w)
w = r->expr_width();
expr_width(w);
cast_signed(l->has_sign() && r->has_sign());
}
NetEBDiv::~NetEBDiv()
{
}
NetEBDiv* NetEBDiv::dup_expr() const
{
NetEBDiv*result = new NetEBDiv(op_, left_->dup_expr(),
right_->dup_expr());
return result;
}
NetEBinary::NetEBinary(char op, NetExpr*l, NetExpr*r)
: op_(op), left_(l), right_(r)
{
@ -1887,24 +1865,6 @@ NetEBLogic* NetEBLogic::dup_expr() const
return result;
}
NetEBMult::NetEBMult(char op, NetExpr*l, NetExpr*r)
: NetEBinary(op, l, r)
{
expr_width(l->expr_width() + r->expr_width());
cast_signed(l->has_sign() && r->has_sign());
}
NetEBMult::~NetEBMult()
{
}
NetEBMult* NetEBMult::dup_expr() const
{
NetEBMult*result = new NetEBMult(op_, left_->dup_expr(),
right_->dup_expr());
return result;
}
NetEBShift::NetEBShift(char op, NetExpr*l, NetExpr*r)
: NetEBinary(op, l, r)
{
@ -2286,6 +2246,10 @@ const NetProc*NetTaskDef::proc() const
/*
* $Log: netlist.cc,v $
* Revision 1.204 2003/01/26 21:15:59 steve
* Rework expression parsing and elaboration to
* accommodate real/realtime values and expressions.
*
* Revision 1.203 2002/11/09 00:25:27 steve
* Add dup_expr for user defined function calls.
*

111
netlist.h
View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: netlist.h,v 1.271 2002/12/07 02:49:24 steve Exp $"
#ident "$Id: netlist.h,v 1.272 2003/01/26 21:15:59 steve Exp $"
#endif
/*
@ -32,6 +32,7 @@
# include <map>
# include <list>
# include "verinum.h"
# include "verireal.h"
# include "HName.h"
# include "LineInfo.h"
# include "svector.h"
@ -51,6 +52,7 @@ class NetProc;
class NetProcTop;
class NetRelease;
class NetScope;
class NetVariable;
class NetEvProbe;
class NetExpr;
class NetESignal;
@ -923,6 +925,16 @@ class NetExpr : public LineInfo {
virtual void expr_scan(struct expr_scan_t*) const =0;
virtual void dump(ostream&) const;
// Expressions have type. The most common type is ET_VECTOR,
// which is a vector (possibly 1 bit) of 4-value bits. The
// ET_VOID is not generally used.
//
// ET_VOID - No value at all.
// ET_VECTOR - Vector of Verilog 4-value bits
// ET_REAL - real/realtime expression
enum TYPE { ET_VOID=0, ET_VECTOR, ET_REAL };
virtual TYPE expr_type() const;
// How wide am I?
unsigned expr_width() const { return width_; }
@ -1006,6 +1018,31 @@ class NetEConst : public NetExpr {
verinum value_;
};
/*
* This class represents a constant real value.
*/
class NetECReal : public NetExpr {
public:
explicit NetECReal(const verireal&val);
~NetECReal();
const verireal&value() const;
// The type of this expression is ET_REAL
TYPE expr_type() const;
virtual void expr_scan(struct expr_scan_t*) const;
virtual void dump(ostream&) const;
virtual NetECReal* dup_expr() const;
virtual NetNet*synthesize(Design*);
virtual NexusSet* nex_input();
private:
verireal value_;
};
/*
* This is a special, magical NetNet object. It represents a constant
* bit or part select of another NetNet, so is used to return that
@ -1285,6 +1322,7 @@ class NetAssign_ {
public:
NetAssign_(NetNet*sig);
NetAssign_(NetMemory*mem);
NetAssign_(NetVariable*var);
~NetAssign_();
// If this expression exists, then only a single bit is to be
@ -1308,6 +1346,7 @@ class NetAssign_ {
NetNet* sig() const;
NetMemory*mem() const;
NetVariable*var() const;
// This pointer is for keeping simple lists.
NetAssign_* more;
@ -1317,6 +1356,7 @@ class NetAssign_ {
private:
NetNet *sig_;
NetMemory*mem_;
NetVariable*var_;
NetExpr*bmux_;
unsigned loff_;
@ -2044,6 +2084,34 @@ class NetTaskDef {
NetTaskDef& operator= (const NetTaskDef&);
};
/*
* Variable object such as real and realtime are represented by
* instances of this class.
*/
class NetVariable : public LineInfo {
friend class NetScope;
public:
NetVariable(const char* name);
~NetVariable();
const char* basename() const;
NetScope* scope();
const NetScope* scope() const;
private:
char* name_;
NetScope*scope_;
NetVariable*snext_;
private:
NetVariable(const NetVariable&);
NetVariable& operator= (const NetVariable&);
};
/*
* This node represents a function call in an expression. The object
* contains a pointer to the function definition, which is used to
@ -2252,6 +2320,8 @@ class NetEBAdd : public NetEBinary {
NetEBAdd(char op, NetExpr*l, NetExpr*r);
~NetEBAdd();
virtual TYPE expr_type() const;
virtual bool set_width(unsigned w);
virtual NetEBAdd* dup_expr() const;
virtual NetEConst* eval_tree();
@ -2269,6 +2339,8 @@ class NetEBDiv : public NetEBinary {
NetEBDiv(char op, NetExpr*l, NetExpr*r);
~NetEBDiv();
virtual TYPE expr_type() const;
virtual bool set_width(unsigned w);
virtual NetEBDiv* dup_expr() const;
virtual NetEConst* eval_tree();
@ -2370,6 +2442,8 @@ class NetEBMult : public NetEBinary {
NetEBMult(char op, NetExpr*l, NetExpr*r);
~NetEBMult();
virtual TYPE expr_type() const;
virtual bool set_width(unsigned w);
virtual NetEBMult* dup_expr() const;
virtual NetEConst* eval_tree();
@ -2443,6 +2517,29 @@ class NetEConcat : public NetExpr {
bool repeat_calculated_;
};
/*
* This node represents a reference to a variable.
*/
class NetEVariable : public NetExpr {
public:
NetEVariable(NetVariable*);
~NetEVariable();
const NetVariable* variable() const;
TYPE expr_type() const;
void expr_scan(struct expr_scan_t*) const;
void dump(ostream&) const;
NetEVariable*dup_expr() const;
NexusSet* nex_input();
private:
NetVariable*var_;
};
/*
* This clas is a placeholder for a parameter expression. When
* parameters are first created, an instance of this object is used to
@ -2797,6 +2894,10 @@ class NetScope {
void rem_event(NetEvent*);
NetEvent*find_event(const char*name);
void add_variable(NetVariable*);
void rem_variable(NetVariable*);
NetVariable*find_variable(const char*name);
/* These methods manage signals. The add_ and rem_signal
methods are used by the NetNet objects to make themselves
@ -2900,6 +3001,7 @@ class NetScope {
map<string,param_expr_t>localparams_;
NetEvent *events_;
NetVariable*vars_;
NetNet *signals_;
NetMemory*memories_;
@ -2999,6 +3101,9 @@ class Design {
// Events
NetEvent* find_event(NetScope*scope, const hname_t&path);
// Variables
NetVariable* find_variable(NetScope*scope, const hname_t&path);
// NODES
void add_node(NetNode*);
void del_node(NetNode*);
@ -3085,6 +3190,10 @@ extern ostream& operator << (ostream&, NetNet::Type);
/*
* $Log: netlist.h,v $
* Revision 1.272 2003/01/26 21:15:59 steve
* Rework expression parsing and elaboration to
* accommodate real/realtime values and expressions.
*
* Revision 1.271 2002/12/07 02:49:24 steve
* Named event triggers can take hierarchical names.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: pad_to_width.cc,v 1.11 2002/08/12 01:35:00 steve Exp $"
#ident "$Id: pad_to_width.cc,v 1.12 2003/01/26 21:15:59 steve Exp $"
#endif
# include "config.h"
@ -40,13 +40,17 @@ NetExpr*pad_to_width(NetExpr*expr, unsigned wid)
const. This is a more efficient result. */
if (NetEConst*tmp = dynamic_cast<NetEConst*>(expr)) {
verinum eval = tmp->value();
bool signed_flag = eval.has_sign();
verinum::V pad = verinum::V0;
if (signed_flag)
pad = eval.get(eval.len()-1);
verinum oval (pad, wid, eval.has_len());
for (unsigned idx = 0 ; idx < eval.len() ; idx += 1)
oval.set(idx, eval.get(idx));
oval.has_sign(signed_flag);
tmp = new NetEConst(oval);
delete expr;
return tmp;
@ -95,6 +99,10 @@ NetNet*pad_to_width(Design*des, NetNet*net, unsigned wid)
/*
* $Log: pad_to_width.cc,v $
* Revision 1.12 2003/01/26 21:15:59 steve
* Rework expression parsing and elaboration to
* accommodate real/realtime values and expressions.
*
* Revision 1.11 2002/08/12 01:35:00 steve
* conditional ident string using autoconfig.
*

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.169 2003/01/17 05:48:02 steve Exp $"
#ident "$Id: parse.y,v 1.170 2003/01/26 21:15:59 steve Exp $"
#endif
# include "config.h"
@ -301,12 +301,10 @@ block_item_decl
{ pform_set_reg_time($2);
}
| K_real list_of_identifiers ';'
{ delete $2;
yyerror(@1, "sorry: real variables not supported.");
{ pform_make_reals($2, @1.text, @1.first_line);
}
| K_realtime list_of_identifiers ';'
{ delete $2;
yyerror(@1, "sorry: realtime variables not supported.");
{ pform_make_reals($2, @1.text, @1.first_line);
}
| K_parameter parameter_assign_decl ';'
| K_localparam localparam_assign_list ';'

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: pform.cc,v 1.106 2003/01/17 05:47:30 steve Exp $"
#ident "$Id: pform.cc,v 1.107 2003/01/26 21:15:59 steve Exp $"
#endif
# include "config.h"
@ -26,6 +26,7 @@
# include "pform.h"
# include "parse_misc.h"
# include "parse_api.h"
# include "PData.h"
# include "PEvent.h"
# include "PUdp.h"
# include <list>
@ -557,6 +558,26 @@ void pform_make_events(list<char*>*names, const char*fn, unsigned ln)
delete names;
}
static void pform_make_datum(const char*name, const char*fn, unsigned ln)
{
PData*datum = new PData(hname_t(name));
datum->set_file(fn);
datum->set_lineno(ln);
pform_cur_module->datum[name] = datum;
}
void pform_make_reals(list<char*>*names, const char*fn, unsigned ln)
{
list<char*>::iterator cur;
for (cur = names->begin() ; cur != names->end() ; cur++) {
char*txt = *cur;
pform_make_datum(txt, fn, ln);
free(txt);
}
delete names;
}
/*
* pform_makegates is called when a list of gates (with the same type)
* are ready to be instantiated. The function runs through the list of
@ -1372,6 +1393,10 @@ int pform_parse(const char*path, FILE*file)
/*
* $Log: pform.cc,v $
* Revision 1.107 2003/01/26 21:15:59 steve
* Rework expression parsing and elaboration to
* accommodate real/realtime values and expressions.
*
* Revision 1.106 2003/01/17 05:47:30 steve
* Missed a case of setting line on an PEident.
*

11
pform.h
View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: pform.h,v 1.64 2002/09/01 03:01:48 steve Exp $"
#ident "$Id: pform.h,v 1.65 2003/01/26 21:15:59 steve Exp $"
#endif
# include "netlist.h"
@ -216,6 +216,11 @@ extern bool pform_expression_is_constant(const PExpr*);
extern void pform_make_events(list<char*>*names,
const char*file, unsigned lineno);
/*
* Make real datum objects.
*/
extern void pform_make_reals(list<char*>*names,
const char*file, unsigned lineno);
/*
* The makegate function creates a new gate (which need not have a
@ -259,6 +264,10 @@ extern void pform_dump(ostream&out, Module*mod);
/*
* $Log: pform.h,v $
* Revision 1.65 2003/01/26 21:15:59 steve
* Rework expression parsing and elaboration to
* accommodate real/realtime values and expressions.
*
* Revision 1.64 2002/09/01 03:01:48 steve
* Properly cast signedness of parameters with ranges.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: pform_dump.cc,v 1.77 2002/10/19 22:59:49 steve Exp $"
#ident "$Id: pform_dump.cc,v 1.78 2003/01/26 21:15:59 steve Exp $"
#endif
# include "config.h"
@ -29,6 +29,7 @@
* module in question.
*/
# include "pform.h"
# include "PData.h"
# include "PEvent.h"
# include <iostream>
# include <iomanip>
@ -753,6 +754,13 @@ void Module::dump(ostream&out) const
<< ev->get_line() << endl;
}
for (map<string,PData*>::const_iterator cur = datum.begin()
; cur != datum.end() ; cur ++ ) {
PData*tmp = (*cur).second;
out << " real " << tmp->name() << "; // "
<< tmp->get_line() << endl;
}
// Iterate through and display all the wires.
for (map<hname_t,PWire*>::const_iterator wire = wires_.begin()
; wire != wires_.end()
@ -848,6 +856,10 @@ void PUdp::dump(ostream&out) const
/*
* $Log: pform_dump.cc,v $
* Revision 1.78 2003/01/26 21:15:59 steve
* Rework expression parsing and elaboration to
* accommodate real/realtime values and expressions.
*
* Revision 1.77 2002/10/19 22:59:49 steve
* Redo the parameter vector support to allow
* parameter names in range expressions.
@ -890,235 +902,5 @@ void PUdp::dump(ostream&out) const
* Revision 1.68 2001/12/03 04:47:15 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
*
* Revision 1.67 2001/07/25 03:10:49 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
*
* Revision 1.66 2001/01/13 22:20:08 steve
* Parse parameters within nested scopes.
*
* Revision 1.65 2000/12/11 00:31:43 steve
* Add support for signed reg variables,
* simulate in t-vvm signed comparisons.
*
* Revision 1.64 2000/12/10 22:01:36 steve
* Support decimal constants in behavioral delays.
*
* Revision 1.63 2000/11/11 01:52:09 steve
* change set for support of nmos, pmos, rnmos, rpmos, notif0, and notif1
* change set to correct behavior of bufif0 and bufif1
* (Tim Leight)
*
* Also includes fix for PR#27
*
* Revision 1.62 2000/10/14 02:23:02 steve
* Check for missing concat subexpressions (PR#11)
*
* Revision 1.61 2000/07/26 05:08:07 steve
* Parse disable statements to pform.
*
* Revision 1.60 2000/05/23 16:03:13 steve
* Better parsing of expressions lists will empty expressoins.
*
* Revision 1.59 2000/05/16 04:05:16 steve
* Module ports are really special PEIdent
* expressions, because a name can be used
* many places in the port list.
*
* Revision 1.58 2000/05/11 23:37:27 steve
* Add support for procedural continuous assignment.
*
* Revision 1.57 2000/05/06 15:41:57 steve
* Carry assignment strength to pform.
*
* Revision 1.56 2000/05/04 03:37:59 steve
* Add infrastructure for system functions, move
* $time to that structure and add $random.
*
* Revision 1.55 2000/04/22 04:20:19 steve
* Add support for force assignment.
*
* Revision 1.54 2000/04/12 20:02:53 steve
* Finally remove the NetNEvent and NetPEvent classes,
* Get synthesis working with the NetEvWait class,
* and get started supporting multiple events in a
* wait in vvm.
*
* Revision 1.53 2000/04/12 04:23:58 steve
* Named events really should be expressed with PEIdent
* objects in the pform,
*
* Handle named events within the mix of net events
* and edges. As a unified lot they get caught together.
* wait statements are broken into more complex statements
* that include a conditional.
*
* Do not generate NetPEvent or NetNEvent objects in
* elaboration. NetEvent, NetEvWait and NetEvProbe
* take over those functions in the netlist.
*
* Revision 1.52 2000/04/01 19:31:57 steve
* Named events as far as the pform.
*
* Revision 1.51 2000/03/12 17:09:41 steve
* Support localparam.
*
* Revision 1.50 2000/03/08 04:36:54 steve
* Redesign the implementation of scopes and parameters.
* I now generate the scopes and notice the parameters
* in a separate pass over the pform. Once the scopes
* are generated, I can process overrides and evalutate
* paremeters before elaboration begins.
*
* Revision 1.49 2000/02/23 02:56:55 steve
* Macintosh compilers do not support ident.
*
* Revision 1.48 2000/02/18 05:15:03 steve
* Catch module instantiation arrays.
*
* Revision 1.47 2000/01/09 20:37:57 steve
* Careful with wires connected to multiple ports.
*
* Revision 1.46 2000/01/09 05:50:49 steve
* Support named parameter override lists.
*
* Revision 1.45 1999/10/10 01:59:55 steve
* Structural case equals device.
*
* Revision 1.44 1999/09/30 02:43:02 steve
* Elaborate ~^ and ~| operators.
*
* Revision 1.43 1999/09/30 00:48:50 steve
* Cope with errors during ternary operator elaboration.
*
* Revision 1.42 1999/09/29 21:15:58 steve
* Handle some mor missing names.
*
* Revision 1.41 1999/09/29 20:23:53 steve
* Handle empty named ports in the dump.
*
* Revision 1.40 1999/09/29 18:36:04 steve
* Full case support
*
* Revision 1.39 1999/09/17 02:06:26 steve
* Handle unconnected module ports.
*
* Revision 1.38 1999/09/08 02:24:39 steve
* Empty conditionals (pmonta@imedia.com)
*
* 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.
*
* Revision 1.35 1999/08/23 16:48:39 steve
* Parameter overrides support from Peter Monta
* AND and XOR support wide expressions.
*
* Revision 1.34 1999/08/03 04:49:13 steve
* Proper port type names.
*
* Revision 1.33 1999/08/03 04:14:49 steve
* Parse into pform arbitrarily complex module
* port declarations.
*
* Revision 1.32 1999/08/01 16:34:50 steve
* Parse and elaborate rise/fall/decay times
* for gates, and handle the rules for partial
* lists of times.
*
* Revision 1.31 1999/07/31 19:14:47 steve
* Add functions up to elaboration (Ed Carter)
*
* Revision 1.30 1999/07/30 00:43:17 steve
* Handle dumping tasks with no ports.
*
* Revision 1.29 1999/07/24 02:11:20 steve
* Elaborate task input ports.
*
* Revision 1.28 1999/07/17 19:51:00 steve
* netlist support for ternary operator.
*
* Revision 1.27 1999/07/12 00:59:36 steve
* procedural blocking assignment delays.
*
* Revision 1.26 1999/07/03 02:12:52 steve
* Elaborate user defined tasks.
*
* Revision 1.25 1999/06/24 04:24:18 steve
* Handle expression widths for EEE and NEE operators,
* add named blocks and scope handling,
* add registers declared in named blocks.
*
* Revision 1.24 1999/06/19 21:06:16 steve
* Elaborate and supprort to vvm the forever
* and repeat statements.
*
* Revision 1.23 1999/06/17 05:34:42 steve
* Clean up interface of the PWire class,
* Properly match wire ranges.
*
* Revision 1.22 1999/06/15 05:38:39 steve
* Support case expression lists.
*
* Revision 1.21 1999/06/15 03:44:53 steve
* Get rid of the STL vector template.
*
* Revision 1.20 1999/06/13 23:51:16 steve
* l-value part select for procedural assignments.
*
* Revision 1.19 1999/06/10 04:03:53 steve
* Add support for the Ternary operator,
* Add support for repeat concatenation,
* Correct some seg faults cause by elaboration
* errors,
* Parse the casex anc casez statements.
*
* Revision 1.18 1999/06/06 20:45:39 steve
* Add parse and elaboration of non-blocking assignments,
* Replace list<PCase::Item*> with an svector version,
* Add integer support.
*
* Revision 1.17 1999/05/29 02:36:17 steve
* module parameter bind by name.
*
* Revision 1.16 1999/05/10 00:16:58 steve
* Parse and elaborate the concatenate operator
* in structural contexts, Replace vector<PExpr*>
* and list<PExpr*> with svector<PExpr*>, evaluate
* constant expressions with parameters, handle
* memories as lvalues.
*
* Parse task declarations, integer types.
*
* Revision 1.15 1999/05/05 03:04:46 steve
* Fix handling of null delay statements.
*
* Revision 1.14 1999/05/01 02:57:53 steve
* Handle much more complex event expressions.
*
* Revision 1.13 1999/04/29 02:16:26 steve
* Parse OR of event expressions.
*
* Revision 1.12 1999/04/19 01:59:37 steve
* Add memories to the parse and elaboration phases.
*
* Revision 1.11 1999/02/21 17:01:57 steve
* Add support for module parameters.
*
* Revision 1.10 1999/02/15 02:06:15 steve
* Elaborate gate ranges.
*
* Revision 1.9 1999/02/03 04:20:11 steve
* Parse and elaborate the Verilog CASE statement.
*
* Revision 1.8 1999/02/01 00:26:49 steve
* Carry some line info to the netlist,
* Dump line numbers for processes.
* Elaborate prints errors about port vector
* width mismatch
* Emit better handles null statements.
*/

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: t-dll-api.cc,v 1.89 2002/12/21 00:55:58 steve Exp $"
#ident "$Id: t-dll-api.cc,v 1.90 2003/01/26 21:15:59 steve Exp $"
#endif
# include "config.h"
@ -218,6 +218,12 @@ extern "C" ivl_scope_t ivl_expr_def(ivl_expr_t net)
return 0;
}
extern "C" double ivl_expr_dvalue(ivl_expr_t net)
{
assert(net->type_ == IVL_EX_REALNUM);
return net->u_.real_.value;
}
extern "C" unsigned ivl_expr_lsi(ivl_expr_t net)
{
switch (net->type_) {
@ -242,6 +248,9 @@ extern "C" const char* ivl_expr_name(ivl_expr_t net)
case IVL_EX_SIGNAL:
return net->u_.signal_.sig->name_;
case IVL_EX_VARIABLE:
return net->u_.variable_.var->name;
default:
assert(0);
}
@ -414,6 +423,12 @@ extern "C" unsigned long ivl_expr_uvalue(ivl_expr_t net)
return net->u_.ulong_.value;
}
extern "C" ivl_variable_type_t ivl_expr_value(ivl_expr_t net)
{
assert(net);
return net->value_;
}
extern "C" unsigned ivl_expr_width(ivl_expr_t net)
{
assert(net);
@ -426,6 +441,12 @@ extern "C" ivl_memory_t ivl_expr_memory(ivl_expr_t net)
return net->u_.memory_.mem_;
}
extern "C" ivl_variable_t ivl_expr_variable(ivl_expr_t net)
{
assert(net->type_ == IVL_EX_VARIABLE);
return net->u_.variable_.var;
}
extern "C" const char* ivl_logic_attr(ivl_net_logic_t net, const char*key)
{
assert(net);
@ -899,6 +920,14 @@ extern "C" ivl_memory_t ivl_lval_mem(ivl_lval_t net)
return 0x0;
}
extern "C" ivl_variable_t ivl_lval_var(ivl_lval_t net)
{
assert(net);
if (net->type_ == IVL_LVAL_VAR)
return net->n.var;
return 0x0;
}
extern "C" unsigned ivl_lval_part_off(ivl_lval_t net)
{
assert(net);
@ -1079,6 +1108,19 @@ extern "C" ivl_event_t ivl_scope_event(ivl_scope_t net, unsigned idx)
return net->event_[idx];
}
extern "C" unsigned ivl_scope_vars(ivl_scope_t net)
{
assert(net);
return net->nvar_;
}
extern "C" ivl_variable_t ivl_scope_var(ivl_scope_t net, unsigned idx)
{
assert(net);
assert(idx < net->nvar_);
return net->var_[idx];
}
extern "C" unsigned ivl_scope_logs(ivl_scope_t net)
{
assert(net);
@ -1484,6 +1526,9 @@ extern "C" unsigned ivl_stmt_lwidth(ivl_statement_t net)
case IVL_LVAL_MEM:
sum += ivl_memory_width(ivl_lval_mem(cur));
break;
case IVL_LVAL_VAR:
sum += 0;
break;
default:
assert(0);
}
@ -1589,8 +1634,24 @@ extern "C" ivl_statement_t ivl_stmt_sub_stmt(ivl_statement_t net)
return 0;
}
extern "C" const char* ivl_variable_name(ivl_variable_t net)
{
assert(net);
return net->name;
}
extern "C" ivl_variable_type_t ivl_variable_type(ivl_variable_t net)
{
assert(net);
return net->type;
}
/*
* $Log: t-dll-api.cc,v $
* Revision 1.90 2003/01/26 21:15:59 steve
* Rework expression parsing and elaboration to
* accommodate real/realtime values and expressions.
*
* Revision 1.89 2002/12/21 00:55:58 steve
* The $time system task returns the integer time
* scaled to the local units. Change the internal
@ -1634,278 +1695,5 @@ extern "C" ivl_statement_t ivl_stmt_sub_stmt(ivl_statement_t net)
*
* Revision 1.79 2002/05/24 04:36:23 steve
* Verilog 2001 attriubtes on nets/wires.
*
* Revision 1.78 2002/05/23 03:08:51 steve
* Add language support for Verilog-2001 attribute
* syntax. Hook this support into existing $attribute
* handling, and add number and void value types.
*
* Add to the ivl_target API new functions for access
* of complex attributes attached to gates.
*
* Revision 1.77 2002/03/17 19:30:47 steve
* Add API to support user defined function.
*
* Revision 1.76 2002/03/09 02:10:22 steve
* Add the NetUserFunc netlist node.
*
* Revision 1.75 2002/01/28 00:52:41 steve
* Add support for bit select of parameters.
* This leads to a NetESelect node and the
* vvp code generator to support that.
*
* Revision 1.74 2002/01/03 04:19:01 steve
* Add structural modulus support down to vvp.
*
* Revision 1.73 2001/12/06 03:11:00 steve
* Add ivl_logic_delay function to ivl_target.
*
* Revision 1.72 2001/11/14 03:28:49 steve
* DLL target support for force and release.
*
* Revision 1.71 2001/11/01 04:25:31 steve
* ivl_target support for cassign.
*
* Revision 1.70 2001/10/31 05:24:52 steve
* ivl_target support for assign/deassign.
*
* Revision 1.69 2001/10/19 21:53:24 steve
* Support multiple root modules (Philip Blundell)
*
* Revision 1.68 2001/10/16 02:19:27 steve
* Support IVL_LPM_DIVIDE for structural divide.
*
* Revision 1.67 2001/09/16 22:19:42 steve
* Support attributes to logic gates.
*
* Revision 1.66 2001/09/01 01:57:31 steve
* Make constants available through the design root
*
* Revision 1.65 2001/08/31 22:58:40 steve
* Support DFF CE inputs.
*
* Revision 1.64 2001/08/28 04:07:18 steve
* Add some ivl_target convenience functions.
*
* Revision 1.63 2001/08/25 23:50:03 steve
* Change the NetAssign_ class to refer to the signal
* instead of link into the netlist. This is faster
* and uses less space. Make the NetAssignNB carry
* the delays instead of the NetAssign_ lval objects.
*
* Change the vvp code generator to support multiple
* l-values, i.e. concatenations of part selects.
*
* Revision 1.62 2001/08/10 00:40:45 steve
* tgt-vvp generates code that skips nets as inputs.
*
* Revision 1.61 2001/07/28 01:17:40 steve
* Support getting the signal from IVL_EX_SIGNAL expressions.
*
* Revision 1.60 2001/07/27 04:51:44 steve
* Handle part select expressions as variants of
* NetESignal/IVL_EX_SIGNAL objects, instead of
* creating new and useless temporary signals.
*
* Revision 1.59 2001/07/27 02:41:55 steve
* Fix binding of dangling function ports. do not elide them.
*
* Revision 1.58 2001/07/25 03:10:49 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
*
* Revision 1.57 2001/07/22 00:17:49 steve
* Support the NetESubSignal expressions in vvp.tgt.
*
* Revision 1.56 2001/07/19 04:55:06 steve
* Support calculated delays in vvp.tgt.
*
* Revision 1.55 2001/07/07 20:20:10 steve
* Pass parameters to system functions.
*
* Revision 1.54 2001/07/07 03:01:37 steve
* Detect and make available to t-dll the right shift.
*
* Revision 1.53 2001/07/04 22:59:25 steve
* handle left shifter in dll output.
*
* Revision 1.52 2001/06/30 23:03:16 steve
* support fast programming by only writing the bits
* that are listed in the input file.
*
* Revision 1.51 2001/06/16 23:45:05 steve
* Add support for structural multiply in t-dll.
* Add code generators and vvp support for both
* structural and behavioral multiply.
*
* Revision 1.50 2001/06/16 02:41:41 steve
* Generate code to support memory access in continuous
* assignment statements. (Stephan Boettcher)
*
* Revision 1.49 2001/06/15 04:14:19 steve
* Generate vvp code for GT and GE comparisons.
*
* Revision 1.48 2001/06/07 03:09:37 steve
* support subtraction in tgt-vvp.
*
* Revision 1.47 2001/06/07 02:12:43 steve
* Support structural addition.
*
* Revision 1.46 2001/05/20 01:06:16 steve
* stub ivl_expr_parms for sfunctions.
*
* Revision 1.45 2001/05/17 04:37:02 steve
* Behavioral ternary operators for vvp.
*
* Revision 1.44 2001/05/08 23:59:33 steve
* Add ivl and vvp.tgt support for memories in
* expressions and l-values. (Stephan Boettcher)
*
* Revision 1.43 2001/05/06 17:48:20 steve
* Support memory objects. (Stephan Boettcher)
*
* Revision 1.42 2001/04/29 23:17:38 steve
* Carry drive strengths in the ivl_nexus_ptr_t, and
* handle constant devices in targets.'
*
* Revision 1.41 2001/04/26 05:12:02 steve
* Implement simple MUXZ for ?: operators.
*
* Revision 1.40 2001/04/22 23:09:46 steve
* More UDP consolidation from Stephan Boettcher.
*
* Revision 1.39 2001/04/21 00:55:46 steve
* Generate code for disable.
*
* Revision 1.38 2001/04/15 02:58:11 steve
* vvp support for <= with internal delay.
*
* Revision 1.37 2001/04/06 02:28:02 steve
* Generate vvp code for functions with ports.
*
* Revision 1.36 2001/04/05 03:20:57 steve
* Generate vvp code for the repeat statement.
*
* Revision 1.35 2001/04/05 01:12:28 steve
* Get signed compares working correctly in vvp.
*
* Revision 1.34 2001/04/04 04:50:35 steve
* Support forever loops in the tgt-vvp target.
*
* Revision 1.33 2001/04/03 04:50:37 steve
* Support non-blocking assignments.
*
* Revision 1.32 2001/04/02 02:28:12 steve
* Generate code for task calls.
*
* Revision 1.31 2001/04/02 00:28:35 steve
* Support the scope expression node.
*
* Revision 1.30 2001/04/01 06:52:27 steve
* support the NetWhile statement.
*
* Revision 1.29 2001/04/01 01:48:21 steve
* Redesign event information to support arbitrary edge combining.
*
* Revision 1.28 2001/03/31 17:36:38 steve
* Generate vvp code for case statements.
*
* Revision 1.27 2001/03/30 05:49:52 steve
* Generate code for fork/join statements.
*
* Revision 1.26 2001/03/29 03:47:38 steve
* Behavioral trigger statements.
*
* Revision 1.25 2001/03/29 02:52:39 steve
* Add unary ~ operator to tgt-vvp.
*
* Revision 1.24 2001/03/28 06:07:39 steve
* Add the ivl_event_t to ivl_target, and use that to generate
* .event statements in vvp way ahead of the thread that uses it.
*
* Revision 1.23 2001/03/27 06:27:40 steve
* Generate code for simple @ statements.
*
* Revision 1.22 2001/03/20 01:44:13 steve
* Put processes in the proper scope.
*
* Revision 1.21 2001/01/15 00:47:02 steve
* Pass scope type information to the target module.
*
* Revision 1.20 2001/01/15 00:05:39 steve
* Add client data pointer for scope and process scanners.
*
* Revision 1.19 2000/12/05 06:29:33 steve
* Make signal attributes available to ivl_target API.
*
* Revision 1.18 2000/11/12 17:47:29 steve
* flip-flop pins for ivl_target API.
*
* Revision 1.17 2000/11/11 00:03:36 steve
* Add support for the t-dll backend grabing flip-flops.
*
* Revision 1.16 2000/10/28 22:32:34 steve
* API for concatenation expressions.
*
* Revision 1.15 2000/10/25 05:41:24 steve
* Get target signal from nexus_ptr.
*
* Revision 1.14 2000/10/18 20:04:39 steve
* Add ivl_lval_t and support for assignment l-values.
*
* Revision 1.13 2000/10/16 22:44:54 steve
* Stubs so that cygwin port will link ivl.
*
* Revision 1.12 2000/10/15 04:46:23 steve
* Scopes and processes are accessible randomly from
* the design, and signals and logic are accessible
* from scopes. Remove the target calls that are no
* longer needed.
*
* Add the ivl_nexus_ptr_t and the means to get at
* them from nexus objects.
*
* Give names to methods that manipulate the ivl_design_t
* type more consistent names.
*
* Revision 1.11 2000/10/08 04:01:54 steve
* Back pointers in the nexus objects into the devices
* that point to it.
*
* Collect threads into a list in the design.
*
* Revision 1.10 2000/10/06 23:46:50 steve
* ivl_target updates, including more complete
* handling of ivl_nexus_t objects. Much reduced
* dependencies on pointers to netlist objects.
*
* Revision 1.9 2000/10/05 05:03:01 steve
* xor and constant devices.
*
* Revision 1.8 2000/09/30 02:18:15 steve
* ivl_expr_t support for binary operators,
* Create a proper ivl_scope_t object.
*
* Revision 1.7 2000/09/26 00:30:07 steve
* Add EX_NUMBER and ST_TRIGGER to dll-api.
*
* Revision 1.6 2000/09/24 15:46:00 steve
* API access to signal type and port type.
*
* Revision 1.5 2000/09/24 02:21:53 steve
* Add support for signal expressions.
*
* Revision 1.4 2000/09/23 05:15:07 steve
* Add enough tgt-verilog code to support hello world.
*
* Revision 1.3 2000/09/22 03:58:30 steve
* Access to the name of a system task call.
*
* Revision 1.2 2000/09/19 04:15:27 steve
* Introduce the means to get statement types.
*
* Revision 1.1 2000/09/18 01:24:32 steve
* Get the structure for ivl_statement_t worked out.
*
*/

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: t-dll-expr.cc,v 1.29 2002/10/23 01:47:17 steve Exp $"
#ident "$Id: t-dll-expr.cc,v 1.30 2003/01/26 21:15:59 steve Exp $"
#endif
# include "config.h"
@ -32,6 +32,26 @@
#endif
# include <stdlib.h>
/*
* This is a little convenience function for converting a NetExpr
* expresion type to the expression type used by ivl_expr_t objects.
*/
static ivl_variable_type_t get_expr_type(const NetExpr*net)
{
switch (net->expr_type()) {
case NetExpr::ET_VOID:
return IVL_VT_VOID;
case NetExpr::ET_REAL:
return IVL_VT_REAL;
case NetExpr::ET_VECTOR:
return IVL_VT_VECTOR;
}
return IVL_VT_VOID;
}
/*
* These methods implement the expression scan that generates the
* ivl_expr_t representing the expression. Each method leaves the
@ -50,6 +70,7 @@ void dll_target::sub_off_from_expr_(long off)
char*bits;
ivl_expr_t tmpc = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s));
tmpc->type_ = IVL_EX_NUMBER;
tmpc->value_ = IVL_VT_VECTOR;
tmpc->width_ = expr_->width_;
tmpc->signed_ = expr_->signed_;
tmpc->u_.number_.bits_ = bits = (char*)malloc(tmpc->width_);
@ -63,6 +84,7 @@ void dll_target::sub_off_from_expr_(long off)
the constant to subtract. */
ivl_expr_t tmps = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s));
tmps->type_ = IVL_EX_BINARY;
tmps->value_ = IVL_VT_VECTOR;
tmps->width_ = tmpc->width_;
tmps->signed_ = tmpc->signed_;
tmps->u_.binary_.op_ = '-';
@ -80,6 +102,7 @@ void dll_target::mul_expr_by_const_(long val)
char*bits;
ivl_expr_t tmpc = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s));
tmpc->type_ = IVL_EX_NUMBER;
tmpc->value_ = IVL_VT_VECTOR;
tmpc->width_ = expr_->width_;
tmpc->signed_ = expr_->signed_;
tmpc->u_.number_.bits_ = bits = (char*)malloc(tmpc->width_);
@ -93,6 +116,7 @@ void dll_target::mul_expr_by_const_(long val)
the constant to subtract. */
ivl_expr_t tmps = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s));
tmps->type_ = IVL_EX_BINARY;
tmps->value_ = IVL_VT_VECTOR;
tmps->width_ = tmpc->width_;
tmps->signed_ = tmpc->signed_;
tmps->u_.binary_.op_ = '*';
@ -111,6 +135,7 @@ ivl_expr_t dll_target::expr_from_value_(const verinum&val)
unsigned idx;
char*bits;
expr->type_ = IVL_EX_NUMBER;
expr->value_= IVL_VT_VECTOR;
expr->width_= val.len();
expr->signed_ = val.has_sign()? 1 : 0;
expr->u_.number_.bits_ = bits = (char*)malloc(expr->width_);
@ -150,6 +175,7 @@ void dll_target::expr_binary(const NetEBinary*net)
assert(expr_);
expr_->type_ = IVL_EX_BINARY;
expr_->value_= get_expr_type(net);
expr_->width_= net->expr_width();
expr_->signed_ = net->has_sign()? 1 : 0;
@ -165,8 +191,9 @@ void dll_target::expr_concat(const NetEConcat*net)
ivl_expr_t cur = new struct ivl_expr_s;
assert(cur);
cur->type_ = IVL_EX_CONCAT;
cur->width_= net->expr_width();
cur->type_ = IVL_EX_CONCAT;
cur->value_ = IVL_VT_VECTOR;
cur->width_ = net->expr_width();
cur->u_.concat_.rept = net->repeat();
cur->u_.concat_.parms = net->nparms();
@ -194,6 +221,7 @@ void dll_target::expr_memory(const NetEMemory*net)
assert(cur);
cur->type_ = IVL_EX_MEMORY;
cur->value_ = IVL_VT_VECTOR;
cur->width_= net->expr_width();
cur->signed_ = net->has_sign()? 1 : 0;
cur->u_.memory_.mem_ = find_memory(des_, net->memory());
@ -210,6 +238,7 @@ void dll_target::expr_const(const NetEConst*net)
expr_ = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s));
assert(expr_);
expr_->value_= IVL_VT_VECTOR;
if (net->value().is_string()) {
expr_->type_ = IVL_EX_STRING;
@ -245,6 +274,17 @@ void dll_target::expr_const(const NetEConst*net)
}
}
void dll_target::expr_creal(const NetECReal*net)
{
assert(expr_ == 0);
expr_ = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s));
expr_->width_ = net->expr_width();
expr_->signed_ = 1;
expr_->type_ = IVL_EX_REALNUM;
expr_->value_= IVL_VT_REAL;
expr_->u_.real_.value = net->value().as_double();
}
void dll_target::expr_scope(const NetEScope*net)
{
assert(expr_ == 0);
@ -253,6 +293,7 @@ void dll_target::expr_scope(const NetEScope*net)
assert(expr_);
expr_->type_ = IVL_EX_SCOPE;
expr_->value_= IVL_VT_VOID;
expr_->u_.scope_.scope = lookup_scope_(net->scope());
}
@ -271,6 +312,7 @@ void dll_target::expr_select(const NetESelect*net)
assert(expr_);
expr_->type_ = IVL_EX_SELECT;
expr_->value_= IVL_VT_VECTOR;
expr_->width_= net->expr_width();
expr_->signed_ = net->has_sign()? 1 : 0;
@ -286,6 +328,7 @@ void dll_target::expr_sfunc(const NetESFunc*net)
assert(expr);
expr->type_ = IVL_EX_SFUNC;
expr->value_= IVL_VT_VECTOR;
expr->width_= net->expr_width();
expr->u_.sfunc_.name_ = strdup(net->name());
@ -312,6 +355,7 @@ void dll_target::expr_ternary(const NetETernary*net)
assert(expr);
expr->type_ = IVL_EX_TERNARY;
expr->value_= IVL_VT_VECTOR;
expr->width_ = net->expr_width();
expr->signed_ = net->has_sign()? 1 : 0;
@ -340,6 +384,7 @@ void dll_target::expr_signal(const NetESignal*net)
assert(expr_);
expr_->type_ = IVL_EX_SIGNAL;
expr_->value_= IVL_VT_VECTOR;
expr_->width_= net->expr_width();
expr_->signed_ = net->has_sign()? 1 : 0;
expr_->u_.signal_.sig = find_signal(des_, net->sig());
@ -355,6 +400,7 @@ void dll_target::expr_subsignal(const NetEBitSel*net)
assert(expr);
expr->type_ = IVL_EX_BITSEL;
expr->value_= IVL_VT_VECTOR;
expr->width_= net->expr_width();
expr->signed_ = net->has_sign()? 1 : 0;
expr->u_.bitsel_.sig = find_signal(des_, net->sig());
@ -450,6 +496,7 @@ void dll_target::expr_ufunc(const NetEUFunc*net)
assert(expr);
expr->type_ = IVL_EX_UFUNC;
expr->value_= IVL_VT_VECTOR;
expr->width_= net->expr_width();
expr->signed_ = net->has_sign()? 1 : 0;
@ -482,14 +529,31 @@ void dll_target::expr_unary(const NetEUnary*net)
expr_ = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s));
expr_->type_ = IVL_EX_UNARY;
expr_->value_= IVL_VT_VECTOR;
expr_->width_ = net->expr_width();
expr_->signed_ = net->has_sign()? 1 : 0;
expr_->u_.unary_.op_ = net->op();
expr_->u_.unary_.sub_ = sub;
}
void dll_target::expr_variable(const NetEVariable*net)
{
assert(expr_ == 0);
expr_ = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s));
expr_->type_ = IVL_EX_VARIABLE;
expr_->value_ = IVL_VT_REAL;
expr_->width_ = 0;
expr_->signed_= net->has_sign()? 1 : 0;
expr_->u_.variable_.var = find_variable(des_, net->variable());
}
/*
* $Log: t-dll-expr.cc,v $
* Revision 1.30 2003/01/26 21:15:59 steve
* Rework expression parsing and elaboration to
* accommodate real/realtime values and expressions.
*
* Revision 1.29 2002/10/23 01:47:17 steve
* Fix synth2 handling of aset/aclr signals where
* flip-flops are split by begin-end blocks.

View File

@ -18,7 +18,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: t-dll-proc.cc,v 1.54 2002/08/19 00:06:12 steve Exp $"
#ident "$Id: t-dll-proc.cc,v 1.55 2003/01/26 21:15:59 steve Exp $"
#endif
# include "config.h"
@ -163,6 +163,11 @@ void dll_target::proc_assign(const NetAssign*net)
expr_ = 0;
}
} else if (asn->var()) {
cur->type_ = IVL_LVAL_VAR;
cur->idx = 0;
cur->n.var = find_variable(des_, asn->var());
} else {
assert(asn->mem());
cur->type_ = IVL_LVAL_MEM;
@ -822,6 +827,10 @@ void dll_target::proc_while(const NetWhile*net)
/*
* $Log: t-dll-proc.cc,v $
* Revision 1.55 2003/01/26 21:15:59 steve
* Rework expression parsing and elaboration to
* accommodate real/realtime values and expressions.
*
* Revision 1.54 2002/08/19 00:06:12 steve
* Allow release to handle removal of target net.
*

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000-2002 Stephen Williams (steve@icarus.com)
* Copyright (c) 2000-2003 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,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: t-dll.cc,v 1.102 2003/01/16 21:43:52 steve Exp $"
#ident "$Id: t-dll.cc,v 1.103 2003/01/26 21:15:59 steve Exp $"
#endif
# include "config.h"
@ -235,6 +235,22 @@ ivl_signal_t dll_target::find_signal(ivl_design_s &des, const NetNet*net)
return 0;
}
ivl_variable_t dll_target::find_variable(ivl_design_s&des,
const NetVariable*net)
{
ivl_scope_t scope = find_scope(des, net->scope());
assert(scope);
const char*nname = net->basename();
for (unsigned idx = 0 ; idx < scope->nvar_ ; idx += 1) {
if (strcmp(scope->var_[idx]->name, nname) == 0)
return scope->var_[idx];
}
assert(0);
return 0;
}
/*
* This function locates an ivl_memory_t object that matches the
* NetMemory object. The search works by looking for the parent scope,
@ -415,6 +431,14 @@ static void scope_add_mem(ivl_scope_t scope, ivl_memory_t net)
scope->mem_[scope->nmem_-1] = net;
}
static void scope_add_var(ivl_scope_t scope, ivl_variable_t net)
{
scope->nvar_ += 1;
scope->var_ = (ivl_variable_t*)
realloc(scope->var_, scope->nvar_*sizeof(ivl_variable_t));
scope->var_[scope->nvar_-1] = net;
}
void dll_target::add_root(ivl_design_s &des_, const NetScope *s)
{
ivl_scope_t root_ = new struct ivl_scope_s;
@ -433,6 +457,8 @@ void dll_target::add_root(ivl_design_s &des_, const NetScope *s)
root_->lpm_ = 0;
root_->nmem_ = 0;
root_->mem_ = 0;
root_->nvar_ = 0;
root_->var_ = 0;
root_->type_ = IVL_SCT_MODULE;
root_->tname_ = root_->name_;
root_->time_units = s->time_unit();
@ -633,6 +659,18 @@ void dll_target::event(const NetEvent*net)
}
void dll_target::variable(const NetVariable*net)
{
struct ivl_variable_s *obj = new struct ivl_variable_s;
ivl_scope_t scope = find_scope(des_, net->scope());
obj->type = IVL_VT_REAL;
obj->name = strings_.add(net->basename());
obj->scope = scope;
scope_add_var(scope, obj);
}
void dll_target::logic(const NetLogic*net)
{
struct ivl_net_logic_s *obj = new struct ivl_net_logic_s;
@ -1779,6 +1817,8 @@ void dll_target::scope(const NetScope*net)
scope->lpm_ = 0;
scope->nmem_ = 0;
scope->mem_ = 0;
scope->nvar_ = 0;
scope->var_ = 0;
scope->time_units = net->time_unit();
switch (net->type()) {
@ -1993,6 +2033,10 @@ extern const struct target tgt_dll = { "dll", &dll_target_obj };
/*
* $Log: t-dll.cc,v $
* Revision 1.103 2003/01/26 21:15:59 steve
* Rework expression parsing and elaboration to
* accommodate real/realtime values and expressions.
*
* Revision 1.102 2003/01/16 21:43:52 steve
* Assert some task definition sanity.
*

34
t-dll.h
View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: t-dll.h,v 1.96 2002/12/21 00:55:58 steve Exp $"
#ident "$Id: t-dll.h,v 1.97 2003/01/26 21:15:59 steve Exp $"
#endif
# include "target.h"
@ -68,6 +68,7 @@ struct dll_target : public target_t, public expr_scan_t {
bool bufz(const NetBUFZ*);
void event(const NetEvent*);
void variable(const NetVariable*);
void logic(const NetLogic*);
void net_case_cmp(const NetCaseCmp*);
void udp(const NetUDP*);
@ -130,6 +131,7 @@ struct dll_target : public target_t, public expr_scan_t {
void expr_concat(const NetEConcat*);
void expr_memory(const NetEMemory*);
void expr_const(const NetEConst*);
void expr_creal(const NetECReal*);
void expr_scope(const NetEScope*);
void expr_select(const NetESelect*);
void expr_sfunc(const NetESFunc*);
@ -138,6 +140,7 @@ struct dll_target : public target_t, public expr_scan_t {
void expr_ufunc(const NetEUFunc*);
void expr_unary(const NetEUnary*);
void expr_signal(const NetESignal*);
void expr_variable(const NetEVariable*);
ivl_scope_t lookup_scope_(const NetScope*scope);
@ -150,6 +153,7 @@ struct dll_target : public target_t, public expr_scan_t {
static ivl_scope_t find_scope(ivl_design_s &des, const NetScope*cur);
static ivl_signal_t find_signal(ivl_design_s &des, const NetNet*net);
static ivl_memory_t find_memory(ivl_design_s &des, const NetMemory*net);
static ivl_variable_t find_variable(ivl_design_s &des, const NetVariable*net);
void add_root(ivl_design_s &des_, const NetScope *s);
void sub_off_from_expr_(long);
@ -177,6 +181,7 @@ struct ivl_event_s {
*/
struct ivl_expr_s {
ivl_expr_type_t type_;
ivl_variable_type_t value_;
unsigned width_ :24;
unsigned signed_ : 1;
@ -243,11 +248,18 @@ struct ivl_expr_s {
unsigned long value;
} ulong_;
struct {
double value;
} real_;
struct {
char op_;
ivl_expr_t sub_;
} unary_;
struct {
ivl_variable_t var;
} variable_;
} u_;
};
@ -334,7 +346,8 @@ enum ivl_lval_type_t {
IVL_LVAL_REG = 0,
IVL_LVAL_MUX = 1,
IVL_LVAL_MEM = 2,
IVL_LVAL_NET = 3 /* Only force can have NET l-values */
IVL_LVAL_NET = 3, /* Only force can have NET l-values */
IVL_LVAL_VAR = 4
};
struct ivl_lval_s {
@ -345,6 +358,7 @@ struct ivl_lval_s {
union {
ivl_signal_t sig;
ivl_memory_t mem;
ivl_variable_t var;
} n;
};
@ -495,6 +509,9 @@ struct ivl_scope_s {
unsigned nmem_;
ivl_memory_t* mem_;
unsigned nvar_;
ivl_variable_t* var_;
/* Scopes that are tasks/functions have a definition. */
ivl_statement_t def;
@ -622,8 +639,21 @@ struct ivl_statement_s {
} u_;
};
/*
* This holds the details about a variable object.
*/
struct ivl_variable_s {
ivl_variable_type_t type;
const char* name;
ivl_scope_t scope;
};
/*
* $Log: t-dll.h,v $
* Revision 1.97 2003/01/26 21:15:59 steve
* Rework expression parsing and elaboration to
* accommodate real/realtime values and expressions.
*
* Revision 1.96 2002/12/21 00:55:58 steve
* The $time system task returns the integer time
* scaled to the local units. Change the internal

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998-2002 Stephen Williams <steve@icarus.com>
* Copyright (c) 1998-2003 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,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: target.cc,v 1.63 2002/08/12 01:35:01 steve Exp $"
#ident "$Id: target.cc,v 1.64 2003/01/26 21:15:59 steve Exp $"
#endif
# include "config.h"
@ -47,6 +47,12 @@ void target_t::memory(const NetMemory*)
"Unhandled memory." << endl;
}
void target_t::variable(const NetVariable*that)
{
cerr << that->get_line() << ": error: target (" << typeid(*this).name()
<< "): Unhandled variable <" << that->basename() << ">." << endl;
}
void target_t::func_def(const NetScope*)
{
cerr << "target (" << typeid(*this).name() << "): "
@ -317,6 +323,12 @@ void expr_scan_t::expr_const(const NetEConst*)
"unhandled expr_const." << endl;
}
void expr_scan_t::expr_creal(const NetECReal*)
{
cerr << "expr_scan_t (" << typeid(*this).name() << "): "
"unhandled expr_creal." << endl;
}
void expr_scan_t::expr_concat(const NetEConcat*that)
{
cerr << that->get_line() << ": expr_scan_t (" <<
@ -377,6 +389,12 @@ void expr_scan_t::expr_unary(const NetEUnary*)
"unhandled expr_unary." << endl;
}
void expr_scan_t::expr_variable(const NetEVariable*)
{
cerr << "expr_scan_t (" << typeid(*this).name() << "): "
"unhandled expr_variable." << endl;
}
void expr_scan_t::expr_binary(const NetEBinary*ex)
{
cerr << "expr_scan_t (" << typeid(*this).name() << "): "
@ -385,6 +403,10 @@ void expr_scan_t::expr_binary(const NetEBinary*ex)
/*
* $Log: target.cc,v $
* Revision 1.64 2003/01/26 21:15:59 steve
* Rework expression parsing and elaboration to
* accommodate real/realtime values and expressions.
*
* Revision 1.63 2002/08/12 01:35:01 steve
* conditional ident string using autoconfig.
*

View File

@ -1,7 +1,7 @@
#ifndef __target_H
#define __target_H
/*
* Copyright (c) 1998-1999 Stephen Williams (steve@icarus.com)
* Copyright (c) 1998-2003 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
@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: target.h,v 1.60 2002/08/12 01:35:01 steve Exp $"
#ident "$Id: target.h,v 1.61 2003/01/26 21:15:59 steve Exp $"
#endif
# include "netlist.h"
@ -68,6 +68,9 @@ struct target_t {
/* Output a memory (called for each memory object) */
virtual void memory(const NetMemory*);
/* Output an event object. Called for each named event in the scope. */
virtual void variable(const NetVariable*);
/* Output a defined task. */
virtual void task_def(const NetScope*);
virtual void func_def(const NetScope*);
@ -128,6 +131,7 @@ struct target_t {
struct expr_scan_t {
virtual ~expr_scan_t();
virtual void expr_const(const NetEConst*);
virtual void expr_creal(const NetECReal*);
virtual void expr_concat(const NetEConcat*);
virtual void expr_memory(const NetEMemory*);
virtual void expr_scope(const NetEScope*);
@ -138,6 +142,7 @@ struct expr_scan_t {
virtual void expr_ternary(const NetETernary*);
virtual void expr_ufunc(const NetEUFunc*);
virtual void expr_unary(const NetEUnary*);
virtual void expr_variable(const NetEVariable*);
virtual void expr_binary(const NetEBinary*);
};
@ -162,6 +167,10 @@ extern const struct target *target_table[];
/*
* $Log: target.h,v $
* Revision 1.61 2003/01/26 21:15:59 steve
* Rework expression parsing and elaboration to
* accommodate real/realtime values and expressions.
*
* Revision 1.60 2002/08/12 01:35:01 steve
* conditional ident string using autoconfig.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: stub.c,v 1.71 2002/12/21 00:55:58 steve Exp $"
#ident "$Id: stub.c,v 1.72 2003/01/26 21:15:59 steve Exp $"
#endif
# include "config.h"
@ -40,6 +40,19 @@ static void show_expression(ivl_expr_t net, unsigned ind)
const ivl_expr_type_t code = ivl_expr_type(net);
unsigned width = ivl_expr_width(net);
const char*sign = ivl_expr_signed(net)? "signed" : "unsigned";
const char*vt = "?";
switch (ivl_expr_value(net)) {
case IVL_VT_VOID:
vt = "void";
break;
case IVL_VT_REAL:
vt = "real";
break;
case IVL_VT_VECTOR:
vt = "vector";
break;
}
switch (code) {
@ -50,15 +63,15 @@ static void show_expression(ivl_expr_t net, unsigned ind)
break;
case IVL_EX_BINARY:
fprintf(out, "%*s<\"%c\" width=%u, %s>\n", ind, "",
ivl_expr_opcode(net), width, sign);
fprintf(out, "%*s<\"%c\" width=%u, %s, type=%s>\n", ind, "",
ivl_expr_opcode(net), width, sign, vt);
show_expression(ivl_expr_oper1(net), ind+3);
show_expression(ivl_expr_oper2(net), ind+3);
break;
case IVL_EX_CONCAT:
fprintf(out, "%*s<concat repeat=%u, width=%u, %s>\n", ind, "",
ivl_expr_repeat(net), width, sign);
fprintf(out, "%*s<concat repeat=%u, width=%u, %s, type=%s>\n",
ind, "", ivl_expr_repeat(net), width, sign, vt);
for (idx = 0 ; idx < ivl_expr_parms(net) ; idx += 1)
show_expression(ivl_expr_parm(net, idx), ind+3);
@ -116,6 +129,15 @@ static void show_expression(ivl_expr_t net, unsigned ind)
show_expression(ivl_expr_oper1(net), ind+4);
break;
case IVL_EX_VARIABLE:
fprintf(out, "%*s<variable %s, type=%s>\n",
ind, "", ivl_expr_name(net), vt);
break;
case IVL_EX_REALNUM:
fprintf(out, "%*s<realnum=%f>\n", ind, "", ivl_expr_dvalue(net));
break;
default:
fprintf(out, "%*s<expr_type=%u>\n", ind, "", code);
break;
@ -244,6 +266,7 @@ static void show_lpm(ivl_lpm_t net)
static void show_assign_lval(ivl_lval_t lval, unsigned ind)
{
ivl_memory_t mem;
ivl_variable_t var;
if ( (mem = ivl_lval_mem(lval)) ) {
@ -254,6 +277,10 @@ static void show_assign_lval(ivl_lval_t lval, unsigned ind)
show_expression(ivl_lval_idx(lval), ind+4);
fprintf(out, "%*s]\n", ind, "");
} else if ( (var = ivl_lval_var(lval)) ) {
fprintf(out, "%*svariable %s\n", ind, "", ivl_variable_name(var));
} else {
unsigned pp;
ivl_nexus_t nex = ivl_lval_pin(lval, 0);
@ -450,6 +477,26 @@ static int show_process(ivl_process_t net, void*x)
return 0;
}
static void show_variable(ivl_variable_t net)
{
const char*type = "?";
const char*name = ivl_variable_name(net);
switch (ivl_variable_type(net)) {
case IVL_VT_VOID:
type = "void";
break;
case IVL_VT_REAL:
type = "real";
break;
case IVL_VT_VECTOR:
type = "vector";
break;
}
fprintf(out, " variable %s %s;\n", type, name);
}
static void show_event(ivl_event_t net)
{
unsigned idx;
@ -688,6 +735,9 @@ static int show_scope(ivl_scope_t net, void*x)
fprintf(out, " time units = 10e%d\n", ivl_scope_time_units(net));
for (idx = 0 ; idx < ivl_scope_vars(net) ; idx += 1)
show_variable(ivl_scope_var(net, idx));
for (idx = 0 ; idx < ivl_scope_events(net) ; idx += 1)
show_event(ivl_scope_event(net, idx));
@ -730,6 +780,10 @@ int target_design(ivl_design_t des)
/*
* $Log: stub.c,v $
* Revision 1.72 2003/01/26 21:15:59 steve
* Rework expression parsing and elaboration to
* accommodate real/realtime values and expressions.
*
* Revision 1.71 2002/12/21 00:55:58 steve
* The $time system task returns the integer time
* scaled to the local units. Change the internal

View File

@ -16,7 +16,7 @@
# 59 Temple Place - Suite 330
# Boston, MA 02111-1307, USA
#
#ident "$Id: Makefile.in,v 1.12 2002/11/05 02:14:41 steve Exp $"
#ident "$Id: Makefile.in,v 1.13 2003/01/26 21:15:59 steve Exp $"
#
#
SHELL = /bin/sh
@ -50,7 +50,7 @@ all: vvp.tgt
$(CC) -Wall @ident_support@ -I$(srcdir)/.. $(CPPFLAGS) $(CFLAGS) -MD -c $< -o $*.o
mv $*.d dep
O = vvp.o draw_mux.o eval_expr.o vector.o vvp_process.o vvp_scope.o
O = vvp.o draw_mux.o eval_expr.o eval_real.o vector.o vvp_process.o vvp_scope.o
ifeq (@WIN32@,yes)
TGTLDFLAGS=-L.. -livl

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: eval_expr.c,v 1.88 2002/12/20 01:11:14 steve Exp $"
#ident "$Id: eval_expr.c,v 1.89 2003/01/26 21:15:59 steve Exp $"
#endif
# include "vvp_priv.h"
@ -189,7 +189,8 @@ static struct vector_info draw_eq_immediate(ivl_expr_t exp, unsigned ewid,
} else if (lv.wid < ewid) {
unsigned short base = allocate_vector(ewid);
clr_vector(lv);
if (lv.base >= 8)
clr_vector(lv);
fprintf(vvp_out, " %%mov %u, %u, %u;\n", base,
lv.base, lv.wid);
fprintf(vvp_out, " %%mov %u, 0, %u;\n",
@ -201,6 +202,43 @@ static struct vector_info draw_eq_immediate(ivl_expr_t exp, unsigned ewid,
return lv;
}
/*
* This handles the special case that the operands of the comparison
* are real valued expressions.
*/
static struct vector_info draw_binary_expr_eq_real(ivl_expr_t exp)
{
struct vector_info res;
int lword, rword;
res.base = allocate_vector(1);
res.wid = 1;
lword = draw_eval_real(ivl_expr_oper1(exp));
rword = draw_eval_real(ivl_expr_oper2(exp));
clr_word(lword);
clr_word(rword);
fprintf(vvp_out, " %%cmp/wr %d, %d;\n", lword, rword);
switch (ivl_expr_opcode(exp)) {
case 'e':
fprintf(vvp_out, " %%mov %u, 4, 1;\n", res.base);
break;
case 'n': /* != */
fprintf(vvp_out, " %%mov %u, 4, 1;\n", res.base);
fprintf(vvp_out, " %%inv %u, 1;\n", res.base);
break;
default:
assert(0);
}
return res;
}
static struct vector_info draw_binary_expr_eq(ivl_expr_t exp,
unsigned ewid,
int stuff_ok_flag)
@ -222,6 +260,14 @@ static struct vector_info draw_binary_expr_eq(ivl_expr_t exp,
&& number_is_immediate(re, 16))
return draw_eq_immediate(exp, ewid, le, re, stuff_ok_flag);
if (ivl_expr_value(le) == IVL_VT_REAL) {
assert(ivl_expr_value(re) == IVL_VT_REAL);
return draw_binary_expr_eq_real(exp);
}
assert(ivl_expr_value(le) == IVL_VT_VECTOR);
assert(ivl_expr_value(re) == IVL_VT_VECTOR);
wid = ivl_expr_width(le);
if (ivl_expr_width(re) > wid)
wid = ivl_expr_width(re);
@ -234,8 +280,10 @@ static struct vector_info draw_binary_expr_eq(ivl_expr_t exp,
assert(lv.wid == rv.wid);
fprintf(vvp_out, " %%cmp/u %u, %u, %u;\n", lv.base,
rv.base, lv.wid);
clr_vector(lv);
clr_vector(rv);
if (lv.base >= 8)
clr_vector(lv);
if (rv.base >= 8)
clr_vector(rv);
lv.base = 6;
lv.wid = 1;
break;
@ -462,6 +510,40 @@ static struct vector_info draw_binary_expr_lor(ivl_expr_t exp, unsigned wid)
return lv;
}
static struct vector_info draw_binary_expr_le_real(ivl_expr_t exp)
{
struct vector_info res;
ivl_expr_t le = ivl_expr_oper1(exp);
ivl_expr_t re = ivl_expr_oper2(exp);
int lword = draw_eval_real(le);
int rword = draw_eval_real(re);
res.base = allocate_vector(1);
res.wid = 1;
clr_word(lword);
clr_word(rword);
switch (ivl_expr_opcode(exp)) {
case '<':
fprintf(vvp_out, " %%cmp/wr %d, %d;\n", lword, rword);
fprintf(vvp_out, " %%mov %u, 5, 1;\n", res.base);
break;
case '>':
fprintf(vvp_out, " %%cmp/wr %d, %d;\n", rword, lword);
fprintf(vvp_out, " %%mov %u, 5, 1;\n", res.base);
break;
default:
assert(0);
}
return res;
}
static struct vector_info draw_binary_expr_le(ivl_expr_t exp,
unsigned wid,
int stuff_ok_flag)
@ -478,6 +560,14 @@ static struct vector_info draw_binary_expr_le(ivl_expr_t exp,
if (ivl_expr_width(re) > owid)
owid = ivl_expr_width(re);
if (ivl_expr_value(le) == IVL_VT_REAL) {
assert(ivl_expr_value(re) == IVL_VT_REAL);
return draw_binary_expr_le_real(exp);
}
assert(ivl_expr_value(le) == IVL_VT_VECTOR);
assert(ivl_expr_value(re) == IVL_VT_VECTOR);
lv = draw_eval_expr_wid(le, owid, STUFF_OK_XZ);
rv = draw_eval_expr_wid(re, owid, STUFF_OK_XZ);
@ -834,6 +924,12 @@ static struct vector_info draw_binary_expr_arith(ivl_expr_t exp, unsigned wid)
lv = draw_eval_expr_wid(le, wid, STUFF_OK_XZ);
rv = draw_eval_expr_wid(re, wid, STUFF_OK_XZ);
if (lv.wid != wid) {
fprintf(stderr, "XXXX ivl_expr_opcode(exp) = %c,"
" lv.wid=%u, wid=%u\n", ivl_expr_opcode(exp),
lv.wid, wid);
}
assert(lv.wid == wid);
assert(rv.wid == wid);
@ -1164,6 +1260,19 @@ static struct vector_info draw_number_expr(ivl_expr_t exp, unsigned wid)
return res;
}
static struct vector_info draw_realnum_expr(ivl_expr_t exp, unsigned wid)
{
struct vector_info res;
double val = ivl_expr_dvalue(exp);
res.base = allocate_vector(wid);
res.wid = wid;
fprintf(vvp_out, " ; XXXX draw_realnum_expr(%f, %u)\n", val, wid);
return res;
}
/*
* A string in an expression is made up by copying constant bits into
* the allocated vector.
@ -1861,6 +1970,18 @@ static struct vector_info draw_unary_expr(ivl_expr_t exp, unsigned wid)
return res;
}
static struct vector_info draw_variable_expr(ivl_expr_t exp, unsigned wid)
{
struct vector_info res;
ivl_variable_t var = ivl_expr_variable(exp);
fprintf(vvp_out, " ; XXXX Read variable %s\n",
ivl_variable_name(var));
res.base = 0;
res.wid = wid;
return res;
}
/*
* Sometimes we know ahead of time where we want the expression value
* to go. In that case, call this function. It will check to see if
@ -1931,6 +2052,10 @@ struct vector_info draw_eval_expr_wid(ivl_expr_t exp, unsigned wid,
res = draw_number_expr(exp, wid);
break;
case IVL_EX_REALNUM:
res = draw_realnum_expr(exp, wid);
break;
case IVL_EX_SELECT:
res = draw_select_expr(exp, wid);
break;
@ -1958,6 +2083,10 @@ struct vector_info draw_eval_expr_wid(ivl_expr_t exp, unsigned wid,
case IVL_EX_UNARY:
res = draw_unary_expr(exp, wid);
break;
case IVL_EX_VARIABLE:
res = draw_variable_expr(exp, wid);
break;
}
return res;
@ -1970,79 +2099,15 @@ struct vector_info draw_eval_expr(ivl_expr_t exp, int stuff_ok_flag)
/*
* $Log: eval_expr.c,v $
* Revision 1.89 2003/01/26 21:15:59 steve
* Rework expression parsing and elaboration to
* accommodate real/realtime values and expressions.
*
* Revision 1.88 2002/12/20 01:11:14 steve
* Evaluate shift index after shift operand because
* the chift operand may use the index register itself.
*
* Revision 1.87 2002/12/19 23:11:29 steve
* Keep bit select subexpression width if it is constant.
*
* Revision 1.86 2002/11/22 00:01:50 steve
* Careful of left operands to shift that are constant.
*
* Revision 1.85 2002/11/21 22:42:48 steve
* Allow right values of right shift to shift in.
*
* Revision 1.84 2002/11/07 03:12:17 steve
* Vectorize load from REG variables.
*
* Revision 1.83 2002/11/06 05:41:37 steve
* Concatenation can evaluate sub-expressions in place.
*
* Revision 1.82 2002/10/20 02:55:37 steve
* Properly set or clear expression lookaside for binary expressions.
*
* Revision 1.81 2002/09/27 20:24:42 steve
* Allow expression lookaside map to spam statements.
*
* Revision 1.80 2002/09/27 16:33:34 steve
* Add thread expression lookaside map.
*
* Revision 1.79 2002/09/24 04:20:32 steve
* Allow results in register bits 47 in certain cases.
*
* Revision 1.78 2002/09/18 04:29:55 steve
* Add support for binary NOR operator.
*
* Revision 1.77 2002/09/13 04:09:51 steve
* single bit optimization for != in expressions,
* and expand ++ and != results if needed.
*
* Revision 1.76 2002/09/13 03:12:50 steve
* Optimize ==1 when in context where x vs z doesnt matter.
*
* Revision 1.75 2002/09/12 15:49:43 steve
* Add support for binary nand operator.
*
* Revision 1.74 2002/09/01 01:42:34 steve
* Fix leaking vthread bits in ?: eval.
*
* Revision 1.73 2002/08/28 18:38:07 steve
* Add the %subi instruction, and use it where possible.
*
* Revision 1.72 2002/08/28 17:15:35 steve
* Generate %load/nx for indexed load of nets.
*
* Revision 1.71 2002/08/27 05:39:57 steve
* Fix l-value indexing of memories and vectors so that
* an unknown (x) index causes so cell to be addresses.
*
* Fix tangling of label identifiers in the fork-join
* code generator.
*
* Revision 1.70 2002/08/22 03:38:40 steve
* Fix behavioral eval of x?a:b expressions.
*
* Revision 1.69 2002/08/12 01:35:03 steve
* conditional ident string using autoconfig.
*
* Revision 1.68 2002/08/05 04:18:45 steve
* Store only the base name of memories.
*
* Revision 1.67 2002/08/04 18:28:15 steve
* Do not use hierarchical names of memories to
* generate vvp labels. -tdll target does not
* used hierarchical name string to look up the
* memory objects in the design.
*/

202
tgt-vvp/eval_real.c Normal file
View File

@ -0,0 +1,202 @@
/*
* Copyright (c) 2003 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
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: eval_real.c,v 1.1 2003/01/26 21:16:00 steve Exp $"
#endif
/*
* This file includes functions for evaluating REAL expressions.
*/
# include "vvp_priv.h"
# include <string.h>
#ifdef HAVE_MALLOC_H
# include <malloc.h>
#endif
# include <stdlib.h>
# include <math.h>
# include <assert.h>
static unsigned long word_alloc_mask = 0x0f;
int allocate_word()
{
int res = 4;
while ((1 << res) & word_alloc_mask)
res += 1;
word_alloc_mask |= 1 << res;
return res;
}
void clr_word(int res)
{
assert(word_alloc_mask & (1 << res));
word_alloc_mask &= ~ (1 << res);
}
static int draw_binary_real(ivl_expr_t exp)
{
int l, r;
l = draw_eval_real(ivl_expr_oper1(exp));
r = draw_eval_real(ivl_expr_oper2(exp));
switch (ivl_expr_opcode(exp)) {
case '+':
fprintf(vvp_out, " %%add/wr %d, %d;\n", l, r);
clr_word(r);
break;
case '*':
fprintf(vvp_out, " %%mul/wr %d, %d;\n", l, r);
clr_word(r);
break;
default:
assert(0);
}
return l;
}
static int draw_number_real(ivl_expr_t exp)
{
int idx;
int res = allocate_word();
const char*bits = ivl_expr_bits(exp);
unsigned wid = ivl_expr_width(exp);
unsigned long mant = 0;
for (idx = 0 ; idx < wid ; idx += 1) {
if (bits[idx] == '1')
mant |= 1 << idx;
}
fprintf(vvp_out, " %%loadi/wr %d, %lu, 4096;\n", res, mant);
return res;
}
/*
* Evaluate a real variable expression by loading the real variable
* into a real thread word.
*/
static int draw_variable_real(ivl_expr_t exp)
{
int res = allocate_word();
ivl_variable_t var = ivl_expr_variable(exp);
fprintf(vvp_out, " %%load/wr %d, W_%s;\n", res, vvp_word_label(var));
return res;
}
static int draw_realnum_real(ivl_expr_t exp)
{
int res = allocate_word();
double value = ivl_expr_dvalue(exp);
double fract;
int vexp;
unsigned long mant;
int sign = 0;
if (value < 0) {
sign = 0x4000;;
value *= -1;
}
fract = frexp(value, &vexp);
fract *= 0x10000;
fract *= 0x10000;
mant = fract;
vexp -= 32;
vexp += 0x1000;
assert(vexp >= 0);
assert(vexp < 0x2000);
vexp += sign;
fprintf(vvp_out, " %%loadi/wr %d, %lu, %d; load=%f\n",
res, mant, vexp, ivl_expr_dvalue(exp));
return res;
}
/*
* The real value of a signal is the integer value of a signal
* converted to real.
*/
static int draw_signal_real(ivl_expr_t exp)
{
int res = allocate_word();
struct vector_info sv = draw_eval_expr(exp, 0);
fprintf(vvp_out, " %%ix/get %d, %u, %u;\n", res, sv.base, sv.wid);
clr_vector(sv);
fprintf(vvp_out, " %%cvt/ri %d, %d;\n", res, res);
return res;
}
int draw_eval_real(ivl_expr_t exp)
{
int res = 0;
switch (ivl_expr_type(exp)) {
case IVL_EX_BINARY:
res = draw_binary_real(exp);
break;
case IVL_EX_NUMBER:
res = draw_number_real(exp);
break;
case IVL_EX_REALNUM:
res = draw_realnum_real(exp);
break;
case IVL_EX_VARIABLE:
res = draw_variable_real(exp);
break;
case IVL_EX_SIGNAL:
res = draw_signal_real(exp);
break;
default:
fprintf(vvp_out, " ; XXXX Evaluate real expression (%d)\n",
ivl_expr_type(exp));
return 0;
}
return res;
}
/*
* $Log: eval_real.c,v $
* Revision 1.1 2003/01/26 21:16:00 steve
* Rework expression parsing and elaboration to
* accommodate real/realtime values and expressions.
*
*/

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: vvp_priv.h,v 1.22 2002/09/27 16:33:34 steve Exp $"
#ident "$Id: vvp_priv.h,v 1.23 2003/01/26 21:16:00 steve Exp $"
#endif
# include "ivl_target.h"
@ -48,6 +48,8 @@ extern const char* vvp_signal_label(ivl_signal_t sig);
*/
extern const char* vvp_memory_label(ivl_memory_t mem);
extern const char* vvp_word_label(ivl_variable_t var);
/*
* This function draws a process (initial or always) into the output
* file. It normally returns 0, but returns !0 of there is some sort
@ -158,6 +160,19 @@ extern int number_is_unknown(ivl_expr_t ex);
extern int number_is_immediate(ivl_expr_t ex, unsigned lim_wid);
extern unsigned long get_number_immediate(ivl_expr_t ex);
/*
* draw_eval_real evaluates real value expressions. The return code
* from the function is the index of the word register that contains
* the result.
*/
extern int draw_eval_real(ivl_expr_t ex);
/*
* These functions manage word register allocation.
*/
extern int allocate_word(void);
extern void clr_word(int idx);
/*
* These are used to count labels as I generate code.
*/
@ -166,6 +181,10 @@ extern unsigned thread_count;
/*
* $Log: vvp_priv.h,v $
* Revision 1.23 2003/01/26 21:16:00 steve
* Rework expression parsing and elaboration to
* accommodate real/realtime values and expressions.
*
* Revision 1.22 2002/09/27 16:33:34 steve
* Add thread expression lookaside map.
*
@ -211,37 +230,5 @@ extern unsigned thread_count;
* 2. Id and name mangling
* 3. A memory leak in draw_net_in_scope()
* (Stephan Boettcher)
*
* Revision 1.10 2001/05/17 04:37:02 steve
* Behavioral ternary operators for vvp.
*
* Revision 1.9 2001/05/06 17:54:33 steve
* Behavioral code to read memories. (Stephan Boettcher)
*
* Revision 1.8 2001/04/06 02:28:03 steve
* Generate vvp code for functions with ports.
*
* Revision 1.7 2001/04/02 02:28:13 steve
* Generate code for task calls.
*
* Revision 1.6 2001/03/31 17:36:39 steve
* Generate vvp code for case statements.
*
* Revision 1.5 2001/03/27 06:27:41 steve
* Generate code for simple @ statements.
*
* Revision 1.4 2001/03/27 03:31:07 steve
* Support error code from target_t::end_design method.
*
* Revision 1.3 2001/03/22 05:06:21 steve
* Geneate code for conditional statements.
*
* Revision 1.2 2001/03/21 01:49:43 steve
* Scan the scopes of a design, and draw behavioral
* blocking assignments of constants to vectors.
*
* Revision 1.1 2001/03/19 01:20:46 steve
* Add the tgt-vvp code generator target.
*
*/
#endif

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: vvp_process.c,v 1.76 2002/11/21 22:43:13 steve Exp $"
#ident "$Id: vvp_process.c,v 1.77 2003/01/26 21:16:00 steve Exp $"
#endif
# include "vvp_priv.h"
@ -164,7 +164,7 @@ static void calculate_into_x1(ivl_expr_t expr)
clr_vector(vec);
}
static int show_stmt_assign(ivl_statement_t net)
static int show_stmt_assign_vector(ivl_statement_t net)
{
ivl_lval_t lval;
ivl_expr_t rval = ivl_stmt_rval(net);
@ -325,6 +325,56 @@ static int show_stmt_assign(ivl_statement_t net)
return 0;
}
static int show_stmt_assign_real(ivl_statement_t net)
{
int res;
ivl_lval_t lval;
ivl_variable_t var;
res = draw_eval_real(ivl_stmt_rval(net));
clr_word(res);
assert(ivl_stmt_lvals(net) == 1);
lval = ivl_stmt_lval(net, 0);
var = ivl_lval_var(lval);
assert(var != 0);
fprintf(vvp_out, " %%set/wr W_%s, %d;\n",
vvp_word_label(var), res);
return 0;
}
static int show_stmt_assign(ivl_statement_t net)
{
ivl_lval_t lval;
ivl_variable_t var;
lval = ivl_stmt_lval(net, 0);
if ( (var = ivl_lval_var(lval)) != 0 ) {
switch (ivl_variable_type(var)) {
case IVL_VT_VOID:
assert(0);
return 1;
case IVL_VT_VECTOR:
/* Can't happen. */
assert(0);
return 1;
case IVL_VT_REAL:
return show_stmt_assign_real(net);
}
} else {
return show_stmt_assign_vector(net);
}
return 0;
}
static int show_stmt_assign_nb(ivl_statement_t net)
{
ivl_lval_t lval;
@ -834,9 +884,25 @@ static int show_stmt_delayx(ivl_statement_t net, ivl_scope_t sscope)
ivl_expr_t exp = ivl_stmt_delay_expr(net);
ivl_statement_t stmt = ivl_stmt_sub_stmt(net);
{ struct vector_info del = draw_eval_expr(exp, 0);
fprintf(vvp_out, " %%ix/get 0, %u, %u;\n", del.base, del.wid);
clr_vector(del);
switch (ivl_expr_value(exp)) {
case IVL_VT_VECTOR: {
struct vector_info del = draw_eval_expr(exp, 0);
fprintf(vvp_out, " %%ix/get 0, %u, %u;\n",
del.base, del.wid);
clr_vector(del);
break;
}
case IVL_VT_REAL: {
int word = draw_eval_real(exp);
fprintf(vvp_out, " %%cvt/ir 0, %d;\n", word);
clr_word(word);
break;
}
default:
assert(0);
}
fprintf(vvp_out, " %%delayx 0;\n");
@ -1131,21 +1197,33 @@ static int show_system_task_call(ivl_statement_t net)
return 0;
}
/* Figure out how many expressions are going to be evaluated
for this task call. I won't need to evaluate expressions
for items that are VPI objects directly. */
for (idx = 0 ; idx < parm_count ; idx += 1) {
ivl_expr_t expr = ivl_stmt_parm(net, idx);
switch (ivl_expr_type(expr)) {
/* These expression types can be handled directly,
with VPI handles of their own. Therefore, skip
them in the process of evaluating expressions. */
case IVL_EX_NONE:
case IVL_EX_NUMBER:
case IVL_EX_STRING:
case IVL_EX_SCOPE:
case IVL_EX_SFUNC:
case IVL_EX_VARIABLE:
continue;
case IVL_EX_SIGNAL:
/* If the signal node is narrower then the signal
itself, then this is a part select so I'm going
to need to evaluate the expression. */
to need to evaluate the expression.
If I don't need to do any evaluating, then skip
it as I'll be passing the handle to the signal
itself. */
if (ivl_expr_width(expr) !=
ivl_signal_pins(ivl_expr_signal(expr))) {
break;
@ -1153,17 +1231,32 @@ static int show_system_task_call(ivl_statement_t net)
continue;
}
case IVL_EX_MEMORY:
if (!ivl_expr_oper1(expr)) {
continue;
}
/* Everything else will need to be evaluated and
passed as a constant to the vpi task. */
default:
break;
}
vec = (struct vector_info *)
realloc(vec, (vecs+1)*sizeof(struct vector_info));
vec[vecs] = draw_eval_expr(expr, 0);
switch (ivl_expr_value(expr)) {
case IVL_VT_VECTOR:
vec[vecs] = draw_eval_expr(expr, 0);
break;
case IVL_VT_REAL:
vec[vecs].base = draw_eval_real(expr);
vec[vecs].wid = 0;
break;
default:
assert(0);
}
vecs++;
}
@ -1200,6 +1293,12 @@ static int show_system_task_call(ivl_statement_t net)
continue;
}
case IVL_EX_VARIABLE: {
ivl_variable_t var = ivl_expr_variable(expr);
fprintf(vvp_out, ", W_%s", vvp_word_label(var));
continue;
}
case IVL_EX_STRING:
fprintf(vvp_out, ", \"%s\"",
ivl_expr_string(expr));
@ -1231,16 +1330,31 @@ static int show_system_task_call(ivl_statement_t net)
break;
}
assert(veci < vecs);
fprintf(vvp_out, ", T<%u,%u,%s>", vec[veci].base,
vec[veci].wid, ivl_expr_signed(expr)? "s" : "u");
switch (ivl_expr_value(expr)) {
case IVL_VT_VECTOR:
fprintf(vvp_out, ", T<%u,%u,%s>", vec[veci].base,
vec[veci].wid, ivl_expr_signed(expr)? "s" : "u");
break;
case IVL_VT_REAL:
fprintf(vvp_out, ", W<%u,r>", vec[veci].base);
break;
default:
assert(0);
}
veci++;
}
assert(veci == vecs);
if (vecs) {
for (idx = 0; idx < vecs; idx++)
clr_vector(vec[idx]);
for (idx = 0; idx < vecs; idx++) {
if (vec[idx].wid > 0)
clr_vector(vec[idx]);
}
free(vec);
}
@ -1449,6 +1563,10 @@ int draw_func_definition(ivl_scope_t scope)
/*
* $Log: vvp_process.c,v $
* Revision 1.77 2003/01/26 21:16:00 steve
* Rework expression parsing and elaboration to
* accommodate real/realtime values and expressions.
*
* Revision 1.76 2002/11/21 22:43:13 steve
* %set/x0 instruction to support bounds checking.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: vvp_scope.c,v 1.82 2002/12/21 00:55:58 steve Exp $"
#ident "$Id: vvp_scope.c,v 1.83 2003/01/26 21:16:00 steve Exp $"
#endif
# include "vvp_priv.h"
@ -139,6 +139,13 @@ const char* vvp_signal_label(ivl_signal_t sig)
return buf;
}
const char* vvp_word_label(ivl_variable_t sig)
{
static char buf[32];
sprintf(buf, "$%p", sig);
return buf;
}
/*
* This makes a string suitable for use as a label for memories.
*/
@ -1568,6 +1575,16 @@ int draw_scope(ivl_scope_t net, ivl_scope_t parent)
}
/* Scan the scope for word variables. */
for (idx = 0 ; idx < ivl_scope_vars(net) ; idx += 1) {
ivl_variable_t var = ivl_scope_var(net, idx);
const char*type = "real";
fprintf(vvp_out, "W_%s .word %s, \"%s\";\n",
vvp_word_label(var), type,
ivl_variable_name(var));
}
/* Scan the signals (reg and net) and draw the appropriate
statements to make the signal function. */
@ -1611,6 +1628,10 @@ int draw_scope(ivl_scope_t net, ivl_scope_t parent)
/*
* $Log: vvp_scope.c,v $
* Revision 1.83 2003/01/26 21:16:00 steve
* Rework expression parsing and elaboration to
* accommodate real/realtime values and expressions.
*
* Revision 1.82 2002/12/21 00:55:58 steve
* The $time system task returns the integer time
* scaled to the local units. Change the internal

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: verireal.cc,v 1.8 2002/08/12 01:35:01 steve Exp $"
#ident "$Id: verireal.cc,v 1.9 2003/01/26 21:15:59 steve Exp $"
#endif
# include "config.h"
@ -25,6 +25,7 @@
# include "verireal.h"
# include <ctype.h>
# include <iostream>
# include <math.h>
# include <assert.h>
verireal::verireal()
@ -123,6 +124,11 @@ long verireal::as_long(int shift) const
return val;
}
double verireal::as_double() const
{
return mant_ * pow(10.0, exp10_) * (sign_? -1 : 1);
}
verireal operator* (const verireal&l, const verireal&r)
{
verireal res;
@ -140,6 +146,10 @@ ostream& operator<< (ostream&out, const verireal&v)
/*
* $Log: verireal.cc,v $
* Revision 1.9 2003/01/26 21:15:59 steve
* Rework expression parsing and elaboration to
* accommodate real/realtime values and expressions.
*
* Revision 1.8 2002/08/12 01:35:01 steve
* conditional ident string using autoconfig.
*

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: verireal.h,v 1.6 2002/08/12 01:35:01 steve Exp $"
#ident "$Id: verireal.h,v 1.7 2003/01/26 21:15:59 steve Exp $"
#endif
#ifdef HAVE_IOSFWD
@ -53,6 +53,7 @@ class verireal {
is 25. */
long as_long(int shift =0) const;
double as_double() const;
private:
bool sign_;
@ -65,6 +66,10 @@ extern verireal operator* (const verireal&, const verireal&);
/*
* $Log: verireal.h,v $
* Revision 1.7 2003/01/26 21:15:59 steve
* Rework expression parsing and elaboration to
* accommodate real/realtime values and expressions.
*
* Revision 1.6 2002/08/12 01:35:01 steve
* conditional ident string using autoconfig.
*

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: vpi_user.h,v 1.16 2003/01/09 04:10:17 steve Exp $"
#ident "$Id: vpi_user.h,v 1.17 2003/01/26 21:15:59 steve Exp $"
#endif
@ -161,6 +161,7 @@ typedef struct t_vpi_value {
#define vpiNamedEvent 34
#define vpiNamedFork 35
#define vpiNet 36
#define vpiRealVar 47
#define vpiReg 48
#define vpiSysFuncCall 56
#define vpiSysTaskCall 57
@ -366,6 +367,10 @@ EXTERN_C_END
/*
* $Log: vpi_user.h,v $
* Revision 1.17 2003/01/26 21:15:59 steve
* Rework expression parsing and elaboration to
* accommodate real/realtime values and expressions.
*
* Revision 1.16 2003/01/09 04:10:17 steve
* Add vpi_put_userdata
*