Compare commits

...
10 Commits
Author SHA1 Message Date
steve 04ada23119 Support in various contexts the $realtime
system task.
2003-01-27 00:14:37 +00:00
steve 46253ed873 Rework expression parsing and elaboration to
accommodate real/realtime values and expressions.
2003-01-26 21:15:58 +00:00
steve 1a9ab8ec84 Remember to save signedness of number. 2003-01-26 21:02:21 +00:00
steve 47db309d30 Support display of real values and constants. 2003-01-26 18:18:36 +00:00
steve 7de4108bad Add %cvt/ir and %cvt/ri instructions, and support
real values passed as arguments to VPI tasks.
2003-01-26 18:16:22 +00:00
steve 9a5a00f836 Add thread word array, and add the instructions,
%add/wr, %cmp/wr, %load/wr, %mul/wr and %set/wr.
2003-01-25 23:48:05 +00:00
steve 07a427bf28 Detect null arguments to concatenation operator. 2003-01-19 00:35:39 +00:00
steve dfc9a9474a Add a dummy function to reduce confusion on some systems. 2003-01-19 00:03:23 +00:00
steve 54206ef92b Make sure to use local system.vpi. 2003-01-18 23:56:06 +00:00
steve ddd43f1378 Add a means to clear the module search path. 2003-01-18 23:55:35 +00:00
65 changed files with 2434 additions and 1149 deletions
+4 -4
View File
@@ -16,7 +16,7 @@
# 59 Temple Place - Suite 330
# Boston, MA 02111-1307, USA
#
#ident "$Id: Makefile.in,v 1.141 2003/01/10 03:06:32 steve Exp $"
#ident "$Id: Makefile.in,v 1.143 2003/01/26 21:15:58 steve Exp $"
#
#
SHELL = /bin/sh
@@ -96,7 +96,7 @@ endif
check: all
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) check); done
driver/iverilog -Ccheck.conf -ocheck.vvp -tvvp-check -B./ivlpp $(srcdir)/examples/hello.vl
vvp/vvp -M./vpi ./check.vvp | grep 'Hello, World'
vvp/vvp -M- -M./vpi ./check.vvp | grep 'Hello, World'
clean:
rm -f *.o parse.cc parse.cc.output parse.h dep/*.d lexor.cc lexor_keyword.cc ivl@EXEEXT@ libivl.a libvpi.a iverilog-vpi
@@ -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)
+9 -1
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
View File
@@ -0,0 +1,46 @@
/*
* Copyright (c) 2003 Stephen Williams ([email protected])
*
* 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
View File
@@ -0,0 +1,63 @@
#ifndef __PData_H
#define __PData_H
/*
* Copyright (c) 2003 Stephen Williams ([email protected])
*
* 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
+5 -2
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.
*
+22 -1
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.
+11 -1
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.
*
+23 -6
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
+30 -5
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.23 2002/11/21 23:27:51 steve Exp $"
#ident "$Id: elab_lval.cc,v 1.25 2003/01/26 21:15:58 steve Exp $"
#endif
# include "config.h"
@@ -103,6 +103,14 @@ NetAssign_* PEConcat::elaborate_lval(Design*des, NetScope*scope) const
NetAssign_*res = 0;
for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) {
if (parms_[idx] == 0) {
cerr << get_line() << ": error: Empty expressions "
<< "not allowed in concatenations." << endl;
des->errors += 1;
continue;
}
NetAssign_*tmp = parms_[idx]->elaborate_lval(des, scope);
/* If the l-value doesn't elaborate, the error was
@@ -130,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() <<
@@ -149,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() <<
@@ -329,6 +347,13 @@ 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.
*
* Revision 1.23 2002/11/21 23:27:51 steve
* Precalculate indices to l-value arrays.
*
+12 -1
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_net.cc,v 1.104 2003/01/17 05:48:35 steve Exp $"
#ident "$Id: elab_net.cc,v 1.105 2003/01/19 00:35:39 steve Exp $"
#endif
# include "config.h"
@@ -1458,6 +1458,14 @@ NetNet* PEConcat::elaborate_lnet(Design*des, NetScope*scope,
/* Elaborate the operands of the concatenation. */
for (unsigned idx = 0 ; idx < nets.count() ; idx += 1) {
if (parms_[idx] == 0) {
cerr << get_line() << ": error: Empty expressions "
<< "not allowed in concatenations." << endl;
errors += 1;
continue;
}
nets[idx] = parms_[idx]->elaborate_lnet(des, scope,
implicit_net_ok);
if (nets[idx] == 0)
@@ -2276,6 +2284,9 @@ NetNet* PEUnary::elaborate_net(Design*des, NetScope*scope,
/*
* $Log: elab_net.cc,v $
* Revision 1.105 2003/01/19 00:35:39 steve
* Detect null arguments to concatenation operator.
*
* Revision 1.104 2003/01/17 05:48:35 steve
* Remove useless variable.
*
+21 -1
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.
+18 -20
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.
*
+18 -1
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.
*
+13 -1
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.
*
+54 -4
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
+3 -2
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);
}
/*
+20 -3
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.
*
+29 -1
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.
*
+172 -1
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.12 2003/01/27 00:14:37 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)
{
@@ -240,8 +344,75 @@ bool NetESelect::set_width(unsigned w)
return false;
}
NetESFunc::NetESFunc(const string&n, unsigned width, unsigned np)
: name_(0)
{
name_ = new char [n.length()+1];
strcpy(name_, n.c_str());
expr_width(width);
nparms_ = np;
parms_ = new NetExpr*[np];
for (unsigned idx = 0 ; idx < nparms_ ; idx += 1)
parms_[idx] = 0;
}
NetESFunc::~NetESFunc()
{
for (unsigned idx = 0 ; idx < nparms_ ; idx += 1)
if (parms_[idx]) delete parms_[idx];
delete[]parms_;
delete[]name_;
}
const char* NetESFunc::name() const
{
return name_;
}
unsigned NetESFunc::nparms() const
{
return nparms_;
}
void NetESFunc::parm(unsigned idx, NetExpr*v)
{
assert(idx < nparms_);
if (parms_[idx])
delete parms_[idx];
parms_[idx] = v;
}
const NetExpr* NetESFunc::parm(unsigned idx) const
{
assert(idx < nparms_);
return parms_[idx];
}
NetExpr* NetESFunc::parm(unsigned idx)
{
assert(idx < nparms_);
return parms_[idx];
}
NetExpr::TYPE NetESFunc::expr_type() const
{
if (strcmp(name_,"$realtime") == 0)
return ET_REAL;
return ET_VECTOR;
}
/*
* $Log: net_expr.cc,v $
* Revision 1.12 2003/01/27 00:14:37 steve
* Support in various contexts the $realtime
* system task.
*
* 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.
*
+15 -1
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.
*
+23 -1
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.
*
+9 -92
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.205 2003/01/27 00:14:37 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)
{
@@ -2029,57 +1989,6 @@ const NetScope* NetEScope::scope() const
return scope_;
}
NetESFunc::NetESFunc(const string&n, unsigned width, unsigned np)
: name_(0)
{
name_ = new char [n.length()+1];
strcpy(name_, n.c_str());
expr_width(width);
nparms_ = np;
parms_ = new NetExpr*[np];
for (unsigned idx = 0 ; idx < nparms_ ; idx += 1)
parms_[idx] = 0;
}
NetESFunc::~NetESFunc()
{
for (unsigned idx = 0 ; idx < nparms_ ; idx += 1)
if (parms_[idx]) delete parms_[idx];
delete[]parms_;
delete[]name_;
}
const char* NetESFunc::name() const
{
return name_;
}
unsigned NetESFunc::nparms() const
{
return nparms_;
}
void NetESFunc::parm(unsigned idx, NetExpr*v)
{
assert(idx < nparms_);
if (parms_[idx])
delete parms_[idx];
parms_[idx] = v;
}
const NetExpr* NetESFunc::parm(unsigned idx) const
{
assert(idx < nparms_);
return parms_[idx];
}
NetExpr* NetESFunc::parm(unsigned idx)
{
assert(idx < nparms_);
return parms_[idx];
}
NetESignal::NetESignal(NetNet*n)
: NetExpr(n->pin_count()), net_(n)
{
@@ -2286,6 +2195,14 @@ const NetProc*NetTaskDef::proc() const
/*
* $Log: netlist.cc,v $
* Revision 1.205 2003/01/27 00:14:37 steve
* Support in various contexts the $realtime
* system task.
*
* 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.
*
+115 -1
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.273 2003/01/27 00:14:37 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
@@ -2543,6 +2640,7 @@ class NetESFunc : public NetExpr {
NetExpr* parm(unsigned idx);
const NetExpr* parm(unsigned idx) const;
virtual TYPE expr_type() const;
virtual NexusSet* nex_input();
virtual bool set_width(unsigned);
virtual void dump(ostream&) const;
@@ -2797,6 +2895,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 +3002,7 @@ class NetScope {
map<string,param_expr_t>localparams_;
NetEvent *events_;
NetVariable*vars_;
NetNet *signals_;
NetMemory*memories_;
@@ -2999,6 +3102,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 +3191,14 @@ extern ostream& operator << (ostream&, NetNet::Type);
/*
* $Log: netlist.h,v $
* Revision 1.273 2003/01/27 00:14:37 steve
* Support in various contexts the $realtime
* system task.
*
* 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.
*
+9 -1
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.
*
+3 -5
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 ';'
+26 -1
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.
*
+10 -1
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.
*
+13 -231
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.
*/
+6 -2
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: set_width.cc,v 1.25 2002/11/13 03:03:08 steve Exp $"
#ident "$Id: set_width.cc,v 1.26 2003/01/26 21:02:21 steve Exp $"
#endif
# include "config.h"
@@ -257,6 +257,7 @@ bool NetEConst::set_width(unsigned w)
for (unsigned idx = value_.len() ; idx < w ; idx += 1)
tmp.set(idx, pad);
tmp.has_sign(value_.has_sign());
value_ = tmp;
expr_width(w);
@@ -370,6 +371,9 @@ bool NetEUReduce::set_width(unsigned w)
/*
* $Log: set_width.cc,v $
* Revision 1.26 2003/01/26 21:02:21 steve
* Remember to save signedness of number.
*
* Revision 1.25 2002/11/13 03:03:08 steve
* Do not truncate high bits of right shift.
*
+62 -274
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.
*
*/
+82 -3
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.31 2003/01/27 00:14:37 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,18 @@ void dll_target::expr_sfunc(const NetESFunc*net)
assert(expr);
expr->type_ = IVL_EX_SFUNC;
switch (net->expr_type()) {
case NetExpr::ET_VECTOR:
expr->value_= IVL_VT_VECTOR;
break;
case NetExpr::ET_REAL:
expr->value_= IVL_VT_REAL;
break;
case NetExpr::ET_VOID:
assert(0);
expr->value_= IVL_VT_VECTOR;
break;
}
expr->width_= net->expr_width();
expr->u_.sfunc_.name_ = strdup(net->name());
@@ -312,6 +366,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 +395,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 +411,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 +507,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 +540,35 @@ 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.31 2003/01/27 00:14:37 steve
* Support in various contexts the $realtime
* system task.
*
* 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.
+10 -1
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.
*
+46 -2
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.
*
+32 -2
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
+24 -2
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.
*
+11 -2
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.
*
+59 -5
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
+2 -2
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
+144 -73
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.90 2003/01/27 00:14:37 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.
@@ -1576,8 +1685,10 @@ static struct vector_info draw_sfunc_expr(ivl_expr_t exp, unsigned wid)
fprintf(vvp_out, ", $time");
else if (strcmp("$stime", ivl_expr_name(expr)) == 0)
fprintf(vvp_out, ", $stime");
else if (strcmp("$realtime", ivl_expr_name(expr)) == 0)
fprintf(vvp_out, ", $realtime");
else
fprintf(vvp_out, ", ?");
fprintf(vvp_out, ", ?%s?", ivl_expr_name(expr));
continue;
case IVL_EX_MEMORY:
@@ -1861,6 +1972,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 +2054,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 +2085,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 +2101,19 @@ struct vector_info draw_eval_expr(ivl_expr_t exp, int stuff_ok_flag)
/*
* $Log: eval_expr.c,v $
* Revision 1.90 2003/01/27 00:14:37 steve
* Support in various contexts the $realtime
* system task.
*
* 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.
*/
+223
View File
@@ -0,0 +1,223 @@
/*
* 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.2 2003/01/27 00:14:37 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;
}
static int draw_sfunc_real(ivl_expr_t exp)
{
int res;
assert(ivl_expr_parms(exp) == 0);
assert(ivl_expr_value(exp) == IVL_VT_REAL);
res = allocate_word();
fprintf(vvp_out, " %%vpi_func/r \"%s\", %d;\n",
ivl_expr_name(exp), res);
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_SFUNC:
res = draw_sfunc_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.2 2003/01/27 00:14:37 steve
* Support in various contexts the $realtime
* system task.
*
* Revision 1.1 2003/01/26 21:16:00 steve
* Rework expression parsing and elaboration to
* accommodate real/realtime values and expressions.
*
*/
+20 -33
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
+137 -13
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.78 2003/01/27 00:14:37 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));
@@ -1214,9 +1313,11 @@ static int show_system_task_call(ivl_statement_t net)
if (strcmp("$time", ivl_expr_name(expr)) == 0)
fprintf(vvp_out, ", $time");
else if (strcmp("$stime", ivl_expr_name(expr)) == 0)
fprintf(vvp_out, ", $time");
fprintf(vvp_out, ", $stime");
else if (strcmp("$realtime", ivl_expr_name(expr)) == 0)
fprintf(vvp_out, ", $realtime");
else
fprintf(vvp_out, ", ?");
fprintf(vvp_out, ", ?%s?", ivl_expr_name(expr));
continue;
case IVL_EX_MEMORY:
@@ -1231,16 +1332,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 +1565,14 @@ int draw_func_definition(ivl_scope_t scope)
/*
* $Log: vvp_process.c,v $
* Revision 1.78 2003/01/27 00:14:37 steve
* Support in various contexts the $realtime
* system task.
*
* 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.
*
+22 -1
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
+11 -1
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.
*
+6 -1
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.
*
+25 -4
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: sys_display.c,v 1.48 2003/01/09 04:10:58 steve Exp $"
#ident "$Id: sys_display.c,v 1.49 2003/01/26 18:18:36 steve Exp $"
#endif
# include "config.h"
@@ -425,6 +425,14 @@ static int format_str(vpiHandle scope, unsigned int mcd,
cp += 1;
break;
case 'f':
case 'F':
format_char = 'f';
do_arg = 1;
value.format = vpiRealVal;
cp += 1;
break;
case 'h':
case 'H':
case 'x':
@@ -522,7 +530,6 @@ static int format_str(vpiHandle scope, unsigned int mcd,
break;
case 'e':
case 'f':
case 'g':
// new Verilog 2001 format specifiers...
case 'l':
@@ -559,8 +566,13 @@ static int format_str(vpiHandle scope, unsigned int mcd,
switch(format_char){
case 'c':
vpi_mcd_printf(mcd, "%c", value.value.str[strlen(value.value.str)-1]);
break;
vpi_mcd_printf(mcd, "%c", value.value.str[strlen(value.value.str)-1]);
break;
case 'f':
vpi_mcd_printf(mcd, "%f",
value.value.real);
break;
case 't':
format_time(mcd, fsize,
@@ -762,6 +774,12 @@ static void do_display(unsigned int mcd, struct strobe_cb_info*info)
vpi_mcd_printf(mcd, "%20u", value.value.time->low);
break;
case vpiRealVar:
value.format = vpiRealVal;
vpi_get_value(item, &value);
vpi_mcd_printf(mcd, "%f", value.value.real);
break;
default:
vpi_mcd_printf(mcd, "?");
break;
@@ -1556,6 +1574,9 @@ void sys_display_register()
/*
* $Log: sys_display.c,v $
* Revision 1.49 2003/01/26 18:18:36 steve
* Support display of real values and constants.
*
* Revision 1.48 2003/01/09 04:10:58 steve
* use userdata to save $display argument handles.
*
+56 -1
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: sys_time.c,v 1.5 2002/12/21 00:55:58 steve Exp $"
#ident "$Id: sys_time.c,v 1.6 2003/01/27 00:14:37 steve Exp $"
#endif
# include "config.h"
@@ -89,6 +89,49 @@ static int sys_time_calltf(char*name)
return 0;
}
static int sys_realtime_calltf(char*name)
{
s_vpi_value val;
s_vpi_time now;
vpiHandle call_handle;
vpiHandle mod;
int units, prec;
double scale;
call_handle = vpi_handle(vpiSysTfCall, 0);
assert(call_handle);
mod = module_of_function(call_handle);
now.type = vpiSimTime;
vpi_get_time(0, &now);
/* All the variants but $simtime return the time in units of
the local scope. The $simtime function returns the
simulation time. */
if (strcmp(name, "$simtime") == 0)
units = vpi_get(vpiTimePrecision, 0);
else
units = vpi_get(vpiTimeUnit, mod);
prec = vpi_get(vpiTimePrecision, 0);
scale = 1;
while (units > prec) {
scale *= 10;
units -= 1;
}
val.format = vpiRealVal;
val.value.real = now.low;
assert(now.high == 0);
val.value.real /= scale;
vpi_put_value(call_handle, &val, 0, vpiNoDelay);
return 0;
}
void sys_time_register()
{
s_vpi_systf_data tf_data;
@@ -101,6 +144,14 @@ void sys_time_register()
tf_data.user_data = "$time";
vpi_register_systf(&tf_data);
tf_data.type = vpiSysFunc;
tf_data.tfname = "$realtime";
tf_data.calltf = sys_realtime_calltf;
tf_data.compiletf = 0;
tf_data.sizetf = 0;
tf_data.user_data = "$realtime";
vpi_register_systf(&tf_data);
tf_data.type = vpiSysFunc;
tf_data.tfname = "$stime";
tf_data.calltf = sys_time_calltf;
@@ -120,6 +171,10 @@ void sys_time_register()
/*
* $Log: sys_time.c,v $
* Revision 1.6 2003/01/27 00:14:37 steve
* Support in various contexts the $realtime
* system task.
*
* Revision 1.5 2002/12/21 00:55:58 steve
* The $time system task returns the integer time
* scaled to the local units. Change the internal
+6 -1
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
*
+5 -4
View File
@@ -16,7 +16,7 @@
# 59 Temple Place - Suite 330
# Boston, MA 02111-1307, USA
#
#ident "$Id: Makefile.in,v 1.41 2003/01/10 03:06:32 steve Exp $"
#ident "$Id: Makefile.in,v 1.42 2003/01/25 23:48:05 steve Exp $"
#
#
SHELL = /bin/sh
@@ -62,13 +62,14 @@ check: all
./vvp -M../vpi $(srcdir)/examples/hello.vvp | grep 'Hello, World.'
V = vpi_modules.o vpi_callback.o vpi_const.o vpi_event.o vpi_iter.o vpi_mcd.o \
vpi_priv.o vpi_scope.o vpi_signal.o vpi_tasks.o vpi_time.o vpi_memory.o \
vpi_vthr_vector.o vpip_bin.o vpip_hex.o vpip_oct.o vpip_to_dec.o vvp_vpi.o
vpi_priv.o vpi_scope.o vpi_real.o vpi_signal.o vpi_tasks.o vpi_time.o \
vpi_memory.o vpi_vthr_vector.o vpip_bin.o vpip_hex.o vpip_oct.o \
vpip_to_dec.o vvp_vpi.o
O = main.o parse.o parse_misc.o lexor.o arith.o bufif.o compile.o debug.o \
functor.o fvectors.o npmos.o resolv.o symbols.o ufunc.o codes.o vthread.o \
schedule.o statistics.o tables.o udp.o memory.o force.o event.o \
logic.o delay.o $V
logic.o delay.o words.o $V
ifeq (@WIN32@,yes)
# Under Windows (mingw) I need to make the ivl.exe in two steps.
+16 -1
View File
@@ -1,7 +1,7 @@
/*
* Copyright (c) 2001 Stephen Williams ([email protected])
*
* $Id: README.txt,v 1.40 2002/03/18 00:19:34 steve Exp $
* $Id: README.txt,v 1.41 2003/01/25 23:48:06 steve Exp $
*/
VVP SIMULATION ENGINE
@@ -386,6 +386,21 @@ to trigger this event. Only one of the input events needs to trigger
to make this one go.
WORD STATEMENTS:
Verilog includes some scalered word types available to the programmer,
including real variables, and possible extension types that the code
generator can transparently use. Variables of these special types are
declared with .word statements:
<label> .word <type>, "vpi name";
The <type> values supported are listed below. The vpi name is the base
name given to the VPI object that is created.
real - represents a double precision real variable.
RESOLVER STATEMENTS:
Resolver statements are strength-aware functors with 4 inputs, but
+18 -17
View File
@@ -1,7 +1,7 @@
#ifndef __codes_H
#define __codes_H
/*
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
* Copyright (c) 2001-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: codes.h,v 1.54 2002/11/21 22:43:13 steve Exp $"
#ident "$Id: codes.h,v 1.56 2003/01/26 18:16:22 steve Exp $"
#endif
@@ -36,6 +36,7 @@ typedef bool (*vvp_code_fun)(vthread_t thr, vvp_code_t code);
* access to the thread context.
*/
extern bool of_ADD(vthread_t thr, vvp_code_t code);
extern bool of_ADD_WR(vthread_t thr, vvp_code_t code);
extern bool of_ADDI(vthread_t thr, vvp_code_t code);
extern bool of_AND(vthread_t thr, vvp_code_t code);
extern bool of_ANDR(vthread_t thr, vvp_code_t code);
@@ -50,8 +51,11 @@ extern bool of_CASSIGN(vthread_t thr, vvp_code_t code);
extern bool of_CMPIU(vthread_t thr, vvp_code_t code);
extern bool of_CMPS(vthread_t thr, vvp_code_t code);
extern bool of_CMPU(vthread_t thr, vvp_code_t code);
extern bool of_CMPWR(vthread_t thr, vvp_code_t code);
extern bool of_CMPX(vthread_t thr, vvp_code_t code);
extern bool of_CMPZ(vthread_t thr, vvp_code_t code);
extern bool of_CVT_IR(vthread_t thr, vvp_code_t code);
extern bool of_CVT_RI(vthread_t thr, vvp_code_t code);
extern bool of_DEASSIGN(vthread_t thr, vvp_code_t code);
extern bool of_DELAY(vthread_t thr, vvp_code_t code);
extern bool of_DELAYX(vthread_t thr, vvp_code_t code);
@@ -76,10 +80,13 @@ extern bool of_LOAD(vthread_t thr, vvp_code_t code);
extern bool of_LOAD_MEM(vthread_t thr, vvp_code_t code);
extern bool of_LOAD_NX(vthread_t thr, vvp_code_t code);
extern bool of_LOAD_VEC(vthread_t thr, vvp_code_t code);
extern bool of_LOAD_WR(vthread_t thr, vvp_code_t code);
extern bool of_LOAD_X(vthread_t thr, vvp_code_t code);
extern bool of_LOADI_WR(vthread_t thr, vvp_code_t code);
extern bool of_MOD(vthread_t thr, vvp_code_t code);
extern bool of_MOV(vthread_t thr, vvp_code_t code);
extern bool of_MUL(vthread_t thr, vvp_code_t code);
extern bool of_MUL_WR(vthread_t thr, vvp_code_t code);
extern bool of_MULI(vthread_t thr, vvp_code_t code);
extern bool of_NAND(vthread_t thr, vvp_code_t code);
extern bool of_NANDR(vthread_t thr, vvp_code_t code);
@@ -92,6 +99,7 @@ extern bool of_RELEASE(vthread_t thr, vvp_code_t code);
extern bool of_SET(vthread_t thr, vvp_code_t code);
extern bool of_SET_MEM(vthread_t thr, vvp_code_t code);
extern bool of_SET_VEC(vthread_t thr, vvp_code_t code);
extern bool of_SET_WORDR(vthread_t thr, vvp_code_t code);
extern bool of_SET_X0(vthread_t thr, vvp_code_t code);
extern bool of_SHIFTL_I0(vthread_t thr, vvp_code_t code);
extern bool of_SHIFTR_I0(vthread_t thr, vvp_code_t code);
@@ -160,6 +168,14 @@ extern vvp_code_t codespace_index(vvp_cpoint_t ptr);
/*
* $Log: codes.h,v $
* Revision 1.56 2003/01/26 18:16:22 steve
* Add %cvt/ir and %cvt/ri instructions, and support
* real values passed as arguments to VPI tasks.
*
* Revision 1.55 2003/01/25 23:48:06 steve
* Add thread word array, and add the instructions,
* %add/wr, %cmp/wr, %load/wr, %mul/wr and %set/wr.
*
* Revision 1.54 2002/11/21 22:43:13 steve
* %set/x0 instruction to support bounds checking.
*
@@ -207,20 +223,5 @@ extern vvp_code_t codespace_index(vvp_cpoint_t ptr);
*
* Revision 1.39 2002/04/14 18:41:34 steve
* Support signed integer division.
*
* Revision 1.38 2002/03/18 00:19:34 steve
* Add the .ufunc statement.
*
* Revision 1.37 2001/11/07 03:34:42 steve
* Use functor pointers where vvp_ipoint_t is unneeded.
*
* Revision 1.36 2001/11/01 03:00:19 steve
* Add force/cassign/release/deassign support. (Stephan Boettcher)
*
* Revision 1.35 2001/10/16 01:26:54 steve
* Add %div support (Anthony Bybell)
*
* Revision 1.34 2001/08/26 22:59:32 steve
* Add the assign/x0 and set/x opcodes.
*/
#endif
+36 -66
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
* Copyright (c) 2001-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: compile.cc,v 1.147 2002/12/21 00:55:58 steve Exp $"
#ident "$Id: compile.cc,v 1.150 2003/01/27 00:14:37 steve Exp $"
#endif
# include "arith.h"
@@ -83,6 +83,7 @@ struct opcode_table_s {
const static struct opcode_table_s opcode_table[] = {
{ "%add", of_ADD, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
{ "%add/wr", of_ADD_WR, 2, {OA_BIT1, OA_BIT2, OA_NONE} },
{ "%addi", of_ADDI, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
{ "%and", of_AND, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
{ "%and/r", of_ANDR, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
@@ -96,9 +97,12 @@ const static struct opcode_table_s opcode_table[] = {
{ "%cassign",of_CASSIGN,2, {OA_FUNC_PTR, OA_FUNC_PTR2,OA_NONE} },
{ "%cmp/s", of_CMPS, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
{ "%cmp/u", of_CMPU, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
{ "%cmp/wr", of_CMPWR, 2, {OA_BIT1, OA_BIT2, OA_NONE} },
{ "%cmp/x", of_CMPX, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
{ "%cmp/z", of_CMPZ, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
{ "%cmpi/u", of_CMPIU, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
{ "%cvt/ir", of_CVT_IR, 2, {OA_BIT1, OA_BIT2, OA_NONE} },
{ "%cvt/ri", of_CVT_RI, 2, {OA_BIT1, OA_BIT2, OA_NONE} },
{ "%deassign",of_DEASSIGN,2,{OA_FUNC_PTR, OA_BIT1, OA_NONE} },
{ "%delay", of_DELAY, 1, {OA_NUMBER, OA_NONE, OA_NONE} },
{ "%delayx", of_DELAYX, 1, {OA_NUMBER, OA_NONE, OA_NONE} },
@@ -121,10 +125,13 @@ const static struct opcode_table_s opcode_table[] = {
{ "%load/m", of_LOAD_MEM,2, {OA_BIT1, OA_MEM_PTR, OA_NONE} },
{ "%load/nx",of_LOAD_NX,3, {OA_BIT1, OA_VPI_PTR, OA_BIT2} },
{ "%load/v", of_LOAD_VEC,3, {OA_BIT1, OA_FUNC_PTR, OA_BIT2} },
{ "%load/x", of_LOAD_X, 3, {OA_BIT1, OA_FUNC_PTR, OA_BIT2} },
{ "%load/wr",of_LOAD_WR,2, {OA_BIT1, OA_VPI_PTR, OA_BIT2} },
{ "%load/x", of_LOAD_X, 3, {OA_BIT1, OA_FUNC_PTR, OA_NONE} },
{ "%loadi/wr",of_LOADI_WR,3,{OA_BIT1, OA_NUMBER, OA_BIT2} },
{ "%mod", of_MOD, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
{ "%mov", of_MOV, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
{ "%mul", of_MUL, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
{ "%mul/wr", of_MUL_WR, 2, {OA_BIT1, OA_BIT2, OA_NONE} },
{ "%muli", of_MULI, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
{ "%nand", of_NAND, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
{ "%nand/r", of_NANDR, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
@@ -137,6 +144,7 @@ const static struct opcode_table_s opcode_table[] = {
{ "%set", of_SET, 2, {OA_FUNC_PTR, OA_BIT1, OA_NONE} },
{ "%set/m", of_SET_MEM,2, {OA_MEM_PTR, OA_BIT1, OA_NONE} },
{ "%set/v", of_SET_VEC,3, {OA_FUNC_PTR, OA_BIT1, OA_BIT2} },
{ "%set/wr", of_SET_WORDR,2,{OA_VPI_PTR, OA_BIT1, OA_NONE} },
{ "%set/x0", of_SET_X0, 3, {OA_FUNC_PTR, OA_BIT1, OA_BIT2} },
{ "%shiftl/i0", of_SHIFTL_I0, 2, {OA_BIT1,OA_NUMBER, OA_NONE} },
{ "%shiftr/i0", of_SHIFTR_I0, 2, {OA_BIT1,OA_NUMBER, OA_NONE} },
@@ -397,7 +405,13 @@ bool vpi_handle_resolv_list_s::resolve(bool mes)
val.ptr = vpip_make_vthr_vector(base, wid, signed_flag);
sym_set_value(sym_vpi, label, val);
} else if (2 == sscanf(label, "W<%u,%[r]>%n", &base, ss, &n)
&& n == strlen(label)) {
val.ptr = vpip_make_vthr_word(base, ss);
sym_set_value(sym_vpi, label, val);
}
}
if (!val.ptr) {
@@ -430,6 +444,12 @@ void compile_vpi_lookup(vpiHandle *handle, char*label)
return;
}
if (strcmp(label, "$realtime") == 0) {
*handle = vpip_sim_time(vpip_peek_current_scope());
free(label);
return;
}
struct vpi_handle_resolv_list_s*res
= new struct vpi_handle_resolv_list_s;
@@ -1395,7 +1415,7 @@ void compile_vpi_call(char*label, char*name, unsigned argc, vpiHandle*argv)
}
void compile_vpi_func_call(char*label, char*name,
unsigned vbit, unsigned vwid,
unsigned vbit, int vwid,
unsigned argc, vpiHandle*argv)
{
if (label)
@@ -1493,6 +1513,18 @@ void compile_net(char*label, char*name, int msb, int lsb, bool signed_flag,
/*
* $Log: compile.cc,v $
* Revision 1.150 2003/01/27 00:14:37 steve
* Support in various contexts the $realtime
* system task.
*
* Revision 1.149 2003/01/26 18:16:22 steve
* Add %cvt/ir and %cvt/ri instructions, and support
* real values passed as arguments to VPI tasks.
*
* Revision 1.148 2003/01/25 23:48:06 steve
* Add thread word array, and add the instructions,
* %add/wr, %cmp/wr, %load/wr, %mul/wr and %set/wr.
*
* Revision 1.147 2002/12/21 00:55:58 steve
* The $time system task returns the integer time
* scaled to the local units. Change the internal
@@ -1538,67 +1570,5 @@ void compile_net(char*label, char*name, int msb, int lsb, bool signed_flag,
*
* Revision 1.134 2002/07/05 17:14:15 steve
* Names of vpi objects allocated as vpip_strings.
*
* Revision 1.133 2002/07/05 04:40:59 steve
* Symbol table uses more efficient key string allocator,
* and remove all the symbol tables after compile is done.
*
* Revision 1.132 2002/07/05 02:50:58 steve
* Remove the vpi object symbol table after compile.
*
* Revision 1.131 2002/06/21 04:58:55 steve
* Add support for special integer vectors.
*
* Revision 1.130 2002/06/02 18:55:58 steve
* Add %cmpi/u instruction.
*
* Revision 1.129 2002/05/31 20:04:22 steve
* Add the %muli instruction.
*
* Revision 1.128 2002/05/29 16:29:34 steve
* Add %addi, which is faster to simulate.
*
* Revision 1.127 2002/05/10 16:00:57 steve
* Support scope iterate over vpiNet,vpiReg/vpiMemory.
*
* Revision 1.126 2002/05/07 04:15:43 steve
* Fix uninitialized memory accesses.
*
* Revision 1.125 2002/04/21 22:29:49 steve
* Add the assign/d instruction for computed delays.
*
* Revision 1.124 2002/04/14 18:41:34 steve
* Support signed integer division.
*
* Revision 1.123 2002/04/14 02:56:19 steve
* Support signed expressions through to VPI.
*
* Revision 1.122 2002/03/18 00:19:34 steve
* Add the .ufunc statement.
*
* Revision 1.121 2002/03/08 05:41:45 steve
* Debug code for write to constants.
*
* Revision 1.120 2002/01/11 05:21:47 steve
* Magic stime object support.
*
* Revision 1.119 2002/01/06 03:15:13 steve
* Support weak functor inputs.
*
* Revision 1.118 2002/01/03 04:19:02 steve
* Add structural modulus support down to vvp.
*
* Revision 1.117 2001/12/15 02:11:51 steve
* Give tri0 and tri1 their proper strengths.
*
* Revision 1.116 2001/12/15 01:54:38 steve
* Support tri0 and tri1 resolvers.
*
* Revision 1.115 2001/12/06 03:31:24 steve
* Support functor delays for gates and UDP devices.
* (Stephan Boettcher)
*
* Revision 1.114 2001/11/07 03:34:42 steve
* Use functor pointers where vvp_ipoint_t is unneeded.
*/
+20 -3
View File
@@ -1,7 +1,7 @@
#ifndef __compile_H
#define __compile_H
/*
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
* Copyright (c) 2001-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: compile.h,v 1.46 2002/12/21 00:55:58 steve Exp $"
#ident "$Id: compile.h,v 1.48 2003/01/27 00:14:37 steve Exp $"
#endif
# include <stdio.h>
@@ -188,6 +188,11 @@ extern void compile_event(char*label, char*type,
unsigned argc, struct symb_s*argv);
extern void compile_named_event(char*label, char*type);
/*
* Word declarations include a label, a type symbol, and a vpi name.
*/
extern void compile_word(char*label, char*type, char*name);
/*
* A code statement is a label, an opcode and up to 3 operands. There
* are a few lexical types that the parser recognizes of the operands,
@@ -219,8 +224,12 @@ extern void compile_disable(char*label, struct symb_s symb);
extern void compile_vpi_call(char*label, char*name,
unsigned argc, vpiHandle*argv);
/* Compile a function call. The vbit and vwid encode the return
type. If the vwid >0, the return type is a vector. If the vwid is
<0, the return type is -vpiRealConst or some other constant subtype
code that represents the function type. */
extern void compile_vpi_func_call(char*label, char*name,
unsigned vbit, unsigned vwid,
unsigned vbit, int vwid,
unsigned argc, vpiHandle*argv);
extern void compile_fork(char*label, struct symb_s targ_s,
@@ -252,6 +261,14 @@ extern void compile_net(char*label, char*name,
/*
* $Log: compile.h,v $
* Revision 1.48 2003/01/27 00:14:37 steve
* Support in various contexts the $realtime
* system task.
*
* Revision 1.47 2003/01/25 23:48:06 steve
* Add thread word array, and add the instructions,
* %add/wr, %cmp/wr, %load/wr, %mul/wr and %set/wr.
*
* Revision 1.46 2002/12/21 00:55:58 steve
* The $time system task returns the integer time
* scaled to the local units. Change the internal
+11 -1
View File
@@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: lexor.lex,v 1.35 2002/12/21 00:55:58 steve Exp $"
#ident "$Id: lexor.lex,v 1.37 2003/01/27 00:14:37 steve Exp $"
#endif
# include "parse_misc.h"
@@ -105,6 +105,7 @@
".var" { return K_VAR; }
".var/s" { return K_VAR_S; }
".var/i" { return K_VAR_I; /* integer */ }
".word" { return K_WORD; }
".udp" { return K_UDP; }
".udp/c"(omb)? { return K_UDP_C; }
".udp/s"(equ)? { return K_UDP_S; }
@@ -119,6 +120,7 @@
"%vpi_call" { return K_vpi_call; }
"%vpi_func" { return K_vpi_func; }
"%vpi_func/r" { return K_vpi_func_r; }
"%disable" { return K_disable; }
"%fork" { return K_fork; }
@@ -174,6 +176,14 @@ int yywrap()
/*
* $Log: lexor.lex,v $
* Revision 1.37 2003/01/27 00:14:37 steve
* Support in various contexts the $realtime
* system task.
*
* Revision 1.36 2003/01/25 23:48:06 steve
* Add thread word array, and add the instructions,
* %add/wr, %cmp/wr, %load/wr, %mul/wr and %set/wr.
*
* Revision 1.35 2002/12/21 00:55:58 steve
* The $time system task returns the integer time
* scaled to the local units. Change the internal
+8 -1
View File
@@ -17,15 +17,22 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: libvpi.c,v 1.1 2003/01/10 03:06:32 steve Exp $"
#ident "$Id: libvpi.c,v 1.2 2003/01/19 00:03:23 steve Exp $"
#endif
/*
* Things that should be statically linked by VPI modules go here.
*/
void __libvpi_c_dummy_function()
{
}
/*
* $Log: libvpi.c,v $
* Revision 1.2 2003/01/19 00:03:23 steve
* Add a dummy function to reduce confusion on some systems.
*
* Revision 1.1 2003/01/10 03:06:32 steve
* Remove vpithunk, and move libvpi to vvp directory.
*
+11 -2
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: main.cc,v 1.32 2003/01/06 23:57:26 steve Exp $"
#ident "$Id: main.cc,v 1.33 2003/01/18 23:55:35 steve Exp $"
#endif
# include "config.h"
@@ -157,6 +157,7 @@ int main(int argc, char*argv[])
" -h Print this help message.\n"
" -l file Logfile, '-' for <stderr>\n"
" -M path VPI module directory\n"
" -M - Clear VPI module path\n"
" -m module Load vpi module.\n"
" -v Verbose progress messages.\n" );
exit(0);
@@ -164,7 +165,12 @@ int main(int argc, char*argv[])
logfile_name = optarg;
break;
case 'M':
vpip_module_path[vpip_module_path_cnt++] = optarg;
if (strcmp(optarg,"-") == 0) {
vpip_module_path_cnt = 0;
vpip_module_path[0] = 0;
} else {
vpip_module_path[vpip_module_path_cnt++] = optarg;
}
break;
case 'm':
module_tab[module_cnt++] = optarg;
@@ -291,6 +297,9 @@ int main(int argc, char*argv[])
/*
* $Log: main.cc,v $
* Revision 1.33 2003/01/18 23:55:35 steve
* Add a means to clear the module search path.
*
* Revision 1.32 2003/01/06 23:57:26 steve
* Schedule wait lists of threads as a single event,
* to save on events. Also, improve efficiency of
+42 -1
View File
@@ -1,7 +1,7 @@
/*
* Copyright (c) 2001 Stephen Williams ([email protected])
*
* $Id: opcodes.txt,v 1.45 2002/11/21 22:43:13 steve Exp $
* $Id: opcodes.txt,v 1.47 2003/01/26 18:16:22 steve Exp $
*/
@@ -30,6 +30,10 @@ sum.
See also the %sub instruction.
* %add/wr <bit-l>, <bit-r>
* %addi <bit-l>, <imm>, <wid>
This instruction adds the immediate value (no x or z bits) into the
@@ -155,6 +159,12 @@ The %cmp/u and %cmp/s differ only in the handling of the lt bit. The
compare. In either case, if either operand constains x or z, then lt
bit gets the x value.
* %cmp/wr <bit-l>, <bit-r>
[compare real values.]
* %cmp/z <bit-l>, <bit-r>, <wid>
* %cmp/x <bit-l>, <bit-r>, <wid>
@@ -166,6 +176,14 @@ instruction will also treat x values in either operand as don't care.
Only bit 4 is set by these instructions.
* %cvt/ir <bit-l>, <bit-r>
* %cvt/ri <bit-l>, <bit-r>
Copy a word from r to l, converting int from real to integer in the
process.
* %delay <delay>
This opcode pauses the thread, and causes it to be rescheduled for a
@@ -325,6 +343,10 @@ This instruction load a value from a .net object bit. Since .net
objects don't really exist (they are only named indirection into the
netlist) this instruction indexes into the .net list of bits.
* %load/wr <bit>, <vpi-label>
This instruction reads a real value from the vpi-like object to a word
register.
* %load/x <bit>, <functor-label>, <idx>
@@ -334,6 +356,15 @@ bit is pulled from the addressed functor and loaded into the
destination bit. This function does not do any bounds checking.
* %loadi/wr <bit>, <mant>, <exp>
This opcode loads an immediate value, floating point, into the word
register selected by <bit>. The mantissa is an unsigned integer value,
up to 32 bits, that multiplied by 2**(<exp>-0x1000) to make a real
value. The sign bit is OR-ed into the <exp> value at bit 0x2000, and
is removed from the <exp> before calculating the real value.
* %mod <bit-l>, <bit-r>, <wid>
This instruction calculates the modulus %r of the left operand, and
@@ -359,6 +390,12 @@ are x or z, the result is x. Otherwise, the result is the arithmetic
product.
* %mul/wr <bit-l>, <bit-r>
This opcode multiplies two real words together. The result replaces
the left operand.
* %muli <bit-l>, <imm>, <wid>
This instruction is the same as %mul, but the second operand is an
@@ -459,6 +496,10 @@ address zero is the LSB of the first memory word. This instruction
sets only a single bit.
* %set/wr <vpi-label>, <bit>
This instruction writes a real word to the specified VPI-like object.
* %set/x0 <var-label>, <bit>, <top>
This sets the bit of a variable functor, the address calculated by
+21 -3
View File
@@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: parse.y,v 1.48 2002/12/21 00:55:58 steve Exp $"
#ident "$Id: parse.y,v 1.50 2003/01/27 00:14:37 steve Exp $"
#endif
# include "parse_misc.h"
@@ -63,8 +63,9 @@ extern FILE*yyin;
%token K_RESOLV K_SCOPE K_SHIFTL K_SHIFTR K_THREAD K_TIMESCALE K_UFUNC
%token K_UDP K_UDP_C K_UDP_S
%token K_MEM K_MEM_P K_MEM_I
%token K_FORCE
%token K_VAR K_VAR_S K_VAR_I K_vpi_call K_vpi_func K_disable K_fork
%token K_FORCE K_WORD
%token K_VAR K_VAR_S K_VAR_I K_vpi_call K_vpi_func K_vpi_func_r
%token K_disable K_fork
%token K_vpi_module K_vpi_time_precision
%token <text> T_INSTR
@@ -250,6 +251,11 @@ statement
{ compile_event($1, 0, $3.cnt, $3.vect); }
/* match word statements. */
| T_LABEL K_WORD T_SYMBOL ',' T_STRING ';'
{ compile_word($1, $3, $5); }
/* Instructions may have a label, and have zero or more
operands. The meaning of and restrictions on the operands depends
on the specific instruction. */
@@ -272,6 +278,10 @@ statement
T_NUMBER ',' T_NUMBER argument_opt ';'
{ compile_vpi_func_call($1, $3, $5, $7, $8.argc, $8.argv); }
| label_opt K_vpi_func_r T_STRING ',' T_NUMBER argument_opt ';'
{ compile_vpi_func_call($1, $3, $5, -vpiRealConst,
$6.argc, $6.argv); }
/* %disable statements are instructions that takes a scope reference
as an operand. It therefore is parsed uniquely. */
@@ -559,6 +569,14 @@ int compile_design(const char*path)
/*
* $Log: parse.y,v $
* Revision 1.50 2003/01/27 00:14:37 steve
* Support in various contexts the $realtime
* system task.
*
* Revision 1.49 2003/01/25 23:48:06 steve
* Add thread word array, and add the instructions,
* %add/wr, %cmp/wr, %load/wr, %mul/wr and %set/wr.
*
* Revision 1.48 2002/12/21 00:55:58 steve
* The $time system task returns the integer time
* scaled to the local units. Change the internal
+24 -63
View File
@@ -1,7 +1,7 @@
#ifndef __vpi_priv_H
#define __vpi_priv_H
/*
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
* Copyright (c) 2001-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: vpi_priv.h,v 1.42 2003/01/09 04:09:44 steve Exp $"
#ident "$Id: vpi_priv.h,v 1.45 2003/01/27 00:14:37 steve Exp $"
#endif
# include "vpi_user.h"
@@ -211,6 +211,11 @@ extern void vpip_run_named_event_callbacks(vpiHandle ref);
extern vpiHandle vpip_make_memory(vvp_memory_t mem);
/*
* These are the various variable types.
*/
extern vpiHandle vpip_make_real_var(const char*name);
/*
* When a loaded VPI module announces a system task/function, one
* __vpiUserSystf object is created to hold the definition of that
@@ -243,7 +248,8 @@ struct __vpiSysTaskCall {
/* Support for vpi_get_userdata. */
void*userdata;
/* These represent where in the vthread to put the return value. */
unsigned short vbit, vwid;
unsigned short vbit;
signed short vwid;
};
extern struct __vpiSysTaskCall*vpip_cur_task;
@@ -283,6 +289,8 @@ vpiHandle vpip_make_dec_const(struct __vpiDecConst*obj, int value);
vpiHandle vpip_make_vthr_vector(unsigned base, unsigned wid, bool signed_flag);
vpiHandle vpip_make_vthr_word(unsigned base, const char*type);
/*
* This function is called before any compilation to load VPI
* modules. This gives the modules a chance to announce their
@@ -314,7 +322,7 @@ extern unsigned vpip_module_path_cnt;
* not be released by the caller.
*/
extern vpiHandle vpip_build_vpi_call(const char*name,
unsigned vbit, unsigned vwid,
unsigned vbit, int vwid,
unsigned argc,
vpiHandle*argv);
@@ -385,6 +393,18 @@ extern char *need_result_buf(unsigned cnt, vpi_rbuf_t type);
/*
* $Log: vpi_priv.h,v $
* Revision 1.45 2003/01/27 00:14:37 steve
* Support in various contexts the $realtime
* system task.
*
* Revision 1.44 2003/01/26 18:16:22 steve
* Add %cvt/ir and %cvt/ri instructions, and support
* real values passed as arguments to VPI tasks.
*
* Revision 1.43 2003/01/25 23:48:06 steve
* Add thread word array, and add the instructions,
* %add/wr, %cmp/wr, %load/wr, %mul/wr and %set/wr.
*
* Revision 1.42 2003/01/09 04:09:44 steve
* Add vpi_put_userdata
*
@@ -431,64 +451,5 @@ extern char *need_result_buf(unsigned cnt, vpi_rbuf_t type);
* Support specified times in cbReadOnlySync, and
* add support for cbReadWriteSync.
* Keep simulation time in a 64bit number.
*
* Revision 1.30 2002/04/14 03:53:20 steve
* Allow signed constant vectors for call_vpi parameters.
*
* Revision 1.29 2002/04/14 02:56:19 steve
* Support signed expressions through to VPI.
*
* Revision 1.28 2002/02/03 01:01:51 steve
* Use Larrys bits-to-decimal-string code.
*
* Revision 1.27 2002/01/31 04:28:17 steve
* Full support for $readmem ranges (Tom Verbeure)
*
* Revision 1.26 2002/01/06 17:50:50 steve
* Support scope for functors. (Stephan Boettcher)
*
* Revision 1.25 2002/01/06 00:48:39 steve
* VPI access to root module scopes.
*
* Revision 1.24 2001/10/31 04:27:47 steve
* Rewrite the functor type to have fewer functor modes,
* and use objects to manage the different types.
* (Stephan Boettcher)
*
* Revision 1.23 2001/10/15 01:49:50 steve
* Support getting scope of scope, and scope of signals.
*
* Revision 1.22 2001/08/08 01:05:06 steve
* Initial implementation of vvp_fvectors.
* (Stephan Boettcher)
*
* Revision 1.21 2001/07/30 02:44:05 steve
* Cleanup defines and types for mingw compile.
*
* Revision 1.20 2001/07/26 03:13:51 steve
* Make the -M flag add module search paths.
*
* Revision 1.19 2001/07/11 02:27:21 steve
* Add support for REadOnlySync and monitors.
*
* Revision 1.18 2001/06/30 23:03:17 steve
* support fast programming by only writing the bits
* that are listed in the input file.
*
* Revision 1.17 2001/06/21 22:54:12 steve
* Support cbValueChange callbacks.
*
* Revision 1.16 2001/05/20 00:46:12 steve
* Add support for system function calls.
*
* Revision 1.15 2001/05/10 00:26:53 steve
* VVP support for memories in expressions,
* including general support for thread bit
* vectors as system task parameters.
* (Stephan Boettcher)
*
* Revision 1.14 2001/05/08 23:59:33 steve
* Add ivl and vvp.tgt support for memories in
* expressions and l-values. (Stephan Boettcher)
*/
#endif
+118
View File
@@ -0,0 +1,118 @@
/*
* 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: vpi_real.cc,v 1.2 2003/01/27 00:14:37 steve Exp $"
#endif
# include "vpi_priv.h"
# include <stdio.h>
# include <stdlib.h>
#ifdef HAVE_MALLOC_H
# include <malloc.h>
#endif
# include <assert.h>
struct __vpiRealVar {
struct __vpiHandle base;
const char*name;
double value;
};
static void real_var_get_value(vpiHandle ref, s_vpi_value*vp)
{
assert(ref->vpi_type->type_code == vpiRealVar);
static char buf[64];
struct __vpiRealVar*rfp = (struct __vpiRealVar*)ref;
switch (vp->format) {
case vpiObjTypeVal:
vp->format = vpiRealVal;
case vpiRealVal:
vp->value.real = rfp->value;
break;
case vpiDecStrVal:
sprintf(buf, "%0.0f", rfp->value);
vp->value.str = buf;
break;
default:
fprintf(stderr, "ERROR: Unsupported format code: %d\n",
vp->format);
assert(0);
}
}
static vpiHandle real_var_put_value(vpiHandle ref, p_vpi_value vp,
p_vpi_time, int)
{
assert(ref->vpi_type->type_code == vpiRealVar);
struct __vpiRealVar*rfp = (struct __vpiRealVar*)ref;
assert(vp->format == vpiRealVal);
rfp->value = vp->value.real;
return 0;
}
static int real_var_free_object(vpiHandle)
{
return 0;
}
static const struct __vpirt vpip_real_var_rt = {
vpiRealVar,
0,
0,
&real_var_get_value,
&real_var_put_value,
0,
0,
0,
real_var_free_object
};
vpiHandle vpip_make_real_var(const char*name)
{
struct __vpiRealVar*obj = (struct __vpiRealVar*)
malloc(sizeof(struct __vpiRealVar));
obj->base.vpi_type = &vpip_real_var_rt;
obj->name = vpip_string(name);
obj->value = 0.0;
return &obj->base;
}
/*
* $Log: vpi_real.cc,v $
* Revision 1.2 2003/01/27 00:14:37 steve
* Support in various contexts the $realtime
* system task.
*
* Revision 1.1 2003/01/25 23:48:06 steve
* Add thread word array, and add the instructions,
* %add/wr, %cmp/wr, %load/wr, %mul/wr and %set/wr.
*
*/
+60 -7
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: vpi_tasks.cc,v 1.18 2003/01/09 04:09:44 steve Exp $"
#ident "$Id: vpi_tasks.cc,v 1.19 2003/01/27 00:14:37 steve Exp $"
#endif
/*
@@ -118,7 +118,7 @@ static vpiHandle sysfunc_put_value(vpiHandle ref, p_vpi_value vp,
case vpiIntVal: {
long val = vp->value.integer;
for (unsigned idx = 0 ; idx < rfp->vwid ; idx += 1) {
for (int idx = 0 ; idx < rfp->vwid ; idx += 1) {
vthread_put_bit(vpip_current_vthread,
rfp->vbit+idx, val&1);
val >>= 1;
@@ -150,7 +150,7 @@ static vpiHandle sysfunc_put_value(vpiHandle ref, p_vpi_value vp,
unsigned long aval = vp->value.vector->aval;
unsigned long bval = vp->value.vector->bval;
for (unsigned idx = 0 ; idx < rfp->vwid ; idx += 1) {
for (int idx = 0 ; idx < rfp->vwid ; idx += 1) {
int bit = (aval&1) | (((bval^aval)<<1)&2);
vthread_put_bit(vpip_current_vthread,
@@ -169,6 +169,34 @@ static vpiHandle sysfunc_put_value(vpiHandle ref, p_vpi_value vp,
return 0;
}
static vpiHandle sysfunc_put_real_value(vpiHandle ref, p_vpi_value vp,
p_vpi_time t, int flags)
{
assert(ref->vpi_type->type_code == vpiSysFuncCall);
struct __vpiSysTaskCall*rfp = (struct __vpiSysTaskCall*)ref;
/* delays are not allowed. */
assert(flags == vpiNoDelay);
/* Make sure this is a real valued function. */
assert(rfp->vwid == -vpiRealConst);
double val = 0.0;
switch (vp->format) {
case vpiRealVal:
val = vp->value.real;
break;
default:
assert(0);
}
vthread_put_real(vpip_current_vthread, rfp->vbit, val);
return 0;
}
static const struct __vpirt vpip_sysfunc_rt = {
vpiSysFuncCall,
@@ -180,6 +208,16 @@ static const struct __vpirt vpip_sysfunc_rt = {
systask_iter
};
static const struct __vpirt vpip_sysfunc_real_rt = {
vpiSysFuncCall,
0,
0,
0,
sysfunc_put_real_value,
systask_handle,
systask_iter
};
/* **** Manipulate the internal datastructures. **** */
static struct __vpiUserSystf**def_table = 0;
@@ -225,7 +263,7 @@ static struct __vpiUserSystf* vpip_find_systf(const char*name)
* describes the call, and return it. The %vpi_call instruction will
* store this handle for when it is executed.
*/
vpiHandle vpip_build_vpi_call(const char*name, unsigned vbit, unsigned vwid,
vpiHandle vpip_build_vpi_call(const char*name, unsigned vbit, int vwid,
unsigned argc, vpiHandle*argv)
{
struct __vpiUserSystf*defn = vpip_find_systf(name);
@@ -237,7 +275,7 @@ vpiHandle vpip_build_vpi_call(const char*name, unsigned vbit, unsigned vwid,
switch (defn->info.type) {
case vpiSysTask:
if (vwid > 0) {
if (vwid != 0) {
fprintf(stderr, "%s: This is a system Task, "
"you cannot call it as a Function\n", name);
return 0;
@@ -251,7 +289,6 @@ vpiHandle vpip_build_vpi_call(const char*name, unsigned vbit, unsigned vwid,
"you cannot call it as a Task\n", name);
return 0;
}
assert(vwid > 0);
break;
default:
@@ -266,7 +303,19 @@ vpiHandle vpip_build_vpi_call(const char*name, unsigned vbit, unsigned vwid,
break;
case vpiSysFunc:
obj->base.vpi_type = &vpip_sysfunc_rt;
if (vwid > 0) {
obj->base.vpi_type = &vpip_sysfunc_rt;
} else switch (vwid) {
case -vpiRealConst:
obj->base.vpi_type = &vpip_sysfunc_real_rt;
break;
default:
assert(0);
obj->base.vpi_type = &vpip_sysfunc_rt;
}
break;
}
@@ -365,6 +414,10 @@ void* vpi_get_userdata(vpiHandle ref)
/*
* $Log: vpi_tasks.cc,v $
* Revision 1.19 2003/01/27 00:14:37 steve
* Support in various contexts the $realtime
* system task.
*
* Revision 1.18 2003/01/09 04:09:44 steve
* Add vpi_put_userdata
*
+64 -1
View File
@@ -18,7 +18,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: vpi_vthr_vector.cc,v 1.8 2002/08/12 01:35:09 steve Exp $"
#ident "$Id: vpi_vthr_vector.cc,v 1.9 2003/01/26 18:16:22 steve Exp $"
#endif
/*
@@ -360,9 +360,72 @@ vpiHandle vpip_make_vthr_vector(unsigned base, unsigned wid, bool signed_flag)
return &obj->base;
}
struct __vpiVThrWord {
struct __vpiHandle base;
char* name;
int subtype;
unsigned short index;
};
static void vthr_real_get_value(vpiHandle ref, s_vpi_value*vp)
{
assert(ref->vpi_type->type_code==vpiConstant);
struct __vpiVThrWord*obj = (struct __vpiVThrWord*)ref;
static char buf[64];
double val = vthread_get_real(vpip_current_vthread, obj->index);
switch (vp->format) {
case vpiObjTypeVal:
vp->format = vpiRealVal;
case vpiRealVal:
vp->value.real = val;
break;
case vpiDecStrVal:
sprintf(buf, "%0.0f", val);
vp->value.str = buf;
break;
default:
vp->format = vpiSuppressVal;
break;
}
}
static const struct __vpirt vpip_vthr_const_real_rt = {
vpiConstant,
0,
0,
vthr_real_get_value,
0,
0,
0
};
vpiHandle vpip_make_vthr_word(unsigned base, const char*type)
{
struct __vpiVThrWord*obj = (struct __vpiVThrWord*)
malloc(sizeof(struct __vpiVThrWord));
assert(type[0] == 'r');
obj->base.vpi_type = &vpip_vthr_const_real_rt;
obj->name = "W<>";
obj->subtype = vpiRealConst;
obj->index = base;
return &obj->base;
}
/*
* $Log: vpi_vthr_vector.cc,v $
* Revision 1.9 2003/01/26 18:16:22 steve
* Add %cvt/ir and %cvt/ri instructions, and support
* real values passed as arguments to VPI tasks.
*
* Revision 1.8 2002/08/12 01:35:09 steve
* conditional ident string using autoconfig.
*
+135 -166
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2002 Stephen Williams (steve@icarus.com)
* Copyright (c) 2001-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: vthread.cc,v 1.96 2003/01/06 23:57:26 steve Exp $"
#ident "$Id: vthread.cc,v 1.99 2003/01/27 00:14:37 steve Exp $"
#endif
# include "vthread.h"
@@ -34,6 +34,7 @@
# include <stdlib.h>
# include <limits.h>
# include <string.h>
# include <math.h>
# include <assert.h>
#include <stdio.h>
@@ -96,7 +97,13 @@ struct vthread_s {
unsigned long pc;
/* These hold the private thread bits. */
unsigned long *bits;
long index[4];
/* These are the word registers. */
union {
long w_int;
double w_real;
} words[16];
unsigned nbits :16;
/* My parent sets this when it wants me to wake it up. */
unsigned schedule_parent_on_end :1;
@@ -175,6 +182,16 @@ void vthread_put_bit(struct vthread_s*thr, unsigned addr, unsigned bit)
thr_put_bit(thr, addr, bit);
}
double vthread_get_real(struct vthread_s*thr, unsigned addr)
{
return thr->words[addr].w_real;
}
void vthread_put_real(struct vthread_s*thr, unsigned addr, double val)
{
thr->words[addr].w_real = val;
}
static unsigned long* vector_to_array(struct vthread_s*thr,
unsigned addr, unsigned wid)
{
@@ -423,6 +440,14 @@ bool of_ADD(vthread_t thr, vvp_code_t cp)
return true;
}
bool of_ADD_WR(vthread_t thr, vvp_code_t cp)
{
double l = thr->words[cp->bit_idx[0]].w_real;
double r = thr->words[cp->bit_idx[1]].w_real;
thr->words[cp->bit_idx[0]].w_real = l + r;
return true;
}
/*
* This is %addi, add-immediate. The first value is a vector, the
* second value is the immediate value in the bin_idx[1] position. The
@@ -492,7 +517,7 @@ bool of_ASSIGN_D(vthread_t thr, vvp_code_t cp)
{
assert(cp->bit_idx[0] < 4);
unsigned char bit_val = thr_get_bit(thr, cp->bit_idx[1]);
schedule_assign(cp->iptr, bit_val, thr->index[cp->bit_idx[0]]);
schedule_assign(cp->iptr, bit_val, thr->words[cp->bit_idx[0]].w_int);
return true;
}
@@ -502,7 +527,7 @@ bool of_ASSIGN_D(vthread_t thr, vvp_code_t cp)
*/
bool of_ASSIGN_V0(vthread_t thr, vvp_code_t cp)
{
unsigned wid = thr->index[0];
unsigned wid = thr->words[0].w_int;
assert(wid > 0);
assert(wid < 0x10000);
@@ -525,7 +550,7 @@ bool of_ASSIGN_V0(vthread_t thr, vvp_code_t cp)
bool of_ASSIGN_X0(vthread_t thr, vvp_code_t cp)
{
unsigned char bit_val = thr_get_bit(thr, cp->bit_idx[1]);
vvp_ipoint_t itmp = ipoint_index(cp->iptr, thr->index[0]);
vvp_ipoint_t itmp = ipoint_index(cp->iptr, thr->words[0].w_int);
schedule_assign(itmp, bit_val, cp->bit_idx[0]);
return true;
}
@@ -533,7 +558,7 @@ bool of_ASSIGN_X0(vthread_t thr, vvp_code_t cp)
bool of_ASSIGN_MEM(vthread_t thr, vvp_code_t cp)
{
unsigned char bit_val = thr_get_bit(thr, cp->bit_idx[1]);
schedule_memory(cp->mem, thr->index[3], bit_val, cp->bit_idx[0]);
schedule_memory(cp->mem, thr->words[3].w_int, bit_val, cp->bit_idx[0]);
return true;
}
@@ -752,6 +777,20 @@ bool of_CMPX(vthread_t thr, vvp_code_t cp)
return true;
}
bool of_CMPWR(vthread_t thr, vvp_code_t cp)
{
double l = thr->words[cp->bit_idx[0]].w_real;
double r = thr->words[cp->bit_idx[1]].w_real;
unsigned eq = (l == r)? 1 : 0;
unsigned lt = (l < r)? 1 : 0;
thr_put_bit(thr, 4, eq);
thr_put_bit(thr, 5, lt);
return true;
}
bool of_CMPZ(vthread_t thr, vvp_code_t cp)
{
unsigned eq = 1;
@@ -777,6 +816,22 @@ bool of_CMPZ(vthread_t thr, vvp_code_t cp)
return true;
}
bool of_CVT_IR(vthread_t thr, vvp_code_t cp)
{
double r = thr->words[cp->bit_idx[1]].w_real;
thr->words[cp->bit_idx[0]].w_int = (long)(r);
return true;
}
bool of_CVT_RI(vthread_t thr, vvp_code_t cp)
{
long r = thr->words[cp->bit_idx[1]].w_int;
thr->words[cp->bit_idx[0]].w_real = (double)(r);
return true;
}
bool of_DELAY(vthread_t thr, vvp_code_t cp)
{
//printf("thread %p: %%delay %lu\n", thr, cp->number);
@@ -789,7 +844,7 @@ bool of_DELAYX(vthread_t thr, vvp_code_t cp)
unsigned long delay;
assert(cp->number < 4);
delay = thr->index[cp->number];
delay = thr->words[cp->number].w_int;
schedule_vthread(thr, delay);
return false;
}
@@ -1301,25 +1356,25 @@ bool of_INV(vthread_t thr, vvp_code_t cp)
bool of_IX_ADD(vthread_t thr, vvp_code_t cp)
{
thr->index[cp->bit_idx[0] & 3] += cp->number;
thr->words[cp->bit_idx[0] & 3].w_int += cp->number;
return true;
}
bool of_IX_SUB(vthread_t thr, vvp_code_t cp)
{
thr->index[cp->bit_idx[0] & 3] -= cp->number;
thr->words[cp->bit_idx[0] & 3].w_int -= cp->number;
return true;
}
bool of_IX_MUL(vthread_t thr, vvp_code_t cp)
{
thr->index[cp->bit_idx[0] & 3] *= cp->number;
thr->words[cp->bit_idx[0] & 3].w_int *= cp->number;
return true;
}
bool of_IX_LOAD(vthread_t thr, vvp_code_t cp)
{
thr->index[cp->bit_idx[0] & 3] = cp->number;
thr->words[cp->bit_idx[0] & 3].w_int = cp->number;
return true;
}
@@ -1350,7 +1405,7 @@ bool of_IX_GET(vthread_t thr, vvp_code_t cp)
}
v |= vv << i;
}
thr->index[cp->bit_idx[0] & 3] = v;
thr->words[cp->bit_idx[0]].w_int = v;
/* Set bit 4 as a flag if the input is unknown. */
thr_put_bit(thr, 4, unknown_flag? 1 : 0);
return true;
@@ -1425,7 +1480,7 @@ bool of_LOAD(vthread_t thr, vvp_code_t cp)
bool of_LOAD_MEM(vthread_t thr, vvp_code_t cp)
{
assert(cp->bit_idx[0] >= 4);
unsigned char val = memory_get(cp->mem, thr->index[3]);
unsigned char val = memory_get(cp->mem, thr->words[3].w_int);
thr_put_bit(thr, cp->bit_idx[0], val);
return true;
}
@@ -1442,7 +1497,7 @@ bool of_LOAD_NX(vthread_t thr, vvp_code_t cp)
struct __vpiSignal*sig =
reinterpret_cast<struct __vpiSignal*>(cp->handle);
unsigned idx = thr->index[cp->bit_idx[1]];
unsigned idx = thr->words[cp->bit_idx[1]].w_int;
vvp_ipoint_t ptr = vvp_fvector_get(sig->bits, idx);
thr_put_bit(thr, cp->bit_idx[0], functor_get(ptr));
@@ -1464,16 +1519,43 @@ bool of_LOAD_VEC(vthread_t thr, vvp_code_t cp)
return true;
}
bool of_LOAD_WR(vthread_t thr, vvp_code_t cp)
{
struct __vpiHandle*tmp = cp->handle;
t_vpi_value val;
val.format = vpiRealVal;
vpi_get_value(tmp, &val);
thr->words[cp->bit_idx[0]].w_real = val.value.real;
return true;
}
bool of_LOAD_X(vthread_t thr, vvp_code_t cp)
{
assert(cp->bit_idx[0] >= 4);
assert(cp->bit_idx[1] < 4);
vvp_ipoint_t ptr = ipoint_index(cp->iptr, thr->index[cp->bit_idx[1]]);
vvp_ipoint_t ptr = ipoint_index(cp->iptr, thr->words[cp->bit_idx[1]].w_int);
thr_put_bit(thr, cp->bit_idx[0], functor_get(ptr));
return true;
}
bool of_LOADI_WR(vthread_t thr, vvp_code_t cp)
{
unsigned idx = cp->bit_idx[0];
double mant = cp->number;
int exp = cp->bit_idx[1];
double sign = (exp & 0x2000)? -1.0 : 1.0;
exp &= 0x1fff;
mant = sign * ldexp(mant, exp - 0x1000);
thr->words[idx].w_real = mant;
return true;
}
bool of_MOD(vthread_t thr, vvp_code_t cp)
{
assert(cp->bit_idx[0] >= 4);
@@ -1813,6 +1895,15 @@ bool of_MUL(vthread_t thr, vvp_code_t cp)
return true;
}
bool of_MUL_WR(vthread_t thr, vvp_code_t cp)
{
double l = thr->words[cp->bit_idx[0]].w_real;
double r = thr->words[cp->bit_idx[1]].w_real;
thr->words[cp->bit_idx[0]].w_real = l * r;
return true;
}
bool of_MULI(vthread_t thr, vvp_code_t cp)
{
assert(cp->bit_idx[0] >= 4);
@@ -2164,7 +2255,7 @@ bool of_SET(vthread_t thr, vvp_code_t cp)
bool of_SET_MEM(vthread_t thr, vvp_code_t cp)
{
unsigned char val = thr_get_bit(thr, cp->bit_idx[0]);
memory_set(cp->mem, thr->index[3], val);
memory_set(cp->mem, thr->words[3].w_int, val);
return true;
}
@@ -2192,6 +2283,18 @@ bool of_SET_VEC(vthread_t thr, vvp_code_t cp)
return true;
}
bool of_SET_WORDR(vthread_t thr, vvp_code_t cp)
{
struct __vpiHandle*tmp = cp->handle;
t_vpi_value val;
val.format = vpiRealVal;
val.value.real = thr->words[cp->bit_idx[0]].w_real;
vpi_put_value(tmp, &val, 0, vpiNoDelay);
return true;
}
/*
* Implement the %set/x instruction:
*
@@ -2203,7 +2306,7 @@ bool of_SET_VEC(vthread_t thr, vvp_code_t cp)
bool of_SET_X0(vthread_t thr, vvp_code_t cp)
{
unsigned char bit_val = thr_get_bit(thr, cp->bit_idx[0]);
long idx = thr->index[0];
long idx = thr->words[0].w_int;
/* If idx < 0, then the index value is probably generated from
an undefined value. At any rate, this is defined to have no
@@ -2228,7 +2331,7 @@ bool of_SHIFTL_I0(vthread_t thr, vvp_code_t cp)
{
unsigned base = cp->bit_idx[0];
unsigned wid = cp->number;
unsigned long shift = thr->index[0];
unsigned long shift = thr->words[0].w_int;
assert(base >= 4);
@@ -2255,7 +2358,7 @@ bool of_SHIFTR_I0(vthread_t thr, vvp_code_t cp)
{
unsigned base = cp->bit_idx[0];
unsigned wid = cp->number;
unsigned long shift = thr->index[0];
unsigned long shift = thr->words[0].w_int;
if (shift >= wid) {
for (unsigned idx = 0 ; idx < wid ; idx += 1)
@@ -2505,6 +2608,18 @@ bool of_CALL_UFUNC(vthread_t thr, vvp_code_t cp)
/*
* $Log: vthread.cc,v $
* Revision 1.99 2003/01/27 00:14:37 steve
* Support in various contexts the $realtime
* system task.
*
* Revision 1.98 2003/01/26 18:16:22 steve
* Add %cvt/ir and %cvt/ri instructions, and support
* real values passed as arguments to VPI tasks.
*
* Revision 1.97 2003/01/25 23:48:06 steve
* Add thread word array, and add the instructions,
* %add/wr, %cmp/wr, %load/wr, %mul/wr and %set/wr.
*
* Revision 1.96 2003/01/06 23:57:26 steve
* Schedule wait lists of threads as a single event,
* to save on events. Also, improve efficiency of
@@ -2531,151 +2646,5 @@ bool of_CALL_UFUNC(vthread_t thr, vvp_code_t cp)
*
* Revision 1.89 2002/09/21 23:47:30 steve
* Remove some now useless asserts.
*
* Revision 1.88 2002/09/21 04:55:00 steve
* Fix disable in arbitrary fork/join situations.
*
* Revision 1.87 2002/09/20 03:59:34 steve
* disable threads with children.
*
* Revision 1.86 2002/09/18 04:29:55 steve
* Add support for binary NOR operator.
*
* Revision 1.85 2002/09/12 15:49:43 steve
* Add support for binary nand operator.
*
* Revision 1.84 2002/08/28 18:38:07 steve
* Add the %subi instruction, and use it where possible.
*
* Revision 1.83 2002/08/28 17:15:06 steve
* Add the %load/nx opcode to index vpi nets.
*
* Revision 1.82 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.81 2002/08/22 03:38:40 steve
* Fix behavioral eval of x?a:b expressions.
*
* Revision 1.80 2002/08/18 01:05:50 steve
* x in index values leads to 0.
*
* Revision 1.79 2002/08/12 01:35:09 steve
* conditional ident string using autoconfig.
*
* Revision 1.78 2002/06/02 18:55:58 steve
* Add %cmpi/u instruction.
*
* Revision 1.77 2002/05/31 20:04:22 steve
* Add the %muli instruction.
*
* Revision 1.76 2002/05/31 04:09:58 steve
* Slight improvement in %mov performance.
*
* Revision 1.75 2002/05/31 00:05:49 steve
* Word oriented bit storage.
*
* Revision 1.74 2002/05/29 16:29:34 steve
* Add %addi, which is faster to simulate.
*
* Revision 1.73 2002/05/27 00:53:10 steve
* Able to disable thread self.
*
* Revision 1.72 2002/05/24 04:55:13 steve
* Detect long division by zero.
*
* Revision 1.71 2002/05/19 05:18:16 steve
* Add callbacks for vpiNamedEvent objects.
*
* Revision 1.70 2002/05/12 23:44:41 steve
* task calls and forks push the thread event in the queue.
*
* Revision 1.69 2002/04/21 22:29:49 steve
* Add the assign/d instruction for computed delays.
*
* Revision 1.68 2002/04/14 18:41:34 steve
* Support signed integer division.
*
* Revision 1.67 2002/03/18 00:19:34 steve
* Add the .ufunc statement.
*
* Revision 1.66 2002/01/26 02:08:07 steve
* Handle x in l-value of set/x
*
* Revision 1.65 2001/12/31 00:01:16 steve
* Account for negatives in cmp/s
*
* Revision 1.64 2001/11/06 03:07:22 steve
* Code rearrange. (Stephan Boettcher)
*
* Revision 1.63 2001/11/01 03:00:20 steve
* Add force/cassign/release/deassign support. (Stephan Boettcher)
*
* Revision 1.62 2001/10/31 04:27:47 steve
* Rewrite the functor type to have fewer functor modes,
* and use objects to manage the different types.
* (Stephan Boettcher)
*
* Revision 1.61 2001/10/25 04:19:53 steve
* VPI support for callback to return values.
*
* Revision 1.60 2001/10/23 03:49:13 steve
* Fix carry between works for %add instruction.
*
* Revision 1.59 2001/10/20 23:20:32 steve
* Catch and X division by 0.
*
* Revision 1.58 2001/10/16 01:26:55 steve
* Add %div support (Anthony Bybell)
*
* Revision 1.57 2001/10/14 17:36:19 steve
* Forgot to propagate carry.
*
* Revision 1.56 2001/10/14 16:36:43 steve
* Very wide multiplication (Anthony Bybell)
*
* Revision 1.55 2001/09/15 18:27:05 steve
* Make configure detect malloc.h
*
* Revision 1.54 2001/09/07 23:29:28 steve
* Redo of_SUBU in a more obvious algorithm, that
* is not significantly slower. Also, clean up the
* implementation of %mov from a constant.
*
* Fix initial clearing of vector by vector_to_array
*
* Revision 1.53 2001/08/26 22:59:32 steve
* Add the assign/x0 and set/x opcodes.
*
* Revision 1.52 2001/08/08 00:53:50 steve
* signed/unsigned warnings?
*
* Revision 1.51 2001/07/22 00:04:50 steve
* Add the load/x instruction for bit selects.
*
* Revision 1.50 2001/07/20 04:57:00 steve
* Fix of_END when a middle thread ends.
*
* Revision 1.49 2001/07/19 04:40:55 steve
* Add support for the delayx opcode.
*
* Revision 1.48 2001/07/04 04:57:10 steve
* Relax limit on behavioral subtraction.
*
* Revision 1.47 2001/06/30 21:07:26 steve
* Support non-const right shift (unsigned).
*
* Revision 1.46 2001/06/23 18:26:26 steve
* Add the %shiftl/i0 instruction.
*
* Revision 1.45 2001/06/22 00:03:05 steve
* Infinitely wide behavioral add.
*
* Revision 1.44 2001/06/18 01:09:32 steve
* More behavioral unary reduction operators.
* (Stephan Boettcher)
*/
+12 -1
View File
@@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: vthread.h,v 1.8 2002/08/12 01:35:09 steve Exp $"
#ident "$Id: vthread.h,v 1.10 2003/01/27 00:14:37 steve Exp $"
#endif
/*
@@ -71,8 +71,19 @@ extern void vthread_schedule_list(vthread_t thr);
extern unsigned vthread_get_bit(struct vthread_s*thr, unsigned addr);
extern void vthread_put_bit(struct vthread_s*thr, unsigned addr, unsigned bit);
extern double vthread_get_real(struct vthread_s*thr, unsigned addr);
extern void vthread_put_real(struct vthread_s*thr, unsigned addr, double val);
/*
* $Log: vthread.h,v $
* Revision 1.10 2003/01/27 00:14:37 steve
* Support in various contexts the $realtime
* system task.
*
* Revision 1.9 2003/01/26 18:16:22 steve
* Add %cvt/ir and %cvt/ri instructions, and support
* real values passed as arguments to VPI tasks.
*
* Revision 1.8 2002/08/12 01:35:09 steve
* conditional ident string using autoconfig.
*
+53
View File
@@ -0,0 +1,53 @@
/*
* 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: words.cc,v 1.1 2003/01/25 23:48:06 steve Exp $"
#endif
# include "compile.h"
# include "vpi_priv.h"
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
#ifdef HAVE_MALLOC_H
# include <malloc.h>
#endif
# include <assert.h>
void compile_word(char*label, char*type, char*name)
{
assert(strcmp(type, "real") == 0);
free(type);
vpiHandle obj = vpip_make_real_var(name);
free(name);
compile_vpi_symbol(label, obj);
free(label);
}
/*
* $Log: words.cc,v $
* Revision 1.1 2003/01/25 23:48:06 steve
* Add thread word array, and add the instructions,
* %add/wr, %cmp/wr, %load/wr, %mul/wr and %set/wr.
*
*/