Compare commits

...
65 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
steve 38ccb12eb0 Use stringstream in place of sprintf. 2003-01-17 05:49:03 +00:00
steve ca3bf14fb6 Remove useless variable. 2003-01-17 05:48:35 +00:00
steve 982474899b Set proper line text for later bison. 2003-01-17 05:48:02 +00:00
steve ad6ff5562d Missed a case of setting line on an PEident. 2003-01-17 05:47:30 +00:00
steve d4cd1dbd27 Keep some debugging status. 2003-01-16 21:44:46 +00:00
steve 3c1426e631 Detect duplicate module declarations. 2003-01-16 21:44:19 +00:00
steve c3a1a9514f Assert some task definition sanity. 2003-01-16 21:43:52 +00:00
steve f56d763411 Move strstream to ostringstream for compatibility. 2003-01-14 21:16:18 +00:00
steve 4ec91047dd Ignore vvp.exp 2003-01-10 19:02:47 +00:00
steve 0579ae08cd Add missing vpi entry points. 2003-01-10 19:02:21 +00:00
steve 9074999666 Remove thunks from vpi init. 2003-01-10 19:01:38 +00:00
steve 0458ab5a53 Only use libiberty.h if available. 2003-01-10 19:01:04 +00:00
steve 4a3459c87c Spelling fixes. 2003-01-10 03:08:13 +00:00
steve 301cbe31ad Remove vpithunk, and move libvpi to vvp directory. 2003-01-10 03:06:32 +00:00
steve 165dd82bb2 Remove files of vvm directory. 2003-01-10 03:05:05 +00:00
steve 9c3b3246c8 use userdata to save $display argument handles. 2003-01-09 04:10:58 +00:00
steve 6416f8b90e Add vpi_put_userdata 2003-01-09 04:09:44 +00:00
steve e6eae5fd15 Allocate res-buf in bigger chunks 2003-01-07 18:07:50 +00:00
steve aa3a6dba4e Schedule wait lists of threads as a single event,
to save on events. Also, improve efficiency of
 event_s allocation. Add some event statistics to
 get an idea where performance is really going.
2003-01-06 23:57:26 +00:00
steve dedae73761 Account for local units in calculated delays. 2002-12-21 19:42:17 +00:00
steve d7f3d00f5c Rewrite time formatting to account for local scope. 2002-12-21 19:41:49 +00:00
steve c2070777b2 The $time system task returns the integer time
scaled to the local units. Change the internal
 implementation of vpiSystemTime the $time functions
 to properly account for this. Also add $simtime
 to get the simulation time.
2002-12-21 00:55:57 +00:00
steve 42b34c2ce6 Evaluate shift index after shift operand because
the chift operand may use the index register itself.
2002-12-20 01:11:14 +00:00
steve 6fbfdd8f3f Keep bit select subexpression width if it is constant. 2002-12-19 23:11:29 +00:00
steve bee3acfd12 Add tf_message, tf_get/setworkarea, and
ty_typep functions, along with defines
 related to these functions.
2002-12-19 21:37:04 +00:00
steve 2e279b61dd Update to 0.7 release. 2002-12-14 18:20:14 +00:00
steve 8ab909a765 Add vpi_handle_by_name to the VPI interface,
and bump the vpithunk magic number.
2002-12-11 23:55:22 +00:00
steve cca07fa42d Account for bison 1.35 and stack manipulations. 2002-12-10 05:49:51 +00:00
steve 5b81798205 install iverilog-vpi as a script. 2002-12-10 05:45:44 +00:00
steve a8a82df47d Prepare for 20021207 snapshot 2002-12-08 03:06:30 +00:00
steve e62e1d89b6 Named event triggers can take hierarchical names. 2002-12-07 02:49:24 +00:00
steve c032186133 Reword some error messages for clarity. 2002-12-06 03:08:19 +00:00
steve b89e138404 precalculate r-values of nb assignments and task arguments. 2002-12-05 04:15:14 +00:00
steve 9f80ed32b6 Support bit select in constant expressions. 2002-12-05 02:14:33 +00:00
steve c16a4a3950 distclean target. 2002-12-04 03:33:38 +00:00
steve 90fa90a508 Mingw32 compatible temp file management. 2002-12-04 03:26:59 +00:00
steve aaa734690f Use O_EXCL when opening temp files. 2002-12-04 02:29:36 +00:00
steve 88da7804c4 Improve the bad character error message. 2002-12-04 02:07:00 +00:00
steve 8604f922a5 specify delay can take an unbracketed simple value. 2002-11-26 03:56:10 +00:00
steve 807a758f7c Do not set width if width is already OK. 2002-11-26 03:35:13 +00:00
steve ef55086543 Support put of vpiStringVal to signals. 2002-11-25 23:33:45 +00:00
steve 2001903c89 Cygwin doesnot need driver-vpi sibdirectory. 2002-11-24 02:27:28 +00:00
steve 751e4e4c79 Fix instanceRef spelling. 2002-11-24 02:26:14 +00:00
steve 9d91b5db4c Document the Windows specific flags. 2002-11-23 00:51:53 +00:00
steve 9a3c9507ed Handle wide AND/NOR devices with Virtex carry logic. 2002-11-22 05:46:06 +00:00
steve d71d52bfe9 Implement bufif1 as BUFT 2002-11-22 01:45:40 +00:00
steve 8e30bc9f9e Careful of left operands to shift that are constant. 2002-11-22 00:01:50 +00:00
steve 412518d1ca Precalculate indices to l-value arrays. 2002-11-21 23:27:51 +00:00
steve 03afbf157b %set/x0 instruction to support bounds checking. 2002-11-21 22:43:13 +00:00
steve 00b2d467e4 Allow right values of right shift to shift in. 2002-11-21 22:42:48 +00:00
steve 856829d299 Fix const test of msb in assignment l-values. 2002-11-21 18:15:40 +00:00
steve 2fafe6866f Better handling of select width of shifters. 2002-11-21 18:08:09 +00:00
steve b9188ad0ca PATHPULSE specparam assignment syntax. 2002-11-21 17:40:11 +00:00
steve 0ccb9139c9 Magnitude compare to 0. 2002-11-17 23:37:55 +00:00
steve 18e402ddc8 Close old file if $dumpfile is called again. 2002-11-17 22:28:42 +00:00
138 changed files with 4497 additions and 8958 deletions
+25 -5
View File
@@ -17,13 +17,18 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: LineInfo.cc,v 1.3 2002/08/12 01:34:58 steve Exp $"
#ident "$Id: LineInfo.cc,v 1.4 2003/01/17 05:49:03 steve Exp $"
#endif
# include "config.h"
# include "LineInfo.h"
# include <cstdio>
# include <sstream>
LineInfo::LineInfo()
: file_(0), lineno_(0)
{
}
LineInfo::~LineInfo()
{
@@ -31,9 +36,11 @@ LineInfo::~LineInfo()
string LineInfo::get_line() const
{
char buf[8];
sprintf(buf, "%u", lineno_);
return string(file_? file_ : "") + ":" + buf;
ostringstream buf;
buf << (file_? file_ : "") << ":" << lineno_;
string res = buf.str();
return res;
}
void LineInfo::set_line(const LineInfo&that)
@@ -42,8 +49,21 @@ void LineInfo::set_line(const LineInfo&that)
lineno_ = that.lineno_;
}
void LineInfo::set_file(const char*f)
{
file_ = f;
}
void LineInfo::set_lineno(unsigned n)
{
lineno_ = n;
}
/*
* $Log: LineInfo.cc,v $
* Revision 1.4 2003/01/17 05:49:03 steve
* Use stringstream in place of sprintf.
*
* Revision 1.3 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
+7 -4
View File
@@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: LineInfo.h,v 1.6 2002/08/12 01:34:58 steve Exp $"
#ident "$Id: LineInfo.h,v 1.7 2003/01/17 05:49:03 steve Exp $"
#endif
# include <string>
@@ -35,15 +35,15 @@
class LineInfo {
public:
LineInfo() : file_(0), lineno_(0) { }
LineInfo();
~LineInfo();
string get_line() const;
void set_line(const LineInfo&that);
void set_file(const char*f) { file_ = f; }
void set_lineno(unsigned n) { lineno_ = n; }
void set_file(const char*f);
void set_lineno(unsigned n);
private:
const char* file_;
@@ -52,6 +52,9 @@ class LineInfo {
/*
* $Log: LineInfo.h,v $
* Revision 1.7 2003/01/17 05:49:03 steve
* Use stringstream in place of sprintf.
*
* Revision 1.6 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
+11 -25
View File
@@ -16,7 +16,7 @@
# 59 Temple Place - Suite 330
# Boston, MA 02111-1307, USA
#
#ident "$Id: Makefile.in,v 1.137 2002/11/13 01:50:11 steve Exp $"
#ident "$Id: Makefile.in,v 1.143 2003/01/26 21:15:58 steve Exp $"
#
#
SHELL = /bin/sh
@@ -25,7 +25,7 @@ SHELL = /bin/sh
# by the compiler. It reflects the assigned version number for the
# product as a whole. Most components also print the CVS Name: token
# in order to get a more automatic version stamp as well.
VERSION = 0.6
VERSION = 0.7
prefix = @prefix@
exec_prefix = @exec_prefix@
@@ -67,7 +67,7 @@ ifeq ('@HAVE_IPAL@','yes')
TARGETS += tgt-pal
endif
all: ivl@EXEEXT@ libvpi.a
all: ivl@EXEEXT@
for dir in $(SUBDIRS) ; do (cd $$dir ; $(MAKE) all); done
cd vpi ; $(MAKE) all
cd ivlpp ; $(MAKE) all
@@ -83,7 +83,10 @@ all: dosify.exe
dosify.exe: dosify.c
$(CC) -o dosify.exe dosify.c
ifeq (@MINGW32@,yes)
SUBDIRS += driver-vpi
endif
else
all: iverilog-vpi
endif
@@ -93,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
@@ -125,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)
@@ -138,19 +141,6 @@ Makefile: Makefile.in config.h.in config.status
./config.status
libvpi.a: vpithunk.o
rm -f $@
ar cvq $@ vpithunk.o
ranlib $@
# The vpithunk.c file (that makes up the libvpi.a library) needs to
# be make with PIC flags, because shared objects load it.
vpithunk.o: vpithunk.c
@[ -d dep ] || mkdir dep
$(CC) $(CPPFLAGS) $(CFLAGS) $(PICFLAGS) -MD -c $< -o $*.o
mv $*.d dep/$*.d
ifeq (@WIN32@,yes)
# Under Windows (mingw) I need to make the ivl.exe in two steps.
# The first step makes an ivl.exe that dlltool can use to make an
@@ -222,7 +212,7 @@ else
WIN32_INSTALL = $(bindir)/iverilog-vpi
endif
install: all installdirs $(libdir)/ivl/ivl@EXEEXT@ $(libdir)/ivl/iverilog.conf $(includedir)/ivl_target.h $(includedir)/vpi_user.h $(includedir)/acc_user.h $(includedir)/veriuser.h $(libdir)/libvpi.a $(WIN32_INSTALL) $(INSTALL_DOC)
install: all installdirs $(libdir)/ivl/ivl@EXEEXT@ $(libdir)/ivl/iverilog.conf $(includedir)/ivl_target.h $(includedir)/vpi_user.h $(includedir)/acc_user.h $(includedir)/veriuser.h $(WIN32_INSTALL) $(INSTALL_DOC)
cd vpi ; $(MAKE) install
cd ivlpp ; $(MAKE) install
cd driver ; $(MAKE) install
@@ -230,10 +220,7 @@ install: all installdirs $(libdir)/ivl/ivl@EXEEXT@ $(libdir)/ivl/iverilog.conf $
for tgt in $(TARGETS); do (cd $$tgt ; $(MAKE) install); done
$(bindir)/iverilog-vpi: ./iverilog-vpi
$(INSTALL_PROGRAM) ./iverilog-vpi $(bindir)/iverilog-vpi
$(libdir)/libvpi.a : ./libvpi.a
$(INSTALL_DATA) libvpi.a $(libdir)/libvpi.a
$(INSTALL_SCRIPT) ./iverilog-vpi $(bindir)/iverilog-vpi
$(libdir)/ivl/ivl@EXEEXT@: ./ivl@EXEEXT@
$(INSTALL_PROGRAM) ./ivl@EXEEXT@ $(libdir)/ivl/ivl@EXEEXT@
@@ -291,7 +278,6 @@ uninstall:
rm -f $(libdir)/ivl/iverilog.conf
rm -f $(libdir)/ivl/ivl
-rmdir $(libdir)/ivl
rm -f $(libdir)/libvpi.a
rm -f $(bindir)/verilog
rm -f $(bindir)/iverilog-vpi
rm -f $(bindir)/gverilog@EXEEXT@
+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.
*
+13
View File
@@ -344,6 +344,19 @@ language that are defined.
The $sizeof function is deprecated in favor of $bits, which is
the same thing, but included in the SystemVerilog definition.
$simtime
The $simtime system function returns as a 64bit value the
simulation time, unscaled by the time units of local
scope. This is different from the $time and $stime functions
which return the scaled times. This function is added for
regression testing of the compiler and run time, but can be
used by applications who really want the simulation time.
Note that the simulation time can be confusing if there are
lots of different `timescales within a design. It is not in
general possible to predict what the simulation precision will
turn out to be.
Builtin system functions
Certain of the system functions have well defined meanings, so
+9 -1
View File
@@ -23,7 +23,7 @@
* Picture Elements, Inc., 777 Panoramic Way, Berkeley, CA 94704.
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: StringHeap.cc,v 1.2 2002/08/12 01:34:58 steve Exp $"
#ident "$Id: StringHeap.cc,v 1.3 2003/01/16 21:44:46 steve Exp $"
#endif
# include "StringHeap.h"
@@ -38,6 +38,7 @@ StringHeap::StringHeap()
{
cell_base_ = 0;
cell_ptr_ = HEAPCELL;
cell_count_ = 0;
}
StringHeap::~StringHeap()
@@ -55,6 +56,8 @@ const char* StringHeap::add(const char*text)
if (rem < (len+1)) {
cell_base_ = (char*)malloc(HEAPCELL);
cell_ptr_ = 0;
cell_count_ += 1;
assert(cell_base_ != 0);
}
char*res = cell_base_ + cell_ptr_;
@@ -62,11 +65,16 @@ const char* StringHeap::add(const char*text)
cell_ptr_ += len;
cell_base_[cell_ptr_++] = 0;
assert(cell_ptr_ <= HEAPCELL);
return res;
}
/*
* $Log: StringHeap.cc,v $
* Revision 1.3 2003/01/16 21:44:46 steve
* Keep some debugging status.
*
* Revision 1.2 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
+5 -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: StringHeap.h,v 1.2 2002/08/12 01:34:58 steve Exp $"
#ident "$Id: StringHeap.h,v 1.3 2003/01/16 21:44:46 steve Exp $"
#endif
class StringHeap {
@@ -35,6 +35,7 @@ class StringHeap {
char*cell_base_;
unsigned cell_ptr_;
unsigned cell_count_;
private: // not implemented
StringHeap(const StringHeap&);
@@ -43,6 +44,9 @@ class StringHeap {
/*
* $Log: StringHeap.h,v $
* Revision 1.3 2003/01/16 21:44:46 steve
* Keep some debugging status.
*
* Revision 1.2 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
+5 -1
View File
@@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: config.h.in,v 1.5 2002/08/11 23:39:33 steve Exp $"
#ident "$Id: config.h.in,v 1.6 2003/01/10 19:01:04 steve Exp $"
#endif
#if defined(__cplusplus)
@@ -37,6 +37,7 @@
# undef HAVE_TIMES
# undef HAVE_IOSFWD
# undef HAVE_GETOPT_H
# undef HAVE_LIBIBERTY_H
# undef HAVE_MALLOC_H
# undef HAVE_DLFCN_H
# undef HAVE_DL_H
@@ -46,6 +47,9 @@
/*
* $Log: config.h.in,v $
* Revision 1.6 2003/01/10 19:01:04 steve
* Only use libiberty.h if available.
*
* Revision 1.5 2002/08/11 23:39:33 steve
* Remove VVM option.
*
+3 -1
View File
@@ -32,7 +32,7 @@ fi
AC_LANG_CPLUSPLUS
AC_CHECK_HEADERS(getopt.h malloc.h iosfwd sys/wait.h)
AC_CHECK_HEADERS(getopt.h malloc.h libiberty.h iosfwd sys/wait.h)
AC_MSG_CHECKING(for sys/times)
AC_TRY_LINK(
@@ -190,6 +190,8 @@ if test "$CYGWIN" = "yes" -o "$MINGW32" = "yes"
then
WIN32=yes
fi
AC_SUBST(MINGW32)
AC_SUBST(WIN32)
AC_MSG_RESULT($WIN32)
AC_SUBST(EXEEXT)
+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.
+6 -5
View File
@@ -3,9 +3,7 @@
# and/or modify it in source code form under the terms of the GNU
# Library General Public License as published by the Free Software
# Foundation; either version 2 of the License, or (at your option)
# any later version. In order to redistribute the software in
# binary form, you will need a Picture Elements Binary Software
# License.
# 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
@@ -18,12 +16,12 @@
# 59 Temple Place - Suite 330
# Boston, MA 02111-1307, USA
#
#ident "$Id: Makefile.in,v 1.3 2002/11/13 17:25:10 steve Exp $"
#ident "$Id: Makefile.in,v 1.5 2002/12/08 03:06:30 steve Exp $"
#
#
SHELL = /bin/sh
VERSION = 0.6
VERSION = 0.7
prefix = @prefix@
exec_prefix = @exec_prefix@
@@ -55,6 +53,9 @@ clean:
rm -f *.o
rm -f iverilog-vpi@EXEEXT@
distclean: clean
rm -f Makefile
O = main.o res.o
iverilog-vpi@EXEEXT@: $O
+3 -5
View File
@@ -3,9 +3,7 @@
# and/or modify it in source code form under the terms of the GNU
# Library General Public License as published by the Free Software
# Foundation; either version 2 of the License, or (at your option)
# any later version. In order to redistribute the software in
# binary form, you will need a Picture Elements Binary Software
# License.
# 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
@@ -18,12 +16,12 @@
# 59 Temple Place - Suite 330
# Boston, MA 02111-1307, USA
#
#ident "$Id: Makefile.in,v 1.15 2002/08/10 22:36:59 steve Exp $"
#ident "$Id: Makefile.in,v 1.16 2002/12/08 03:06:30 steve Exp $"
#
#
SHELL = /bin/sh
VERSION = 0.6
VERSION = 0.7
prefix = @prefix@
exec_prefix = @exec_prefix@
+42 -2
View File
@@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ident "$Id: main.c,v 1.47 2002/08/12 01:27:48 steve Exp $"
#ident "$Id: main.c,v 1.50 2003/01/10 19:01:04 steve Exp $"
# include "config.h"
@@ -44,8 +44,10 @@ const char HELP[] =
#ifdef __MINGW32__
#include <windows.h>
#ifdef HAVE_LIBIBERTY_H
#include <libiberty.h>
#endif
#endif
#if HAVE_GETOPT_H
#include <getopt.h>
@@ -119,6 +121,35 @@ char tmp[MAXSIZE];
static char ivl_root[MAXSIZE];
#ifdef __MINGW32__
# include <io.h>
# include <fcntl.h>
static FILE*fopen_safe(const char*path)
{
FILE*file = 0;
int fd;
fd = _open(path, _O_WRONLY|_O_CREAT|_O_EXCL, 0700);
if (fd != -1)
file = _fdopen(fd, "w");
return file;
}
#else
# include <fcntl.h>
static FILE*fopen_safe(const char*path)
{
FILE*file = 0;
int fd;
fd = open(path, O_WRONLY|O_CREAT|O_EXCL, 0700);
if (fd != -1)
file = fdopen(fd, "w");
return file;
}
#endif
static const char*my_tempfile(const char*str, FILE**fout)
{
FILE*file;
@@ -148,7 +179,7 @@ static const char*my_tempfile(const char*str, FILE**fout)
while ((retry > 0) && (file == NULL)) {
unsigned code = rand();
sprintf(pathbuf, "%s%c%s%04x", tmpdir, sep, str, code);
file = fopen(pathbuf, "w");
file = fopen_safe(pathbuf);
retry -= 1;
}
@@ -657,6 +688,15 @@ int main(int argc, char **argv)
/*
* $Log: main.c,v $
* Revision 1.50 2003/01/10 19:01:04 steve
* Only use libiberty.h if available.
*
* Revision 1.49 2002/12/04 03:26:59 steve
* Mingw32 compatible temp file management.
*
* Revision 1.48 2002/12/04 02:29:36 steve
* Use O_EXCL when opening temp files.
*
* Revision 1.47 2002/08/12 01:27:48 steve
* Escape the backslash in the windows file name.
*
+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.
*
+32 -6
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1999-2000 Stephen Williams ([email protected])
* Copyright (c) 1999-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
@@ -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.66 2002/09/21 21:28:18 steve Exp $"
#ident "$Id: elab_expr.cc,v 1.68 2003/01/26 21:15:58 steve Exp $"
#endif
# include "config.h"
@@ -215,6 +215,8 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope) const
if (strcmp(path_.peek_name(0), "$time") == 0)
wid = 64;
if (strcmp(path_.peek_name(0), "$simtime") == 0)
wid = 64;
if (strcmp(path_.peek_name(0), "$stime") == 0)
wid = 32;
@@ -404,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;
}
/*
@@ -719,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.
@@ -810,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 {
@@ -885,6 +900,17 @@ 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
* implementation of vpiSystemTime the $time functions
* to properly account for this. Also add $simtime
* to get the simulation time.
*
* Revision 1.66 2002/09/21 21:28:18 steve
* Allow constant bit selects out of range.
*
+56 -10
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.21 2002/11/02 01:10:49 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() <<
@@ -170,16 +188,20 @@ NetAssign_* PEIdent::elaborate_lval(Design*des, NetScope*scope) const
verinum*vl = lsb_->eval_const(des, scope);
if (vl == 0) {
cerr << lsb_->get_line() << ": error: "
"Part select expressions must be constant: "
<< *lsb_;
"Part select expressions must be constant."
<< endl;
cerr << lsb_->get_line() << ": : This lsb expression "
"violates the rule: " << *lsb_ << endl;
des->errors += 1;
return 0;
}
verinum*vm = msb_->eval_const(des, scope);
if (vl == 0) {
if (vm == 0) {
cerr << msb_->get_line() << ": error: "
"Part select expressions must be constant: "
<< *msb_;
"Part select expressions must be constant."
<< endl;
cerr << msb_->get_line() << ": : This msb expression "
"violates the rule: " << *msb_ << endl;
des->errors += 1;
return 0;
}
@@ -298,6 +320,17 @@ NetAssign_* PEIdent::elaborate_mem_lval_(Design*des, NetScope*scope,
if (ix == 0)
return 0;
/* Evaluate the memory index expression down as must as
possible. Ideally, we can get it down to a constant. */
if (! dynamic_cast<NetEConst*>(ix)) {
NetExpr*tmp = ix->eval_tree();
if (tmp) {
tmp->set_line(*ix);
delete ix;
ix = tmp;
}
}
NetAssign_*lv = new NetAssign_(mem);
lv->set_bmux(ix);
lv->set_part(0, mem->width());
@@ -314,6 +347,19 @@ 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.
*
* Revision 1.22 2002/11/21 18:15:40 steve
* Fix const test of msb in assignment l-values.
*
* Revision 1.21 2002/11/02 01:10:49 steve
* Detect memories without work index in l-value.
*
+24 -10
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.102 2002/11/09 19:20:48 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)
@@ -1502,8 +1510,6 @@ NetNet* PEConcat::elaborate_lnet(Design*des, NetScope*scope,
NetNet* PEIdent::elaborate_lnet(Design*des, NetScope*scope,
bool implicit_net_ok) const
{
string path = scope->name();
NetNet*sig = des->find_signal(scope, path_);
if (sig == 0) {
/* Don't allow memories here. Is it a memory? */
@@ -1538,18 +1544,17 @@ NetNet* PEIdent::elaborate_lnet(Design*des, NetScope*scope,
/* Don't allow registers as assign l-values. */
if (sig->type() == NetNet::REG) {
cerr << get_line() << ": error: registers (" << sig->name()
<< ") cannot be l-values in continuous"
cerr << get_line() << ": error: reg " << sig->name()
<< "; cannot be an L-value in continuous"
<< " assignments." << endl;
return 0;
}
if (sig->port_type() == NetNet::PINPUT) {
cerr << get_line() << ": warning: assign l-value ``"
<< sig->name() << "'' is also an input to "
<< sig->scope()->name() << "." << endl;
cerr << sig->get_line() << ": warning: input ``"
<< sig->name() << "'' is coerced to inout." << endl;
cerr << get_line() << ": warning: L-value ``"
<< sig->name() << "'' is also an input port." << endl;
cerr << sig->get_line() << ": warning: input "
<< sig->name() << "; is coerced to inout." << endl;
sig->port_type(NetNet::PINOUT);
}
@@ -2279,6 +2284,15 @@ 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.
*
* Revision 1.103 2002/12/06 03:08:19 steve
* Reword some error messages for clarity.
*
* Revision 1.102 2002/11/09 19:20:48 steve
* Port expressions for output ports are lnets, not nets.
*
+21 -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: elab_pexpr.cc,v 1.17 2002/11/09 01:40:19 steve Exp $"
#ident "$Id: elab_pexpr.cc,v 1.18 2002/12/05 02:14:33 steve Exp $"
#endif
# include "config.h"
@@ -145,15 +145,26 @@ NetExpr*PEIdent::elaborate_pexpr(Design*des, NetScope*scope) const
return 0;
}
if (msb_ || lsb_ || idx_) {
cerr << get_line() << ": error: Cannot bit/part select "
"bits of parameters." << endl;
des->errors += 1;
}
NetExpr*res = new NetEParam(des, pscope, hname_t(name));
assert(res);
delete name;
assert(idx_ == 0);
if (msb_ && lsb_) {
cerr << get_line() << ": sorry: Cannot part select "
"bits of parameters." << endl;
des->errors += 1;
} else if (msb_) {
/* We have here a bit select. Insert a NetESelect node
to handle it. */
NetExpr*tmp = msb_->elaborate_pexpr(des, scope);
if (tmp != 0) {
res = new NetESelect(res, tmp, 1);
}
}
return res;
}
@@ -217,6 +228,9 @@ NetExpr*PEUnary::elaborate_pexpr (Design*des, NetScope*scope) const
/*
* $Log: elab_pexpr.cc,v $
* Revision 1.18 2002/12/05 02:14:33 steve
* Support bit select in constant expressions.
*
* Revision 1.17 2002/11/09 01:40:19 steve
* Postpone parameter width check to evaluation.
*
+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.
+75 -24
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.264 2002/11/09 19:20:48 steve Exp $"
#ident "$Id: elaborate.cc,v 1.269 2003/01/26 21:15:58 steve Exp $"
#endif
# include "config.h"
@@ -30,7 +30,7 @@
*/
# include <typeinfo>
# include <strstream>
# include <sstream>
# include <list>
# include "pform.h"
# include "PEvent.h"
@@ -314,14 +314,14 @@ void PGBuiltin::elaborate(Design*des, NetScope*scope) const
a unique name, and set the delay times. */
for (unsigned idx = 0 ; idx < count ; idx += 1) {
strstream tmp;
ostringstream tmp;
unsigned index;
if (low < high)
index = low + idx;
else
index = low - idx;
tmp << name << "<" << index << ">" << ends;
tmp << name << "<" << index << ">";
const string inm = tmp.str();
switch (type()) {
@@ -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);
@@ -975,7 +964,7 @@ NetProc* PAssign::elaborate(Design*des, NetScope*scope) const
rv->set_width(wid);
rv = pad_to_width(rv, wid);
if (! rv->set_width(wid)) {
if (wid != rv->expr_width()) {
cerr << get_line() << ": error: Unable to match "
"expression width of " << rv->expr_width() <<
" to l-value width of " << wid << "." << endl;
@@ -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);
@@ -1076,6 +1070,12 @@ NetProc* PAssignNB::elaborate(Design*des, NetScope*scope) const
assert(rv);
/* Try to evaluate the expression, at least as far as possible. */
if (NetExpr*tmp = rv->eval_tree()) {
delete rv;
rv = tmp;
}
{ unsigned wid = count_lval_width(lv);
rv->set_width(wid);
rv = pad_to_width(rv, wid);
@@ -1351,6 +1351,17 @@ NetProc* PCallTask::elaborate_sys(Design*des, NetScope*scope) const
for (unsigned idx = 0 ; idx < parm_count ; idx += 1) {
PExpr*ex = parm(idx);
eparms[idx] = ex? ex->elaborate_expr(des, scope, true) : 0;
/* Attempt to pre-evaluate the parameters. It may be
possible to at least partially reduce the
expression. */
if (eparms[idx] && !dynamic_cast<NetEConst*>(eparms[idx])) {
NetExpr*tmp = eparms[idx]->eval_tree();
if (tmp != 0) {
delete eparms[idx];
eparms[idx] = tmp;
}
}
}
NetSTask*cur = new NetSTask(path_.peek_name(0), eparms);
@@ -1589,6 +1600,30 @@ NetProc* PDelayStatement::elaborate(Design*des, NetScope*scope) const
/* Ah, the delay is not constant. OK, elaborate the
expression and let the run-time handle it. */
NetExpr*dex = delay_->elaborate_expr(des, scope);
/* If the local scope units are different from the
simulation precision, then extend the expression to
convert the delay to simulation time. */
if (scope->time_unit() != des->get_precision()) {
long scale = 1;
int unit = scope->time_unit();
int prec = des->get_precision();
while (unit > prec) {
scale *= 10;
unit -= 1;
}
verinum scale_v (scale);
NetEConst*scale_e = new NetEConst(scale_v);
NetEBMult*scale_m = new NetEBMult('*', scale_e, dex);
if (NetExpr*tmp = scale_m->eval_tree()) {
dex = tmp;
delete scale_m;
} else {
dex = scale_m;
}
}
if (statement_)
return new NetPDelay(dex, statement_->elaborate(des, scope));
else
@@ -2472,6 +2507,22 @@ 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.
*
* Revision 1.267 2002/12/21 19:42:17 steve
* Account for local units in calculated delays.
*
* Revision 1.266 2002/12/05 04:15:14 steve
* precalculate r-values of nb assignments and task arguments.
*
* Revision 1.265 2002/11/26 03:35:13 steve
* Do not set width if width is already OK.
*
* Revision 1.264 2002/11/09 19:20:48 steve
* Port expressions for output ports are lnets, not nets.
*
+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.
*
+51 -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: eval_tree.cc,v 1.43 2002/11/09 01:40:19 steve Exp $"
#ident "$Id: eval_tree.cc,v 1.44 2002/12/05 02:14:33 steve Exp $"
#endif
# include "config.h"
@@ -894,6 +894,53 @@ NetExpr* NetEParam::eval_tree()
return res->dup_expr();
}
NetEConst* NetESelect::eval_tree()
{
NetEConst*expr = dynamic_cast<NetEConst*>(expr_);
if (expr == 0) {
NetExpr*tmp = expr_->eval_tree();
if (tmp != 0) {
delete expr_;
expr_ = tmp;
}
expr = dynamic_cast<NetEConst*>(expr_);
}
NetEConst*base = dynamic_cast<NetEConst*>(base_);
if (base == 0) {
NetExpr*tmp = base_->eval_tree();
if (tmp != 0) {
delete base_;
base_ = tmp;
}
base = dynamic_cast<NetEConst*>(base_);
}
if (expr == 0)
return 0;
if (base == 0)
return 0;
verinum eval = expr->value();
verinum oval (verinum::V0, expr_width(), true);
long bval = base->value().as_long();
for (long idx = 0 ; idx < expr_width() ; idx += 1) {
if ((bval >= eval.len()) || (bval < 0))
oval.set(idx, verinum::Vx);
else
oval.set(idx, eval.get(bval));
bval += 1;
}
NetEConst*res = new NetEConst(oval);
return res;
}
/*
* A ternary expression evaluation is controlled by the condition
* expression. If the condition evaluates to true or false, then
@@ -1140,6 +1187,9 @@ NetEConst* NetEUReduce::eval_tree()
/*
* $Log: eval_tree.cc,v $
* Revision 1.44 2002/12/05 02:14:33 steve
* Support bit select in constant expressions.
*
* Revision 1.43 2002/11/09 01:40:19 steve
* Postpone parameter width check to evaluation.
*
+43 -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.36 2002/08/12 01:34:59 steve Exp $"
#ident "$Id: expr_synth.cc,v 1.38 2003/01/26 21:15:58 steve Exp $"
#endif
# include "config.h"
@@ -192,6 +192,33 @@ NetNet* NetEBComp::synthesize(Design*des)
gate = new NetLogic(scope, des->local_symbol(path),
lsig->pin_count()+1, NetLogic::OR);
break;
case '>':
/* sig > 0 is true if any bit in sig is set. This
is very much like sig != 0. (0 > sig) shouldn't
happen. */
if (rcon) {
gate = new NetLogic(scope, des->local_symbol(path),
lsig->pin_count()+1, NetLogic::OR);
} else {
assert(0);
gate = new NetLogic(scope, des->local_symbol(path),
lsig->pin_count()+1, NetLogic::NOR);
}
break;
case '<':
/* 0 < sig is handled like sig > 0. */
if (! rcon) {
gate = new NetLogic(scope, des->local_symbol(path),
lsig->pin_count()+1, NetLogic::OR);
} else {
assert(0);
gate = new NetLogic(scope, des->local_symbol(path),
lsig->pin_count()+1, NetLogic::NOR);
}
break;
default:
assert(0);
}
@@ -425,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.
@@ -608,6 +643,13 @@ 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.
*
* Revision 1.36 2002/08/12 01:34:59 steve
* conditional ident string using autoconfig.
*
+26 -2
View File
@@ -1,4 +1,4 @@
.TH iverilog-vpi 1 "$Date: 2002/07/05 17:17:20 $" Version "$Date: 2002/07/05 17:17:20 $"
.TH iverilog-vpi 1 "$Date: 2002/11/23 00:51:53 $" Version "$Date: 2002/11/23 00:51:53 $"
.SH NAME
iverilog-vpi - Compile front end for VPI modules
@@ -32,13 +32,37 @@ VPI modules to further reference external libraries.
Normally, the output VPI module will be named after the first source
file passed to the command. This flag sets the name (without the .vpi
suffix) of the output vpi module.
.SH "PC-ONLY OPTIONS"
The PC port of \fIiverilog-vpi\fP includes two special flags needed to
support the more intractable development environment. These flags help
the program locate parts that it needs.
.TP 8
.B -mingw=\fIpath\fP
Tell the program the root of the Mingw compiler tool suite. The
\fBvvp\fP runtime is compiled with this compiler, and this is the
compiler that \fIiverilog-vpi\fP expects to use to compile your source
code. This is notmally not needed, and if you do use it, it is only
needed once. The compiler will save the \fIpath\fP in the registry for
use later.
.TP 8
.B -ivl=\fIpath\fP
Set for the use during compilation the root if the Icarus Verilog
install. This is the place where you installed Icarus Verilog when you
ran the installer. This flag is also only needed once, and the path is
stored in the registry for future use.
.SH "AUTHOR"
.nf
Steve Williams ([email protected])
.SH SEE ALSO
iverilog(1), vvp(1),
.BR "<http://www.icarus.com/eda/verilog/>"
.BR "<http://www.icarus.com/eda/verilog/>",
.BR "<http://www.mingw.org>",
.SH COPYRIGHT
.nf
+1
View File
@@ -120,6 +120,7 @@ ivl_scope_port
ivl_scope_ports
ivl_scope_sigs
ivl_scope_sig
ivl_scope_time_units
ivl_scope_type
ivl_scope_tname
+67 -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.108 2002/10/23 01:47:17 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
@@ -861,6 +892,11 @@ extern ivl_signal_t ivl_nexus_ptr_sig(ivl_nexus_ptr_t net);
* anything that can become and ivl_signal_t, include synthetic
* signals generated by the compiler.
*
* ivl_scope_time_units
* Scopes have their own intrinsic time units, typically from the
* timescale compiler directive. This method returns the units as a
* signed power of 10 value.
*
* ivl_scope_type
* ivl_scope_tname
* Scopes have a type and a type name. For example, if a scope is
@@ -882,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);
@@ -891,6 +929,7 @@ extern unsigned ivl_scope_sigs(ivl_scope_t net);
extern ivl_signal_t ivl_scope_sig(ivl_scope_t net, unsigned idx);
extern ivl_scope_type_t ivl_scope_type(ivl_scope_t net);
extern const char* ivl_scope_tname(ivl_scope_t net);
extern int ivl_scope_time_units(ivl_scope_t net);
/* SIGNALS
@@ -1065,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)
@@ -1091,6 +1143,17 @@ _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
* implementation of vpiSystemTime the $time functions
* to properly account for this. Also add $simtime
* to get the simulation time.
*
* Revision 1.108 2002/10/23 01:47:17 steve
* Fix synth2 handling of aset/aclr signals where
* flip-flops are split by begin-end blocks.
+4 -3
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.73 2002/06/06 18:57:18 steve Exp $"
#ident "$Id: lexor.lex,v 1.75 2003/01/26 21:15:58 steve Exp $"
#endif
# include "config.h"
@@ -375,7 +375,7 @@ W [ \t\b\f\r]+
if (isgraph(yytext[0]))
cerr << yytext[0];
else
cerr << (unsigned)yytext[0];
cerr << "hex " << hex << (0xffU & ((unsigned) (yytext[0])));
cerr << ")" << endl; }
@@ -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);
}
/*
+2 -2
View File
@@ -16,7 +16,7 @@
# 59 Temple Place - Suite 330
# Boston, MA 02111-1307, USA
#
#ident "$Id: Makefile.in,v 1.14 2002/06/11 15:19:12 steve Exp $"
#ident "$Id: Makefile.in,v 1.15 2002/12/19 21:37:04 steve Exp $"
#
#
SHELL = /bin/sh
@@ -50,7 +50,7 @@ a_initialize.o a_next_topmod.o a_object_of_type.o a_product_version.o \
a_set_value.o a_version.o
O = asynch.o finish.o getcstringp.o getinstance.o getlongp.o \
getp.o getsimtime.o io_print.o mc_scan_plusargs.o nump.o putlongp.o \
putp.o veriusertfs.o $A
putp.o typep.o workarea.o veriusertfs.o $A
all: libveriuser.a
+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: io_print.c,v 1.3 2002/08/12 01:35:02 steve Exp $"
#ident "$Id: io_print.c,v 1.4 2002/12/19 21:37:04 steve Exp $"
#endif
# include <vpi_user.h>
@@ -56,8 +56,29 @@ void tf_error(const char *fmt, ...)
va_end(ap);
}
PLI_INT32 tf_message(PLI_INT32 level, char*facility,
char*messno, char*fmt, ...)
{
va_list ap;
vpi_printf("%s[%s] ", facility, messno);
va_start(ap, fmt);
vpi_vprintf(fmt, ap);
va_end(ap);
vpi_printf("\n");
return 0;
}
/*
* $Log: io_print.c,v $
* Revision 1.4 2002/12/19 21:37:04 steve
* Add tf_message, tf_get/setworkarea, and
* ty_typep functions, along with defines
* related to these functions.
*
* Revision 1.3 2002/08/12 01:35:02 steve
* conditional ident string using autoconfig.
*
+82
View File
@@ -0,0 +1,82 @@
/*
* Copyright (c) 2002 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: typep.c,v 1.1 2002/12/19 21:37:04 steve Exp $"
#endif
#include <assert.h>
#include <veriuser.h>
#include <vpi_user.h>
PLI_INT32 tf_typep(PLI_INT32 narg)
{
vpiHandle sys_h, argv, arg_h = 0;
s_vpi_value value;
int rtn;
assert(narg > 0);
/* get task/func handle */
sys_h = vpi_handle(vpiSysTfCall, 0);
argv = vpi_iterate(vpiArgument, sys_h);
/* find nth arg */
while (narg > 0) {
/* Watch that the argument is not out of range. */
if (!(arg_h = vpi_scan(argv)))
return TF_NULLPARAM;
narg -= 1;
}
switch (vpi_get(vpiType, arg_h)) {
case vpiConstant:
switch (vpi_get(vpiConstType, arg_h)) {
case vpiStringConst:
rtn = TF_STRING;
break;
default:
rtn = TF_READONLY;
break;
}
break;
case vpiIntegerVar:
case vpiReg:
case vpiMemoryWord:
rtn = TF_READWRITE;
break;
default:
rtn = TF_READONLY;
break;
}
vpi_free_object(argv);
return rtn;
}
/*
* $Log: typep.c,v $
* Revision 1.1 2002/12/19 21:37:04 steve
* Add tf_message, tf_get/setworkarea, and
* ty_typep functions, along with defines
* related to these functions.
*
*/
+94
View File
@@ -0,0 +1,94 @@
/*
* Copyright (c) 2002 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: workarea.c,v 1.1 2002/12/19 21:37:04 steve Exp $"
#endif
# include <veriuser.h>
# include <vpi_user.h>
# include <stdlib.h>
#ifdef HAVE_MALLOC_H
# include <malloc.h>
#endif
/*
* Keep a list of sys handle to work area bindings.
*/
struct workarea_cell {
vpiHandle sys;
void* area;
struct workarea_cell*next;
};
static struct workarea_cell*area_list = 0;
PLI_INT32 tf_setworkarea(void*workarea)
{
vpiHandle sys;
struct workarea_cell*cur;
sys = vpi_handle(vpiSysTfCall, 0);
cur = area_list;
while (cur) {
if (cur->sys == sys) {
cur->area = workarea;
return 0;
}
cur = cur->next;
}
cur = calloc(1, sizeof (struct workarea_cell));
cur->next = area_list;
cur->sys = sys;
cur->area = workarea;
area_list = cur;
return 0;
}
PLI_BYTE8* tf_getworkarea(void)
{
struct workarea_cell*cur;
vpiHandle sys;
sys = vpi_handle(vpiSysTfCall, 0);
cur = area_list;
while (cur) {
if (cur->sys == sys) {
return cur->area;
}
cur = cur->next;
}
return 0;
}
/*
* $Log: workarea.c,v $
* Revision 1.1 2002/12/19 21:37:04 steve
* Add tf_message, tf_get/setworkarea, and
* ty_typep functions, along with defines
* related to these functions.
*
*/
+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.
*
+50 -12
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.29 2002/11/02 03:27:52 steve Exp $"
#ident "$Id: net_design.cc,v 1.32 2003/01/26 21:15:58 steve Exp $"
#endif
# include "config.h"
@@ -31,7 +31,7 @@
# include "netlist.h"
# include "util.h"
# include <strstream>
# include <sstream>
Design:: Design()
: errors(0), nodes_(0), procs_(0), lcounter_(0)
@@ -48,10 +48,11 @@ Design::~Design()
string Design::local_symbol(const string&path)
{
strstream res;
res << "_L" << (lcounter_++) << ends;
ostringstream res;
res << path << "." << "_L" << lcounter_;
lcounter_ += 1;
return path + "." + res.str();
return res.str();
}
void Design::set_precision(int val)
@@ -501,24 +502,51 @@ NetScope* Design::find_task(const hname_t&key)
return 0;
}
NetEvent* Design::find_event(NetScope*scope, const hname_t&path)
NetEvent* Design::find_event(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 (NetEvent*ev = scope->find_event(path)) {
if (NetEvent*ev = scope->find_event(key)) {
delete key;
return ev;
}
// If this is a simple name, then do not scan up scopes
// past a module scope. This is a Verilog scoping rule.
if ((path.component_count() == 1)
&& (scope->type() == NetScope::MODULE))
if (scope->type() == NetScope::MODULE)
break;
scope = scope->parent();
}
delete key;
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;
}
@@ -597,6 +625,16 @@ 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.
*
* Revision 1.30 2002/12/07 02:49:24 steve
* Named event triggers can take hierarchical names.
*
* Revision 1.29 2002/11/02 03:27:52 steve
* Allow named events to be referenced by
* hierarchical names.
+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.
*
+9 -6
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_link.cc,v 1.12 2002/10/21 01:42:08 steve Exp $"
#ident "$Id: net_link.cc,v 1.13 2003/01/14 21:16:18 steve Exp $"
#endif
# include "config.h"
@@ -25,7 +25,7 @@
# include <iostream>
# include "netlist.h"
# include <strstream>
# include <sstream>
# include <string>
# include <typeinfo>
#ifdef HAVE_MALLOC_H
@@ -363,14 +363,14 @@ const char* Nexus::name() const
}
assert(sig);
ostrstream tmp;
ostringstream tmp;
tmp << sig->name();
if (sig->pin_count() > 1)
tmp << "<" << pin << ">";
tmp << ends;
name_ = new char[strlen(tmp.str()) + 1];
strcpy(name_, tmp.str());
const string tmps = tmp.str();
name_ = new char[strlen(tmps.c_str()) + 1];
strcpy(name_, tmps.c_str());
return name_;
}
@@ -499,6 +499,9 @@ bool NexusSet::intersect(const NexusSet&that) const
/*
* $Log: net_link.cc,v $
* Revision 1.13 2003/01/14 21:16:18 steve
* Move strstream to ostringstream for compatibility.
*
* Revision 1.12 2002/10/21 01:42:08 steve
* Synthesizer support for synchronous begin-end blocks.
*
+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.
*
+34 -6
View File
@@ -17,13 +17,13 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: net_scope.cc,v 1.20 2002/10/19 22:59:49 steve Exp $"
#ident "$Id: net_scope.cc,v 1.23 2003/01/26 21:15:58 steve Exp $"
#endif
# include "config.h"
# include "netlist.h"
# include <strstream>
# include <sstream>
/*
* The NetScope class keeps a scope tree organized. Each node of the
@@ -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) {
@@ -255,10 +256,19 @@ void NetScope::rem_event(NetEvent*ev)
}
NetEvent* NetScope::find_event(const hname_t&name)
NetEvent* NetScope::find_event(const char*name)
{
for (NetEvent*cur = events_; cur ; cur = cur->snext_)
if (strcmp(cur->name(), name.peek_tail_name()) == 0)
if (strcmp(cur->name(), name) == 0)
return cur;
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;
@@ -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.
@@ -419,8 +437,8 @@ const NetScope* NetScope::parent() const
string NetScope::local_symbol()
{
strstream res;
res << "_s" << (lcounter_++) << ends;
ostringstream res;
res << "_s" << (lcounter_++);
return res.str();
}
@@ -432,6 +450,16 @@ 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.
*
* Revision 1.21 2002/12/07 02:49:24 steve
* Named event triggers can take hierarchical names.
*
* Revision 1.20 2002/10/19 22:59:49 steve
* Redo the parameter vector support to allow
* parameter names in range expressions.
+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.
*
+123 -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: netlist.h,v 1.269 2002/11/09 01:40:19 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
@@ -2494,6 +2591,7 @@ class NetESelect : public NetExpr {
virtual bool set_width(unsigned w);
virtual bool has_width() const;
virtual void expr_scan(struct expr_scan_t*) const;
virtual NetEConst* eval_tree();
virtual NetESelect* dup_expr() const;
private:
@@ -2542,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;
@@ -2794,7 +2893,11 @@ class NetScope {
void add_event(NetEvent*);
void rem_event(NetEvent*);
NetEvent*find_event(const hname_t&name);
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
@@ -2899,6 +3002,7 @@ class NetScope {
map<string,param_expr_t>localparams_;
NetEvent *events_;
NetVariable*vars_;
NetNet *signals_;
NetMemory*memories_;
@@ -2998,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*);
@@ -3084,6 +3191,20 @@ 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.
*
* Revision 1.270 2002/12/05 02:14:33 steve
* Support bit select in constant expressions.
*
* Revision 1.269 2002/11/09 01:40:19 steve
* Postpone parameter width check to evaluation.
*
+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.
*
+26 -9
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.164 2002/11/09 02:22:07 steve Exp $"
#ident "$Id: parse.y,v 1.170 2003/01/26 21:15:59 steve Exp $"
#endif
# include "config.h"
@@ -33,6 +33,24 @@ extern void lex_end_table();
static svector<PExpr*>* active_range = 0;
static bool active_signed = false;
/* Later version of bison (including 1.35) will not compile in stack
extension if the output is compiled with C++ and either the YYSTYPE
or YYLTYPE are provided by the source code. However, I can get the
old behavior back by defining these symbols. */
# define YYSTYPE_IS_TRIVIAL 1
# define YYLTYPE_IS_TRIVIAL 1
/* Recent version of bison expect that the user supply a
YYLLOC_DEFAULT macro that makes up a yylloc value from existing
values. I need to supply an explicit version to account for the
text field, that otherwise won't be copied. */
# define YYLLOC_DEFAULT(Current, Rhs, N) \
Current.first_line = Rhs[1].first_line; \
Current.first_column = Rhs[1].first_column; \
Current.last_line = Rhs[N].last_line; \
Current.last_column = Rhs[N].last_column; \
Current.text = Rhs[1].text;
/*
* These are some common strength pairs that are used as defaults when
* the user is not otherwise specific.
@@ -283,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 ';'
@@ -2084,6 +2100,7 @@ specify_item_list
specify_edge_path_decl
: specify_edge_path '=' '(' specify_delay_value_list ')'
| specify_edge_path '=' delay_value_simple
;
specify_edge_path
@@ -2139,9 +2156,9 @@ specparam
delete $5;
delete $7;
}
| PATHPULSE_IDENTIFIER '=' '(' expression ')'
| PATHPULSE_IDENTIFIER '=' expression
{ delete $1;
delete $4;
delete $3;
}
| PATHPULSE_IDENTIFIER '=' '(' expression ',' expression ')'
{ delete $1;
@@ -2315,8 +2332,8 @@ statement
delete $2;
$$ = tmp;
}
| K_TRIGGER IDENTIFIER ';'
{ PTrigger*tmp = new PTrigger(hname_t($2));
| K_TRIGGER identifier ';'
{ PTrigger*tmp = new PTrigger(*$2);
tmp->set_file(@2.text);
tmp->set_lineno(@2.first_line);
delete $2;
+66 -17
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.102 2002/09/01 03:01:48 steve Exp $"
#ident "$Id: pform.cc,v 1.107 2003/01/26 21:15:59 steve Exp $"
#endif
# include "config.h"
@@ -26,13 +26,14 @@
# include "pform.h"
# include "parse_misc.h"
# include "parse_api.h"
# include "PData.h"
# include "PEvent.h"
# include "PUdp.h"
# include <list>
# include <map>
# include <assert.h>
# include <typeinfo>
# include <strstream>
# include <sstream>
map<string,Module*> pform_modules;
map<string,PUdp*> pform_primitives;
@@ -212,6 +213,16 @@ void pform_endmodule(const char*name)
{
assert(pform_cur_module);
assert(strcmp(name, pform_cur_module->mod_name()) == 0);
map<string,Module*>::const_iterator test = pform_modules.find(name);
if (test != pform_modules.end()) {
ostringstream msg;
msg << "Module " << name << " was already declared here: "
<< (*test).second->get_line() << endl;
VLerror(msg.str().c_str());
pform_cur_module = 0;
return;
}
pform_modules[name] = pform_cur_module;
pform_cur_module = 0;
}
@@ -421,7 +432,7 @@ void pform_make_udp(const char*name, list<string>*parms,
}
/* Verify the "initial" statement, if present, to be sure that
it only assignes to the output and the output is
it only assigns to the output and the output is
registered. Then save the initial value that I get. */
verinum::V init = verinum::Vx;
if (init_expr) {
@@ -547,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
@@ -608,7 +639,7 @@ void pform_makegates(PGBuiltin::Type type,
/*
* A module is different from a gate in that there are different
* constraints, and sometimes different syntax. The X_modgate
* functions handle the instantaions of modules (and UDP objects) by
* functions handle the instantiations of modules (and UDP objects) by
* making PGModule objects.
*/
static void pform_make_modgate(const char*type,
@@ -767,13 +798,13 @@ void pform_make_pgassign_list(svector<PExpr*>*alist,
*
* reg foo = <expr>;
*
* This is equivilent to the combination of statements:
* This is equivalent to the combination of statements:
*
* reg foo;
* initital foo = <expr>;
* initial foo = <expr>;
*
* and that is how it is parsed. This syntax is not part of the
* IEEE1364-1994 standard, but is approved by OVI as enhancement
* IEEE1364-1995 standard, but is approved by OVI as enhancement
* BTF-B14.
*/
void pform_make_reginit(const struct vlltype&li,
@@ -820,11 +851,11 @@ void pform_module_define_port(const struct vlltype&li,
hname_t name = hier_name(nm);
PWire*cur = pform_cur_module->get_wire(name);
if (cur) {
strstream msg;
ostringstream msg;
msg << name << " definition conflicts with "
<< "definition at " << cur->get_line()
<< "." << ends;
VLerror(msg.str());
<< ".";
VLerror(msg.str().c_str());
return;
}
@@ -862,7 +893,7 @@ void pform_module_define_port(const struct vlltype&li,
* reg bar;
*
* The output (or other port direction indicator) may or may not have
* been seen already, so I do not do any cheching with it yet. But I
* been seen already, so I do not do any checking with it yet. But I
* do check to see if the name has already been declared, as this
* function is called for every declaration.
*/
@@ -874,18 +905,18 @@ void pform_makewire(const vlltype&li, const char*nm,
if (cur) {
if ((cur->get_wire_type() != NetNet::IMPLICIT)
&& (cur->get_wire_type() != NetNet::IMPLICIT_REG)) {
strstream msg;
ostringstream msg;
msg << name << " previously defined at " <<
cur->get_line() << "." << ends;
VLerror(msg.str());
cur->get_line() << ".";
VLerror(msg.str().c_str());
} else {
bool rc = cur->set_wire_type(type);
if (rc == false) {
strstream msg;
ostringstream msg;
msg << name << " definition conflicts with "
<< "definition at " << cur->get_line()
<< "." << ends;
VLerror(msg.str());
<< ".";
VLerror(msg.str().c_str());
}
}
@@ -948,6 +979,8 @@ void pform_makewire(const vlltype&li,
PWire*cur = pform_cur_module->get_wire(name);
if (cur != 0) {
PEIdent*lval = new PEIdent(hname_t(first->name));
lval->set_file(li.text);
lval->set_lineno(li.first_line);
pform_make_pgassign(lval, first->expr, delay, str);
}
@@ -1360,6 +1393,22 @@ 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.
*
* Revision 1.105 2003/01/16 21:44:19 steve
* Detect duplicate module declarations.
*
* Revision 1.104 2003/01/14 21:16:18 steve
* Move strstream to ostringstream for compatibility.
*
* Revision 1.103 2003/01/10 03:08:13 steve
* Spelling fixes.
*
* Revision 1.102 2002/09/01 03:01:48 steve
* Properly cast signedness of parameters with ranges.
*
+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.
*
+1 -1
View File
@@ -1,7 +1,7 @@
PKG="IVLver"
NAME="verilog"
ARCH="sparc"
VERSION="0.6"
VERSION="0.7"
CATEGORY="application"
VENDOR="Icarus.com"
EMAIL="[email protected]"
+75 -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.88 2002/10/23 01:47:17 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);
@@ -1157,6 +1199,12 @@ extern "C" ivl_signal_t ivl_scope_sig(ivl_scope_t net, unsigned idx)
return net->sigs_[idx];
}
extern "C" int ivl_scope_time_units(ivl_scope_t net)
{
assert(net);
return net->time_units;
}
extern "C" ivl_scope_type_t ivl_scope_type(ivl_scope_t net)
{
assert(net);
@@ -1478,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);
}
@@ -1583,8 +1634,31 @@ 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
* implementation of vpiSystemTime the $time functions
* to properly account for this. Also add $simtime
* to get the simulation time.
*
* Revision 1.88 2002/10/23 01:47:17 steve
* Fix synth2 handling of aset/aclr signals where
* flip-flops are split by begin-end blocks.
@@ -1621,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.
*
+72 -6
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.100 2002/11/05 02:12:35 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,8 +457,12 @@ 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();
des_.nroots_++;
if (des_.roots_)
des_.roots_ = (ivl_scope_t *)realloc(des_.roots_, des_.nroots_ * sizeof(ivl_scope_t));
@@ -631,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;
@@ -1766,6 +1806,7 @@ void dll_target::scope(const NetScope*net)
scope->child_ = 0;
scope->sibling_ = 0;
scope->parent = find_scope(des_, net->parent());
assert(scope->parent);
scope->nsigs_ = 0;
scope->sigs_ = 0;
scope->nlog_ = 0;
@@ -1776,16 +1817,27 @@ 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()) {
case NetScope::MODULE:
scope->type_ = IVL_SCT_MODULE;
scope->tname_ = net->module_name();
break;
case NetScope::TASK:
scope->type_ = IVL_SCT_TASK;
scope->tname_ = strings_.add(net->task_def()->name().c_str());
break;
case NetScope::TASK: {
const NetTaskDef*def = net->task_def();
if (def == 0) {
cerr << "?:?" << ": internal error: "
<< "task " << scope->name_
<< " has no definition." << endl;
}
assert(def);
scope->type_ = IVL_SCT_TASK;
scope->tname_ = strings_.add(def->name().c_str());
break;
}
case NetScope::FUNC:
scope->type_ = IVL_SCT_FUNCTION;
scope->tname_ = strings_.add(net->func_def()->name().c_str());
@@ -1981,6 +2033,20 @@ 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.
*
* Revision 1.101 2002/12/21 00:55:58 steve
* The $time system task returns the integer time
* scaled to the local units. Change the internal
* implementation of vpiSystemTime the $time functions
* to properly account for this. Also add $simtime
* to get the simulation time.
*
* Revision 1.100 2002/11/05 02:12:35 steve
* Fix the call to FormatMessage under Windows.
*
+41 -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.95 2002/10/23 01:47:17 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,11 +509,16 @@ 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;
unsigned ports;
ivl_signal_t*port;
signed int time_units :8;
};
/*
@@ -620,8 +639,28 @@ 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
* implementation of vpiSystemTime the $time functions
* to properly account for this. Also add $simtime
* to get the simulation time.
*
* Revision 1.95 2002/10/23 01:47:17 steve
* Fix synth2 handling of aset/aclr signals where
* flip-flops are split by begin-end blocks.
+7 -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: t-xnf.cc,v 1.45 2002/08/12 01:35:01 steve Exp $"
#ident "$Id: t-xnf.cc,v 1.46 2003/01/14 21:16:18 steve Exp $"
#endif
# include "config.h"
@@ -77,7 +77,7 @@
# include "netlist.h"
# include "target.h"
# include <fstream>
# include <strstream>
# include <sstream>
verinum::V link_get_ival(const Link&lnk)
{
@@ -765,8 +765,8 @@ void target_xnf::lpm_ram_dq(const NetRamDq*ram)
draw_pin(out_, "WE", ram->pin_WE());
draw_pin(out_, "WCLK", ram->pin_InClock());
for (unsigned adr = 0 ; adr < ram->awidth() ; adr += 1) {
strstream tmp;
tmp << "A" << adr << ends;
ostringstream tmp;
tmp << "A" << adr;
draw_pin(out_, tmp.str(), ram->pin_Address(adr));
}
@@ -927,6 +927,9 @@ extern const struct target tgt_xnf = { "xnf", &target_xnf_obj };
/*
* $Log: t-xnf.cc,v $
* Revision 1.46 2003/01/14 21:16:18 steve
* Move strstream to ostringstream for compatibility.
*
* Revision 1.45 2002/08/12 01:35:01 steve
* conditional ident string using autoconfig.
*
+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.
*
+263 -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: d-virtex.c,v 1.18 2002/11/01 02:36:34 steve Exp $"
#ident "$Id: d-virtex.c,v 1.21 2002/11/24 02:26:14 steve Exp $"
#endif
# include "device.h"
@@ -38,6 +38,8 @@
* place-and-route step, as it is not normally needed within an
* FPGA net.
*
* BUFT O, I, T
*
* INV O, I
* Inverting buffer.
*
@@ -74,6 +76,13 @@ static const char*virtex_library_text =
" (interface\n"
" (port O (direction OUTPUT))\n"
" (port I (direction INPUT)))))\n"
" (cell BUFT (cellType GENERIC)\n"
" (view net\n"
" (viewType NETLIST)\n"
" (interface\n"
" (port O (direction OUTPUT))\n"
" (port I (direction OUTPUT))\n"
" (port T (direction INPUT)))))\n"
" (cell FDCE (cellType GENERIC)\n"
" (view net\n"
" (viewType NETLIST)\n"
@@ -422,6 +431,227 @@ void edif_show_cellref_logic(ivl_net_logic_t net, const char*cellref)
}
}
/*
* This function draw wide AND-like devices. The input must have at
* least 5 bits.
*/
static void wide_AND_logic(ivl_net_logic_t net, unsigned edif_uref)
{
char jbuf[1024];
/* This is the number of input bits left to connect. */
unsigned ibits = ivl_logic_pins(net) - 1;
/* Index to the next input bit. */
unsigned idx = 1;
unsigned slice = 0;
const char*lut4_init;
const char*lut3_init;
const char*lut2_init;
const char*lut1_dev;
switch (ivl_logic_type(net)) {
case IVL_LO_AND:
lut4_init = "\"8000\"";
lut3_init = "\"80\"";
lut2_init = "\"8\"";
lut1_dev = "BUF";
break;
case IVL_LO_NOR:
lut4_init = "\"0001\"";
lut3_init = "\"01\"";
lut2_init = "\"1\"";
lut1_dev = "INV";
break;
default:
assert(0);
}
assert(ibits > 4);
while (ibits >= 4) {
/* The least significant bits are ANDed together 4 at a
time with LUT4 devices. The output of the LUT4 device
connects to a MUXCY device that passes its output
up to the next stage.
The DI input of the MUXCY (S==0) is connected to
ground, so that the ouput of the chain is pinned to 0
if this slice does not AND to 1.
If the LUT emits 1, S==1 and this slice passes the
compare from below. So the CI of the MUXCY gets the O
of the MUXCY one slice back. */
fprintf(xnf, "(instance U%uL%u"
" (viewRef net"
" (cellRef LUT4 (libraryRef VIRTEX)))"
" (property INIT (string %s)))\n",
edif_uref, slice, lut4_init);
fprintf(xnf, "(instance U%uM%u"
" (viewRef net"
" (cellRef MUXCY (libraryRef VIRTEX))))\n",
edif_uref, slice);
fprintf(xnf, "(instance U%uG%u"
" (viewRef net"
" (cellRef GND (libraryRef VIRTEX))))\n",
edif_uref, slice);
fprintf(xnf, "(net U%uLM%u (joined"
" (portRef O (instanceRef U%uL%u))"
" (portRef S (instanceRef U%uM%u))))\n",
edif_uref, slice,
edif_uref, slice,
edif_uref, slice);
fprintf(xnf, "(net U%uGM%u (joined"
" (portRef GROUND (instanceRef U%uG%u))"
" (portRef DI (instanceRef U%uM%u))))\n",
edif_uref, slice,
edif_uref, slice,
edif_uref, slice);
if (slice == 0) {
fprintf(xnf, "(instance U%uV%u"
" (viewRef net"
" (cellRef VCC (libraryRef VIRTEX))))\n",
edif_uref, slice);
fprintf(xnf, "(net U%uMM%u (joined"
" (portRef VCC (instanceRef U%uG%u))"
" (portRef CI (instanceRef U%uM%u))))\n",
edif_uref, slice,
edif_uref, slice,
edif_uref, slice);
} else {
fprintf(xnf, "(net U%uMM%u (joined"
" (portRef O (instanceRef U%uM%u))"
" (portReg CI (instanceRef U%uM%u))))\n",
edif_uref, slice,
edif_uref, slice-1,
edif_uref, slice);
}
sprintf(jbuf, "(portRef I0 (instanceRef U%uL%u))",
edif_uref, slice);
edif_set_nexus_joint(ivl_logic_pin(net, idx+0), jbuf);
sprintf(jbuf, "(portRef I1 (instanceRef U%uL%u))",
edif_uref, slice);
edif_set_nexus_joint(ivl_logic_pin(net, idx+1), jbuf);
sprintf(jbuf, "(portRef I2 (instanceRef U%uL%u))",
edif_uref, slice);
edif_set_nexus_joint(ivl_logic_pin(net, idx+2), jbuf);
sprintf(jbuf, "(portRef I3 (instanceRef U%uL%u))",
edif_uref, slice);
edif_set_nexus_joint(ivl_logic_pin(net, idx+3), jbuf);
ibits -= 4;
idx += 4;
slice += 1;
}
if (ibits == 0) {
sprintf(jbuf, "(portRef O (instanceRef U%uM%u))",
edif_uref, slice-1);
edif_set_nexus_joint(ivl_logic_pin(net, 0), jbuf);
return;
}
switch (ibits) {
case 1:
fprintf(xnf, "(instance U%uL%u"
" (viewRef net"
" (cellRef %s (libraryRef VIRTEX))))\n",
edif_uref, slice, lut1_dev);
sprintf(jbuf, "(portRef I0 (instanceRef U%uL%u))",
edif_uref, slice);
edif_set_nexus_joint(ivl_logic_pin(net, idx+0), jbuf);
break;
case 2:
fprintf(xnf, "(instance U%uL%u"
" (viewRef net"
" (cellRef LUT2 (libraryRef VIRTEX)))"
" (property INIT (string %s)))\n",
edif_uref, slice, lut2_init);
sprintf(jbuf, "(portRef I0 (instanceRef U%uL%u))",
edif_uref, slice);
edif_set_nexus_joint(ivl_logic_pin(net, idx+0), jbuf);
sprintf(jbuf, "(portRef I1 (instanceRef U%uL%u))",
edif_uref, slice);
edif_set_nexus_joint(ivl_logic_pin(net, idx+1), jbuf);
break;
case 3:
fprintf(xnf, "(instance U%uL%u"
" (viewRef net"
" (cellRef LUT3 (libraryRef VIRTEX)))"
" (property INIT (string %s)))\n",
edif_uref, slice, lut3_init);
sprintf(jbuf, "(portRef I0 (instanceRef U%uL%u))",
edif_uref, slice);
edif_set_nexus_joint(ivl_logic_pin(net, idx+0), jbuf);
sprintf(jbuf, "(portRef I1 (instanceRef U%uL%u))",
edif_uref, slice);
edif_set_nexus_joint(ivl_logic_pin(net, idx+1), jbuf);
sprintf(jbuf, "(portRef I2 (instanceRef U%uL%u))",
edif_uref, slice);
edif_set_nexus_joint(ivl_logic_pin(net, idx+2), jbuf);
break;
default:
assert(0);
}
fprintf(xnf, "(instance U%uM%u"
" (viewRef net"
" (cellRef MUXCY (libraryRef VIRTEX))))\n",
edif_uref, slice);
fprintf(xnf, "(instance U%uG%u"
" (viewRef net"
" (cellRef GND (libraryRef VIRTEX))))\n",
edif_uref, slice);
fprintf(xnf, "(net U%uLM%u (joined"
" (portRef O (instanceRef U%uL%u))"
" (portRef S (instanceRef U%uM%u))))\n",
edif_uref, slice,
edif_uref, slice,
edif_uref, slice);
fprintf(xnf, "(net U%uGM%u (joined"
" (portRef GROUND (instanceRef U%uG%u))"
" (portRef DI (instanceRef U%uM%u))))\n",
edif_uref, slice,
edif_uref, slice,
edif_uref, slice);
fprintf(xnf, "(net U%uMM%u (joined"
" (portRef O (instanceRef U%uM%u))"
" (portReg CI (instanceRef U%uM%u))))\n",
edif_uref, slice,
edif_uref, slice-1,
edif_uref, slice);
sprintf(jbuf, "(portRef O (instanceRef U%uM%u))",
edif_uref, slice);
edif_set_nexus_joint(ivl_logic_pin(net, 0), jbuf);
}
static void edif_show_virtex_logic(ivl_net_logic_t net)
{
char jbuf[1024];
@@ -438,7 +668,6 @@ static void edif_show_virtex_logic(ivl_net_logic_t net)
switch (ivl_logic_type(net)) {
case IVL_LO_AND:
assert(ivl_logic_pins(net) <= 5);
assert(ivl_logic_pins(net) >= 3);
switch (ivl_logic_pins(net)) {
@@ -463,6 +692,9 @@ static void edif_show_virtex_logic(ivl_net_logic_t net)
ivl_logic_pin(net, 3),
ivl_logic_pin(net, 4), "8000");
break;
default:
wide_AND_logic(net, edif_uref);
break;
}
break;
@@ -481,8 +713,24 @@ static void edif_show_virtex_logic(ivl_net_logic_t net)
edif_set_nexus_joint(ivl_logic_pin(net, 1), jbuf);
break;
case IVL_LO_BUFIF1:
assert(ivl_logic_pins(net) == 3);
fprintf(xnf, "(instance (rename U%u \"%s\")",
edif_uref, ivl_logic_name(net));
fprintf(xnf, " (viewRef net"
" (cellRef TBUF (libraryRef VIRTEX))))\n");
sprintf(jbuf, "(portRef O (instanceRef U%u))", edif_uref);
edif_set_nexus_joint(ivl_logic_pin(net, 0), jbuf);
sprintf(jbuf, "(portRef I (instanceRef U%u))", edif_uref);
edif_set_nexus_joint(ivl_logic_pin(net, 1), jbuf);
sprintf(jbuf, "(portRef T (instanceRef U%u))", edif_uref);
edif_set_nexus_joint(ivl_logic_pin(net, 2), jbuf);
break;
case IVL_LO_NOR:
assert(ivl_logic_pins(net) <= 5);
assert(ivl_logic_pins(net) >= 3);
switch (ivl_logic_pins(net)) {
@@ -507,6 +755,9 @@ static void edif_show_virtex_logic(ivl_net_logic_t net)
ivl_logic_pin(net, 3),
ivl_logic_pin(net, 4), "0001");
break;
default:
wide_AND_logic(net, edif_uref);
break;
}
break;
@@ -1657,6 +1908,15 @@ const struct device_s d_virtex_edif = {
/*
* $Log: d-virtex.c,v $
* Revision 1.21 2002/11/24 02:26:14 steve
* Fix instanceRef spelling.
*
* Revision 1.20 2002/11/22 05:46:06 steve
* Handle wide AND/NOR devices with Virtex carry logic.
*
* Revision 1.19 2002/11/22 01:45:40 steve
* Implement bufif1 as BUFT
*
* Revision 1.18 2002/11/01 02:36:34 steve
* Fix bottom bit of ADD/SUB device.
*
+74 -11
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.70 2002/10/23 01:45:24 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;
@@ -666,26 +713,31 @@ static int show_scope(ivl_scope_t net, void*x)
switch (ivl_scope_type(net)) {
case IVL_SCT_MODULE:
fprintf(out, " module %s\n", ivl_scope_tname(net));
fprintf(out, " module %s", ivl_scope_tname(net));
break;
case IVL_SCT_FUNCTION:
fprintf(out, " function %s\n", ivl_scope_tname(net));
fprintf(out, " function %s", ivl_scope_tname(net));
break;
case IVL_SCT_BEGIN:
fprintf(out, " begin : %s\n", ivl_scope_tname(net));
fprintf(out, " begin : %s", ivl_scope_tname(net));
break;
case IVL_SCT_FORK:
fprintf(out, " fork : %s\n", ivl_scope_tname(net));
fprintf(out, " fork : %s", ivl_scope_tname(net));
break;
case IVL_SCT_TASK:
fprintf(out, " task %s\n", ivl_scope_tname(net));
fprintf(out, " task %s", ivl_scope_tname(net));
break;
default:
fprintf(out, " type(%u) %s\n", ivl_scope_type(net),
fprintf(out, " type(%u) %s", ivl_scope_type(net),
ivl_scope_tname(net));
break;
}
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));
@@ -728,6 +780,17 @@ 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
* implementation of vpiSystemTime the $time functions
* to properly account for this. Also add $simtime
* to get the simulation time.
*
* Revision 1.70 2002/10/23 01:45:24 steve
* Fix synth2 handling of aset/aclr signals where
* flip-flops are split by begin-end blocks.
+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
+204 -77
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.84 2002/11/07 03:12:17 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);
@@ -618,9 +708,62 @@ static struct vector_info draw_binary_expr_lrs(ivl_expr_t exp, unsigned wid)
{
ivl_expr_t le = ivl_expr_oper1(exp);
ivl_expr_t re = ivl_expr_oper2(exp);
const char*opcode = "?";
struct vector_info lv;
/* Evaluate the expression that is to be shifted. */
switch (ivl_expr_opcode(exp)) {
case 'l': /* << (left shift) */
lv = draw_eval_expr_wid(le, wid, 0);
/* shifting 0 gets 0. */
if (lv.base == 0)
break;
if (lv.base < 4) {
struct vector_info tmp;
tmp.base = allocate_vector(lv.wid);
tmp.wid = lv.wid;
fprintf(vvp_out, " %%mov %u, %u, %u;\n",
tmp.base, lv.base, lv.wid);
lv = tmp;
}
opcode = "%shiftl";
break;
case 'r': /* >> (unsigned right shift) */
/* with the right shift, there may be high bits that are
shifted into the desired width of the expression, so
we let the expression size itself, if it is bigger
then what is requested of us. */
if (wid > ivl_expr_width(le)) {
lv = draw_eval_expr_wid(le, wid, 0);
} else {
lv = draw_eval_expr_wid(le, ivl_expr_width(le), 0);
}
/* shifting 0 gets 0. */
if (lv.base == 0)
break;
if (lv.base < 4) {
struct vector_info tmp;
tmp.base = allocate_vector(lv.wid);
tmp.wid = lv.wid;
fprintf(vvp_out, " %%mov %u, %u, %u;\n",
tmp.base, lv.base, lv.wid);
lv = tmp;
}
opcode = "%shiftr";
break;
default:
assert(0);
}
/* Figure out the shift amount and load that into the index
register. The value may be a constant, or may need to be
evaluated at run time. */
@@ -661,21 +804,11 @@ static struct vector_info draw_binary_expr_lrs(ivl_expr_t exp, unsigned wid)
}
}
lv = draw_eval_expr_wid(le, wid, 0);
switch (ivl_expr_opcode(exp)) {
fprintf(vvp_out, " %s/i0 %u, %u;\n", opcode, lv.base, lv.wid);
case 'l': /* << (left shift) */
fprintf(vvp_out, " %%shiftl/i0 %u, %u;\n", lv.base, lv.wid);
break;
case 'r': /* >> (unsigned right shift) */
fprintf(vvp_out, " %%shiftr/i0 %u, %u;\n", lv.base, lv.wid);
break;
default:
assert(0);
}
if (lv.base >= 8)
save_expression_lookaside(lv.base, exp, lv.wid);
return lv;
}
@@ -791,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);
@@ -1121,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.
@@ -1338,7 +1490,7 @@ static struct vector_info draw_select_expr(ivl_expr_t exp, unsigned wid)
writeable vector space and work from there instead. */
if (subv.base < 4) {
res.base = allocate_vector(subv.wid);
res.wid = wid;
res.wid = subv.wid;
fprintf(vvp_out, " %%mov %u, %u, %u;\n", res.base,
subv.base, res.wid);
subv = res;
@@ -1533,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:
@@ -1818,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
@@ -1888,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;
@@ -1915,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;
@@ -1927,66 +2101,19 @@ struct vector_info draw_eval_expr(ivl_expr_t exp, int stuff_ok_flag)
/*
* $Log: eval_expr.c,v $
* Revision 1.84 2002/11/07 03:12:17 steve
* Vectorize load from REG variables.
* Revision 1.90 2003/01/27 00:14:37 steve
* Support in various contexts the $realtime
* system task.
*
* Revision 1.83 2002/11/06 05:41:37 steve
* Concatenation can evaluate sub-expressions in place.
* Revision 1.89 2003/01/26 21:15:59 steve
* Rework expression parsing and elaboration to
* accommodate real/realtime values and expressions.
*
* Revision 1.82 2002/10/20 02:55:37 steve
* Properly set or clear expression lookaside for binary 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.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.
* Revision 1.87 2002/12/19 23:11:29 steve
* Keep bit select subexpression width if it is constant.
*/
+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
+146 -22
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.75 2002/11/17 18:31:09 steve Exp $"
#ident "$Id: vvp_process.c,v 1.78 2003/01/27 00:14:37 steve Exp $"
#endif
# include "vvp_priv.h"
@@ -79,8 +79,8 @@ static void set_to_lvariable(ivl_lval_t lval, unsigned idx,
if (ivl_lval_mux(lval)) {
assert(wid == 1);
fprintf(vvp_out, " %%set/x V_%s, %u, 0;\n",
vvp_signal_label(sig), bit);
fprintf(vvp_out, " %%set/x0 V_%s, %u, %u;\n",
vvp_signal_label(sig), bit, ivl_signal_pins(sig)-1);
} else if (wid == 1) {
fprintf(vvp_out, " %%set V_%s[%u], %u;\n",
vvp_signal_label(sig), idx+part_off, bit);
@@ -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);
@@ -191,6 +191,8 @@ static int show_stmt_assign(ivl_statement_t net)
value and write it into index0. */
if (ivl_lval_mux(lval)) {
calculate_into_x0(ivl_lval_mux(lval));
/* Generate code to skip around the set
if the index has X values. */
fprintf(vvp_out, " %%jmp/1 t_%u, 4;\n", skip_set);
skip_set_flag = 1;
}
@@ -198,6 +200,8 @@ static int show_stmt_assign(ivl_statement_t net)
mem = ivl_lval_mem(lval);
if (mem) {
draw_memory_index_expr(mem, ivl_lval_idx(lval));
/* Generate code to skip around the set
if the index has X values. */
fprintf(vvp_out, " %%jmp/1 t_%u, 4;\n", skip_set);
skip_set_flag = 1;
}
@@ -234,14 +238,7 @@ static int show_stmt_assign(ivl_statement_t net)
idx += cnt;
}
#if 0
for (idx = 0 ; idx < bit_limit ; idx += 1) {
set_to_lvariable(lval, idx,
bitchar_to_idx(bits[cur_rbit]), 1);
cur_rbit += 1;
}
#endif
if (bit_limit < ivl_lval_pins(lval)) {
unsigned cnt = ivl_lval_pins(lval) - bit_limit;
set_to_lvariable(lval, bit_limit, 0, cnt);
@@ -328,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;
@@ -837,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");
@@ -1134,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;
@@ -1156,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++;
}
@@ -1203,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));
@@ -1217,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:
@@ -1234,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);
}
@@ -1452,6 +1565,17 @@ 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.
*
* Revision 1.75 2002/11/17 18:31:09 steve
* Generate unique labels for force functors.
*
+54 -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: vvp_scope.c,v 1.80 2002/10/23 04:39:35 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.
*/
@@ -1367,10 +1374,21 @@ static void draw_lpm_ff(ivl_lpm_t net)
static void draw_lpm_shiftl(ivl_lpm_t net)
{
unsigned idx, width, selects;
unsigned selwid;
width = ivl_lpm_width(net);
selects = ivl_lpm_selects(net);
/* The .shift device can only take as many select inputs as
the width of the device.
XXXX I should make some sort of overflow gate for this? If
any high bits are set, then the shift is certain to be
*way* beyond the width of the left shifted value. XXXX */
selwid = selects;
if (selwid > width)
selwid = width;
if (ivl_lpm_type(net) == IVL_LPM_SHIFTR)
fprintf(vvp_out, "L_%s .shift/r %u",
vvp_mangle_id(ivl_lpm_name(net)), width);
@@ -1383,11 +1401,15 @@ static void draw_lpm_shiftl(ivl_lpm_t net)
draw_input_from_net(ivl_lpm_data(net, idx));
}
for (idx = 0 ; idx < selects ; idx += 1) {
for (idx = 0 ; idx < selwid ; idx += 1) {
fprintf(vvp_out, ", ");
draw_input_from_net(ivl_lpm_select(net, idx));
}
for (idx = selwid ; idx < width ; idx += 1) {
fprintf(vvp_out, ", C<0>");
}
fprintf(vvp_out, ";\n");
}
@@ -1532,12 +1554,16 @@ int draw_scope(ivl_scope_t net, ivl_scope_t parent)
vvp_mangle_id(ivl_scope_name(net)),
type,
vvp_mangle_name(ivl_scope_name(net)));
if (parent) {
fprintf(vvp_out, ", S_%s;\n",
vvp_mangle_id(ivl_scope_name(parent)));
}
else
} else {
fprintf(vvp_out, ";\n");
}
fprintf(vvp_out, " .timescale %d;\n", ivl_scope_time_units(net));
/* Scan the scope for logic devices. For each device, draw out
a functor that connects pin 0 to the output, and the
@@ -1549,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. */
@@ -1592,6 +1628,20 @@ 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
* implementation of vpiSystemTime the $time functions
* to properly account for this. Also add $simtime
* to get the simulation time.
*
* Revision 1.81 2002/11/21 18:08:09 steve
* Better handling of select width of shifters.
*
* Revision 1.80 2002/10/23 04:39:35 steve
* draw lpm ff with aset_expr taken into account.
*
+3 -3
View File
@@ -1,10 +1,10 @@
Summary: Icarus Verilog
Name: verilog
Version: 0.6.20021117
Version: 0.7
Release: 0
Copyright: GPL
Group: Applications/Engineering
Source: ftp://icarus.com/pub/eda/verilog/snapshots/verilog-20021117.tar.gz
Source: ftp://icarus.com/pub/eda/verilog/snapshots/verilog-0.7.tar.gz
URL: http://www.icarus.com/eda/verilog/index.html
Packager: Stephen Williams <[email protected]>
@@ -20,7 +20,7 @@ engineering formats, including simulation. It strives to be true
to the IEEE-1364 standard.
%prep
%setup -n verilog-20021117
%setup -n verilog-0.7
%build
./configure --prefix=/usr
+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.
*
+134 -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: veriuser.h,v 1.17 2002/08/12 01:35:01 steve Exp $"
#ident "$Id: veriuser.h,v 1.18 2002/12/19 21:37:04 steve Exp $"
#endif
/*
@@ -56,6 +56,47 @@
EXTERN_C_START
#ifndef PLI_TYPES
#define PLI_TYPES
typedef signed int PLI_INT32;
typedef unsigned int PLI_UINT32;
typedef signed short PLI_INT16;
typedef unsigned short PLI_UINT12;
typedef signed char PLI_BYTE8;
typedef unsigned char PLI_UBYTE8;
#endif
/*
* defines for tf_message
*/
#define ERR_MESSAGE 1
#define ERR_WARNING 2
#define ERR_ERROR 3
#define ERR_INTERNAL 4
#define ERR_SYSTEM 5
/*
* These are some defines for backwards compatibility. They should not
* be used in new code.
*/
#ifndef TRUE
# define TRUE 1
#endif
#ifndef FALSE
# define FALSE 0
#endif
#ifndef __cplusplus
# ifndef true
# define true 1
# endif
# ifndef false
# define false 0
# endif
# ifndef bool
# define bool int
# endif
#endif
/*
* structure for veriusertfs array
*/
@@ -74,6 +115,20 @@ typedef struct t_tfcell
char reserved[20]; /* reserved */
} s_tfcell, *p_tfcell;
/*
* Normal PLI1.0 modules export a veriusertfs array that contains all
* the function definitions for use by the simulator. The user code is
* expected to supply that array.
*
* However, Icarus Verilog doesn't normally look for the veriusertfs
* array, it instead looks for the vlog_startup_routines array, as
* declared in vpi_user.h. So the veriuser library includes the
* veriusertfs_register function that can be used to do the PLI 1.0
* setup. Create a vlog_startup_routines table like this if you are
* just interested in making your PLI1 functions work:
*
* void (*vlog_startup_routines[])() = { &veriusertfs_register };
*/
extern s_tfcell veriusertfs[];
extern void veriusertfs_register();
@@ -88,6 +143,64 @@ extern void veriusertfs_register();
#define reason_finish 9
#define reason_endofcompile 16
/* These are values returned by tf_typep */
#define tf_nullparam 0
#define TF_NULLPARAM tf_nullparam
#define tf_string 1
#define TF_STRING tf_string
#define tf_readonly 10
#define TF_READONLY tf_readonly
#define tf_readwrite 11
#define TF_READWRITE tf_readwrite
#define tf_rwbitselect 12
#define TF_RWBITSELECT tf_rwbitselect
#define tf_rwpartselect 13
#define TF_RWPARTSELECT tf_rwpartselect
#define tf_rwmemselect 14
#define TF_RWMEMSELECT tf_rwmemselect
#define tf_readonlyreal 15
#define TF_READONLYREAL tf_readonlyreal
#define tf_readwritereal 16
#define TF_READWRITEREAD tf_readwritereal
typedef struct t_tfnodeinfo {
PLI_INT16 node_type;
PLI_INT16 padding;
union {
struct t_vecval *vecval_p;
struct t_strengthval *strengthval_p;
PLI_BYTE8 *memoryval_p;
double *read_value_p;
} node_value;
char* node_symbol;
PLI_INT32 node_ngroups;
PLI_INT32 node_vec_size;
PLI_INT32 node_sign;
PLI_INT32 node_ms_index;
PLI_INT32 node_ls_index;
PLI_INT32 node_mem_size;
PLI_INT32 node_lhs_element;
PLI_INT32 node_rhs_element;
PLI_INT32*node_handle;
} s_tfnodeinfo, *p_tfnodeinfo;
/* values used in the node_type of the tfnodeinfo structure. */
#define tf_null_node 100
#define TF_NULL_NODE tf_null_node
#define tf_reg_node 101
#define TF_REG_NODE tf_reg_node
#define tf_integer_node 102
#define TF_INTEGER_NODE tf_integer_node
#define tf_time_node 103
#define TF_TIME_NODE tf_time_node
#define tf_netvector_node 104
#define TF_NETVECTOR_NODE tf_netvector_node
#define tf_netscalar_node 105
#define TF_NETSCALAR_NODE tf_netscalar_node
#define tf_memory_node 106
#define TF_MEMORY_NODE tf_memory_node
#define tf_real_node 107
#define TF_REAL_NODE tf_real_node
/* Extern functions from the library. */
extern void io_printf (const char *, ...)
@@ -114,6 +227,12 @@ extern int tf_getlongtime(int*high_bits);
extern int tf_getp(int pnum);
extern PLI_BYTE8* tf_getworkarea(void);
extern PLI_INT32 tf_message(PLI_INT32 level, char*facility,
char*messno, char*fmt, ...)
__attribute__((format (printf,4,5)));
extern int tf_nump(void);
/* IEEE1364 NOTE: tf_putlongp is listed as returning in in the header
@@ -123,6 +242,15 @@ extern void tf_putlongp(int pnum, int lowvalue, int highvalue);
extern void tf_putp(int pnum, int value);
/* IEEE1364 NOTE: tf_setworkarea is listed as taking a PLI_BYTE8*, but
that is silly, it really takes any kind of pointer. Taking void* is
compatible with those who pass a PLI_BYTE8*. */
extern PLI_INT32 tf_setworkarea(void*workarea);
extern char* tf_spname(void);
extern PLI_INT32 tf_typep(PLI_INT32 narg);
extern void tf_warning(const char*, ...)
__attribute__((format (printf,1,2)));
@@ -130,6 +258,11 @@ EXTERN_C_END
/*
* $Log: veriuser.h,v $
* Revision 1.18 2002/12/19 21:37:04 steve
* Add tf_message, tf_get/setworkarea, and
* ty_typep functions, along with defines
* related to these functions.
*
* Revision 1.17 2002/08/12 01:35:01 steve
* conditional ident string using autoconfig.
*
+3 -3
View File
@@ -18,7 +18,7 @@
# 59 Temple Place - Suite 330
# Boston, MA 02111-1307, USA
#
#ident "$Id: Makefile.in,v 1.31 2002/04/07 04:37:53 steve Exp $"
#ident "$Id: Makefile.in,v 1.32 2003/01/10 03:06:32 steve Exp $"
#
#
SHELL = /bin/sh
@@ -60,12 +60,12 @@ sys_random.o sys_readmem.o sys_readmem_lex.o sys_time.o sys_vcd.o \
sys_lxt.o lxt_write.o \
mt19937int.o
SYSTEM_VPI_LDFLAGS = -L.. -lvpi
SYSTEM_VPI_LDFLAGS = -L../vvp -lvpi
ifeq (@WIN32@,yes)
SYSTEM_VPI_LDFLAGS += -liberty
endif
system.vpi: $O ../libvpi.a
system.vpi: $O ../vvp/libvpi.a
$(CC) @shared@ -o $@ $O $(SYSTEM_VPI_LDFLAGS)
sys_readmem_lex.c: sys_readmem_lex.lex
+182 -83
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.46 2002/11/09 06:01:11 steve Exp $"
#ident "$Id: sys_display.c,v 1.49 2003/01/26 18:18:36 steve Exp $"
#endif
# include "config.h"
@@ -113,96 +113,158 @@ static void array_from_iterator(struct strobe_cb_info*info, vpiHandle argv)
}
}
static void format_time(unsigned mcd, int fsize, const char*value)
/*
* This function writes the time value into the mcd target with the
* proper format. The mcd is the destination file.
*
* The fsize is the width of the field to use. Normally, this is -1 to
* reflect the format string "%t". It may also be 0 for the format
* string "%0t". This formatter also allows for the nonstandard use of
* positive values to enforce a with to override the width given in
* the $timeformat system task.
*
* The value argument is the time value as a decimal string. There are
* no leading zeros in this string, and the units of the value are
* given in the units argument.
*/
static void format_time(unsigned mcd, int fsize,
const char*value, int time_units)
{
char buf[256];
const char*cp;
char*bp;
unsigned len;
char*bp, *start_address;
int idx, idx_point, idx_start, idx_value;
int idx;
int fraction_chars, fraction_pad, value_chop, whole_fill;
/* This is the time precision for the simulation. */
int prec = vpi_get(vpiTimePrecision, 0);
/* This is the format precision expressed as the power of 10
of the desired precision. The following code uses this
format to be consistent with the units specifications. */
int format_precision = timeformat_info.units - timeformat_info.prec;
/* If the fsize is <0, then use the value from the
$timeformat. If the fsize is >=0, then it overrides the
$timeformat value. */
if (fsize < 0)
fsize = timeformat_info.width;
/* bp starts at the end of the buffer, and works forward as we
build up the output value. */
bp = buf + sizeof buf;
assert(fsize < (sizeof buf - 1));
/* cp points to digits of the value, starting with the least
significant. If the value is only '0', then short circuit
the value by setting cp = value. */
if (value[0] != '0')
cp = value + strlen(value);
/* This is the number of characters to the right of the
decimal point. This is defined completely by the
timeformat. It is legal for the precision to be larger then
the units, and in this case there will be no fraction_chars
at all. */
fraction_chars = timeformat_info.units - format_precision;
if (fraction_chars < 0)
fraction_chars = 0;
/* This is the number of zeros I must add to the value to get
the desired precision within the fraction. If this value is
greater then 0, the value does not have enough characters,
so I will be adding zeros. */
fraction_pad = time_units - format_precision;
if (fraction_pad < 0)
fraction_pad = 0;
if (fraction_pad > fraction_chars)
fraction_pad = fraction_chars;
/* This is the number of characters of excess precision in the
supplied value. This many characters are chopped from the
least significant end. */
value_chop = format_precision - time_units;
if (value_chop < 0)
value_chop = 0;
/* This is the number of zeros that I must add to the integer
part of the output string to pad the value out to the
desired units. This will only have a non-zero value if the
units of the value is greater then the desired units.
Detect the special case where the value is 0. In this case,
do not do any integer filling ever. The output should be
padded with blanks in that case. */
whole_fill = time_units - timeformat_info.units;
if (whole_fill < 0)
whole_fill = 0;
if (strcmp(value,"0") == 0)
whole_fill = 0;
/* This is the expected start address of the output. It
accounts for the fsize value that is chosen. The output
will be filled out to complete the buffer. */
if (fsize == 0)
start_address = buf;
else
start_address = buf + sizeof buf - fsize - 1;
/* Now start the character pointers, ready to start copying
the value into the format. */
cp = value + strlen(value);
if (value_chop > (cp - value))
cp = value;
else
cp -= value_chop;
/* Draw the suffix into the buffer. */
bp = buf + sizeof buf;
*--bp = 0;
/* Write the suffix. */
bp -= strlen(timeformat_info.suff);
strcpy(bp, timeformat_info.suff);
/* This is the precision index where the decimal point goes. */
idx_point = timeformat_info.units;
/* This is the precision index where we start drawing digits. */
idx_start = idx_point - (int)timeformat_info.prec;
/* This is the precision index where the integer time value
digits start. */
idx_value = prec;
idx = idx_start;
if (idx > idx_value)
idx = idx_value;
/* If we want no precision, then set idx_point to a high value
so that the '.' is never printed. */
if (timeformat_info.prec == 0)
idx_point = idx - 1;
/* Now build up the time string, from the least significant
digit up to the last. */
while ((cp > value) || (idx <= idx_point)) {
if (idx == idx_point) {
*--bp = '.';
}
if (idx >= idx_start) {
if (idx < idx_value) {
*--bp = '0';
} else if (cp > value) {
*--bp = cp[-1];
} else {
*--bp = '0';
}
}
if ((idx >= idx_value) && (cp > value))
cp -= 1;
idx += 1;
}
/* Patch up cases that need a leading 0. */
if ((*bp == '.') || (idx == idx_start))
/* Write the padding needed to fill out the fraction. */
for (idx = 0 ; idx < fraction_pad ; idx += 1)
*--bp = '0';
/* Pad the string on the left to the requested minimum
width. Pad with spaces. */
len = strlen(bp);
while (len < fsize) {
*--bp = ' ';
len += 1;
/* Subtract the pad from the needed chars. */
assert(fraction_pad <= fraction_chars);
fraction_chars -= fraction_pad;
fraction_pad = 0;
/* Write the fraction chars. */
for (idx = 0 ; idx < fraction_chars ; idx += 1) {
if (cp > value)
*--bp = *--cp;
else
*--bp = '0';
assert(cp >= value);
}
/* Write the decimal point, if needed. */
if (timeformat_info.prec > 0)
*--bp = '.';
/* Fill the gap between the value and the decimal point. */
for (idx = 0 ; idx < whole_fill ; idx += 1)
*--bp = '0';
/* Write the integer part of the value. */
while (cp > value) {
*--bp = *--cp;
}
/* Fill the leading characters to make up the desired
width. This may require a '0' if the last character
written was the decimal point. */
if (fsize > 0) {
while (bp > start_address) {
if (*bp == '.')
*--bp = '0';
else
*--bp = ' ';
}
} else {
if (*bp == '.')
*--bp = '0';
}
vpi_mcd_printf(mcd, "%s", bp);
}
@@ -305,6 +367,8 @@ static int format_str(vpiHandle scope, unsigned int mcd,
char*cp = fmt;
char format_char = ' ';
int idx;
/* Time units of the current scope. */
int time_units = vpi_get(vpiTimeUnit, scope);
assert(fmt);
@@ -361,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':
@@ -458,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':
@@ -495,11 +566,17 @@ 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, value.value.str);
format_time(mcd, fsize,
value.value.str, time_units);
break;
case 'd':
@@ -697,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;
@@ -725,19 +808,24 @@ static int get_default_format(char *name)
static int sys_display_calltf(char *name)
{
struct strobe_cb_info info;
struct strobe_cb_info*info;
vpiHandle sys = vpi_handle(vpiSysTfCall, 0);
vpiHandle scope = vpi_handle(vpiScope, sys);
vpiHandle argv = vpi_iterate(vpiArgument, sys);
info = vpi_get_userdata(sys);
if (info == 0) {
vpiHandle scope = vpi_handle(vpiScope, sys);
vpiHandle argv = vpi_iterate(vpiArgument, sys);
assert(scope);
info.default_format = get_default_format(name);
info.scope = scope;
array_from_iterator(&info, argv);
assert(scope);
info = malloc(sizeof (struct strobe_cb_info));
info->default_format = get_default_format(name);
info->scope = scope;
array_from_iterator(info, argv);
do_display(5, &info);
free(info.items);
vpi_put_userdata(sys, info);
}
do_display(5, info);
if (strncmp(name,"$display",8) == 0)
vpi_mcd_printf(5, "\n");
@@ -1229,6 +1317,8 @@ static int sys_timeformat_calltf(char *xx)
static int sys_end_of_compile(p_cb_data cb_data)
{
/* The default timeformat prints times in unit of simulation
precision. */
timeformat_info.suff = strdup("");
timeformat_info.units = vpi_get(vpiTimePrecision, 0);
timeformat_info.prec = 0;
@@ -1484,6 +1574,15 @@ 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.
*
* Revision 1.47 2002/12/21 19:41:49 steve
* Rewrite time formatting to account for local scope.
*
* Revision 1.46 2002/11/09 06:01:11 steve
* display octal escapes properly.
*
+17 -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_lxt.c,v 1.11 2002/08/15 02:12:20 steve Exp $"
#ident "$Id: sys_lxt.c,v 1.13 2002/12/21 00:55:58 steve Exp $"
#endif
# include "config.h"
@@ -343,6 +343,7 @@ static int sys_dumpoff_calltf(char*name)
if (dump_header_pending())
return 0;
now.type = vpiSimTime;
vpi_get_time(0, &now);
if (now.low > vcd_cur_time)
lt_set_time(dump_file, now.low);
@@ -368,6 +369,7 @@ static int sys_dumpon_calltf(char*name)
if (dump_header_pending())
return 0;
now.type = vpiSimTime;
vpi_get_time(0, &now);
if (now.low > vcd_cur_time)
lt_set_time(dump_file, now.low);
@@ -388,6 +390,7 @@ static int sys_dumpall_calltf(char*name)
if (dump_header_pending())
return 0;
now.type = vpiSimTime;
vpi_get_time(0, &now);
if (now.low > vcd_cur_time)
lt_set_time(dump_file, now.low);
@@ -460,6 +463,9 @@ static int sys_dumpfile_calltf(char*name)
path = strdup("dumpfile.lxt");
}
if (dump_file)
close_dumpfile();
assert(dump_file == 0);
open_dumpfile(path);
@@ -814,6 +820,16 @@ void sys_lxt_register()
/*
* $Log: sys_lxt.c,v $
* Revision 1.13 2002/12/21 00:55:58 steve
* The $time system task returns the integer time
* scaled to the local units. Change the internal
* implementation of vpiSystemTime the $time functions
* to properly account for this. Also add $simtime
* to get the simulation time.
*
* Revision 1.12 2002/11/17 22:28:42 steve
* Close old file if $dumpfile is called again.
*
* Revision 1.11 2002/08/15 02:12:20 steve
* add dumpvars_compiletf to check first argument.
*
+107 -1
View File
@@ -17,14 +17,25 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: sys_time.c,v 1.4 2002/08/12 01:35:05 steve Exp $"
#ident "$Id: sys_time.c,v 1.6 2003/01/27 00:14:37 steve Exp $"
#endif
# include "config.h"
# include "vpi_user.h"
# include <string.h>
# include <assert.h>
static vpiHandle module_of_function(vpiHandle obj)
{
while (vpi_get(vpiType, obj) != vpiModule) {
obj = vpi_handle(vpiScope, obj);
assert(obj);
}
return obj;
}
static int sys_time_sizetf(char*x)
{
return 64;
@@ -40,16 +51,82 @@ static int sys_time_calltf(char*name)
s_vpi_value val;
s_vpi_time now;
vpiHandle call_handle;
vpiHandle mod;
int units, prec;
long 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 = vpiIntVal;
val.value.integer = now.low;
assert(now.high == 0);
val.value.integer /= scale;
vpi_put_value(call_handle, &val, 0, vpiNoDelay);
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;
@@ -64,6 +141,15 @@ void sys_time_register()
tf_data.calltf = sys_time_calltf;
tf_data.compiletf = 0;
tf_data.sizetf = sys_time_sizetf;
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;
@@ -71,11 +157,31 @@ void sys_time_register()
tf_data.calltf = sys_time_calltf;
tf_data.compiletf = 0;
tf_data.sizetf = sys_stime_sizetf;
tf_data.user_data = "$stime";
vpi_register_systf(&tf_data);
tf_data.type = vpiSysFunc;
tf_data.tfname = "$simtime";
tf_data.calltf = sys_time_calltf;
tf_data.compiletf = 0;
tf_data.sizetf = sys_time_sizetf;
tf_data.user_data = "$simtime";
vpi_register_systf(&tf_data);
}
/*
* $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
* implementation of vpiSystemTime the $time functions
* to properly account for this. Also add $simtime
* to get the simulation time.
*
* Revision 1.4 2002/08/12 01:35:05 steve
* conditional ident string using autoconfig.
*
+19 -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_vcd.c,v 1.38 2002/11/14 22:43:58 steve Exp $"
#ident "$Id: sys_vcd.c,v 1.40 2002/12/21 00:55:58 steve Exp $"
#endif
# include "config.h"
@@ -315,6 +315,7 @@ static int sys_dumpoff_calltf(char*name)
if (dump_header_pending())
return 0;
now.type = vpiSimTime;
vpi_get_time(0, &now);
if (now.low > vcd_cur_time)
fprintf(dump_file, "#%u\n", now.low);
@@ -342,6 +343,7 @@ static int sys_dumpon_calltf(char*name)
if (dump_header_pending())
return 0;
now.type = vpiSimTime;
vpi_get_time(0, &now);
if (now.low > vcd_cur_time)
fprintf(dump_file, "#%u\n", now.low);
@@ -364,6 +366,7 @@ static int sys_dumpall_calltf(char*name)
if (dump_header_pending())
return 0;
now.type = vpiSimTime;
vpi_get_time(0, &now);
if (now.low > vcd_cur_time)
fprintf(dump_file, "#%u\n", now.low);
@@ -449,6 +452,11 @@ static int sys_dumpfile_calltf(char*name)
path = strdup("dumpfile.vcd");
}
if (dump_file) {
fclose(dump_file);
dump_file = 0;
}
assert(dump_file == 0);
open_dumpfile(path);
@@ -844,6 +852,16 @@ void sys_vcd_register()
/*
* $Log: sys_vcd.c,v $
* Revision 1.40 2002/12/21 00:55:58 steve
* The $time system task returns the integer time
* scaled to the local units. Change the internal
* implementation of vpiSystemTime the $time functions
* to properly account for this. Also add $simtime
* to get the simulation time.
*
* Revision 1.39 2002/11/17 22:28:42 steve
* Close old file if $dumpfile is called again.
*
* Revision 1.38 2002/11/14 22:43:58 steve
* Save vpiFullName results.
*
+16 -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.15 2002/08/12 01:35:01 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
@@ -323,6 +324,13 @@ extern vpiHandle vpi_put_value(vpiHandle obj, p_vpi_value value,
extern int vpi_free_object(vpiHandle ref);
extern int vpi_get_vlog_info(p_vpi_vlog_info vlog_info_p);
/*
* These functions support attaching user data to an instance of a
* system task or function. These functions only apply to
* vpiSysTaskCall or vpiSysFuncCall handles.
*/
extern int vpi_put_userdata(vpiHandle obj, void*data);
extern void*vpi_get_userdata(vpiHandle obj);
/*
* Support for handling errors.
@@ -359,6 +367,13 @@ 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
*
* Revision 1.15 2002/08/12 01:35:01 steve
* conditional ident string using autoconfig.
*
-241
View File
@@ -1,241 +0,0 @@
/*
* Copyright (c) 2001-2002 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: vpithunk.c,v 1.6 2002/08/12 01:35:01 steve Exp $"
#endif
#include <stdio.h>
#include <stdarg.h>
#include "vpi_user.h"
#include "vpithunk.h"
/*
* This code is linked into the VPI module, not the simulator. The
* module uses the symbols defined in here to call implementations
* supplied by the simulator, which loaded this module with dlopen or
* the equivilent.
*
* The vpi_thunk_p pointer points to a table of function pointers that
* point to all the functions that a simulator is expected to provide.
* The vlog_register_sim is a function that the simulator is expected
* to call with a value for the vpi_thunk_p pointer. This is how the
* run time linkage to all the functions in the make program are made.
*
* In Icarus Verilog, the VPI module is also supposed to export a
* vlog_startup_routines table. This is something that the programmer
* does, so the libvpi library, and the vlog_register_sim function,
* are invisible to the user.
*
* The simulator is careful to call the vpi_register_sim function from
* a loaded module before executing the startup routines.
*/
static p_vpi_thunk vpi_thunk_p = 0;
#define VPITV_CALL(fn,args) { \
if (vpi_thunk_p == 0) { \
no_sim(#fn); return; \
} \
if (vpi_thunk_p->fn == 0) { \
no_func(#fn); return; \
} \
vpi_thunk_p->fn args; \
}
#define VPIT_CALL(fn,def,args) { \
if (vpi_thunk_p == 0) { \
no_sim(#fn); return def; \
} \
if (vpi_thunk_p->fn == 0) { \
no_func(#fn); return def; \
} \
return vpi_thunk_p->fn args; \
}
static void no_sim(const char *fn)
{
fprintf(stderr, "No Simulator registered, cannot handle vpi "
"call to %s\n", fn);
}
static void no_func(const char *fn)
{
fprintf(stderr, "Simulator doesn't have a %s function\n",fn);
}
DLLEXPORT int vpi_register_sim(p_vpi_thunk tp)
{
vpi_thunk_p = 0;
if (tp->magic != VPI_THUNK_MAGIC) {
fprintf(stderr, "Thunk Magic Number mismatch. Got %08X, expected %08x\n",
tp->magic, VPI_THUNK_MAGIC);
return 0;
}
vpi_thunk_p = tp;
return 1;
}
void vpi_register_systf(const struct t_vpi_systf_data *ss)
{
VPITV_CALL(vpi_register_systf,(ss));
}
void vpi_printf(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
VPITV_CALL(vpi_vprintf,(fmt,ap));
va_end(ap);
}
unsigned int vpi_mcd_close(unsigned int mcd)
{
VPIT_CALL(vpi_mcd_close,-1,(mcd));
}
char *vpi_mcd_name(unsigned int mcd)
{
VPIT_CALL(vpi_mcd_name,0,(mcd));
}
unsigned int vpi_mcd_open(char *name)
{
VPIT_CALL(vpi_mcd_open,-1,(name));
}
unsigned int vpi_mcd_open_x(char *name, char *mode)
{
VPIT_CALL(vpi_mcd_open_x,-1, (name, mode));
}
int vpi_mcd_printf(unsigned int mcd, const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
VPIT_CALL(vpi_mcd_vprintf,0,(mcd,fmt,ap));
va_end(ap); /* bad - never hit */
}
int vpi_mcd_fputc(unsigned int mcd, unsigned char x)
{
VPIT_CALL(vpi_mcd_fputc, 0, (mcd, x));
}
int vpi_mcd_fgetc(unsigned int mcd)
{
VPIT_CALL(vpi_mcd_fgetc, -1, (mcd));
}
extern vpiHandle vpi_register_cb(p_cb_data data)
{
VPIT_CALL(vpi_register_cb,0,(data));
}
extern int vpi_remove_cb(vpiHandle ref)
{
VPIT_CALL(vpi_remove_cb,0,(ref));
}
extern void vpi_sim_control(int operation, ...)
{
va_list ap;
va_start(ap, operation);
VPITV_CALL(vpi_sim_vcontrol,(operation,ap));
va_end(ap); /* bad - never hit */
}
extern void vpi_control(int operation, ...)
{
va_list ap;
va_start(ap, operation);
VPITV_CALL(vpi_sim_vcontrol,(operation,ap));
va_end(ap); /* bad - never hit */
}
extern vpiHandle vpi_handle(int type, vpiHandle ref)
{
VPIT_CALL(vpi_handle, 0, (type, ref));
}
extern vpiHandle vpi_iterate(int type, vpiHandle ref)
{
VPIT_CALL(vpi_iterate, 0, (type, ref));
}
extern vpiHandle vpi_scan(vpiHandle iter)
{
VPIT_CALL(vpi_scan, 0, (iter));
}
extern vpiHandle vpi_handle_by_index(vpiHandle ref, int index)
{
VPIT_CALL(vpi_handle_by_index,0,(ref, index));
}
extern void vpi_get_time(vpiHandle obj, s_vpi_time*t)
{
VPITV_CALL(vpi_get_time, (obj,t));
}
extern int vpi_get(int property, vpiHandle ref)
{
VPIT_CALL(vpi_get, 0, (property, ref));
}
extern char* vpi_get_str(int property, vpiHandle ref)
{
VPIT_CALL(vpi_get_str, 0, (property,ref));
}
extern void vpi_get_value(vpiHandle expr, p_vpi_value value)
{
VPITV_CALL(vpi_get_value, (expr, value));
}
extern vpiHandle vpi_put_value(vpiHandle obj, p_vpi_value value,
p_vpi_time when, int flags)
{
VPIT_CALL(vpi_put_value, 0, (obj, value, when, flags));
}
extern int vpi_free_object(vpiHandle ref)
{
VPIT_CALL(vpi_free_object, -1, (ref));
}
extern int vpi_get_vlog_info(p_vpi_vlog_info vlog_info_p)
{
VPIT_CALL(vpi_get_vlog_info, 0, (vlog_info_p));
}
extern int vpi_chk_error(p_vpi_error_info info)
{
VPIT_CALL(vpi_chk_error, 0, (info));
}
/*
* $Log: vpithunk.c,v $
* Revision 1.6 2002/08/12 01:35:01 steve
* conditional ident string using autoconfig.
*
* Revision 1.5 2002/08/11 23:47:04 steve
* Add missing Log and Ident strings.
*
*/
-84
View File
@@ -1,84 +0,0 @@
#ifndef _VPI_THUNK_H_
#define _VPI_THUNK_H_ 1
/*
* Copyright (c) 2001-2002 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: vpithunk.h,v 1.4 2002/08/12 01:35:01 steve Exp $"
#endif
/* These functions are actually defined in lieu of the vpi functions
by the simulator. These prototypes should'nt go into vpi_user.h,
because we don't want the users to be seeing this stuff. They
are non-standard. We have to put them here, so that
including vpi_user.h doesn't require including stdarg.h */
EXTERN_C_START
# include <stdarg.h>
extern void vpi_vprintf(const char*fmt, va_list ap);
extern int vpi_mcd_vprintf(unsigned int mcd, const char*fmt, va_list ap);
extern void vpi_sim_vcontrol(int operation, va_list ap);
EXTERN_C_END
#define VPI_THUNK_MAGIC (0x87836BA4)
typedef struct {
int magic;
void (*vpi_register_systf)(const struct t_vpi_systf_data*ss);
void (*vpi_vprintf)(const char*fmt, va_list ap);
unsigned int (*vpi_mcd_close)(unsigned int mcd);
char *(*vpi_mcd_name)(unsigned int mcd);
unsigned int (*vpi_mcd_open)(char *name);
unsigned int (*vpi_mcd_open_x)(char *name, char *mode);
int (*vpi_mcd_vprintf)(unsigned int mcd, const char*fmt, va_list ap);
int (*vpi_mcd_fputc)(unsigned int mcd, unsigned char x);
int (*vpi_mcd_fgetc)(unsigned int mcd);
vpiHandle (*vpi_register_cb)(p_cb_data data);
int (*vpi_remove_cb)(vpiHandle ref);
void (*vpi_sim_vcontrol)(int operation, va_list ap);
vpiHandle (*vpi_handle)(int type, vpiHandle ref);
vpiHandle (*vpi_iterate)(int type, vpiHandle ref);
vpiHandle (*vpi_scan)(vpiHandle iter);
vpiHandle (*vpi_handle_by_index)(vpiHandle ref, int index);
void (*vpi_get_time)(vpiHandle obj, s_vpi_time*t);
int (*vpi_get)(int property, vpiHandle ref);
char* (*vpi_get_str)(int property, vpiHandle ref);
void (*vpi_get_value)(vpiHandle expr, p_vpi_value value);
vpiHandle (*vpi_put_value)(vpiHandle obj, p_vpi_value value,
p_vpi_time when, int flags);
int (*vpi_free_object)(vpiHandle ref);
int (*vpi_get_vlog_info)(p_vpi_vlog_info vlog_info_p);
int (*vpi_chk_error)(p_vpi_error_info info);
} vpi_thunk, *p_vpi_thunk;
DLLEXPORT int vpi_register_sim(p_vpi_thunk tp);
#endif
/*
* $Log: vpithunk.h,v $
* Revision 1.4 2002/08/12 01:35:01 steve
* conditional ident string using autoconfig.
*
* Revision 1.3 2002/08/11 23:47:04 steve
* Add missing Log and Ident strings.
*
*/
-121
View File
@@ -1,121 +0,0 @@
#
# This source code is free software; you can redistribute it
# and/or modify it in source code form under the terms of the GNU
# Library General Public License as published by the Free Software
# Foundation; either version 2 of the License, or (at your option)
# any later version. In order to redistribute the software in
# binary form, you will need a Picture Elements Binary Software
# License.
#
# 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 Library General Public License for more details.
#
# You should have received a copy of the GNU Library 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
#
#ident "$Id: Makefile.in,v 1.44 2001/06/12 03:53:10 steve Exp $"
#
#
SHELL = /bin/sh
VERSION = 0.0
prefix = @prefix@
exec_prefix = @exec_prefix@
srcdir = @srcdir@
VPATH = $(srcdir)
bindir = @bindir@
libdir = @libdir@
includedir = $(prefix)/include
CC = @CC@ -I$(srcdir) -I$(srcdir)/.. -I$(srcdir)/../vpip
CXX = @CXX@ -I$(srcdir) -I$(srcdir)/.. -I$(srcdir)/../vpip
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
CPPFLAGS = @CPPFLAGS@ @DEFS@
CXXFLAGS = @CXXFLAGS@
CFLAGS = @CFLAGS@
LDFLAGS = @LDFLAGS@
STRIP = @STRIP@
O = vvm_add_sub.o vvm_bit.o vvm_calltf.o vvm_clshift.o vvm_compare.o \
vvm_event.o vvm_ff.o vvm_force.o \
vvm_func.o vvm_gates.o vvm_idiv.o vvm_imod.o vvm_memory.o vvm_mult.o \
vvm_mux.o vvm_nexus.o vvm_pevent.o vvm_signal.o vvm_thread.o vvm_udp.o \
vvm_vpi.o
all: libvvm.a
libvvm.a: $O
rm -f $@
ar cvq $@ $O
%.o: %.cc
@[ -d dep ] || mkdir dep
$(CXX) -Wall -fno-exceptions $(CPPFLAGS) $(CXXFLAGS) -MD -c $< -o $*.o
mv $*.d dep
clean:
rm -f *.o dep/*.d libvvm.a
install:: all installdirs \
$(libdir)/libvvm.a \
$(includedir)/vvm.h \
$(includedir)/vvm_func.h \
$(includedir)/vvm_gates.h \
$(includedir)/vvm_nexus.h \
$(includedir)/vvm_signal.h \
$(includedir)/vvm_thread.h \
$(includedir)/vvm_calltf.h
$(libdir)/libvvm.a: ./libvvm.a
$(INSTALL_DATA) ./libvvm.a $(libdir)/libvvm.a
$(includedir)/vvm.h: $(srcdir)/vvm.h
$(INSTALL_DATA) $(srcdir)/vvm.h $(includedir)/vvm.h
$(includedir)/vvm_calltf.h: $(srcdir)/vvm_calltf.h
$(INSTALL_DATA) $(srcdir)/vvm_calltf.h $(includedir)/vvm_calltf.h
$(includedir)/vvm_func.h: $(srcdir)/vvm_func.h
$(INSTALL_DATA) $(srcdir)/vvm_func.h $(includedir)/vvm_func.h
$(includedir)/vvm_gates.h: $(srcdir)/vvm_gates.h
$(INSTALL_DATA) $(srcdir)/vvm_gates.h $(includedir)/vvm_gates.h
$(includedir)/vvm_nexus.h: $(srcdir)/vvm_nexus.h
$(INSTALL_DATA) $(srcdir)/vvm_nexus.h $(includedir)/vvm_nexus.h
$(includedir)/vvm_signal.h: $(srcdir)/vvm_signal.h
$(INSTALL_DATA) $(srcdir)/vvm_signal.h $(includedir)/vvm_signal.h
$(includedir)/vvm_thread.h: $(srcdir)/vvm_thread.h
$(INSTALL_DATA) $(srcdir)/vvm_thread.h $(includedir)/vvm_thread.h
installdirs: mkinstalldirs
$(srcdir)/mkinstalldirs $(includedir) $(libdir)
uninstall::
rm -f $(libdir)/libvvm.a
rm -f $(includedir)/vvm.h
rm -f $(includedir)/vvm_calltf.h
rm -f $(includedir)/vvm_func.h
rm -f $(includedir)/vvm_gates.h
rm -f $(includedir)/vvm_nexus.h
rm -f $(includedir)/vvm_signal.h
rm -f $(includedir)/vvm_thread.h
-include $(patsubst %.o, dep/%.d, $O $P)
-100
View File
@@ -1,100 +0,0 @@
#ifndef __ivl_dlfcn_H
#define __ivl_dlfcn_H
/*
* Copyright (c) 2001 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: ivl_dlfcn.h,v 1.5 2002/08/12 01:35:06 steve Exp $"
#endif
#if defined(__MINGW32__)
# include <windows.h>
# include <stdio.h>
typedef void * ivl_dll_t;
#elif defined(HAVE_DLFCN_H)
# include <dlfcn.h>
typedef void* ivl_dll_t;
#elif defined(HAVE_DL_H)
# include <dl.h>
typedef shl_t ivl_dll_t;
#endif
#if defined(__MINGW32__)
inline ivl_dll_t ivl_dlopen(const char *name)
{ return (void *)LoadLibrary(name); }
inline void *ivl_dlsym(ivl_dll_t dll, const char *nm)
{ return (void *)GetProcAddress((HINSTANCE)dll,nm);}
inline void ivl_dlclose(ivl_dll_t dll)
{ (void)FreeLibrary((HINSTANCE)dll);}
inline const char *dlerror(void)
{ static char s[30]; sprintf(s,"DLError:%ld", GetLastError()); return s;}
#elif defined(HAVE_DLFCN_H)
inline ivl_dll_t ivl_dlopen(const char*name)
{ return dlopen(name,RTLD_LAZY); }
inline void* ivl_dlsym(ivl_dll_t dll, const char*nm)
{ return dlsym(dll, nm); }
inline void ivl_dlclose(ivl_dll_t dll)
{ dlclose(dll); }
#elif defined(HAVE_DL_H)
inline ivl_dll_t ivl_dlopen(const char*name)
{ return shl_load(name, BIND_IMMEDIATE, 0); }
inline void* ivl_dlsym(ivl_dll_t dll, const char*nm)
{
void*sym;
int rc = shl_findsym(&dll, nm, TYPE_PROCEDURE, &sym);
return (rc == 0) ? sym : 0;
}
inline void ivl_dlclose(ivl_dll_t dll)
{ shl_unload(dll); }
inline const char*dlerror(void)
{ return strerror( errno ); }
#endif
/*
* $Log: ivl_dlfcn.h,v $
* Revision 1.5 2002/08/12 01:35:06 steve
* conditional ident string using autoconfig.
*
* Revision 1.4 2002/01/23 04:54:38 steve
* Load modules with RTLD_LAZY
*
* Revision 1.3 2001/05/22 02:14:47 steve
* Update the mingw build to not require cygwin files.
*
* Revision 1.2 2001/05/20 15:09:40 steve
* Mingw32 support (Venkat Iyer)
*
* Revision 1.1 2001/03/16 01:44:34 steve
* Add structures for VPI support, and all the %vpi_call
* instruction. Get linking of VPI modules to work.
*
* Revision 1.1 2001/01/14 17:12:59 steve
* possible HP/UX portability support.
*
*/
#endif
-40
View File
@@ -1,40 +0,0 @@
#! /bin/sh
# mkinstalldirs --- make directory hierarchy
# Author: Noah Friedman <[email protected]>
# Created: 1993-05-16
# Public domain
# $Id: mkinstalldirs,v 1.1 1999/05/09 01:24:59 steve Exp $
errstatus=0
for file
do
set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
shift
pathcomp=
for d
do
pathcomp="$pathcomp$d"
case "$pathcomp" in
-* ) pathcomp=./$pathcomp ;;
esac
if test ! -d "$pathcomp"; then
echo "mkdir $pathcomp" 1>&2
mkdir "$pathcomp" || lasterr=$?
if test ! -d "$pathcomp"; then
errstatus=$lasterr
fi
fi
pathcomp="$pathcomp/"
done
done
exit $errstatus
# mkinstalldirs ends here
-161
View File
@@ -1,161 +0,0 @@
#ifndef __vvm_H
#define __vvm_H
/*
* Copyright (c) 1998-2000 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: vvm.h,v 1.38 2002/08/12 01:35:06 steve Exp $"
#endif
# include <cassert>
# include "vpi_priv.h"
/*
* The Verilog Virtual Machine are definitions for the virtual machine
* that executes models that the simulation generator makes.
*/
typedef unsigned vvm_u32;
class vvm_event;
class vvm_thread;
inline vpip_bit_t B_AND(vpip_bit_t l, vpip_bit_t r)
{
if (B_IS0(l)) return St0;
if (B_IS0(r)) return St0;
if (B_IS1(l) && B_IS1(r)) return St1;
return StX;
}
inline vpip_bit_t B_OR(vpip_bit_t l, vpip_bit_t r)
{
if (B_IS1(l)) return St1;
if (B_IS1(r)) return St1;
if (B_IS0(l) && B_IS0(r)) return St0;
return StX;
}
inline vpip_bit_t B_XOR(vpip_bit_t l, vpip_bit_t r)
{
if (B_ISZ(l)) return StX;
if (B_ISZ(r)) return StX;
if (B_ISX(l)) return StX;
if (B_ISX(r)) return StX;
if (B_IS0(l)) return r;
return B_IS0(r)? St1 : St0;
}
inline vpip_bit_t less_with_cascade(vpip_bit_t l, vpip_bit_t r, vpip_bit_t c)
{
if (B_ISXZ(l)) return StX;
if (B_ISXZ(r)) return StX;
if ((l&0x80) > (r&0x80)) return St0;
if ((l&0x80) < (r&0x80)) return St1;
return c;
}
inline vpip_bit_t greater_with_cascade(vpip_bit_t l, vpip_bit_t r, vpip_bit_t c)
{
if (B_ISXZ(l)) return StX;
if (B_ISXZ(r)) return StX;
if ((l&0x80) > (r&0x80)) return St1;
if ((l&0x80) < (r&0x80)) return St0;
return c;
}
extern vpip_bit_t add_with_carry(vpip_bit_t l, vpip_bit_t r, vpip_bit_t&carry);
inline vpip_bit_t B_NOT(vpip_bit_t l)
{
if (B_IS0(l)) return St1;
if (B_IS1(l)) return St0;
return StX;
}
/*
* These functions return true if the transition from A to B is a
* Verilog type of negedge of posedge.
*/
extern bool negedge(vpip_bit_t from, vpip_bit_t to);
extern bool posedge(vpip_bit_t from, vpip_bit_t to);
/*
* Verilog events (update events and nonblocking assign) are derived
* from this abstract class so that the simulation engine can treat
* all of them identically.
*/
class vvm_event {
public:
vvm_event();
virtual ~vvm_event() =0;
virtual void event_function() =0;
void schedule(unsigned long delay =0);
private:
struct vpip_event*event_;
static void callback_(void*);
private: // not implemented
vvm_event(const vvm_event&);
vvm_event& operator= (const vvm_event&);
};
/*
* $Log: vvm.h,v $
* Revision 1.38 2002/08/12 01:35:06 steve
* conditional ident string using autoconfig.
*
* Revision 1.37 2001/01/16 02:44:18 steve
* Use the iosfwd header if available.
*
* Revision 1.36 2000/04/10 05:26:06 steve
* All events now use the NetEvent class.
*
* Revision 1.35 2000/03/26 16:55:41 steve
* Remove the vvm_bits_t abstract class.
*
* Revision 1.34 2000/03/22 04:26:41 steve
* Replace the vpip_bit_t with a typedef and
* define values for all the different bit
* values, including strengths.
*
* Revision 1.33 2000/03/16 19:03:04 steve
* Revise the VVM backend to use nexus objects so that
* drivers and resolution functions can be used, and
* the t-vvm module doesn't need to write a zillion
* output functions.
*
* Revision 1.32 2000/03/13 00:02:34 steve
* Remove unneeded templates.
*
* Revision 1.31 2000/02/23 04:43:43 steve
* Some compilers do not accept the not symbol.
*
* Revision 1.30 2000/02/23 02:56:56 steve
* Macintosh compilers do not support ident.
*
* Revision 1.29 2000/01/08 03:09:14 steve
* Non-blocking memory writes.
*/
#endif
-135
View File
@@ -1,135 +0,0 @@
/*
* Copyright (c) 2000 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: vvm_add_sub.cc,v 1.4 2002/08/12 01:35:06 steve Exp $"
#endif
# include "config.h"
# include "vvm_gates.h"
# include <assert.h>
vvm_add_sub::vvm_add_sub(unsigned wid)
: width_(wid), ndir_(St0)
{
ibits_ = new vpip_bit_t[width_*3];
ro_ = new vvm_nexus::drive_t[width_];
c_ = StX;
for (unsigned idx = 0 ; idx < width_*3 ; idx += 1)
ibits_[idx] = StX;
}
vvm_add_sub::~vvm_add_sub()
{
delete[]ro_;
delete[]ibits_;
}
vvm_nexus::drive_t* vvm_add_sub::config_rout(unsigned idx)
{
assert(idx < width_);
return ro_+idx;
}
vvm_nexus::drive_t* vvm_add_sub::config_cout()
{
return &co_;
}
unsigned vvm_add_sub::key_DataA(unsigned idx) const
{
assert(idx < width_);
return idx;
}
unsigned vvm_add_sub::key_DataB(unsigned idx) const
{
assert(idx < width_);
return idx+width_;
}
void vvm_add_sub::init_DataA(unsigned idx, vpip_bit_t val)
{
assert(idx < width_);
ibits_[idx] = val;
}
void vvm_add_sub::init_DataB(unsigned idx, vpip_bit_t val)
{
assert(idx < width_);
ibits_[width_+idx] = val;
}
void vvm_add_sub::init_Add_Sub(unsigned, vpip_bit_t val)
{
ndir_ = B_NOT(val);
}
void vvm_add_sub::start()
{
compute_();
}
void vvm_add_sub::take_value(unsigned key, vpip_bit_t val)
{
if (ibits_[key] == val) return;
ibits_[key] = val;
compute_();
}
void vvm_add_sub::compute_()
{
vpip_bit_t carry = ndir_;
vpip_bit_t*a = ibits_;
vpip_bit_t*b = ibits_+width_;
vpip_bit_t*r = ibits_+2*width_;
for (unsigned idx = 0 ; idx < width_ ; idx += 1) {
vpip_bit_t val;
val = add_with_carry(a[idx], B_XOR(b[idx],ndir_), carry);
if (val == r[idx]) continue;
r[idx] = val;
vvm_event*ev = new vvm_out_event(val, ro_+idx);
ev->schedule();
}
if (carry != c_)
(new vvm_out_event(carry, &co_)) -> schedule();
}
/*
* $Log: vvm_add_sub.cc,v $
* Revision 1.4 2002/08/12 01:35:06 steve
* conditional ident string using autoconfig.
*
* Revision 1.3 2001/07/25 03:10:50 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
*
* Revision 1.2 2000/03/22 04:26:41 steve
* Replace the vpip_bit_t with a typedef and
* define values for all the different bit
* values, including strengths.
*
* Revision 1.1 2000/03/17 17:25:53 steve
* Adder and comparator in nexus style.
*
*/
-133
View File
@@ -1,133 +0,0 @@
/*
* Copyright (c) 1998-2000 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: vvm_bit.cc,v 1.15 2002/08/12 01:35:06 steve Exp $"
#endif
# include "config.h"
# include "vvm.h"
bool negedge(vpip_bit_t from, vpip_bit_t to)
{
if (B_IS0(from))
return false;
if (B_ISX(from) || B_ISZ(from))
return B_IS0(to);
if (B_IS1(from))
return ! B_IS1(to);
return false;
}
bool posedge(vpip_bit_t from, vpip_bit_t to)
{
if (B_IS1(from))
return false;
if (B_ISX(from) || B_ISZ(from))
return B_IS1(to);
if (B_IS0(from))
return ! B_IS0(to);
return false;
}
vpip_bit_t add_with_carry(vpip_bit_t l, vpip_bit_t r, vpip_bit_t&carry)
{
unsigned li, ri, ci;
if (B_IS1(l)) {
li = 1;
} else if (B_IS0(l)) {
li = 0;
} else {
carry = StX;
return StX;
}
if (B_IS1(r)) {
ri = 1;
} else if (B_IS0(r)) {
ri = 0;
} else {
carry = StX;
return StX;
}
if (B_IS1(carry)) {
ci = 1;
} else if (B_IS0(carry)) {
ci = 0;
} else {
carry = StX;
return StX;
}
unsigned sum = li + ri + ci;
carry = (sum & 2)? St1 : St0;
return (sum & 1)? St1 : St0;
}
/*
* $Log: vvm_bit.cc,v $
* Revision 1.15 2002/08/12 01:35:06 steve
* conditional ident string using autoconfig.
*
* Revision 1.14 2001/07/25 03:10:50 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
*
* Revision 1.13 2001/01/16 02:44:18 steve
* Use the iosfwd header if available.
*
* Revision 1.12 2000/04/10 05:26:07 steve
* All events now use the NetEvent class.
*
* Revision 1.11 2000/03/26 16:55:41 steve
* Remove the vvm_bits_t abstract class.
*
* Revision 1.10 2000/03/22 04:26:41 steve
* Replace the vpip_bit_t with a typedef and
* define values for all the different bit
* values, including strengths.
*
* Revision 1.9 2000/03/16 19:03:04 steve
* Revise the VVM backend to use nexus objects so that
* drivers and resolution functions can be used, and
* the t-vvm module doesn't need to write a zillion
* output functions.
*
* Revision 1.8 2000/02/23 02:56:56 steve
* Macintosh compilers do not support ident.
*
* Revision 1.7 1999/12/02 03:36:01 steve
* shiftl and shiftr take unsized second parameter.
*
* Revision 1.6 1999/11/22 00:30:52 steve
* Detemplate some and, or and nor methods.
*
* Revision 1.5 1999/11/21 00:13:09 steve
* Support memories in continuous assignments.
*/
-174
View File
@@ -1,174 +0,0 @@
/*
* Copyright (c) 1998-2000 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: vvm_calltf.cc,v 1.16 2002/08/12 01:35:06 steve Exp $"
#endif
# include "config.h"
# include "machine.h"
# include "vvm_calltf.h"
# include <vpi_user.h>
# include "vpi_priv.h"
# include <new>
# include <iostream>
# include <assert.h>
# include <stdlib.h>
# include <stdarg.h>
#ifdef HAVE_MALLOC_H
# include <malloc.h>
#endif
# include <stdio.h>
# include "ivl_dlfcn.h"
# include "vpithunk.h"
# define MAX_PATHLEN 1024
static char*module_path = 0;
void vvm_set_module_path(const char*path)
{
if (module_path) free(module_path);
module_path = strdup(path);
}
/*
* The load_vpi_module function attempts to locate and load the named
* vpi module and call the included startup routines. This is invoked
* by the generated C++ code to load all the modules that the
* simulation requires.
*
* If there is a '/' character in the name, or there is no
* VPI_MODULE_PATH, the the name is usd as is. No path is searched for
* the module.
*
* If there is a VPI_MODULE_PATH and there is no '/' in the name, the
* VPI_MODULE_PATH is taken as a ':' separated list of directory
* names. Each directory is searched for a module with the right name
* that will link in. The current working directory is not implicitly
* tried. If you wish '.' be in th search path, include it.
*/
typedef void (*vlog_startup_routines_t)(void);
typedef int (*vpi_register_sim_t)(p_vpi_thunk tp);
void vvm_load_vpi_module(const char*name)
{
ivl_dll_t mod = 0;
const char*path = getenv("VPI_MODULE_PATH");
if (path == 0) path = module_path;
if ((path == 0) || (strchr(name, '/'))) {
mod = ivl_dlopen(name);
if (mod == 0) {
cerr << name << ": " << dlerror() << endl;
return;
}
} else {
const char*cur = path;
const char*ep;
for (cur = path ; cur ; cur = ep? ep+1 : 0) {
char dest[MAX_PATHLEN+1];
ep = strchr(cur, ':');
size_t n = ep? ep-cur : strlen(cur);
if ((n + strlen(name) + 2) > sizeof dest)
continue;
strncpy(dest, cur, n);
dest[n] = '/';
dest[n+1] = 0;
strcat(dest, name);
mod = ivl_dlopen(dest);
if (mod) break;
}
}
if (mod == 0) {
cerr << dlerror() << endl;
return;
}
void *regsub = ivl_dlsym(mod, LU "vpi_register_sim" TU);
vpi_register_sim_t simreg = (vpi_register_sim_t)regsub;
if (regsub == 0) {
cerr << name << ": Unable to locate vpi_register_sim" << endl;
ivl_dlclose(mod);
return;
}
extern vpi_thunk vvmt;
if (((simreg)(&vvmt)) == 0) {
cerr << name << ": vpi_register_sim returned zero" << endl;
ivl_dlclose(mod);
return;
}
void*table = ivl_dlsym(mod, LU "vlog_startup_routines" TU);
vlog_startup_routines_t*routines = (vlog_startup_routines_t*)table;
if (routines == 0) {
cerr << name << ": Unable to locate the vlog_startup_routines"
" table." << endl;
ivl_dlclose(mod);
return;
}
for (unsigned idx = 0 ; routines[idx] ; idx += 1)
(routines[idx])();
}
/*
* $Log: vvm_calltf.cc,v $
* Revision 1.16 2002/08/12 01:35:06 steve
* conditional ident string using autoconfig.
*
* Revision 1.15 2001/09/15 18:27:04 steve
* Make configure detect malloc.h
*
* Revision 1.14 2001/07/25 03:10:50 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
*
* Revision 1.13 2001/06/12 03:53:10 steve
* Change the VPI call process so that loaded .vpi modules
* use a function table instead of implicit binding.
*
* Revision 1.12 2001/01/14 17:12:59 steve
* possible HP/UX portability support.
*
* Revision 1.11 2000/02/23 02:56:56 steve
* Macintosh compilers do not support ident.
*
* Revision 1.10 2000/01/24 00:18:20 steve
* Handle systems that need underscores in symbols.
*
* Revision 1.9 1999/11/28 18:05:37 steve
* Set VPI_MODULE_PATH in the target code, if desired.
*
* Revision 1.8 1999/10/28 00:47:25 steve
* Rewrite vvm VPI support to make objects more
* persistent, rewrite the simulation scheduler
* in C (to interface with VPI) and add VPI support
* for callbacks.
*/
-60
View File
@@ -1,60 +0,0 @@
#ifndef __vvm_vvm_calltf_H
#define __vvm_vvm_calltf_H
/*
* Copyright (c) 1998-1999 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: vvm_calltf.h,v 1.6 2002/08/12 01:35:06 steve Exp $"
#endif
# include "vvm.h"
# include <string>
/*
* This function loads a vpi module by name.
*/
extern void vvm_set_module_path(const char*path);
extern void vvm_load_vpi_module(const char*path);
/*
* $Log: vvm_calltf.h,v $
* Revision 1.6 2002/08/12 01:35:06 steve
* conditional ident string using autoconfig.
*
* Revision 1.5 2000/02/23 02:56:56 steve
* Macintosh compilers do not support ident.
*
* Revision 1.4 1999/11/28 18:05:37 steve
* Set VPI_MODULE_PATH in the target code, if desired.
*
* Revision 1.3 1999/10/28 00:47:25 steve
* Rewrite vvm VPI support to make objects more
* persistent, rewrite the simulation scheduler
* in C (to interface with VPI) and add VPI support
* for callbacks.
*
* Revision 1.2 1999/08/15 01:23:56 steve
* Convert vvm to implement system tasks with vpi.
*
* Revision 1.1 1998/11/09 23:44:11 steve
* Add vvm library.
*
*/
#endif
-178
View File
@@ -1,178 +0,0 @@
/*
* Copyright (c) 2000 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: vvm_clshift.cc,v 1.4 2002/08/12 01:35:06 steve Exp $"
#endif
# include "config.h"
# include "vvm_gates.h"
/*
* This is the implementation of the LMP_CLSHIFT device.
*
* The device has input/output width if width_ bits, and a distance
* input of wdist_ bits. The inputs are stored in the ibits_ array,
* the data bits first, then the select bits.
*/
vvm_clshift::vvm_clshift(unsigned wid, unsigned wid_dist)
: width_(wid), wdist_(wid_dist)
{
ibits_ = new vpip_bit_t[width_ + wdist_];
out_ = new vvm_nexus::drive_t[width_];
dist_val_ = width_;
dir_ = St0;
for (unsigned idx = 0 ; idx < width_+wdist_ ; idx += 1)
ibits_[idx] = StX;
}
vvm_clshift::~vvm_clshift()
{
delete[]out_;
delete[]ibits_;
}
vvm_nexus::drive_t* vvm_clshift::config_rout(unsigned idx)
{
return out_+idx;
}
unsigned vvm_clshift::key_Data(unsigned idx) const
{
return idx;
}
unsigned vvm_clshift::key_Distance(unsigned idx) const
{
return idx+width_;
}
unsigned vvm_clshift::key_Direction(unsigned) const
{
return 0x20000;
}
void vvm_clshift::init_Data(unsigned idx, vpip_bit_t val)
{
ibits_[idx] = val;
}
void vvm_clshift::init_Distance(unsigned idx, vpip_bit_t val)
{
ibits_[width_+idx] = val;
calculate_dist_();
}
void vvm_clshift::init_Direction(unsigned, vpip_bit_t val)
{
dir_ = val;
}
void vvm_clshift::take_value(unsigned key, vpip_bit_t val)
{
if (key == 0x20000) {
if (dir_ == val) return;
dir_ = val;
calculate_dist_();
compute_();
return;
}
if (ibits_[key] == val) return;
ibits_[key] = val;
if (key < width_) {
if ((dist_val_ + key) >= width_) return;
if ((dist_val_ + key) < 0) return;
out_[dist_val_ + key].set_value(val);
} else {
calculate_dist_();
compute_();
}
}
void vvm_clshift::compute_()
{
// The dist_val_ is set to width_ if its value is not fully
// known. In this case, just set the output to unknown.
if (dist_val_ == (int)width_) {
for (unsigned idx = 0 ; idx < width_ ; idx += 1)
out_[idx].set_value(StX);
return;
}
for (unsigned idx = 0 ; idx < width_ ; idx += 1) {
vpip_bit_t val;
if ((idx-dist_val_) >= width_) val = St0;
else if ((idx-dist_val_) < 0) val = St0;
else val = ibits_[idx-dist_val_];
out_[idx].set_value(val);
}
}
void vvm_clshift::calculate_dist_()
{
int tmp = 0;
for (unsigned idx = 0 ; idx < wdist_ ; idx += 1) {
if (B_ISX(ibits_[width_+idx]) || B_ISZ(ibits_[width_+idx])) {
tmp = width_;
break;
}
if (B_IS1(ibits_[width_+idx]))
tmp |= 1<<idx;
}
/* If the shift amount is too large (no matter the direction)
then set it to exactly width_ and the compute_ function
will handle the case directly. Otherwise, turn the shift
amount into a signed value that depends on the direction. */
if (tmp > (int)width_)
tmp = width_;
else if (B_IS1(dir_))
tmp = -tmp;
dist_val_ = tmp;
}
/*
* $Log: vvm_clshift.cc,v $
* Revision 1.4 2002/08/12 01:35:06 steve
* conditional ident string using autoconfig.
*
* Revision 1.3 2001/07/25 03:10:50 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
*
* Revision 1.2 2000/03/22 04:26:41 steve
* Replace the vpip_bit_t with a typedef and
* define values for all the different bit
* values, including strengths.
*
* Revision 1.1 2000/03/17 02:22:03 steve
* vvm_clshift implementation without templates.
*
*/
-137
View File
@@ -1,137 +0,0 @@
/*
* Copyright (c) 2000 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: vvm_compare.cc,v 1.4 2002/08/12 01:35:06 steve Exp $"
#endif
# include "config.h"
# include "vvm_gates.h"
# include <assert.h>
vvm_compare::vvm_compare(unsigned wid)
: width_(wid)
{
gt_ = StX;
lt_ = StX;
ibits_ = new vpip_bit_t[2*width_];
for (unsigned idx = 0 ; idx < 2*width_ ; idx += 1)
ibits_[idx] = StX;
}
vvm_compare::~vvm_compare()
{
delete[]ibits_;
}
void vvm_compare::init_DataA(unsigned idx, vpip_bit_t val)
{
assert(idx < width_);
ibits_[idx] = val;
}
void vvm_compare::init_DataB(unsigned idx, vpip_bit_t val)
{
assert(idx < width_);
ibits_[width_+idx] = val;
}
vvm_nexus::drive_t* vvm_compare::config_ALB_out()
{
return &out_lt_;
}
vvm_nexus::drive_t* vvm_compare::config_ALEB_out()
{
return &out_le_;
}
vvm_nexus::drive_t* vvm_compare::config_AGB_out()
{
return &out_gt_;
}
vvm_nexus::drive_t* vvm_compare::config_AGEB_out()
{
return &out_ge_;
}
unsigned vvm_compare::key_DataA(unsigned idx) const
{
assert(idx < width_);
return idx;
}
unsigned vvm_compare::key_DataB(unsigned idx) const
{
assert(idx < width_);
return width_ + idx;
}
void vvm_compare::take_value(unsigned key, vpip_bit_t val)
{
if (ibits_[key] == val)
return;
ibits_[key] = val;
compute_();
}
void vvm_compare::compute_()
{
vpip_bit_t gt = St0;
vpip_bit_t lt = St0;
vpip_bit_t*a = ibits_;
vpip_bit_t*b = ibits_+width_;
for (unsigned idx = 0 ; idx < width_ ; idx += 1) {
gt = greater_with_cascade(a[idx], b[idx], gt);
lt = less_with_cascade(a[idx], b[idx], lt);
}
if ((gt_ == gt) && (lt_ == lt)) return;
gt_ = gt;
lt_ = lt;
out_lt_.set_value(lt_);
out_le_.set_value(B_NOT(gt_));
out_gt_.set_value(gt_);
out_ge_.set_value(B_NOT(lt_));
}
/*
* $Log: vvm_compare.cc,v $
* Revision 1.4 2002/08/12 01:35:06 steve
* conditional ident string using autoconfig.
*
* Revision 1.3 2001/07/25 03:10:50 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
*
* Revision 1.2 2000/03/22 04:26:41 steve
* Replace the vpip_bit_t with a typedef and
* define values for all the different bit
* values, including strengths.
*
* Revision 1.1 2000/03/17 17:25:53 steve
* Adder and comparator in nexus style.
*
*/
-79
View File
@@ -1,79 +0,0 @@
/*
* Copyright (c) 1998-2000 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: vvm_event.cc,v 1.7 2002/08/12 01:35:06 steve Exp $"
#endif
# include "config.h"
# include "vvm.h"
# include <assert.h>
vvm_event::vvm_event()
{
event_ = 0;
}
vvm_event::~vvm_event()
{
assert(event_ == 0);
}
void vvm_event::schedule(unsigned long delay)
{
event_ = vpip_sim_insert_event(delay, this, callback_, 0);
}
void vvm_event::callback_(void*cbd)
{
vvm_event*obj = reinterpret_cast<vvm_event*>(cbd);
obj->event_ = 0;
obj->event_function();
delete obj;
}
/*
* $Log: vvm_event.cc,v $
* Revision 1.7 2002/08/12 01:35:06 steve
* conditional ident string using autoconfig.
*
* Revision 1.6 2001/07/25 03:10:50 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
*
* Revision 1.5 2000/02/23 02:56:56 steve
* Macintosh compilers do not support ident.
*
* Revision 1.4 2000/01/06 05:56:22 steve
* Cleanup and some asserts.
*
* Revision 1.3 1999/12/12 19:47:54 steve
* Remove the useless vvm_simulation class.
*
* Revision 1.2 1999/10/28 00:47:25 steve
* Rewrite vvm VPI support to make objects more
* persistent, rewrite the simulation scheduler
* in C (to interface with VPI) and add VPI support
* for callbacks.
*
* Revision 1.1 1998/11/09 23:44:11 steve
* Add vvm library.
*
*/
-117
View File
@@ -1,117 +0,0 @@
/*
* Copyright (c) 2000 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: vvm_ff.cc,v 1.4 2002/08/12 01:35:06 steve Exp $"
#endif
# include "config.h"
# include "vvm_gates.h"
vvm_ff::vvm_ff(unsigned w)
: width_(w)
{
out_ = new vvm_nexus::drive_t[width_];
bits_ = new vpip_bit_t[width_*2];
for (unsigned idx = 0 ; idx < width_*2 ; idx += 1)
bits_[idx] = StX;
}
vvm_ff::~vvm_ff()
{
delete[]bits_;
delete[]out_;
}
vvm_nexus::drive_t* vvm_ff::config_rout(unsigned idx)
{
assert(idx < width_);
return out_+idx;
}
unsigned vvm_ff::key_Data(unsigned idx) const
{
assert(idx < width_);
return idx+width_;
}
unsigned vvm_ff::key_Clock() const
{
return 0;
}
void vvm_ff::init_Data(unsigned idx, vpip_bit_t val)
{
assert(idx < width_);
bits_[idx+width_] = val;
}
void vvm_ff::init_Clock(unsigned, vpip_bit_t val)
{
clk_ = val;
}
void vvm_ff::take_value(unsigned key, vpip_bit_t val)
{
if (key == 0) {
if (val == clk_)
return;
bool flag = posedge(clk_, val);
clk_ = val;
if (flag)
latch_();
return;
}
bits_[key] = val;
}
void vvm_ff::latch_()
{
vpip_bit_t*q = bits_;
vpip_bit_t*d = bits_+width_;
for (unsigned idx = 0 ; idx < width_ ; idx += 1) {
if (q[idx] == d[idx])
continue;
q[idx] = d[idx];
out_[idx].set_value(q[idx]);
}
}
/*
* $Log: vvm_ff.cc,v $
* Revision 1.4 2002/08/12 01:35:06 steve
* conditional ident string using autoconfig.
*
* Revision 1.3 2001/07/25 03:10:50 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
*
* Revision 1.2 2000/03/22 04:26:41 steve
* Replace the vpip_bit_t with a typedef and
* define values for all the different bit
* values, including strengths.
*
* Revision 1.1 2000/03/18 23:22:37 steve
* Update the FF device to nexus style.
*
*/
-114
View File
@@ -1,114 +0,0 @@
/*
* Copyright (c) 2000 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: vvm_force.cc,v 1.5 2002/08/12 01:35:06 steve Exp $"
#endif
# include "config.h"
# include "vvm_gates.h"
# include <assert.h>
vvm_force::vvm_force(unsigned w)
: width_(w)
{
force_flag_ = true;
bits_ = new vpip_bit_t[width_];
target_ = new vvm_nexus*[width_];
for (unsigned idx = 0 ; idx < width_ ; idx += 1)
target_[idx] = 0;
}
vvm_force::~vvm_force()
{
delete[]bits_;
delete[]target_;
}
void vvm_force::init_I(unsigned key, vpip_bit_t val)
{
assert(key < width_);
bits_[key] = val;
}
void vvm_force::take_value(unsigned key, vpip_bit_t val)
{
assert(key < width_);
if (bits_[key] == val)
return;
bits_[key] = val;
if (! target_[key]) return;
if (force_flag_)
target_[key]->force_assign(val);
else
target_[key]->cassign(val);
}
void vvm_force::assign(unsigned key, vvm_nexus*tgt)
{
assert(key < width_);
assert(target_[key] == 0);
force_flag_ = false;
target_[key] = tgt;
target_[key]->cassign_set(this, key);
target_[key]->cassign(bits_[key]);
}
void vvm_force::force(unsigned key, vvm_nexus*tgt)
{
assert(key < width_);
assert(target_[key] == 0);
force_flag_ = true;
target_[key] = tgt;
target_[key]->force_set(this, key);
target_[key]->force_assign(bits_[key]);
}
/*
* This method is to be called from the vvm_nexus only when it has
* been told to release me.
*/
void vvm_force::release(unsigned key)
{
assert(target_[key]);
target_[key] = 0;
}
/*
* $Log: vvm_force.cc,v $
* Revision 1.5 2002/08/12 01:35:06 steve
* conditional ident string using autoconfig.
*
* Revision 1.4 2001/07/25 03:10:50 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
*
* Revision 1.3 2000/05/11 23:37:27 steve
* Add support for procedural continuous assignment.
*
* Revision 1.2 2000/04/23 03:45:25 steve
* Add support for the procedural release statement.
*
* Revision 1.1 2000/04/22 04:20:20 steve
* Add support for force assignment.
*
*/
-705
View File
@@ -1,705 +0,0 @@
/*
* Copyright (c) 2000 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: vvm_func.cc,v 1.18 2002/08/12 01:35:06 steve Exp $"
#endif
# include "config.h"
# include "vvm_func.h"
vpip_bit_t vvm_unop_and(const vvm_bitset_t&r)
{
vpip_bit_t v = r[0];
for (unsigned idx = 1 ; idx < r.get_width() ; idx += 1)
v = B_AND(v, r[idx]);
return v;
}
vpip_bit_t vvm_unop_nand(const vvm_bitset_t&r)
{
vpip_bit_t v = vvm_unop_and(r);
return B_NOT(v);
}
vpip_bit_t vvm_unop_lnot(const vvm_bitset_t&r)
{
vpip_bit_t v = vvm_unop_or(r);
return B_NOT(v);
}
void vvm_unop_not(vvm_bitset_t&v, const vvm_bitset_t&p)
{
assert(v.nbits <= p.nbits);
for (unsigned idx = 0 ; idx < v.nbits ; idx += 1)
v[idx] = B_NOT(p[idx]);
}
vpip_bit_t vvm_unop_or(const vvm_bitset_t&r)
{
for (unsigned idx = 0 ; idx < r.get_width() ; idx += 1) {
if (B_IS1(r.get_bit(idx)))
return St1;
}
return St0;
}
vpip_bit_t vvm_unop_nor(const vvm_bitset_t&r)
{
vpip_bit_t v = vvm_unop_or(r);
return B_NOT(v);
}
void vvm_unop_uminus(vvm_bitset_t&v, const vvm_bitset_t&l)
{
vvm_unop_not(v, l);
vpip_bit_t carry = St1;
for (unsigned i = 0 ; i < v.nbits ; i += 1)
v[i] = add_with_carry(v[i], St0, carry);
}
vpip_bit_t vvm_unop_xor(const vvm_bitset_t&r)
{
vpip_bit_t v = St0;
for (unsigned idx = 0 ; idx < r.get_width() ; idx += 1) {
if (B_IS1(r.get_bit(idx)))
v = B_NOT(v);
}
return v;
}
vpip_bit_t vvm_unop_xnor(const vvm_bitset_t&r)
{
vpip_bit_t v = vvm_unop_xor(r);
return B_NOT(v);
}
/*
* Do a bitwise AND into the result. We only need to calculate enough
* bits to fill the result. If I need to extend either value, extend
* it with St0.
*/
void vvm_binop_and(vvm_bitset_t&v, const vvm_bitset_t&l, const vvm_bitset_t&r)
{
unsigned min = v.nbits;
if (r.nbits < min) min = r.nbits;
if (l.nbits < min) min = l.nbits;
for (unsigned idx = 0 ; idx < min ; idx += 1)
v[idx] = B_AND(l[idx], r[idx]);
for (unsigned idx = min ; idx < v.nbits ; idx += 1)
v[idx] = St0;
}
void vvm_binop_minus(vvm_bitset_t&v, const vvm_bitset_t&l,
const vvm_bitset_t&r)
{
vvm_unop_not(v, r);
vpip_bit_t carry = St1;
for (unsigned idx = 0 ; idx < v.nbits ; idx += 1)
v[idx] = add_with_carry(l[idx], v[idx], carry);
}
void vvm_binop_nor(vvm_bitset_t&v, const vvm_bitset_t&l, const vvm_bitset_t&r)
{
unsigned min = v.nbits;
if (r.nbits < min) min = r.nbits;
if (l.nbits < min) min = l.nbits;
for (unsigned idx = 0 ; idx < min ; idx += 1)
v[idx] = B_NOT(B_OR(l[idx], r[idx]));
for (unsigned idx = min ; idx < v.nbits ; idx += 1)
v[idx] = B_NOT(r.nbits > min? r[idx] : l[idx]);
}
void vvm_binop_or(vvm_bitset_t&v, const vvm_bitset_t&l, const vvm_bitset_t&r)
{
unsigned min = v.nbits;
if (r.nbits < min) min = r.nbits;
if (l.nbits < min) min = l.nbits;
for (unsigned idx = 0 ; idx < min ; idx += 1)
v[idx] = B_OR(l[idx], r[idx]);
for (unsigned idx = min ; idx < v.nbits ; idx += 1)
v[idx] = r.nbits > min? r[idx] : l[idx];
}
/*
* This function adds two vectors to make a result vector. The
* operands and the result have their sizes already determined, so we
* take those into account.
*/
void vvm_binop_plus(vvm_bitset_t&v, const vvm_bitset_t&l, const vvm_bitset_t&r)
{
vpip_bit_t carry = St0;
unsigned top = v.nbits;
if (l.nbits < top)
top = l.nbits;
if (r.nbits < top)
top = r.nbits;
unsigned idx;
/* First do the addition for the part of the vector where we
know that the bits from both inputs are present. */
for (idx = 0 ; idx < top ; idx += 1)
v[idx] = add_with_carry(l[idx], r[idx], carry);
/* Now continue the addition, padding the shorter vector with
St0 until we fill the result vector. */
for ( ; idx < v.nbits ; idx += 1) {
vpip_bit_t lv = (idx < l.nbits) ? l[idx] : St0;
vpip_bit_t rv = (idx < r.nbits) ? r[idx] : St0;
v[idx] = add_with_carry(lv, rv, carry);
}
}
void vvm_binop_shiftl(vvm_bitset_t&v,
const vvm_bitset_t&l,
const vvm_bitset_t&r)
{
assert(v.nbits <= l.nbits);
vvm_u32 s = r.as_unsigned();
for (unsigned idx = 0 ; idx < v.nbits; idx += 1)
v[idx] = (idx < s) ? St0 : l[idx-s];
}
void vvm_binop_shiftr(vvm_bitset_t&v,
const vvm_bitset_t&l,
const vvm_bitset_t&r)
{
vvm_u32 s = r.as_unsigned();
for (unsigned idx = 0 ; idx < v.nbits ; idx += 1)
v[idx] = ((idx+s) < l.nbits) ? l[idx+s] : St0;
}
void vvm_binop_xnor(vvm_bitset_t&v, const vvm_bitset_t&l, const vvm_bitset_t&r)
{
assert(v.nbits <= l.nbits);
assert(v.nbits <= r.nbits);
for (unsigned idx = 0 ; idx < v.nbits ; idx += 1)
v[idx] = B_NOT(B_XOR(l[idx], r[idx]));
}
void vvm_binop_xor(vvm_bitset_t&v, const vvm_bitset_t&l, const vvm_bitset_t&r)
{
assert(v.nbits <= l.nbits);
assert(v.nbits <= r.nbits);
for (unsigned idx = 0 ; idx < v.nbits ; idx += 1)
v[idx] = B_XOR(l[idx], r[idx]);
}
vpip_bit_t vvm_binop_eq(const vvm_bitset_t&l, const vvm_bitset_t&r)
{
const unsigned lwid = l.get_width();
const unsigned rwid = r.get_width();
if (lwid <= rwid) {
for (unsigned idx = 0 ; idx < lwid ; idx += 1) {
if (B_ISXZ(l.get_bit(idx)))
return StX;
if (B_ISXZ(r.get_bit(idx)))
return StX;
if (! B_EQ(l.get_bit(idx), r.get_bit(idx)))
return St0;
}
for (unsigned idx = lwid ; idx < rwid ; idx += 1) {
if (B_IS0(r.get_bit(idx)))
continue;
if (B_IS1(r.get_bit(idx)))
return St0;
return StX;
}
return St1;
} else {
for (unsigned idx = 0 ; idx < rwid ; idx += 1) {
if (B_ISXZ(l.get_bit(idx)))
return StX;
if (B_ISXZ(r.get_bit(idx)))
return StX;
if (! B_EQ(l.get_bit(idx), r.get_bit(idx)))
return St0;
}
for (unsigned idx = rwid ; idx < lwid ; idx += 1) {
if (B_IS0(l.get_bit(idx)))
continue;
if (B_IS1(l.get_bit(idx)))
return St0;
return StX;
}
return St1;
}
}
vpip_bit_t vvm_binop_ne(const vvm_bitset_t&l, const vvm_bitset_t&r)
{
vpip_bit_t result = vvm_binop_eq(l,r);
return B_NOT(result);
}
vpip_bit_t vvm_binop_eeq(const vvm_bitset_t&l, const vvm_bitset_t&r)
{
const unsigned lwid = l.get_width();
const unsigned rwid = r.get_width();
if (lwid <= rwid) {
for (unsigned idx = 0 ; idx < lwid ; idx += 1)
if (! B_EQ(l.get_bit(idx), r.get_bit(idx)))
return St0;
for (unsigned idx = lwid ; idx < rwid ; idx += 1)
if (! B_IS0(r.get_bit(idx)))
return St0;
} else {
for (unsigned idx = 0 ; idx < rwid ; idx += 1)
if (! B_EQ(l.get_bit(idx), r.get_bit(idx)))
return St0;
for (unsigned idx = rwid ; idx < lwid ; idx += 1)
if (! B_IS0(l.get_bit(idx)))
return St0;
}
return St1;
}
vpip_bit_t vvm_binop_nee(const vvm_bitset_t&l, const vvm_bitset_t&r)
{
vpip_bit_t result = vvm_binop_eeq(l,r);
return B_NOT(result);
}
vpip_bit_t vvm_binop_xeq(const vvm_bitset_t&l, const vvm_bitset_t&r)
{
const unsigned lwid = l.get_width();
const unsigned rwid = r.get_width();
if (lwid <= rwid) {
for (unsigned idx = 0 ; idx < lwid ; idx += 1) {
if (B_ISXZ(l.get_bit(idx)))
continue;
if (B_ISXZ(r.get_bit(idx)))
continue;
if (! B_EQ(l.get_bit(idx), r.get_bit(idx)))
return St0;
}
for (unsigned idx = lwid ; idx < rwid ; idx += 1) {
if (B_ISXZ(r.get_bit(idx)))
continue;
if (! B_IS0(r.get_bit(idx)))
return St0;
}
} else {
for (unsigned idx = 0 ; idx < rwid ; idx += 1) {
if (B_ISXZ(l.get_bit(idx)))
continue;
if (B_ISXZ(r.get_bit(idx)))
continue;
if (! B_EQ(l.get_bit(idx), r.get_bit(idx)))
return St0;
}
for (unsigned idx = rwid ; idx < lwid ; idx += 1) {
if (B_ISXZ(l.get_bit(idx)))
continue;
if (! B_IS0(l.get_bit(idx)))
return St0;
}
}
return St1;
}
vpip_bit_t vvm_binop_zeq(const vvm_bitset_t&l, const vvm_bitset_t&r)
{
const unsigned lwid = l.get_width();
const unsigned rwid = r.get_width();
if (lwid <= rwid) {
for (unsigned idx = 0 ; idx < lwid ; idx += 1) {
if (B_ISZ(l.get_bit(idx)) || B_ISZ(r.get_bit(idx)))
continue;
if (! B_EQ(l.get_bit(idx), r.get_bit(idx)))
return St0;
}
for (unsigned idx = lwid ; idx < rwid ; idx += 1) {
if (B_ISZ(r.get_bit(idx)))
continue;
if (! B_IS0(r.get_bit(idx)))
return St0;
}
} else {
for (unsigned idx = 0 ; idx < rwid ; idx += 1) {
if (B_ISZ(l.get_bit(idx)) || B_ISZ(r.get_bit(idx)))
continue;
if (! B_EQ(l.get_bit(idx), r.get_bit(idx)))
return St0;
}
for (unsigned idx = rwid ; idx < lwid ; idx += 1) {
if (B_ISZ(l.get_bit(idx)))
continue;
if (! B_IS0(l.get_bit(idx)))
return St0;
}
}
return St1;
}
vpip_bit_t vvm_binop_lt(const vvm_bitset_t&l, const vvm_bitset_t&r)
{
vpip_bit_t result;
result = St0;
const unsigned lwid = l.get_width();
const unsigned rwid = r.get_width();
const unsigned common = (lwid < rwid)? lwid : rwid;
for (unsigned idx = 0 ; idx < common ; idx += 1)
result = less_with_cascade(l.get_bit(idx), r.get_bit(idx), result);
if (lwid > rwid) {
for (unsigned idx = rwid ; idx < lwid ; idx += 1)
result = less_with_cascade(l.get_bit(idx), St0, result);
} else {
for (unsigned idx = lwid ; idx < rwid ; idx += 1)
result = less_with_cascade(St0, r.get_bit(idx), result);
}
return result;
}
/*
* This is the < operator that applies to signed operands.
*/
vpip_bit_t vvm_binop_lt_s(const vvm_bitset_t&l, const vvm_bitset_t&r)
{
vpip_bit_t l_pad = l.get_bit(l.get_width()-1);
vpip_bit_t r_pad = r.get_bit(r.get_width()-1);
/* If l>=0 and r>=0, return $unsigned(l) < $unsigned(r) */
if (B_IS0(l_pad) && B_IS0(r_pad))
return vvm_binop_lt(l, r);
/* If l < 0 and r < 0, return $unsigned(r) < $unsigned(l) */
if (B_IS1(l_pad) && B_IS1(r_pad))
return vvm_binop_lt(r, l);
/* If l >= 0 and r < 0, return false; */
if (B_IS0(l_pad) && B_IS1(r_pad))
return St0;
/* if l < 0 and r >= 0, return true; */
if (B_IS1(l_pad) && B_IS0(r_pad))
return St1;
/* Otherwise, one or the other side is unknown. Return X. */
return StX;
}
vpip_bit_t vvm_binop_le(const vvm_bitset_t&l, const vvm_bitset_t&r)
{
vpip_bit_t result = St1;
const unsigned lwid = l.get_width();
const unsigned rwid = r.get_width();
const unsigned common = (lwid < rwid)? lwid : rwid;
for (unsigned idx = 0 ; idx < common ; idx += 1)
result = less_with_cascade(l.get_bit(idx), r.get_bit(idx), result);
if (lwid > rwid) {
for (unsigned idx = rwid ; idx < lwid ; idx += 1)
result = less_with_cascade(l.get_bit(idx), St0, result);
} else {
for (unsigned idx = lwid ; idx < rwid ; idx += 1)
result = less_with_cascade(St0, r.get_bit(idx), result);
}
return result;
}
/*
* This is the <= operator that applies to signed operands.
*/
vpip_bit_t vvm_binop_le_s(const vvm_bitset_t&l, const vvm_bitset_t&r)
{
vpip_bit_t l_pad = l.get_bit(l.get_width()-1);
vpip_bit_t r_pad = r.get_bit(r.get_width()-1);
/* If l>=0 and r>=0, return $unsigned(l) <= $unsigned(r) */
if (B_IS0(l_pad) && B_IS0(r_pad))
return vvm_binop_le(l, r);
/* If l < 0 and r < 0, return $unsigned(r) <= $unsigned(l) */
if (B_IS1(l_pad) && B_IS1(r_pad))
return vvm_binop_le(r, l);
/* If l >= 0 and r < 0, return false; */
if (B_IS0(l_pad) && B_IS1(r_pad))
return St0;
/* if l < 0 and r >= 0, return true; */
if (B_IS1(l_pad) && B_IS0(r_pad))
return St1;
/* Otherwise, one or the other side is unknown. Return X. */
return StX;
}
vpip_bit_t vvm_binop_gt(const vvm_bitset_t&l, const vvm_bitset_t&r)
{
vpip_bit_t result = St0;
const unsigned lwid = l.get_width();
const unsigned rwid = r.get_width();
const unsigned common = (lwid < rwid)? lwid : rwid;
for (unsigned idx = 0 ; idx < common ; idx += 1)
result = greater_with_cascade(l.get_bit(idx),
r.get_bit(idx),
result);
if (lwid > rwid) {
for (unsigned idx = rwid ; idx < lwid ; idx += 1)
result = greater_with_cascade(l.get_bit(idx), St0, result);
} else {
for (unsigned idx = lwid ; idx < rwid ; idx += 1)
result = greater_with_cascade(St0, r.get_bit(idx), result);
}
return result;
}
/*
* This is the > operator that applies to signed operands.
*/
vpip_bit_t vvm_binop_gt_s(const vvm_bitset_t&l, const vvm_bitset_t&r)
{
vpip_bit_t l_pad = l.get_bit(l.get_width()-1);
vpip_bit_t r_pad = r.get_bit(r.get_width()-1);
/* If l>=0 and r>=0, return $unsigned(l) > $unsigned(r) */
if (B_IS0(l_pad) && B_IS0(r_pad))
return vvm_binop_gt(l, r);
/* If l < 0 and r < 0, return $unsigned(r) > $unsigned(l) */
if (B_IS1(l_pad) && B_IS1(r_pad))
return vvm_binop_gt(r, l);
/* If l >= 0 and r < 0, return true; */
if (B_IS0(l_pad) && B_IS1(r_pad))
return St1;
/* if l < 0 and r >= 0, return false; */
if (B_IS1(l_pad) && B_IS0(r_pad))
return St0;
/* Otherwise, one or the other side is unknown. Return X. */
return StX;
}
vpip_bit_t vvm_binop_ge(const vvm_bitset_t&l, const vvm_bitset_t&r)
{
vpip_bit_t result = St1;
const unsigned lwid = l.get_width();
const unsigned rwid = r.get_width();
const unsigned common = (lwid < rwid)? lwid : rwid;
for (unsigned idx = 0 ; idx < common ; idx += 1)
result = greater_with_cascade(l.get_bit(idx),
r.get_bit(idx), result);
if (lwid > rwid) {
for (unsigned idx = rwid ; idx < lwid ; idx += 1)
result = greater_with_cascade(l.get_bit(idx), St0, result);
} else {
for (unsigned idx = lwid ; idx < rwid ; idx += 1)
result = greater_with_cascade(St0, r.get_bit(idx), result);
}
return result;
}
/*
* This is the >= operator that applies to signed operands.
*/
vpip_bit_t vvm_binop_ge_s(const vvm_bitset_t&l, const vvm_bitset_t&r)
{
vpip_bit_t l_pad = l.get_bit(l.get_width()-1);
vpip_bit_t r_pad = r.get_bit(r.get_width()-1);
/* If l>=0 and r>=0, return $unsigned(l) >= $unsigned(r) */
if (B_IS0(l_pad) && B_IS0(r_pad))
return vvm_binop_ge(l, r);
/* If l < 0 and r < 0, return $unsigned(r) >= $unsigned(l) */
if (B_IS1(l_pad) && B_IS1(r_pad))
return vvm_binop_ge(r, l);
/* If l >= 0 and r < 0, return true; */
if (B_IS0(l_pad) && B_IS1(r_pad))
return St1;
/* if l < 0 and r >= 0, return false; */
if (B_IS1(l_pad) && B_IS0(r_pad))
return St0;
/* Otherwise, one or the other side is unknown. Return X. */
return StX;
}
vpip_bit_t vvm_binop_land(const vvm_bitset_t&l, const vvm_bitset_t&r)
{
vpip_bit_t res1 = vvm_unop_or(l);
vpip_bit_t res2 = vvm_unop_or(r);
return B_AND(res1, res2);
}
vpip_bit_t vvm_binop_lor(const vvm_bitset_t&l, const vvm_bitset_t&r)
{
vpip_bit_t res1 = vvm_unop_or(l);
vpip_bit_t res2 = vvm_unop_or(r);
return B_OR(res1, res2);
}
void vvm_ternary(vvm_bitset_t&v, vpip_bit_t c,
const vvm_bitset_t&t,
const vvm_bitset_t&f)
{
if (B_IS0(c)) {
for (unsigned idx = 0 ; idx < v.nbits ; idx += 1)
v[idx] = (idx < f.nbits)? f[idx] : St0;
return;
}
if (B_IS1(c)) {
for (unsigned idx = 0 ; idx < v.nbits ; idx += 1)
v[idx] = (idx < t.nbits)? t[idx] : St0;
return;
}
for (unsigned idx = 0 ; idx < v.nbits ; idx += 1) {
vpip_bit_t tb = (idx < t.nbits)? t[idx] : St0;
vpip_bit_t fb = (idx < f.nbits)? f[idx] : St0;
if (B_EQ(tb, fb))
v[idx] = tb;
else
v[idx] = StX;
}
}
/*
* $Log: vvm_func.cc,v $
* Revision 1.18 2002/08/12 01:35:06 steve
* conditional ident string using autoconfig.
*
* Revision 1.17 2001/07/25 03:10:50 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
*
* Revision 1.16 2001/02/13 03:38:55 steve
* Binary or and nor resilient to bit widths.
*
* Revision 1.15 2001/02/10 01:57:18 steve
* Make the add func resilient to bit widths (PR#141)
*
* Revision 1.14 2001/02/07 21:47:13 steve
* Fix expression widths for rvalues and parameters (PR#131,132)
*
* Revision 1.13 2000/12/11 00:31:44 steve
* Add support for signed reg variables,
* simulate in t-vvm signed comparisons.
*
* Revision 1.12 2000/07/06 18:12:28 steve
* unop_not can take out width same as in width.
*
* Revision 1.11 2000/06/30 15:47:06 steve
* Reduce result is OK in ~ operator.
*
* Revision 1.10 2000/05/18 20:35:08 steve
* Ternary operator handles bit sizes.
*
* Revision 1.9 2000/05/18 20:23:40 steve
* Overcautious assert in shift is removed.
*
* Revision 1.8 2000/04/29 01:19:47 steve
* Proper bounds checking of the left operator of right shift.
*
* Revision 1.7 2000/04/26 03:32:40 steve
* AND handles argument padding if necessary.
*
* Revision 1.6 2000/03/26 16:55:41 steve
* Remove the vvm_bits_t abstract class.
*
* Revision 1.5 2000/03/26 16:28:31 steve
* vvm_bitset_t is no longer a template.
*
* Revision 1.4 2000/03/25 02:43:56 steve
* Remove all remain vvm_bitset_t return values,
* and disallow vvm_bitset_t copying.
*
* Revision 1.3 2000/03/24 02:43:37 steve
* vvm_unop and vvm_binop pass result by reference
* instead of returning a value.
*
* Revision 1.2 2000/03/22 04:26:41 steve
* Replace the vpip_bit_t with a typedef and
* define values for all the different bit
* values, including strengths.
*
* Revision 1.1 2000/03/13 00:02:34 steve
* Remove unneeded templates.
*
*/
-269
View File
@@ -1,269 +0,0 @@
#ifndef __vvm_vvm_func_H
#define __vvm_vvm_func_H
/*
* Copyright (c) 1998-2000 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: vvm_func.h,v 1.31 2002/08/12 01:35:06 steve Exp $"
#endif
# include "vvm.h"
# include "vvm_signal.h"
/*
* Implement the unary NOT operator in the verilog way. This takes a
* vector of a certain width and returns a result of the same width.
*/
extern void vvm_unop_not(vvm_bitset_t&v, const vvm_bitset_t&p);
/*
* The unary AND is the reduction AND. It returns a single bit.
*/
extern vpip_bit_t vvm_unop_and(const vvm_bitset_t&r);
extern vpip_bit_t vvm_unop_nand(const vvm_bitset_t&r);
extern vpip_bit_t vvm_unop_lnot(const vvm_bitset_t&r);
/*
* The unary OR is the reduction OR. It returns a single bit.
*/
extern vpip_bit_t vvm_unop_or(const vvm_bitset_t&r);
extern vpip_bit_t vvm_unop_nor(const vvm_bitset_t&r);
/*
* The unary XOR is the reduction XOR. It returns a single bit.
*/
extern vpip_bit_t vvm_unop_xor(const vvm_bitset_t&r);
extern vpip_bit_t vvm_unop_xnor(const vvm_bitset_t&r);
/*
* simple-minded unary minus operator (two's complement)
*/
extern void vvm_unop_uminus(vvm_bitset_t&v, const vvm_bitset_t&l);
/*
* Implement the binary AND operator. This is a bitwise and with all
* the parameters and the result having the same width.
*/
extern void vvm_binop_and(vvm_bitset_t&v,
const vvm_bitset_t&l,
const vvm_bitset_t&r);
/*
* Implement the binary OR operator. This is a bitwise and with all
* the parameters and the result having the same width.
*/
extern void vvm_binop_or(vvm_bitset_t&v,
const vvm_bitset_t&l,
const vvm_bitset_t&r);
extern void vvm_binop_nor(vvm_bitset_t&v,
const vvm_bitset_t&l,
const vvm_bitset_t&r);
/*
* Implement the binary + operator in the verilog way. This takes
* vectors of identical width and returns another vector of same width
* that contains the arithmetic sum. Z values are converted to X.
*/
extern void vvm_binop_plus(vvm_bitset_t&v,
const vvm_bitset_t&l,
const vvm_bitset_t&r);
/*
* Integer division and modulus
*/
extern void vvm_binop_idiv(vvm_bitset_t&v,
const vvm_bitset_t&l,
const vvm_bitset_t&r);
extern void vvm_binop_imod(vvm_bitset_t&v,
const vvm_bitset_t&l,
const vvm_bitset_t&r);
/*
* The binary - operator is turned into + by doing 2's complement
* arithmetic. l-r == l+~r+1. The "+1" is accomplished by adding in a
* carry of 1 to the 0 bit position.
*/
extern void vvm_binop_minus(vvm_bitset_t&v,
const vvm_bitset_t&l,
const vvm_bitset_t&r);
/*
* The multiply binary operator takes an A and B parameter and returns
* the result in the vpip_bit_t array. The template form arranges for
* the right parameters to be passed to the extern form.
*/
extern void vvm_binop_mult(vpip_bit_t*res, unsigned nres,
const vpip_bit_t*a, unsigned na,
const vpip_bit_t*b, unsigned nb);
inline void vvm_binop_mult(vvm_bitset_t&r,
const vvm_bitset_t&a,
const vvm_bitset_t&b)
{
vvm_binop_mult(r.bits, r.nbits,
a.bits, a.nbits,
b.bits, b.nbits);
}
/*
* The binary ^ (xor) operator is a bitwise XOR of equal width inputs
* to generate the corresponsing output.
*/
extern void vvm_binop_xor(vvm_bitset_t&v,
const vvm_bitset_t&l,
const vvm_bitset_t&r);
extern void vvm_binop_xnor(vvm_bitset_t&v,
const vvm_bitset_t&l,
const vvm_bitset_t&r);
/*
* the binary 'l' operator is a logic left-shift by the number of positions
* indicated by argument r. r is an unsigned integer, which is represented
* internally as a 32-bit bitvector.
*/
extern void vvm_binop_shiftl(vvm_bitset_t&v,
const vvm_bitset_t&l,
const vvm_bitset_t&r);
/*
* The binary 'r' operator is a logic right-shift by the number of positions
* indicated by argument r. r is an unsigned integer, which is represented
* internally by a 32-bit bitvector.
*/
extern void vvm_binop_shiftr(vvm_bitset_t&v,
const vvm_bitset_t&l,
const vvm_bitset_t&r);
/*
* Tests for equality are a bit tricky, as they allow for the left and
* right subexpressions to have different size. The shorter bitset is
* extended with zeros. Also, if there is Vx or Vz anywhere in either
* vectors, the result is Vx.
*/
extern vpip_bit_t vvm_binop_eq(const vvm_bitset_t&l, const vvm_bitset_t&r);
extern vpip_bit_t vvm_binop_ne(const vvm_bitset_t&l, const vvm_bitset_t&r);
/*
* This function return true if all the bits are the same. Even x and
* z bites are compared for equality.
*/
extern vpip_bit_t vvm_binop_eeq(const vvm_bitset_t&l, const vvm_bitset_t&r);
extern vpip_bit_t vvm_binop_nee(const vvm_bitset_t&l, const vvm_bitset_t&r);
/*
* This function return true if all the bits are the same. The x and z
* bits are don't care, s don't make the result false.
*/
extern vpip_bit_t vvm_binop_xeq(const vvm_bitset_t&l, const vvm_bitset_t&r);
/*
* This function return true if all the bits are the same. The z
* bits are don't care, so don't make the result false.
*/
extern vpip_bit_t vvm_binop_zeq(const vvm_bitset_t&l, const vvm_bitset_t&r);
/*
* The _s variants are signed versions. That is, it assumes the
* operands are signed values and does the comparison on that basis.
*/
extern vpip_bit_t vvm_binop_lt(const vvm_bitset_t&l, const vvm_bitset_t&r);
extern vpip_bit_t vvm_binop_lt_s(const vvm_bitset_t&l, const vvm_bitset_t&r);
extern vpip_bit_t vvm_binop_le(const vvm_bitset_t&l, const vvm_bitset_t&r);
extern vpip_bit_t vvm_binop_le_s(const vvm_bitset_t&l, const vvm_bitset_t&r);
extern vpip_bit_t vvm_binop_gt(const vvm_bitset_t&l, const vvm_bitset_t&r);
extern vpip_bit_t vvm_binop_gt_s(const vvm_bitset_t&l, const vvm_bitset_t&r);
extern vpip_bit_t vvm_binop_ge(const vvm_bitset_t&l, const vvm_bitset_t&r);
extern vpip_bit_t vvm_binop_ge_s(const vvm_bitset_t&l, const vvm_bitset_t&r);
extern vpip_bit_t vvm_binop_land(const vvm_bitset_t&l, const vvm_bitset_t&r);
extern vpip_bit_t vvm_binop_lor(const vvm_bitset_t&l, const vvm_bitset_t&r);
extern void vvm_ternary(vvm_bitset_t&v, vpip_bit_t c,
const vvm_bitset_t&t,
const vvm_bitset_t&f);
/*
* $Log: vvm_func.h,v $
* Revision 1.31 2002/08/12 01:35:06 steve
* conditional ident string using autoconfig.
*
* Revision 1.30 2000/12/11 00:31:44 steve
* Add support for signed reg variables,
* simulate in t-vvm signed comparisons.
*
* Revision 1.29 2000/05/19 04:22:56 steve
* Add the integer modulus function.
*
* Revision 1.28 2000/04/01 21:40:23 steve
* Add support for integer division.
*
* Revision 1.27 2000/03/26 16:55:41 steve
* Remove the vvm_bits_t abstract class.
*
* Revision 1.26 2000/03/26 16:28:31 steve
* vvm_bitset_t is no longer a template.
*
* Revision 1.25 2000/03/25 02:43:57 steve
* Remove all remain vvm_bitset_t return values,
* and disallow vvm_bitset_t copying.
*
* Revision 1.24 2000/03/24 02:43:37 steve
* vvm_unop and vvm_binop pass result by reference
* instead of returning a value.
*
* Revision 1.23 2000/03/22 04:26:41 steve
* Replace the vpip_bit_t with a typedef and
* define values for all the different bit
* values, including strengths.
*
* Revision 1.22 2000/03/16 19:03:04 steve
* Revise the VVM backend to use nexus objects so that
* drivers and resolution functions can be used, and
* the t-vvm module doesn't need to write a zillion
* output functions.
*
* Revision 1.21 2000/03/13 00:02:34 steve
* Remove unneeded templates.
*
* Revision 1.20 2000/02/23 04:43:43 steve
* Some compilers do not accept the not symbol.
*
* Revision 1.19 2000/02/23 02:56:56 steve
* Macintosh compilers do not support ident.
*
* Revision 1.18 2000/01/13 06:05:46 steve
* Add the XNOR operator.
*
* Revision 1.17 2000/01/13 03:35:35 steve
* Multiplication all the way to simulation.
*
* Revision 1.16 1999/12/02 03:36:01 steve
* shiftl and shiftr take unsized second parameter.
*/
#endif
-971
View File
@@ -1,971 +0,0 @@
/*
* Copyright (c) 1999-2000 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: vvm_gates.cc,v 1.24 2002/08/12 01:35:06 steve Exp $"
#endif
# include "config.h"
# include "vvm_gates.h"
# include <stdlib.h>
# include <typeinfo>
# include <string>
# include <map>
# include <sys/time.h>
# include <unistd.h>
vvm_out_event::vvm_out_event(vpip_bit_t v, vvm_nexus::drive_t*o)
: output_(o), val_(v)
{
}
vvm_out_event::~vvm_out_event()
{
}
void vvm_out_event::event_function()
{
output_->set_value(val_);
}
vvm_1bit_out::vvm_1bit_out(unsigned d)
: delay_(d)
{
drive0_ = St0;
drive1_ = St1;
driveX_ = StX;
driveZ_ = HiZ;
}
vvm_1bit_out::~vvm_1bit_out()
{
}
void vvm_1bit_out::drive0(vpip_bit_t v)
{
drive0_ = v;
driveX_ = (drive1_&0xf0) | (drive0_&0x0f);
}
void vvm_1bit_out::drive1(vpip_bit_t v)
{
drive1_ = v;
driveX_ = (drive1_&0xf0) | (drive0_&0x0f);
}
void vvm_1bit_out::driveZ(vpip_bit_t v)
{
driveZ_ = v;
}
void vvm_1bit_out::output(vpip_bit_t val)
{
if (delay_) {
vvm_event*ev = new vvm_out_event(val, this);
ev -> schedule(delay_);
} else {
set_value(val);
}
}
vpip_bit_t compute_and(const vpip_bit_t*inp, unsigned count)
{
vpip_bit_t outval = inp[0];
for (unsigned i = 1 ; i < count ; i += 1)
outval = B_AND(outval, inp[i]);
return outval;
}
vpip_bit_t compute_or(const vpip_bit_t*inp, unsigned count)
{
vpip_bit_t outval = inp[0];
for (unsigned i = 1 ; i < count ; i += 1)
outval = B_OR(outval, inp[i]);
return outval;
}
vpip_bit_t compute_nor(const vpip_bit_t*inp, unsigned count)
{
vpip_bit_t outval = inp[0];
for (unsigned i = 1 ; i < count ; i += 1)
outval = B_OR(outval, inp[i]);
return B_NOT(outval);
}
vpip_bit_t compute_xor(const vpip_bit_t*inp, unsigned count)
{
vpip_bit_t outval = inp[0];
for (unsigned i = 1; i < count; i++)
outval = B_XOR(outval, inp[i]);
return outval;
}
vpip_bit_t compute_nand(const vpip_bit_t*inp, unsigned count)
{
return B_NOT(compute_and(inp,count));
}
vpip_bit_t compute_xnor(const vpip_bit_t*inp, unsigned count)
{
return B_NOT(compute_xor(inp,count));
}
vpip_bit_t reduce_strength(vpip_bit_t val)
{
if (B_IS0(val)) {
if ((val == Su0) ||
(val == St0))
return(Pu0);
else if (val == Pu0)
return(We0);
else if ((val == We0) ||
(val == La0))
return(Me0);
else if ((val == Me0) ||
(val == Sm0))
return(Sm0);
} else if (B_IS1(val)) {
if ((val == Su1) ||
(val == St1))
return(Pu1);
else if (val == Pu1)
return(We1);
else if ((val == We1) ||
(val == La1))
return(Me1);
else if ((val == Me1) ||
(val == Sm1))
return(Sm1);
} else if (B_ISX(val)) {
if ((val == SuX) ||
(val == StX))
return(PuX);
else if (val == PuX)
return(WeX);
else if ((val == WeX) ||
(val == LaX))
return(MeX);
else if ((val == MeX) ||
(val == SmX))
return(SmX);
}
return(HiZ);
}
vvm_and::vvm_and(unsigned wid, unsigned long d)
: vvm_1bit_out(d), width_(wid)
{
input_ = new vpip_bit_t[wid];
}
vvm_and::~vvm_and()
{
delete [] input_;
}
void vvm_and::init_I(unsigned idx, vpip_bit_t val)
{
input_[idx] = val;
}
void vvm_and::start()
{
output(compute_and(input_,width_));
}
void vvm_and::take_value(unsigned key, vpip_bit_t val)
{
assert(key < width_);
if (input_[key] == val) return;
input_[key] = val;
output(compute_and(input_,width_));
}
vvm_and2::vvm_and2(unsigned long d)
: vvm_1bit_out(d)
{
}
vvm_and2::~vvm_and2()
{
}
void vvm_and2::init_I(unsigned idx, vpip_bit_t val)
{
assert(idx < 2);
input_[idx] = val;
}
void vvm_and2::start()
{
output(B_AND(input_[0], input_[1]));
}
void vvm_and2::take_value(unsigned key, vpip_bit_t val)
{
if (input_[key] == val)
return;
input_[key] = val;
output(B_AND(input_[0], input_[1]));
}
vvm_buf::vvm_buf(unsigned long d)
: vvm_1bit_out(d)
{
}
vvm_buf::~vvm_buf()
{
}
void vvm_buf::init_I(unsigned, vpip_bit_t)
{
}
void vvm_buf::take_value(unsigned, vpip_bit_t val)
{
vpip_bit_t outval = val;
if (B_ISXZ(val))
outval = StX;
else if (B_IS1(val))
outval = St1;
else
outval = St0;
output(outval);
}
vvm_bufif0::vvm_bufif0(unsigned long d)
: vvm_1bit_out(d)
{
input_[0] = StX;
input_[1] = StX;
}
vvm_bufif0::~vvm_bufif0()
{
}
void vvm_bufif0::init_I(unsigned key, vpip_bit_t val)
{
assert(key < 2);
input_[key] = val;
}
void vvm_bufif0::take_value(unsigned key, vpip_bit_t val)
{
if (input_[key] == val) return;
input_[key] = val;
if ( B_IS1(input_[1]))
output(HiZ);
else if ( B_ISX(input_[0]) ||
B_ISZ(input_[0]))
output(StX);
else if (B_IS0(input_[0])) {
if (B_IS0(input_[1])) {
output(St0);
} else {
output(StL);
}
} else {
if (B_IS0(input_[1])) {
output(St1);
} else {
output(StH);
}
}
}
vvm_bufif1::vvm_bufif1(unsigned long d)
: vvm_1bit_out(d)
{
input_[0] = StX;
input_[1] = StX;
}
vvm_bufif1::~vvm_bufif1()
{
}
void vvm_bufif1::init_I(unsigned key, vpip_bit_t val)
{
assert(key < 2);
input_[key] = val;
}
void vvm_bufif1::take_value(unsigned key, vpip_bit_t val)
{
if (input_[key] == val) return;
input_[key] = val;
if ( B_IS0(input_[1]))
output(HiZ);
else if ( B_ISX(input_[0]) ||
B_ISZ(input_[0]))
output(StX);
else if (B_IS0(input_[0])) {
if (B_IS1(input_[1])) {
output(St0);
} else {
output(StL);
}
} else {
if (B_IS1(input_[1])) {
output(St1);
} else {
output(StH);
}
}
}
vvm_bufz::vvm_bufz(unsigned delay)
: vvm_1bit_out(delay)
{
}
vvm_bufz::~vvm_bufz()
{
}
void vvm_bufz::init_I(unsigned, vpip_bit_t val)
{
output(val);
}
void vvm_bufz::take_value(unsigned, vpip_bit_t val)
{
output(val);
}
vvm_eeq::vvm_eeq(unsigned long d)
: vvm_1bit_out(d)
{
}
vvm_eeq::~vvm_eeq()
{
}
void vvm_eeq::init_I(unsigned idx, vpip_bit_t val)
{
input_[idx] = val;
}
void vvm_eeq::start()
{
output(compute_());
}
void vvm_eeq::take_value(unsigned key, vpip_bit_t val)
{
if (input_[key] == val)
return;
input_[key] = val;
output(compute_());
}
vpip_bit_t vvm_eeq::compute_() const
{
vpip_bit_t outval = St0;
if (B_EQ(input_[0], input_[1]))
outval = St1;
return outval;
}
vvm_nand::vvm_nand(unsigned wid, unsigned long d)
: vvm_1bit_out(d), width_(wid)
{
input_ = new vpip_bit_t[wid];
}
vvm_nand::~vvm_nand()
{
delete [] input_;
}
void vvm_nand::init_I(unsigned idx, vpip_bit_t val)
{
input_[idx] = val;
}
void vvm_nand::start()
{
output(compute_nand(input_,width_));
}
void vvm_nand::take_value(unsigned key, vpip_bit_t val)
{
assert(key < width_);
if (input_[key] == val) return;
input_[key] = val;
output(compute_nand(input_, width_));
}
vvm_nor::vvm_nor(unsigned wid, unsigned long d)
: vvm_1bit_out(d), width_(wid)
{
input_ = new vpip_bit_t[wid];
}
vvm_nor::~vvm_nor()
{
delete [] input_;
}
void vvm_nor::init_I(unsigned idx, vpip_bit_t val)
{
input_[idx] = val;
}
void vvm_nor::start()
{
output(compute_nor(input_,width_));
}
void vvm_nor::take_value(unsigned key, vpip_bit_t val)
{
assert(key < width_);
if (input_[key] == val) return;
input_[key] = val;
output(compute_nor(input_, width_));
}
vvm_or::vvm_or(unsigned wid, unsigned long d)
: vvm_1bit_out(d), width_(wid)
{
input_ = new vpip_bit_t[wid];
}
vvm_or::~vvm_or()
{
delete [] input_;
}
void vvm_or::init_I(unsigned idx, vpip_bit_t val)
{
input_[idx] = val;
}
void vvm_or::start()
{
output(compute_or(input_,width_));
}
void vvm_or::take_value(unsigned key, vpip_bit_t val)
{
assert(key < width_);
if (input_[key] == val) return;
input_[key] = val;
output(compute_or(input_, width_));
}
vvm_nmos::vvm_nmos(unsigned long d)
: vvm_1bit_out(d)
{
input_[0] = StX;
input_[1] = StX;
}
void vvm_nmos::init_I(unsigned key, vpip_bit_t val)
{
assert(key < 2);
input_[key] = val;
}
void vvm_nmos::take_value(unsigned key, vpip_bit_t val)
{
if (input_[key] == val) {
return;
}
input_[key] = val;
if ( B_IS0(input_[1])) {
output(HiZ);
} else if (B_ISX(input_[0]))
output(StX);
else if (B_ISZ(input_[0])) {
output(HiZ);
} else if (B_IS0(input_[0])) {
if (B_IS1(input_[1])) {
output(St0);
} else {
output(StL);
}
} else {
if (B_IS1(input_[1])) {
output(St1);
} else {
output(StH);
}
}
}
vvm_rnmos::vvm_rnmos(unsigned long d)
: vvm_1bit_out(d)
{
input_[0] = StX;
input_[1] = StX;
}
void vvm_rnmos::init_I(unsigned key, vpip_bit_t val)
{
assert(key < 2);
input_[key] = val;
}
void vvm_rnmos::take_value(unsigned key, vpip_bit_t val)
{
if (input_[key] == val) return;
input_[key] = val;
if ( B_IS0(input_[1]))
output(HiZ);
else if (B_ISX(input_[0]))
output(reduce_strength(input_[0]));
else if (B_ISZ(input_[0]))
output(HiZ);
else if (B_IS0(input_[0])) {
if (B_IS1(input_[1])) {
output(reduce_strength(input_[0]));
} else {
output(StL);
}
} else {
if (B_IS1(input_[1])) {
output(reduce_strength(input_[0]));
} else {
output(StH);
}
}
}
vvm_pmos::vvm_pmos(unsigned long d)
: vvm_1bit_out(d)
{
input_[0] = StX;
input_[1] = StX;
}
void vvm_pmos::init_I(unsigned key, vpip_bit_t val)
{
assert(key < 2);
input_[key] = val;
}
void vvm_pmos::take_value(unsigned key, vpip_bit_t val)
{
if (input_[key] == val) return;
input_[key] = val;
if ( B_IS1(input_[1]))
output(HiZ);
else if (B_ISX(input_[0]))
output(StX);
else if (B_ISZ(input_[0]))
output(HiZ);
else if (B_IS0(input_[0])) {
if (B_IS0(input_[1])) {
output(St0);
} else {
output(StL);
}
} else {
if (B_IS0(input_[1])) {
output(St1);
} else {
output(StH);
}
}
}
vvm_rpmos::vvm_rpmos(unsigned long d)
: vvm_1bit_out(d)
{
input_[0] = StX;
input_[1] = StX;
}
void vvm_rpmos::init_I(unsigned key, vpip_bit_t val)
{
assert(key < 2);
input_[key] = val;
}
void vvm_rpmos::take_value(unsigned key, vpip_bit_t val)
{
if (input_[key] == val) return;
input_[key] = val;
if ( B_IS1(input_[1]))
output(HiZ);
else if (B_ISX(input_[0]))
output(reduce_strength(input_[0]));
else if (B_ISZ(input_[0]))
output(HiZ);
else if (B_IS0(input_[0])) {
if (B_IS0(input_[1])) {
output(reduce_strength(input_[0]));
} else {
output(StL);
}
} else {
if (B_IS0(input_[1])) {
output(reduce_strength(input_[0]));
} else {
output(StH);
}
}
}
void vvm_nor2::init_I(unsigned idx, vpip_bit_t val)
{
assert(idx < 2);
input_[idx] = val;
}
void vvm_nor2::start()
{
output(B_NOT(B_OR(input_[0], input_[1])));
}
vvm_nor2::vvm_nor2(unsigned long d)
: vvm_1bit_out(d)
{
}
vvm_nor2::~vvm_nor2()
{
}
void vvm_nor2::take_value(unsigned key, vpip_bit_t val)
{
if (input_[key] == val)
return;
input_[key] = val;
output(B_NOT(B_OR(input_[0], input_[1])));
}
vvm_not::vvm_not(unsigned long d)
: vvm_1bit_out(d)
{
}
vvm_not::~vvm_not()
{
}
void vvm_not::init_I(unsigned, vpip_bit_t)
{
}
void vvm_not::start()
{
}
void vvm_not::take_value(unsigned, vpip_bit_t val)
{
output(B_NOT(val));
}
vvm_notif0::vvm_notif0(unsigned long d)
: vvm_1bit_out(d)
{
input_[0] = StX;
input_[1] = StX;
}
vvm_notif0::~vvm_notif0()
{
}
void vvm_notif0::init_I(unsigned key, vpip_bit_t val)
{
assert(key < 2);
input_[key] = val;
}
void vvm_notif0::take_value(unsigned key, vpip_bit_t val)
{
if (input_[key] == val) return;
input_[key] = val;
if ( B_IS1(input_[1]))
output(HiZ);
else if ( B_ISX(input_[0]) ||
B_ISZ(input_[0]))
output(StX);
else if (B_IS0(input_[0])) {
if (B_IS0(input_[1])) {
output(St1);
} else {
output(StH);
}
} else {
if (B_IS0(input_[1])) {
output(St0);
} else {
output(StL);
}
}
}
vvm_notif1::vvm_notif1(unsigned long d)
: vvm_1bit_out(d)
{
input_[0] = StX;
input_[1] = StX;
}
vvm_notif1::~vvm_notif1()
{
}
void vvm_notif1::init_I(unsigned key, vpip_bit_t val)
{
assert(key < 2);
input_[key] = val;
}
void vvm_notif1::take_value(unsigned key, vpip_bit_t val)
{
if (input_[key] == val) return;
input_[key] = val;
if ( B_IS0(input_[1]))
output(HiZ);
else if ( B_ISX(input_[0]) ||
B_ISZ(input_[0]))
output(StX);
else if (B_IS0(input_[0])) {
if (B_IS1(input_[1])) {
output(St1);
} else {
output(StH);
}
} else {
if (B_IS1(input_[1])) {
output(St0);
} else {
output(StL);
}
}
}
vvm_xnor::vvm_xnor(unsigned wid, unsigned long d)
: vvm_1bit_out(d), width_(wid)
{
input_ = new vpip_bit_t[wid];
}
vvm_xnor::~vvm_xnor()
{
delete [] input_;
}
void vvm_xnor::init_I(unsigned idx, vpip_bit_t val)
{
input_[idx] = val;
}
void vvm_xnor::start()
{
output(compute_xnor(input_,width_));
}
void vvm_xnor::take_value(unsigned key, vpip_bit_t val)
{
assert(key < width_);
if (input_[key] == val) return;
input_[key] = val;
output(compute_xnor(input_, width_));
}
vvm_xor::vvm_xor(unsigned wid, unsigned long d)
: vvm_1bit_out(d), width_(wid)
{
input_ = new vpip_bit_t[wid];
}
vvm_xor::~vvm_xor()
{
delete [] input_;
}
void vvm_xor::init_I(unsigned idx, vpip_bit_t val)
{
input_[idx] = val;
}
void vvm_xor::start()
{
output(compute_xor(input_,width_));
}
void vvm_xor::take_value(unsigned key, vpip_bit_t val)
{
assert(key < width_);
if (input_[key] == val) return;
input_[key] = val;
output(compute_xor(input_, width_));
}
vvm_pullup::vvm_pullup(unsigned d)
: vvm_1bit_out(d)
{
}
void vvm_pullup::start()
{
output(St1);
}
void vvm_pullup::take_value(unsigned key, vpip_bit_t val)
{
}
vvm_pullup::~vvm_pullup()
{
}
vvm_pulldown::vvm_pulldown(unsigned d)
: vvm_1bit_out(d)
{
}
void vvm_pulldown::start()
{
output(St0);
}
void vvm_pulldown::take_value(unsigned key, vpip_bit_t val)
{
}
vvm_pulldown::~vvm_pulldown()
{
}
/*
* $Log: vvm_gates.cc,v $
* Revision 1.24 2002/08/12 01:35:06 steve
* conditional ident string using autoconfig.
*
* Revision 1.23 2001/10/14 03:50:53 steve
* vvm support for pullup/down gates (PR#288)
*
* Revision 1.22 2001/07/25 03:10:50 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
*
* Revision 1.21 2001/01/16 03:57:46 steve
* Get rid of gate templates.
*
* Revision 1.20 2000/12/10 06:42:00 steve
* Support delays on continuous assignment from idents. (PR#40)
*
* Revision 1.19 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.18 2000/07/11 23:08:33 steve
* proper init method for bufz devices.
*
* Revision 1.17 2000/07/08 22:39:32 steve
* pass zero-delay values immediately.
*
* Revision 1.16 2000/05/11 01:37:33 steve
* Calculate the X output value from drive0 and drive1
*
* Revision 1.15 2000/05/09 21:16:35 steve
* Give strengths to logic and bufz devices.
*
* Revision 1.14 2000/05/08 05:27:32 steve
* Restore vvm_bufz to working condition.
*
* Revision 1.13 2000/04/23 21:15:07 steve
* Emit code for the bufif devices.
*
* Revision 1.12 2000/03/22 04:26:41 steve
* Replace the vpip_bit_t with a typedef and
* define values for all the different bit
* values, including strengths.
*
* Revision 1.11 2000/03/18 02:26:02 steve
* Update bufz to nexus style.
*
* Revision 1.10 2000/03/18 01:27:00 steve
* Generate references into a table of nexus objects instead of
* generating lots of isolated nexus objects. Easier on linkers
* and compilers,
*
* Add missing nexus support for l-value bit selects,
*
* Detemplatize the vvm_mux type.
*
* Fix up the vvm_nexus destructor to disconnect from drivers.
*
* Revision 1.9 2000/03/17 19:24:00 steve
* nor2 and and2 optimized gates.
*
* Revision 1.8 2000/03/17 03:36:07 steve
* Remove some useless template parameters.
*
* Revision 1.7 2000/03/16 19:03:04 steve
* Revise the VVM backend to use nexus objects so that
* drivers and resolution functions can be used, and
* the t-vvm module doesn't need to write a zillion
* output functions.
*
* Revision 1.6 2000/02/24 01:56:28 steve
* change not to v_not.
*
* Revision 1.5 2000/02/23 02:56:56 steve
* Macintosh compilers do not support ident.
*
* Revision 1.4 1999/12/12 19:47:54 steve
* Remove the useless vvm_simulation class.
*
* Revision 1.3 1999/12/02 04:54:11 steve
* Handle mux sel of X, if inputs are equal.
*
* Revision 1.2 1999/11/24 04:38:49 steve
* LT and GT fixes from Eric Aardoom.
*
* Revision 1.1 1999/11/22 00:30:52 steve
* Detemplate some and, or and nor methods.
*
*/
-1069
View File
File diff suppressed because it is too large Load Diff
-157
View File
@@ -1,157 +0,0 @@
/*
* Copyright (c) 2000 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: vvm_idiv.cc,v 1.3 2002/08/12 01:35:07 steve Exp $"
#endif
# include "config.h"
# include "vvm_func.h"
# include "vvm_gates.h"
# include <assert.h>
void vvm_binop_idiv(vvm_bitset_t&v, const vvm_bitset_t&l, const vvm_bitset_t&r)
{
assert(v.get_width() <= 8*sizeof(unsigned long));
assert(l.get_width() <= 8*sizeof(unsigned long));
assert(r.get_width() <= 8*sizeof(unsigned long));
unsigned long lv = 0, rv = 0;
unsigned long vv;
for (unsigned idx = 0 ; idx < l.get_width() ; idx += 1) {
if (B_ISXZ(l[idx]))
goto unknown_result;
if (B_IS1(l[idx]))
lv |= 1 << idx;
}
for (unsigned idx = 0 ; idx < r.get_width() ; idx += 1) {
if (B_ISXZ(r[idx]))
goto unknown_result;
if (B_IS1(r[idx]))
rv |= 1 << idx;
}
if (rv == 0)
goto unknown_result;
vv = lv / rv;
for (unsigned idx = 0 ; idx < v.get_width() ; idx += 1) {
if (vv & 1)
v[idx] = St1;
else
v[idx] = St0;
vv >>= 1;
}
return;
unknown_result:
for (unsigned idx= 0 ; idx < v.get_width() ; idx += 1)
v[idx] = StX;
}
vvm_idiv::vvm_idiv(unsigned rwid, unsigned awid, unsigned bwid)
: rwid_(rwid), awid_(awid), bwid_(bwid)
{
bits_ = new vpip_bit_t[rwid_+awid_+bwid_];
for (unsigned idx = 0 ; idx < rwid_+awid_+bwid_ ; idx += 1)
bits_[idx] = StX;
out_ = new vvm_nexus::drive_t[rwid];
}
vvm_idiv::~vvm_idiv()
{
delete[]out_;
delete[]bits_;
}
void vvm_idiv::init_DataA(unsigned idx, vpip_bit_t val)
{
assert(idx < awid_);
bits_[rwid_+idx] = val;
}
void vvm_idiv::init_DataB(unsigned idx, vpip_bit_t val)
{
assert(idx < bwid_);
bits_[rwid_+awid_+idx] = val;
}
vvm_nexus::drive_t* vvm_idiv::config_rout(unsigned idx)
{
assert(idx < rwid_);
return out_+idx;
}
unsigned vvm_idiv::key_DataA(unsigned idx) const
{
assert(idx < awid_);
return rwid_+idx;
}
unsigned vvm_idiv::key_DataB(unsigned idx) const
{
assert(idx < bwid_);
return rwid_+awid_+idx;
}
void vvm_idiv::take_value(unsigned key, vpip_bit_t val)
{
if (B_EQ(bits_[key], val)) {
bits_[key] = val;
return;
}
bits_[key] = val;
vvm_bitset_t r (bits_, rwid_);
vvm_bitset_t a (bits_+rwid_, awid_);
vvm_bitset_t b (bits_+rwid_+awid_, bwid_);
vvm_binop_idiv(r, a, b);
for (unsigned idx = 0 ; idx < rwid_ ; idx += 1)
out_[idx].set_value(bits_[idx]);
}
/*
* $Log: vvm_idiv.cc,v $
* Revision 1.3 2002/08/12 01:35:07 steve
* conditional ident string using autoconfig.
*
* Revision 1.2 2001/07/25 03:10:50 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
*
* Revision 1.1 2000/04/01 21:40:23 steve
* Add support for integer division.
*
*/
-165
View File
@@ -1,165 +0,0 @@
/*
* Copyright (c) 2000 Stephen Williams (steve@picturel.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: vvm_imod.cc,v 1.5 2002/08/12 01:35:07 steve Exp $"
#endif
# include "config.h"
# include "vvm_func.h"
# include "vvm_gates.h"
# include <assert.h>
void vvm_binop_imod(vvm_bitset_t&v, const vvm_bitset_t&l, const vvm_bitset_t&r)
{
assert(v.get_width() <= 8*sizeof(unsigned long));
assert(l.get_width() <= 8*sizeof(unsigned long));
assert(r.get_width() <= 8*sizeof(unsigned long));
unsigned long lv = 0, rv = 0;
unsigned long vv;
for (unsigned idx = 0 ; idx < l.get_width() ; idx += 1) {
if (B_ISXZ(l[idx]))
goto unknown_result;
if (B_IS1(l[idx]))
lv |= 1 << idx;
}
for (unsigned idx = 0 ; idx < r.get_width() ; idx += 1) {
if (B_ISXZ(r[idx]))
goto unknown_result;
if (B_IS1(r[idx]))
rv |= 1 << idx;
}
if (rv == 0)
goto unknown_result;
vv = lv % rv;
for (unsigned idx = 0 ; idx < v.get_width() ; idx += 1) {
if (vv & 1)
v[idx] = St1;
else
v[idx] = St0;
vv >>= 1;
}
return;
unknown_result:
for (unsigned idx= 0 ; idx < v.get_width() ; idx += 1)
v[idx] = StX;
}
vvm_imod::vvm_imod(unsigned rwid, unsigned awid, unsigned bwid)
: rwid_(rwid), awid_(awid), bwid_(bwid)
{
bits_ = new vpip_bit_t[rwid_+awid_+bwid_];
for (unsigned idx = 0 ; idx < rwid_+awid_+bwid_ ; idx += 1)
bits_[idx] = StX;
out_ = new vvm_nexus::drive_t[rwid];
}
vvm_imod::~vvm_imod()
{
delete[]out_;
delete[]bits_;
}
void vvm_imod::init_DataA(unsigned idx, vpip_bit_t val)
{
assert(idx < awid_);
bits_[rwid_+idx] = val;
}
void vvm_imod::init_DataB(unsigned idx, vpip_bit_t val)
{
assert(idx < bwid_);
bits_[rwid_+awid_+idx] = val;
}
vvm_nexus::drive_t* vvm_imod::config_rout(unsigned idx)
{
assert(idx < rwid_);
return out_+idx;
}
unsigned vvm_imod::key_DataA(unsigned idx) const
{
assert(idx < awid_);
return rwid_+idx;
}
unsigned vvm_imod::key_DataB(unsigned idx) const
{
assert(idx < bwid_);
return rwid_+awid_+idx;
}
void vvm_imod::take_value(unsigned key, vpip_bit_t val)
{
if (B_EQ(bits_[key], val)) {
bits_[key] = val;
return;
}
bits_[key] = val;
vvm_bitset_t r (bits_, rwid_);
vvm_bitset_t a (bits_+rwid_, awid_);
vvm_bitset_t b (bits_+rwid_+awid_, bwid_);
vvm_binop_imod(r, a, b);
for (unsigned idx = 0 ; idx < rwid_ ; idx += 1)
out_[idx].set_value(bits_[idx]);
}
/*
* $Log: vvm_imod.cc,v $
* Revision 1.5 2002/08/12 01:35:07 steve
* conditional ident string using autoconfig.
*
* Revision 1.4 2001/07/25 03:10:50 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
*
* Revision 1.3 2000/09/17 21:26:16 steve
* Add support for modulus (Eric Aardoom)
*
* Revision 1.2 2000/08/20 17:49:05 steve
* Clean up warnings and portability issues.
*
* Revision 1.1 2000/05/19 04:22:56 steve
* Add the integer modulus function.
*
*/
-122
View File
@@ -1,122 +0,0 @@
/*
* Copyright (c) 2000 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: vvm_memory.cc,v 1.4 2002/08/12 01:35:07 steve Exp $"
#endif
# include "config.h"
# include "vvm_signal.h"
vvm_memory_t::vvm_memory_t()
{
cb_list_ = 0;
}
void vvm_memory_t::set_word(unsigned addr, const vvm_bitset_t&val)
{
if (addr >= size)
return;
unsigned base = width * addr;
for (unsigned idx = 0 ; idx < width ; idx += 1)
bits[base+idx] = val[idx];
call_list_(addr);
}
void vvm_memory_t::set_word(unsigned addr, const vpip_bit_t*val)
{
if (addr >= size)
return;
unsigned base = width * addr;
for (unsigned idx = 0 ; idx < width ; idx += 1)
bits[base+idx] = val[idx];
call_list_(addr);
}
void vvm_memory_t::get_word(unsigned addr, vvm_bitset_t&val) const
{
if (addr >= size) {
for (unsigned idx = 0 ; idx < width ; idx += 1)
val[idx] = StX;
return;
}
unsigned base = width * addr;
for (unsigned idx = 0 ; idx < width ; idx += 1)
val[idx] = bits[base+idx];
}
void vvm_memory_t::set_callback(vvm_ram_callback*ram)
{
ram->next_ = cb_list_;
cb_list_ = ram;
}
void vvm_memory_t::call_list_(unsigned idx)
{
for (vvm_ram_callback*cur = cb_list_; cur; cur = cur->next_)
cur->handle_write(idx);
}
vvm_memory_t::assign_nb::assign_nb(vvm_memory_t&m, unsigned i,
const vvm_bitset_t&v)
: mem_(m), index_(i), bits_(new vpip_bit_t[m.width]), val_(bits_, m.width)
{
unsigned top = m.width;
if (top > v.nbits)
top = v.nbits;
for (unsigned idx = 0 ; idx < top ; idx += 1)
val_[idx] = v[idx];
for (unsigned idx = top ; idx < m.width ; idx += 1)
val_[idx] = St0;
}
vvm_memory_t::assign_nb::~assign_nb()
{
delete[]bits_;
}
void vvm_memory_t::assign_nb::event_function()
{
mem_.set_word(index_, val_);
}
/*
* $Log: vvm_memory.cc,v $
* Revision 1.4 2002/08/12 01:35:07 steve
* conditional ident string using autoconfig.
*
* Revision 1.3 2001/07/25 03:10:50 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
*
* Revision 1.2 2000/12/15 21:54:43 steve
* Allow non-blocking assign to pad memory word with zeros.
*
* Revision 1.1 2000/12/15 20:05:16 steve
* Fix memory access in vvm. (PR#70)
*
*/
-219
View File
@@ -1,219 +0,0 @@
/*
* Copyright (c) 2000 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: vvm_mult.cc,v 1.8 2002/08/12 01:35:07 steve Exp $"
#endif
# include "config.h"
# include "vvm_gates.h"
# include <assert.h>
static void add_into_result(vpip_bit_t *r, unsigned nr,
const vpip_bit_t *a, unsigned na) {
unsigned idx;
vpip_bit_t carry_bit = St0;
for (idx = 0; idx < nr && idx < na; idx++) {
vpip_bit_t val;
val = B_XOR(B_XOR(a[idx], r[idx]), carry_bit);
carry_bit = B_OR(B_OR(B_AND(a[idx], r[idx]),
B_AND(a[idx], carry_bit)),
B_AND(r[idx], carry_bit));
r[idx] = val;
}
}
static void vvm_binop_mult_generic(vpip_bit_t*r, unsigned nr,
const vpip_bit_t*a, unsigned na,
const vpip_bit_t*b, unsigned nb) {
unsigned idx;
for (idx = 0 ; idx < na ; idx += 1)
if (B_ISXZ(a[idx]))
goto unknown_result;
for (idx = 0 ; idx < nb ; idx += 1)
if (B_ISXZ(b[idx]))
goto unknown_result;
// Start off initialized to 0...
for (idx = 0 ; idx < nr ; idx += 1)
r[idx] = St0;
for (idx = 0; idx < nb && idx < nr; idx++)
if (B_IS1(b[idx]))
add_into_result(r+idx, nr-idx, a, na);
return;
unknown_result:
for (unsigned idx= 0 ; idx < nr ; idx += 1)
r[idx] = StX;
}
void vvm_binop_mult(vpip_bit_t*r, unsigned nr,
const vpip_bit_t*a, unsigned na,
const vpip_bit_t*b, unsigned nb)
{
if (nr > 8*sizeof(unsigned long) ||
na > 8*sizeof(unsigned long) ||
nb > 8*sizeof(unsigned long)) {
// If we can't use the fast routine, default to
// the slow one...
vvm_binop_mult_generic(r, nr, a, na, b, nb);
return;
}
assert(nr <= 8*sizeof(unsigned long));
assert(na <= 8*sizeof(unsigned long));
assert(nb <= 8*sizeof(unsigned long));
unsigned long av = 0, bv = 0;
unsigned long rv;
for (unsigned idx = 0 ; idx < na ; idx += 1) {
if (B_ISXZ(a[idx]))
goto unknown_result;
if (B_IS1(a[idx]))
av |= 1 << idx;
}
for (unsigned idx = 0 ; idx < nb ; idx += 1) {
if (B_ISXZ(b[idx]))
goto unknown_result;
if (B_IS1(b[idx]))
bv |= 1 << idx;
}
rv = av * bv;
for (unsigned idx = 0 ; idx < nr ; idx += 1) {
if (rv & 1)
r[idx] = St1;
else
r[idx] = St0;
rv >>= 1;
}
return;
unknown_result:
for (unsigned idx= 0 ; idx < nr ; idx += 1)
r[idx] = StX;
}
vvm_mult::vvm_mult(unsigned rwid, unsigned awid,
unsigned bwid, unsigned swid)
: rwid_(rwid), awid_(awid), bwid_(bwid), swid_(swid)
{
bits_ = new vpip_bit_t[rwid_+awid_+bwid_+swid_];
out_ = new vvm_nexus::drive_t[rwid_];
for (unsigned idx = 0 ; idx < rwid_+awid_+bwid_+swid_ ; idx += 1)
bits_[idx] = StX;
}
vvm_mult::~vvm_mult()
{
delete[]bits_;
delete[]out_;
}
vvm_nexus::drive_t* vvm_mult::config_rout(unsigned idx)
{
assert(idx < rwid_);
return out_+idx;
}
unsigned vvm_mult::key_DataA(unsigned idx) const
{
assert(idx < awid_);
return rwid_ + idx;
}
void vvm_mult::init_DataA(unsigned idx, vpip_bit_t val)
{
assert(idx < awid_);
bits_[rwid_+idx] = val;
}
unsigned vvm_mult::key_DataB(unsigned idx) const
{
assert(idx < bwid_);
return rwid_+awid_+idx;
}
void vvm_mult::init_DataB(unsigned idx, vpip_bit_t val)
{
assert(idx < bwid_);
bits_[rwid_+awid_+idx] = val;
}
void vvm_mult::take_value(unsigned key, vpip_bit_t val)
{
bits_[key] = val;
vvm_binop_mult(bits_, rwid_,
bits_+rwid_, awid_,
bits_+rwid_+awid_, bwid_);
for (unsigned idx = 0 ; idx < rwid_ ; idx += 1)
out_[idx].set_value(bits_[idx]);
}
/*
* $Log: vvm_mult.cc,v $
* Revision 1.8 2002/08/12 01:35:07 steve
* conditional ident string using autoconfig.
*
* Revision 1.7 2001/07/25 03:10:50 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
*
* Revision 1.6 2000/04/21 02:30:40 steve
* Generic multiplier (Chris Lattner)
*
* Revision 1.5 2000/03/22 04:26:41 steve
* Replace the vpip_bit_t with a typedef and
* define values for all the different bit
* values, including strengths.
*
* Revision 1.4 2000/03/17 03:05:13 steve
* Update vvm_mult to nexus style.
*
* Revision 1.3 2000/03/04 01:13:54 steve
* Simpler implementation of multiplication.
*
* Revision 1.2 2000/02/23 02:56:57 steve
* Macintosh compilers do not support ident.
*
* Revision 1.1 2000/01/13 03:35:36 steve
* Multiplication all the way to simulation.
*
*/
-171
View File
@@ -1,171 +0,0 @@
/*
* Copyright (c) 2000 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: vvm_mux.cc,v 1.4 2002/08/12 01:35:07 steve Exp $"
#endif
# include "config.h"
# include "vvm_gates.h"
# include <assert.h>
/*
* The array of bits is arranged as:
*
* oooo ss 0000 1111 2222 3333 ...
*
*/
vvm_mux::vvm_mux(unsigned w, unsigned s, unsigned sw)
: width_(w), size_(s), selwid_(sw)
{
bits_ = new vpip_bit_t[width_*size_+selwid_+width_];
out_ = new vvm_nexus::drive_t[width_];
for (unsigned idx = 0 ; idx < width_*size_+selwid_+width_ ; idx += 1)
bits_[idx] = StX;
}
vvm_mux::~vvm_mux()
{
delete[]out_;
delete[]bits_;
}
vvm_nexus::drive_t* vvm_mux::config_rout(unsigned idx)
{
assert(idx < width_);
return out_+idx;
}
unsigned vvm_mux::key_Sel(unsigned idx) const
{
assert(idx < selwid_);
return idx + width_;
}
unsigned vvm_mux::key_Data(unsigned wi, unsigned si) const
{
assert(si < size_);
assert(wi < width_);
return width_ + selwid_ + si*width_ + wi;
}
void vvm_mux::init_Sel(unsigned idx, vpip_bit_t val)
{
assert(idx < selwid_);
bits_[width_+idx] = val;
}
void vvm_mux::init_Data(unsigned idx, vpip_bit_t val)
{
assert(idx < width_*size_);
bits_[width_+selwid_+idx] = val;
}
void vvm_mux::take_value(unsigned key, vpip_bit_t val)
{
if (bits_[key] == val)
return;
bits_[key] = val;
evaluate_();
}
void vvm_mux::evaluate_()
{
vpip_bit_t*tmp = new vpip_bit_t[width_];
vpip_bit_t*sel = bits_+width_;
vpip_bit_t*inp = bits_+width_+selwid_;
compute_mux(tmp, width_, sel, selwid_, inp, size_);
for (unsigned idx = 0 ; idx < width_ ; idx += 1)
if (tmp[idx] != bits_[idx]) {
bits_[idx] = tmp[idx];
out_[idx].set_value(bits_[idx]);
}
delete[]tmp;
}
void compute_mux(vpip_bit_t*out, unsigned wid,
const vpip_bit_t*sel, unsigned swid,
const vpip_bit_t*dat, unsigned size)
{
unsigned tmp = 0;
for (unsigned idx = 0 ; idx < swid ; idx += 1) {
if (B_ISXZ(sel[idx])) {
tmp = size;
break;
}
if (B_IS1(sel[idx]))
tmp |= (1<<idx);
}
if (tmp >= size) {
if (swid > 1) {
for (unsigned idx = 0; idx < wid ; idx += 1)
out[idx] = StX;
} else {
const unsigned b0 = 0;
const unsigned b1 = wid;
for (unsigned idx = 0 ; idx < wid ; idx += 1) {
if (dat[idx+b0] == dat[idx+b1])
out[idx] = dat[idx+b0];
else
out[idx] = StX;
}
}
} else {
unsigned b = tmp * wid;
for (unsigned idx = 0; idx < wid ; idx += 1)
out[idx] = dat[idx+b];
}
}
/*
* $Log: vvm_mux.cc,v $
* Revision 1.4 2002/08/12 01:35:07 steve
* conditional ident string using autoconfig.
*
* Revision 1.3 2001/07/25 03:10:50 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
*
* Revision 1.2 2000/03/22 04:26:41 steve
* Replace the vpip_bit_t with a typedef and
* define values for all the different bit
* values, including strengths.
*
* Revision 1.1 2000/03/18 01:27:00 steve
* Generate references into a table of nexus objects instead of
* generating lots of isolated nexus objects. Easier on linkers
* and compilers,
*
* Add missing nexus support for l-value bit selects,
*
* Detemplatize the vvm_mux type.
*
* Fix up the vvm_nexus destructor to disconnect from drivers.
*
*/
-386
View File
@@ -1,386 +0,0 @@
/*
* Copyright (c) 2000 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: vvm_nexus.cc,v 1.13 2002/08/12 01:35:07 steve Exp $"
#endif
# include "config.h"
# include "vvm_nexus.h"
# include "vvm_gates.h"
# include <assert.h>
vvm_nexus::vvm_nexus()
{
drivers_ = 0;
recvrs_ = 0;
ival_ = 0;
nival_ = 0;
value_ = 0;
force_ = 0;
forcer_ = 0;
forcer_key_ = 0;
assigner_ = 0;
assigner_key_ = 0;
resolution_function = &vvm_resolution_wire;
}
vvm_nexus::~vvm_nexus()
{
while (drivers_) {
drive_t*cur = drivers_;
drivers_ = cur->next_;
assert(cur->nexus_ == this);
cur->nexus_ = 0;
cur->next_ = 0;
}
/* assert(recvrs_ == 0); XXXX I really should make a point to
guarantee that all the receivers that I refer to are gone,
but since I know for now that this destructor is only
called when the simulation exist, nevermind. */
}
/*
* Connect a driver to this nexus. The driver needs to know who I am
* (and can only be connected to one nexus) and also I need to keep a
* list of all the drivers connected to me. Arranging the list
* pointers accordingly. Also, keep track of the number of drivers I
* have connected to me, and maintain the ival_ array so that I do not
* need to manage the array at run time.
*/
void vvm_nexus::connect(vvm_nexus::drive_t*drv)
{
// Link the driver into my list of drivers.
assert(drv->nexus_ == 0);
drv->nexus_ = this;
drv->next_ = drivers_;
drivers_ = drv;
nival_ += 1;
if (ival_) delete[]ival_;
ival_ = new vpip_bit_t[nival_];
}
/*
* Connect this receiver to me. Receivers are handled a little
* differently from drivers, a receiver is fully specified by the
* pointer to the receiver AS WELL AS a magic key value. This allows a
* gate to me a receiver with many different input pins.
*/
void vvm_nexus::connect(vvm_nexus::recvr_t*rcv, unsigned key)
{
recvr_cell*cur = new recvr_cell;
cur->dev = rcv;
cur->key = key;
cur->next = recvrs_;
recvrs_ = cur;
}
void vvm_nexus::disconnect(vvm_nexus::drive_t*drv)
{
drive_t*cur = drivers_;
drivers_ = 0;
while (cur) {
drive_t*tmp = cur;
cur = cur->next_;
if (tmp != drv) {
tmp->next_ = drivers_;
drivers_ = tmp;
}
}
}
/*
* This method disconnects a receiver completely by removing every
* access to it. (Remember that a recvr_t object may be connected many
* times with different keys.)
*/
void vvm_nexus::disconnect(vvm_nexus::recvr_t*rcv)
{
recvr_cell*cur = recvrs_;
recvrs_ = 0;
while (cur) {
recvr_cell*tmp = cur;
cur = tmp->next;
if (tmp->dev == rcv) {
delete tmp;
} else {
tmp->next = recvrs_;
recvrs_ = tmp;
}
}
}
/*
* Reg assign (or procedural assignment) does not use the concept of
* drivers. Instead, I skip the resolution function, save the value
* for myself and pass the value to the receivers.
*/
void vvm_nexus::reg_assign(vpip_bit_t val)
{
assert(drivers_ == 0);
value_ = val;
if (forcer_)
return;
for (recvr_cell*cur = recvrs_; cur ; cur = cur->next)
cur->dev->take_value(cur->key, value_);
}
void vvm_nexus::force_set(vvm_force*f, unsigned k)
{
if (forcer_)
forcer_->release(forcer_key_);
forcer_ = f;
forcer_key_ = k;
}
void vvm_nexus::cassign_set(vvm_force*f, unsigned k)
{
assert(drivers_ == 0);
if (assigner_)
assigner_->release(assigner_key_);
assigner_ = f;
assigner_key_ = k;
}
void vvm_nexus::force_assign(vpip_bit_t val)
{
assert(forcer_);
force_ = val;
for (recvr_cell*cur = recvrs_; cur ; cur = cur->next)
cur->dev->take_value(cur->key, force_);
}
void vvm_nexus::cassign(vpip_bit_t val)
{
assert(assigner_);
value_ = val;
if (forcer_) return;
for (recvr_cell*cur = recvrs_; cur ; cur = cur->next)
cur->dev->take_value(cur->key, value_);
}
void vvm_nexus::release()
{
if (forcer_) {
forcer_->release(forcer_key_);
forcer_ = 0;
}
/* Now deliver that output value to all the receivers
connected to this nexus. */
for (recvr_cell*cur = recvrs_; cur ; cur = cur->next)
cur->dev->take_value(cur->key, value_);
}
void vvm_nexus::deassign()
{
assert(drivers_ == 0);
if (assigner_) {
assigner_->release(assigner_key_);
assigner_ = 0;
}
}
/*
* This method is invoked when something interesting happens at one of
* the drivers. It collects all the driver values, resolves them into
* a signal value, and passed them to all the connected
* receivers. This is the workhorse of the nexus object.
*/
void vvm_nexus::run_values()
{
/* Collect the values from all the signal drivers. We should
have exactly the right size ival_ array for the number of
drives. */
unsigned idx = 0;
for (drive_t*cur = drivers_; cur ; cur = cur->next_) {
assert(idx < nival_);
ival_[idx++] = cur->peek_value();
}
assert(idx == nival_);
/* Use the resolution function to generate the settled value
for this nexus. */
vpip_bit_t val = resolution_function(ival_, nival_);
if (value_ == val) return;
value_ = val;
if (forcer_)
return;
/* Now deliver that output value to all the receivers
connected to this nexus. */
for (recvr_cell*cur = recvrs_; cur ; cur = cur->next)
cur->dev->take_value(cur->key, value_);
}
vvm_nexus::drive_t::drive_t()
{
value_ = StX;
nexus_ = 0;
}
vvm_nexus::drive_t::~drive_t()
{
if (nexus_) nexus_->disconnect(this);
}
vpip_bit_t vvm_nexus::drive_t::peek_value() const
{
return value_;
}
void vvm_nexus::drive_t::set_value(vpip_bit_t val)
{
if (val == value_) return;
value_ = val;
if (nexus_) nexus_->run_values();
}
vvm_nexus::recvr_t::recvr_t()
{
}
vvm_nexus::recvr_t::~recvr_t()
{
}
vpip_bit_t vvm_resolution_wire(const vpip_bit_t*bits, unsigned nbits)
{
if (nbits == 0) return HiZ;
return vpip_bits_resolve(bits, nbits);
}
vpip_bit_t vvm_resolution_sup0(const vpip_bit_t*, unsigned)
{
return Su0;
}
vpip_bit_t vvm_resolution_sup1(const vpip_bit_t*, unsigned)
{
return Su1;
}
vpip_bit_t vvm_resolution_tri0(const vpip_bit_t*bits, unsigned nbits)
{
if (nbits == 0) return Pu0;
vpip_bit_t res = vpip_bits_resolve(bits, nbits);
if (B_ISZ(res)) return Pu0;
return res;
}
vpip_bit_t vvm_resolution_tri1(const vpip_bit_t*bits, unsigned nbits)
{
if (nbits == 0) return Pu1;
vpip_bit_t res = vpip_bits_resolve(bits, nbits);
if (B_ISZ(res)) return Pu1;
return res;
}
class delayed_assign_event : public vvm_event {
public:
delayed_assign_event(vvm_nexus&l, vpip_bit_t r)
: l_val_(l), r_val_(r) { }
void event_function() { l_val_.reg_assign(r_val_); }
private:
vvm_nexus& l_val_;
vpip_bit_t r_val_;
};
void vvm_delayed_assign(vvm_nexus&l_val, vpip_bit_t r_val,
unsigned long delay)
{
delayed_assign_event*ev = new delayed_assign_event(l_val, r_val);
ev->schedule(delay);
}
/*
* $Log: vvm_nexus.cc,v $
* Revision 1.13 2002/08/12 01:35:07 steve
* conditional ident string using autoconfig.
*
* Revision 1.12 2001/07/25 03:10:50 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
*
* Revision 1.11 2000/11/20 00:58:40 steve
* Add support for supply nets (PR#17)
*
* Revision 1.10 2000/10/23 00:32:48 steve
* Nexus value is initially unknown so that it propogates for sure.
*
* Revision 1.9 2000/08/02 00:57:03 steve
* tri01 support in vvm.
*
* Revision 1.8 2000/05/11 23:37:28 steve
* Add support for procedural continuous assignment.
*
* Revision 1.7 2000/04/23 03:45:25 steve
* Add support for the procedural release statement.
*
* Revision 1.6 2000/04/22 04:20:20 steve
* Add support for force assignment.
*
* Revision 1.5 2000/03/22 05:16:38 steve
* Integrate drive resolution function.
*
* Revision 1.4 2000/03/22 04:26:41 steve
* Replace the vpip_bit_t with a typedef and
* define values for all the different bit
* values, including strengths.
*
* Revision 1.3 2000/03/18 01:27:00 steve
* Generate references into a table of nexus objects instead of
* generating lots of isolated nexus objects. Easier on linkers
* and compilers,
*
* Add missing nexus support for l-value bit selects,
*
* Detemplatize the vvm_mux type.
*
* Fix up the vvm_nexus destructor to disconnect from drivers.
*
* Revision 1.2 2000/03/16 21:45:07 steve
* Properly initialize driver and nexus values.
*
* Revision 1.1 2000/03/16 19:03:04 steve
* Revise the VVM backend to use nexus objects so that
* drivers and resolution functions can be used, and
* the t-vvm module doesn't need to write a zillion
* output functions.
*
*/

Some files were not shown because too many files have changed in this diff Show More