Compare commits

...
162 Commits
Author SHA1 Message Date
steve 6854660e18 v0.8 is its own directory. 2004-10-13 22:08:10 +00:00
steve 6818d996ea Version stamps for 0.8 2004-10-13 22:01:34 +00:00
steve 4907776eaa Prepare for snapshot 20041004 2004-10-04 18:46:26 +00:00
steve 51dd41f81a Fix excessive error message. 2004-10-04 03:09:38 +00:00
steve e4ae832153 Clean up spurious trailing white space. 2004-10-04 01:10:51 +00:00
steve b3a3428b9a Clean up bin32 files. 2004-10-04 01:09:07 +00:00
steve 2abdcfcaa4 Error message to match assertion. 2004-10-04 00:25:46 +00:00
steve 526b87cae3 Remove inaccurate comment. 2004-10-04 00:25:18 +00:00
steve 9383b165a4 MTI functions only user Mersene Twister 2004-10-04 00:14:08 +00:00
steve e827f8f8c1 Cleanup and factoring of autoconf. 2004-09-27 22:34:10 +00:00
steve 965d928430 More carefull about eliding bufzs that carry strength. 2004-09-25 21:04:25 +00:00
steve 96936456da Add a debug_elaborate flag 2004-09-25 01:58:44 +00:00
steve 94647be1f0 Some commentary on ivl_logic_pin. 2004-09-25 01:58:12 +00:00
steve e45230061e Dump tri0 and tri1 nets. 2004-09-25 01:57:33 +00:00
steve 180bfc5e72 Detect and prevent implicit declaration of hierarchical names. 2004-09-24 04:25:19 +00:00
steve 6d40326a2f Fix LPM GE to match LPM GT behavior. 2004-09-22 16:44:07 +00:00
steve 0a630b60dd Fix make check for pristine sources. 2004-09-18 01:59:44 +00:00
steve 1e4ffc292d Snapshot 20040915 2004-09-16 03:24:28 +00:00
steve a579114ae2 net_output handles l-value concatenations. 2004-09-16 03:17:33 +00:00
steve 8dfe16f6d2 Parse attributes attached to reg declarations. 2004-09-14 18:24:56 +00:00
steve d1dac0017d Fix the evaluation of constant ternary expressions. 2004-09-10 23:51:42 +00:00
steve 5e627c9adc Compile cleanup of C code. 2004-09-10 23:13:05 +00:00
steve 98ba641e67 Remove bad casts. 2004-09-10 00:15:45 +00:00
steve a70dd79cd8 Missing stdio.h header for warnings. 2004-09-10 00:15:17 +00:00
steve a8ee786036 Relaxed width constraint on pad_expression output. 2004-09-10 00:14:31 +00:00
steve d16e8f7c94 Macros can have null values. 2004-09-06 03:01:48 +00:00
steve 4148a2a44c Better type safety. 2004-09-05 21:29:07 +00:00
steve 5f38591676 Better type safety. 2004-09-05 21:19:51 +00:00
steve c10e572091 Support degenerat wait statements. 2004-09-05 21:07:26 +00:00
steve 1ab8879100 Fix syntax for $period to allow min:Ltyp:max expressions. 2004-09-05 21:01:51 +00:00
steve 2d498363d7 Handle instance array of port-less modules. 2004-09-05 18:09:47 +00:00
steve 15059bbfdc More acurate note about system functions. 2004-09-05 17:54:22 +00:00
steve 9de786fc44 Add support for module instance arrays. 2004-09-05 17:44:41 +00:00
steve 62cffe16f4 PR1026: assignment statements can have sensitivities in the l-values. 2004-09-04 04:24:15 +00:00
steve d3eb53e6b1 Better rule for install of system.sft. 2004-08-30 17:42:53 +00:00
steve b631e6e704 Snapshot 20040828 2004-08-28 16:50:26 +00:00
steve ba3790dc2b .net range values can be signed. 2004-08-28 16:26:41 +00:00
steve f02f5be3cc Fix use of system tasks in AT_STAR statements. 2004-08-28 16:23:05 +00:00
steve 7f67afe9d5 Add support for $unsigned. 2004-08-28 15:42:11 +00:00
steve d76ad25778 Do not change reg to wire in NetAssign_ unless synthesizing. 2004-08-28 15:08:31 +00:00
steve 21ba781604 More detailed error message about bad variable. 2004-08-28 14:59:44 +00:00
steve 95c8115fc7 Add support for localparam ranges. 2004-08-26 04:02:03 +00:00
steve 49366d1334 Add the $is_signed function. 2004-08-26 03:51:51 +00:00
steve e2b94947f5 Fix read count passed to fgets. 2004-08-24 16:16:23 +00:00
steve efe05a77cb nex_output for NetPDelay statements. 2004-06-30 15:32:18 +00:00
steve 8bf434754f Propagate source line number in synthetic delay statements. 2004-06-30 15:32:02 +00:00
steve 491df9c327 Watch out for real compared to constant. Handle as real. 2004-06-30 03:07:32 +00:00
steve fca2e64808 Dump variable type of system function. 2004-06-30 03:05:04 +00:00
steve 6cd7c1a650 Some explination of vpi_func arguments. 2004-06-30 03:00:36 +00:00
steve 3dbc07f34d Implement signed divide and signed right shift in nets. 2004-06-30 02:16:26 +00:00
steve 57b8ca191f Add signed LPM divide. 2004-06-30 02:15:57 +00:00
steve 9ee0210cac Code cleanup from Larry. 2004-06-24 15:22:23 +00:00
steve 69cfdbdc54 Fix broken calcuation of NE for constant. 2004-06-22 18:41:48 +00:00
steve 76c0fe459c Only pad the width of vector r-values. 2004-06-20 15:59:06 +00:00
steve 9ba1177a4d Generate signed modulus if appropriate. 2004-06-19 16:17:37 +00:00
steve 51fd249d8a Watch type of mak bit matches masked value. 2004-06-19 16:17:02 +00:00
steve 050ec6f325 Add signed modulus operator. 2004-06-19 15:52:53 +00:00
steve 03d7448550 compare-to-constant uses sig len, not val len. 2004-06-18 16:38:22 +00:00
steve b3529d8593 Help system function signedness survive elaboration. 2004-06-17 16:06:18 +00:00
steve 112368c7de Add a .sft file for the system functions. 2004-06-17 14:47:22 +00:00
steve d1f0a0b0d7 Save seed in static variable, in case user doesnt pass it. 2004-06-17 14:44:01 +00:00
steve b043445c80 Generate .cmp/eq nodes instead of sea of gates. 2004-06-16 23:33:42 +00:00
steve fd371a3958 Handle equality compare to constants specially. 2004-06-16 23:32:58 +00:00
steve 35619771dd Add structural equality compare nodes. 2004-06-16 16:33:25 +00:00
steve bdc6cb8723 Dump NE LPM device. 2004-06-16 16:22:04 +00:00
steve 2d63705093 Connect rsif of multiply to DataB. 2004-06-16 16:21:34 +00:00
steve b108167441 rdynamic for openbsd. 2004-06-13 16:27:17 +00:00
steve 9949040285 Add support for the default_nettype directive. 2004-06-13 04:56:53 +00:00
steve e8e0cd7cab Support / and % in synthesized contexts. 2004-06-12 15:00:02 +00:00
steve f2d4966634 Fix transcription error scaling c in uniform range. 2004-06-10 02:14:42 +00:00
steve 50bf2095df Move Mersenne Twister to $mti_random, and make
the standard $random standard. Also, add $dist_poisson.
2004-06-09 22:14:10 +00:00
steve 2003c5a21e Fix build order of vvp and vpi. 2004-06-09 22:13:43 +00:00
steve bfd393c91c Remove extra sub-make of vpi directory. 2004-06-09 22:13:14 +00:00
steve 37ae777111 Update to snapshot 20040606 2004-06-06 14:51:58 +00:00
steve dd69872266 Special case for unary - of real literal. 2004-06-04 23:34:15 +00:00
steve fbfc796647 Add unary minus as operator supported by verireal. 2004-06-04 23:33:51 +00:00
steve 8d3102388b Pick sign bit from the right place in the exponent number. 2004-06-04 23:26:34 +00:00
steve ba309e60bb Fix synthesis method for logical and/or 2004-06-01 01:04:57 +00:00
steve 5472b27e1f Rewire/generalize parsing an elaboration of
function return values to allow for better
 speed and more type support.
2004-05-31 23:34:36 +00:00
steve e7fa56981a More identifier lists use perm_strings. 2004-05-25 19:21:06 +00:00
steve 55ba131997 Handle wait with constant-false expression. 2004-05-25 03:42:58 +00:00
steve 559f73c135 Attach line numbers to wait statements. 2004-05-25 03:42:44 +00:00
steve b97f9448e0 Add support for the -I compiler flag. 2004-05-20 00:40:34 +00:00
steve a7ae8adf9b Support delayed/non-blocking assignment to reals and others. 2004-05-19 03:26:24 +00:00
steve 896f1b0de1 Generate code for nb assign to reals. 2004-05-19 03:25:42 +00:00
steve ca55cadc6c Add ivl_target support for non-blocking assign of real. 2004-05-19 03:18:40 +00:00
steve 324ba713e5 Handle explicit set of unsigned long width. For -m32 2004-05-18 18:45:11 +00:00
steve 69ebd0c49e Allow vpiParamter as a string type. 2004-05-18 18:43:38 +00:00
steve d60112d58b Handle null string as a single nul character. 2004-05-18 18:43:15 +00:00
steve 5807d6912e Protect ident pragma. 2004-03-17 17:07:12 +00:00
steve ec0e35b940 Treat cygwin like Unix for build purposes. 2004-03-17 17:06:44 +00:00
steve c8d67b904a Only include DEBUG_SYNTH2 if __FUNCTION__ defined. 2004-03-15 18:40:12 +00:00
steve c55adddb69 Assume struct initializers are GCC specific. 2004-03-15 18:35:37 +00:00
steve 8e63f56caf standard conpliant stdio.h. 2004-03-13 05:12:36 +00:00
steve 9e223b9696 Clean up rules for iverilog-vpi vs driver-vpi. 2004-03-11 06:13:58 +00:00
steve dd7472d125 Mingw needs -liberty, but Cygwin cannot tolerate it. 2004-03-11 06:06:59 +00:00
steve 0ef1ecab5e Verbose details for sft parsing. 2004-03-11 06:02:58 +00:00
steve 28719e8584 Add support for system function table files. 2004-03-10 04:51:24 +00:00
steve a0ed5e9e29 Separate out the lookup_sys_func table, for eventual
support for function type tables.

 Remove ipal compile flags.
2004-03-09 04:29:42 +00:00
steve 20b7a23bde Define function types. 2004-03-09 04:29:26 +00:00
steve 33783385d2 Get vpiModule of signals. 2004-03-09 03:11:02 +00:00
steve 914746f6f3 Minor spelling fixes. 2004-03-08 02:33:49 +00:00
steve c6453a0854 primitive ports can bind bi name. 2004-03-08 00:47:44 +00:00
steve 413932e406 Verilog2001 new style port declartions for primitives. 2004-03-08 00:10:29 +00:00
steve 9531920685 MOre thorough use of elab_and_eval function. 2004-03-07 20:04:10 +00:00
steve 4456937274 Snapshot 20040220 2004-02-21 01:39:58 +00:00
steve efef8fba85 Add load command to interactive stop.
Support decimal constants passed interactive to system tasks.
2004-02-21 00:44:34 +00:00
steve 177b6ffb6a Addtrbute keys are perm_strings. 2004-02-20 18:53:33 +00:00
steve 1295058e5d parameter keys are per_strings. 2004-02-20 06:22:56 +00:00
steve b5b02269f1 unused variable warning. 2004-02-20 03:20:04 +00:00
steve 60adfb845d Do not strip leading spaces, or expect them either. 2004-02-20 01:53:02 +00:00
steve a4c5ff0bd3 vpiStringVal does not include leading nulls. 2004-02-20 01:52:25 +00:00
steve 72f9dc5094 Add the $fgets function. 2004-02-19 21:33:13 +00:00
steve 65f09337f6 Add sysfunctype to calltf structure. 2004-02-19 21:32:46 +00:00
steve 8d2858c555 vpiStringVal writes need to set all the bits of a reg. 2004-02-19 21:31:59 +00:00
steve 89acc41437 LPM, logic and Variables have perm_string names. 2004-02-19 07:06:57 +00:00
steve 536068bdfb Memory and Event names use perm_string. 2004-02-19 06:57:10 +00:00
steve 2d7380c03b PRototypes match the standard. 2004-02-18 17:52:00 +00:00
steve 27af95d402 Use perm_strings for named langiage items. 2004-02-18 17:11:54 +00:00
steve 17c891bc9c Fix type mismatches of various VPI functions. 2004-02-18 02:51:59 +00:00
steve 38ec4b7851 Support unsigned divide of huge numbers. 2004-02-17 06:52:55 +00:00
steve 6f9ebb1e60 Add the $dumpflush function 2004-02-15 20:46:01 +00:00
steve 0fd5a79760 Cleanup of warnings. 2004-02-15 18:03:30 +00:00
steve 4288f3c6d0 Better error checking of primitive tables. 2004-02-15 17:48:28 +00:00
steve d64295ed65 primitives support reg output name syntax. 2004-02-15 17:48:16 +00:00
steve 2f8a40b159 Fix evaluation of compare to constant expression. 2004-02-15 04:23:48 +00:00
steve 081a6a4088 Cleanup configure detection of win32. 2004-02-15 03:17:36 +00:00
steve c971448760 dumpfile selects file at compiletf time. 2004-02-15 03:17:15 +00:00
steve c275ef9482 Report elaboration errors without crashing. 2004-02-15 00:19:29 +00:00
steve 8188c4c690 Makefile cleanup. 2004-02-10 19:25:00 +00:00
steve d482e341ae Fix direction of Q/D signals of FD devices. 2004-02-10 16:39:33 +00:00
steve f2b9b8946f Snapshot 20040209 2004-02-09 21:29:05 +00:00
steve fa4a873628 Add support for lxt2 break size 2004-02-06 18:23:30 +00:00
steve a436bfc711 Include from current directory. 2004-01-28 23:54:10 +00:00
steve c2ab27541f Make sure I get ivl_target.h from this source. 2004-01-26 23:31:57 +00:00
steve 5160021b48 Make sure file64 support is on cc -D flags. 2004-01-26 21:52:46 +00:00
steve f349449a49 Honor default format of numbers. 2004-01-23 23:40:44 +00:00
steve de7f87853d Generate error when missing concatenation operands. 2004-01-21 04:57:40 +00:00
steve 6a02613fca Get rid of useless warning. 2004-01-21 04:35:03 +00:00
steve 3bb408faf2 Add support for initialization assign in port list declaration of reg. 2004-01-21 03:37:12 +00:00
steve 4987970af4 Give the vip directory its own configure and vpi_config.h 2004-01-21 01:22:51 +00:00
steve d98720af4d Isolate configure from containing config.h 2004-01-20 21:00:47 +00:00
steve 793493d3ff Snapshot 20040118 2004-01-19 00:10:58 +00:00
steve 36785997cb Improve the gperf warning message. 2004-01-18 23:34:00 +00:00
steve 923a3ea537 The is_combinational function really need not recurse. 2004-01-18 23:26:54 +00:00
steve 8aca824c0f Further unify the configure.in scripts. 2004-01-15 20:52:32 +00:00
steve e6b25a4e20 Get the NEED_LU define right for win32. 2004-01-15 06:05:20 +00:00
steve d98b7ffb2e Remove duplicate NetEvProbe objects in nodangle. 2004-01-15 06:04:19 +00:00
steve e617e4a98c Handle wide expressions in wait condition. 2004-01-13 03:42:49 +00:00
steve 1970e41041 Get value for vpoiConstType correct. 2004-01-13 02:55:50 +00:00
steve e331b182a7 Synthesis debug messages. 2003-12-20 00:59:31 +00:00
steve 11b0cc5bf3 More thorough check that NetEvWait is asynchronous. 2003-12-20 00:33:39 +00:00
steve 5b0c7be6b7 Add ANSI style parameter port declarations. 2003-12-19 05:15:04 +00:00
steve 59ac435c71 Fix various unsigned compare warnings. 2003-12-19 01:27:10 +00:00
steve 57c3e86084 Debug dumps for synth2. 2003-12-17 16:52:39 +00:00
steve f0e0377a20 Add acc_set_scope function. 2003-12-17 15:45:07 +00:00
steve ae3198b505 Install target gets vvp.conf that is built, not from srcdir. 2003-12-12 19:58:40 +00:00
steve d4525ddc16 Some systems dlsym requires leading _ or not on whim. 2003-12-12 05:43:08 +00:00
steve 19e8a92729 Fix make check to support -tconf configuration method. 2003-12-12 04:36:48 +00:00
steve 1bd1d287e4 tfname can be constant. 2003-12-07 20:06:24 +00:00
steve 4c8c14ceec Ducument lxt2 access. 2003-12-07 20:05:56 +00:00
steve df968687e4 Generate VVP_EXECUTABLE flag in conf files. 2003-12-07 19:28:43 +00:00
257 changed files with 8714 additions and 4874 deletions
+8 -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: Attrib.cc,v 1.5 2002/08/12 01:34:58 steve Exp $"
#ident "$Id: Attrib.cc,v 1.6 2004/02/20 18:53:33 steve Exp $"
#endif
# include "config.h"
@@ -36,25 +36,8 @@ Attrib::~Attrib()
delete[] list_;
}
#if 0
void Attrib::copy_attributes(const map<string,verinum>&attr)
{
assert(list_ == 0);
nlist_ = attr.size();
list_ = new cell_[nlist_];
map<string,verinum>::const_iterator idx;
unsigned jdx;
for (idx = attr.begin(), jdx = 0 ; idx != attr.end() ; idx ++, jdx++) {
struct cell_*tmp = list_ + jdx;
tmp->key = (*idx).first;
tmp->val = (*idx).second;
}
}
#endif
const verinum& Attrib::attribute(const string&key) const
const verinum& Attrib::attribute(perm_string key) const
{
for (unsigned idx = 0 ; idx < nlist_ ; idx += 1) {
@@ -66,7 +49,7 @@ const verinum& Attrib::attribute(const string&key) const
return null;
}
void Attrib::attribute(const string&key, const verinum&value)
void Attrib::attribute(perm_string key, const verinum&value)
{
unsigned idx;
@@ -108,10 +91,10 @@ unsigned Attrib::attr_cnt() const
return nlist_;
}
const char* Attrib::attr_key(unsigned idx) const
perm_string Attrib::attr_key(unsigned idx) const
{
assert(idx < nlist_);
return list_[idx].key.c_str();
return list_[idx].key;
}
const verinum& Attrib::attr_value(unsigned idx) const
@@ -123,6 +106,9 @@ const verinum& Attrib::attr_value(unsigned idx) const
/*
* $Log: Attrib.cc,v $
* Revision 1.6 2004/02/20 18:53:33 steve
* Addtrbute keys are perm_strings.
*
* Revision 1.5 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
+9 -6
View File
@@ -19,10 +19,10 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: Attrib.h,v 1.4 2002/08/12 01:34:58 steve Exp $"
#ident "$Id: Attrib.h,v 1.5 2004/02/20 18:53:33 steve Exp $"
#endif
# include <string>
# include "StringHeap.h"
# include "verinum.h"
/*
@@ -35,20 +35,20 @@ class Attrib {
Attrib();
~Attrib();
const verinum&attribute(const string&key) const;
void attribute(const string&key, const verinum&value);
const verinum&attribute(perm_string key) const;
void attribute(perm_string key, const verinum&value);
bool has_compat_attributes(const Attrib&that) const;
/* Provide a means of iterating over the entries in the map. */
unsigned attr_cnt() const;
const char* attr_key(unsigned idx) const;
perm_string attr_key(unsigned idx) const;
const verinum& attr_value(unsigned idx) const;
private:
struct cell_ {
string key;
perm_string key;
verinum val;
};
@@ -62,6 +62,9 @@ class Attrib {
/*
* $Log: Attrib.h,v $
* Revision 1.5 2004/02/20 18:53:33 steve
* Addtrbute keys are perm_strings.
*
* Revision 1.4 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
+21 -29
View File
@@ -16,7 +16,7 @@
# 59 Temple Place - Suite 330
# Boston, MA 02111-1307, USA
#
#ident "$Id: Makefile.in,v 1.160 2003/11/26 01:36:55 steve Exp $"
#ident "$Id: Makefile.in,v 1.169 2004/10/13 22:01:34 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.7
VERSION = 0.8
prefix = @prefix@
exec_prefix = @exec_prefix@
@@ -43,7 +43,6 @@ mandir = @mandir@
libdir64 = @libdir64@
dllib=@DLLIB@
rdynamic=@rdynamic@
strip_dynamic=@strip_dynamic@
CC = @CC@
@@ -56,23 +55,20 @@ STRIP = @STRIP@
LEX = @LEX@
YACC = @YACC@
CPPFLAGS = @CPPFLAGS@ @DEFS@
CXXFLAGS = @CXXFLAGS@ -I. -I$(srcdir)
CPPFLAGS = @ident_support@ @DEFS@ -I. -I$(srcdir) @CPPFLAGS@
CXXFLAGS = -Wall @CXXFLAGS@
PICFLAGS = @PICFLAG@
LDFLAGS = @LDFLAGS@
LDFLAGS = @rdynamic@ @LDFLAGS@
# The TARGETS variable lists the target modules that can be build and
# installed. Some of them depend on external things, so are only
# compiled if the prerequisites are installed.
TARGETS = tgt-null
ifeq ('@HAVE_IPAL@','yes')
TARGETS += tgt-pal
endif
all: dep ivl@EXEEXT@
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) $@); done
for tgt in $(TARGETS); do (cd $$tgt ; $(MAKE) $@); done
for dir in vpi ivlpp tgt-verilog tgt-stub; \
for dir in ivlpp tgt-verilog tgt-stub; \
do (cd $$dir ; $(MAKE) $@); done
cd driver ; $(MAKE) VERSION=$(VERSION) $@
@@ -82,20 +78,14 @@ ifeq (@WIN32@,yes)
all: dep dosify.exe
dosify.exe: dosify.c
$(CC) -o dosify.exe dosify.c
ifeq (@MINGW32@,yes)
SUBDIRS += driver-vpi
endif
else
all: dep iverilog-vpi
endif
# This rule rules the compiler in the trivial hello.vl program to make
# sure the basics were compiled properly.
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
test -r check.conf || cp $(srcdir)/check.conf .
driver/iverilog -B. -BPivlpp -tcheck -ocheck.vvp $(srcdir)/examples/hello.vl
vvp/vvp -M- -M./vpi ./check.vvp | grep 'Hello, World'
clean:
@@ -103,7 +93,7 @@ clean:
for tgt in $(TARGETS); do (cd $$tgt ; $(MAKE) $@); done
for dir in vpi ivlpp tgt-verilog tgt-stub driver; \
do (cd $$dir ; $(MAKE) $@); done
rm -f *.o parse.cc parse.cc.output parse.h lexor.cc
rm -f *.o parse.cc parse.cc.output parse.h lexor.cc
rm -f lexor_keyword.cc libivl.a libvpi.a iverilog-vpi syn-rules.cc*
rm -rf dep ivl@EXEEXT@
@@ -126,7 +116,7 @@ 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 net_variable.o pad_to_width.o \
parse.o parse_misc.o pform.o pform_dump.o \
set_width.o symbol_search.o sync.o \
set_width.o symbol_search.o sync.o sys_funcs.o \
verinum.o verireal.o target.o targets.o \
Attrib.o HName.o LineInfo.o Module.o PData.o PDelays.o PEvent.o \
PExpr.o PGate.o \
@@ -143,19 +133,21 @@ ifeq (@WIN32@,yes)
# export and import library, and the last link makes a, ivl.exe
# that really exports the things that the import library imports.
ivl@EXEEXT@: $O ivl.def
$(CXX) -o ivl@EXEEXT@ $O $(dllib) @EXTRALIBS@
$(CXX) -o ivl@EXEEXT@ $O $(dllib) @EXTRALIBS@
dlltool --dllname ivl@EXEEXT@ --def ivl.def \
--output-lib libivl.a --output-exp ivl.exp
$(CXX) -o ivl@EXEEXT@ ivl.exp $O $(dllib) @EXTRALIBS@
$(CXX) -o ivl@EXEEXT@ ivl.exp $O $(dllib) @EXTRALIBS@
else
ivl@EXEEXT@: $O
$(CXX) $(CXXFLAGS) $(rdynamic) $(LDFLAGS) -o ivl@EXEEXT@ $O $(dllib)
$(CXX) $(LDFLAGS) -o ivl@EXEEXT@ $O $(dllib)
endif
ifeq (@WIN32@,yes)
ifeq (@MINGW32@,yes)
SUBDIRS += driver-vpi
else
all: dep iverilog-vpi
iverilog-vpi: iverilog-vpi.sh
sed -e 's;@SHARED@;@shared@;' -e 's;@PIC@;@PICFLAG@;' \
-e 's;@INCLUDEDIR@;@includedir@;' \
@@ -169,7 +161,7 @@ dep:
mkdir dep
%.o: %.cc
$(CXX) -Wall @ident_support@ $(CPPFLAGS) $(CXXFLAGS) -MD -c $< -o $*.o
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -MD -c $< -o $*.o
mv $*.d dep/$*.d
@@ -209,7 +201,7 @@ INSTALL_DOC = $(mandir)/man1/iverilog-vpi.1
INSTALL_DOCDIR = $(mandir)/man1
endif
ifeq (@WIN32@,yes)
ifeq (@MINGW32@,yes)
WIN32_INSTALL = $(prefix)/hello.vl $(prefix)/sqrt.vl $(prefix)/sqrt-virtex.v $(prefix)/QUICK_START.txt
else
WIN32_INSTALL = $(bindir)/iverilog-vpi
@@ -259,7 +251,7 @@ $(prefix)/iverilog-vpi.pdf: iverilog-vpi.pdf
# In windows installations, put a few examples and the quick_start
# into the destination directory.
ifeq (@WIN32@,yes)
ifeq (@MINGW32@,yes)
$(prefix)/hello.vl: $(srcdir)/examples/hello.vl
./dosify.exe $(srcdir)/examples/hello.vl tmp.vl
mv tmp.vl $(prefix)/hello.vl
+20 -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: Module.cc,v 1.21 2003/04/02 03:00:14 steve Exp $"
#ident "$Id: Module.cc,v 1.25 2004/10/04 01:10:51 steve Exp $"
#endif
# include "config.h"
@@ -28,9 +28,10 @@
# include <assert.h>
/* n is a permallocated string. */
Module::Module(const char*n)
Module::Module(perm_string n)
: name_(n)
{
default_nettype = NetNet::NONE;
}
Module::~Module()
@@ -42,12 +43,12 @@ void Module::add_gate(PGate*gate)
gates_.push_back(gate);
}
void Module::add_task(const string&name, PTask*task)
void Module::add_task(perm_string name, PTask*task)
{
tasks_[name] = task;
}
void Module::add_function(const string &name, PFunction *func)
void Module::add_function(perm_string name, PFunction *func)
{
funcs_[name] = func;
}
@@ -75,7 +76,7 @@ unsigned Module::port_count() const
/*
* Return the array of PEIdent object that are at this port of the
* module. If the port is internally unconnected, return an empty
* array.
* array.
*/
const svector<PEIdent*>& Module::get_port(unsigned idx) const
{
@@ -88,7 +89,7 @@ const svector<PEIdent*>& Module::get_port(unsigned idx) const
return zero;
}
unsigned Module::find_port(const string&name) const
unsigned Module::find_port(const char*name) const
{
assert(name != "");
for (unsigned idx = 0 ; idx < ports.count() ; idx += 1) {
@@ -118,7 +119,7 @@ PWire* Module::get_wire(const hname_t&name) const
return (*obj).second;
}
PGate* Module::get_gate(const string&name)
PGate* Module::get_gate(perm_string name)
{
for (list<PGate*>::iterator cur = gates_.begin()
; cur != gates_.end()
@@ -149,6 +150,18 @@ const list<PProcess*>& Module::get_behaviors() const
/*
* $Log: Module.cc,v $
* Revision 1.25 2004/10/04 01:10:51 steve
* Clean up spurious trailing white space.
*
* Revision 1.24 2004/06/13 04:56:53 steve
* Add support for the default_nettype directive.
*
* Revision 1.23 2004/02/20 06:22:56 steve
* parameter keys are per_strings.
*
* Revision 1.22 2004/02/18 17:11:54 steve
* Use perm_strings for named langiage items.
*
* Revision 1.21 2003/04/02 03:00:14 steve
* Cope with empty module ports while binding by name.
*
+36 -19
View File
@@ -1,7 +1,7 @@
#ifndef __Module_H
#define __Module_H
/*
* Copyright (c) 1998-2000 Stephen Williams ([email protected])
* Copyright (c) 1998-2004 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
@@ -19,16 +19,17 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: Module.h,v 1.32 2003/06/20 00:53:19 steve Exp $"
#ident "$Id: Module.h,v 1.37 2004/06/13 04:56:53 steve Exp $"
#endif
# include <list>
# include <map>
# include "svector.h"
# include "StringHeap.h"
# include "HName.h"
# include "named.h"
# include "LineInfo.h"
# include <string>
# include "netlist.h"
class PData;
class PEvent;
class PExpr;
@@ -56,16 +57,17 @@ class Module : public LineInfo {
the port. */
public:
struct port_t {
string name;
perm_string name;
svector<PEIdent*> expr;
};
public:
/* The name passed here is the module name, not the instance
name. This make must be a permallocated string. */
explicit Module(const char*name);
explicit Module(perm_string name);
~Module();
NetNet::Type default_nettype;
/* The module has parameters that are evaluated when the
module is elaborated. During parsing, I put the parameters
@@ -76,14 +78,14 @@ class Module : public LineInfo {
PExpr*lsb;
bool signed_flag;
};
map<string,param_expr_t>parameters;
map<string,param_expr_t>localparams;
map<perm_string,param_expr_t>parameters;
map<perm_string,param_expr_t>localparams;
/* specparams are simpler then other params, in that they have
no type information. They are merely constant
expressions. */
map<string,PExpr*>specparams;
map<perm_string,PExpr*>specparams;
/* The module also has defparam assignments which don't create
new parameters within the module, but may be used to set
@@ -97,25 +99,25 @@ class Module : public LineInfo {
appear in the instantiated module. Therefore a
list of names in module-order is needed to pass from
a parameter-index to its name. */
list<string> param_names;
list<perm_string> param_names;
/* This is an array of port descriptors, which is in turn a
named array of PEident pointers. */
svector<port_t*> ports;
/* Keep a table of named events declared in the module. */
map<string,PEvent*>events;
map<perm_string,PEvent*>events;
/* Keep a table of datum variables declared in the module. */
map<hname_t,PData*>datum;
map<string,PExpr*> attributes;
map<perm_string,PExpr*> attributes;
/* These are the timescale for this module. The default is
set by the `timescale directive. */
int time_unit, time_precision;
const char*mod_name() const { return name_; }
perm_string mod_name() const { return name_; }
void add_gate(PGate*gate);
@@ -125,17 +127,17 @@ class Module : public LineInfo {
PWire* add_wire(PWire*wire);
void add_behavior(PProcess*behave);
void add_task(const string&name, PTask*def);
void add_function(const string&name, PFunction*def);
void add_task(perm_string name, PTask*def);
void add_function(perm_string name, PFunction*def);
unsigned port_count() const;
const svector<PEIdent*>& get_port(unsigned idx) const;
unsigned find_port(const string&) const;
unsigned find_port(const char*name) const;
// Find a wire by name. This is used for connecting gates to
// existing wires, etc.
PWire* get_wire(const hname_t&name) const;
PGate* get_gate(const string&name);
PGate* get_gate(perm_string name);
const map<hname_t,PWire*>& get_wires() const;
const list<PGate*>& get_gates() const;
@@ -149,13 +151,13 @@ class Module : public LineInfo {
bool elaborate_sig(Design*, NetScope*scope) const;
private:
const char* name_;
perm_string name_;
map<hname_t,PWire*> wires_;
list<PGate*> gates_;
list<PProcess*> behaviors_;
map<string,PTask*> tasks_;
map<string,PFunction*> funcs_;
map<perm_string,PTask*> tasks_;
map<perm_string,PFunction*> funcs_;
private: // Not implemented
Module(const Module&);
@@ -165,6 +167,21 @@ class Module : public LineInfo {
/*
* $Log: Module.h,v $
* Revision 1.37 2004/06/13 04:56:53 steve
* Add support for the default_nettype directive.
*
* Revision 1.36 2004/05/25 19:21:06 steve
* More identifier lists use perm_strings.
*
* Revision 1.35 2004/02/20 18:53:33 steve
* Addtrbute keys are perm_strings.
*
* Revision 1.34 2004/02/20 06:22:56 steve
* parameter keys are per_strings.
*
* Revision 1.33 2004/02/18 17:11:54 steve
* Use perm_strings for named langiage items.
*
* Revision 1.32 2003/06/20 00:53:19 steve
* Module attributes from the parser
* through to elaborated form.
+7 -4
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2003 Stephen Williams ([email protected])
* Copyright (c) 2004 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,14 +17,14 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: PEvent.cc,v 1.4 2003/03/01 06:25:30 steve Exp $"
#ident "$Id: PEvent.cc,v 1.5 2004/02/19 06:57:10 steve Exp $"
#endif
# include "config.h"
# include "PEvent.h"
PEvent::PEvent(const char*n)
PEvent::PEvent(perm_string n)
: name_(n)
{
}
@@ -33,13 +33,16 @@ PEvent::~PEvent()
{
}
const char* PEvent::name() const
perm_string PEvent::name() const
{
return name_;
}
/*
* $Log: PEvent.cc,v $
* Revision 1.5 2004/02/19 06:57:10 steve
* Memory and Event names use perm_string.
*
* Revision 1.4 2003/03/01 06:25:30 steve
* Add the lex_strings string handler, and put
* scope names and system task/function names
+11 -6
View File
@@ -1,7 +1,7 @@
#ifndef __PEvent_H
#define __PEvent_H
/*
* Copyright (c) 2000 Stephen Williams ([email protected])
* Copyright (c) 2000-2004 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
@@ -19,10 +19,11 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: PEvent.h,v 1.8 2003/03/01 06:25:30 steve Exp $"
#ident "$Id: PEvent.h,v 1.9 2004/02/19 06:57:10 steve Exp $"
#endif
# include "LineInfo.h"
# include "StringHeap.h"
# include <string>
class Design;
@@ -36,16 +37,17 @@ class NetScope;
class PEvent : public LineInfo {
public:
// The name is a perm-allocated string.
explicit PEvent(const char*name);
// The name is a perm-allocated string. It is the simple name
// of the event, without any scope.
explicit PEvent(perm_string name);
~PEvent();
const char* name() const;
perm_string name() const;
void elaborate_scope(Design*des, NetScope*scope) const;
private:
const char* name_;
perm_string name_;
private: // not implemented
PEvent(const PEvent&);
@@ -54,6 +56,9 @@ class PEvent : public LineInfo {
/*
* $Log: PEvent.h,v $
* Revision 1.9 2004/02/19 06:57:10 steve
* Memory and Event names use perm_string.
*
* Revision 1.8 2003/03/01 06:25:30 steve
* Add the lex_strings string handler, and put
* scope names and system task/function names
+19 -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: PExpr.cc,v 1.33 2003/01/27 05:09:17 steve Exp $"
#ident "$Id: PExpr.cc,v 1.35 2004/10/04 01:10:51 steve Exp $"
#endif
# include "config.h"
@@ -67,12 +67,12 @@ bool PEBinary::is_constant(Module*mod) const
return left_->is_constant(mod) && right_->is_constant(mod);
}
PECallFunction::PECallFunction(const hname_t&n, const svector<PExpr *> &parms)
PECallFunction::PECallFunction(const hname_t&n, const svector<PExpr *> &parms)
: path_(n), parms_(parms)
{
}
PECallFunction::PECallFunction(const hname_t&n)
PECallFunction::PECallFunction(const hname_t&n)
: path_(n)
{
}
@@ -161,13 +161,19 @@ bool PEIdent::is_constant(Module*mod) const
{
if (mod == 0) return false;
{ map<string,Module::param_expr_t>::const_iterator cur;
cur = mod->parameters.find(path_.peek_name(0));
/* This is a work-around for map not matching < even when
there is a perm_string operator that can do the comprare.
The real fix is to make the path_ carry perm_strings. */
perm_string tmp = perm_string::literal(path_.peek_name(0));
{ map<perm_string,Module::param_expr_t>::const_iterator cur;
cur = mod->parameters.find(tmp);
if (cur != mod->parameters.end()) return true;
}
{ map<string,Module::param_expr_t>::const_iterator cur;
cur = mod->localparams.find(path_.peek_name(0));
{ map<perm_string,Module::param_expr_t>::const_iterator cur;
cur = mod->localparams.find(tmp);
if (cur != mod->localparams.end()) return true;
}
@@ -256,6 +262,12 @@ bool PEUnary::is_constant(Module*m) const
/*
* $Log: PExpr.cc,v $
* Revision 1.35 2004/10/04 01:10:51 steve
* Clean up spurious trailing white space.
*
* Revision 1.34 2004/02/20 06:22:56 steve
* parameter keys are per_strings.
*
* Revision 1.33 2003/01/27 05:09:17 steve
* Spelling fixes.
*
+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: PExpr.h,v 1.65 2003/02/08 19:49:21 steve Exp $"
#ident "$Id: PExpr.h,v 1.66 2004/10/04 01:10:51 steve Exp $"
#endif
# include <string>
@@ -160,7 +160,7 @@ class PEEvent : public PExpr {
edge_t type() const;
PExpr* expr() const;
virtual void dump(ostream&) const;
private:
@@ -492,6 +492,9 @@ class PECallFunction : public PExpr {
/*
* $Log: PExpr.h,v $
* Revision 1.66 2004/10/04 01:10:51 steve
* Clean up spurious trailing white space.
*
* Revision 1.65 2003/02/08 19:49:21 steve
* Calculate delay statement delays using elaborated
* expressions instead of pre-elaborated expression
+11 -6
View File
@@ -17,16 +17,17 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: PFunction.cc,v 1.6 2002/08/12 01:34:58 steve Exp $"
#ident "$Id: PFunction.cc,v 1.7 2004/05/31 23:34:36 steve Exp $"
#endif
# include "config.h"
#include "PTask.h"
PFunction::PFunction()
: out_(0), ports_(0), statement_(0)
PFunction::PFunction(perm_string name)
: name_(name), ports_(0), statement_(0)
{
return_type_.type = PTF_NONE;
}
PFunction::~PFunction()
@@ -46,14 +47,18 @@ void PFunction::set_statement(Statement*s)
statement_ = s;
}
void PFunction::set_output(PWire*o)
void PFunction::set_return(PTaskFuncArg t)
{
assert(out_ == 0);
out_ = o;
return_type_ = t;
}
/*
* $Log: PFunction.cc,v $
* Revision 1.7 2004/05/31 23:34:36 steve
* Rewire/generalize parsing an elaboration of
* function return values to allow for better
* speed and more type support.
*
* Revision 1.6 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
+15 -12
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1999-2000 Stephen Williams ([email protected])
* Copyright (c) 1999-2004 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: PGate.cc,v 1.15 2003/03/06 04:37:12 steve Exp $"
#ident "$Id: PGate.cc,v 1.16 2004/02/18 17:11:54 steve Exp $"
#endif
# include "config.h"
@@ -27,7 +27,7 @@
# include "verinum.h"
# include <assert.h>
PGate::PGate(const string&name,
PGate::PGate(perm_string name,
svector<PExpr*>*pins,
const svector<PExpr*>*del)
: name_(name), pins_(pins)
@@ -37,7 +37,7 @@ PGate::PGate(const string&name,
str1_ = STRONG;
}
PGate::PGate(const string&name,
PGate::PGate(perm_string name,
svector<PExpr*>*pins,
PExpr*del)
: name_(name), pins_(pins)
@@ -47,7 +47,7 @@ PGate::PGate(const string&name,
str1_ = STRONG;
}
PGate::PGate(const string&name, svector<PExpr*>*pins)
PGate::PGate(perm_string name, svector<PExpr*>*pins)
: name_(name), pins_(pins)
{
str0_ = STRONG;
@@ -99,13 +99,13 @@ void PGate::eval_delays(Design*des, NetScope*scope,
}
PGAssign::PGAssign(svector<PExpr*>*pins)
: PGate("", pins)
: PGate(perm_string(), pins)
{
assert(pins->count() == 2);
}
PGAssign::PGAssign(svector<PExpr*>*pins, svector<PExpr*>*dels)
: PGate("", pins, dels)
: PGate(perm_string(), pins, dels)
{
assert(pins->count() == 2);
}
@@ -114,14 +114,14 @@ PGAssign::~PGAssign()
{
}
PGBuiltin::PGBuiltin(Type t, const string&name,
PGBuiltin::PGBuiltin(Type t, perm_string name,
svector<PExpr*>*pins,
svector<PExpr*>*del)
: PGate(name, pins, del), type_(t), msb_(0), lsb_(0)
{
}
PGBuiltin::PGBuiltin(Type t, const string&name,
PGBuiltin::PGBuiltin(Type t, perm_string name,
svector<PExpr*>*pins,
PExpr*del)
: PGate(name, pins, del), type_(t), msb_(0), lsb_(0)
@@ -142,14 +142,14 @@ void PGBuiltin::set_range(PExpr*msb, PExpr*lsb)
lsb_ = lsb;
}
PGModule::PGModule(const char*type, const string&name, svector<PExpr*>*pins)
PGModule::PGModule(perm_string type, perm_string name, svector<PExpr*>*pins)
: PGate(name, pins), overrides_(0), pins_(0),
npins_(0), parms_(0), nparms_(0), msb_(0), lsb_(0)
{
type_ = type;
}
PGModule::PGModule(const char*type, const string&name,
PGModule::PGModule(perm_string type, perm_string name,
named<PExpr*>*pins, unsigned npins)
: PGate(name, 0), overrides_(0), pins_(pins),
npins_(npins), parms_(0), nparms_(0), msb_(0), lsb_(0)
@@ -184,13 +184,16 @@ void PGModule::set_range(PExpr*msb, PExpr*lsb)
lsb_ = lsb;
}
const char* PGModule::get_type()
perm_string PGModule::get_type()
{
return type_;
}
/*
* $Log: PGate.cc,v $
* Revision 1.16 2004/02/18 17:11:54 steve
* Use perm_strings for named langiage items.
*
* Revision 1.15 2003/03/06 04:37:12 steve
* lex_strings.add module names earlier.
*
+30 -18
View File
@@ -1,7 +1,7 @@
#ifndef __PGate_H
#define __PGate_H
/*
* Copyright (c) 1998-2000 Stephen Williams ([email protected])
* Copyright (c) 1998-2004 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
@@ -19,10 +19,11 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: PGate.h,v 1.25 2003/03/06 04:37:12 steve Exp $"
#ident "$Id: PGate.h,v 1.29 2004/10/04 01:10:52 steve Exp $"
#endif
# include "svector.h"
# include "StringHeap.h"
# include "named.h"
# include "LineInfo.h"
# include "PDelays.h"
@@ -49,21 +50,21 @@ class Module;
* strength of the 1 drive.
*/
class PGate : public LineInfo {
public:
enum strength_t { HIGHZ, WEAK, PULL, STRONG, SUPPLY };
explicit PGate(const string&name, svector<PExpr*>*pins,
explicit PGate(perm_string name, svector<PExpr*>*pins,
const svector<PExpr*>*del);
explicit PGate(const string&name, svector<PExpr*>*pins,
explicit PGate(perm_string name, svector<PExpr*>*pins,
PExpr*del);
explicit PGate(const string&name, svector<PExpr*>*pins);
explicit PGate(perm_string name, svector<PExpr*>*pins);
virtual ~PGate();
const string& get_name() const { return name_; }
perm_string get_name() const { return name_; }
void eval_delays(Design*des, NetScope*scope,
unsigned long&rise_time,
@@ -79,7 +80,7 @@ class PGate : public LineInfo {
void strength0(strength_t);
void strength1(strength_t);
map<string,PExpr*> attributes;
map<perm_string,PExpr*> attributes;
virtual void dump(ostream&out) const;
virtual void elaborate(Design*des, NetScope*scope) const;
@@ -87,13 +88,13 @@ class PGate : public LineInfo {
virtual bool elaborate_sig(Design*des, NetScope*scope) const;
protected:
const svector<PExpr*>* get_pins() const { return pins_; }
const svector<PExpr*>& get_pins() const { return *pins_; }
void dump_pins(ostream&out) const;
void dump_delays(ostream&out) const;
private:
const string name_;
perm_string name_;
PDelays delay_;
svector<PExpr*>*pins_;
@@ -141,10 +142,10 @@ class PGBuiltin : public PGate {
TRANIF1, RTRANIF0, RTRANIF1 };
public:
explicit PGBuiltin(Type t, const string&name,
explicit PGBuiltin(Type t, perm_string name,
svector<PExpr*>*pins,
svector<PExpr*>*del);
explicit PGBuiltin(Type t, const string&name,
explicit PGBuiltin(Type t, perm_string name,
svector<PExpr*>*pins,
PExpr*del);
~PGBuiltin();
@@ -171,17 +172,16 @@ class PGBuiltin : public PGate {
class PGModule : public PGate {
public:
// NOTE: The type parameter to all the constructors is assumed
// to have been permallocated.
// The name is the *instance* name of the gate.
// If the binding of ports is by position, this constructor
// builds everything all at once.
explicit PGModule(const char*type, const string&name,
explicit PGModule(perm_string type, perm_string name,
svector<PExpr*>*pins);
// If the binding of ports is by name, this constructor takes
// the bindings and stores them for later elaboration.
explicit PGModule(const char*type, const string&name,
explicit PGModule(perm_string type, perm_string name,
named<PExpr*>*pins, unsigned npins);
@@ -203,10 +203,10 @@ class PGModule : public PGate {
// This returns the module name of this module. It is a
// permallocated string.
const char* get_type();
perm_string get_type();
private:
const char* type_;
perm_string type_;
svector<PExpr*>*overrides_;
named<PExpr*>*pins_;
unsigned npins_;
@@ -227,6 +227,18 @@ class PGModule : public PGate {
/*
* $Log: PGate.h,v $
* Revision 1.29 2004/10/04 01:10:52 steve
* Clean up spurious trailing white space.
*
* Revision 1.28 2004/03/08 00:47:44 steve
* primitive ports can bind bi name.
*
* Revision 1.27 2004/02/20 18:53:33 steve
* Addtrbute keys are perm_strings.
*
* Revision 1.26 2004/02/18 17:11:54 steve
* Use perm_strings for named langiage items.
*
* Revision 1.25 2003/03/06 04:37:12 steve
* lex_strings.add module names earlier.
*
+28 -4
View File
@@ -19,16 +19,32 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: PTask.h,v 1.12 2002/08/12 01:34:58 steve Exp $"
#ident "$Id: PTask.h,v 1.13 2004/05/31 23:34:36 steve Exp $"
#endif
# include "LineInfo.h"
# include "svector.h"
# include "StringHeap.h"
# include <string>
class Design;
class NetScope;
class PWire;
class Statement;
class PExpr;
enum PTaskFuncEnum {
PTF_NONE,
PTF_REG,
PTF_INTEGER,
PTF_REAL,
PTF_REALTIME,
PTF_TIME
};
struct PTaskFuncArg {
PTaskFuncEnum type;
svector<PExpr*>*range;
};
/*
* The PTask holds the parsed definitions of a task.
@@ -69,16 +85,18 @@ class PTask : public LineInfo {
* The function is similar to a task (in this context) but there is a
* single output port and a set of input ports. The output port is the
* function return value.
*
* The output value is not elaborated until elaborate_sig.
*/
class PFunction : public LineInfo {
public:
explicit PFunction();
explicit PFunction(perm_string name);
~PFunction();
void set_ports(svector<PWire *>*p);
void set_statement(Statement *s);
void set_output(PWire*);
void set_return(PTaskFuncArg t);
void elaborate_scope(Design*des, NetScope*scope) const;
@@ -91,13 +109,19 @@ class PFunction : public LineInfo {
void dump(ostream&, unsigned) const;
private:
PWire*out_;
perm_string name_;
PTaskFuncArg return_type_;
svector<PWire *> *ports_;
Statement *statement_;
};
/*
* $Log: PTask.h,v $
* Revision 1.13 2004/05/31 23:34:36 steve
* Rewire/generalize parsing an elaboration of
* function return values to allow for better
* speed and more type support.
*
* Revision 1.12 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
+20 -3
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2003 Stephen Williams ([email protected])
* Copyright (c) 2003-2004 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,18 +17,35 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: PUdp.cc,v 1.1 2003/07/15 05:07:13 steve Exp $"
#ident "$Id: PUdp.cc,v 1.3 2004/03/08 00:47:44 steve Exp $"
#endif
# include "PUdp.h"
PUdp::PUdp(const string&n, unsigned nports)
PUdp::PUdp(perm_string n, unsigned nports)
: ports(nports), sequential(false), initial(verinum::Vx), name_(n)
{
}
unsigned PUdp::find_port(const char*name)
{
for (unsigned idx = 0 ; idx < ports.count() ; idx += 1) {
if (ports[idx] == name)
return idx;
}
return ports.count();
}
/*
* $Log: PUdp.cc,v $
* Revision 1.3 2004/03/08 00:47:44 steve
* primitive ports can bind bi name.
*
* Revision 1.2 2004/02/18 17:11:54 steve
* Use perm_strings for named langiage items.
*
* Revision 1.1 2003/07/15 05:07:13 steve
* Move PUdp constructor into compiled file.
*
+13 -4
View File
@@ -1,7 +1,7 @@
#ifndef __PUdp_H
#define __PUdp_H
/*
* Copyright (c) 1998-2000 Stephen Williams ([email protected])
* Copyright (c) 1998-2004 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
@@ -19,10 +19,11 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: PUdp.h,v 1.10 2003/07/15 05:07:13 steve Exp $"
#ident "$Id: PUdp.h,v 1.12 2004/03/08 00:47:44 steve Exp $"
#endif
# include <map>
# include "StringHeap.h"
# include "svector.h"
# include "verinum.h"
@@ -52,9 +53,11 @@ class PExpr;
class PUdp {
public:
explicit PUdp(const string&n, unsigned nports);
explicit PUdp(perm_string n, unsigned nports);
svector<string>ports;
unsigned find_port(const char*name);
bool sequential;
svector<string>tinput;
@@ -67,7 +70,7 @@ class PUdp {
void dump(ostream&out) const;
const string name_;
perm_string name_;
private:
private: // Not implemented
@@ -77,6 +80,12 @@ class PUdp {
/*
* $Log: PUdp.h,v $
* Revision 1.12 2004/03/08 00:47:44 steve
* primitive ports can bind bi name.
*
* Revision 1.11 2004/02/18 17:11:54 steve
* Use perm_strings for named langiage items.
*
* Revision 1.10 2003/07/15 05:07:13 steve
* Move PUdp constructor into compiled file.
*
+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.16 2003/01/30 16:23:07 steve Exp $"
#ident "$Id: PWire.h,v 1.17 2004/02/20 18:53:33 steve Exp $"
#endif
# include "netlist.h"
@@ -69,7 +69,7 @@ class PWire : public LineInfo {
void set_memory_idx(PExpr*ldx, PExpr*rdx);
map<string,PExpr*> attributes;
map<perm_string,PExpr*> attributes;
// Write myself to the specified stream.
void dump(ostream&out) const;
@@ -100,6 +100,9 @@ class PWire : public LineInfo {
/*
* $Log: PWire.h,v $
* Revision 1.17 2004/02/20 18:53:33 steve
* Addtrbute keys are perm_strings.
*
* Revision 1.16 2003/01/30 16:23:07 steve
* Spelling fixes.
*
+2 -2
View File
@@ -16,8 +16,8 @@ execute even the most trivial design. For the purposes of simulation,
we use as our example *the* most trivial simulation:
module main;
initial
initial
begin
$display("Hello, World");
$finish ;
+21 -11
View File
@@ -1,5 +1,5 @@
THE ICARUS VERILOG COMPILATION SYSTEM
Copyright 2000-2003 Stephen Williams
THE ICARUS VERILOG COMPILATION SYSTEM
Copyright 2000-2004 Stephen Williams
1.0 What is ICARUS Verilog?
@@ -9,7 +9,7 @@ described in the IEEE-1364 standard. Of course, it's not quite there
yet. It does currently handle a mix of structural and behavioral
constructs. For a view of the current state of Icarus Verilog, see its
home page at <http://www.icarus.com/eda/verilog>.
Icarus Verilog is not aimed at being a simulator in the traditional
sense, but a compiler that generates code employed by back-end
tools. These back-end tools currently include a simulator engine
@@ -296,8 +296,8 @@ Example: Compiling "hello.vl"
------------------------ hello.vl ----------------------------
module main();
initial
initial
begin
$display("Hi there");
$finish ;
@@ -307,7 +307,7 @@ endmodule
--------------------------------------------------------------
Ensure that "iverilog" is on your search path, and the vpi library
Ensure that "iverilog" is on your search path, and the vpi library
is available.
To compile the program:
@@ -334,8 +334,8 @@ Verilog web page for the current state of support for Verilog, and in
particular, browse the bug report database for reported unsupported
constructs.
- System functions are supported, but the compiler presumes that
they return 32 bits. This is the typical case.
- System functions are supported, but the return value is a little
tricky. See SYSTEM FUNCTION TABLE FILES in the iverilog man page.
- Specify blocks are parsed but ignored in general.
@@ -344,9 +344,6 @@ constructs.
- tran primitives, i.e. tran, tranif1, tranif0, rtran, rtranif1
and rtranif0 are not supported.
- Module instance arrays are not supported, although gate instance
arrays do work.
- Net delays, of the form "wire #N foo;" do not work. Delays in
every other context do work properly, including the V2001 form
"wire #5 foo = bar;"
@@ -364,6 +361,11 @@ IEEE1364 standard, but have well defined meaning, and also sometimes
gives nonstandard (but extended) meanings to some features of the
language that are defined.
$is_signed(<expr>)
This system function returns 1 if the expression contained is
signed, or 0 otherwise. This is mostly of use for compiler
regression tests.
$sizeof(<expr>)
$bits(<expr>)
The $bits system function returns the size in bits of the
@@ -387,6 +389,14 @@ language that are defined.
general possible to predict what the simulation precision will
turn out to be.
$mti_random()
$mti_dist_uniform
These functions are similar to the IEEE1364 standard $random
functions, but they use the Mersenne Twister (MT19937)
algorithm. This is considered an excellent random number
generator, but does not generate the same sequence as the
standardized $random.
Builtin system functions
Certain of the system functions have well defined meanings, so
+5 -2
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: Statement.cc,v 1.28 2002/08/12 01:34:58 steve Exp $"
#ident "$Id: Statement.cc,v 1.29 2004/02/18 17:11:54 steve Exp $"
#endif
# include "config.h"
@@ -86,7 +86,7 @@ PAssignNB::~PAssignNB()
{
}
PBlock::PBlock(const string&n, BL_TYPE t, const svector<Statement*>&st)
PBlock::PBlock(perm_string n, BL_TYPE t, const svector<Statement*>&st)
: name_(n), bl_type_(t), list_(st)
{
}
@@ -295,6 +295,9 @@ PWhile::~PWhile()
/*
* $Log: Statement.cc,v $
* Revision 1.29 2004/02/18 17:11:54 steve
* Use perm_strings for named langiage items.
*
* Revision 1.28 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
+11 -4
View File
@@ -19,11 +19,12 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: Statement.h,v 1.38 2003/05/19 02:50:58 steve Exp $"
#ident "$Id: Statement.h,v 1.40 2004/02/20 18:53:33 steve Exp $"
#endif
# include <string>
# include "svector.h"
# include "StringHeap.h"
# include "PDelays.h"
# include "PExpr.h"
# include "HName.h"
@@ -56,7 +57,7 @@ class PProcess : public LineInfo {
Type type() const { return type_; }
Statement*statement() { return statement_; }
map<string,PExpr*> attributes;
map<perm_string,PExpr*> attributes;
virtual void dump(ostream&out, unsigned ind) const;
@@ -148,7 +149,7 @@ class PBlock : public Statement {
public:
enum BL_TYPE { BL_SEQ, BL_PAR };
explicit PBlock(const string&n, BL_TYPE t, const svector<Statement*>&st);
explicit PBlock(perm_string n, BL_TYPE t, const svector<Statement*>&st);
explicit PBlock(BL_TYPE t, const svector<Statement*>&st);
explicit PBlock(BL_TYPE t);
~PBlock();
@@ -161,7 +162,7 @@ class PBlock : public Statement {
virtual void elaborate_scope(Design*des, NetScope*scope) const;
private:
string name_;
perm_string name_;
const BL_TYPE bl_type_;
svector<Statement*>list_;
};
@@ -455,6 +456,12 @@ class PWhile : public Statement {
/*
* $Log: Statement.h,v $
* Revision 1.40 2004/02/20 18:53:33 steve
* Addtrbute keys are perm_strings.
*
* Revision 1.39 2004/02/18 17:11:54 steve
* Use perm_strings for named langiage items.
*
* Revision 1.38 2003/05/19 02:50:58 steve
* Implement the wait statement behaviorally instead of as nets.
*
+63 -2
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2003 Stephen Williams ([email protected])
* Copyright (c) 2002-2004 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: StringHeap.cc,v 1.5 2003/03/01 06:25:30 steve Exp $"
#ident "$Id: StringHeap.cc,v 1.6 2004/02/18 17:11:54 steve Exp $"
#endif
# include "StringHeap.h"
@@ -64,6 +64,11 @@ const char* StringHeap::add(const char*text)
return res;
}
perm_string StringHeap::make(const char*text)
{
return perm_string(add(text));
}
StringHeapLex::StringHeapLex()
{
@@ -121,8 +126,64 @@ const char* StringHeapLex::add(const char*text)
return res;
}
perm_string StringHeapLex::make(const char*text)
{
return perm_string(add(text));
}
perm_string StringHeapLex::make(const string&text)
{
return perm_string(add(text.c_str()));
}
bool operator == (perm_string a, const char*b)
{
if (a.str() == b)
return true;
if (! (a.str() && b))
return false;
if (strcmp(a.str(), b) == 0)
return true;
return false;
}
bool operator == (perm_string a, perm_string b)
{
return a == b.str();
}
bool operator != (perm_string a, const char*b)
{
return ! (a == b);
}
bool operator != (perm_string a, perm_string b)
{
return ! (a == b);
}
bool operator < (perm_string a, perm_string b)
{
if (b.str() && !a.str())
return true;
if (b.str() == a.str())
return false;
if (strcmp(a.str(), b.str()) < 0)
return true;
return false;
}
/*
* $Log: StringHeap.cc,v $
* Revision 1.6 2004/02/18 17:11:54 steve
* Use perm_strings for named langiage items.
*
* Revision 1.5 2003/03/01 06:25:30 steve
* Add the lex_strings string handler, and put
* scope names and system task/function names
+47 -2
View File
@@ -1,7 +1,7 @@
#ifndef __StringHeap_H
#define __StringHeap_H
/*
* Copyright (c) 2002-2003 Stephen Williams ([email protected])
* Copyright (c) 2002-2004 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
@@ -19,9 +19,48 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: StringHeap.h,v 1.4 2003/03/01 06:25:30 steve Exp $"
#ident "$Id: StringHeap.h,v 1.5 2004/02/18 17:11:54 steve Exp $"
#endif
# include "config.h"
# include <string>
class perm_string {
public:
perm_string() : text_(0) { }
perm_string(const perm_string&that) : text_(that.text_) { }
~perm_string() { }
perm_string& operator = (const perm_string&that)
{ text_ = that.text_; return *this; }
const char*str() const { return text_; }
operator const char* () const { return str(); }
// This is an escape for making perm_string objects out of
// literals. For example, per_string::literal("Label"); Please
// do *not* cheat and pass arbitrary const char* items here.
static perm_string literal(const char*t) { return perm_string(t); }
private:
friend class StringHeap;
friend class StringHeapLex;
perm_string(const char*t) : text_(t) { };
private:
const char*text_;
};
extern bool operator == (perm_string a, perm_string b);
extern bool operator == (perm_string a, const char* b);
extern bool operator != (perm_string a, perm_string b);
extern bool operator != (perm_string a, const char* b);
extern bool operator > (perm_string a, perm_string b);
extern bool operator < (perm_string a, perm_string b);
extern bool operator >= (perm_string a, perm_string b);
extern bool operator <= (perm_string a, perm_string b);
/*
* The string heap is a way to permanently allocate strings
* efficiently. They only take up the space of the string characters
@@ -34,6 +73,7 @@ class StringHeap {
~StringHeap();
const char*add(const char*);
perm_string make(const char*);
private:
enum { HEAPCELL = 0x10000 };
@@ -60,6 +100,8 @@ class StringHeapLex : private StringHeap {
~StringHeapLex();
const char*add(const char*);
perm_string make(const char*);
perm_string make(const string&);
unsigned add_count() const;
unsigned add_hit_count() const;
@@ -78,6 +120,9 @@ class StringHeapLex : private StringHeap {
/*
* $Log: StringHeap.h,v $
* Revision 1.5 2004/02/18 17:11:54 steve
* Use perm_strings for named langiage items.
*
* Revision 1.4 2003/03/01 06:25:30 steve
* Add the lex_strings string handler, and put
* scope names and system task/function names
+7 -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: acc_user.h,v 1.19 2003/10/10 02:57:45 steve Exp $"
#ident "$Id: acc_user.h,v 1.20 2003/12/17 15:45:07 steve Exp $"
#endif
/*
@@ -195,6 +195,7 @@ extern void acc_close(void);
* codes that are accepted.
*/
extern int acc_configure(PLI_INT32 config_param, const char*value);
#define accEnableArgs 6
#define accDevelopmentVersion 11
extern int acc_fetch_argc(void);
@@ -258,6 +259,8 @@ extern int acc_object_of_type(handle object, PLI_INT32 type);
extern char*acc_product_version(void);
extern char*acc_set_scope(handle ref, ...);
extern int acc_set_value(handle obj, p_setval_value value,
p_setval_delay delay);
@@ -272,6 +275,9 @@ EXTERN_C_END
/*
* $Log: acc_user.h,v $
* Revision 1.20 2003/12/17 15:45:07 steve
* Add acc_set_scope function.
*
* Revision 1.19 2003/10/10 02:57:45 steve
* Some PLI1 stubs.
*
Vendored
+140 -2
View File
@@ -14,7 +14,7 @@
AC_DEFUN([AX_CPP_IDENT],
[AC_CACHE_CHECK([for ident support in C compiler], ax_cv_cpp_ident,
[AC_TRY_COMPILE([
#ident "$Id: aclocal.m4,v 1.1 2003/11/08 19:27:50 steve Exp $"
#ident "$Id: aclocal.m4,v 1.6 2004/10/04 01:10:52 steve Exp $"
],[while (0) {}],
[AS_VAR_SET(ax_cv_cpp_ident, yes)],
[AS_VAR_SET(ax_cv_cpp_ident, no)])])
@@ -47,7 +47,7 @@ AC_DEFUN([AX_C_UNDERSCORES_LEADING],
[_AX_C_UNDERSCORES_MATCH_IF([_underscore],
[AS_VAR_SET(ax_cv_c_underscores_leading, yes)],
[AS_VAR_SET(ax_cv_c_underscores_leading, no)])])
if test $ax_cv_c_underscores_leading = yes; then
if test $ax_cv_c_underscores_leading = yes -a "$CYGWIN" != "yes" -a "$MINGW32" != "yes"; then
AC_DEFINE(NEED_LU)
fi
])# AX_C_UNDERSCORES_LEADING
@@ -67,3 +67,141 @@ if test $ax_cv_c_underscores_trailing = yes; then
fi
])# AX_C_UNDERSCORES_TRAILING
# AX_WIN32
# --------
# Combined check for several flavors of Microsoft Windows so
# their "issues" can be dealt with
AC_DEFUN([AX_WIN32],
[AC_CYGWIN
AC_MINGW32
WIN32=no
AC_MSG_CHECKING([for Microsoft Windows])
if test "$CYGWIN" = "yes" -o "$MINGW32" = "yes"
then
WIN32=yes
fi
AC_SUBST(MINGW32)
AC_SUBST(WIN32)
AC_MSG_RESULT($WIN32)
])# AX_WIN32
# AX_LD_EXTRALIBS
# ---------------
# mingw needs to link with libiberty.a, but cygwin alone can't tolerate it
AC_DEFUN([AX_LD_EXTRALIBS],
[AC_MSG_CHECKING([for extra libs needed])
EXTRALIBS=
case "${host}" in
*-*-cygwin* )
if test "$MINGW32" = "yes"; then
EXTRALIBS="-liberty"
fi
;;
esac
AC_SUBST(EXTRALIBS)
AC_MSG_RESULT($EXTRALIBS)
])# AX_LD_EXTRALIBS
# AX_LD_SHAREDLIB_OPTS
# --------------------
# linker options when building a shared library
AC_DEFUN([AX_LD_SHAREDLIB_OPTS],
[AC_MSG_CHECKING([for shared library link flag])
shared=-shared
case "${host}" in
*-*-cygwin*)
shared="-shared -Wl,--enable-auto-image-base"
;;
*-*-hpux*)
shared="-b"
;;
*-*-darwin1.[0123])
shared="-bundle -undefined suppress"
;;
*-*-darwin*)
shared="-bundle -undefined suppress -flat_namespace"
;;
esac
AC_SUBST(shared)
AC_MSG_RESULT($shared)
])# AX_LD_SHAREDLIB_OPTS
# AX_C_PICFLAG
# ------------
# The -fPIC flag is used to tell the compiler to make position
# independent code. It is needed when making shared objects.
AC_DEFUN([AX_C_PICFLAG],
[AC_MSG_CHECKING([for flag to make position independent code])
PICFLAG=-fPIC
case "${host}" in
*-*-cygwin*)
PICFLAG=
;;
*-*-hpux*)
PICFLAG=+z
;;
esac
AC_SUBST(PICFLAG)
AC_MSG_RESULT($PICFLAG)
])# AX_C_PICFLAG
# AX_LD_RDYNAMIC
# --------------
# The -rdynamic flag is used by iverilog when compiling the target,
# to know how to export symbols of the main program to loadable modules
# that are brought in by -ldl
AC_DEFUN([AX_LD_RDYNAMIC],
[AC_MSG_CHECKING([for -rdynamic compiler flag])
rdynamic=-rdynamic
case "${host}" in
*-*-netbsd*)
rdynamic="-Wl,--export-dynamic"
;;
*-*-openbsd*)
rdynamic="-Wl,--export-dynamic"
;;
*-*-solaris*)
rdynamic=""
;;
*-*-cygwin*)
rdynamic=""
;;
*-*-hpux*)
rdynamic="-E"
;;
*-*-darwin*)
rdynamic="-Wl,-all_load"
strip_dynamic="-SX"
;;
esac
AC_SUBST(rdynamic)
AC_MSG_RESULT($rdynamic)
AC_SUBST(strip_dynamic)
# since we didn't tell them we're "checking", no good place to tell the answer
# AC_MSG_RESULT($strip_dynamic)
])# AX_LD_RDYNAMIC
# AX_CPP_PRECOMP
# --------------
AC_DEFUN([AX_CPP_PRECOMP],
[# Darwin requires -no-cpp-precomp
case "${host}" in
*-*-darwin*)
CPPFLAGS="-no-cpp-precomp $CPPFLAGS"
CFLAGS="-no-cpp-precomp $CFLAGS"
;;
esac
])# AX_CPP_PRECOMP
+20 -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: async.cc,v 1.5 2003/09/04 20:28:05 steve Exp $"
#ident "$Id: async.cc,v 1.7 2004/01/18 23:26:54 steve Exp $"
#endif
# include "config.h"
@@ -36,6 +36,16 @@ bool NetCondit::is_asynchronous()
return false;
}
/*
* NetEvWait statements come from statements of the form @(...) in the
* Verilog source. These event waits are considered asynchronous if
* all of the events in the list are ANYEDGE, and all the inputs to
* the statement are included in the sensitivity list. If any of the
* events are posedge or negedge, the statement is synchronous
* (i.e. an edge-triggered flip-flop) and if any of the inputs are
* unaccounted for in the sensitivity list then the statement is a
* latch.
*/
bool NetEvWait::is_asynchronous()
{
/* The "sense" set contains the set of Nexa that are in the
@@ -64,6 +74,9 @@ bool NetEvWait::is_asynchronous()
delete sense;
delete inputs;
/* If it passes all the other tests, then this statement is
asynchronous. */
return true;
}
@@ -82,6 +95,12 @@ bool NetProcTop::is_asynchronous()
/*
* $Log: async.cc,v $
* Revision 1.7 2004/01/18 23:26:54 steve
* The is_combinational function really need not recurse.
*
* Revision 1.6 2003/12/20 00:33:39 steve
* More thorough check that NetEvWait is asynchronous.
*
* Revision 1.5 2003/09/04 20:28:05 steve
* Support time0 resolution of combinational threads.
*
+2 -2
View File
@@ -9,10 +9,10 @@
echo "Autoconf in root..."
autoconf
for dir in vpip vvp tgt-vvp tgt-fpga libveriuser cadpli
for dir in vpip vpi vvp tgt-vvp tgt-fpga libveriuser cadpli
do
echo "Autoconf in $dir..."
( cd ./$dir ; autoconf )
( cd ./$dir ; autoconf --include=.. )
done
echo "Precompiling lexor_keyword.gperf"
+6 -7
View File
@@ -16,7 +16,7 @@
# 59 Temple Place - Suite 330
# Boston, MA 02111-1307, USA
#
#ident "$Id: Makefile.in,v 1.8 2003/11/08 19:30:15 steve Exp $"
#ident "$Id: Makefile.in,v 1.11 2004/10/04 01:09:07 steve Exp $"
#
#
SHELL = /bin/sh
@@ -38,13 +38,12 @@ vpidir = @libdir@/ivl/@vpidir1@
strip_dynamic=@strip_dynamic@
CC = @CC@
CXX = @CXX@
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
CPPFLAGS = @CPPFLAGS@ @DEFS@ @PICFLAG@
CFLAGS = @CFLAGS@
CPPFLAGS = @ident_support@ -I$(srcdir) -I$(srcdir)/.. -I.. @CPPFLAGS@ @DEFS@ @PICFLAG@
CFLAGS = -Wall @CFLAGS@
LDFLAGS = @LDFLAGS@
STRIP = @STRIP@
@@ -69,21 +68,21 @@ dep:
mkdir dep
%.o: %.c
$(CC) -Wall -I$(srcdir) -I$(srcdir)/.. -I.. $(CPPFLAGS) $(CFLAGS) -MD -c $<
$(CC) $(CPPFLAGS) $(CFLAGS) -MD -c $<
mv $*.d dep
O = cadpli.o
SYSTEM_VPI_LDFLAGS = -L../vvp -lvpi
ifeq (@WIN32@,yes)
SYSTEM_VPI_LDFLAGS += -liberty
SYSTEM_VPI_LDFLAGS += @EXTRALIBS@
endif
cadpli.vpl: $O ../vvp/libvpi.a ../libveriuser/libveriuser.o
$(CC) @shared@ -o $@ $O ../libveriuser/libveriuser.o $(SYSTEM_VPI_LDFLAGS)
clean:
rm -rf *.o dep cadpli.vpl
rm -rf *.o dep cadpli.vpl bin32
distclean: clean
rm -f Makefile config.status config.log config.cache
+8 -2
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: cadpli.c,v 1.5 2003/08/26 16:26:02 steve Exp $"
#ident "$Id: cadpli.c,v 1.7 2004/09/10 00:15:45 steve Exp $"
#endif
# include <vpi_user.h>
@@ -37,7 +37,7 @@ static void thunker_register(void)
struct t_vpi_vlog_info vlog_info;
void*mod;
void*boot;
void*tf;
struct t_tfcell*tf;
int idx;
vpi_get_vlog_info(&vlog_info);
@@ -91,6 +91,12 @@ void (*vlog_startup_routines[])() = {
/*
* $Log: cadpli.c,v $
* Revision 1.7 2004/09/10 00:15:45 steve
* Remove bad casts.
*
* Revision 1.6 2004/09/05 21:19:51 steve
* Better type safety.
*
* Revision 1.5 2003/08/26 16:26:02 steve
* ifdef idents correctly.
*
+14 -161
View File
@@ -4,11 +4,12 @@ AC_PROG_CC
AC_PROG_CXX
AC_CHECK_TOOL(STRIP, strip, true)
AC_CYGWIN
AC_EXEEXT
AC_MINGW32
AC_SUBST(EXEEXT)
# Combined check for Microsoft-related bogosities; sets WIN32 if found
AX_WIN32
AC_PROG_INSTALL
# vvp32 is by default disabled
@@ -34,180 +35,32 @@ AC_CHECK_LIB(dld,shl_load,[DLLIB=-ldld])
fi
AC_SUBST(DLLIB)
AX_CPP_PRECOMP
# Darwin requires -no-cpp-precomp
case "${host}" in
*-*-darwin*)
CPPFLAGS="-no-cpp-precomp $CPPFLAGS"
CFLAGS="-no-cpp-precomp $CFLAGS"
;;
esac
# Compiler option for position independent code, needed whan making shared objects.
AX_C_PICFLAG
# The -fPIC flag is used to tell the compiler to make position
# independent code. It is needed when making shared objects.
# Linker option used when compiling the target
AX_LD_RDYNAMIC
AC_MSG_CHECKING("for flag to make position independent code")
PICFLAG=-fPIC
case "${host}" in
# linker options when building a shared library
AX_LD_SHAREDLIB_OPTS
*-*-cygwin*)
PICFLAG=
;;
*-*-hpux*)
PICFLAG=+z
;;
esac
AC_SUBST(PICFLAG)
AC_MSG_RESULT($PICFLAG)
# The -rdynamic flag is used by iverilog when compiling the target,
# to know how to export symbols of the main program to loadable modules
# that are brought in by -ldl. VPI support requires this.
AC_MSG_CHECKING("for -rdynamic compiler flag")
rdynamic=-rdynamic
case "${host}" in
*-*-netbsd*)
rdynamic="-Wl,--export-dynamic"
;;
*-*-solaris*)
rdynamic=""
;;
*-*-cygwin*)
rdynamic=""
;;
*-*-hpux*)
rdynamic="-E"
;;
*-*-darwin*)
rdynamic="-Wl,-all_load"
;;
esac
AC_SUBST(rdynamic)
AC_MSG_RESULT($rdynamic)
AC_MSG_CHECKING("for shared library link flag")
shared=-shared
case "${host}" in
*-*-cygwin*)
shared="-shared -Wl,--enable-auto-image-base"
;;
*-*-hpux*)
shared="-b"
;;
*-*-darwin1.[0123])
shared="-bundle -undefined suppress"
;;
*-*-darwin*)
shared="-bundle -undefined suppress -flat_namespace"
;;
esac
AC_SUBST(shared)
AC_MSG_RESULT($shared)
AC_MSG_CHECKING("for extra libs needed")
EXTRALIBS=
case "${host}" in
*-*-cygwin*)
EXTRALIBS="-liberty"
;;
esac
AC_SUBST(EXTRALIBS)
AC_MSG_RESULT($EXTRALIBS)
AX_LD_EXTRALIBS
#######################
## test for underscores. The vpi module loader in vvm needs to know this
## in order to know the name of the start symbol for the .vpi module.
#######################
AC_CYGWIN
AC_EXEEXT
AC_MINGW32
WIN32=no
AC_MSG_CHECKING("Checking for windows")
if test "$CYGWIN" = "yes" -o "$MINGW32" = "yes"
then
WIN32=yes
fi
AC_SUBST(WIN32)
AC_MSG_RESULT($WIN32)
AC_SUBST(EXEEXT)
AC_MSG_CHECKING("for leading and/or trailing underscores")
cat << EOF > underscore.c
void underscore(void){}
EOF
$CC -shared -c underscore.c > /dev/null 2>&1
CC_LEADING_UNDERSCORE=no
CC_TRAILING_UNDERSCORE=no
output=`nm underscore.o|grep _underscore 2>&1`
if test ! -z "$output" -a "$CYGWIN" != "yes" -a "$MINGW32" != "yes"; then
CC_LEADING_UNDERSCORE=yes
AC_DEFINE(NEED_LU)
fi
output=`nm underscore.o|grep underscore_ 2>&1`
if test ! -z "$output"; then
CC_TRAILING_UNDERSCORE=yes
AC_DEFINE(NEED_TU)
fi
if test "$CC_LEADING_UNDERSCORE" = yes; then
AC_DEFINE(WLU)
fi
if test "$CC_TRAILING_UNDERSCORE" = yes; then
AC_DEFINE(WTU)
fi
rm underscore.c underscore.o
AC_MSG_RESULT("$CC_LEADING_UNDERSCORE $CC_TRAILING_UNDERSCORE")
AX_C_UNDERSCORES_LEADING
AX_C_UNDERSCORES_TRAILING
#######################
## end of test for underscores
#######################
AC_MSG_CHECKING("for ident support in C compiler")
ident_support='-DHAVE_CVS_IDENT=1'
case "${host}" in
*-*-cygwin*)
ident_support=
;;
*-*-darwin*)
ident_support=
;;
*-*-machten*)
ident_support=
;;
esac
AC_SUBST(ident_support)
AC_MSG_RESULT($ident_support)
AX_CPP_IDENT
# where to put vpi subdirectories
AC_MSG_CHECKING(for VPI subdirectories)
+16 -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: ivl_dlfcn.h,v 1.1 2003/02/17 00:01:25 steve Exp $"
#ident "$Id: ivl_dlfcn.h,v 1.3 2004/10/04 01:10:56 steve Exp $"
#endif
#if defined(__MINGW32__)
@@ -48,14 +48,14 @@ inline const char *dlerror(void)
{
static char msg[256];
unsigned long err = GetLastError();
FormatMessage(
FormatMessage(
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
err,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &msg,
sizeof(msg) - 1,
NULL
NULL
);
return msg;
}
@@ -65,7 +65,13 @@ 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); }
{
void*sym = dlsym(dll, nm);
/* Not found? try without the leading _ */
if (sym == 0 && nm[0] == '_')
sym = dlsym(dll, nm+1);
return sym;
}
inline void ivl_dlclose(ivl_dll_t dll)
{ dlclose(dll); }
@@ -90,6 +96,12 @@ inline const char*dlerror(void)
/*
* $Log: ivl_dlfcn.h,v $
* Revision 1.3 2004/10/04 01:10:56 steve
* Clean up spurious trailing white space.
*
* Revision 1.2 2003/12/12 05:43:08 steve
* Some systems dlsym requires leading _ or not on whim.
*
* Revision 1.1 2003/02/17 00:01:25 steve
* Use a variant of ivl_dlfcn to do dynamic loading
* from within the cadpli module.
+4 -6
View File
@@ -1,6 +1,4 @@
# The make check target uses this to check the compilation of the
# compiler.
[-tvvp-check]
<ivl>./ivl %[N-N%N] -C%C -tdll -fDLL=./tgt-vvp/vvp.tgt -Fcprop -Fnodangle -fVPI_MODULE_PATH=vpi %f %m -- -
functor:cprop
functor:nodangle
-t:dll
flag:DLL=tgt-vvp/vvp.tgt
+57 -35
View File
@@ -1,7 +1,7 @@
#ifndef __compiler_H
#define __compiler_H
/*
* Copyright (c) 1999-2000 Stephen Williams ([email protected])
* Copyright (c) 1999-2004 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
@@ -19,12 +19,12 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: compiler.h,v 1.19 2003/11/13 05:55:33 steve Exp $"
#ident "$Id: compiler.h,v 1.26 2004/10/04 01:10:52 steve Exp $"
#endif
# include <list>
# include <map>
# include <string>
# include "netlist.h"
# include "StringHeap.h"
/*
@@ -65,7 +65,7 @@
/*
* These are flags to enable various sorts of warnings. By default all
* the warnings are off, the -W<list> parameter arranges for each to be
* enabled.
* enabled.
*/
/* Implicit definitions of wires. */
@@ -81,6 +81,10 @@ extern bool warn_portbinding;
/* This is true if verbose output is requested. */
extern bool verbose_flag;
extern bool debug_scopes;
extern bool debug_eval_tree;
extern bool debug_elaborate;
/* Path to a directory useful for finding subcomponents. */
extern const char*basedir;
@@ -102,12 +106,60 @@ extern generation_t generation_flag;
/* This is the string to use to invoke the preprocessor. */
extern char*ivlpp_string;
extern map<string,unsigned> missing_modules;
extern map<perm_string,unsigned> missing_modules;
/*
* the lex_strings are perm_strings made up of tokens from the source
* file. Identifiers are so likely to be used many times that it makes
* much sense to use a StringHeapLex to hold them.
*/
extern StringHeapLex lex_strings;
/*
* system task/function listings.
*/
/*
* This table describes all the return values of various system
* functions. This table is used to elaborate expressions that are
* system function calls.
*/
struct sfunc_return_type {
const char* name;
NetExpr::TYPE type;
unsigned wid;
int signed_flag;
};
extern const struct sfunc_return_type* lookup_sys_func(const char*name);
extern int load_sys_func_table(const char*path);
/*
* $Log: compiler.h,v $
* Revision 1.26 2004/10/04 01:10:52 steve
* Clean up spurious trailing white space.
*
* Revision 1.25 2004/09/25 01:58:44 steve
* Add a debug_elaborate flag
*
* Revision 1.24 2004/09/10 23:51:42 steve
* Fix the evaluation of constant ternary expressions.
*
* Revision 1.23 2004/09/05 17:44:41 steve
* Add support for module instance arrays.
*
* Revision 1.22 2004/03/10 04:51:24 steve
* Add support for system function table files.
*
* Revision 1.21 2004/03/09 04:29:42 steve
* Separate out the lookup_sys_func table, for eventual
* support for function type tables.
*
* Remove ipal compile flags.
*
* Revision 1.20 2004/02/18 17:11:54 steve
* Use perm_strings for named langiage items.
*
* Revision 1.19 2003/11/13 05:55:33 steve
* Move the DLL= flag to target config files.
*
@@ -122,35 +174,5 @@ extern StringHeapLex lex_strings;
* scope names and system task/function names
* into this table. Also, permallocate event
* names from the beginning.
*
* Revision 1.15 2003/02/22 04:12:49 steve
* Add the portbind warning.
*
* Revision 1.14 2003/01/30 16:23:07 steve
* Spelling fixes.
*
* Revision 1.13 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.12 2002/05/28 20:40:37 steve
* ivl indexes the search path for libraries, and
* supports case insensitive module-to-file lookup.
*
* Revision 1.11 2002/05/28 00:50:39 steve
* Add the ivl -C flag for bulk configuration
* from the driver, and use that to run library
* modules through the preprocessor.
*
* Revision 1.10 2002/05/24 01:13:00 steve
* Support language generation flag -g.
*
* Revision 1.9 2002/04/22 00:53:39 steve
* Do not allow implicit wires in sensitivity lists.
*
* Revision 1.8 2002/04/15 00:04:22 steve
* Timescale warnings.
*
* Revision 1.7 2001/11/16 05:07:19 steve
* Add support for +libext+ in command files.
*/
#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: config.h.in,v 1.10 2003/08/26 16:26:01 steve Exp $"
#ident "$Id: config.h.in,v 1.11 2004/10/04 01:10:52 steve Exp $"
#endif
#if defined(__cplusplus)
@@ -31,7 +31,7 @@
#endif
# undef NEED_LU
# undef NEED_TU
# undef NEED_TU
# undef WLU
# undef WTU
# undef HAVE_TIMES
@@ -50,6 +50,9 @@
/*
* $Log: config.h.in,v $
* Revision 1.11 2004/10/04 01:10:52 steve
* Clean up spurious trailing white space.
*
* Revision 1.10 2003/08/26 16:26:01 steve
* ifdef idents correctly.
*
+23 -123
View File
@@ -3,6 +3,7 @@ AC_INIT(netlist.h)
AC_CONFIG_HEADER(config.h)
AC_CONFIG_HEADER(_pli_types.h)
AC_CANONICAL_HOST
dnl Checks for programs.
AC_PROG_CC
AC_PROG_CXX
@@ -10,9 +11,13 @@ AC_CHECK_TOOL(STRIP, strip, true)
AC_CHECK_PROGS(XGPERF,gperf,none)
if test "$XGPERF" = "none"
then
echo "*** Error: No suitable gperf found. ***"
echo " Please install the 'gperf' package."
exit 1
echo ""
echo "*** Warning: No suitable gperf found. ***"
echo " The gperf package is essential for building ivl from"
echo " CVS sources, or modifying the parse engine of ivl itself."
echo " You can get away without it when simply building from"
echo " snapshots or major releases."
echo ""
fi
AC_CHECK_PROGS(LEX,flex,none)
@@ -31,22 +36,12 @@ then
exit 1
fi
AC_CYGWIN
AC_EXEEXT
AC_MINGW32
WIN32=no
AC_MSG_CHECKING("Checking for windows")
if test "$CYGWIN" = "yes" -o "$MINGW32" = "yes"
then
WIN32=yes
fi
AC_SUBST(MINGW32)
AC_SUBST(WIN32)
AC_MSG_RESULT($WIN32)
AC_SUBST(EXEEXT)
# Combined check for Microsoft-related bogosities; sets WIN32 if found
AX_WIN32
# vvp32 is by default disabled
#enable_vvp32=no
AC_SUBST(enable_vvp32)
@@ -76,16 +71,6 @@ do_times=no
)
AC_MSG_RESULT($do_times)
AC_CHECK_HEADER(ipal.h, HAVE_IPAL=yes, HAVE_IPAL=)
AC_ARG_WITH(ipal,
[ --with-ipal enable PAL target],
if test "$with_ipal" = no; then
echo Disabling ipal support
HAVE_IPAL=
fi
)
AC_SUBST(HAVE_IPAL)
# --
# Look for a dl library to use. First look for the standard dlopen
# functions, and failing that look for the HP specific shl_load function.
@@ -104,107 +89,22 @@ AC_PROG_INSTALL
AC_LANG_C
AC_C_BIGENDIAN
AC_CANONICAL_HOST
# $host
# The -fPIC flag is used to tell the compiler to make position
# independent code. It is needed when making shared objects.
AX_LD_EXTRALIBS
AC_MSG_CHECKING("for flag to make position independent code")
PICFLAG=-fPIC
case "${host}" in
# Compiler option for position independent code, needed whan making shared objects.
# CFLAGS inherited by cadpli/Makefile?
AX_C_PICFLAG
*-*-cygwin*)
PICFLAG=
;;
# may modify CPPFLAGS and CFLAGS
AX_CPP_PRECOMP
*-*-hpux*)
PICFLAG=+z
;;
# Linker option used when compiling the target
AX_LD_RDYNAMIC
esac
AC_SUBST(PICFLAG)
AC_MSG_RESULT($PICFLAG)
# mingw needs to link with libiberty.a, cygwin can tolerate it
AC_MSG_CHECKING("for extra libs needed")
EXTRALIBS=
case "${host}" in
*-*-cygwin*)
EXTRALIBS="-liberty"
;;
esac
AC_SUBST(EXTRALIBS)
AC_MSG_RESULT($EXTRALIBS)
# Darwin requires -no-cpp-precomp
case "${host}" in
*-*-darwin*)
CPPFLAGS="-no-cpp-precomp $CPPFLAGS"
CFLAGS="-no-cpp-precomp $CFLAGS"
;;
esac
# The -rdynamic flag is used by iverilog when compiling the target,
# to know how to export symbols of the main program to loadable modules
# that are brought in by -ldl
AC_MSG_CHECKING("for -rdynamic compiler flag")
rdynamic=-rdynamic
case "${host}" in
*-*-netbsd*)
rdynamic="-Wl,--export-dynamic"
;;
*-*-solaris*)
rdynamic=""
;;
*-*-cygwin*)
rdynamic=""
;;
*-*-hpux*)
rdynamic="-E"
;;
*-*-darwin*)
rdynamic="-Wl,-all_load"
strip_dynamic="-SX"
;;
esac
AC_SUBST(rdynamic)
AC_MSG_RESULT($rdynamic)
AC_SUBST(strip_dynamic)
AC_MSG_RESULT($strip_dynamic)
AC_MSG_CHECKING("for shared library link flag")
shared=-shared
case "${host}" in
*-*-cygwin*)
shared="-shared -Wl,--enable-auto-image-base"
;;
*-*-hpux*)
shared="-b"
;;
*-*-darwin1.[0123])
shared="-bundle -undefined suppress"
;;
*-*-darwin*)
shared="-bundle -undefined suppress -flat_namespace"
;;
esac
AC_SUBST(shared)
AC_MSG_RESULT($shared)
# linker options when building a shared library
AX_LD_SHAREDLIB_OPTS
#######################
## test for underscores. The vpi module loader needs to know this
@@ -241,6 +141,6 @@ AC_SUBST(vpidir1)
AC_SUBST(vpidir2)
AC_MSG_RESULT(${vpidir1} ${vpidir2})
AC_CONFIG_SUBDIRS(vvp tgt-vvp tgt-fpga libveriuser cadpli)
AC_CONFIG_SUBDIRS(vvp vpi tgt-vvp tgt-fpga libveriuser cadpli)
AC_OUTPUT(Makefile vpi/Makefile ivlpp/Makefile driver/Makefile driver-vpi/Makefile tgt-null/Makefile tgt-stub/Makefile tgt-verilog/Makefile tgt-pal/Makefile)
AC_OUTPUT(Makefile ivlpp/Makefile driver/Makefile driver-vpi/Makefile tgt-null/Makefile tgt-stub/Makefile tgt-verilog/Makefile tgt-pal/Makefile)
+5 -2
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: cprop.cc,v 1.46 2003/11/08 17:53:34 steve Exp $"
#ident "$Id: cprop.cc,v 1.47 2004/02/20 18:53:34 steve Exp $"
#endif
# include "config.h"
@@ -56,7 +56,7 @@ void cprop_functor::signal(Design*des, NetNet*obj)
void cprop_functor::lpm_add_sub(Design*des, NetAddSub*obj)
{
// For now, only additions are handled.
if (obj->attribute("LPM_Direction") != verinum("ADD"))
if (obj->attribute(perm_string::literal("LPM_Direction")) != verinum("ADD"))
return;
// If the low bit on the A side is 0, then eliminate it from
@@ -1038,6 +1038,9 @@ void cprop(Design*des)
/*
* $Log: cprop.cc,v $
* Revision 1.47 2004/02/20 18:53:34 steve
* Addtrbute keys are perm_strings.
*
* Revision 1.46 2003/11/08 17:53:34 steve
* Do not remove constants accessible to VPI.
*
+35 -35
View File
@@ -1,35 +1,35 @@
This file describes the build procedure under cygwin32 (Windows 95/98/NT/2K)
----------------------------------------------------------------------------
Note: Icarus Verilog also compiles to native Windows binaries if you
use the instructions in the mingw.txt file. Some people prefer cygwin
binaries, and these instructions apply.
To build using cygwin:
Prerequisites:
o Latest net release (1.1.4) of cygwin (sources.redhat.com/cygwin)
Procedure:
o Get the source code - see the main Icarus Verilog page for how to
do this
o cd to the verilog directory
o autoconf.sh
o ./configure
o make
o make install
That's all that's needed.
To build your own extensions - just include vpi_user.h and link with
a command like this:
$(CC) -shared -o <dllname> <objects> -Wl,--enable-auto-image-base -L../vvm -lvvm -lvpip
- Venkat Iyer <[email protected]>
This file describes the build procedure under cygwin32 (Windows 95/98/NT/2K)
----------------------------------------------------------------------------
Note: Icarus Verilog also compiles to native Windows binaries if you
use the instructions in the mingw.txt file. Some people prefer cygwin
binaries, and these instructions apply.
To build using cygwin:
Prerequisites:
o Latest net release (1.1.4) of cygwin (sources.redhat.com/cygwin)
Procedure:
o Get the source code - see the main Icarus Verilog page for how to
do this
o cd to the verilog directory
o autoconf.sh
o ./configure
o make
o make install
That's all that's needed.
To build your own extensions - just include vpi_user.h and link with
a command like this:
$(CC) -shared -o <dllname> <objects> -Wl,--enable-auto-image-base -L../vvm -lvvm -lvpip
- Venkat Iyer <[email protected]>
+43 -5
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: design_dump.cc,v 1.144 2003/07/26 03:34:42 steve Exp $"
#ident "$Id: design_dump.cc,v 1.149 2004/10/04 01:10:52 steve Exp $"
#endif
# include "config.h"
@@ -495,6 +495,15 @@ void NetAssignNB::dump(ostream&o, unsigned ind) const
}
void NetAssignBase::dump(ostream&o, unsigned ind) const
{
if (const NetAssignNB *n1 = dynamic_cast<const NetAssignNB*>(this)) {
n1->dump(o,ind);
} else if (const NetAssign *n2 = dynamic_cast<const NetAssign*>(this)) {
n2->dump(o,ind);
}
}
/* Dump a block statement */
void NetBlock::dump(ostream&o, unsigned ind) const
{
@@ -636,6 +645,13 @@ void NetForever::dump(ostream&o, unsigned ind) const
void NetFuncDef::dump(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "function " << scope_->name() << endl;
if (result_sig_)
o << setw(ind+2) << "" << "Return signal: "
<< result_sig_->name() << endl;
if (result_var_)
o << setw(ind+2) << "" << "Return variable: "
<< result_var_->basename() << endl;
if (statement_)
statement_->dump(o, ind+2);
else
@@ -677,7 +693,9 @@ void NetRepeat::dump(ostream&o, unsigned ind) const
void NetScope::dump(ostream&o) const
{
/* This is a constructed hierarchical name. */
o << name();
switch (type_) {
case BEGIN_END:
o << " sequential block";
@@ -689,7 +707,7 @@ void NetScope::dump(ostream&o) const
o << " function";
break;
case MODULE:
o << " module <" << (module_name_? module_name_ : "") << ">";
o << " module <" << (module_name_? module_name_.str() : "") << ">";
break;
case TASK:
o << " task";
@@ -706,7 +724,7 @@ void NetScope::dump(ostream&o) const
/* Dump the parameters for this scope. */
{
map<string,param_expr_t>::const_iterator pp;
map<perm_string,param_expr_t>::const_iterator pp;
for (pp = parameters.begin()
; pp != parameters.end() ; pp ++) {
o << " parameter ";
@@ -770,7 +788,10 @@ void NetScope::dump(ostream&o) const
switch (type_) {
case FUNC:
func_def()->dump(o, 4);
if (func_def())
func_def()->dump(o, 4);
else
o << " MISSING FUNCTION DEFINITION" << endl;
break;
case TASK:
task_def()->dump(o, 4);
@@ -1043,7 +1064,7 @@ void Design::dump(ostream&o) const
{
o << "DESIGN TIME PRECISION: 10e" << get_precision() << endl;
o << "SCOPES:" << endl;
for (list<NetScope*>::const_iterator scope = root_scopes_.begin();
for (list<NetScope*>::const_iterator scope = root_scopes_.begin();
scope != root_scopes_.end(); scope++)
(*scope)->dump(o);
@@ -1068,6 +1089,23 @@ void Design::dump(ostream&o) const
/*
* $Log: design_dump.cc,v $
* Revision 1.149 2004/10/04 01:10:52 steve
* Clean up spurious trailing white space.
*
* Revision 1.148 2004/05/31 23:34:36 steve
* Rewire/generalize parsing an elaboration of
* function return values to allow for better
* speed and more type support.
*
* Revision 1.147 2004/02/20 06:22:56 steve
* parameter keys are per_strings.
*
* Revision 1.146 2004/02/18 17:11:54 steve
* Use perm_strings for named langiage items.
*
* Revision 1.145 2003/12/17 16:52:39 steve
* Debug dumps for synth2.
*
* Revision 1.144 2003/07/26 03:34:42 steve
* Start handling pad of expressions in code generators.
*
+5 -7
View File
@@ -16,12 +16,12 @@
# 59 Temple Place - Suite 330
# Boston, MA 02111-1307, USA
#
#ident "$Id: Makefile.in,v 1.5 2002/12/08 03:06:30 steve Exp $"
#ident "$Id: Makefile.in,v 1.7 2004/10/13 22:01:34 steve Exp $"
#
#
SHELL = /bin/sh
VERSION = 0.7
VERSION = 0.8
prefix = @prefix@
exec_prefix = @exec_prefix@
@@ -37,14 +37,12 @@ mandir = @mandir@
dllib=@DLLIB@
CC = @CC@
CXX = @CXX@
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
CPPFLAGS = @CPPFLAGS@ @DEFS@
CFLAGS = @CFLAGS@ -I. -I$(srcdir)/.. -DVERSION='"$(VERSION)"'
CXXFLAGS = @CXXFLAGS@ -I. -I$(srcdir)/..
CPPFLAGS = @ident_support@ -I. -I$(srcdir)/.. -DVERSION='"$(VERSION)"' @CPPFLAGS@ @DEFS@
CFLAGS = -Wall @CFLAGS@
LDFLAGS = @LDFLAGS@
all: iverilog-vpi@EXEEXT@
@@ -63,7 +61,7 @@ iverilog-vpi@EXEEXT@: $O
main.o: main.c
$(CC) $(CFLAGS) -c $(srcdir)/main.c
$(CC) $(CPPFLAGS) $(CFLAGS) -c $(srcdir)/main.c
# Windows specific...
res.o: res.rc
+565 -565
View File
File diff suppressed because it is too large Load Diff
+5 -7
View File
@@ -16,12 +16,12 @@
# 59 Temple Place - Suite 330
# Boston, MA 02111-1307, USA
#
#ident "$Id: Makefile.in,v 1.22 2003/11/18 06:31:46 steve Exp $"
#ident "$Id: Makefile.in,v 1.24 2004/10/13 22:01:34 steve Exp $"
#
#
SHELL = /bin/sh
VERSION = 0.7
VERSION = 0.8
prefix = @prefix@
exec_prefix = @exec_prefix@
@@ -37,14 +37,12 @@ mandir = @mandir@
dllib=@DLLIB@
CC = @CC@
CXX = @CXX@
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
CPPFLAGS = @CPPFLAGS@ @DEFS@
CFLAGS = @CFLAGS@ -Wall @ident_support@ -I. -I.. -I$(srcdir)/.. -I$(srcdir) -DVERSION='"$(VERSION)"'
CXXFLAGS = @CXXFLAGS@ -I.. -I. -I$(srcdir)/.. -I$(srcdir)
CPPFLAGS = @ident_support@ -I. -I.. -I$(srcdir)/.. -I$(srcdir) -DVERSION='"$(VERSION)"' @CPPFLAGS@ @DEFS@
CFLAGS = -Wall @CFLAGS@
LDFLAGS = @LDFLAGS@
all: iverilog@EXEEXT@
@@ -70,7 +68,7 @@ cfparse.h cfparse.c: cfparse.y
main.o: main.c globals.h
$(CC) $(CFLAGS) -c -DCXX='"@CXX@"' -DIVL_ROOT='"@libdir@/ivl"' -DIVL_INC='"@includedir@"' -DIVL_LIB='"@libdir@"' -DDLLIB='"@DLLIB@"' $(srcdir)/main.c
$(CC) $(CPPFLAGS) $(CFLAGS) -c -DIVL_ROOT='"@libdir@/ivl"' -DIVL_INC='"@includedir@"' -DIVL_LIB='"@libdir@"' -DDLLIB='"@DLLIB@"' $(srcdir)/main.c
build_string.o: build_string.c globals.h
cflexor.o: cflexor.c cfparse.h cfparse_misc.h globals.h
+3 -3
View File
@@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: cflexor.lex,v 1.7 2003/08/26 16:26:02 steve Exp $"
#ident "$Id: cflexor.lex,v 1.8 2004/10/04 01:10:56 steve Exp $"
#endif
# include "cfparse.h"
@@ -113,10 +113,10 @@ static int comment_enter;
is a little bit tricky, as we don't want to mistake a comment for
a string word. */
"/"[^\*\/].* { cflval.text = strdup(yytext);
return TOK_STRING; }
return TOK_STRING; }
[^/\n \t\b\r+-].* { cflval.text = strdup(yytext);
return TOK_STRING; }
return TOK_STRING; }
/* Fallback match. */
. { return yytext[0]; }
+6 -1
View File
@@ -20,7 +20,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: cfparse_misc.h,v 1.5 2003/09/26 21:25:58 steve Exp $"
#ident "$Id: cfparse_misc.h,v 1.6 2004/02/15 18:03:30 steve Exp $"
#endif
/*
@@ -38,10 +38,15 @@ struct cfltype {
# define YYLTYPE struct cfltype
extern YYLTYPE yylloc;
int cflex(void);
int cferror(const char *);
int cfparse(void);
/*
* $Log: cfparse_misc.h,v $
* Revision 1.6 2004/02/15 18:03:30 steve
* Cleanup of warnings.
*
* Revision 1.5 2003/09/26 21:25:58 steve
* Warnings cleanup.
*
+31 -4
View File
@@ -1,4 +1,4 @@
.TH iverilog 1 "$Date: 2003/11/26 01:36:25 $" Version "$Date: 2003/11/26 01:36:25 $"
.TH iverilog 1 "$Date: 2004/10/04 01:10:56 $" Version "$Date: 2004/10/04 01:10:56 $"
.SH NAME
iverilog - Icarus Verilog compiler
@@ -57,7 +57,7 @@ language. This flag is most useful to restrict the language to a set
supported by tools of specific generations, for compatibility with
other tools.
.TP 8
.B -I\fIincludedir\fP
.B -I\fIincludedir\fP
Append directory \fIincludedir\fP to list of directories searched
for Verilog include files. The \fB-I\fP switch may be used many times
to specify several directories to search, the directories are searched
@@ -212,6 +212,33 @@ inherit timescale from another file. Both probably mean that
timescales are inconsistent, and simulation timing can be confusing
and dependent on compilation order.
.SH "SYSTEM FUNCTION TABLE FILES"
If the source file name as a \fB.sft\fP suffix, then it is taken to be
a system function table file. A System function table file is used to
describe to the compiler the return types for system functions. This
is necessary because the compiler needs this information to elaborate
expressions that contain these system functions, but cannot run the
sizetf functions since it has no run-time.
The format of the table is ASCII, one function per line. Empty lines
are ignored, and lines that start with the '\fI#\fP' character are
comment lines. Each non-comment line starts with the function name,
then the vpi type (i.e. vpiSysFuncReal). The following types are
supported:
.TP 8
.B vpiSysFuncReal
The function returns a real/realtime value.
.TP 8
.B vpiSysFuncInt
The function returns an integer.
.TP 8
.B vpiSysFuncSized <wid> <signed|unsigned>
The function returns a vector with the given width, and is signed or
unsigned according to the flag.
.SH "COMMAND FILES"
The command file allows the user to place source file names and
certain command line switches into a text file instead of on a long
@@ -289,7 +316,7 @@ and directory strings.
Variable values come from the operating system environment, and not
from preprocessor defines elsewhere in the file or the command line.
.SH EXAMPLES
.SH EXAMPLES
These examples assume that you have a Verilog source file called hello.v in
the current directory
@@ -322,5 +349,5 @@ vvp(1),
.nf
Copyright \(co 2002 Stephen Williams
This document can be freely redistributed according to the terms of the
This document can be freely redistributed according to the terms of the
GNU General Public License version 2.0
+50 -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: main.c,v 1.61 2003/11/18 06:31:46 steve Exp $"
#ident "$Id: main.c,v 1.65 2004/06/17 14:47:22 steve Exp $"
#endif
# include "config.h"
@@ -89,6 +89,7 @@ extern const char*optarg;
#endif
# include "globals.h"
#include "cfparse_misc.h" /* cfparse() */
#ifdef __MINGW32__
const char sep = '\\';
@@ -99,6 +100,7 @@ const char sep = '/';
extern void cfreset(FILE*fd, const char*path);
const char*base = 0;
const char*pbase = 0;
const char*mtm = 0;
const char*opath = "a.out";
const char*npath = 0;
@@ -212,7 +214,9 @@ static const char*my_tempfile(const char*str, FILE**fout)
static int t_default(char*cmd, unsigned ncmd)
{
unsigned rc;
#ifdef __MINGW32__
unsigned ncmd_start = ncmd;
#endif
snprintf(tmp, sizeof tmp, " | %s/ivl", base);
rc = strlen(tmp);
@@ -364,10 +368,21 @@ void process_define(const char*name)
}
}
/*
* This function is called while processing a file name in a command
* file, or a file name on the command line. Look to see if there is a
* .sft suffix, and if so pass that as a sys_func file. Otherwise, it
* is a Verilog source file to be written into the file list.
*/
void process_file_name(const char*name)
{
fprintf(source_file, "%s\n", name);
source_count += 1;
if (strlen(name) > 4 && strcasecmp(".sft", name+strlen(name)-4) == 0) {
fprintf(iconfig_file,"sys_func:%s\n", name);
} else {
fprintf(source_file, "%s\n", name);
source_count += 1;
}
}
int process_generation(const char*name)
@@ -477,7 +492,15 @@ int main(int argc, char **argv)
switch (opt) {
case 'B':
base = optarg;
/* Undocumented feature: The preprocessor itself
may be located at a different location. If the
base starts with a 'P', set this special base
instead of the main base. */
if (optarg[0] == 'P') {
pbase = optarg+1;
} else {
base=optarg;
}
break;
case 'c':
command_filename = malloc(strlen(optarg)+1);
@@ -567,6 +590,9 @@ int main(int argc, char **argv)
}
}
if (pbase == 0)
pbase = base;
if (version_flag || verbose_flag) {
printf("Icarus Verilog version " VERSION " ($Name: $)\n");
printf("Copyright 1998-2003 Stephen Williams\n");
@@ -582,6 +608,12 @@ int main(int argc, char **argv)
/* Write values to the iconfig file. */
fprintf(iconfig_file, "basedir:%s\n", base);
/* Tell the core where to find the system.sft. This file
describes the system functions so that elaboration knows
how to handle them. */
fprintf(iconfig_file, "sys_func:%s%csystem.sft\n", base, sep);
if (mtm != 0) fprintf(iconfig_file, "-T:%s\n", mtm);
fprintf(iconfig_file, "generation:%s\n", generation);
fprintf(iconfig_file, "warnings:%s\n", warning_flags);
@@ -624,7 +656,7 @@ int main(int argc, char **argv)
/* Start building the preprocess command line. */
sprintf(tmp, "%s%civlpp %s%s -D__ICARUS__=1 -f%s ", base,sep,
sprintf(tmp, "%s%civlpp %s%s -D__ICARUS__=1 -f%s ", pbase,sep,
verbose_flag?" -v":"",
e_flag?"":" -L", source_path);
@@ -689,7 +721,7 @@ int main(int argc, char **argv)
single file. This may be used to preprocess library
files. */
fprintf(iconfig_file, "ivlpp:%s%civlpp -D__ICARUS__ -L %s %s\n",
base, sep,
pbase, sep,
inc_list? inc_list : "",
def_list? def_list : "");
@@ -703,6 +735,18 @@ int main(int argc, char **argv)
/*
* $Log: main.c,v $
* Revision 1.65 2004/06/17 14:47:22 steve
* Add a .sft file for the system functions.
*
* Revision 1.64 2004/03/10 04:51:25 steve
* Add support for system function table files.
*
* Revision 1.63 2004/02/15 18:03:30 steve
* Cleanup of warnings.
*
* Revision 1.62 2003/12/12 04:36:48 steve
* Fix make check to support -tconf configuration method.
*
* Revision 1.61 2003/11/18 06:31:46 steve
* Remove the iverilog.conf file.
*
+6 -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: substit.c,v 1.4 2002/08/12 01:35:01 steve Exp $"
#ident "$Id: substit.c,v 1.5 2003/12/19 01:27:10 steve Exp $"
#endif
# include <string.h>
@@ -66,7 +66,7 @@ char* substitutions(const char*str)
cp += strlen(cp);
} else {
if ( (cp - buf) == nbuf ) {
if ( cp == (buf + nbuf) ) {
size_t old_size = nbuf;
nbuf = old_size + 32;
buf = realloc(buf, nbuf);
@@ -79,7 +79,7 @@ char* substitutions(const char*str)
/* Add the trailing nul to the string, and reallocate the
buffer to be a tight fit. */
if ( (cp - buf) == nbuf ) {
if ( cp == (buf + nbuf) ) {
size_t old_size = nbuf;
nbuf = old_size + 1;
buf = realloc(buf, nbuf);
@@ -96,6 +96,9 @@ char* substitutions(const char*str)
/*
* $Log: substit.c,v $
* Revision 1.5 2003/12/19 01:27:10 steve
* Fix various unsigned compare warnings.
*
* Revision 1.4 2002/08/12 01:35:01 steve
* conditional ident string using autoconfig.
*
+17 -2
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: dup_expr.cc,v 1.16 2003/10/31 02:47:11 steve Exp $"
#ident "$Id: dup_expr.cc,v 1.18 2004/06/17 16:06:18 steve Exp $"
#endif
# include "config.h"
@@ -75,6 +75,8 @@ NetESFunc* NetESFunc::dup_expr() const
{
NetESFunc*tmp = new NetESFunc(name_, type_, expr_width(), nparms());
assert(tmp);
tmp->cast_signed(has_sign());
for (unsigned idx = 0 ; idx < nparms() ; idx += 1) {
assert(tmp->parm(idx));
tmp->parm(idx, tmp->parm(idx)->dup_expr());
@@ -109,8 +111,13 @@ NetEUFunc* NetEUFunc::dup_expr() const
tmp_parms[idx] = parms_[idx]->dup_expr();
}
tmp = new NetEUFunc(func_, result_->dup_expr(), tmp_parms);
tmp = 0;
if (result_sig_)
tmp = new NetEUFunc(func_, result_sig_->dup_expr(), tmp_parms);
if (result_var_)
tmp = new NetEUFunc(func_, result_var_->dup_expr(), tmp_parms);
assert(tmp);
return tmp;
}
@@ -136,6 +143,14 @@ NetEVariable* NetEVariable::dup_expr() const
/*
* $Log: dup_expr.cc,v $
* Revision 1.18 2004/06/17 16:06:18 steve
* Help system function signedness survive elaboration.
*
* Revision 1.17 2004/05/31 23:34:36 steve
* Rewire/generalize parsing an elaboration of
* function return values to allow for better
* speed and more type support.
*
* Revision 1.16 2003/10/31 02:47:11 steve
* NetEUReduce has its own dup_expr method.
*
+5 -2
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: elab_anet.cc,v 1.9 2003/09/19 03:50:12 steve Exp $"
#ident "$Id: elab_anet.cc,v 1.10 2004/10/04 01:10:52 steve Exp $"
#endif
# include "config.h"
@@ -157,7 +157,7 @@ NetNet* PEIdent::elaborate_anet(Design*des, NetScope*scope) const
cerr << get_line() << ": error: bit/part selects not allowed "
<< "on left side of procedural continuous assignment."
<< endl;
<< endl;
des->errors += 1;
return 0;
}
@@ -167,6 +167,9 @@ NetNet* PEIdent::elaborate_anet(Design*des, NetScope*scope) const
/*
* $Log: elab_anet.cc,v $
* Revision 1.10 2004/10/04 01:10:52 steve
* Clean up spurious trailing white space.
*
* Revision 1.9 2003/09/19 03:50:12 steve
* Remove find_memory method from Design class.
*
+114 -47
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_expr.cc,v 1.82 2003/10/09 16:52:52 steve Exp $"
#ident "$Id: elab_expr.cc,v 1.91 2004/10/04 01:10:52 steve Exp $"
#endif
# include "config.h"
@@ -28,30 +28,6 @@
# include "netmisc.h"
# include "util.h"
/*
* This table describes all the return values of various system
* functions. This table is used to elaborate expressions that are
* system function calls.
*/
struct sfunc_return_type {
const char* name;
NetExpr::TYPE type;
unsigned wid;
int signed_flag;
};
static const struct sfunc_return_type sfunc_table[] = {
{ "$realtime", NetExpr::ET_REAL, 0, 0 },
{ "$bitstoreal", NetExpr::ET_REAL, 0, 0 },
{ "$itor", NetExpr::ET_REAL, 0, 0 },
{ "$realtobits", NetExpr::ET_VECTOR, 64, 0 },
{ "$time", NetExpr::ET_VECTOR, 64, 0 },
{ "$stime", NetExpr::ET_VECTOR, 32, 0 },
{ "$simtime", NetExpr::ET_VECTOR, 64, 0 },
{ 0, NetExpr::ET_VECTOR, 32, 0 }
};
NetExpr* PExpr::elaborate_expr(Design*des, NetScope*, bool) const
{
cerr << get_line() << ": internal error: I do not know how to elaborate"
@@ -65,7 +41,7 @@ NetExpr* PExpr::elaborate_expr(Design*des, NetScope*, bool) const
/*
* Elaborate binary expressions. This involves elaborating the left
* and right sides, and creating one of a variety of different NetExpr
* types.
* types.
*/
NetEBinary* PEBinary::elaborate_expr(Design*des, NetScope*scope, bool) const
{
@@ -216,6 +192,20 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope) const
sub->cast_signed(true);
return sub;
}
/* add $unsigned to match $signed */
if (strcmp(path_.peek_name(0), "$unsigned") == 0) {
if ((parms_.count() != 1) || (parms_[0] == 0)) {
cerr << get_line() << ": error: The $unsigned() function "
<< "takes exactly one(1) argument." << endl;
des->errors += 1;
return 0;
}
PExpr*expr = parms_[0];
NetExpr*sub = expr->elaborate_expr(des, scope, true);
sub->cast_signed(false);
return sub;
}
/* Interpret the internal $sizeof system function to return
the bit width of the sub-expression. The value of the
@@ -245,15 +235,37 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope) const
return sub;
}
/* Interpret the internal $is_signed system function to return
a single bit flag -- 1 if the expression is signed, 0
otherwise. The subexpression is elaborated but not
evaluated. */
if (strcmp(path_.peek_name(0), "$is_signed") == 0) {
if ((parms_.count() != 1) || (parms_[0] == 0)) {
cerr << get_line() << ": error: The $is_signed() function "
<< "takes exactly one(1) argument." << endl;
des->errors += 1;
return 0;
}
PExpr*expr = parms_[0];
NetExpr*sub = expr->elaborate_expr(des, scope, true);
verinum val (sub->has_sign()? verinum::V1 : verinum::V0, 1);
delete sub;
sub = new NetEConst(val);
sub->set_line(*this);
return sub;
}
/* Get the return type of the system function by looking it up
in the sfunc_table. */
unsigned sfunc_idx;
for (sfunc_idx = 0 ; sfunc_table[sfunc_idx].name ; sfunc_idx += 1)
if (strcmp(path_.peek_name(0), sfunc_table[sfunc_idx].name) == 0)
break;
const struct sfunc_return_type*sfunc_info
= lookup_sys_func(path_.peek_name(0));
NetExpr::TYPE sfunc_type = sfunc_table[sfunc_idx].type;
unsigned wid = sfunc_table[sfunc_idx].wid;
NetExpr::TYPE sfunc_type = sfunc_info->type;
unsigned wid = sfunc_info->wid;
/* How many parameters are there? The Verilog language allows
@@ -270,6 +282,8 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope) const
NetESFunc*fun = new NetESFunc(path_.peek_name(0), sfunc_type,
wid, nparms);
if (sfunc_info->signed_flag)
fun->cast_signed(true);
/* Now run through the expected parameters. If we find that
there are missing parameters, print an error message.
@@ -332,7 +346,7 @@ NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope, bool) const
if ((parms_count == 1) && (parms_[0] == 0))
parms_count = 0;
svector<NetExpr*> parms (parms_count);
@@ -370,20 +384,24 @@ NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope, bool) const
dscope, in this case, is the scope of the function, so the
return value is the name within that scope. */
NetNet*res = dscope->find_signal(dscope->basename());
if (res == 0) {
cerr << get_line() << ": internal error: Unable to locate "
"function return value for " << path_ << " in " <<
def->name() << "." << endl;
des->errors += 1;
return 0;
if (NetNet*res = dscope->find_signal(dscope->basename())) {
NetESignal*eres = new NetESignal(res);
NetEUFunc*func = new NetEUFunc(dscope, eres, parms);
return func;
}
assert(res);
NetESignal*eres = new NetESignal(res);
assert(eres);
NetEUFunc*func = new NetEUFunc(dscope, eres, parms);
return func;
if (NetVariable*res = dscope->find_variable(dscope->basename())) {
NetEVariable*eres = new NetEVariable(res);
eres->set_line(*res);
NetEUFunc*func = new NetEUFunc(dscope, eres, parms);
return func;
}
cerr << get_line() << ": internal error: Unable to locate "
"function return value for " << path_
<< " in " << def->name() << "." << endl;
des->errors += 1;
return 0;
}
@@ -418,6 +436,13 @@ NetExpr* PEConcat::elaborate_expr(Design*des, NetScope*scope, bool) const
/* Elaborate all the parameters and attach them to the concat node. */
for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) {
if (parms_[idx] == 0) {
cerr << get_line() << ": error: Missing expression "
<< (idx+1) << " of concatenation list." << endl;
des->errors += 1;
continue;
}
assert(parms_[idx]);
NetExpr*ex = elab_and_eval(des, scope, parms_[idx]);
if (ex == 0) continue;
@@ -598,8 +623,8 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
NetEConstParam if possible. */
NetEConst*ctmp = dynamic_cast<NetEConst*>(tmp);
if (ctmp != 0) {
const char*name
= lex_strings.add(path_.peek_tail_name());
perm_string name
= lex_strings.make(path_.peek_tail_name());
NetEConstParam*ptmp
= new NetEConstParam(found_in, name, ctmp->value());
delete tmp;
@@ -901,6 +926,16 @@ NetExpr* PEUnary::elaborate_expr(Design*des, NetScope*scope, bool) const
val.has_sign(true);
tmp = new NetEConst(val);
delete ip;
} else if (NetECReal*ipc = dynamic_cast<NetECReal*>(ip)) {
/* When taking the - of a real, fold this into the
constant value. */
verireal val = - ipc->value();
tmp = new NetECReal(val);
tmp->set_line( *ip );
delete ip;
} else {
tmp = new NetEUnary(op_, ip);
tmp->set_line(*this);
@@ -970,6 +1005,38 @@ NetExpr* PEUnary::elaborate_expr(Design*des, NetScope*scope, bool) const
/*
* $Log: elab_expr.cc,v $
* Revision 1.91 2004/10/04 01:10:52 steve
* Clean up spurious trailing white space.
*
* Revision 1.90 2004/08/28 15:42:11 steve
* Add support for $unsigned.
*
* Revision 1.89 2004/08/26 03:52:07 steve
* Add the $is_signed function.
*
* Revision 1.88 2004/06/17 16:06:18 steve
* Help system function signedness survive elaboration.
*
* Revision 1.87 2004/06/04 23:34:15 steve
* Special case for unary - of real literal.
*
* Revision 1.86 2004/05/31 23:34:36 steve
* Rewire/generalize parsing an elaboration of
* function return values to allow for better
* speed and more type support.
*
* Revision 1.85 2004/03/09 04:29:42 steve
* Separate out the lookup_sys_func table, for eventual
* support for function type tables.
*
* Remove ipal compile flags.
*
* Revision 1.84 2004/02/20 06:22:56 steve
* parameter keys are per_strings.
*
* Revision 1.83 2004/01/21 04:57:40 steve
* Generate error when missing concatenation operands.
*
* Revision 1.82 2003/10/09 16:52:52 steve
* Put parameter name in NetEConstParam, not scope.
*
+10 -2
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: elab_lval.cc,v 1.27 2003/09/19 03:30:05 steve Exp $"
#ident "$Id: elab_lval.cc,v 1.29 2004/10/04 01:10:52 steve Exp $"
#endif
# include "config.h"
@@ -40,7 +40,7 @@
* If there is a part select (i.e., foo[3:1] <= <value>) the NetAssign_
* is made only as wide as it needs to be (3 bits in this example) and
* connected to the correct bits of foo. A constant bit select is a
* special case of the part select.
* special case of the part select.
*
* If the bit-select is non-constant (i.e., foo[<expr>] = <value>) the
* NetAssign_ is made wide enough to connect to all the bits of foo,
@@ -176,6 +176,8 @@ NetAssign_* PEIdent::elaborate_lval(Design*des, NetScope*scope) const
cerr << get_line() << ": error: " << path_ <<
" is not a reg/integer/time in " << scope->name() <<
"." << endl;
cerr << reg->get_line() << ": : " << path_ <<
" is declared here as " << reg->type() << "." << endl;
des->errors += 1;
return 0;
}
@@ -350,6 +352,12 @@ NetAssign_* PENumber::elaborate_lval(Design*des, NetScope*) const
/*
* $Log: elab_lval.cc,v $
* Revision 1.29 2004/10/04 01:10:52 steve
* Clean up spurious trailing white space.
*
* Revision 1.28 2004/08/28 14:59:44 steve
* More detailed error message about bad variable.
*
* Revision 1.27 2003/09/19 03:30:05 steve
* Fix name search in elab_lval.
*
+375 -215
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.122 2003/10/30 04:31:34 steve Exp $"
#ident "$Id: elab_net.cc,v 1.138 2004/10/04 03:09:38 steve Exp $"
#endif
# include "config.h"
@@ -94,6 +94,7 @@ NetNet* PEBinary::elaborate_net(Design*des, NetScope*scope,
return elaborate_net_log_(des, scope, width, rise, fall, decay);
case 'l': // <<
case 'r': // >>
case 'R': // >>>
return elaborate_net_shift_(des, scope, width, rise, fall, decay);
}
@@ -138,6 +139,7 @@ NetNet* PEBinary::elaborate_net(Design*des, NetScope*scope,
case 'l':
case 'r':
case 'R':
assert(0);
break;
default:
@@ -244,15 +246,8 @@ NetNet* PEBinary::elaborate_net_add_(Design*des, NetScope*scope,
gate->decay_time(decay);
des->add_node(gate);
switch (op_) {
case '+':
gate->attribute("LPM_Direction", verinum("ADD"));
break;
case '-':
gate->attribute("LPM_Direction", verinum("SUB"));
break;
}
gate->attribute(perm_string::literal("LPM_Direction"),
verinum(op_ == '+' ? "ADD" : "SUB"));
return osig;
}
@@ -303,95 +298,151 @@ NetNet* PEBinary::elaborate_net_bit_(Design*des, NetScope*scope,
lsig->pin_count());
osig->local_flag(true);
NetLogic::TYPE gtype=NetLogic::AND;
switch (op_) {
case '^': // XOR
for (unsigned idx = 0 ; idx < lsig->pin_count() ; idx += 1) {
NetLogic*gate = new NetLogic(scope, scope->local_symbol(),
3, NetLogic::XOR);
connect(gate->pin(1), lsig->pin(idx));
connect(gate->pin(2), rsig->pin(idx));
connect(gate->pin(0), osig->pin(idx));
gate->rise_time(rise);
gate->fall_time(fall);
gate->decay_time(decay);
des->add_node(gate);
}
break;
case 'X': // XNOR
for (unsigned idx = 0 ; idx < lsig->pin_count() ; idx += 1) {
NetLogic*gate = new NetLogic(scope, scope->local_symbol(),
3, NetLogic::XNOR);
connect(gate->pin(1), lsig->pin(idx));
connect(gate->pin(2), rsig->pin(idx));
connect(gate->pin(0), osig->pin(idx));
gate->rise_time(rise);
gate->fall_time(fall);
gate->decay_time(decay);
des->add_node(gate);
}
break;
case '&': // AND
for (unsigned idx = 0 ; idx < lsig->pin_count() ; idx += 1) {
NetLogic*gate = new NetLogic(scope, scope->local_symbol(),
3, NetLogic::AND);
connect(gate->pin(1), lsig->pin(idx));
connect(gate->pin(2), rsig->pin(idx));
connect(gate->pin(0), osig->pin(idx));
gate->rise_time(rise);
gate->fall_time(fall);
gate->decay_time(decay);
des->add_node(gate);
}
break;
case 'A': // NAND (~&)
for (unsigned idx = 0 ; idx < lsig->pin_count() ; idx += 1) {
NetLogic*gate = new NetLogic(scope, scope->local_symbol(),
3, NetLogic::NAND);
connect(gate->pin(1), lsig->pin(idx));
connect(gate->pin(2), rsig->pin(idx));
connect(gate->pin(0), osig->pin(idx));
gate->rise_time(rise);
gate->fall_time(fall);
gate->decay_time(decay);
des->add_node(gate);
}
break;
case '|': // Bitwise OR
for (unsigned idx = 0 ; idx < lsig->pin_count() ; idx += 1) {
NetLogic*gate = new NetLogic(scope, scope->local_symbol(),
3, NetLogic::OR);
connect(gate->pin(1), lsig->pin(idx));
connect(gate->pin(2), rsig->pin(idx));
connect(gate->pin(0), osig->pin(idx));
gate->rise_time(rise);
gate->fall_time(fall);
gate->decay_time(decay);
des->add_node(gate);
}
break;
case 'O': // Bitwise NOR
for (unsigned idx = 0 ; idx < lsig->pin_count() ; idx += 1) {
NetLogic*gate = new NetLogic(scope, scope->local_symbol(),
3, NetLogic::NOR);
connect(gate->pin(1), lsig->pin(idx));
connect(gate->pin(2), rsig->pin(idx));
connect(gate->pin(0), osig->pin(idx));
gate->rise_time(rise);
gate->fall_time(fall);
gate->decay_time(decay);
des->add_node(gate);
}
break;
default:
assert(0);
case '^': gtype = NetLogic::XOR; break; // XOR
case 'X': gtype = NetLogic::XNOR; break; // XNOR
case '&': gtype = NetLogic::AND; break; // AND
case 'A': gtype = NetLogic::NAND; break; // NAND (~&)
case '|': gtype = NetLogic::OR; break; // Bitwise OR
case 'O': gtype = NetLogic::NOR; break; // Bitwise NOR
default: assert(0);
}
for (unsigned idx = 0 ; idx < lsig->pin_count() ; idx += 1) {
NetLogic*gate = new NetLogic(scope, scope->local_symbol(),
3, gtype);
connect(gate->pin(1), lsig->pin(idx));
connect(gate->pin(2), rsig->pin(idx));
connect(gate->pin(0), osig->pin(idx));
gate->rise_time(rise);
gate->fall_time(fall);
gate->decay_time(decay);
des->add_node(gate);
}
return osig;
}
/*
* This function attempts to handle the special case of == or !=
* compare to a constant value. The caller has determined already that
* one of the operands is a NetEConst, and has already elaborated the
* other.
*/
static NetNet* compare_eq_constant(Design*des, NetScope*scope,
NetNet*lsig, NetEConst*rexp,
char op_code,
unsigned long rise,
unsigned long fall,
unsigned long decay)
{
if (op_code != 'e' && op_code != 'n')
return 0;
verinum val = rexp->value();
/* Abandon special case if there are x or z bits in the
constant. We can't get the right behavior out of
OR/NOR in this case. */
if (! val.is_defined())
return 0;
if (val.len() < lsig->pin_count())
val = verinum(val, lsig->pin_count());
/* Look for the very special case that we know the compare
results a priori due to different high bits, that are
constant pad in the signal. */
if (val.len() > lsig->pin_count()) {
unsigned idx = lsig->pin_count();
verinum::V lpad = verinum::V0;
while (idx < val.len()) {
if (val.get(idx) != lpad) {
verinum oval (op_code == 'e'
? verinum::V0
: verinum::V1,
1);
NetEConst*ogate = new NetEConst(oval);
NetNet*osig = ogate->synthesize(des);
delete ogate;
return osig;
}
idx +=1;
}
}
unsigned zeros = 0;
unsigned ones = 0;
for (unsigned idx = 0 ; idx < lsig->pin_count() ; idx += 1) {
if (val.get(idx) == verinum::V0)
zeros += 1;
if (val.get(idx) == verinum::V1)
ones += 1;
}
/* Now make reduction logic to test that all the 1 bits are 1,
and all the 0 bits are 0. The results will be ANDed
together later, if needed. NOTE that if the compare is !=,
and we know that we will not need an AND later, then fold
the final invert into the reduction gate to get the right
sense of the output. If we do need the AND later, then we
will put the invert on that instead. */
NetLogic*zero_gate = 0;
NetLogic*ones_gate = 0;
if (zeros > 0)
zero_gate = new NetLogic(scope,
scope->local_symbol(), zeros + 1,
(op_code == 'n') ? NetLogic::OR : NetLogic::NOR);
if (ones > 0)
ones_gate = new NetLogic(scope,
scope->local_symbol(), ones + 1,
(op_code == 'n') ? NetLogic::NAND : NetLogic::AND);
unsigned zidx = 0;
unsigned oidx = 0;
for (unsigned idx = 0 ; idx < lsig->pin_count() ; idx += 1) {
if (val.get(idx) == verinum::V0) {
zidx += 1;
connect(zero_gate->pin(zidx), lsig->pin(idx));
}
if (val.get(idx) == verinum::V1) {
oidx += 1;
connect(ones_gate->pin(oidx), lsig->pin(idx));
}
}
NetNet*osig = new NetNet(scope, scope->local_symbol(),
NetNet::WIRE, 1);
osig->local_flag(true);
if (zero_gate && ones_gate) {
NetNet*and_sig = new NetNet(scope, scope->local_symbol(),
NetNet::WIRE, 2);
and_sig->local_flag(true);
connect(and_sig->pin(0), zero_gate->pin(0));
connect(and_sig->pin(1), ones_gate->pin(0));
NetLogic*and_gate = new NetLogic(scope,
scope->local_symbol(), 3,
(op_code == 'n') ? NetLogic::OR : NetLogic::AND);
connect(and_gate->pin(0), osig->pin(0));
connect(and_gate->pin(1), and_sig->pin(0));
connect(and_gate->pin(2), and_sig->pin(1));
des->add_node(and_gate);
des->add_node(zero_gate);
des->add_node(ones_gate);
} else if (zero_gate) {
connect(zero_gate->pin(0), osig->pin(0));
des->add_node(zero_gate);
} else {
assert(ones_gate);
connect(ones_gate->pin(0), osig->pin(0));
des->add_node(ones_gate);
}
return osig;
}
@@ -408,21 +459,90 @@ NetNet* PEBinary::elaborate_net_cmp_(Design*des, NetScope*scope,
unsigned long fall,
unsigned long decay) const
{
NetNet*lsig = left_->elaborate_net(des, scope, 0, 0, 0, 0),
*rsig = right_->elaborate_net(des, scope, 0, 0, 0, 0);
if (lsig == 0) {
/* Elaborate the operands of the compare first as expressions
(so that the eval_tree method can reduce constant
expressions, including parameters) then turn those results
into synthesized nets. */
NetExpr*lexp = left_->elaborate_expr(des, scope);
if (lexp == 0) {
cerr << get_line() << ": error: Cannot elaborate ";
left_->dump(cerr);
cerr << endl;
return 0;
}
if (rsig == 0) {
if (NetExpr*tmp = lexp->eval_tree()) {
delete lexp;
lexp = tmp;
}
NetExpr*rexp = right_->elaborate_expr(des, scope);
if (rexp == 0) {
cerr << get_line() << ": error: Cannot elaborate ";
right_->dump(cerr);
cerr << endl;
return 0;
}
if (NetExpr*tmp = rexp->eval_tree()) {
delete rexp;
rexp = tmp;
}
NetNet*lsig = 0;
NetNet*rsig = 0;
/* Handle the special case that the right or left
sub-expression is a constant value. The compare_eq_constant
function will return an elaborated result if it can make
use of the situation, or 0 if it cannot. */
if (NetEConst*tmp = dynamic_cast<NetEConst*>(rexp)) {
lsig = lexp->synthesize(des);
if (lsig == 0) {
cerr << get_line() << ": internal error: "
"Cannot elaborate net for " << *lexp << endl;
}
assert(lsig);
delete lexp;
lexp = 0;
NetNet*osig = compare_eq_constant(des, scope,
lsig, tmp, op_,
rise, fall, decay);
if (osig != 0) {
delete rexp;
return osig;
}
}
if (NetEConst*tmp = dynamic_cast<NetEConst*>(lexp)) {
rsig = rexp->synthesize(des);
assert(rsig);
delete rexp;
NetNet*osig = compare_eq_constant(des, scope,
rsig, tmp, op_,
rise, fall, decay);
if (osig != 0) {
delete lexp;
return osig;
}
}
if (lsig == 0) {
lsig = lexp->synthesize(des);
assert(lsig);
delete lexp;
}
if (rsig == 0) {
rsig = rexp->synthesize(des);
assert(rsig);
delete rexp;
}
unsigned dwidth = lsig->pin_count();
if (rsig->pin_count() > dwidth) dwidth = rsig->pin_count();
@@ -657,6 +777,7 @@ NetNet* PEBinary::elaborate_net_div_(Design*des, NetScope*scope,
rsig->pin_count());
des->add_node(div);
div->set_signed(lsig->get_signed() && rsig->get_signed());
// Connect the left and right inputs of the divider to the
// nets that are the left and right expressions.
@@ -675,6 +796,7 @@ NetNet* PEBinary::elaborate_net_div_(Design*des, NetScope*scope,
NetNet*osig = new NetNet(scope, scope->local_symbol(),
NetNet::IMPLICIT, lwidth);
osig->local_flag(true);
osig->set_signed(div->get_signed());
for (unsigned idx = 0 ; idx < rwidth ; idx += 1)
connect(div->pin_Result(idx), osig->pin(idx));
@@ -757,8 +879,8 @@ NetNet* PEBinary::elaborate_net_log_(Design*des, NetScope*scope,
unsigned long fall,
unsigned long decay) const
{
NetNet*lsig = left_->elaborate_net(des, scope, 0, 0, 0, 0),
*rsig = right_->elaborate_net(des, scope, 0, 0, 0, 0);
NetNet*lsig = left_->elaborate_net(des, scope, 0, 0, 0, 0);
NetNet*rsig = right_->elaborate_net(des, scope, 0, 0, 0, 0);
if (lsig == 0) {
cerr << get_line() << ": error: Cannot elaborate ";
left_->dump(cerr);
@@ -934,6 +1056,9 @@ NetNet* PEBinary::elaborate_net_shift_(Design*des, NetScope*scope,
if (lsig->pin_count() > lwidth)
lwidth = lsig->pin_count();
bool right_flag = op_ == 'r' || op_ == 'R';
bool signed_flag = op_ == 'R';
/* Handle the special case of a constant shift amount. There
is no reason in this case to create a gate at all, just
connect the lsig to the osig with the bit positions
@@ -956,6 +1081,8 @@ NetNet* PEBinary::elaborate_net_shift_(Design*des, NetScope*scope,
des->add_node(zero);
if (op_ == 'l') {
/* Left shift means put some zeros on the bottom
of the vector. */
unsigned idx;
for (idx = 0 ; idx < dist ; idx += 1)
connect(osig->pin(idx), zero->pin(0));
@@ -965,7 +1092,17 @@ NetNet* PEBinary::elaborate_net_shift_(Design*des, NetScope*scope,
for ( ; idx < lwidth ; idx += 1)
connect(osig->pin(idx), zero->pin(0));
} else if (op_ == 'R') {
/* Signed right shift. */
unsigned idx;
unsigned keep = lsig->pin_count()-dist;
for (idx = 0 ; idx < keep ; idx += 1)
connect(osig->pin(idx), lsig->pin(idx+dist));
for (idx = keep ; idx < lwidth ; idx += 1)
connect(osig->pin(idx), lsig->pin(keep+dist-1));
} else {
/* Unsigned right shift. */
assert(op_ == 'r');
unsigned idx;
unsigned keep = lsig->pin_count()-dist;
@@ -990,7 +1127,8 @@ NetNet* PEBinary::elaborate_net_shift_(Design*des, NetScope*scope,
// Make the shift device itself, and the output
// NetNet. Connect the Result output pins to the osig signal
NetCLShift*gate = new NetCLShift(scope, scope->local_symbol(),
lwidth, rsig->pin_count());
lwidth, rsig->pin_count(),
right_flag, signed_flag);
NetNet*osig = new NetNet(scope, scope->local_symbol(),
NetNet::WIRE, lwidth);
@@ -1021,17 +1159,6 @@ NetNet* PEBinary::elaborate_net_shift_(Design*des, NetScope*scope,
for (unsigned idx = 0 ; idx < rsig->pin_count() ; idx += 1)
connect(rsig->pin(idx), gate->pin_Distance(idx));
if (op_ == 'r') {
NetNet*tmp = new NetNet(scope, scope->local_symbol(),
NetNet::IMPLICIT, 1);
tmp->local_flag(true);
NetConst*dir = new NetConst(scope, scope->local_symbol(),
verinum::V1);
connect(dir->pin(0), gate->pin_Direction());
connect(tmp->pin(0), gate->pin_Direction());
des->add_node(dir);
}
des->add_node(gate);
return osig;
@@ -1039,7 +1166,10 @@ NetNet* PEBinary::elaborate_net_shift_(Design*des, NetScope*scope,
/*
* This method elaborates a call to a function in the context of a
* continuous assignment.
* continuous assignment. The definition of the function contains a
* list of the ports, and an output port. The NetEUFunc that I create
* here has a port for all the input ports and the output port. The
* ports are connected by pins.
*/
NetNet* PECallFunction::elaborate_net(Design*des, NetScope*scope,
unsigned width,
@@ -1070,6 +1200,21 @@ NetNet* PECallFunction::elaborate_net(Design*des, NetScope*scope,
sub->set_signed(true);
return sub;
}
/* handle $unsigned like $signed */
if (strcmp(path_.peek_name(0), "$unsigned") == 0) {
if ((parms_.count() != 1) || (parms_[0] == 0)) {
cerr << get_line() << ": error: The $unsigned() function "
<< "takes exactly one(1) argument." << endl;
des->errors += 1;
return 0;
}
PExpr*expr = parms_[0];
NetNet*sub = expr->elaborate_net(des, scope, width, rise,
fall, decay, drive0, drive1);
sub->set_signed(false);
return sub;
}
/* Look up the function definition. */
NetFuncDef*def = des->find_function(scope, path_);
@@ -1084,6 +1229,9 @@ NetNet* PECallFunction::elaborate_net(Design*des, NetScope*scope,
NetScope*dscope = def->scope();
assert(dscope);
/* This must be a ufuction that returns a signal. */
assert(def->return_sig());
/* check the validity of the parameters. */
if (! check_call_matches_definition_(des, dscope))
return 0;
@@ -1092,9 +1240,9 @@ NetNet* PECallFunction::elaborate_net(Design*des, NetScope*scope,
and collect the resulting NetNet objects. All the
parameters take on the size of the target port. */
svector<NetNet*> eparms (def->port_count()-1);
svector<NetNet*> eparms (def->port_count());
for (unsigned idx = 0 ; idx < eparms.count() ; idx += 1) {
const NetNet* port_reg = def->port(idx+1);
const NetNet* port_reg = def->port(idx);
NetNet*tmp = parms_[idx]->elaborate_net(des, scope,
port_reg->pin_count(),
0, 0, 0,
@@ -1117,7 +1265,7 @@ NetNet* PECallFunction::elaborate_net(Design*des, NetScope*scope,
NetUserFunc*net = new NetUserFunc(scope,
scope->local_symbol().c_str(),
scope->local_symbol(),
dscope);
des->add_node(net);
@@ -1125,7 +1273,7 @@ NetNet* PECallFunction::elaborate_net(Design*des, NetScope*scope,
of the function net. */
NetNet*osig = new NetNet(scope, scope->local_symbol(),
NetNet::WIRE,
def->port(0)->pin_count());
def->return_sig()->pin_count());
osig->local_flag(true);
for (unsigned idx = 0 ; idx < osig->pin_count() ; idx += 1)
@@ -1133,7 +1281,7 @@ NetNet* PECallFunction::elaborate_net(Design*des, NetScope*scope,
/* Connect the parameter pins to the parameter expressions. */
for (unsigned idx = 0 ; idx < eparms.count() ; idx += 1) {
const NetNet* port = def->port(idx+1);
const NetNet* port = def->port(idx);
NetNet*cur = eparms[idx];
NetNet*tmp = pad_to_width(des, cur, port->pin_count());
@@ -1349,7 +1497,7 @@ NetNet* PEIdent::elaborate_net(Design*des, NetScope*scope,
assert(pc);
verinum pvalue = pc->value();
sig = new NetNet(scope, path_.peek_name(0),
sig = new NetNet(scope, lex_strings.make(path_.peek_name(0)),
NetNet::IMPLICIT, pc->expr_width());
NetConst*cp = new NetConst(scope, scope->local_symbol(),
pvalue);
@@ -1365,13 +1513,34 @@ NetNet* PEIdent::elaborate_net(Design*des, NetScope*scope,
return 0;
}
/* Check for the error case that the name is not found, and it
is hierarchical. We can't just create a name in another
scope, it's just not allowed. */
if (sig == 0 && path_.component_count() != 1) {
cerr << get_line() << ": error: The hierarchical name "
<< path_ << " is undefined in "
<< scope->name() << "." << endl;
hname_t tmp_path = path_;
delete[] tmp_path.remove_tail_name();
NetScope*tmp_scope = des->find_scope(scope, tmp_path);
if (tmp_scope == 0) {
cerr << get_line() << ": : I can't even find "
<< "the scope " << tmp_path << "." << endl;
}
des->errors += 1;
return 0;
}
/* Fallback, this may be an implicitly declared net. */
if (sig == 0) {
NetNet::Type nettype = scope->default_nettype();
sig = new NetNet(scope, lex_strings.make(path_.peek_name(0)),
nettype, 1);
sig = new NetNet(scope, path_.peek_name(0),
NetNet::IMPLICIT, 1);
if (error_implicit) {
if (error_implicit || (nettype == NetNet::NONE)) {
cerr << get_line() << ": error: "
<< scope->name() << "." << path_.peek_name(0)
<< " not defined in this scope." << endl;
@@ -1627,10 +1796,11 @@ NetNet* PEIdent::elaborate_lnet(Design*des, NetScope*scope,
}
if (sig == 0) {
NetNet::Type nettype = scope->default_nettype();
if (implicit_net_ok && !error_implicit) {
if (implicit_net_ok && !error_implicit && nettype!=NetNet::NONE) {
sig = new NetNet(scope, path_.peek_name(0),
sig = new NetNet(scope, lex_strings.make(path_.peek_name(0)),
NetNet::IMPLICIT, 1);
if (warn_implicit) {
@@ -1671,7 +1841,7 @@ NetNet* PEIdent::elaborate_lnet(Design*des, NetScope*scope,
if (msb_ && lsb_) {
/* Detect a part select. Evaluate the bits and elaborate
the l-value by creating a sub-net that links to just
the right pins. */
the right pins. */
verinum*mval = msb_->eval_const(des, scope);
assert(mval);
verinum*lval = lsb_->eval_const(des, scope);
@@ -1781,7 +1951,7 @@ NetNet* PEIdent::elaborate_port(Design*des, NetScope*scope) const
if (msb_ && lsb_) {
/* Detect a part select. Evaluate the bits and elaborate
the l-value by creating a sub-net that links to just
the right pins. */
the right pins. */
verinum*mval = msb_->eval_const(des, scope);
assert(mval);
verinum*lval = lsb_->eval_const(des, scope);
@@ -1859,6 +2029,7 @@ NetNet* PENumber::elaborate_net(Design*des, NetScope*scope,
NetNet*net = new NetNet(scope, scope->local_symbol(),
NetNet::IMPLICIT, lwidth);
net->local_flag(true);
net->set_signed(value_->has_sign());
/* when expanding a constant to fit into the net, extend
the Vx or Vz values if they are in the sign position,
@@ -1899,6 +2070,7 @@ NetNet* PENumber::elaborate_net(Design*des, NetScope*scope,
NetNet*net = new NetNet(scope, scope->local_symbol(),
NetNet::IMPLICIT, value_->len());
net->local_flag(true);
net->set_signed(value_->has_sign());
NetConst*tmp = new NetConst(scope, scope->local_symbol(),
*value_);
for (unsigned idx = 0 ; idx < value_->len() ; idx += 1)
@@ -2167,7 +2339,7 @@ NetNet* PEUnary::elaborate_net(Design*des, NetScope*scope,
break;
}
NetNet* sig;
NetNet* sig = 0;
NetLogic*gate;
// Handle the special case of a 2's complement of a constant
@@ -2206,6 +2378,9 @@ NetNet* PEUnary::elaborate_net(Design*des, NetScope*scope,
}
assert(sub_sig);
bool reduction=false;
NetLogic::TYPE gtype = NetLogic::AND;
switch (op_) {
case '~': // Bitwise NOT
sig = new NetNet(scope, scope->local_symbol(), NetNet::WIRE,
@@ -2225,95 +2400,17 @@ NetNet* PEUnary::elaborate_net(Design*des, NetScope*scope,
case 'N': // Reduction NOR
case '!': // Reduction NOT
sig = new NetNet(scope, scope->local_symbol(), NetNet::WIRE);
sig->local_flag(true);
gate = new NetLogic(scope, scope->local_symbol(),
1+sub_sig->pin_count(), NetLogic::NOR);
connect(gate->pin(0), sig->pin(0));
for (unsigned idx = 0 ; idx < sub_sig->pin_count() ; idx += 1)
connect(gate->pin(idx+1), sub_sig->pin(idx));
des->add_node(gate);
gate->rise_time(rise);
gate->fall_time(fall);
gate->decay_time(decay);
break;
reduction=true; gtype = NetLogic::NOR; break;
case '&': // Reduction AND
sig = new NetNet(scope, scope->local_symbol(), NetNet::WIRE);
sig->local_flag(true);
gate = new NetLogic(scope, scope->local_symbol(),
1+sub_sig->pin_count(), NetLogic::AND);
connect(gate->pin(0), sig->pin(0));
for (unsigned idx = 0 ; idx < sub_sig->pin_count() ; idx += 1)
connect(gate->pin(idx+1), sub_sig->pin(idx));
des->add_node(gate);
gate->rise_time(rise);
gate->fall_time(fall);
gate->decay_time(decay);
break;
reduction=true; gtype = NetLogic::AND; break;
case '|': // Reduction OR
sig = new NetNet(scope, scope->local_symbol(), NetNet::WIRE);
sig->local_flag(true);
gate = new NetLogic(scope, scope->local_symbol(),
1+sub_sig->pin_count(), NetLogic::OR);
connect(gate->pin(0), sig->pin(0));
for (unsigned idx = 0 ; idx < sub_sig->pin_count() ; idx += 1)
connect(gate->pin(idx+1), sub_sig->pin(idx));
des->add_node(gate);
gate->rise_time(rise);
gate->fall_time(fall);
gate->decay_time(decay);
break;
reduction=true; gtype = NetLogic::OR; break;
case '^': // Reduction XOR
sig = new NetNet(scope, scope->local_symbol(), NetNet::WIRE);
sig->local_flag(true);
gate = new NetLogic(scope, scope->local_symbol(),
1+sub_sig->pin_count(), NetLogic::XOR);
connect(gate->pin(0), sig->pin(0));
for (unsigned idx = 0 ; idx < sub_sig->pin_count() ; idx += 1)
connect(gate->pin(idx+1), sub_sig->pin(idx));
des->add_node(gate);
gate->rise_time(rise);
gate->fall_time(fall);
gate->decay_time(decay);
break;
reduction=true; gtype = NetLogic::XOR; break;
case 'A': // Reduction NAND (~&)
sig = new NetNet(scope, scope->local_symbol(), NetNet::WIRE);
sig->local_flag(true);
gate = new NetLogic(scope, scope->local_symbol(),
1+sub_sig->pin_count(), NetLogic::NAND);
connect(gate->pin(0), sig->pin(0));
for (unsigned idx = 0 ; idx < sub_sig->pin_count() ; idx += 1)
connect(gate->pin(idx+1), sub_sig->pin(idx));
des->add_node(gate);
gate->rise_time(rise);
gate->fall_time(fall);
gate->decay_time(decay);
break;
reduction=true; gtype = NetLogic::NAND; break;
case 'X': // Reduction XNOR (~^)
sig = new NetNet(scope, scope->local_symbol(), NetNet::WIRE);
sig->local_flag(true);
gate = new NetLogic(scope, scope->local_symbol(),
1+sub_sig->pin_count(), NetLogic::XNOR);
connect(gate->pin(0), sig->pin(0));
for (unsigned idx = 0 ; idx < sub_sig->pin_count() ; idx += 1)
connect(gate->pin(idx+1), sub_sig->pin(idx));
des->add_node(gate);
gate->rise_time(rise);
gate->fall_time(fall);
gate->decay_time(decay);
break;
reduction=true; gtype = NetLogic::XNOR; break;
case '-': // Unary 2's complement.
sig = new NetNet(scope, scope->local_symbol(),
@@ -2363,7 +2460,7 @@ NetNet* PEUnary::elaborate_net(Design*des, NetScope*scope,
default:
NetAddSub*sub = new NetAddSub(scope, scope->local_symbol(),
sig->pin_count());
sub->attribute("LPM_Direction", verinum("SUB"));
sub->attribute(perm_string::literal("LPM_Direction"), verinum("SUB"));
des->add_node(sub);
@@ -2396,13 +2493,76 @@ NetNet* PEUnary::elaborate_net(Design*des, NetScope*scope,
cerr << "internal error: Unhandled UNARY '" << op_ << "'" << endl;
sig = 0;
}
if (reduction) {
sig = new NetNet(scope, scope->local_symbol(), NetNet::WIRE);
sig->local_flag(true);
gate = new NetLogic(scope, scope->local_symbol(),
1+sub_sig->pin_count(), gtype);
connect(gate->pin(0), sig->pin(0));
for (unsigned idx = 0 ; idx < sub_sig->pin_count() ; idx += 1)
connect(gate->pin(idx+1), sub_sig->pin(idx));
des->add_node(gate);
gate->rise_time(rise);
gate->fall_time(fall);
gate->decay_time(decay);
}
return sig;
}
/*
* $Log: elab_net.cc,v $
* Revision 1.138 2004/10/04 03:09:38 steve
* Fix excessive error message.
*
* Revision 1.137 2004/10/04 01:10:52 steve
* Clean up spurious trailing white space.
*
* Revision 1.136 2004/10/04 00:25:46 steve
* Error message to match assertion.
*
* Revision 1.135 2004/09/24 04:25:19 steve
* Detect and prevent implicit declaration of hierarchical names.
*
* Revision 1.134 2004/08/28 15:42:12 steve
* Add support for $unsigned.
*
* Revision 1.133 2004/06/30 02:16:26 steve
* Implement signed divide and signed right shift in nets.
*
* Revision 1.132 2004/06/24 15:22:23 steve
* Code cleanup from Larry.
*
* Revision 1.131 2004/06/22 18:41:48 steve
* Fix broken calcuation of NE for constant.
*
* Revision 1.130 2004/06/18 16:38:22 steve
* compare-to-constant uses sig len, not val len.
*
* Revision 1.129 2004/06/16 23:32:58 steve
* Handle equality compare to constants specially.
*
* Revision 1.128 2004/06/13 04:56:53 steve
* Add support for the default_nettype directive.
*
* Revision 1.127 2004/06/01 01:04:57 steve
* Fix synthesis method for logical and/or
*
* Revision 1.126 2004/05/31 23:34:36 steve
* Rewire/generalize parsing an elaboration of
* function return values to allow for better
* speed and more type support.
*
* Revision 1.125 2004/02/20 18:53:34 steve
* Addtrbute keys are perm_strings.
*
* Revision 1.124 2004/02/18 17:11:54 steve
* Use perm_strings for named langiage items.
*
* Revision 1.123 2004/02/15 04:23:48 steve
* Fix evaluation of compare to constant expression.
*
* Revision 1.122 2003/10/30 04:31:34 steve
* Catch real variables in net expressions.
*
+10 -5
View File
@@ -17,12 +17,13 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: elab_pexpr.cc,v 1.20 2003/05/30 02:55:32 steve Exp $"
#ident "$Id: elab_pexpr.cc,v 1.21 2004/02/20 06:22:56 steve Exp $"
#endif
# include "config.h"
# include "PExpr.h"
# include "compiler.h"
# include "util.h"
# include <iostream>
@@ -136,19 +137,20 @@ NetExpr*PEIdent::elaborate_pexpr(Design*des, NetScope*scope) const
if (path.peek_name(0))
pscope = des->find_scope(scope, path);
const NetExpr*ex = pscope->get_parameter(name);
perm_string perm_name = lex_strings.make(name);
delete name;
const NetExpr*ex = pscope->get_parameter(perm_name);
if (ex == 0) {
cerr << get_line() << ": error: identifier ``" << path_ <<
"'' is not a parameter in " << scope->name() << "." << endl;
des->errors += 1;
delete name;
return 0;
}
NetExpr*res = new NetEParam(des, pscope, hname_t(name));
NetExpr*res = new NetEParam(des, pscope, perm_name);
res->set_line(*this);
assert(res);
delete name;
assert(idx_ == 0);
if (msb_ && lsb_) {
@@ -229,6 +231,9 @@ NetExpr*PEUnary::elaborate_pexpr (Design*des, NetScope*scope) const
/*
* $Log: elab_pexpr.cc,v $
* Revision 1.21 2004/02/20 06:22:56 steve
* parameter keys are per_strings.
*
* Revision 1.20 2003/05/30 02:55:32 steve
* Support parameters in real expressions and
* as real expressions, and fix multiply and
+183 -73
View File
@@ -17,12 +17,13 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: elab_scope.cc,v 1.27 2003/09/13 01:01:51 steve Exp $"
#ident "$Id: elab_scope.cc,v 1.35 2004/09/10 00:15:17 steve Exp $"
#endif
# include "config.h"
# include "compiler.h"
# include <iostream>
# include <stdio.h>
/*
* Elaboration happens in two passes, generally. The first scans the
@@ -46,6 +47,11 @@
bool Module::elaborate_scope(Design*des, NetScope*scope) const
{
if (debug_scopes) {
cerr << get_line() << ": debug: Elaborate scope "
<< scope->name() << "." << endl;
}
// Generate all the parameters that this instance of this
// module introduces to the design. This loop elaborates the
// parameters, but doesn't evaluate references to
@@ -57,7 +63,7 @@ bool Module::elaborate_scope(Design*des, NetScope*scope) const
// the pform and just place a NetEParam placeholder in the
// place of the elaborated expression.
typedef map<string,param_expr_t>::const_iterator mparm_it_t;
typedef map<perm_string,param_expr_t>::const_iterator mparm_it_t;
typedef map<hname_t,PExpr*>::const_iterator hparm_it_t;
@@ -129,7 +135,25 @@ bool Module::elaborate_scope(Design*des, NetScope*scope) const
assert(ex);
NetExpr*val = ex->elaborate_pexpr(des, scope);
val = scope->set_parameter((*cur).first, val, 0, 0, false);
NetExpr*msb = 0;
NetExpr*lsb = 0;
bool signed_flag = false;
/* If the parameter declaration includes msb and lsb,
then use them to calculate a width for the
result. Then make sure the constant expression of the
parameter value is coerced to have the correct
and defined width. */
if ((*cur).second.msb) {
msb = (*cur).second.msb ->elaborate_pexpr(des, scope);
assert(msb);
lsb = (*cur).second.lsb ->elaborate_pexpr(des, scope);
signed_flag = (*cur).second.signed_flag;
}
val->cast_signed(signed_flag);
val = scope->set_parameter((*cur).first, val,
msb, lsb, signed_flag);
assert(val);
delete val;
}
@@ -171,12 +195,12 @@ bool Module::elaborate_scope(Design*des, NetScope*scope) const
// elaborate_scope method of the PTask for detailed
// processing.
typedef map<string,PTask*>::const_iterator tasks_it_t;
typedef map<perm_string,PTask*>::const_iterator tasks_it_t;
for (tasks_it_t cur = tasks_.begin()
; cur != tasks_.end() ; cur ++ ) {
NetScope*task_scope = new NetScope(scope, (*cur).first.c_str(),
NetScope*task_scope = new NetScope(scope, (*cur).first,
NetScope::TASK);
(*cur).second->elaborate_scope(des, task_scope);
}
@@ -186,12 +210,12 @@ bool Module::elaborate_scope(Design*des, NetScope*scope) const
// perspective of scopes. So handle them exactly the same
// way.
typedef map<string,PFunction*>::const_iterator funcs_it_t;
typedef map<perm_string,PFunction*>::const_iterator funcs_it_t;
for (funcs_it_t cur = funcs_.begin()
; cur != funcs_.end() ; cur ++ ) {
NetScope*func_scope = new NetScope(scope, (*cur).first.c_str(),
NetScope*func_scope = new NetScope(scope, (*cur).first,
NetScope::FUNC);
(*cur).second->elaborate_scope(des, func_scope);
}
@@ -201,7 +225,6 @@ bool Module::elaborate_scope(Design*des, NetScope*scope) const
// scan all of them to create those scopes.
typedef list<PGate*>::const_iterator gates_it_t;
for (gates_it_t cur = gates_.begin()
; cur != gates_.end() ; cur ++ ) {
@@ -226,7 +249,7 @@ bool Module::elaborate_scope(Design*des, NetScope*scope) const
// elaboration, so do it now. This allows for normal
// elaboration to reference these events.
for (map<string,PEvent*>::const_iterator et = events.begin()
for (map<perm_string,PEvent*>::const_iterator et = events.begin()
; et != events.end() ; et ++ ) {
(*et).second->elaborate_scope(des, scope);
@@ -287,79 +310,142 @@ void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const
return;
}
// Create the new scope as a MODULE with my name.
NetScope*my_scope = new NetScope(sc, get_name().c_str(), NetScope::MODULE);
my_scope->set_module_name(mod->mod_name());
verinum*msb = msb_ ? msb_->eval_const(des, sc) : 0;
verinum*lsb = lsb_ ? lsb_->eval_const(des, sc) : 0;
// Set time units and precision.
my_scope->time_unit(mod->time_unit);
my_scope->time_precision(mod->time_precision);
des->set_precision(mod->time_precision);
assert( (msb == 0) || (lsb != 0) );
// This call actually arranges for the description of the
// module type to process this instance and handle parameters
// and sub-scopes that might occur. Parameters are also
// created in that scope, as they exist. (I'll override them
// later.)
mod->elaborate_scope(des, my_scope);
long instance_low = 0;
long instance_high = 0;
long instance_count = 1;
bool instance_array = false;
// Look for module parameter replacements. The "replace" map
// maps parameter name to replacement expression that is
// passed. It is built up by the ordered overrides or named
// overrides.
if (msb) {
instance_array = true;
instance_high = msb->as_long();
instance_low = lsb->as_long();
if (instance_high > instance_low)
instance_count = instance_high - instance_low + 1;
else
instance_count = instance_low - instance_high + 1;
}
typedef map<string,PExpr*>::const_iterator mparm_it_t;
map<string,PExpr*> replace;
NetScope::scope_vec_t instances (instance_count);
if (debug_scopes) {
cerr << get_line() << ": debug: Create " << instance_count
<< " instances of " << get_name()
<< "." << endl;
}
// Run through the module instances, and make scopes out of
// them. Also do parameter overrides that are done on the
// instantiation line.
for (int idx = 0 ; idx < instance_count ; idx += 1) {
perm_string use_name = get_name();
if (instance_array) {
char name_buf[128];
int instance_idx = idx;
if (instance_low < instance_high)
instance_idx = instance_low + idx;
else
instance_idx = instance_low - idx;
snprintf(name_buf, sizeof name_buf,
"%s[%d]", get_name().str(), instance_idx);
use_name = lex_strings.make(name_buf);
}
if (debug_scopes) {
cerr << get_line() << ": debug: Module instance " << use_name
<< " becomes child of " << sc->name()
<< "." << endl;
}
// Create the new scope as a MODULE with my name.
NetScope*my_scope = new NetScope(sc, use_name, NetScope::MODULE);
my_scope->set_module_name(mod->mod_name());
my_scope->default_nettype(mod->default_nettype);
instances[idx] = my_scope;
// Set time units and precision.
my_scope->time_unit(mod->time_unit);
my_scope->time_precision(mod->time_precision);
des->set_precision(mod->time_precision);
// This call actually arranges for the description of the
// module type to process this instance and handle parameters
// and sub-scopes that might occur. Parameters are also
// created in that scope, as they exist. (I'll override them
// later.)
mod->elaborate_scope(des, my_scope);
// Look for module parameter replacements. The "replace" map
// maps parameter name to replacement expression that is
// passed. It is built up by the ordered overrides or named
// overrides.
typedef map<perm_string,PExpr*>::const_iterator mparm_it_t;
map<perm_string,PExpr*> replace;
// Positional parameter overrides are matched to parameter
// names by using the param_names list of parameter
// names. This is an ordered list of names so the first name
// is parameter 0, the second parameter 1, and so on.
// Positional parameter overrides are matched to parameter
// names by using the param_names list of parameter
// names. This is an ordered list of names so the first name
// is parameter 0, the second parameter 1, and so on.
if (overrides_) {
assert(parms_ == 0);
list<string>::const_iterator cur = mod->param_names.begin();
unsigned idx = 0;
for (;;) {
if (idx >= overrides_->count())
break;
if (cur == mod->param_names.end())
break;
if (overrides_) {
assert(parms_ == 0);
list<perm_string>::const_iterator cur
= mod->param_names.begin();
unsigned idx = 0;
for (;;) {
if (idx >= overrides_->count())
break;
if (cur == mod->param_names.end())
break;
replace[*cur] = (*overrides_)[idx];
replace[*cur] = (*overrides_)[idx];
idx += 1;
cur ++;
idx += 1;
cur ++;
}
}
// Named parameter overrides carry a name with each override
// so the mapping into the replace list is much easier.
if (parms_) {
assert(overrides_ == 0);
for (unsigned idx = 0 ; idx < nparms_ ; idx += 1)
replace[parms_[idx].name] = parms_[idx].parm;
}
// And here we scan the replacements we collected. Elaborate
// the expression in my context, then replace the sub-scope
// parameter value with the new expression.
for (mparm_it_t cur = replace.begin()
; cur != replace.end() ; cur ++ ) {
PExpr*tmp = (*cur).second;
NetExpr*val = tmp->elaborate_pexpr(des, sc);
bool flag = my_scope->replace_parameter((*cur).first, val);
if (! flag) {
cerr << val->get_line() << ": warning: parameter "
<< (*cur).first << " not found in "
<< sc->name() << "." << endl;
}
}
}
// Named parameter overrides carry a name with each override
// so the mapping into the replace list is much easier.
if (parms_) {
assert(overrides_ == 0);
for (unsigned idx = 0 ; idx < nparms_ ; idx += 1)
replace[parms_[idx].name] = parms_[idx].parm;
}
// And here we scan the replacements we collected. Elaborate
// the expression in my context, then replace the sub-scope
// parameter value with the new expression.
for (mparm_it_t cur = replace.begin()
; cur != replace.end() ; cur ++ ) {
PExpr*tmp = (*cur).second;
NetExpr*val = tmp->elaborate_pexpr(des, sc);
bool flag = my_scope->replace_parameter((*cur).first, val);
if (! flag) {
cerr << val->get_line() << ": warning: parameter "
<< (*cur).first << " not found in "
<< sc->name() << "." << endl;
}
}
/* Stash the instance array of scopes into the parent
scope. Later elaboration passes will use this vector to
further elaborate the array. */
sc->instance_arrays[get_name()] = instances;
}
/*
@@ -385,7 +471,7 @@ void PData::elaborate_scope(Design*des, NetScope*scope) const
}
const char*basename = hname_.peek_tail_name();
NetVariable*tmp = new NetVariable(lex_strings.add(basename));
NetVariable*tmp = new NetVariable(lex_strings.make(basename));
tmp->set_line(*this);
sub_scope->add_variable(tmp);
}
@@ -439,8 +525,8 @@ void PBlock::elaborate_scope(Design*des, NetScope*scope) const
{
NetScope*my_scope = scope;
if (name_ != "") {
my_scope = new NetScope(scope, name_.c_str(), bl_type_==BL_PAR
if (name_ != 0) {
my_scope = new NetScope(scope, name_, bl_type_==BL_PAR
? NetScope::FORK_JOIN
: NetScope::BEGIN_END);
}
@@ -549,6 +635,30 @@ void PWhile::elaborate_scope(Design*des, NetScope*scope) const
/*
* $Log: elab_scope.cc,v $
* Revision 1.35 2004/09/10 00:15:17 steve
* Missing stdio.h header for warnings.
*
* Revision 1.34 2004/09/05 17:44:41 steve
* Add support for module instance arrays.
*
* Revision 1.33 2004/08/26 04:02:03 steve
* Add support for localparam ranges.
*
* Revision 1.32 2004/06/13 04:56:54 steve
* Add support for the default_nettype directive.
*
* Revision 1.31 2004/05/25 19:21:06 steve
* More identifier lists use perm_strings.
*
* Revision 1.30 2004/02/20 06:22:56 steve
* parameter keys are per_strings.
*
* Revision 1.29 2004/02/19 07:06:57 steve
* LPM, logic and Variables have perm_string names.
*
* Revision 1.28 2004/02/18 17:11:55 steve
* Use perm_strings for named langiage items.
*
* Revision 1.27 2003/09/13 01:01:51 steve
* Spelling fixes.
*
+137 -39
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2000 Stephen Williams (steve@icarus.com)
* Copyright (c) 2000-2004 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: elab_sig.cc,v 1.32 2003/09/20 05:24:00 steve Exp $"
#ident "$Id: elab_sig.cc,v 1.36 2004/09/27 22:34:10 steve Exp $"
#endif
# include "config.h"
@@ -29,6 +29,7 @@
# include "PGate.h"
# include "PTask.h"
# include "PWire.h"
# include "compiler.h"
# include "netlist.h"
# include "netmisc.h"
# include "util.h"
@@ -174,7 +175,7 @@ bool Module::elaborate_sig(Design*des, NetScope*scope) const
}
typedef map<string,PFunction*>::const_iterator mfunc_it_t;
typedef map<perm_string,PFunction*>::const_iterator mfunc_it_t;
for (mfunc_it_t cur = funcs_.begin()
; cur != funcs_.end() ; cur ++) {
@@ -195,7 +196,7 @@ bool Module::elaborate_sig(Design*des, NetScope*scope) const
// elaborate the ports of the tasks defined within this
// module. Run through them now.
typedef map<string,PTask*>::const_iterator mtask_it_t;
typedef map<perm_string,PTask*>::const_iterator mtask_it_t;
for (mtask_it_t cur = tasks_.begin()
; cur != tasks_.end() ; cur ++) {
@@ -210,31 +211,42 @@ bool Module::elaborate_sig(Design*des, NetScope*scope) const
bool PGModule::elaborate_sig_mod_(Design*des, NetScope*scope,
Module*rmod) const
{
// Missing module instance names have already been rejected.
assert(get_name() != "");
bool flag = true;
NetScope::scope_vec_t instance = scope->instance_arrays[get_name()];
for (unsigned idx = 0 ; idx < instance.count() ; idx += 1) {
// I know a priori that the elaborate_scope created the scope
// already, so just look it up as a child of the current scope.
NetScope*my_scope = instance[idx];
assert(my_scope);
if (my_scope->parent() != scope) {
cerr << get_line() << ": internal error: "
<< "Instance " << my_scope->name()
<< " is in parent " << my_scope->parent()->name()
<< " instead of " << scope->name()
<< endl;
}
assert(my_scope->parent() == scope);
if (! rmod->elaborate_sig(des, my_scope))
flag = false;
if (msb_) {
cerr << get_line() << ": sorry: Module instantiation arrays "
"are not yet supported." << endl;
des->errors += 1;
return false;
}
// I know a priori that the elaborate_scope created the scope
// already, so just look it up as a child of the current scope.
NetScope*my_scope = scope->child(get_name());
assert(my_scope);
return rmod->elaborate_sig(des, my_scope);
return flag;
}
/*
* A function definition exists within an elaborated module.
* A function definition exists within an elaborated module. This
* matters when elaborating signals, as the ports of the function are
* created as signals/variables for each instance of the
* function. That is why PFunction has an elaborate_sig method.
*/
void PFunction::elaborate_sig(Design*des, NetScope*scope) const
{
string fname = scope->basename();
perm_string fname = scope->basename();
assert(scope->type() == NetScope::FUNC);
/* Make sure the function has at least one input port. If it
@@ -248,21 +260,81 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const
des->errors += 1;
}
svector<NetNet*>ports (ports_? ports_->count()+1 : 1);
NetNet*ret_sig = 0;
NetVariable*ret_real = 0;
/* Get the reg for the return value. I know the name of the
reg variable, and I know that it is in this scope, so look
it up directly. */
ports[0] = scope->find_signal(scope->basename());
if (ports[0] == 0) {
cerr << get_line() << ": internal error: function scope "
<< scope->name() << " is missing return reg "
<< fname << "." << endl;
scope->dump(cerr);
des->errors += 1;
return;
/* Create the signals/variables of the return value and write
them into the function scope. */
switch (return_type_.type) {
case PTF_REG:
if (return_type_.range) {
NetExpr*me = elab_and_eval(des, scope,
(*return_type_.range)[0]);
assert(me);
NetExpr*le = elab_and_eval(des, scope,
(*return_type_.range)[1]);
assert(le);
long mnum = 0, lnum = 0;
if (NetEConst*tmp = dynamic_cast<NetEConst*>(me)) {
mnum = tmp->value().as_long();
} else {
cerr << me->get_line() << ": error: "
"Unable to evaluate constant expression "
<< *me << "." << endl;
des->errors += 1;
}
if (NetEConst*tmp = dynamic_cast<NetEConst*>(le)) {
lnum = tmp->value().as_long();
} else {
cerr << le->get_line() << ": error: "
"Unable to evaluate constant expression "
<< *le << "." << endl;
des->errors += 1;
}
ret_sig = new NetNet(scope, fname, NetNet::REG, mnum, lnum);
} else {
ret_sig = new NetNet(scope, fname, NetNet::REG);
}
ret_sig->set_line(*this);
ret_sig->port_type(NetNet::POUTPUT);
break;
case PTF_INTEGER:
ret_sig = new NetNet(scope, fname, NetNet::REG, INTEGER_WIDTH);
ret_sig->set_line(*this);
ret_sig->set_signed(true);
ret_sig->set_isint(true);
ret_sig->port_type(NetNet::POUTPUT);
break;
case PTF_TIME:
ret_sig = new NetNet(scope, fname, NetNet::REG, 64);
ret_sig->set_line(*this);
ret_sig->set_signed(false);
ret_sig->set_isint(false);
ret_sig->port_type(NetNet::POUTPUT);
break;
case PTF_REAL:
case PTF_REALTIME:
ret_real = new NetVariable(fname);
ret_real->set_line(*this);
scope->add_variable(ret_real);
break;
default:
cerr << get_line() << ": internal error: I don't know how "
<< "to deal with return type of function "
<< scope->basename() << "." << endl;
}
svector<NetNet*>ports (ports_? ports_->count() : 0);
if (ports_)
for (unsigned idx = 0 ; idx < ports_->count() ; idx += 1) {
@@ -271,8 +343,8 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const
as two components: <func>.<port>. */
hname_t path = (*ports_)[idx]->path();
string pname = path.peek_name(1);
string ppath = path.peek_name(0);
perm_string pname = lex_strings.make(path.peek_name(1));
perm_string ppath = lex_strings.make(path.peek_name(0));
if (ppath != scope->basename()) {
cerr << get_line() << ": internal error: function "
@@ -288,14 +360,19 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const
<< scope->name() << " is missing port "
<< pname << "." << endl;
scope->dump(cerr);
cerr << get_line() << ": Continuing..." << endl;
des->errors += 1;
}
ports[idx+1] = tmp;
ports[idx] = tmp;
}
NetFuncDef*def = new NetFuncDef(scope, ports);
NetFuncDef*def = 0;
if (ret_sig) def = new NetFuncDef(scope, ret_sig, ports);
if (ret_real) def = new NetFuncDef(scope, ret_real, ports);
assert(def);
scope->set_func_def(def);
}
@@ -366,6 +443,7 @@ bool PGate::elaborate_sig(Design*des, NetScope*scope) const
*/
void PWire::elaborate_sig(Design*des, NetScope*scope) const
{
/* The parser may produce hierarchical names for wires. I here
follow the scopes down to the base where I actually want to
elaborate the NetNet object. */
@@ -373,7 +451,13 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
free(tmp_path.remove_tail_name());
for (unsigned idx = 0 ; tmp_path.peek_name(idx) ; idx += 1) {
scope = scope->child(tmp_path.peek_name(idx));
assert(scope);
if (scope == 0) {
cerr << get_line() << ": internal error: "
<< "Bad scope component for name "
<< hname_ << endl;
assert(scope);
}
}
}
@@ -514,7 +598,7 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
delete lexp;
delete rexp;
string name = hname_.peek_tail_name();
perm_string name = lex_strings.make(hname_.peek_tail_name());
long lnum = lval.as_long();
long rnum = rval.as_long();
@@ -525,7 +609,7 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
} else {
string name = hname_.peek_tail_name();
perm_string name = lex_strings.make(hname_.peek_tail_name());
NetNet*sig = new NetNet(scope, name, wtype, msb, lsb);
sig->set_line(*this);
sig->port_type(port_type_);
@@ -539,6 +623,20 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
/*
* $Log: elab_sig.cc,v $
* Revision 1.36 2004/09/27 22:34:10 steve
* Cleanup and factoring of autoconf.
*
* Revision 1.35 2004/09/05 17:44:41 steve
* Add support for module instance arrays.
*
* Revision 1.34 2004/05/31 23:34:37 steve
* Rewire/generalize parsing an elaboration of
* function return values to allow for better
* speed and more type support.
*
* Revision 1.33 2004/02/18 17:11:55 steve
* Use perm_strings for named langiage items.
*
* Revision 1.32 2003/09/20 05:24:00 steve
* Evaluate memory index constants using elab_and_eval.
*
+373 -169
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998-2003 Stephen Williams (steve@icarus.com)
* Copyright (c) 1998-2004 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: elaborate.cc,v 1.293 2003/10/26 04:49:51 steve Exp $"
#ident "$Id: elaborate.cc,v 1.308 2004/10/04 01:10:52 steve Exp $"
#endif
# include "config.h"
@@ -176,8 +176,8 @@ void PGAssign::elaborate(Design*des, NetScope*scope) const
} else {
verinum tmpv (0UL, lval->pin_count()-cnt);
NetConst*tmp = new NetConst(scope,
scope->local_symbol(),
tmpv);
scope->local_symbol(),
tmpv);
des->add_node(tmp);
for (idx = cnt
; idx < lval->pin_count()
@@ -191,8 +191,7 @@ void PGAssign::elaborate(Design*des, NetScope*scope) const
strength and delays. */
unsigned idx;
for (idx = 0 ; idx < cnt ; idx += 1) {
NetBUFZ*dev = new NetBUFZ(scope,
scope->local_symbol());
NetBUFZ*dev = new NetBUFZ(scope,scope->local_symbol());
connect(lval->pin(idx), dev->pin(0));
connect(rid->pin(idx), dev->pin(1));
dev->rise_time(rise_time);
@@ -212,9 +211,9 @@ void PGAssign::elaborate(Design*des, NetScope*scope) const
} else {
NetConst*dev = new NetConst(scope,
scope->local_symbol(),
verinum::V0);
scope->local_symbol(),
verinum::V0);
des->add_node(dev);
dev->pin(0).drive0(drive0);
dev->pin(0).drive1(drive1);
@@ -269,7 +268,7 @@ void PGBuiltin::elaborate(Design*des, NetScope*scope) const
{
unsigned count = 1;
long low = 0, high = 0;
string name = get_name();
string name = string(get_name());
if (name == "")
name = scope->local_symbol();
@@ -351,7 +350,7 @@ void PGBuiltin::elaborate(Design*des, NetScope*scope) const
index = low - idx;
tmp << name << "<" << index << ">";
const string inm = tmp.str();
perm_string inm = lex_strings.make(tmp.str());
switch (type()) {
case AND:
@@ -493,24 +492,15 @@ void PGBuiltin::elaborate(Design*des, NetScope*scope) const
*/
void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
{
// Missing module instance names have already been rejected.
assert(get_name() != "");
if (msb_) {
cerr << get_line() << ": sorry: Module instantiation arrays "
"are not yet supported." << endl;
des->errors += 1;
return;
}
assert(scope);
// I know a priori that the elaborate_scope created the scope
// already, so just look it up as a child of the current scope.
NetScope*my_scope = scope->child(get_name());
assert(my_scope);
const svector<PExpr*>*pins;
// This is the array of pin expressions, shuffled to match the
// order of the declaration. If the source instantiation uses
// bind by order, this is the same as the source
// list. Otherwise, the source list is rearranged by name
// binding into this list.
svector<PExpr*>pins (rmod->port_count());
// Detect binding by name. If I am binding by name, then make
// up a pins array that reflects the positions of the named
@@ -518,7 +508,6 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
// place, then get the binding from the base class.
if (pins_) {
unsigned nexp = rmod->port_count();
svector<PExpr*>*exp = new svector<PExpr*>(nexp);
// Scan the bindings, matching them with port names.
for (unsigned idx = 0 ; idx < npins_ ; idx += 1) {
@@ -541,7 +530,7 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
// If I already bound something to this port, then
// the (*exp) array will already have a pointer
// value where I want to place this expression.
if ((*exp)[pidx]) {
if (pins[pidx]) {
cerr << get_line() << ": error: port ``" <<
pins_[idx].name << "'' already bound." <<
endl;
@@ -551,10 +540,9 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
// OK, do the binding by placing the expression in
// the right place.
(*exp)[pidx] = pins_[idx].parm;
pins[pidx] = pins_[idx].parm;
}
pins = exp;
} else if (pin_count() == 0) {
@@ -563,11 +551,8 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
connect-by-name list, so we'll allow it and assume
that is the case. */
svector<PExpr*>*tmp = new svector<PExpr*>(rmod->port_count());
for (unsigned idx = 0 ; idx < rmod->port_count() ; idx += 1)
(*tmp)[idx] = 0;
pins = tmp;
pins[idx] = 0;
} else {
@@ -590,11 +575,18 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
pins = get_pins();
}
// Elaborate this instance of the module. The recursive
// Elaborate these instances of the module. The recursive
// elaboration causes the module to generate a netlist with
// the ports represented by NetNet objects. I will find them
// later.
rmod->elaborate(des, my_scope);
NetScope::scope_vec_t&instance = scope->instance_arrays[get_name()];
for (unsigned inst = 0 ; inst < instance.count() ; inst += 1) {
rmod->elaborate(des, instance[inst]);
}
// Now connect the ports of the newly elaborated designs to
// the expressions that are the instantiation parameters. Scan
@@ -606,12 +598,12 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
// to a concatenation, or connected to an internally
// unconnected port.
for (unsigned idx = 0 ; idx < pins->count() ; idx += 1) {
for (unsigned idx = 0 ; idx < pins.count() ; idx += 1) {
// Skip unconnected module ports. This happens when a
// null parameter is passed in.
if ((*pins)[idx] == 0) {
if (pins[idx] == 0) {
// While we're here, look to see if this
// unconnected (from the outside) port is an
@@ -622,7 +614,7 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
if (mport.count() == 0)
continue;
NetNet*tmp = des->find_signal(my_scope,
NetNet*tmp = des->find_signal(instance[0],
mport[0]->path());
assert(tmp);
@@ -640,47 +632,59 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
}
// Inside the module, the port is zero or more signals
// that were already elaborated. List all those signals
// and the NetNet equivalents.
// and the NetNet equivalents, for all the instances.
svector<PEIdent*> mport = rmod->get_port(idx);
svector<NetNet*>prts (mport.count());
svector<NetNet*>prts (mport.count() * instance.count());
// Count the internal pins of the port.
unsigned prts_pin_count = 0;
for (unsigned ldx = 0 ; ldx < mport.count() ; ldx += 1) {
PEIdent*pport = mport[ldx];
assert(pport);
prts[ldx] = pport->elaborate_port(des, my_scope);
if (prts[ldx] == 0)
continue;
assert(prts[ldx]);
prts_pin_count += prts[ldx]->pin_count();
for (unsigned inst = 0 ; inst < instance.count() ; inst += 1) {
NetScope*inst_scope = instance[inst];
// Scan the module sub-ports for this instance...
for (unsigned ldx = 0 ; ldx < mport.count() ; ldx += 1) {
unsigned lbase = inst * mport.count();
PEIdent*pport = mport[ldx];
assert(pport);
prts[lbase + ldx]
= pport->elaborate_port(des, inst_scope);
if (prts[lbase + ldx] == 0)
continue;
assert(prts[lbase + ldx]);
prts_pin_count += prts[lbase + ldx]->pin_count();
}
}
// If I find that the port in unconnected inside the
// module, then there is nothing to connect. Skip the
// parameter.
// argument.
if (prts_pin_count == 0) {
continue;
}
// Elaborate the expression that connects to the module
// port. sig is the thing outside the module that
// connects to the port.
// We know by design that each instance has the same
// width port. Therefore, the prts_pin_count must be an
// even multiple of the instance count.
assert(prts_pin_count % instance.count() == 0);
// Elaborate the expression that connects to the
// module[s] port. sig is the thing outside the module
// that connects to the port.
NetNet*sig;
if ((prts.count() >= 1)
&& (prts[0]->port_type() != NetNet::PINPUT)) {
sig = (*pins)[idx]->elaborate_lnet(des, scope, true);
sig = pins[idx]->elaborate_lnet(des, scope, true);
if (sig == 0) {
cerr << (*pins)[idx]->get_line() << ": error: "
cerr << pins[idx]->get_line() << ": error: "
<< "Output port expression must support "
<< "continuous assignment." << endl;
cerr << (*pins)[idx]->get_line() << ": : "
cerr << pins[idx]->get_line() << ": : "
<< "Port of " << rmod->mod_name()
<< " is " << rmod->ports[idx]->name << endl;
des->errors += 1;
@@ -688,11 +692,20 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
}
} else {
sig = (*pins)[idx]->elaborate_net(des, scope,
prts_pin_count,
0, 0, 0);
/* Input to module. elaborate the expression to
the desired width. If this in an instance
array, then let the net determine it's own
width. We use that, then, to decide how to hook
it up. */
unsigned desired_pin_count = prts_pin_count;
if (instance.count() != 1)
desired_pin_count = 0;
sig = pins[idx]->elaborate_net(des, scope,
desired_pin_count,
0, 0, 0);
if (sig == 0) {
cerr << (*pins)[idx]->get_line()
cerr << pins[idx]->get_line()
<< ": internal error: Port expression "
<< "too complicated for elaboration." << endl;
continue;
@@ -708,10 +721,25 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
}
#endif
/* If we are working with an instance array, then the
signal width must match the port width exactly. */
if ((instance.count() != 1)
&& (sig->pin_count() != prts_pin_count)
&& (sig->pin_count() != prts_pin_count/instance.count())) {
cerr << pins[idx]->get_line() << ": error: "
<< "Port expression width " << sig->pin_count()
<< " does not match expected width " << prts_pin_count
<< " or " << (prts_pin_count/instance.count())
<< "." << endl;
des->errors += 1;
continue;
}
// Check that the parts have matching pin counts. If
// not, they are different widths. Note that idx is 0
// based, but users count parameter positions from 1.
if (prts_pin_count != sig->pin_count()) {
if ((instance.count() == 1)
&& (prts_pin_count != sig->pin_count())) {
cerr << get_line() << ": warning: Port " << (idx+1)
<< " (" << rmod->ports[idx]->name << ") of "
<< type_ << " expects " << prts_pin_count <<
@@ -742,9 +770,17 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
// Connect this many of the port pins. If the expression
// is too small, the reduce the number of connects.
unsigned ccount = prts_pin_count;
if (sig->pin_count() < ccount)
if (instance.count() == 1 && sig->pin_count() < ccount)
ccount = sig->pin_count();
// The spin_modulus is the width of the signal (not the
// port) if this is an instance array. This causes
// signals wide enough for a single instance to be
// connected to all the instances.
unsigned spin_modulus = prts_pin_count;
if (instance.count() != 1)
spin_modulus = sig->pin_count();
// Now scan the concatenation that makes up the port,
// connecting pins until we run out of port pins or sig
// pins.
@@ -755,7 +791,8 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
if (cnt > ccount)
cnt = ccount;
for (unsigned p = 0 ; p < cnt ; p += 1) {
connect(sig->pin(spin), prts[ldx-1]->pin(p));
connect(sig->pin(spin%spin_modulus),
prts[ldx-1]->pin(p));
ccount -= 1;
spin += 1;
}
@@ -767,6 +804,7 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
if (NetSubnet*tmp = dynamic_cast<NetSubnet*>(sig))
delete tmp;
}
}
/*
@@ -778,8 +816,8 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
void PGModule::elaborate_udp_(Design*des, PUdp*udp, NetScope*scope) const
{
string my_name = get_name();
if (my_name == "")
perm_string my_name = get_name();
if (my_name == 0)
my_name = scope->local_symbol();
/* When the parser notices delay expressions in front of a
@@ -793,6 +831,7 @@ void PGModule::elaborate_udp_(Design*des, PUdp*udp, NetScope*scope) const
}
assert(udp);
NetUDP*net = new NetUDP(scope, my_name, udp->ports.count(), udp);
net->rise_time(rise_time);
net->fall_time(fall_time);
@@ -808,17 +847,110 @@ void PGModule::elaborate_udp_(Design*des, PUdp*udp, NetScope*scope) const
delete[]attrib_list;
// This is the array of pin expressions, shuffled to match the
// order of the declaration. If the source instantiation uses
// bind by order, this is the same as the source
// list. Otherwise, the source list is rearranged by name
// binding into this list.
svector<PExpr*>pins;
// Detect binding by name. If I am binding by name, then make
// up a pins array that reflects the positions of the named
// ports. If this is simply positional binding in the first
// place, then get the binding from the base class.
if (pins_) {
unsigned nexp = udp->ports.count();
pins = svector<PExpr*>(nexp);
// Scan the bindings, matching them with port names.
for (unsigned idx = 0 ; idx < npins_ ; idx += 1) {
// Given a binding, look at the module port names
// for the position that matches the binding name.
unsigned pidx = udp->find_port(pins_[idx].name);
// If the port name doesn't exist, the find_port
// method will return the port count. Detect that
// as an error.
if (pidx == nexp) {
cerr << get_line() << ": error: port ``" <<
pins_[idx].name << "'' is not a port of "
<< get_name() << "." << endl;
des->errors += 1;
continue;
}
// If I already bound something to this port, then
// the (*exp) array will already have a pointer
// value where I want to place this expression.
if (pins[pidx]) {
cerr << get_line() << ": error: port ``" <<
pins_[idx].name << "'' already bound." <<
endl;
des->errors += 1;
continue;
}
// OK, do the binding by placing the expression in
// the right place.
pins[pidx] = pins_[idx].parm;
}
} else {
/* Otherwise, this is a positional list of port
connections. In this case, the port count must be
right. Check that is is, the get the pin list. */
if (pin_count() != udp->ports.count()) {
cerr << get_line() << ": error: Wrong number "
"of ports. Expecting " << udp->ports.count() <<
", got " << pin_count() << "."
<< endl;
des->errors += 1;
return;
}
// No named bindings, just use the positional list I
// already have.
assert(pin_count() == udp->ports.count());
pins = get_pins();
}
/* Handle the output port of the primitive special. It is an
output port (the only output port) so must be passed an
l-value net. */
if (pins[0] == 0) {
cerr << get_line() << ": warning: output port unconnected."
<< endl;
} else {
NetNet*sig = pins[0]->elaborate_lnet(des, scope, true);
if (sig == 0) {
cerr << get_line() << ": error: "
<< "Output port expression is not valid." << endl;
cerr << get_line() << ": : Output "
<< "port of " << udp->name_
<< " is " << udp->ports[0] << "." << endl;
des->errors += 1;
} else {
connect(sig->pin(0), net->pin(0));
}
}
/* Run through the pins, making netlists for the pin
expressions and connecting them to the pin in question. All
of this is independent of the nature of the UDP. */
for (unsigned idx = 0 ; idx < net->pin_count() ; idx += 1) {
if (pin(idx) == 0)
for (unsigned idx = 1 ; idx < net->pin_count() ; idx += 1) {
if (pins[idx] == 0)
continue;
NetNet*sig = pin(idx)->elaborate_net(des, scope, 1, 0, 0, 0);
NetNet*sig = pins[idx]->elaborate_net(des, scope, 1, 0, 0, 0);
if (sig == 0) {
cerr << "internal error: Expression too complicated "
"for elaboration:" << *pin(idx) << endl;
"for elaboration:" << pins[idx] << endl;
continue;
}
@@ -828,7 +960,7 @@ void PGModule::elaborate_udp_(Design*des, PUdp*udp, NetScope*scope) const
if (NetSubnet*tmp = dynamic_cast<NetSubnet*>(sig))
delete tmp;
}
// All done. Add the object to the design.
des->add_node(net);
}
@@ -837,7 +969,7 @@ void PGModule::elaborate_udp_(Design*des, PUdp*udp, NetScope*scope) const
bool PGModule::elaborate_sig(Design*des, NetScope*scope) const
{
// Look for the module type
map<string,Module*>::const_iterator mod = pform_modules.find(type_);
map<perm_string,Module*>::const_iterator mod = pform_modules.find(type_);
if (mod != pform_modules.end())
return elaborate_sig_mod_(des, scope, (*mod).second);
@@ -848,15 +980,16 @@ bool PGModule::elaborate_sig(Design*des, NetScope*scope) const
void PGModule::elaborate(Design*des, NetScope*scope) const
{
// Look for the module type
map<string,Module*>::const_iterator mod = pform_modules.find(type_);
map<perm_string,Module*>::const_iterator mod = pform_modules.find(type_);
if (mod != pform_modules.end()) {
elaborate_mod_(des, (*mod).second, scope);
return;
}
// Try a primitive type
map<string,PUdp*>::const_iterator udp = pform_primitives.find(type_);
map<perm_string,PUdp*>::const_iterator udp = pform_primitives.find(type_);
if (udp != pform_primitives.end()) {
assert((*udp).second);
elaborate_udp_(des, (*udp).second, scope);
return;
}
@@ -868,14 +1001,14 @@ void PGModule::elaborate(Design*des, NetScope*scope) const
void PGModule::elaborate_scope(Design*des, NetScope*sc) const
{
// Look for the module type
map<string,Module*>::const_iterator mod = pform_modules.find(type_);
map<perm_string,Module*>::const_iterator mod = pform_modules.find(type_);
if (mod != pform_modules.end()) {
elaborate_scope_mod_(des, (*mod).second, sc);
return;
}
// Try a primitive type
map<string,PUdp*>::const_iterator udp = pform_primitives.find(type_);
map<perm_string,PUdp*>::const_iterator udp = pform_primitives.find(type_);
if (udp != pform_primitives.end())
return;
@@ -929,12 +1062,7 @@ NetAssign_* PAssign_::elaborate_lval(Design*des, NetScope*scope) const
*/
static NetExpr*elaborate_delay_expr(PExpr*expr, Design*des, NetScope*scope)
{
NetExpr*dex = expr->elaborate_expr(des, scope);
if (NetExpr*tmp = dex->eval_tree()) {
delete dex;
dex = tmp;
}
NetExpr*dex = elab_and_eval(des, scope, expr);
/* If the delay expression is a real constant or vector
constant, then evaluate it, scale it to the local time
@@ -1011,17 +1139,10 @@ NetProc* PAssign::elaborate(Design*des, NetScope*scope) const
/* Elaborate the r-value expression, then try to evaluate it. */
assert(rval());
NetExpr*rv = rval()->elaborate_expr(des, scope);
if (rv == 0)
return 0;
NetExpr*rv = elab_and_eval(des, scope, rval());
if (rv == 0) return 0;
assert(rv);
/* Try to evaluate the expression, at least as far as possible. */
if (NetExpr*tmp = rv->eval_tree()) {
delete rv;
rv = tmp;
}
/* Rewrite delayed assignments as assignments that are
delayed. For example, a = #<d> b; becomes:
@@ -1088,6 +1209,7 @@ NetProc* PAssign::elaborate(Design*des, NetScope*scope) const
} else {
NetPDelay*de = new NetPDelay(delay, a2);
de->set_line(*this);
st = de;
}
@@ -1122,6 +1244,10 @@ NetProc* PAssign::elaborate(Design*des, NetScope*scope) const
}
/*
* Elaborate non-blocking assignments. The statement is of the general
* form:
*
* <lval> <= #<delay> <rval> ;
*/
NetProc* PAssignNB::elaborate(Design*des, NetScope*scope) const
{
@@ -1138,10 +1264,16 @@ NetProc* PAssignNB::elaborate(Design*des, NetScope*scope) const
if (rv == 0)
return 0;
/* Handle the (common) case that the r-value is a vector. This
includes just about everything but reals. In this case, we
need to pad the r-value to match the width of the l-value.
{ unsigned wid = count_lval_width(lv);
rv->set_width(wid);
rv = pad_to_width(rv, wid);
If in this case the l-val is a variable (i.e. real) then
the width to pad to will be 0, so this code is harmless. */
if (rv->expr_type() == NetExpr::ET_VECTOR) {
unsigned wid = count_lval_width(lv);
rv->set_width(wid);
rv = pad_to_width(rv, wid);
}
NetExpr*delay = 0;
@@ -1171,7 +1303,7 @@ NetProc* PBlock::elaborate(Design*des, NetScope*scope) const
: NetBlock::SEQU;
NetScope*nscope = 0;
if (name_.length()) {
if (name_.str() != 0) {
nscope = scope->child(name_);
if (nscope == 0) {
cerr << get_line() << ": internal error: "
@@ -1195,7 +1327,7 @@ NetProc* PBlock::elaborate(Design*des, NetScope*scope) const
// statement. There is no need to keep the block node. Also,
// don't elide named blocks, because they might be referenced
// elsewhere.
if ((list_.count() == 1) && (name_.length() == 0)) {
if ((list_.count() == 1) && (name_.str() == 0)) {
assert(list_[0]);
NetProc*tmp = list_[0]->elaborate(des, nscope);
return tmp;
@@ -1234,22 +1366,13 @@ NetProc* PCase::elaborate(Design*des, NetScope*scope) const
{
assert(scope);
NetExpr*expr = expr_->elaborate_expr(des, scope);
NetExpr*expr = elab_and_eval(des, scope, expr_);
if (expr == 0) {
cerr << get_line() << ": error: Unable to elaborate this case"
" expression." << endl;
return 0;
}
/* Try to evaluate the case expression. */
if (! dynamic_cast<NetEConst*>(expr)) {
NetExpr*tmp = expr->eval_tree();
if (tmp != 0) {
delete expr;
expr = tmp;
}
}
/* Count the items in the case statement. Note that there may
be some cases that have multiple guards. Count each as a
separate item. */
@@ -1295,17 +1418,7 @@ NetProc* PCase::elaborate(Design*des, NetScope*scope) const
NetExpr*gu = 0;
NetProc*st = 0;
assert(cur->expr[e]);
gu = cur->expr[e]->elaborate_expr(des, scope);
/* Try to evaluate the guard expression down to a
simple constant. */
if (! dynamic_cast<NetEConst*>(gu)) {
NetExpr*tmp = gu->eval_tree();
if (tmp != 0) {
delete gu;
gu = tmp;
}
}
gu = elab_and_eval(des, scope, cur->expr[e]);
if (cur->stat)
st = cur->stat->elaborate(des, scope);
@@ -1323,18 +1436,13 @@ NetProc* PCondit::elaborate(Design*des, NetScope*scope) const
assert(scope);
// Elaborate and try to evaluate the conditional expression.
NetExpr*expr = expr_->elaborate_expr(des, scope);
NetExpr*expr = elab_and_eval(des, scope, expr_);
if (expr == 0) {
cerr << get_line() << ": error: Unable to elaborate"
" condition expression." << endl;
des->errors += 1;
return 0;
}
NetExpr*tmp = expr->eval_tree();
if (tmp) {
delete expr;
expr = tmp;
}
// If the condition of the conditional statement is constant,
// then look at the value and elaborate either the if statement
@@ -1541,7 +1649,7 @@ NetProc* PCallTask::elaborate_usr(Design*des, NetScope*scope) const
if (port->port_type() == NetNet::POUTPUT)
continue;
NetExpr*rv = parms_[idx]->elaborate_expr(des, scope);
NetExpr*rv = elab_and_eval(des, scope, parms_[idx]);
NetAssign_*lv = new NetAssign_(port);
NetAssign*pr = new NetAssign(lv, rv);
block->append(pr);
@@ -1802,7 +1910,7 @@ NetProc* PEventStatement::elaborate_st(Design*des, NetScope*scope,
list. The NetEvProbe objects all refer back to the NetEvent
object. */
NetEvent*ev = new NetEvent(lex_strings.add(scope->local_symbol().c_str()));
NetEvent*ev = new NetEvent(scope->local_symbol());
ev->set_line(*this);
unsigned expr_count = 0;
@@ -1954,6 +2062,8 @@ NetProc* PEventStatement::elaborate_wait(Design*des, NetScope*scope,
const PExpr *pe = expr_[0]->expr();
/* Elaborate wait expression. Don't eval yet, we will do that
shortly, after we apply a reduction or. */
NetExpr*expr = pe->elaborate_expr(des, scope);
if (expr == 0) {
cerr << get_line() << ": error: Unable to elaborate"
@@ -1962,6 +2072,67 @@ NetProc* PEventStatement::elaborate_wait(Design*des, NetScope*scope,
return 0;
}
// If the condition expression is more then 1 bits, then
// generate a reduction operator to get the result down to
// one bit. In other words, Turn <e> into |<e>;
if (expr->expr_width() < 1) {
cerr << get_line() << ": internal error: "
"incomprehensible wait expression width (0)." << endl;
return 0;
}
if (expr->expr_width() > 1) {
assert(expr->expr_width() > 1);
NetEUReduce*cmp = new NetEUReduce('|', expr);
expr = cmp;
}
/* precalculate as much as possible of the wait expression. */
if (NetExpr*tmp = expr->eval_tree()) {
delete expr;
expr = tmp;
}
/* Detect the unusual case that the wait expression is
constant. Constant true is OK (it becomes transparent) but
constant false is almost certainly not what is intended. */
assert(expr->expr_width() == 1);
if (NetEConst*ce = dynamic_cast<NetEConst*>(expr)) {
verinum val = ce->value();
assert(val.len() == 1);
/* Constant true -- wait(1) <s1> reduces to <s1>. */
if (val[0] == verinum::V1) {
delete expr;
assert(enet);
return enet;
}
/* Otherwise, false. wait(0) blocks permanently. */
cerr << get_line() << ": warning: wait expression is "
<< "constant false." << endl;
cerr << get_line() << ": : The statement will "
<< "block permanently." << endl;
/* Create an event wait and an otherwise unreferenced
event variable to force a perpetual wait. */
NetEvent*wait_event = new NetEvent(scope->local_symbol());
scope->add_event(wait_event);
NetEvWait*wait = new NetEvWait(0);
wait->add_event(wait_event);
wait->set_line(*this);
delete expr;
delete enet;
return wait;
}
/* Invert the sense of the test with an exclusive NOR. In
other words, if this adjusted expression returns TRUE, then
wait. */
assert(expr->expr_width() == 1);
expr = new NetEBComp('N', expr, new NetEConst(verinum(verinum::V1)));
NetExpr*tmp = expr->eval_tree();
@@ -1970,25 +2141,7 @@ NetProc* PEventStatement::elaborate_wait(Design*des, NetScope*scope,
expr = tmp;
}
/* Detect the unusual case that the wait expression is
constant. Constant true is OK (it becomes transparent) but
constant false is almost certainly not what is intended. */
if (NetEConst*ce = dynamic_cast<NetEConst*>(expr)) {
verinum val = ce->value();
assert(val.len() == 1);
if (val[0] == verinum::V1) {
delete expr;
assert(enet);
return enet;
}
cerr << get_line() << ": warning: wait expression is "
<< "constant false." << endl;
cerr << get_line() << ": : The statement will "
<< "block permanently." << endl;
}
NetEvent*wait_event = new NetEvent(lex_strings.add(scope->local_symbol().c_str()));
NetEvent*wait_event = new NetEvent(scope->local_symbol());
scope->add_event(wait_event);
NetEvWait*wait = new NetEvWait(0 /* noop */);
@@ -2027,7 +2180,7 @@ NetProc* PEventStatement::elaborate_wait(Design*des, NetScope*scope,
if (enet == 0)
return loop;
/* Create a sequential block to conbine the wait loop and the
/* Create a sequential block to combine the wait loop and the
delayed statement. */
NetBlock*block = new NetBlock(NetBlock::SEQU, 0);
block->append(loop);
@@ -2045,6 +2198,10 @@ NetProc* PEventStatement::elaborate(Design*des, NetScope*scope) const
enet = statement_->elaborate(des, scope);
if (enet == 0)
return 0;
} else {
enet = new NetBlock(NetBlock::SEQU, 0);
enet->set_line(*this);
}
if ((expr_.count() == 1) && (expr_[0]->type() == PEEvent::POSITIVE))
@@ -2173,18 +2330,15 @@ NetProc* PForStatement::elaborate(Design*des, NetScope*scope) const
/* Elaborate the condition expression. Try to evaluate it too,
in case it is a constant. This is an interesting case
worthy of a warning. */
NetExpr*ce = cond_->elaborate_expr(des, scope);
NetExpr*ce = elab_and_eval(des, scope, cond_);
if (ce == 0) {
delete top;
return 0;
}
if (NetExpr*tmp = ce->eval_tree()) {
if (dynamic_cast<NetEConst*>(tmp)) {
cerr << get_line() << ": warning: condition expression "
"of for-loop is constant." << endl;
}
ce = tmp;
if (dynamic_cast<NetEConst*>(ce)) {
cerr << get_line() << ": warning: condition expression "
"of for-loop is constant." << endl;
}
@@ -2220,6 +2374,13 @@ NetProc* PForStatement::elaborate(Design*des, NetScope*scope) const
void PFunction::elaborate(Design*des, NetScope*scope) const
{
NetFuncDef*def = scope->func_def();
if (def == 0) {
cerr << get_line() << ": internal error: "
<< "No function definition for function "
<< scope->name() << endl;
return;
}
assert(def);
NetProc*st = statement_->elaborate(des, scope);
@@ -2250,18 +2411,13 @@ NetProc* PRepeat::elaborate(Design*des, NetScope*scope) const
{
assert(scope);
NetExpr*expr = expr_->elaborate_expr(des, scope);
NetExpr*expr = elab_and_eval(des, scope, expr_);
if (expr == 0) {
cerr << get_line() << ": Unable to elaborate"
" repeat expression." << endl;
des->errors += 1;
return 0;
}
NetExpr*tmp = expr->eval_tree();
if (tmp) {
delete expr;
expr = tmp;
}
NetProc*stat = statement_->elaborate(des, scope);
if (stat == 0) return 0;
@@ -2324,7 +2480,6 @@ void PTask::elaborate(Design*des, NetScope*task) const
NetProc*st;
if (statement_ == 0) {
cerr << get_line() << ": warning: task has no statement." << endl;
st = new NetBlock(NetBlock::SEQU, 0);
} else {
@@ -2378,7 +2533,7 @@ NetProc* PTrigger::elaborate(Design*des, NetScope*scope) const
*/
NetProc* PWhile::elaborate(Design*des, NetScope*scope) const
{
NetWhile*loop = new NetWhile(cond_->elaborate_expr(des, scope),
NetWhile*loop = new NetWhile(elab_and_eval(des, scope, cond_),
statement_->elaborate(des, scope));
return loop;
}
@@ -2393,7 +2548,7 @@ bool Module::elaborate(Design*des, NetScope*scope) const
// Elaborate functions.
typedef map<string,PFunction*>::const_iterator mfunc_it_t;
typedef map<perm_string,PFunction*>::const_iterator mfunc_it_t;
for (mfunc_it_t cur = funcs_.begin()
; cur != funcs_.end() ; cur ++) {
@@ -2405,7 +2560,7 @@ bool Module::elaborate(Design*des, NetScope*scope) const
// Elaborate the task definitions. This is done before the
// behaviors so that task calls may reference these, and after
// the signals so that the tasks can reference them.
typedef map<string,PTask*>::const_iterator mtask_it_t;
typedef map<perm_string,PTask*>::const_iterator mtask_it_t;
for (mtask_it_t cur = tasks_.begin()
; cur != tasks_.end() ; cur ++) {
@@ -2502,7 +2657,8 @@ bool Module::elaborate(Design*des, NetScope*scope) const
if (! anyedge_test)
break;
top->attribute("_ivl_schedule_push", verinum(1));
top->attribute(perm_string::literal("_ivl_schedule_push"),
verinum(1));
} while (0);
}
@@ -2515,7 +2671,7 @@ struct root_elem {
NetScope *scope;
};
Design* elaborate(list<const char*>roots)
Design* elaborate(list<perm_string>roots)
{
svector<root_elem*> root_elems(roots.size());
bool rc = true;
@@ -2525,15 +2681,15 @@ Design* elaborate(list<const char*>roots)
// module and elaborate what I find.
Design*des = new Design;
for (list<const char*>::const_iterator root = roots.begin()
for (list<perm_string>::const_iterator root = roots.begin()
; root != roots.end()
; root++) {
// Look for the root module in the list.
map<string,Module*>::const_iterator mod = pform_modules.find(*root);
map<perm_string,Module*>::const_iterator mod = pform_modules.find(*root);
if (mod == pform_modules.end()) {
cerr << "error: Unable to find the root module \""
<< (*root) << "\" in the Verilog source." << endl;
<< (*root) << "\" in the Verilog source." << endl;
cerr << " : Perhaps ``-s " << (*root)
<< "'' is incorrect?" << endl;
des->errors++;
@@ -2541,12 +2697,13 @@ Design* elaborate(list<const char*>roots)
}
Module *rmod = (*mod).second;
// Make the root scope, then scan the pform looking for scopes
// and parameters.
// and parameters.
NetScope*scope = des->make_root_scope(*root);
scope->time_unit(rmod->time_unit);
scope->time_precision(rmod->time_precision);
scope->default_nettype(rmod->default_nettype);
des->set_precision(rmod->time_precision);
if (! rmod->elaborate_scope(des, scope)) {
delete des;
@@ -2612,6 +2769,53 @@ Design* elaborate(list<const char*>roots)
/*
* $Log: elaborate.cc,v $
* Revision 1.308 2004/10/04 01:10:52 steve
* Clean up spurious trailing white space.
*
* Revision 1.307 2004/09/05 21:07:26 steve
* Support degenerat wait statements.
*
* Revision 1.306 2004/09/05 17:44:41 steve
* Add support for module instance arrays.
*
* Revision 1.305 2004/06/30 15:32:02 steve
* Propagate source line number in synthetic delay statements.
*
* Revision 1.304 2004/06/20 15:59:06 steve
* Only pad the width of vector r-values.
*
* Revision 1.303 2004/06/13 04:56:54 steve
* Add support for the default_nettype directive.
*
* Revision 1.302 2004/05/31 23:34:37 steve
* Rewire/generalize parsing an elaboration of
* function return values to allow for better
* speed and more type support.
*
* Revision 1.301 2004/05/25 03:42:58 steve
* Handle wait with constant-false expression.
*
* Revision 1.300 2004/03/08 00:47:44 steve
* primitive ports can bind bi name.
*
* Revision 1.299 2004/03/08 00:10:29 steve
* Verilog2001 new style port declartions for primitives.
*
* Revision 1.298 2004/03/07 20:04:10 steve
* MOre thorough use of elab_and_eval function.
*
* Revision 1.297 2004/02/20 18:53:34 steve
* Addtrbute keys are perm_strings.
*
* Revision 1.296 2004/02/18 17:11:55 steve
* Use perm_strings for named langiage items.
*
* Revision 1.295 2004/01/21 04:35:03 steve
* Get rid of useless warning.
*
* Revision 1.294 2004/01/13 03:42:49 steve
* Handle wide expressions in wait condition.
*
* Revision 1.293 2003/10/26 04:49:51 steve
* Attach line number information to for loop parts.
*
+17 -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: emit.cc,v 1.75 2003/09/13 01:30:07 steve Exp $"
#ident "$Id: emit.cc,v 1.77 2004/10/04 01:10:53 steve Exp $"
#endif
# include "config.h"
@@ -335,17 +335,18 @@ void NetScope::emit_scope(struct target_t*tgt) const
}
}
void NetScope::emit_defs(struct target_t*tgt) const
bool NetScope::emit_defs(struct target_t*tgt) const
{
bool flag = true;
switch (type_) {
case MODULE:
for (NetScope*cur = sub_ ; cur ; cur = cur->sib_)
cur->emit_defs(tgt);
flag &= cur->emit_defs(tgt);
break;
case FUNC:
tgt->func_def(this);
flag &= tgt->func_def(this);
break;
case TASK:
tgt->task_def(this);
@@ -354,6 +355,7 @@ void NetScope::emit_defs(struct target_t*tgt) const
break;
}
return flag;
}
void NetWhile::emit_proc_recurse(struct target_t*tgt) const
@@ -370,7 +372,7 @@ bool Design::emit(struct target_t*tgt) const
return false;
// enumerate the scopes
for (list<NetScope*>::const_iterator scope = root_scopes_.begin();
for (list<NetScope*>::const_iterator scope = root_scopes_.begin();
scope != root_scopes_.end(); scope++)
(*scope)->emit_scope(tgt);
@@ -386,9 +388,9 @@ bool Design::emit(struct target_t*tgt) const
// emit task and function definitions
for (list<NetScope*>::const_iterator scope = root_scopes_.begin();
for (list<NetScope*>::const_iterator scope = root_scopes_.begin();
scope != root_scopes_.end(); scope++)
(*scope)->emit_defs(tgt);
rc &= (*scope)->emit_defs(tgt);
// emit the processes
@@ -509,6 +511,14 @@ bool emit(const Design*des, const char*type)
/*
* $Log: emit.cc,v $
* Revision 1.77 2004/10/04 01:10:53 steve
* Clean up spurious trailing white space.
*
* Revision 1.76 2004/05/31 23:34:37 steve
* Rewire/generalize parsing an elaboration of
* function return values to allow for better
* speed and more type support.
*
* Revision 1.75 2003/09/13 01:30:07 steve
* Missing case warnings.
*
+7 -4
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2002 Stephen Williams (steve@icarus.com)
* Copyright (c) 2002-2004 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: eval_attrib.cc,v 1.6 2003/01/27 05:09:17 steve Exp $"
#ident "$Id: eval_attrib.cc,v 1.7 2004/02/20 18:53:35 steve Exp $"
#endif
# include "config.h"
@@ -33,7 +33,7 @@
* for passing to netlist devices.
*/
attrib_list_t* evaluate_attributes(const map<string,PExpr*>&att,
attrib_list_t* evaluate_attributes(const map<perm_string,PExpr*>&att,
unsigned&natt,
const Design*des,
const NetScope*scope)
@@ -46,7 +46,7 @@ attrib_list_t* evaluate_attributes(const map<string,PExpr*>&att,
unsigned idx = 0;
typedef map<string,PExpr*>::const_iterator iter_t;
typedef map<perm_string,PExpr*>::const_iterator iter_t;
for (iter_t cur = att.begin() ; cur != att.end() ; cur ++, idx++) {
table[idx].key = (*cur).first;
PExpr*exp = (*cur).second;
@@ -74,6 +74,9 @@ attrib_list_t* evaluate_attributes(const map<string,PExpr*>&att,
/*
* $Log: eval_attrib.cc,v $
* Revision 1.7 2004/02/20 18:53:35 steve
* Addtrbute keys are perm_strings.
*
* Revision 1.6 2003/01/27 05:09:17 steve
* Spelling fixes.
*
+69 -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: eval_tree.cc,v 1.59 2003/10/31 02:47:11 steve Exp $"
#ident "$Id: eval_tree.cc,v 1.62 2004/10/04 01:10:53 steve Exp $"
#endif
# include "config.h"
@@ -1124,8 +1124,7 @@ NetExpr* NetEParam::eval_tree()
return 0;
assert(scope_);
assert(name_.peek_name(1) == 0);
const NetExpr*expr = scope_->get_parameter(name_.peek_name(0));
const NetExpr*expr = scope_->get_parameter(name_);
if (expr == 0) {
cerr << get_line() << ": internal error: Unable to match "
<< "parameter " << name_ << " in scope "
@@ -1142,8 +1141,7 @@ NetExpr* NetEParam::eval_tree()
// return the constant value.
if (NetEConst*tmp = dynamic_cast<NetEConst*>(nexpr)) {
verinum val = tmp->value();
const char*name = lex_strings.add(name_.peek_name(0));
NetEConstParam*ptmp = new NetEConstParam(scope_, name, val);
NetEConstParam*ptmp = new NetEConstParam(scope_, name_, val);
ptmp->set_line(*this);
delete nexpr;
return ptmp;
@@ -1151,8 +1149,7 @@ NetExpr* NetEParam::eval_tree()
if (NetECReal*tmp = dynamic_cast<NetECReal*>(nexpr)) {
verireal val = tmp->value();
const char*name = lex_strings.add(name_.peek_name(0));
NetECRealParam*ptmp = new NetECRealParam(scope_, name, val);
NetECRealParam*ptmp = new NetECRealParam(scope_, name_, val);
ptmp->set_line(*this);
delete nexpr;
return ptmp;
@@ -1171,7 +1168,7 @@ NetExpr* NetEParam::eval_tree()
// The result can be saved as the value of the parameter for
// future reference, and return a copy to the caller.
scope_->replace_parameter(name_.peek_name(0), res);
scope_->replace_parameter(name_, res);
/* Return as a result a NetEConstParam or NetECRealParam
object, depending on the type of the expression. */
@@ -1190,8 +1187,7 @@ NetExpr* NetEParam::eval_tree()
assert(tmp);
verinum val = tmp->value();
const char*name = lex_strings.add(name_.peek_name(0));
NetEConstParam*ptmp = new NetEConstParam(scope_, name, val);
NetEConstParam*ptmp = new NetEConstParam(scope_, name_, val);
return ptmp;
}
@@ -1208,8 +1204,7 @@ NetExpr* NetEParam::eval_tree()
assert(tmp);
verireal val = tmp->value();
const char*name = lex_strings.add(name_.peek_name(0));
NetECRealParam*ptmp = new NetECRealParam(scope_, name, val);
NetECRealParam*ptmp = new NetECRealParam(scope_, name_, val);
return ptmp;
}
@@ -1256,7 +1251,7 @@ NetEConst* NetESelect::eval_tree()
for (unsigned long idx = 0 ; idx < expr_width() ; idx += 1) {
if ((bval >= 0) && ((unsigned long) bval < eval.len()))
oval.set(idx, eval.get(bval));
else
else
oval.set(idx, verinum::Vx);
bval += 1;
@@ -1310,18 +1305,50 @@ NetExpr* NetETernary::eval_tree()
if (c == 0)
return 0;
/* Check the boolean value of the constant condition
expression. Note that the X case is handled explicitly, so
we must differentiate. */
verinum cond_value = c->value();
bool true_flag = false;
bool x_flag = false;
for (unsigned idx = 0 ; idx < cond_value.len() ; idx += 1) {
switch (cond_value.get(idx)) {
case verinum::V1:
true_flag = true;
break;
case verinum::V0:
break;
default:
x_flag = true;
}
}
/* If the condition is 1 or 0, return the true or false
expression. Try to evaluate the expression down as far as
we can. */
if (c->value().get(0) == verinum::V1)
if (true_flag) {
if (debug_eval_tree) {
cerr << get_line() << ": debug: Evaluate ternary with "
<< "constant condition value: " << c->value() << endl;
cerr << get_line() << ": : Selecting true case: "
<< *true_val_ << endl;
}
return true_val_->dup_expr();
}
if (c->value().get(0) == verinum::V0)
if (! x_flag) {
if (debug_eval_tree) {
cerr << get_line() << ": debug: Evaluate ternary with "
<< "constant condition value: " << c->value() << endl;
cerr << get_line() << ": : Selecting false case: "
<< *true_val_ << endl;
}
return false_val_->dup_expr();
}
/* Here we have a more complex case. We need to evaluate both
expressions down to constants then compare the values to
@@ -1337,13 +1364,15 @@ NetExpr* NetETernary::eval_tree()
return 0;
unsigned size = t->expr_width();
assert(size == f->expr_width());
unsigned tsize = t->expr_width();
unsigned fsize = f->expr_width();
/* Size of the result is the size of the widest operand. */
unsigned rsize = tsize > fsize? tsize : fsize;
verinum val (verinum::V0, size);
for (unsigned idx = 0 ; idx < size ; idx += 1) {
verinum::V tv = t->value().get(idx);
verinum::V fv = f->value().get(idx);
verinum val (verinum::V0, rsize);
for (unsigned idx = 0 ; idx < rsize ; idx += 1) {
verinum::V tv = idx < tsize? t->value().get(idx) : verinum::V0;
verinum::V fv = idx < rsize? f->value().get(idx) : verinum::V0;
if (tv == fv)
val.set(idx, tv);
@@ -1351,6 +1380,13 @@ NetExpr* NetETernary::eval_tree()
val.set(idx, verinum::Vx);
}
if (debug_eval_tree) {
cerr << get_line() << ": debug: Evaluate ternary with "
<< "constant condition value: " << c->value() << endl;
cerr << get_line() << ": : Blending cases to get "
<< val << endl;
}
NetEConst*rc = new NetEConst(val);
rc->set_line(*this);
return rc;
@@ -1387,7 +1423,7 @@ NetEConst* NetEUnary::eval_tree()
case '-': {
if (val.is_defined()) {
verinum tmp (verinum::V0, val.len());
tmp.has_sign(val.has_sign());
val = tmp - val;
@@ -1515,6 +1551,15 @@ NetEConst* NetEUReduce::eval_tree()
/*
* $Log: eval_tree.cc,v $
* Revision 1.62 2004/10/04 01:10:53 steve
* Clean up spurious trailing white space.
*
* Revision 1.61 2004/09/10 23:51:42 steve
* Fix the evaluation of constant ternary expressions.
*
* Revision 1.60 2004/02/20 06:22:56 steve
* parameter keys are per_strings.
*
* Revision 1.59 2003/10/31 02:47:11 steve
* NetEUReduce has its own dup_expr method.
*
+8 -8
View File
@@ -218,11 +218,11 @@ output [1:48] k;
wire [1:56] YY;
assign YY[1:28]=c; assign YY[29:56]=d;
assign k[1]=YY[14]; assign k[2]=YY[17]; assign k[3]=YY[11]; assign k[4]=YY[24]; assign k[5]=YY[1]; assign k[6]=YY[5];
assign k[7]=YY[3]; assign k[8]=YY[28]; assign k[9]=YY[15]; assign k[10]=YY[6]; assign k[11]=YY[21]; assign k[12]=YY[10];
assign k[13]=YY[23]; assign k[14]=YY[19]; assign k[15]=YY[12]; assign k[16]=YY[4]; assign k[17]=YY[26]; assign k[18]=YY[8];
assign k[19]=YY[16]; assign k[20]=YY[7]; assign k[21]=YY[27]; assign k[22]=YY[20]; assign k[23]=YY[13]; assign k[24]=YY[2];
assign k[13]=YY[23]; assign k[14]=YY[19]; assign k[15]=YY[12]; assign k[16]=YY[4]; assign k[17]=YY[26]; assign k[18]=YY[8];
assign k[19]=YY[16]; assign k[20]=YY[7]; assign k[21]=YY[27]; assign k[22]=YY[20]; assign k[23]=YY[13]; assign k[24]=YY[2];
assign k[25]=YY[41]; assign k[26]=YY[52]; assign k[27]=YY[31]; assign k[28]=YY[37]; assign k[29]=YY[47]; assign k[30]=YY[55];
assign k[31]=YY[30]; assign k[32]=YY[40]; assign k[33]=YY[51]; assign k[34]=YY[45]; assign k[35]=YY[33]; assign k[36]=YY[48];
assign k[37]=YY[44]; assign k[38]=YY[49]; assign k[39]=YY[39]; assign k[40]=YY[56]; assign k[41]=YY[34]; assign k[42]=YY[53];
@@ -252,13 +252,13 @@ input [1:64] key;
output [1:48] k1x,k2x,k3x,k4x,k5x,k6x,k7x,k8x,k9x,k10x,k11x,k12x,k13x,k14x,k15x,k16x;
wire [1:28] c0x,c1x,c2x,c3x,c4x,c5x,c6x,c7x,c8x,c9x,c10x,c11x,c12x,c13x,c14x,c15x,c16x;
wire [1:28] d0x,d1x,d2x,d3x,d4x,d5x,d6x,d7x,d8x,d9x,d10x,d11x,d12x,d13x,d14x,d15x,d16x;
pc1 pc1(key, c0x, d0x);
rol1 rc1(c1x, c0x); rol1 rd1(d1x, d0x);
rol1 rc2(c2x, c1x); rol1 rd2(d2x, d1x);
rol2 rc3(c3x, c2x); rol2 rd3(d3x, d2x);
rol2 rc4(c4x, c3x); rol2 rd4(d4x, d3x);
rol2 rc4(c4x, c3x); rol2 rd4(d4x, d3x);
rol2 rc5(c5x, c4x); rol2 rd5(d5x, d4x);
rol2 rc6(c6x, c5x); rol2 rd6(d6x, d5x);
rol2 rc7(c7x, c6x); rol2 rd7(d7x, d6x);
@@ -272,7 +272,7 @@ rol2 rce(c14x, c13x); rol2 rde(d14x, d13x);
rol2 rcf(c15x, c14x); rol2 rdf(d15x, d14x);
rol1 rcg(c16x, c15x); rol1 rdg(d16x, d15x);
pc2 pc2x1(c1x,d1x,k1x);
pc2 pc2x2(c2x,d2x,k2x);
pc2 pc2x3(c3x,d3x,k3x);
@@ -913,7 +913,7 @@ assign l0x[17]=pt[62]; assign l0x[18]=pt[54]; assign l0x[19]=pt[46
assign l0x[21]=pt[30]; assign l0x[22]=pt[22]; assign l0x[23]=pt[14]; assign l0x[24]=pt[6];
assign l0x[25]=pt[64]; assign l0x[26]=pt[56]; assign l0x[27]=pt[48]; assign l0x[28]=pt[40];
assign l0x[29]=pt[32]; assign l0x[30]=pt[24]; assign l0x[31]=pt[16]; assign l0x[32]=pt[8];
assign r0x[1]=pt[57]; assign r0x[2]=pt[49]; assign r0x[3]=pt[41]; assign r0x[4]=pt[33];
assign r0x[5]=pt[25]; assign r0x[6]=pt[17]; assign r0x[7]=pt[9]; assign r0x[8]=pt[1];
assign r0x[9]=pt[59]; assign r0x[10]=pt[51]; assign r0x[11]=pt[43]; assign r0x[12]=pt[35];
@@ -935,7 +935,7 @@ assign e[9]=ri[6]; assign e[10]=ri[7]; assign e[11]=ri[8]; assign e[12]=r
assign e[17]=ri[12]; assign e[18]=ri[13]; assign e[19]=ri[12]; assign e[20]=ri[13]; assign e[21]=ri[14]; assign e[22]=ri[15]; assign e[23]=ri[16]; assign e[24]=ri[17];
assign e[25]=ri[16]; assign e[26]=ri[17]; assign e[27]=ri[18]; assign e[28]=ri[19]; assign e[29]=ri[20]; assign e[30]=ri[21]; assign e[31]=ri[20]; assign e[32]=ri[21];
assign e[33]=ri[22]; assign e[34]=ri[23]; assign e[35]=ri[24]; assign e[36]=ri[25]; assign e[37]=ri[24]; assign e[38]=ri[25]; assign e[39]=ri[26]; assign e[40]=ri[27];
assign e[41]=ri[28]; assign e[42]=ri[29]; assign e[43]=ri[28]; assign e[44]=ri[29]; assign e[45]=ri[30]; assign e[46]=ri[31]; assign e[47]=ri[32]; assign e[48]=ri[1];
assign e[41]=ri[28]; assign e[42]=ri[29]; assign e[43]=ri[28]; assign e[44]=ri[29]; assign e[45]=ri[30]; assign e[46]=ri[31]; assign e[47]=ri[32]; assign e[48]=ri[1];
endmodule
+5 -5
View File
@@ -26,21 +26,21 @@
* Compile this program with the command:
*
* iverilog -ohello hello.vl
*
*
* After churning for a little while, the program will create the output
* file "hello" which is compiled, linked and ready to run. Run this
* program like so:
*
*
* vvp hello
*
*
* and the program will print the message to its output. Easy! For
* more on how to make the iverilog command work, see the iverilog
* manual page.
*/
module main();
initial
initial
begin
$display("Hello, World");
$finish ;
+5 -5
View File
@@ -26,21 +26,21 @@
* Compile this program with the command:
*
* iverilog -ohello_vpi hello_vpi.vl
*
*
* After churning for a little while, the program will create the output
* file "hello" which is compiled, linked and ready to run. Run this
* program like so:
*
*
* vvp -M. -mhello_vpi hello_vpi
*
*
* and the program will print the message to its output. Easy! For
* more on how to make the iverilog command work, see the iverilog
* manual page.
*/
module main();
initial
initial
begin
$my_hello;
$finish ;
+11 -11
View File
@@ -20,36 +20,36 @@
/*
* This example program simulates a 16x1 ram, and is used as an
* example for using VCD output and waveform viewers.
*
*
* Like any other Verilog simulation, compile this program with the
* command:
*
*
* iverilog show_vcd.vl
*
*
* This will generate the show_vcd command in the current directory.
* When you run the command, you will see the output from all the
* calls to $display, but also there will be a dump file ``show_vcd.vcd''.
* The name of this file is set by the statement:
*
* $dumpfile("show_vcd.vcd");
*
*
* in the main module. The output file uses the standard VCD file format
* so can be viewed using off-the-shelf waveform viewers. The remaining
* steps describe how to use GTKWave to view the file. If you are using
* a different viewer, see the documentation for that tool.
*
*
* To view the output generated by running show_vcd, start the GTKWave
* viewer with the command:
*
*
* gtkwave show_vcd.vcd
*
*
* The GTKWave program will display its main window, and show in a small
* status box (upper left corner) that it succeeded in loading the dump
* file. However, there are no waveforms displayed yet. Select signals to
* add to the waveform display using the menu selection:
*
* "Search --> Signal Search Tree"
*
*
* This will bring up a dialog box that shows in directory tree format
* the signals of the program. Select the signals you wish to view, and
* click one of the buttons on the bottom of the dialog box to display
@@ -60,7 +60,7 @@
* $dumpvars system tasks. The $dumpfile task tells the simulation where
* to write the VCD output. This task must be called once before the
* $dumpvars task is called.
*
*
* The $dumpvars task tells the simulation what variables to write to
* the VCD output. The first parameter is how far to descend while
* scanning a scope, and the remaining paramters are signals or scope
@@ -77,7 +77,7 @@ module ram16x1 (q, d, a, we, wclk);
input wclk;
reg mem[15:0];
assign q = mem[a];
always @(posedge wclk) if (we) mem[a] = d;
@@ -88,7 +88,7 @@ module main;
reg d;
reg [3:0] a;
reg we, wclk;
ram16x1 r1 (q, d, a, we, wclk);
initial begin
+5 -5
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
*
* $Id: sqrt.vl,v 1.3 2000/11/04 01:53:24 steve Exp $"
* $Id: sqrt.vl,v 1.4 2004/10/04 01:10:56 steve Exp $"
*/
/*
@@ -97,8 +97,8 @@ module sqrt32(clk, rdy, reset, x, .y(acc));
bitl = 15;
end
endtask
initial clear;
initial clear;
always @(reset or posedge clk)
if (reset)
@@ -121,14 +121,14 @@ module main;
wire rdy;
sqrt32 root(.clk(clk), .rdy(rdy), .reset(reset), .x(value), .y(result));
always #5 clk = ~clk;
always @(posedge rdy) begin
$display("sqrt(%d) --> %d", value, result);
$finish;
end
initial begin
clk = 0;
+1 -1
View File
@@ -73,7 +73,7 @@ module main;
// This can be done to wires and registers, as internally both
// are treated as named signals. It doesn't work (yet) on vectors,
// though, so break out the vectors with scalar assignments.
assign a[0] = a0;
assign a[1] = a1;
assign a[2] = a2;
+2 -2
View File
@@ -28,7 +28,7 @@ module ram16x1 (q, d, a, we, wclk);
input wclk;
reg mem[15:0];
assign q = mem[a];
always @(posedge wclk) if (we) mem[a] = d;
@@ -39,7 +39,7 @@ module main;
reg d;
reg [3:0] a;
reg we, wclk;
ram16x1 r1 (q, d, a, we, wclk);
initial begin
+108 -39
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1999-2000 Stephen Williams (steve@icarus.com)
* Copyright (c) 1999-2004 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: expr_synth.cc,v 1.52 2003/11/10 19:39:20 steve Exp $"
#ident "$Id: expr_synth.cc,v 1.59 2004/06/30 02:16:26 steve Exp $"
#endif
# include "config.h"
@@ -54,11 +54,11 @@ NetNet* NetEBAdd::synthesize(Design*des)
assert(lsig->pin_count() == rsig->pin_count());
unsigned width=lsig->pin_count();
string path = lsig->scope()->local_symbol();
perm_string path = lsig->scope()->local_symbol();
NetNet*osig = new NetNet(lsig->scope(), path, NetNet::IMPLICIT, width);
osig->local_flag(true);
string oname = osig->scope()->local_symbol();
perm_string oname = osig->scope()->local_symbol();
NetAddSub *adder = new NetAddSub(lsig->scope(), oname, width);
for (unsigned idx = 0 ; idx < width; idx += 1) {
connect(lsig->pin(idx), adder->pin_DataA(idx));
@@ -69,10 +69,10 @@ NetNet* NetEBAdd::synthesize(Design*des)
switch (op()) {
case '+':
adder->attribute("LPM_Direction", verinum("ADD"));
adder->attribute(perm_string::literal("LPM_Direction"), verinum("ADD"));
break;
case '-':
adder->attribute("LPM_Direction", verinum("SUB"));
adder->attribute(perm_string::literal("LPM_Direction"), verinum("SUB"));
break;
}
@@ -111,7 +111,7 @@ NetNet* NetEBBits::synthesize(Design*des)
osig->local_flag(true);
for (unsigned idx = 0 ; idx < osig->pin_count() ; idx += 1) {
string oname = scope->local_hsymbol();
perm_string oname = scope->local_symbol();
NetLogic*gate;
/* If the rsig bit is constant, then look for special
@@ -190,12 +190,12 @@ NetNet* NetEBComp::synthesize(Design*des)
switch (op_) {
case 'e':
case 'E':
gate = new NetLogic(scope, scope->local_hsymbol(),
gate = new NetLogic(scope, scope->local_symbol(),
lsig->pin_count()+1, NetLogic::NOR);
break;
case 'n':
case 'N':
gate = new NetLogic(scope, scope->local_hsymbol(),
gate = new NetLogic(scope, scope->local_symbol(),
lsig->pin_count()+1, NetLogic::OR);
break;
@@ -204,11 +204,11 @@ NetNet* NetEBComp::synthesize(Design*des)
is very much like sig != 0. (0 > sig) shouldn't
happen. */
if (rcon) {
gate = new NetLogic(scope, scope->local_hsymbol(),
gate = new NetLogic(scope, scope->local_symbol(),
lsig->pin_count()+1, NetLogic::OR);
} else {
assert(0);
gate = new NetLogic(scope, scope->local_hsymbol(),
gate = new NetLogic(scope, scope->local_symbol(),
lsig->pin_count()+1, NetLogic::NOR);
}
break;
@@ -216,11 +216,11 @@ NetNet* NetEBComp::synthesize(Design*des)
case '<':
/* 0 < sig is handled like sig > 0. */
if (! rcon) {
gate = new NetLogic(scope, scope->local_hsymbol(),
gate = new NetLogic(scope, scope->local_symbol(),
lsig->pin_count()+1, NetLogic::OR);
} else {
assert(0);
gate = new NetLogic(scope, scope->local_hsymbol(),
gate = new NetLogic(scope, scope->local_symbol(),
lsig->pin_count()+1, NetLogic::NOR);
}
break;
@@ -257,7 +257,7 @@ NetNet* NetEBComp::synthesize(Design*des)
/* Handle the special case of a single bit equality
operation. Make an XNOR gate instead of a comparator. */
if ((width == 1) && ((op_ == 'e') || (op_ == 'E'))) {
NetLogic*gate = new NetLogic(scope, scope->local_hsymbol(),
NetLogic*gate = new NetLogic(scope, scope->local_symbol(),
3, NetLogic::XNOR);
connect(gate->pin(0), osig->pin(0));
connect(gate->pin(1), lsig->pin(0));
@@ -270,7 +270,7 @@ NetNet* NetEBComp::synthesize(Design*des)
operation. This is similar to single bit equality, but uses
an XOR instead of an XNOR gate. */
if ((width == 1) && ((op_ == 'n') || (op_ == 'N'))) {
NetLogic*gate = new NetLogic(scope, scope->local_hsymbol(),
NetLogic*gate = new NetLogic(scope, scope->local_symbol(),
3, NetLogic::XOR);
connect(gate->pin(0), osig->pin(0));
connect(gate->pin(1), lsig->pin(0));
@@ -349,7 +349,7 @@ NetNet* NetEBMult::synthesize(Design*des)
connect(mult->pin_DataA(idx), lsig->pin(idx));
for (unsigned idx = 0 ; idx < rsig->pin_count() ; idx += 1)
connect(mult->pin_DataB(idx), lsig->pin(idx));
connect(mult->pin_DataB(idx), rsig->pin(idx));
NetNet*osig = new NetNet(scope, scope->local_symbol(),
NetNet::IMPLICIT, expr_width());
@@ -363,10 +363,61 @@ NetNet* NetEBMult::synthesize(Design*des)
NetNet* NetEBDiv::synthesize(Design*des)
{
cerr << get_line() << ": internal error: cannot synthesize division: "
<< *this << endl;
des->errors += 1;
return 0;
NetNet*lsig = left_->synthesize(des);
NetNet*rsig = right_->synthesize(des);
NetScope*scope = lsig->scope();
NetNet*osig = new NetNet(scope, scope->local_symbol(),
NetNet::IMPLICIT, expr_width());
osig->local_flag(true);
switch (op()) {
case '/': {
NetDivide*div = new NetDivide(scope, scope->local_symbol(),
expr_width(),
lsig->pin_count(),
rsig->pin_count());
des->add_node(div);
for (unsigned idx = 0 ; idx < lsig->pin_count() ; idx += 1)
connect(div->pin_DataA(idx), lsig->pin(idx));
for (unsigned idx = 0 ; idx < rsig->pin_count() ; idx += 1)
connect(div->pin_DataB(idx), rsig->pin(idx));
for (unsigned idx = 0 ; idx < osig->pin_count() ; idx += 1)
connect(div->pin_Result(idx), osig->pin(idx));
break;
}
case '%': {
NetModulo*div = new NetModulo(scope, scope->local_symbol(),
expr_width(),
lsig->pin_count(),
rsig->pin_count());
des->add_node(div);
for (unsigned idx = 0 ; idx < lsig->pin_count() ; idx += 1)
connect(div->pin_DataA(idx), lsig->pin(idx));
for (unsigned idx = 0 ; idx < rsig->pin_count() ; idx += 1)
connect(div->pin_DataB(idx), rsig->pin(idx));
for (unsigned idx = 0 ; idx < osig->pin_count() ; idx += 1)
connect(div->pin_Result(idx), osig->pin(idx));
break;
}
default: {
cerr << get_line() << ": internal error: "
<< "NetEBDiv has unexpeced op() code: "
<< op() << endl;
des->errors += 1;
delete osig;
return 0;
}
}
return osig;
}
NetNet* NetEBLogic::synthesize(Design*des)
@@ -394,7 +445,7 @@ NetNet* NetEBLogic::synthesize(Design*des)
comparison with a single wide OR gate. So handle this
magically. */
string oname = scope->local_hsymbol();
perm_string oname = scope->local_symbol();
NetLogic*olog = new NetLogic(scope, oname,
lsig->pin_count()+rsig->pin_count()+1,
@@ -418,7 +469,7 @@ NetNet* NetEBLogic::synthesize(Design*des)
/* Create the logic AND gate. This is a single bit
output, with inputs for each of the operands. */
NetLogic*olog;
string oname = scope->local_hsymbol();
perm_string oname = scope->local_symbol();
olog = new NetLogic(scope, oname, 3, NetLogic::AND);
@@ -436,7 +487,7 @@ NetNet* NetEBLogic::synthesize(Design*des)
connect(lsig->pin(0), olog->pin(1));
assert(rsig->pin_count() == 1);
connect(lsig->pin(0), olog->pin(2));
connect(rsig->pin(0), olog->pin(2));
}
@@ -457,6 +508,9 @@ NetNet* NetEBShift::synthesize(Design*des)
if (lsig == 0)
return 0;
bool right_flag = op_ == 'r' || op_ == 'R';
bool signed_flag = op_ == 'R';
NetScope*scope = lsig->scope();
/* Detect the special case where the shift amount is
@@ -515,7 +569,8 @@ NetNet* NetEBShift::synthesize(Design*des)
assert(op() == 'l');
NetCLShift*dev = new NetCLShift(scope, scope->local_symbol(),
osig->pin_count(),
rsig->pin_count());
rsig->pin_count(),
right_flag, signed_flag);
des->add_node(dev);
for (unsigned idx = 0 ; idx < dev->width() ; idx += 1)
@@ -528,14 +583,6 @@ NetNet* NetEBShift::synthesize(Design*des)
for (unsigned idx = 0 ; idx < dev->width_dist() ; idx += 1)
connect(dev->pin_Distance(idx), rsig->pin(idx));
verinum dir_v = (op() == 'r')? verinum::V1 : verinum::V0;
NetNet*dir_n = new NetNet(scope, scope->local_symbol(),
NetNet::WIRE, 1);
NetConst*dir = new NetConst(scope, scope->local_symbol(), dir_v);
des->add_node(dir);
connect(dev->pin_Direction(), dir->pin(0));
connect(dev->pin_Direction(), dir_n->pin(0));
return osig;
}
@@ -551,7 +598,7 @@ NetNet* NetEConcat::synthesize(Design*des)
assert(scope);
/* Make a NetNet object to carry the output vector. */
string path = scope->local_symbol();
perm_string path = scope->local_symbol();
NetNet*osig = new NetNet(scope, path, NetNet::IMPLICIT, expr_width());
osig->local_flag(true);
@@ -579,11 +626,12 @@ NetNet* NetEConst::synthesize(Design*des)
NetScope*scope = des->find_root_scope();
assert(scope);
string path = scope->local_symbol();
perm_string path = scope->local_symbol();
unsigned width=expr_width();
NetNet*osig = new NetNet(scope, path, NetNet::IMPLICIT, width);
osig->local_flag(true);
osig->set_signed(has_sign());
NetConst*con = new NetConst(scope, scope->local_symbol(), value());
for (unsigned idx = 0 ; idx < width; idx += 1)
connect(osig->pin(idx), con->pin(idx));
@@ -616,7 +664,7 @@ NetNet* NetEUBits::synthesize(Design*des)
osig->local_flag(true);
for (unsigned idx = 0 ; idx < osig->pin_count() ; idx += 1) {
string oname = scope->local_hsymbol();
perm_string oname = scope->local_symbol();
NetLogic*gate;
switch (op()) {
@@ -647,7 +695,7 @@ NetNet* NetEUReduce::synthesize(Design*des)
NetNet::IMPLICIT, 1);
osig->local_flag(true);
string oname = scope->local_hsymbol();
perm_string oname = scope->local_symbol();
NetLogic*gate;
switch (op()) {
@@ -746,7 +794,7 @@ NetNet* NetETernary::synthesize(Design *des)
NetNet*tsig = true_val_->synthesize(des);
NetNet*fsig = false_val_->synthesize(des);
string path = csig->scope()->local_symbol();
perm_string path = csig->scope()->local_symbol();
assert(csig->pin_count() == 1);
@@ -761,7 +809,7 @@ NetNet* NetETernary::synthesize(Design *des)
assert(width <= tsig->pin_count());
assert(width <= fsig->pin_count());
string oname = csig->scope()->local_symbol();
perm_string oname = csig->scope()->local_symbol();
NetMux *mux = new NetMux(csig->scope(), oname, width, 2, 1);
for (unsigned idx = 0 ; idx < width; idx += 1) {
connect(tsig->pin(idx), mux->pin_Data(idx, 1));
@@ -815,7 +863,7 @@ NetNet* NetESignal::synthesize(Design*des)
NetScope*scope = net_->scope();
assert(scope);
string name = scope->local_symbol();
perm_string name = scope->local_symbol();
NetNet*tmp = new NetNet(scope, name, NetNet::WIRE, wid);
tmp->local_flag(true);
@@ -827,6 +875,27 @@ NetNet* NetESignal::synthesize(Design*des)
/*
* $Log: expr_synth.cc,v $
* Revision 1.59 2004/06/30 02:16:26 steve
* Implement signed divide and signed right shift in nets.
*
* Revision 1.58 2004/06/16 16:21:34 steve
* Connect rsif of multiply to DataB.
*
* Revision 1.57 2004/06/12 15:00:02 steve
* Support / and % in synthesized contexts.
*
* Revision 1.56 2004/06/01 01:04:57 steve
* Fix synthesis method for logical and/or
*
* Revision 1.55 2004/02/20 18:53:35 steve
* Addtrbute keys are perm_strings.
*
* Revision 1.54 2004/02/18 17:11:56 steve
* Use perm_strings for named langiage items.
*
* Revision 1.53 2004/02/15 04:23:48 steve
* Fix evaluation of compare to constant expression.
*
* Revision 1.52 2003/11/10 19:39:20 steve
* Remove redundant scope tokens.
*
+5 -2
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: functor.cc,v 1.31 2002/08/16 05:18:27 steve Exp $"
#ident "$Id: functor.cc,v 1.32 2004/10/04 01:10:53 steve Exp $"
#endif
# include "config.h"
@@ -114,7 +114,7 @@ void NetScope::run_functor(Design*des, functor_t*fun)
void Design::functor(functor_t*fun)
{
// Scan the scopes
for (list<NetScope*>::const_iterator scope = root_scopes_.begin();
for (list<NetScope*>::const_iterator scope = root_scopes_.begin();
scope != root_scopes_.end(); scope++)
(*scope)->run_functor(this, fun);
@@ -267,6 +267,9 @@ int proc_match_t::event_wait(NetEvWait*)
/*
* $Log: functor.cc,v $
* Revision 1.32 2004/10/04 01:10:53 steve
* Clean up spurious trailing white space.
*
* Revision 1.31 2002/08/16 05:18:27 steve
* Fix intermix of node functors and node delete.
*
+8 -8
View File
@@ -103,7 +103,7 @@ fi
if [ x"$dir_arg" != x ]; then
dst=$src
src=""
if [ -d $dst ]; then
instcmd=:
else
@@ -112,7 +112,7 @@ if [ x"$dir_arg" != x ]; then
else
# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
# might cause directories to be created, which would be especially bad
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
if [ -f $src -o -d $src ]
@@ -122,7 +122,7 @@ else
echo "install: $src does not exist"
exit 1
fi
if [ x"$dst" = x ]
then
echo "install: no destination specified"
@@ -150,7 +150,7 @@ dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
# Skip lots of stat calls in the usual case.
if [ ! -d "$dstdir" ]; then
defaultIFS='
defaultIFS='
'
IFS="${IFS-${defaultIFS}}"
@@ -189,17 +189,17 @@ else
# If we're going to rename the final executable, determine the name now.
if [ x"$transformarg" = x ]
if [ x"$transformarg" = x ]
then
dstfile=`basename $dst`
else
dstfile=`basename $dst $transformbasename |
dstfile=`basename $dst $transformbasename |
sed $transformarg`$transformbasename
fi
# don't allow the sed command to completely eliminate the filename
if [ x"$dstfile" = x ]
if [ x"$dstfile" = x ]
then
dstfile=`basename $dst`
else
@@ -230,7 +230,7 @@ else
# Now rename the file to the real destination.
$doit $rmcmd -f $dstdir/$dstfile &&
$doit $mvcmd $dsttmp $dstdir/$dstfile
$doit $mvcmd $dsttmp $dstdir/$dstfile
fi &&
+2 -2
View File
@@ -1,4 +1,4 @@
.TH iverilog-vpi 1 "$Date: 2003/10/14 00:40:06 $" Version "$Date: 2003/10/14 00:40:06 $"
.TH iverilog-vpi 1 "$Date: 2004/10/04 01:10:53 $" Version "$Date: 2004/10/04 01:10:53 $"
.SH NAME
iverilog-vpi - Compile front end for VPI modules
@@ -118,5 +118,5 @@ iverilog(1), vvp(1),
.nf
Copyright \(co 2002 Stephen Williams
This document can be freely redistributed according to the terms of the
This document can be freely redistributed according to the terms of the
GNU General Public License version 2.0
+8 -3
View File
@@ -17,7 +17,7 @@
# 59 Temple Place - Suite 330
# Boston, MA 02111-1307, USA
#
#ident "$Id: iverilog-vpi.sh,v 1.13 2003/10/14 18:05:18 steve Exp $"
#ident "$Id: iverilog-vpi.sh,v 1.14 2004/05/20 00:40:34 steve Exp $"
# These are the variables used for compiling files
CC=gcc
@@ -45,6 +45,7 @@ CXSRC=
OBJ=
LIB=
OUT=
INCOPT=
# --
# parse the command line switches. This collects the source files
@@ -80,6 +81,10 @@ do
-l*) LIB="$LIB $parm"
;;
-I*) INCOPT="$INCOPT $parm"
echo "$parm"
;;
-m32) LDFLAGS="-m32 $LDFLAGS32"
CFLAGS="-m32 $CFLAGS"
INSTDIR="$INSTDIR32"
@@ -125,7 +130,7 @@ do
obj=$base".o"
echo "Compiling $src..."
$CC -c -o $obj $CFLAGS $src || compile_errors=`expr $compile_errors + 1`
$CC -c -o $obj $CFLAGS $INCOPT $src || compile_errors=`expr $compile_errors + 1`
OBJ="$OBJ $obj"
done
@@ -135,7 +140,7 @@ do
obj=$base".o"
echo "Compiling $src..."
$CXX -c -o $obj $CFLAGS $src || compile_errors=`expr $compile_errors + 1`
$CXX -c -o $obj $CFLAGS $INCOPT $src || compile_errors=`expr $compile_errors + 1`
OBJ="$OBJ $obj"
done
+20 -11
View File
@@ -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.124 2003/12/03 02:46:24 steve Exp $"
#ident "$Id: ivl_target.h,v 1.126 2004/10/04 01:10:53 steve Exp $"
#endif
#ifdef __cplusplus
@@ -48,7 +48,7 @@ _BEGIN_DECL
*/
/*
/*
* In order to grab onto data in the design, the core passes cookies
* to the various functions of the module. These cookies can in turn
* be passed to access functions in the core to get more detailed
@@ -380,7 +380,7 @@ extern const char* ivl_design_flag(ivl_design_t des, const char*key);
extern int ivl_design_process(ivl_design_t des,
ivl_process_f fun, void*cd);
extern ivl_scope_t ivl_design_root(ivl_design_t des);
extern void ivl_design_roots(ivl_design_t des,
extern void ivl_design_roots(ivl_design_t des,
ivl_scope_t **scopes,
unsigned int *nscopes);
extern int ivl_design_time_precision(ivl_design_t des);
@@ -563,6 +563,9 @@ extern ivl_memory_t ivl_expr_memory(ivl_expr_t net);
*
* ivl_logic_pins
* ivl_logic_pin
* Return the nexus for the pin. If two pins are connected
* together, then these values are the same. Use the nexus
* functions to find other pins that are connected to this nexus.
*
* ivl_logic_attr (obsolete)
* Return the value of a specific attribute, given the key name as
@@ -591,7 +594,7 @@ extern unsigned ivl_logic_attr_cnt(ivl_net_logic_t net);
extern ivl_attribute_t ivl_logic_attr_val(ivl_net_logic_t net, unsigned idx);
/* UDP
*
*
*/
extern unsigned ivl_udp_sequ(ivl_udp_t net);
@@ -644,7 +647,7 @@ extern const char* ivl_udp_name(ivl_udp_t net);
* output vector. This is most devices, it turns out.
*
* ivl_lpm_selects
* This is the size of the select input for a LPM_MUX device, or the
* This is the size of the select input for a LPM_MUX device, or the
* address bus width of an LPM_RAM.
*
* ivl_lpm_signed
@@ -717,9 +720,9 @@ extern ivl_memory_t ivl_lpm_memory(ivl_lpm_t net);
* returns an ivl_expr_t that represents that
* expression. Otherwise, it returns 0.
*
* ivl_lval_mem
* ivl_lval_mem
* If the l-value is a memory, this method returns an
* ivl_memory_t that represents that memory. Otherwise, it
* ivl_memory_t that represents that memory. Otherwise, it
* returns 0.
*
* ivl_lval_sig
@@ -736,9 +739,9 @@ extern ivl_memory_t ivl_lpm_memory(ivl_lpm_t net);
* The part select of the signal is based here. This is the
* canonical index of bit-0 of the part select.
*
* ivl_lval_idx
* ivl_lval_idx
* If the l-value is a memory, this method returns an
* ivl_expr_t that represents the index expression. Otherwise, it
* ivl_expr_t that represents the index expression. Otherwise, it
* returns 0.
*
* ivl_lval_pin
@@ -761,7 +764,7 @@ extern ivl_signal_t ivl_lval_sig(ivl_lval_t net);
* connections of signals and nodes is handled by single-bit
* nexus. These functions manage the ivl_nexus_t object. They also
* manage the ivl_nexus_ptr_t objects that are closely related to the
* nexus.
* nexus.
*
* ivl_nexus_name
* Each nexus is given a name, typically derived from the signals
@@ -941,7 +944,7 @@ extern ivl_expr_t ivl_parameter_expr(ivl_parameter_t net);
* Every scope has a hierarchical name. This name is also a prefix
* of all the names of objects contained within the scope. The
* ivl_scope_basename is the name of the scope without the included
* hierarchy.
* hierarchy.
*
* ivl_scope_param
* ivl_scope_params
@@ -1233,6 +1236,12 @@ _END_DECL
/*
* $Log: ivl_target.h,v $
* Revision 1.126 2004/10/04 01:10:53 steve
* Clean up spurious trailing white space.
*
* Revision 1.125 2004/09/25 01:58:12 steve
* Some commentary on ivl_logic_pin.
*
* Revision 1.124 2003/12/03 02:46:24 steve
* Add support for wait on list of named events.
*
+4 -4
View File
@@ -18,7 +18,7 @@
# 59 Temple Place - Suite 330
# Boston, MA 02111-1307, USA
#
#ident "$Id: Makefile.in,v 1.15 2003/09/05 18:04:16 steve Exp $"
#ident "$Id: Makefile.in,v 1.17 2004/10/04 01:10:56 steve Exp $"
#
#
SHELL = /bin/sh
@@ -40,9 +40,9 @@ INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
CPPFLAGS = @CPPFLAGS@ @DEFS@
CFLAGS = @CFLAGS@ -I. -I.. -I$(srcdir)/.. -I$(srcdir)
LDFLAGS = @LDFLAGS@
CPPFLAGS = @ident_support@ -I. -I.. -I$(srcdir)/.. -I$(srcdir) @CPPFLAGS@ @DEFS@
CFLAGS = -Wall @CFLAGS@
LDFLAGS = @LDFLAGS@
all: ivlpp
+3 -3
View File
@@ -1,17 +1,17 @@
Copyright (c) 1999 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
+8 -5
View File
@@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: lexor.lex,v 1.42 2003/09/26 02:08:31 steve Exp $"
#ident "$Id: lexor.lex,v 1.46 2004/09/10 00:15:45 steve Exp $"
#endif
# include "config.h"
@@ -30,6 +30,7 @@
#endif
# include <stdlib.h>
# include <string.h>
# include <ctype.h>
# include <assert.h>
# include "parse.h"
@@ -90,7 +91,8 @@ static void ifdef_enter(void)
{
struct ifdef_stack_t*cur;
cur = calloc(1, sizeof(struct ifdef_stack_t));
cur = (struct ifdef_stack_t*)
calloc(1, sizeof(struct ifdef_stack_t));
cur->path = strdup(istack->path);
cur->lineno = istack->lineno;
cur->next = ifdef_stack;
@@ -390,7 +392,8 @@ static void def_match()
return;
}
isp = calloc(1, sizeof(struct include_stack_t));
isp = (struct include_stack_t*)
calloc(1, sizeof(struct include_stack_t));
isp->str = cur->value;
isp->next = istack;
istack->yybs = YY_CURRENT_BUFFER;
@@ -552,7 +555,7 @@ static int def_is_done()
/*
* After some number of calls to do_define, this function is called to
* assigned value to the parsed name. If there is no value, then
* assign the string "1"
* assign the string "" (empty string.)
*/
static void def_finish()
{
@@ -566,7 +569,7 @@ static void def_finish()
define_cnt = 0;
} else {
define_macro(def_name, "1", 0);
define_macro(def_name, "", 0);
}
def_name[0] = 0;
}
+13 -2
View File
@@ -17,7 +17,7 @@ const char COPYRIGHT[] =
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: main.c,v 1.17 2003/09/26 02:08:31 steve Exp $"
#ident "$Id: main.c,v 1.20 2004/09/10 00:15:45 steve Exp $"
#endif
# include "config.h"
@@ -47,6 +47,7 @@ const char VERSION[] = "$Name: $ $State: Exp $";
#endif
# include <unistd.h>
# include <string.h>
# include <ctype.h>
#if defined(HAVE_GETOPT_H)
# include <getopt.h>
#endif
@@ -176,7 +177,8 @@ int main(int argc, char*argv[])
break;
case 'I':
include_dir = realloc(include_dir, (include_cnt+1)*sizeof(char*));
include_dir = realloc(include_dir,
(include_cnt+1)*sizeof(char*));
include_dir[include_cnt] = strdup(optarg);
include_cnt += 1;
break;
@@ -288,6 +290,15 @@ int main(int argc, char*argv[])
/*
* $Log: main.c,v $
* Revision 1.20 2004/09/10 00:15:45 steve
* Remove bad casts.
*
* Revision 1.19 2004/09/05 21:29:08 steve
* Better type safety.
*
* Revision 1.18 2004/02/15 18:03:30 steve
* Cleanup of warnings.
*
* Revision 1.17 2003/09/26 02:08:31 steve
* Detect missing endif markers.
*
+32 -2
View File
@@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: lexor.lex,v 1.85 2003/08/31 21:14:28 steve Exp $"
#ident "$Id: lexor.lex,v 1.86 2004/06/13 04:56:54 steve Exp $"
#endif
# include "config.h"
@@ -98,6 +98,7 @@ static int comment_enter;
%x CSTRING
%s UDPTABLE
%x PPTIMESCALE
%x PPDEFAULT_NETTYPE
W [ \t\b\f\r]+
@@ -269,7 +270,6 @@ W [ \t\b\f\r]+
should handle these, not an external preprocessor. */
^{W}?`celldefine{W}?.* { }
^{W}?`default_nettype{W}?.* { }
^{W}?`delay_mode_distributed{W}?.* { }
^{W}?`delay_mode_unit{W}?.* { }
^{W}?`delay_mode_path{W}?.* { }
@@ -285,6 +285,36 @@ W [ \t\b\f\r]+
^{W}?`unconnected_drive{W}?.* { }
^{W}?`uselib{W}?.* { }
/* Notice and handle the default_nettype directive. The lexor
detects the default_nettype keyword, and the second part of the
rule collects the rest of the line and processes it. We only need
to look for the first work, and interpret it. */
`default_nettype{W}? { BEGIN(PPDEFAULT_NETTYPE); }
<PPDEFAULT_NETTYPE>.* {
NetNet::Type net_type;
size_t wordlen = strcspn(yytext, " \t\f\r\n");
yytext[wordlen] = 0;
if (strcmp(yytext,"wire") == 0) {
net_type = NetNet::WIRE;
} else if (strcmp(yytext,"none") == 0) {
net_type = NetNet::NONE;
} else {
cerr << yylloc.text << ":" << yylloc.first_line
<< " error: Net type " << yytext
<< " is not a valid (and supported)"
<< " default net type." << endl;
net_type = NetNet::WIRE;
error_count += 1;
}
pform_set_default_nettype(net_type, yylloc.text, yylloc.first_line);
}
<PPDEFAULT_NETTYPE>\n {
yylloc.first_line += 1;
BEGIN(0); }
/* These are directives that are not supported by me and should have
been handled by an external preprocessor such as ivlpp. */
+7 -9
View File
@@ -16,7 +16,7 @@
# 59 Temple Place - Suite 330
# Boston, MA 02111-1307, USA
#
#ident "$Id: Makefile.in,v 1.31 2003/10/10 02:57:45 steve Exp $"
#ident "$Id: Makefile.in,v 1.34 2004/10/04 01:10:07 steve Exp $"
#
#
SHELL = /bin/sh
@@ -33,15 +33,13 @@ libdir = @libdir@
libdir64 = @libdir64@
includedir = $(prefix)/include
CC = @CC@ -I. -I.. -I$(srcdir) -I$(srcdir)/..
CXX = @CXX@ -I. -I.. -I$(srcdir) -I$(srcdir)/..
CC = @CC@
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
CPPFLAGS = @CPPFLAGS@ @DEFS@ @PICFLAG@
CXXFLAGS = @CXXFLAGS@
CFLAGS = @CFLAGS@
CPPFLAGS = @ident_support@ -I. -I.. -I$(srcdir) -I$(srcdir)/.. @CPPFLAGS@ @DEFS@ @PICFLAG@
CFLAGS = -Wall @CFLAGS@
LDFLAGS = @LDFLAGS@
STRIP = @STRIP@
RANLIB = @RANLIB@
@@ -86,12 +84,12 @@ dep:
mkdir dep
%.o: %.c
$(CC) -Wall $(CPPFLAGS) $(CFLAGS) -MD -c $< -o $*.o
$(CC) $(CPPFLAGS) $(CFLAGS) -MD -c $< -o $*.o
mv $*.d dep
clean:
rm -rf *.o dep libveriuser.a libveriuser.o
rm -rf *.o dep libveriuser.a libveriuser.o bin32
distclean: clean
rm -f Makefile config.status config.log config.cache
@@ -114,7 +112,7 @@ bin32:
mkdir bin32
bin32/%.o: %.c
$(CC) -m32 -Wall $(CPPFLAGS) $(CFLAGS) -MD -c $< -o $@
$(CC) -m32 $(CPPFLAGS) $(CFLAGS) -MD -c $< -o $@
bin32/libveriuser.o: $(addprefix bin32/,$O)
$(LD) -melf_i386 -r -o $@ $(addprefix bin32/,$O)
+5 -2
View File
@@ -17,19 +17,22 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: a_compare_handles.c,v 1.2 2003/08/26 16:26:02 steve Exp $"
#ident "$Id: a_compare_handles.c,v 1.3 2004/02/18 02:51:59 steve Exp $"
#endif
# include <vpi_user.h>
# include <acc_user.h>
int acc_compare_handles(handle handle1, handle handle2)
PLI_INT32 acc_compare_handles(handle handle1, handle handle2)
{
return handle1 == handle2;
}
/*
* $Log: a_compare_handles.c,v $
* Revision 1.3 2004/02/18 02:51:59 steve
* Fix type mismatches of various VPI functions.
*
* Revision 1.2 2003/08/26 16:26:02 steve
* ifdef idents correctly.
*
+31 -1
View File
@@ -17,12 +17,13 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: a_configure.c,v 1.3 2003/06/17 16:55:07 steve Exp $"
#ident "$Id: a_configure.c,v 1.4 2003/12/17 15:45:07 steve Exp $"
#endif
#include <acc_user.h>
#include <vpi_user.h>
#include "priv.h"
#include <string.h>
int acc_configure(PLI_INT32 config_param, const char*value)
{
@@ -39,6 +40,32 @@ int acc_configure(PLI_INT32 config_param, const char*value)
}
break;
case accEnableArgs:
if (pli_trace) {
fprintf(pli_trace, "acc_configure(accEnableArgs, %s)\n",
value);
}
rc = 1;
if (strcmp(value,"acc_set_scope") == 0) {
vpi_printf("XXXX acc_configure argument: Sorry: "
"(accEnableArgs, %s\n", value);
rc = 0;
} else if (strcmp(value,"no_acc_set_scope") == 0) {
vpi_printf("XXXX acc_configure argument: Sorry: "
"(accEnableArgs, %s\n", value);
rc = 0;
} else {
vpi_printf("XXXX acc_configure argument error. "
"(accEnableArgs, %s(invalid)\n", value);
rc = 0;
}
break;
default:
if (pli_trace) {
@@ -56,6 +83,9 @@ int acc_configure(PLI_INT32 config_param, const char*value)
/*
* $Log: a_configure.c,v $
* Revision 1.4 2003/12/17 15:45:07 steve
* Add acc_set_scope function.
*
* Revision 1.3 2003/06/17 16:55:07 steve
* 1) setlinebuf() for vpi_trace
* 2) Addes error checks for trace file opens
+5 -2
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: a_fetch_range.c,v 1.1 2003/06/04 01:56:20 steve Exp $"
#ident "$Id: a_fetch_range.c,v 1.2 2004/02/18 02:51:59 steve Exp $"
#endif
#include <vpi_user.h>
@@ -26,7 +26,7 @@
/*
* acc_fetch_range implemented using VPI interface
*/
PLI_INT32 acc_fetch_range(handle object, PLI_INT32 *msb, PLI_INT32 *lsb)
PLI_INT32 acc_fetch_range(handle object, int *msb, int *lsb)
{
*msb = vpi_get(vpiLeftRange, object);
*lsb = vpi_get(vpiRightRange, object);
@@ -35,6 +35,9 @@ PLI_INT32 acc_fetch_range(handle object, PLI_INT32 *msb, PLI_INT32 *lsb)
/*
* $Log: a_fetch_range.c,v $
* Revision 1.2 2004/02/18 02:51:59 steve
* Fix type mismatches of various VPI functions.
*
* Revision 1.1 2003/06/04 01:56:20 steve
* 1) Adds configure logic to clean up compiler warnings
* 2) adds acc_compare_handle, acc_fetch_range, acc_next_scope and
+10 -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: a_fetch_tfarg.c,v 1.8 2003/06/14 01:16:17 steve Exp $"
#ident "$Id: a_fetch_tfarg.c,v 1.10 2004/10/04 01:10:56 steve Exp $"
#endif
#include <vpi_user.h>
@@ -42,7 +42,7 @@ double acc_fetch_itfarg(PLI_INT32 n, handle obj)
if (hand) {
value.format=vpiRealVal;
vpi_get_value(hand, &value);
rtn = value.value.real;
rtn = value.value.real;
vpi_free_object(iter);
} else {
rtn = 0.0;
@@ -56,7 +56,7 @@ double acc_fetch_itfarg(PLI_INT32 n, handle obj)
return rtn;
}
double acc_fetch_tfarg(int n)
double acc_fetch_tfarg(PLI_INT32 n)
{
return acc_fetch_itfarg_int(n, vpi_handle(vpiSysTfCall,0));
}
@@ -77,7 +77,7 @@ PLI_INT32 acc_fetch_itfarg_int(PLI_INT32 n, handle obj)
if (hand) {
value.format=vpiIntVal;
vpi_get_value(hand, &value);
rtn = value.value.integer;
rtn = value.value.integer;
vpi_free_object(iter);
} else {
rtn = 0;
@@ -134,6 +134,12 @@ char *acc_fetch_tfarg_str(PLI_INT32 n)
/*
* $Log: a_fetch_tfarg.c,v $
* Revision 1.10 2004/10/04 01:10:56 steve
* Clean up spurious trailing white space.
*
* Revision 1.9 2004/02/18 02:51:59 steve
* Fix type mismatches of various VPI functions.
*
* Revision 1.8 2003/06/14 01:16:17 steve
* ihand is system task, not scope.
*
+5 -2
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: a_fetch_type.c,v 1.7 2003/06/04 01:56:20 steve Exp $"
#ident "$Id: a_fetch_type.c,v 1.8 2004/10/04 01:10:56 steve Exp $"
#endif
# include <acc_user.h>
@@ -78,7 +78,7 @@ PLI_INT32 acc_fetch_fulltype(handle obj)
type = vpi_get(vpiNetType, obj);
switch(type) {
case vpiWire: return accWire;
default:
default:
vpi_printf("acc_fetch_fulltype: vpiNetType %d unknown?\n",
type);
return accUnknown;
@@ -121,6 +121,9 @@ PLI_INT32 acc_fetch_fulltype(handle obj)
/*
* $Log: a_fetch_type.c,v $
* Revision 1.8 2004/10/04 01:10:56 steve
* Clean up spurious trailing white space.
*
* Revision 1.7 2003/06/04 01:56:20 steve
* 1) Adds configure logic to clean up compiler warnings
* 2) adds acc_compare_handle, acc_fetch_range, acc_next_scope and
+26 -3
View File
@@ -17,24 +17,47 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: a_handle_object.c,v 1.1 2003/03/13 04:35:09 steve Exp $"
#ident "$Id: a_handle_object.c,v 1.2 2003/12/17 15:45:07 steve Exp $"
#endif
#include <vpi_user.h>
#include <acc_user.h>
#include "priv.h"
static vpiHandle search_scope = 0;
handle acc_handle_object(const char*name)
{
vpiHandle sys = vpi_handle(vpiSysTfCall, 0);
vpiHandle scope = vpi_handle(vpiScope, sys);
vpiHandle scope = search_scope? search_scope : vpi_handle(vpiScope, sys);
vpiHandle res = vpi_handle_by_name(name, scope);
if (pli_trace) {
fprintf(pli_trace, "acc_handle_object(%s <scope=%s>) --> .\n",
name, acc_fetch_fullname(scope));
}
return res;
}
char* acc_set_scope(handle ref, ...)
{
char*name;
search_scope = ref;
name = acc_fetch_fullname(search_scope);
if (pli_trace) {
fprintf(pli_trace, "acc_set_scope(<scope=%s>)\n", name);
}
return acc_fetch_fullname(ref);
}
/*
* $Log: a_handle_object.c,v $
* Revision 1.2 2003/12/17 15:45:07 steve
* Add acc_set_scope function.
*
* Revision 1.1 2003/03/13 04:35:09 steve
* Add a bunch of new acc_ and tf_ functions.
*
+5 -2
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: a_handle_tfarg.c,v 1.5 2003/03/18 01:21:49 steve Exp $"
#ident "$Id: a_handle_tfarg.c,v 1.6 2004/10/04 01:10:56 steve Exp $"
#endif
#include <acc_user.h>
@@ -29,7 +29,7 @@
handle acc_handle_tfarg(int n)
{
vpiHandle sys_h, sys_i, rtn_h = 0;
if (n > 0) {
sys_h = vpi_handle(vpiSysTfCall, 0 /* NULL */);
sys_i = vpi_iterate(vpiArgument, sys_h);
@@ -58,6 +58,9 @@ handle acc_handle_tfinst(void)
/*
* $Log: a_handle_tfarg.c,v $
* Revision 1.6 2004/10/04 01:10:56 steve
* Clean up spurious trailing white space.
*
* Revision 1.5 2003/03/18 01:21:49 steve
* Fix warning about uninitialized variable.
*
+6 -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: a_object_of_type.c,v 1.5 2003/06/04 01:56:20 steve Exp $"
#ident "$Id: a_object_of_type.c,v 1.6 2004/02/18 02:51:59 steve Exp $"
#endif
#include <assert.h>
@@ -28,7 +28,7 @@
/*
* acc_object_of_type implemented using VPI interface
*/
PLI_INT32 acc_object_of_type(handle object, PLI_INT32 type)
int acc_object_of_type(handle object, PLI_INT32 type)
{
int vtype;
int rtn = 0; /* false */
@@ -86,7 +86,7 @@ PLI_INT32 acc_object_of_type(handle object, PLI_INT32 type)
return rtn;
}
PLI_INT32 acc_object_in_typelist(handle object, PLI_INT32*typelist)
int acc_object_in_typelist(handle object, PLI_INT32*typelist)
{
while (typelist[0] != 0) {
int rtn = acc_object_of_type(object, typelist[0]);
@@ -101,6 +101,9 @@ PLI_INT32 acc_object_in_typelist(handle object, PLI_INT32*typelist)
/*
* $Log: a_object_of_type.c,v $
* Revision 1.6 2004/02/18 02:51:59 steve
* Fix type mismatches of various VPI functions.
*
* Revision 1.5 2003/06/04 01:56:20 steve
* 1) Adds configure logic to clean up compiler warnings
* 2) adds acc_compare_handle, acc_fetch_range, acc_next_scope and
+5 -2
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: a_vcl.c,v 1.6 2003/06/17 16:55:07 steve Exp $"
#ident "$Id: a_vcl.c,v 1.7 2004/10/04 01:10:56 steve Exp $"
#endif
#include <vpi_user.h>
@@ -154,7 +154,7 @@ static PLI_INT32 vcl_value_callback(struct t_cb_data*cb)
vcr.vc_hightime = sim_time.high;
vcr.vc_lowtime = sim_time.low;
vcr.user_data = cur->user_data;
(cur->consumer) (&vcr);
return 0;
}
@@ -206,6 +206,9 @@ void acc_vcl_delete(handle obj, PLI_INT32(*consumer)(p_vc_record),
/*
* $Log: a_vcl.c,v $
* Revision 1.7 2004/10/04 01:10:56 steve
* Clean up spurious trailing white space.
*
* Revision 1.6 2003/06/17 16:55:07 steve
* 1) setlinebuf() for vpi_trace
* 2) Addes error checks for trace file opens
+5 -24
View File
@@ -5,8 +5,8 @@ AC_PROG_CC
AC_PROG_INSTALL
AC_PROG_RANLIB
AC_CYGWIN
AC_EXEEXT
AX_CPP_IDENT
# vvp32 is by default disabled
#enable_vvp32=no
@@ -18,30 +18,11 @@ AC_CHECK_SIZEOF(unsigned long long)
AC_CHECK_SIZEOF(unsigned long)
AC_CHECK_SIZEOF(unsigned)
# Darwin requires -no-cpp-precomp
case "${host}" in
*-*-darwin*)
CPPFLAGS="-no-cpp-precomp $CPPFLAGS"
CFLAGS="-no-cpp-precomp $CFLAGS"
;;
esac
AC_MSG_CHECKING(for flag to make position independent code)
PICFLAG=-fPIC
case "${host}" in
*-*-cygwin*)
PICFLAG=
;;
*-*-hpux*)
PICFLAG=+z
;;
esac
AC_SUBST(PICFLAG)
AC_MSG_RESULT($PICFLAG)
# may modify CPPFLAGS and CFLAGS
AX_CPP_PRECOMP
# Compiler option for position independent code, needed whan making shared objects.
AX_C_PICFLAG
AC_SUBST(EXEEXT)
AC_SUBST(EXTRALIBS)
+5 -2
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: getp.c,v 1.6 2003/06/17 16:55:07 steve Exp $"
#ident "$Id: getp.c,v 1.7 2004/10/04 01:10:56 steve Exp $"
#endif
# include <assert.h>
@@ -158,7 +158,7 @@ char *tf_istrgetp(PLI_INT32 n, PLI_INT32 fmt, void *obj)
case 'd': value.format = vpiDecStrVal; break;
case 'h': value.format = vpiHexStrVal; break;
}
if (value.format > 0) {
if (value.format > 0) {
vpi_get_value(arg_h, &value);
rtn = value.value.str;
}
@@ -184,6 +184,9 @@ char *tf_strgetp(PLI_INT32 n, PLI_INT32 fmt)
/*
* $Log: getp.c,v $
* Revision 1.7 2004/10/04 01:10:56 steve
* Clean up spurious trailing white space.
*
* Revision 1.6 2003/06/17 16:55:07 steve
* 1) setlinebuf() for vpi_trace
* 2) Addes error checks for trace file opens
+5 -2
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: putlongp.c,v 1.3 2003/03/15 05:42:39 steve Exp $"
#ident "$Id: putlongp.c,v 1.4 2004/09/10 23:13:05 steve Exp $"
#endif
#include <stdio.h>
@@ -58,13 +58,16 @@ void tf_putlongp(int n, int lowvalue, int highvalue)
sprintf(str, "%x%08x", highvalue, lowvalue);
val.format = vpiHexStrVal;
val.value.str = str;
(void)vpi_put_value(arg_h, &val, 0, vpiNoDelay);
vpi_put_value(arg_h, &val, 0, vpiNoDelay);
vpi_free_object(sys_i);
}
/*
* $Log: putlongp.c,v $
* Revision 1.4 2004/09/10 23:13:05 steve
* Compile cleanup of C code.
*
* Revision 1.3 2003/03/15 05:42:39 steve
* free argument iterators.
*
+6 -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: putp.c,v 1.6 2003/06/26 03:20:24 steve Exp $"
#ident "$Id: putp.c,v 1.7 2004/09/10 23:13:05 steve Exp $"
#endif
# include <assert.h>
@@ -74,7 +74,7 @@ PLI_INT32 tf_iputp(PLI_INT32 n, PLI_INT32 value, void *obj)
/* fill in vpi_value */
val.format = vpiIntVal;
val.value.integer = value;
(void)vpi_put_value(arg_h, &val, 0, vpiNoDelay);
vpi_put_value(arg_h, &val, 0, vpiNoDelay);
if (arg_h)
vpi_free_object(sys_i);
@@ -123,7 +123,7 @@ PLI_INT32 tf_iputrealp(PLI_INT32 n, double value, void *obj)
/* fill in vpi_value */
val.format = vpiRealVal;
val.value.real = value;
(void)vpi_put_value(arg_h, &val, 0, vpiNoDelay);
vpi_put_value(arg_h, &val, 0, vpiNoDelay);
free:
vpi_free_object(sys_i);
@@ -145,6 +145,9 @@ PLI_INT32 tf_putrealp(PLI_INT32 n, double value)
}
/*
* $Log: putp.c,v $
* Revision 1.7 2004/09/10 23:13:05 steve
* Compile cleanup of C code.
*
* Revision 1.6 2003/06/26 03:20:24 steve
* Correct handle of put to function return value.
*
+8 -5
View File
@@ -18,7 +18,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: veriusertfs.c,v 1.14 2003/06/25 04:04:19 steve Exp $"
#ident "$Id: veriusertfs.c,v 1.15 2004/09/10 23:13:05 steve Exp $"
#endif
/*
@@ -84,7 +84,7 @@ void veriusertfs_register_table(p_tfcell vtable)
}
/* squirrel away veriusertfs in persistent user_data */
data = (p_pli_data) calloc(1, sizeof(s_pli_data));
data = calloc(1, sizeof(s_pli_data));
assert(data != NULL);
data->tf = tf;
@@ -92,7 +92,7 @@ void veriusertfs_register_table(p_tfcell vtable)
it to the pli_data that represents this
function. Supply wrapper functions for the system
task actions. */
(void) memset(&tf_data, 0, sizeof(s_vpi_systf_data));
memset(&tf_data, 0, sizeof(s_vpi_systf_data));
switch (tf->type) {
case usertask:
tf_data.type = vpiSysTask;
@@ -164,7 +164,7 @@ static int compiletf(char *data)
vpi_put_userdata(call_h, pli);
/* default cb_data */
(void) memset(&cb_data, 0, sizeof(s_cb_data));
memset(&cb_data, 0, sizeof(s_cb_data));
cb_data.cb_rtn = callback;
cb_data.user_data = data;
@@ -182,7 +182,7 @@ static int compiletf(char *data)
cb_data.reason = cbValueChange;
while ((arg_h = vpi_scan(arg_i)) != NULL) {
/* replicate user_data for each instance */
dp = (p_pli_data)calloc(1, sizeof(s_pli_data));
dp = calloc(1, sizeof(s_pli_data));
assert(dp != NULL);
memcpy(dp, cb_data.user_data, sizeof(s_pli_data));
dp->paramvc = paramvc++;
@@ -389,6 +389,9 @@ PLI_INT32 tf_setrealdelay(double dly)
}
/*
* $Log: veriusertfs.c,v $
* Revision 1.15 2004/09/10 23:13:05 steve
* Compile cleanup of C code.
*
* Revision 1.14 2003/06/25 04:04:19 steve
* Fix mingw portability problems.
*
+5 -2
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: link_const.cc,v 1.16 2003/06/21 01:21:43 steve Exp $"
#ident "$Id: link_const.cc,v 1.17 2004/10/04 01:10:53 steve Exp $"
#endif
# include "config.h"
@@ -59,7 +59,7 @@ bool Nexus::drivers_constant() const
outside world. */
if (cur_dir == Link::PASSIVE) {
const NetObj*obj = cur->get_obj();
if (obj->scope()->parent() != 0)
continue;
@@ -164,6 +164,9 @@ verinum::V Nexus::driven_value() const
/*
* $Log: link_const.cc,v $
* Revision 1.17 2004/10/04 01:10:53 steve
* Clean up spurious trailing white space.
*
* Revision 1.16 2003/06/21 01:21:43 steve
* Harmless fixup of warnings.
*
+1 -1
View File
@@ -38,7 +38,7 @@ quite similar.
lexor_keyword.gperf, and use that.
3) If working with a CVS snapshot, you must run autoconf in several
directories. This is aided by the 'autoconf.sh' script at the
directories. This is aided by the 'autoconf.sh' script at the
top of the source tree:
sh ./autoconf.sh
+70 -21
View File
@@ -1,6 +1,6 @@
const char COPYRIGHT[] =
"Copyright (c) 1998-2003 Stephen Williams ([email protected])";
"Copyright (c) 1998-2004 Stephen Williams ([email protected])";
/*
* This source code is free software; you can redistribute it
@@ -19,7 +19,7 @@ const char COPYRIGHT[] =
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: main.cc,v 1.79 2003/11/26 01:37:14 steve Exp $"
#ident "$Id: main.cc,v 1.86 2004/10/04 01:10:53 steve Exp $"
#endif
# include "config.h"
@@ -86,11 +86,11 @@ generation_t generation_flag = GN_DEFAULT;
map<string,const char*> flags;
char*vpi_module_list = 0;
map<string,unsigned> missing_modules;
map<perm_string,unsigned> missing_modules;
list<const char*> library_suff;
list<const char*> roots;
list<perm_string> roots;
char*ivlpp_string = 0;
@@ -106,6 +106,12 @@ bool warn_portbinding = false;
bool error_implicit = false;
/*
* Debug message class flags.
*/
bool debug_scopes = false;
bool debug_eval_tree = false;
bool debug_elaborate = false;
/*
* Verbose messages enabled.
*/
@@ -228,6 +234,9 @@ static void parm_to_flagmap(const string&flag)
* basedir:<path>
* Location to look for installed sub-components
*
* debug:<name>
* Activate a class of debug messages.
*
* depfile:<path>
* Give the path to an output dependency file.
*
@@ -250,6 +259,9 @@ static void parm_to_flagmap(const string&flag)
* out:<path>
* Path to the output file.
*
* sys_func:<path>
* Path to a system functions descriptor table
*
* root:<name>
* Specify a root module. There may be multiple of this.
*
@@ -292,6 +304,19 @@ static void read_iconfig_file(const char*ipath)
if (strcmp(buf, "basedir") == 0) {
basedir = strdup(cp);
} else if (strcmp(buf, "debug") == 0) {
if (strcmp(cp, "scope") == 0) {
debug_scopes = true;
cerr << "debug: Enable scope debug" << endl;
} else if (strcmp(cp,"eval_tree") == 0) {
debug_eval_tree = true;
cerr << "debug: Enable eval_tree debug" << endl;
} else if (strcmp(cp,"elaborate") == 0) {
debug_elaborate = true;
cerr << "debug: Enable elaborate debug" << endl;
} else {
}
} else if (strcmp(buf, "depfile") == 0) {
depfile_name = strdup(cp);
@@ -333,8 +358,11 @@ static void read_iconfig_file(const char*ipath)
} else if (strcmp(buf, "out") == 0) {
flags["-o"] = strdup(cp);
} else if (strcmp(buf, "sys_func") == 0) {
load_sys_func_table(cp);
} else if (strcmp(buf, "root") == 0) {
roots.push_back(strdup(cp));
roots.push_back(lex_strings.make(cp));
} else if (strcmp(buf,"warnings") == 0) {
/* Scan the warnings enable string for warning flags. */
@@ -384,19 +412,19 @@ static void read_iconfig_file(const char*ipath)
}
}
extern Design* elaborate(list <const char*>root);
extern Design* elaborate(list <perm_string> root);
#if defined(HAVE_TIMES)
static double cycles_diff(struct tms *a, struct tms *b)
{
clock_t aa = a->tms_utime
+ a->tms_stime
+ a->tms_cutime
clock_t aa = a->tms_utime
+ a->tms_stime
+ a->tms_cutime
+ a->tms_cstime;
clock_t bb = b->tms_utime
+ b->tms_stime
+ b->tms_cutime
clock_t bb = b->tms_utime
+ b->tms_stime
+ b->tms_cutime
+ b->tms_cstime;
return (aa-bb)/(double)sysconf(_SC_CLK_TCK);
@@ -498,7 +526,7 @@ int main(int argc, char*argv[])
perror(depfile_name);
}
}
if (verbose_flag) {
if (times_flag)
@@ -526,13 +554,13 @@ int main(int argc, char*argv[])
if (pf_path) {
ofstream out (pf_path);
out << "PFORM DUMP MODULES:" << endl;
for (map<string,Module*>::iterator mod = pform_modules.begin()
for (map<perm_string,Module*>::iterator mod = pform_modules.begin()
; mod != pform_modules.end()
; mod ++ ) {
pform_dump(out, (*mod).second);
}
out << "PFORM DUMP PRIMITIVES:" << endl;
for (map<string,PUdp*>::iterator idx = pform_primitives.begin()
for (map<perm_string,PUdp*>::iterator idx = pform_primitives.begin()
; idx != pform_primitives.end()
; idx ++ ) {
(*idx).second->dump(out);
@@ -548,8 +576,8 @@ int main(int argc, char*argv[])
then look for modules that are not instantiated anywhere. */
if (roots.empty()) {
map<string,bool> mentioned_p;
map<string,Module*>::iterator mod;
map<perm_string,bool> mentioned_p;
map<perm_string,Module*>::iterator mod;
if (verbose_flag)
cout << "LOCATING TOP-LEVEL MODULES" << endl << " ";
for (mod = pform_modules.begin()
@@ -578,7 +606,7 @@ int main(int argc, char*argv[])
if (verbose_flag)
cout << endl;
}
/* If there is *still* no guess for the root module, then give
up completely, and complain. */
@@ -618,7 +646,7 @@ int main(int argc, char*argv[])
des->set_flags(flags);
/* Done iwth all the pform data. Delete the modules. */
for (map<string,Module*>::iterator idx = pform_modules.begin()
for (map<perm_string,Module*>::iterator idx = pform_modules.begin()
; idx != pform_modules.end() ; idx ++) {
delete (*idx).second;
@@ -700,7 +728,7 @@ int main(int argc, char*argv[])
if (missing_modules.size() > 0) {
cerr << "*** These modules were missing:" << endl;
map<string,unsigned>::const_iterator idx;
map<perm_string,unsigned>::const_iterator idx;
for (idx = missing_modules.begin()
; idx != missing_modules.end()
; idx ++)
@@ -711,11 +739,32 @@ int main(int argc, char*argv[])
cerr << "***" << endl;
}
return des->errors;
return des? des->errors : 1;
}
/*
* $Log: main.cc,v $
* Revision 1.86 2004/10/04 01:10:53 steve
* Clean up spurious trailing white space.
*
* Revision 1.85 2004/09/25 01:58:44 steve
* Add a debug_elaborate flag
*
* Revision 1.84 2004/09/10 23:51:42 steve
* Fix the evaluation of constant ternary expressions.
*
* Revision 1.83 2004/09/05 17:44:42 steve
* Add support for module instance arrays.
*
* Revision 1.82 2004/03/10 04:51:24 steve
* Add support for system function table files.
*
* Revision 1.81 2004/02/18 17:11:56 steve
* Use perm_strings for named langiage items.
*
* Revision 1.80 2004/02/15 00:19:29 steve
* Report elaboration errors without crashing.
*
* Revision 1.79 2003/11/26 01:37:14 steve
* Properly initialize vpi_module_list with system.
*
+7 -4
View File
@@ -1,7 +1,7 @@
#ifndef __named_H
#define __named_H
/*
* Copyright (c) 2000 Stephen Williams (steve@icarus.com)
* Copyright (c) 2000-2004 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,10 +19,10 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: named.h,v 1.3 2002/08/12 01:34:59 steve Exp $"
#ident "$Id: named.h,v 1.4 2004/02/20 06:22:56 steve Exp $"
#endif
# include <string>
# include "StringHeap.h"
/*
* There are lots of places where names are attached to objects. This
@@ -30,12 +30,15 @@
*/
template <class T> struct named {
string name;
perm_string name;
T parm;
};
/*
* $Log: named.h,v $
* Revision 1.4 2004/02/20 06:22:56 steve
* parameter keys are per_strings.
*
* Revision 1.3 2002/08/12 01:34:59 steve
* conditional ident string using autoconfig.
*
+17 -36
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.16 2003/01/26 21:15:58 steve Exp $"
#ident "$Id: net_assign.cc,v 1.18 2004/08/28 15:08:31 steve Exp $"
#endif
# include "config.h"
@@ -67,7 +67,7 @@ NetAssign_::~NetAssign_()
{
if (sig_) {
sig_->decr_lref();
if (sig_->peek_lref() == 0)
if (turn_sig_to_wire_on_release_ && sig_->peek_lref() == 0)
sig_->type(NetNet::WIRE);
}
@@ -98,14 +98,14 @@ unsigned NetAssign_::lwidth() const
else return lwid_;
}
const char*NetAssign_::name() const
perm_string NetAssign_::name() const
{
if (sig_) {
return sig_->name();
} else if (mem_) {
return mem_->name();
} else {
return "";
return perm_string::literal("");
}
}
@@ -142,6 +142,13 @@ unsigned NetAssign_::get_loff() const
return loff_;
}
/*
*/
void NetAssign_::turn_sig_to_wire_on_release()
{
turn_sig_to_wire_on_release_ = true;
}
NetAssignBase::NetAssignBase(NetAssign_*lv, NetExpr*rv)
: lval_(lv), rval_(rv), delay_(0)
{
@@ -254,6 +261,12 @@ NetAssignNB::~NetAssignNB()
/*
* $Log: net_assign.cc,v $
* Revision 1.18 2004/08/28 15:08:31 steve
* Do not change reg to wire in NetAssign_ unless synthesizing.
*
* Revision 1.17 2004/02/18 17:11:56 steve
* Use perm_strings for named langiage items.
*
* Revision 1.16 2003/01/26 21:15:58 steve
* Rework expression parsing and elaboration to
* accommodate real/realtime values and expressions.
@@ -289,37 +302,5 @@ NetAssignNB::~NetAssignNB()
* Redo handling of assignment internal delays.
* Leave it possible for them to be calculated
* at run time.
*
* Revision 1.8 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.7 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.6 2000/10/18 20:04:39 steve
* Add ivl_lval_t and support for assignment l-values.
*
* Revision 1.5 2000/09/20 02:53:15 steve
* Correctly measure comples l-values of assignments.
*
* Revision 1.4 2000/09/10 02:18:16 steve
* elaborate complex l-values
*
* Revision 1.3 2000/09/07 00:06:53 steve
* encapsulate access to the l-value expected width.
*
* Revision 1.2 2000/09/02 23:40:13 steve
* Pull NetAssign_ creation out of constructors.
*
* Revision 1.1 2000/09/02 20:54:20 steve
* Rearrange NetAssign to make NetAssign_ separate.
*
*/
+21 -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: net_design.cc,v 1.42 2003/11/10 20:59:03 steve Exp $"
#ident "$Id: net_design.cc,v 1.45 2004/10/04 01:10:54 steve Exp $"
#endif
# include "config.h"
@@ -31,6 +31,7 @@
# include "netlist.h"
# include "util.h"
# include "compiler.h"
# include <sstream>
Design:: Design()
@@ -80,7 +81,7 @@ unsigned long Design::scale_to_precision(unsigned long val,
return val;
}
NetScope* Design::make_root_scope(const char*root)
NetScope* Design::make_root_scope(perm_string root)
{
NetScope *root_scope_;
root_scope_ = new NetScope(0, root, NetScope::MODULE);
@@ -246,7 +247,7 @@ const NetExpr* Design::find_parameter(const NetScope*scope,
*/
void Design::run_defparams()
{
for (list<NetScope*>::const_iterator scope = root_scopes_.begin();
for (list<NetScope*>::const_iterator scope = root_scopes_.begin();
scope != root_scopes_.end(); scope++)
(*scope)->run_defparams(this);
}
@@ -265,32 +266,32 @@ void NetScope::run_defparams(Design*des)
NetExpr*val = (*pp).second;
hname_t path = (*pp).first;
char*name = path.remove_tail_name();
char*tmp = path.remove_tail_name();
perm_string perm_name = lex_strings.make(tmp);
delete[]tmp;
/* If there is no path on the name, then the targ_scope
is the current scope. */
NetScope*targ_scope = des->find_scope(this, path);
if (targ_scope == 0) {
cerr << val->get_line() << ": warning: scope of " <<
path << "." << name << " not found." << endl;
delete[]name;
path << "." << perm_name << " not found." << endl;
continue;
}
bool flag = targ_scope->replace_parameter(name, val);
bool flag = targ_scope->replace_parameter(perm_name, val);
if (! flag) {
cerr << val->get_line() << ": warning: parameter "
<< name << " not found in "
<< perm_name << " not found in "
<< targ_scope->name() << "." << endl;
}
delete[]name;
}
}
void Design::evaluate_parameters()
{
for (list<NetScope*>::const_iterator scope = root_scopes_.begin();
for (list<NetScope*>::const_iterator scope = root_scopes_.begin();
scope != root_scopes_.end(); scope++)
(*scope)->evaluate_parameters(this);
}
@@ -309,7 +310,7 @@ void NetScope::evaluate_parameters(Design*des)
// scanning code. Now the parameter expression can be fully
// evaluated, or it cannot be evaluated at all.
typedef map<string,param_expr_t>::iterator mparm_it_t;
typedef map<perm_string,param_expr_t>::iterator mparm_it_t;
for (mparm_it_t cur = parameters.begin()
; cur != parameters.end() ; cur ++) {
@@ -617,6 +618,15 @@ void Design::delete_process(NetProcTop*top)
/*
* $Log: net_design.cc,v $
* Revision 1.45 2004/10/04 01:10:54 steve
* Clean up spurious trailing white space.
*
* Revision 1.44 2004/02/20 06:22:56 steve
* parameter keys are per_strings.
*
* Revision 1.43 2004/02/18 17:11:56 steve
* Use perm_strings for named langiage items.
*
* Revision 1.42 2003/11/10 20:59:03 steve
* Design::get_flag returns const char* instead of string.
*
+17 -8
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_event.cc,v 1.23 2003/04/22 04:48:29 steve Exp $"
#ident "$Id: net_event.cc,v 1.26 2004/10/04 01:10:54 steve Exp $"
#endif
# include "config.h"
@@ -27,7 +27,7 @@
/*
* NOTE: The name_ is perm-allocated by the caller.
*/
NetEvent::NetEvent(const char*n)
NetEvent::NetEvent(perm_string n)
: name_(n)
{
scope_ = 0;
@@ -51,7 +51,7 @@ NetEvent::~NetEvent()
/* name_ is lex_strings. */
}
const char* NetEvent::name() const
perm_string NetEvent::name() const
{
return name_;
}
@@ -59,7 +59,7 @@ const char* NetEvent::name() const
string NetEvent::full_name() const
{
assert(scope_);
return scope_->name() + "." + name_;
return scope_->name() + "." + string(name_);
}
const NetScope* NetEvent::scope() const
@@ -201,7 +201,7 @@ NexusSet* NetEvent::nex_async_()
if (trig_ != 0)
return 0;
NexusSet*tmp = new NexusSet;
for (NetEvProbe*cur = probes_ ; cur != 0 ; cur = cur->enext_) {
if (cur->edge() != NetEvProbe::ANYEDGE) {
@@ -245,13 +245,13 @@ const NetEvent* NetEvTrig::event() const
return event_;
}
NetEvProbe::NetEvProbe(NetScope*s, const string&n, NetEvent*tgt,
NetEvProbe::NetEvProbe(NetScope*s, perm_string n, NetEvent*tgt,
edge_t t, unsigned p)
: NetNode(s, lex_strings.add(n.c_str()), p), event_(tgt), edge_(t)
: NetNode(s, n, p), event_(tgt), edge_(t)
{
for (unsigned idx = 0 ; idx < p ; idx += 1) {
pin(idx).set_dir(Link::INPUT);
pin(idx).set_name("P", idx);
pin(idx).set_name(perm_string::literal("P"), idx);
}
enext_ = event_->probes_;
@@ -449,6 +449,15 @@ NetProc* NetEvWait::statement()
/*
* $Log: net_event.cc,v $
* Revision 1.26 2004/10/04 01:10:54 steve
* Clean up spurious trailing white space.
*
* Revision 1.25 2004/02/19 06:57:10 steve
* Memory and Event names use perm_string.
*
* Revision 1.24 2004/02/18 17:11:56 steve
* Use perm_strings for named langiage items.
*
* Revision 1.23 2003/04/22 04:48:29 steve
* Support event names as expressions elements.
*
+11 -5
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: net_expr.cc,v 1.21 2003/08/28 04:11:19 steve Exp $"
#ident "$Id: net_expr.cc,v 1.23 2004/10/04 01:10:54 steve Exp $"
#endif
# include "config.h"
@@ -32,7 +32,7 @@ NetExpr::TYPE NetExpr::expr_type() const
/*
* Create an add/sub node from the two operands. Make a best guess of
* the
* the
*/
NetEBAdd::NetEBAdd(char op, NetExpr*l, NetExpr*r)
: NetEBinary(op, l, r)
@@ -377,7 +377,7 @@ NetExpr::TYPE NetECReal::expr_type() const
return ET_REAL;
}
NetECRealParam::NetECRealParam(NetScope*s, const char*n, const verireal&v)
NetECRealParam::NetECRealParam(NetScope*s, perm_string n, const verireal&v)
: NetECReal(v), scope_(s), name_(n)
{
}
@@ -386,7 +386,7 @@ NetECRealParam::~NetECRealParam()
{
}
const char* NetECRealParam::name() const
perm_string NetECRealParam::name() const
{
return name_;
}
@@ -402,7 +402,7 @@ NetEParam::NetEParam()
{
}
NetEParam::NetEParam(Design*d, NetScope*s, const hname_t&n)
NetEParam::NetEParam(Design*d, NetScope*s, perm_string n)
: des_(d), scope_(s), name_(n)
{
}
@@ -516,6 +516,12 @@ NetExpr::TYPE NetESFunc::expr_type() const
/*
* $Log: net_expr.cc,v $
* Revision 1.23 2004/10/04 01:10:54 steve
* Clean up spurious trailing white space.
*
* Revision 1.22 2004/02/20 06:22:56 steve
* parameter keys are per_strings.
*
* Revision 1.21 2003/08/28 04:11:19 steve
* Spelling patch.
*
+11 -8
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2000 Stephen Williams (steve@picturel.com)
* Copyright (c) 2000-2004 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
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: net_force.cc,v 1.11 2003/03/06 00:28:41 steve Exp $"
#ident "$Id: net_force.cc,v 1.12 2004/02/18 17:11:56 steve Exp $"
#endif
# include "config.h"
@@ -45,13 +45,13 @@
* output pins to connect to the netlist? But that would cause the
* link ring to grow, and that is not quite correct either. Hmm...
*/
NetCAssign::NetCAssign(NetScope*s, const string&n, NetNet*l)
: NetNode(s, lex_strings.add(n.c_str()), l->pin_count()), lval_(l)
NetCAssign::NetCAssign(NetScope*s, perm_string n, NetNet*l)
: NetNode(s, n, l->pin_count()), lval_(l)
{
lval_->incr_eref();
for (unsigned idx = 0 ; idx < pin_count() ; idx += 1) {
pin(idx).set_dir(Link::INPUT);
pin(idx).set_name("I", idx);
pin(idx).set_name(perm_string::literal("I"), idx);
}
}
@@ -87,14 +87,14 @@ const NetNet*NetDeassign::lval() const
return lval_;
}
NetForce::NetForce(NetScope*s, const string&n, NetNet*l)
: NetNode(s, lex_strings.add(n.c_str()), l->pin_count()), lval_(l)
NetForce::NetForce(NetScope*s, perm_string n, NetNet*l)
: NetNode(s, n, l->pin_count()), lval_(l)
{
lval_->incr_eref();
for (unsigned idx = 0 ; idx < pin_count() ; idx += 1) {
pin(idx).set_dir(Link::INPUT);
pin(idx).set_name("I", idx);
pin(idx).set_name(perm_string::literal("I"), idx);
}
}
@@ -137,6 +137,9 @@ const NetNet*NetRelease::lval() const
/*
* $Log: net_force.cc,v $
* Revision 1.12 2004/02/18 17:11:56 steve
* Use perm_strings for named langiage items.
*
* Revision 1.11 2003/03/06 00:28:41 steve
* All NetObj objects have lex_string base names.
*
+34 -9
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2002 Stephen Williams (steve@icarus.com)
* Copyright (c) 2002-2004 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: net_func.cc,v 1.4 2003/03/06 00:28:41 steve Exp $"
#ident "$Id: net_func.cc,v 1.6 2004/05/31 23:34:37 steve Exp $"
#endif
# include "config.h"
@@ -28,15 +28,17 @@
static unsigned count_def_pins(const NetFuncDef*def)
{
unsigned sum = 0;
assert(def->return_sig());
unsigned sum = def->return_sig()->pin_count();
for (unsigned idx = 0 ; idx < def->port_count() ; idx += 1)
sum += def->port(idx)->pin_count();
return sum;
}
NetUserFunc::NetUserFunc(NetScope*s, const char*n, NetScope*d)
: NetNode(s, lex_strings.add(n), count_def_pins(d->func_def())),
NetUserFunc::NetUserFunc(NetScope*s, perm_string n, NetScope*d)
: NetNode(s, n, count_def_pins(d->func_def())),
def_(d)
{
NetFuncDef*def = def_->func_def();
@@ -50,7 +52,7 @@ NetUserFunc::NetUserFunc(NetScope*s, const char*n, NetScope*d)
unsigned pin_base = port_wid;
for (unsigned idx = 1 ; idx < port_count() ; idx += 1) {
const NetNet*port_sig = def->port(idx);
const NetNet*port_sig = def->port(idx-1);
unsigned bits = port_width(idx);
for (unsigned bit = 0; bit < bits; bit += 1) {
pin(pin_base+bit).set_dir(Link::INPUT);
@@ -69,13 +71,21 @@ NetUserFunc::~NetUserFunc()
unsigned NetUserFunc::port_count() const
{
return def_->func_def()->port_count();
return def_->func_def()->port_count() + 1;
}
unsigned NetUserFunc::port_width(unsigned port) const
{
NetFuncDef*def = def_->func_def();
/* Port 0 is the return port. */
if (port == 0) {
const NetNet*sig = def->return_sig();
assert(sig);
return sig->pin_count();
}
port -= 1;
assert(port < def->port_count());
const NetNet*port_sig = def->port(port);
@@ -88,6 +98,13 @@ Link& NetUserFunc::port_pin(unsigned port, unsigned idx)
unsigned pin_base = 0;
const NetNet*port_sig;
if (port == 0)
return pin(idx);
port_sig = def->return_sig();
pin_base += port_sig->pin_count();
port -= 1;
assert(port < def->port_count());
for (unsigned port_idx = 0 ; port_idx < port ; port_idx += 1) {
@@ -133,10 +150,10 @@ bool PECallFunction::check_call_matches_definition_(Design*des, NetScope*dscope)
return false;
}
if ((parms_count+1) != dscope->func_def()->port_count()) {
if (parms_count != dscope->func_def()->port_count()) {
cerr << get_line() << ": error: Function " << dscope->name()
<< " expects " << (dscope->func_def()->port_count()-1)
<< " parameters, you passed " << parms_count << "."
<< " arguments, you passed " << parms_count << "."
<< endl;
des->errors += 1;
return false;
@@ -147,6 +164,14 @@ bool PECallFunction::check_call_matches_definition_(Design*des, NetScope*dscope)
/*
* $Log: net_func.cc,v $
* Revision 1.6 2004/05/31 23:34:37 steve
* Rewire/generalize parsing an elaboration of
* function return values to allow for better
* speed and more type support.
*
* Revision 1.5 2004/02/18 17:11:56 steve
* Use perm_strings for named langiage items.
*
* Revision 1.4 2003/03/06 00:28:41 steve
* All NetObj objects have lex_string base names.
*

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