Compare commits

...
626 Commits
Author SHA1 Message Date
Martin Whitaker 4818db887e Fix for LXT/LXT2 output using MinGW.
When using MinGW, routines registered via atexit() inside a
DLL are only called when the DLL is detached. If not detached
manually, DLLs are automatically detached *after* all remaining
open files are closed. This meant that by the time the LXT or
LXT2 close_dumpfile routine was called, the dump file handle
was no longer valid, so any remaining output was lost. This
patch fixes the problem by manually detaching the VPI modules.
2010-02-08 21:07:45 -08:00
Stephen Williams fad5e362ce Add yet more key characters to the gperf command.
The last patch to add key charasters apparently wasn't enough
for gperf 2.7.
2010-02-05 23:09:39 -08:00
Cary R 09a7c63692 Fix autoconf.sh gperf key flags
When I added the SV/Verilog-AMS keywords I forgot to update the
gperf keys in autoconf.sh. This patch makes them match the Makefile.
2010-02-05 22:35:08 -08:00
Stephen Williams 8d65d0735a Fix broken $() substitution in command files. 2010-02-04 16:07:27 -08:00
Cary R b1dc84ccd1 Fix release of variables.
This patch fixes the release of varaibles to work correctly.
2010-02-01 11:51:51 -08:00
Cary R fefc195540 Fix MinGW compile warnings.
This patch fixes a few compile warnings found with the latest
MinGW compiler.
2010-02-01 11:45:32 -08:00
Cary R 7866e92761 Fix an obscure memory leak and fix formatting.
This patch fixes an obscure memory leak and make the formatting
of these two routines match the rest of the code in the file.
2010-01-23 09:44:13 -08:00
Cary R 634d47bfe8 Add all the Verilog-AMS 2.3.1 keywords.
Like I did for SystemVerilog the other day this patch adds all the
Verilog-AMS 2.3.1 keywords. This necessitated adding one my byte
to the gperf -k argument (byte 9) to make the laplace_?? tokens
have a unique hash.
2010-01-23 09:40:56 -08:00
Cary R 511a274b41 Add all the SystemVerilog (1800-2005) keywords.
This patch adds the SystemVerilog keywords to Icarus. This allows
use to easily verify that out plain Verilog does not contain any
SystemVerilog keywords. The keywords are not parsed in any way.
When parsing a Verilog file using -gsystem-verilog any identifier
that is a keyword will cause a parse error. It is the users
responsibility to figure out the problem since bison does not
give nice error message when it finds a keyword instead of an
identifier.
2010-01-23 09:35:07 -08:00
Martin Whitaker 14b2037ce4 Fix for pr2922063.
When handling the $signed/$unsigned system functions, the compiler
was applying the new signed/unsigned property to the NetExpr object
representing the input argument. This caused the input argument to
be evaluated incorrectly. This patch fixes this by applying the new
property to the NetExpr object created to pad the result to the
required size.

In testing this fix, it was also discovered that the width of the
input argument expression was not being calculated correctly. This
patch also fixes this issue.
2010-01-23 09:29:40 -08:00
Nick Gasson b855b0368d Fix build with gcc-4.5
New version of GCC does not like the X::X() construct.
2010-01-23 09:24:42 -08:00
Martin Whitaker f95593716f Fix for pr2924354.
Creation of implicit nets requires knowledge of whether an identifier
has been declared before it is used. Currently implicit nets are
created during elaboration, but by this stage the order of declaration
and use is not known. This patch moves the creation of implicit nets
into the parser stage.
2010-01-23 09:10:00 -08:00
Stephen Williams 9fbb12d9cf Make sure all vvp_vector8_t::val_ bytes are initialized
Often the val_ array is treated as a word (for speed) so make sure
all the bytes of val_ are initialized, even if not used.
2010-01-12 14:45:57 -08:00
Martin Whitaker b4f070e60b Rework of lexical scope handling in parser.
This patch modifies the parser to use a single stack to track lexical
scopes, rather than starting a new stack for each generate construct.
2010-01-12 10:41:43 -08:00
Cary R 6eb5f593f0 realloc() to the correct string.
Someone had mistyped the destination of the realloc. It should
have been the original string not the input buffer.
2010-01-12 10:34:49 -08:00
Martin Whitaker d497b1a694 Fix for pr2929913.
After changing an array word, vvp propagates the change to every port
attached to the array. The code did not properly handle the case of
an array port declared in an automatic scope with an associated array
declared in a static scope.
2010-01-12 10:25:09 -08:00
Cary R 5a0363ebd3 Fix some constant bit/part select bugs and add warnings.
This patch fixes a few bugs in constant bit/part selects and
adds optional warnings for out of bound or undefined selects.
2010-01-12 10:19:35 -08:00
Stephen Williams d0b1936fb5 Optimize handling of invert gates / Tweak vvp_vector8_t performance
The process of inverting and copying can be collapsed into a single
operation that should run a little faster. Also, inverting readily
vectorizes itself. I've also possibly reduced useless vvp_not_fun
iterations.

Also, include some minor tweaks to the vvp_vector8_t handling of
vector copies. This is more to clean up code, although it should
slightly improve performance as well.
2010-01-11 11:42:25 -08:00
Cary R 85e0f8a328 Fix major error in lxt2 info allocation.
The zero element was already returned so it can not be reused a
second time. This was crashing when things went off the end of
the list since the do all functor was off by one.
2010-01-10 16:24:47 -08:00
Stephen Williams 76cc024f67 Optimize the per-signal vcd_info structure
In a typical debug simulation run, a user tracing all the signals
in the simulation may wind up creating millions of these. Rework
the vcd_info structure to be more compact and possibly faster to
scan.
2010-01-10 11:41:51 -08:00
Stephen Williams 94d75e0170 Add missing pthread.h header file. 2010-01-09 16:29:24 -08:00
Stephen Williams 3e7d191abb Add missing header includes. 2010-01-09 13:45:17 -08:00
Stephen Williams ffeeeaf0af Merge branch 'vcd-thread' 2010-01-09 10:39:12 -08:00
Stephen Williams 2638cd9f6e Fix build --with-valgrind broken by scope thread rework.
The scope thread rework broek --with-valgrind builds due to the
different handling of the list of threads. Rework valgrind enabled
handling of the thread set within a scope.
2010-01-09 10:38:24 -08:00
Stephen Williams 7fc6b02e96 Batch vcd work item creation
Rather then lock/unlock the work queue ring for every item, save
tons of pthread lock manipulation by allocating to the producer
in batches. Over the long run, this doesn't change the CPU balance
or hold up either thread, but it eliminates almost 3/4 of the
lock/unlock episodes.
2010-01-09 10:08:16 -08:00
Stephen Williams 76ebde4cd2 Blend time stamp into other work items.
The time change is usually a trivial operation, so instead carry
a timestamp on all the work items and let the work thread decide
on its own when to do a SET_TIME operation. This reduces some
pthread overhead and thus gets us some better performance.
2010-01-08 21:46:32 -08:00
Stephen Williams 06270cdd2b Basic work queue thread for lxt2 output. 2010-01-08 20:20:26 -08:00
Picture Elements Inc a919ee385d Merge branch 'master' of ssh://[email protected]/home/u/icarus/steve/git/verilog 2010-01-06 21:38:56 -08:00
Stephen Williams 5533252cc1 Add generic single-step-display for vvp_gen_event_s objects.
This gives a little bit more specificity to the event step
display.
2010-01-06 21:40:26 -08:00
Picture Elements Inc 5c0094e8fd Fix typeinfo build error. 2010-01-06 21:38:45 -08:00
Stephen Williams dda197e39b Rework the scope thread list to use a std::set
The scope contains the threads running within. The rework of this
patch allows all threads to know their scope, and cleans up the
handling of threads listed in the scope.
2010-01-06 18:43:53 -08:00
Stephen Williams 3ddb421fbf Add some single-step debugging
Work out the basis for single-stepping events in the scheduler,
and fill in some basic single-step results.
2010-01-06 16:08:20 -08:00
Cary R c74ca4a502 If you have C++ .o files you need to link with g++ 2010-01-06 13:50:44 -08:00
Cary R 3dcaf6253b Use CXXFLAGS when compiling C++ programs.
We already have this flag so we may as well us it in the vpi
directory to compile C++ programs.
2010-01-06 13:50:37 -08:00
Cary R 458258d554 A signal select is signed if the select not the signal is signed.
The padding for a signal select was using the signal to determine
if the padding should be singed or not. In reality this should be
unsigned padding unless the select was enclosed in a $signed().
2010-01-06 13:47:24 -08:00
Cary R ea4bae7c33 vpi_get_vlog_info should return the version information.
This patch fixes vpi_get_vlog_info to return the VERSION.
2010-01-06 13:45:07 -08:00
Stephen Williams 53ec59a97f Rework vcd id-mapping for scalability
Huge designs have huge sets of unique nexus ids. Use more efficient
algorithms to map them and detect aliases.
2010-01-06 10:46:39 -08:00
Cary R 3cef85b06b Add +timescale to the command file.
This patch adds a +timescale command to the command file
syntax that can be used to set the default time scale of
the simulation.
2009-12-30 08:35:29 -08:00
Stephen Williams d2dd0daa3c Fix references to version_base.h in Makefiles. 2009-12-28 09:49:35 -08:00
Cary R ebac088511 A constant real number is not unsized.
We can have unsized bit values, but reals always have a size.
2009-12-28 09:28:29 -08:00
Cary R 0f0cadd0eb Add suffix support for windows (both MinGW and Cygwin).
dlltool which is used by both MinGW and Cygwin to create dynamic
libraries must have the name of the executable it creates the
library/information from exactly match the installed executable
name. If we have a suffix then it must be used. This patch adds
that to the build process for vvp since it can be installed with
a suffix. It also modifies the check routines since you must run
vvp with a suffix if the library it links to was built for a
suffixed executable.
2009-12-24 20:55:26 -05:00
Cary R a1e2bfc93c Having lround() does not mean llround() is available.
We need to check for both lround() and llround() for at
least Cygwin.
2009-12-24 20:47:19 -05:00
Martin Whitaker b416176c4d Fix for pr2913404.
In combination with the patch to make all operations on thread words
operate on 64-bit values, this patch ensures casts between real values
and large vector values work correctly.
2009-12-21 09:59:12 -08:00
Martin Whitaker 13cad6f268 Make vvp thread word storage consistently 64 bits.
The vvp thread word storage had previously been changed to always store
64-bit values, but some instructions still only operate on native long
values. This patch ensures all instructions that modify thread words
support 64-bit values.
2009-12-21 09:56:22 -08:00
Cary R f6d1a891a1 Use the correct line information in crop_to_width()
This was using its own information instead of the input nets information.
2009-12-18 14:00:43 -08:00
Cary R 5ff8aa701a Reuse the number of input information.
This was already assigned to a variable so lets use that instead of
geting it again.
2009-12-18 14:00:34 -08:00
Cary R 3ed6c0cfa4 Properly extend/crop a user function argument in a continuous assignment.
When passing an argument to a user function in a continuous assignment
we need to sign extend the value if it is signed and too short. We need
to crop an argument if it is too long.
2009-12-18 13:59:15 -08:00
Cary R b3d828885c Function arg. expressions need to use the expr. width and arg. width.
When evaluating a function argument expression we need to use either
the expression width or the argument width which ever is larger. This
matches the way normal assignments work. We then only take the bits
needed at the end.
2009-12-18 13:55:02 -08:00
Cary R 260828a095 A ternary can be signed.
If the two branches of a ternary are signed then the result will
also be signed.
2009-12-18 13:43:30 -08:00
Nick Gasson 47d3b3365b VHDL: fix spurious resize seen in pr2911213
Another case when ivl_scope_sig list was used instead of
ivl_scope_param.
2009-12-18 13:38:12 -08:00
Cary R 5fad844c30 Add support for a suffix to MinGW.
This patch adds support for a suffix in the relative path for the
MinGW compile of iverilog and vvp.
2009-12-18 13:28:46 -08:00
Cary R 8144283b0d Fix out of bounds select warning text in man page. 2009-12-14 12:09:45 -08:00
Cary R a228d53cc2 Fixe .cast documentation. 2009-12-14 12:08:25 -08:00
Nick Gasson 9c568d8f47 VHDL: ensure with-select statement choices completely cover input space
Newer versions of GHDL seem to be stricter when checking this than
older versions. ModelSim still accepts an incomplete with-select,
however.

This patch makes the output 'U' if none of the conditions match.
2009-12-14 12:01:27 -08:00
Cary R 1a25b3deda Add CFLAGS to vvp/Makefile.in
We do have one C program in the vvp directory so add CFLAGS to
the Makefile. This patch also modifies the two local programs
tables and version to use -Wall.
2009-12-11 21:54:24 -08:00
Nick Gasson a9c85cf5b6 VHDL: emit function parameters in correct order
The function draw_scope was extracting the input/output parameters
just by looking at the (unordered) list of signals in the function
scope rather than using the ivl_scope_ports list.
2009-12-11 21:50:53 -08:00
Cary R 6ae1f64c3c Add some casts in libveriuser to remove warnings.
The Cygwin compiler is a bit picky. This patch adds some casts
to remove compilation warnings. In the past I have had warnings
off because of problems with the STL, but for C directories
like this it makes sense to enable the warnings. It also does
not recognize that an assert(0) or assert(false) ends a routine
so it complains about no return at end of function or variables
not being defined.
2009-12-11 21:48:01 -08:00
Cary R 3f12a401eb Add some casts in tgt-vhdl to remove warnings.
The Cygwin compiler is a bit picky. This patch adds some casts
to remove compilation warnings. In the past I have had warnings
off because of problems with the STL, but we may as well get
rid of the warnings we can. It also does not recognize that an
assert(0) or assert(false) ends a routine so it complains about
no return at end of function or variables not being defined.
2009-12-11 21:46:49 -08:00
Cary R f31a4e6d20 Add some casts in vpi to remove warnings.
The Cygwin compiler is a bit picky. This patch adds some casts
to remove compilation warnings. In the past I have had warnings
off because of problems with the STL, but for C directories
like this it makes sense to enable the warnings. It also does
not recognize that an assert(0) or assert(false) ends a routine
so it complains about no return at end of function or variables
not being defined.
2009-12-11 21:44:53 -08:00
Cary R d6246cf041 Add some casts in vvp to remove warnings.
The Cygwin compiler is a bit picky. This patch adds some casts
to remove compilation warnings. In the past I have had warnings
off because of problems with the STL, but for this directory we
may as well squash as many warings as we can. It also does not
recognize that an assert(0) or assert(false) ends a routine so
it complains about no return at end of function or variables
not being defined.
2009-12-11 21:43:42 -08:00
Cary R 81d4cbc4bd Add some casts in main directory to remove warnings.
The Cygwin compiler is a bit picky. This patch adds some casts
to remove compilation warnings. In the past I have had warnings
off because of problems with the STL, but for this directory we
mas as well remove the warnings we can. It also does not
recognize that an assert(0) or assert(false) ends a routine so
it complains about no return at end of function or variables
not being defined.
2009-12-11 21:41:46 -08:00
Cary R 1f375ef16a Remove extra MinGW only varaible in t-dll.cc. 2009-12-11 21:40:05 -08:00
Cary R 05a3929b1a Remove version.exe with a -f to avoid a warning.
If version.exe does not exist and we don't have a -f then we
will get a warning.
2009-12-11 21:39:24 -08:00
Martin Whitaker e2be397aa8 Fix for pr2909414.
Currently the compiler only applies defparam statements that are
found in the initial root module hierarchy. This patch ensures that
defparam statements within scopes created by generate constructs or
instance arrays are also applied.
2009-12-11 21:30:42 -08:00
Stephen Williams 709f6e71a6 Include climits for HName.h portability. 2009-12-11 17:17:52 -08:00
Stephen Williams e560b99a69 Don't repeat nodangle for signals.
Deleting a signal does not cause a new signal to dangle, so don't
use the deletion of a signal as an excuse to iterate nodangle.
2009-12-11 17:17:24 -08:00
Stephen Williams 38cce38e04 Slightly improve performance of collapsing NetEvent objects
The NetEvent::find_similar_event method should limit its impact
on the netlist (and Nexus objects) by reducing the candidate event
list as it goes, instead of collecting data and testing later.
2009-12-11 17:03:05 -08:00
Stephen Williams 4622f304d5 Remove dead init values from NetNet and Link objects.
It turns out that although there was all kinds of code to manage
these members, there were no uses anywhere. It must have been a
legacy from a previous era. So remove the dead code so that it
doesn't confuse me again.
2009-12-11 13:44:29 -08:00
Stephen Williams 1985bc5821 More verbose detail for nodangle functor. 2009-12-11 13:00:55 -08:00
Stephen Williams 6225e2f405 Fix uninitialized counters.
The count_io method adds its count, so initialize the inout counts
to zero.
2009-12-11 11:25:07 -08:00
Stephen Williams 7403dab028 Optional debug aid of trapping SIGINT
Normally ifdef'ed out.
2009-12-11 08:01:49 -08:00
Stephen Williams 4cda5ae6e9 Clean up some optimizer formance around the fringes.
Remove some wasteful and excess scans of the Nexus of some links,
and remove dead code so we can see what we're doing. Also inline
some commonly used and trivial functions.
2009-12-11 07:56:27 -08:00
Stephen Williams 2ddbf35869 Merge branch 'master' of ssh://[email protected]/home/u/icarus/steve/git/verilog 2009-12-10 13:24:50 -08:00
Stephen Williams 7311047f80 Optimize code generator scope access / tweak ivl_net_const performance
Child scopes need to be accessed quickly, so use O(LogN) maps for
the children instead of O(N) lists.

Also, ivl_net_const_s objects exist in huge abundance for some kinds
of designs, so put some effort into reducing their memory footprint.
2009-12-10 13:24:27 -08:00
Stephen Williams 534207bb83 Optimized Nexus handling during code generation.
Once code generation starts, the Nexus structure no longer needs to
support fast insertion/connect operations. So have the code generator
lock down the Nexus structures and adjust the Link lists for optimal
access during readout.
2009-12-10 13:20:38 -08:00
Cary R 392ac1200c Remove unused MinGW variable.
There was an unused variable in driver/main.c under MinGW.
2009-12-09 22:05:06 -08:00
Stephen Williams f7aef3f966 Merge branch 'master' of ssh://[email protected]/home/u/icarus/steve/git/verilog 2009-12-09 18:20:19 -08:00
Stephen Williams 69f3219f49 Suppress redundant warning messages about input coerced to inout
A message for each signal name at a given source/line need only
have this message emitted once.
2009-12-09 17:17:52 -08:00
Stephen Williams 782c55f7b5 Restructure Nexus lists of Links to handle large net lists.
When netlists get very large, the Nexus::connect() method tickles
the O(N) performance and elaboration gets very slow. Rework the
connect method to be O(C), for a drastic performance boost for
large designs.
2009-12-09 15:49:52 -08:00
Stephen Williams 4db4a467ee Speed up the connect(Nexus*,Link&) function somewhat.
This simplifies and reorganizes this function in order to improve
the performance of this function by a constant factor. I think we
really need to improve this by an entire order (and not just a
simple factor) but this helps.
2009-12-09 08:22:18 -08:00
Stephen Williams 94fa8955e5 Minor code cleanup. 2009-12-09 07:37:02 -08:00
Cary R a85880a8bb Add debug_eval_tree code for the pow operator.
The power operator was missing eval_tree debug information.
This patch fixes that deficiency.
2009-12-08 21:24:59 -08:00
Cary R e9c653dfa3 For MinGW make driver/main.c always create a path with a back slash
The MinGW executable should be able to support a path with mixed
separators, but to make things consistent all the path in the main
driver program (driver/main.c) now always use a '\' or convert a
path to use '\' (e.g. getenv() returns a path with a '/').
2009-12-08 21:21:27 -08:00
Martin Whitaker c7b0aef414 Reduce memory use for simulations that run in zero time.
The fix for pr1830834 causes vvp to only delete a completed thread
when the simulation time next advances. If a procedural model is
being simulated which makes many task or function calls within a
single time step, this can lead to excessive memory use. This patch
modifies the behaviour so that thread deletion is only delayed if
that thread has caused a sync event to be placed in the event queue.
This should catch all cases where the thread private data can be
accessed after a thread has terminated.
2009-12-08 21:13:19 -08:00
Cary R eea816e423 Make the verinum pow operator work correctly.
The functionality of the integer power operator is specified in
1364-2005 on page 45-46 and specifically Table 5-6. This patch
fixes the verinum pow operator to work as specified in this
table. It also fixes an error in the == operator when both
operators are signed and only the left argument is negative.
2009-12-08 21:04:11 -08:00
Cary R 59ebd47ba6 Update wavealloca.h to fix MinGW compilation warning
This patch fixes a warning when compiling vpi/sys_lxt2.c under
MinGW regarding the definition of alloca().
2009-12-08 20:58:53 -08:00
Stephen Williams b1d9d1bda2 Dramatically improve NetScope child lookup.
In physical models, there are often very many child scopes in any
given scope. The lookup for child scope needs to be optimized.
2009-12-08 15:14:55 -08:00
Stephen Williams 26ab32ac3b Add explicit dependencies on generated header files.
These explicit dependencies are not normally needed (because they
are covered by automatic dependency generation) but when the "-jN"
flag is passed to gmake, they help gmake schedule parallel builds.
(cherry picked from commit 5479aaf721)
2009-12-07 16:29:37 -08:00
Stephen Williams a720b2309e More portable use of tail.
Apparently, tail +2 is not portable, but tail -n +2 should work.
(cherry picked from commit b85b2d8a26)
2009-12-07 16:28:41 -08:00
Cary R b6f7354cee Update lxt/lxt2 files to latest from GTKWave.
This patch updated the four file lxt_write.{c,h} and
lxt2_write.{c,h} to the latest ones from GTKWave. This
required adding the wavealloc.h include file and an
update to configure.in and vpi/vpi_config.h.in to add
checks/definitions for ALLOCA and FSEEKO.
2009-12-02 17:21:19 -08:00
Cary R dba2a6e434 Add support for spaces in many paths/files names
This patch adds support for spaces in the path to the temporary files.
Adds support for spaces in output files and in library paths.

A space in the installation path is only supported under MinGW
(windows) at this time.
2009-12-02 17:13:00 -08:00
Cary R f44c1cadde Convert a few sprintfs to snprintf
This patch converts a few sprintf statements to snprintf
to protect against buffer overflow.

It also converts a few sizeof calls from sizeof(x) to
sizeof x like other places in the code.
2009-12-02 17:08:34 -08:00
Cary R 849b241ffa Remove unneeded definitions in drivers/globals.h
There were a bunch of unneeded definitions in drivers/globals.h.
All of these were only used in main.c so do not need to be in a
header file.
2009-12-02 17:03:56 -08:00
Cary R 145133bdb0 Minor rework of how driver-vpi is supported.
Add driver-vpi to either SUBDIRS or NOTUSED depending on if we
are building for MinGW or not. This is more logical and allows
the clean and distclean targets to be simplified.
2009-12-02 17:01:44 -08:00
Stephen Williams 9bcc658e37 Detect and handle unpropagated ufunc input.
During startup it is possible for input port to not yet be
initialized even after some other input ports trigger the
function to be evaluated. Handle this case by substituting
a vector of 'bx for the uninitialized inputs. This will shake
out when the simulation gets going, and only matters for user
defined functions in continuous assignments.

While we're at it, have vec4_unfiltered_value return a reference
to reduce copying of vectors.
2009-11-29 09:59:51 -08:00
Stephen Williams 734124e653 Remove dead code in pointers.h. 2009-11-28 21:39:35 -08:00
Stephen Williams 2e60a181c0 Make all should build the iverilog-vpi.man file.
The "make install" target may not in general be able to build
the iverilog-vpi.man file, so make sure it it build by make all.
2009-11-28 20:32:29 -08:00
Cary R dd425e8945 Add basic support for spaces in the install path for MinGW.
This patch adds support for spaces in the install path on MinGW.
It does this by converting the Long version of the iverilog path
into a Short version that does not have spaces in it. If we don't
do this then we can not add support for other arguments with
spaces in the path or filename. It also modifies the driver-vpi
program to support spaces in the saved ivl path. This is done by
just enclosing the include and library path argument in double
quotes.

The issue on MinGW is that if you put the executable argument to
system in double quotes to escape embedded spaces then you can
not put the arguments in double quotes as well. If you convert
to a Short name then the spaces are removed and we can in the
future escape the arguments as needed.
2009-11-28 20:27:32 -08:00
Cary R 6909737bf2 Some more generic fixes for building in a remote directory
This patch fixes a few more issues related to building
in a remote directory. The start of the problem was
that the version file was not getting built correctly.
This necessitated using vpath instead of VPATH to only
allow the %.cc files. After that a few other places
needed to have $(srcdir) added.

The distclean target was also enhance so that when
building from a remote directory (srcdir != .) we
remove all the extra files and directories.
2009-11-28 20:14:34 -08:00
Cary R 8abe0d7d71 Make MinGW compile using a remote build directory.
This patch fixes a few MinGW specific issues that prevented it
from building in a remote directory.
2009-11-28 20:09:09 -08:00
Stephen Williams 342ec152bc Make version.exe so that subdirs can get access to it. 2009-11-28 20:01:58 -08:00
Stephen Williams ba58e57dc8 Merge branch 'master' of ssh://[email protected]/home/u/icarus/steve/git/verilog 2009-11-27 09:26:35 -08:00
Stephen Williams 966e29db3b Unify the version stamp in the version_*.h header files.
Try to put all the version stamps into common version_base.h
and version_stamp.h header files. All the source programs then
get their version from these header files.

Also handle the version stamps in the man pages by using the
version_*.h header file contents to edit the version strings
in the man page title bar markers.
2009-11-27 09:25:50 -08:00
Stephen Williams de1f17d429 Fix delays in continuous assignment to support 64bit delays.
Remove the 32bit restriction on a few cases of delays in continuous
assignment expressions.
2009-11-26 18:28:19 -08:00
Stephen Williams 1ada697e45 Fix signed/unsigned errors in %shiftl/x0 and %shiftr/x0
Fix these warnings once and for all. Just use only signed integers
for all the variables and arithmetic.
2009-11-26 09:43:35 -08:00
Stephen Williams c73925e775 Handle word aligned bit moves more efficiently
If the source and destination of a subvector to be moved in the
vvp_vector4_t::mov method is nicely word aligned, and the transfer
size is a full word, then we ar much better off handling that as
a special case. This makes the move faster, and also avoids some
shift overflow errors.
2009-11-26 09:34:45 -08:00
Stephen Williams f07577db11 Handle case that delay output is pending when new event arrives
If the delay has an event pending for the current time, then use
that as a reference for calculating the next delay. If that is not
done, then the delay calculated against the wrong reference might
result in zero, and bad results.
2009-11-23 18:27:14 -08:00
Stephen Williams 971179d617 Performance optimizations
For the %mov instruction, implement a vvp_vector4_t::mov method to
manipulate the thread vector directly.

For the %load/v instruction, rework the vec4_value() methods to
avoid creating vvp_vector4_t temporaries, and therefore reduce the
copy overhead.
2009-11-20 17:54:48 -08:00
Stephen Williams 0fc136fad9 Merge branch 'master' of ssh://[email protected]/home/u/icarus/steve/git/verilog
Conflicts:
	driver/iverilog.man
2009-11-20 14:42:21 -08:00
Cary R 74634864cf Fix some extra/invalid font switches in iverilog.man.
Cleanup some unneeded \fP statements and remove the invalid and
unneeded \fp statement. Slightly reword the __ICARUS__ definition.
2009-11-18 20:26:47 -08:00
Stephen Williams c90df71301 Document the iverilog -P command line flag. 2009-11-03 15:11:57 -08:00
Cary R c72ae1b3ea Add more non-breaking hyphens in the manual pages.
This has been started, but this patch adds a bunch more (all?) of
the non-breaking hyphens needed in the manual pages.
2009-11-03 14:36:32 -08:00
Martin Whitaker 9950704735 Fix vvp code generator bug for CA function calls with array word arguments.
If a function in a continuous assignment is passed an array word as
an argument, syntactically incorrect vvp code is generated. This is
because the code calls draw_net_input to generate the input labels
part way through writing out the .ufunc statement. If an input is
an array word, draw_net_input causes a .array/port statement to be
emitted, which gets written out in the middle of the .ufunc statement.
This patch fixes the problem by collecting the necessary input labels
prior to starting writing the .ufunc statement.
2009-11-01 11:06:33 -08:00
Stephen Williams 1b7a42ffcd Implement cbAtStartOfSimTime callback. 2009-11-01 09:26:09 -08:00
Cary R a5060b8adc Add a waring that timing check delayed signals will not be driven.
The $setuphold and $recrem timing checks can create delayed signals
that are needed to get a model to work correctly when negative timing
check values are used. Since we do not support timing checks and just
ignore them this can create simulation problems when a user tries to
use these delayed signals since they are not driven.

This patch adds a waring when the circuit is being compiled that these
delayed signals will not be driven. This will be needed until we get
time to add the real timing checks are mimic the delayed properties of
the timing check.
2009-10-31 20:50:43 -07:00
Cary R ae49197a14 Cleanup a few more issues found with cppcheck.
Minor fixes and code reorganization to remove a few more issues
that cppcheck is complaining about. It has a few false warnings
and some issues that need more investigation.
2009-10-31 20:42:43 -07:00
Stephen Williams 5fb89262df Fix the vpiObjTypeVal for signals to be scalar or vector.
Scalar signals have a preferred type of vpiScalarVal, but vectors
have a preferred type of vpiVectorVal. Use the signal width to
distinguish.
2009-10-29 11:53:31 -07:00
Stephen Williams 711365521d Fix vpi_control operation codes to be standard
Apparently, the vpi_user.h definitions for vpiStop et al were added
before they were standardized by 1364-2000, and never corrected.
Change the values to be standard. (Submitted by Matt Trostel.)

I also added some binary compatibility for existing .vpi modules
that were compiled with the older constant values.
2009-10-29 11:16:26 -07:00
Cary R cf2f99ec3d Cleanup Makefile clean targets.
This patch removes bin32 from the clean targets since it is no
longer user/created. It adds autom4te.cache to the distclean
target in the main directory. It removes the files in driver
that are not created (lexor.c parse.c, etc.). The *.cc.output
files are no longer created so removing them is not needed.
2009-10-29 10:48:04 -07:00
Cary R 83aa1363ea Add a warning message if an environment variable is not found.
Instead of silently skipping the substitution we now print a warning
message if an environment variable substitution is not found.
2009-10-29 10:46:25 -07:00
Cary R 4cb39f584d Add support for ${var} substitutions in the command file.
We still support $(var).
2009-10-29 10:46:16 -07:00
Cary R 9dc4c8cbe1 Fix memory.h include issues.
The local "memory.h" file is no longer used in V0.9 or development,
so it does not need to be included in vvp/codes.h. The VHDL target
does not use the system <memory.h> header file so there is no need
to have a define for it in the vhld_config.h.in file.
2009-10-26 11:09:02 -07:00
Martin Whitaker d0cb963994 Provide different modes for dependency list output.
This patch modifies the iverilog -M command line option to allow
the user to specify an optional output mode that controls which
files get added to the dependency list. This allows the user to
either get a list of all files that contribute to the design,
or a list of the include files, or a list of the module files.
2009-10-26 11:05:01 -07:00
Cary R 1f0857606a Add error message that only 32 bit immediate CA delays are supported.
The .delay (x,y,z) functor and the get_number_immediate() function
only supports 32 bit delay values. This patch adds an error message
if the user passes a larger, but valid value.
2009-10-23 11:00:56 -07:00
Jared Casper c167b3a01f Still more build system cleanup.
- Add missing dependency of configure on aclocal.m4.

- Remove config stamp files in make distclean (and fix another for
  loop in base make distclean that I missed)

- Add stamp files to .gitignore
2009-10-23 10:57:41 -07:00
Jared Casper 7ead2aa88b More build system tweaks, fixing pr2881797.
Use the time stamp file technique recommended by the autoconf manual
to prevent unneccesary rebuilds because of an unchanged config.h.
Uses the automake trick of generating the stamp files in the
_AC_AM_CONFIG_HEADER_HOOK macro instead of littering the source
directory with stamp-h.in files.

Add an extra ./config.status run after ./config.status --recheck
because with --recheck it doesn't actually try to remake the generated
files (and thus doesn't make the timestamp files).  Thus without the
extra run, each stamp-*-h target would need to independently run
./config.status to make sure it wasn't changed by the configuration
change.

An orthogonal fix of how config.status is called in subdirectories.
When in a subdirectory and config.status is called with
../config.status and $(srcdir) is a relative path, config.status gets
confused.  Fixed by replacing '../config.status --file=Makefile.in'
with 'cd ..; ./config.status --file=<dir>/Makefile.in'
2009-10-20 09:45:42 -07:00
Cary R c7d05eefb4 More valgrind cleanup (local nets).
This patch adds code to cleanup local nets and changes a few of
memory cleanup messages.
2009-10-20 09:38:55 -07:00
Jared Casper d098db0a06 Base Makefile improvements.
Instead of calling make in subdirectories using a sh for loop, use GNU
make's $(foreach ) to create a string of commands connected with &&.
This way an error in a subdirectory will stop the build, instead of
continuing on to the next subdirectory, which the old version does.

Also added rules to regenerate configure when configure.in changes,
and to run config.status --recheck when that happens.
2009-10-18 18:00:53 -07:00
Cary R dec524a151 More valgrind cleanup.
This patch adds code to cleanup system functions driving a
continuous assignment. It also modifies the user function
cleanup to not interfere with this. It also adds a count
of the nets and signals that were not cleaned up that is
pnly printed when running valgrind. They are not flagged
y valgrind since they are pool managed objects. There are
a few signals that need to be cleaned up and local nets
are missed so there are a lot of nets.
2009-10-16 20:03:26 -07:00
Cary R c54cd4b473 Update simulator version for V0.10. 2009-10-16 20:00:55 -07:00
Stephen Williams 9164b7719b Add driver for the HiZ of open nets.
Even open nets have a driver for HiZ. The BUFZ is needed as something
to hang .net objects. This is another step closer to not needing the
"create_constant_node" hack in vvp/words.cc.
2009-10-15 21:19:19 -07:00
Stephen Williams 8247d3ef45 The .alias for nets is no longer useful.
In the olden days, the .alias was necessary to create a net name
that is an alias to an existing net in the netlist. But now that
the .net no longer creates a node in the netlist, ALL .net objects
are aliases of a sort, so this (mis)feature gets in the way.
2009-10-14 21:40:15 -07:00
Cary R 02ca7fe7fc Clean up user function calls from thread space.
This patch adds cleanup code that cleans up the memory that is
allocated by the of_EXEC_UFUNC command. This knocks a few more
files off the valgrind list.
2009-10-13 21:38:47 -07:00
Cary R 8abf303753 Don't replace parameter overrides that did not evaluate.
Trying to replace a parameter override that did not evaluate
correctly can lead to a crash, so just skip the substitution.
2009-10-13 21:28:37 -07:00
Cary R bc60536eb9 $clog2() should return an integer value.
The constant $clog2() was returning a value that had an integer
width, but it did not have the sign bit set. This could result
in incorrect math expressions. This patch sets the sign bit for
the constant $clog2() result.
2009-10-13 21:23:37 -07:00
Cary R d9d8d4b093 In driver-vpi only look at the first CC word when checking compiler path.
In the MinGW version of iverilog-vpi (C version located in driver-vpi)
we must only look at the first word of the IVERILOG_VPI_CC definition.
A recent change to the configuration process made this equal to
"gcc -std=gnu99" which will not be found when looking for the
gcc executable. We nee to look for "<path>\\bin\\gcc.exe". This
patch modifies the driver to only use the first word when looking for
the compiler, but uses the full value when compiling.
2009-10-13 21:16:32 -07:00
Stephen Williams 33158355ba Add appropriate hysteresis to tranif input pins.
The tranif input pins are normally nothing special, but sometimes
they are fed back from the switch body. In this case, the control
needs to see the current *output* from the fed back port, in order
to get the results that people expect.
2009-10-13 19:01:02 -07:00
Stephen Williams 6b17dcc587 Get drive of pull-ups right.
The drive for a pullup comes from ivl_nexus_pt_drive1. Get this
wrong and a pullup turns into a HiZ.
2009-10-12 22:01:56 -07:00
Stephen Williams 65f8f3caa8 Merge branch 'master' of ssh://[email protected]/~steve-icarus/git/verilog 2009-10-11 16:51:45 -07:00
Stephen Williams 815e22908b Make control inputs to islands use .import records.
Control inputs (i.e. the control input to tranif switches)
are not driven in any way by the island, so use .import records
instead of .port records to bring them into the island. Properly
handle the now potentially different bindings within the island
and outside the island. This means the draw_net_input_x function
is a little more sophisticated, and the node data more complex.
2009-10-11 16:51:06 -07:00
Cary R ff39575dc0 We must have autoconf version 2.60 or later.
When AC_PROG_CC_C99 was added recently we created an implicit
requirement for autoconf version 2.60. This patch makes that
implicit requirement and explicit requirement.
2009-10-08 17:00:00 -07:00
Cary R 3303cc144f Fix obscure valgrind memory leak. 2009-10-08 16:55:36 -07:00
Cary R 39f243b18e Add a configure check to see if uint64_t and unsigned long are identical.
This is needed to get vvp to compile under MacOS 10.6 and possibly other
64 bit systems that define uint64_t as unsigned long long vs unsigned
long (both are 64 bits).
2009-10-08 11:50:05 -07:00
Stephen Williams 2229ad896b tranif control ports handle nil inputs
In certain special cases, it is possible for the tranif control input
to be nil. (probably only during startup.) Treat that case as HiZ.
2009-10-07 12:58:19 -07:00
Cary R 537ba93fe4 Format the --enable-suffix help correctly. 2009-10-06 20:43:29 -07:00
Stephen Williams abc4eb9d52 Do not cprop through ternaries if the selector is an l-value.
It turns out that it is possible for an otherwise constant net
mux to be non-constant if there is a force that can drive the
net. This can be detected as an l-value reference to an otherwise
constant selector.
2009-10-05 19:46:47 -07:00
Cary R 9ea6604439 Fix bug in vector8 operator=
operator= would try to overwrite it self under some circumstances.
This was found with valgrind and using -O0. It works with -O2.
2009-10-03 08:59:35 -07:00
Cary R 27f96bd6f3 Fix the last of the net rework memory leaks.
This patch fixes the last of the memory leaks introduced by the
net rework.
2009-10-03 08:54:44 -07:00
Cary R ed7e9f8be5 Check if the compiler supports C99 and better check for some math functions.
Add a configuration check that says we would like to use C99 if the
compiler supports it. Also change the lround(), nan(), fmin() and
fmax() checks to look in the default libraries as well as the math
library.

Update the iverilog-vpi sh script to correctly quote CC since it
may now have two words (gcc -std=gnu99).

Add a missing int for main in draw_tt.c.
2009-10-01 11:51:52 -07:00
Stephen Williams d64b1f0275 Unify some duplicated heap management.
Create the permaheap class to hold common code from the vvp_net_fun_t
and vvp_net_fil_t classes.
2009-09-30 22:10:35 -07:00
Stephen Williams 5a96b397e4 Elide local nets that have no drivers.
Local nets that have no (zero) drivers are dead weight. Since
they have no drivers, they are not being used anywhere. Since
they are local, they are not force-able.
2009-09-30 19:51:05 -07:00
Stephen Williams e076087320 Draw PULLUP constants with their own BUFZ.
This doesn't have any significant runtime consequence other then
to create a functor that is otherwise stable. But this does connect
to .net nodes more naturally, and gets me a step closer to banning
Cx<> labels as arguments to .net records.
2009-09-30 19:48:36 -07:00
Stephen Williams 92fe0e0fc7 vvp_net_fil_t objects are permallocated. 2009-09-29 21:17:08 -07:00
Stephen Williams 025f93e321 Attach generated nets to the right scopes.
Nets that are created after being put off for later processing to
allow the vvp_net to be created, need to be more carefully placed
in the correct scope.
2009-09-27 18:29:07 -07:00
Cary R 3259354d29 The concat object can get out of sequence so don't optimize a repeat.
Under some situation the optimized repeat expression can get out
of sync while it is being processed this causes the code to
reference freed memory. This happens when the repeat expression
is converted to an unsigned integer, but the repeat expression
is used in a different path. It was easier to just remove the
optimization then track down the convoluted call sequence that
was causing this and then figure out what needed to be fixed.
The repeat expression must be constant, so is likely not too
complicated so this optimization is very minor and should not
be missed.
2009-09-26 18:34:25 -07:00
Stephen Williams 996424a7be Merge branch 'master' of ssh://[email protected]/~steve-icarus/git/verilog 2009-09-26 10:02:31 -07:00
Stephen Williams a3be083893 Give constants a driver
This driver gives nets something to hang on to, and leads to
more sensible topology when multiple nets are driven by the
same constant.
2009-09-26 09:59:06 -07:00
Cary R 1c8a1bbf7f Clean up a couple of memory leaks in the new net rework code.
This patch fixes a couple of minor memory leaks in the new
net rework code.
2009-09-25 13:50:30 -07:00
Cary R a84faabdb0 A real wire needs an explicit initial value.
To keep valgrind happy we need to give real wires an explicit
initial value of 0.0.
2009-09-25 13:50:20 -07:00
Stephen Williams 91a16764e7 Merge branch 'master' of ssh://[email protected]/~steve-icarus/git/verilog 2009-09-24 19:09:27 -07:00
Stephen Williams 18d7a7f859 Release of nets needs to force propagation
When releasing a net, the release method must force that the
filter propagate the released value to the output. Use the
needs_init_ flag to do that force.
2009-09-24 18:57:15 -07:00
Cary R d7ef9718e7 Fix valgrind error in new net rework code.
This patch fixes a valgrind error and fixes some of the test suite
issues in the new net rework code.
2009-09-24 17:51:22 -07:00
Stephen Williams 8a3df7c4ff Fix build errors when configured --with-valgrind
The vpi_callback base class is parent of the filter object of nets,
and not the functor. The good news is the clear_all_callbacks method
can now be got at without casts.
2009-09-24 15:11:56 -07:00
Cary R b8b70f5ac7 Add ivl_signal_scope to ivl.def to get mingw and cygwin to compile. 2009-09-24 14:21:45 -07:00
Cary R 8d2913ac97 Remove unsigned/signed compile warning. 2009-09-24 12:05:28 -07:00
Stephen Williams b0d5a3b8a2 Merge branch 'vvp-net-out-rework' 2009-09-23 17:16:37 -07:00
Stephen Williams 753a55573f Prepare for snapshot 2009-09-23 16:51:00 -07:00
Stephen Williams d3d84dde6a Better portability for rpm install section. 2009-09-23 15:55:15 -07:00
Stephen Williams 0b2ce7a5ec Merge branch 'master' into vvp-net-out-rework 2009-09-22 21:47:10 -07:00
Stephen Williams b277a672f1 Fix the calculation of top pad in overlapped part select
If the part select is too wide in both the top and bottom ends,
this patch fixes the calculation of the top pad. The compiler
was generating too much pad if the select also extended below
the expression.
(cherry picked from commit 2c0b105de7)
2009-09-22 21:43:52 -07:00
Stephen Williams 2c0b105de7 Fix the calculation of top pad in overlapped part select
If the part select is too wide in both the top and bottom ends,
this patch fixes the calculation of the top pad. The compiler
was generating too much pad if the select also extended below
the expression.
2009-09-22 21:42:59 -07:00
Stephen Williams 6cc16711db Merge branch 'master' into vvp-net-out-rework 2009-09-22 17:48:33 -07:00
Cary R 98c39cfa24 Add support for .part/v.s
This patch adds support for .part/v.s. A variable part select with
a signed select expression in a continuous assign.
2009-09-22 17:31:37 -07:00
Cary R e1af002a32 Warn that a signed part select may not work for signals < 32 bits.
If a signed signal is driving a part select in a CA and the width
is less than 32 bits. the value will be zero extended and will
not work for negative values. This patch adds a warning that this
could happen. This will be fixed in development.
2009-09-22 17:26:35 -07:00
Cary R 09fa57742a Optimize a full L-value indexed part select, etc.
This patch adds an optimization when a constant indexed part
select covers the entire L-value. It also fixes a few issues
in the code generator related to part selects.
2009-09-22 17:23:26 -07:00
Cary R e54fd4df51 Add support for signed thread base index for &A<>
This patch adds support for getting a signed index for &A<> from
thread space. This mimics what was done for &PV<>.
2009-09-22 17:20:31 -07:00
Cary R c82baa2793 Only process the first 32 bits of the part select base.
When reading from thread space only read the first 32 bits
(sizeof int) for the part select base. This matches the other
parts of the PV_get_base() code.
2009-09-22 17:18:04 -07:00
Cary R 1851cba955 Warn that &A<> may have problems with a signed select from thread space.
Like the &PV<> code we should warn the user that a signed select
from thread space may not work correctly for &A<>. This will be fixed
in development.
2009-09-22 17:15:30 -07:00
Cary R 617897f3bf Add support to &PV<> for signed base values from thread space.
When calculating a value from thread space we need to tell &PV<>
if the base value is signed or not. This patch adds support for
that functionality.
2009-09-22 17:11:55 -07:00
Stephen Williams e983e75780 Elide nets that can't work.
In auto scopes, nets cannot work and probably are are artifact of
elaboration. So elide local nets in auto scopes.

Also, get net inputs from the inputs of nets. This is a step
towards eliminating the label on nets altogether.
2009-09-21 22:15:10 -07:00
Stephen Williams b75f02c889 Handle automatic real variables like automatic logic vectors. 2009-09-15 21:28:21 -07:00
Cary R 0b6bd343e8 Don't check the scope for array words.
We do not want to check an array word scope to see if the scope
was already included since a scope does not include array words.
They must be explicitly specified.
2009-09-15 20:26:57 -07:00
Stephen Williams 21b1f620ba Automatic variables cannot use wire filters.
Make vec4 variables use stub filter functions so that the filter
does not interfere with automatic values.
2009-09-15 17:10:59 -07:00
Stephen Williams 0a72df2025 Remove vvp_signal_value from the vvp_fun_signal hierarchy.
We no longer need to access values from the signal functor. Use
the filter (the wire part) everywhere to access signal values.
2009-09-13 18:30:13 -07:00
Stephen Williams 3d5d312786 Merge branch 'master' into vvp-net-out-rework
Conflicts:
	vvp/vpi_signal.cc
2009-09-13 12:31:17 -07:00
Cary R 4d57ede0e5 Warn that events can not be user task or function arguments.
This patch makes events passed as arguments to user tasks or functions
a compile time error with an appropriate error message.
2009-09-13 08:21:41 -07:00
Cary R 43f41572cb Fix 64 bit problem in vvp/vpi_signal.c
This is based on a suggested fix from Martin. It fixes the crash
for two tests in the test suite. As a bonus it is more efficient.
2009-09-13 08:18:11 -07:00
Cary R 6d5d06cae4 Squash some gcc 4.3.3 warnings.
This patch clears all the gcc 4.3.3 warning that can be fixed.
The remaining warning is dictated by older versions of the
1364 standard.
2009-09-13 08:15:59 -07:00
Cary R 5a11a8a9c2 Revert one change from previous patch.
I was mistaken in changing the cast in the comparison.
2009-09-13 08:04:04 -07:00
Cary R 1b300cb2f6 Fix another 64 bit problem in a part select.
This patch fixes a problem in the .part/v select when the index is
undefined. The default value needs to be INT_MIN, so when the long
is cast to an int the value is in range.
2009-09-13 08:03:58 -07:00
Cary R 27f032760e Fix .part/v to only use a 32 bit value.
To get better functionality in V0.9 and development until we
add a select that is sign aware to .part/v this patch uses
a 32 bit integer (int) for the select value. This allows a
normal Verilog integer to produce the correct results. A
warning for smaller signed index vectors is planned, but it
needs more input.
2009-09-13 08:03:48 -07:00
Stephen Williams 72ab7b6515 Handle initialization propagation of wires.
The first input through a net needs to be propagated, since this
is used as an initialization for the net. This patch also cleans
up wires to not need the width_ member, instead inferring the
width from the saved bit value.
2009-09-12 18:46:48 -07:00
Stephen Williams 03f2432f6e Fixup real value output from user defined functions
User defined functions need to check the output from the function,
which is an unfiltered signal.
2009-09-12 12:25:18 -07:00
Stephen Williams a1295db6bf release_pv methods need t account for net_flag.
Whether and what to propagate after a release of a part needs to
match the behavior of the full-vector release. Nets need to restore
their driver, and regs need to hold their forced value.
2009-09-12 09:22:20 -07:00
Stephen Williams caab6b3834 Implement force methods for vec8 nets. 2009-09-11 21:33:24 -07:00
Stephen Williams 1a21b5843f Value change on part select needs to track the filter, not the functor. 2009-09-11 19:49:23 -07:00
Stephen Williams f0f35376cd Implement recv_vec4_pv for event functors. 2009-09-11 19:42:30 -07:00
Stephen Williams 88668e3df5 Run vpi callbacks for force/release. 2009-09-10 20:46:33 -07:00
Stephen Williams 4522e88c27 Get the initial value of a vec4 net correct. 2009-09-10 18:51:19 -07:00
Stephen Williams 14d8c6214f More fixes for real nets and arrays.
Continue to unify real net handling with vector handling.
2009-09-09 21:42:40 -07:00
Stephen Williams a58c02899b Handle filtered part selects.
filters need to be able to cope with parts of vectors moving through
the net. It makes the most sense to handle every filter as a part-
selected filter.
2009-09-08 21:42:50 -07:00
Cary R 4b50473939 Fix &A<> to support an undefined word index.
This patch adds support to &A<> for an undefined word index.
It mostly matches what was done for &PV<>.
2009-09-08 16:04:06 -07:00
Cary R 1b0dd8c8e5 Add support for 'bx from a signal to &PV<>
&PV<> was just using vpi_get_value() when a signal was driving
the select. This incorrectly returned 0 for 'bx or 'bz. This
patch adds a check for an undefined value and returns INT_MIN
for this case.
2009-09-08 16:01:14 -07:00
Cary R dff6a1ebff Add file/line information to named events and better expr. error.
This patch adds file and line number information to named events.
It also modifies the draw_eval_expr_wid() routine to fail with
an appropriate message for named events. This checking needs to
be pushed into the elaboration stage, but this will give a better
message than we had before.
2009-09-08 15:58:24 -07:00
Martin Whitaker fc49420cb5 Add user control over implicit sensitivity list warnings.
This patch adds two new warning classes that can be enabled or
disabled via the -W command line option. The first controls
whether a warning is generated if a part select within an
always @* statement causes the entire vector to be added to
the implicit sensitivity list. The second controls whether a
warning is generated if a word select within an always @*
statement causes the entire array to be added to the implicit
sensitivity list. The first class is not automatically enabled
by -Wall, the second class is.
2009-09-08 15:44:45 -07:00
Stephen Williams 9c516a9d53 Changes to real nets generate callbacks.
Generate the missed callbacks when real values change. In the
process, unify the use of the filterter_mask_ method for scalar
types.
2009-09-07 21:22:00 -07:00
Stephen Williams 0d70adfc47 The .alias node degenerates to .net nodes.
Now that .net nodes are references to filters into vvp_net_t objects
and are no longer functors on their own, the .alias node becomes
exactly the same as a .net itself.
2009-09-07 20:44:47 -07:00
Stephen Williams cbf3793ee6 Net support for arrays handles 2-pass resolution. 2009-09-07 18:59:21 -07:00
Stephen Williams 9b19e3bcf2 Implement support for net arrays. 2009-09-06 21:35:08 -07:00
Stephen Williams 0018cb38b0 Merge branch 'master' into vvp-net-out-rework
Conflicts:
	vvp/schedule.cc
	vvp/schedule.h
2009-09-05 10:19:20 -07:00
Stephen Williams 5be1b25726 Release filter accounts for net vs variable.
When releasing a net, the release needs to propagate the driven
value. When releasing a variable, the driven value must be set
to the previously forced value.
2009-09-04 21:37:31 -07:00
Stephen Williams 3de02ede8b Remove dead code release methods.
The release methods attached to signal functors are dead code.
2009-09-03 21:24:52 -07:00
Stephen Williams 1ea0d40208 Remove "net" flag to release methods.
This flag is redundant. The behavior should be handled in other ways.
2009-09-03 21:15:35 -07:00
Nick Gasson face1a1d15 Allow labelled begin blocks to contain processes in VHDL target
This is a simple fix for a crash that occured when a process
was inside a labelled begin inside a generate statement.
2009-09-03 17:13:41 -07:00
Nick Gasson 388c9c6747 Handle generate scopes with signals in VHDL target
This uniques the name of each copy of a signal and adds
it to the containing VHDL entity.
2009-09-03 17:13:33 -07:00
Nick Gasson bc7ec04cab Translate simple generate loops to VHDL
This handles generate loops and genvars with no local variables
2009-09-03 17:13:27 -07:00
Cary R 5f08f40cad Remove old configure files in vvp directory. 2009-09-03 17:10:36 -07:00
Cary R 9a4cd1af32 Add support for non-blocking assignment to real arrays.
This patch adds support for the various types of non-blocking
assignments to real arrays.
2009-09-03 17:07:17 -07:00
Cary R 9d765820bf Support negative index for %assign/av opcodes.
If the array index is negative these opcodes need to just return.
2009-09-03 17:05:17 -07:00
Cary R bd5593df23 ivl_lpm_selects() is obsolete for IVL_LPM_CONCAT
IVL_LPM_CONCAT should use ivl_lpm_size() instead of ivl_lpm_selects.
This is a requirement in development so add a warning and make using
ivl_lpmp_selects() with a IVL_LPM_CONCAT fatal.
2009-09-03 17:02:58 -07:00
Cary R 4cd790a2d2 Convert IVL_LPM_CONCAT to use ivl_lpm_size() instead of ivl_lpm_selects()
It was documented that a IVL_LPM_CONCAT would use _size() instead
of _selects(). This patch adds the functionality to _size() and
converts all the Icarus provided code generators to use _size().
_select() will be kept for compatibility in V0.9.
2009-09-03 17:02:16 -07:00
Cary R 872962ef18 Fix subtle bug in scope checking.
This check looks to be defined to check the child scope not the
top level scope.
2009-09-03 16:58:36 -07:00
Cary R 9669ccd011 Update config.guess and config.sub to latest version.
This patch updates the config.guess and config.sub files to the
latest ones from automake 1.11.
2009-09-03 16:56:54 -07:00
Stephen Williams 5f51b24c56 Force/release for real nets. 2009-09-01 20:48:57 -07:00
Cary R a51f2dca50 Update MinGW requirements, etc.
The old readline library was causing problem. I updated the mingw.txt
file to use the gnuwin32 version of readline (5.0-1) which works. I
also mentioned that I plan to rewrite the directions using a newer
version of MinGW.
2009-08-31 11:27:35 -07:00
Cary R 2b17366ad5 Major rewrite of indexed part selects.
This patch is a major rewrite of the indexed part selects (+: and -:).

It made the following enhancements:

1. Make indexed part selects work correctly with both big and little
   endian vectors.

2. Add a warning flag that warns about constant out of bounds/or 'bx
   indexed selects.

3. Moved the -: parameter code to its own routine.

4. Added support for straddling before part selects in a CA.

5. Added more assert(! number_is_unknown) statements.

6. Add warning for &PV<> select with a signed index signal that is
  less than the width of an int. This will be fixed later.

7. Add support for loading a 'bx/'bz constant into a numeric register.

8. Add a number of signed value fixes to the compiler/code generator.

9. Major fix of draw_select_expr() in the code generator.
2009-08-31 11:22:58 -07:00
Cary R 8623f804f2 Add support for an undefined index for the %load/a* opcodes.
These opcodes need to return 'bx or 0.0 for the real opcode when
the array index is undefined.

The patch also documents the auto incrementing of the bit
index register done by the %load/avx.p opcode.
2009-08-31 11:19:45 -07:00
Stephen Williams a2bf4904c4 Handle nets driven by C8<> constants. 2009-08-29 08:53:44 -07:00
Stephen Williams aad5029ff3 Get rid of some lingering references to vvp_fun_signal_vec::vec4_value. 2009-08-28 22:08:40 -07:00
Stephen Williams 008a4100b3 Handle real wires as vvp_wire_real filters. 2009-08-28 20:32:33 -07:00
Cary R 83c7a24cff Add missing limits.h include in vpi_signal.cc 2009-08-27 17:48:27 -07:00
Cary R e31b6bd20c For a part select driving another part select the extra bits must be 'bz.
When a part select is driving another part select any bits outside the
original select must be 'bz instead of 'bx. If we initialize the temporary
buffer to 'bz this should work as required. It there are multiple drivers
then a resolver comes into play and this should not matter.
2009-08-27 14:06:12 -07:00
Cary R a49463e728 Propagate sign in synthesize for math operators.
The sign of the expression needs to be propagated for the
math operators when they are synthesized.
2009-08-27 13:39:36 -07:00
Cary R 06997c63ed Pass file/line information for part selects.
Propagate the file and line information for a part select
expression and LPM (continuous assign).
2009-08-27 13:39:24 -07:00
Cary R ecb00017cb Enhance %shiftr/i0 and $shiftl/i0 to work with negative shifts.
The %shiftr/i0 and %shiftl/i0 opcodes are used for some part
selects and if we have a negative shift we want the value to be
padded with 'bx. This patch enhances the two %shift/i0 opcodes
to work with negative shifts and for negative shifts pad with
'bx instead of 'b0.

It also fixes %ix/get/s to use a uint64_t instead of a unsigned
long to avoid problems with sign extension on 32 bit machines.
2009-08-27 13:39:06 -07:00
Cary R d108221fef Assert number is not unknown for many cases in tgt-vvp.
This patch adds a number of asserts that a number is not unknown
in places where this should never happen.
2009-08-27 13:38:55 -07:00
Cary R 1306a6db81 Add vvp support for out of bound variable part selects.
This patch adds support for variable part selects with out of bound
and 'bx index values.
2009-08-27 13:38:41 -07:00
Cary R e576e1eb2c Add a -Wselect-range warning class.
This patch adds support for a -Wselect-range warning class to the
driver and ivl programs. This is part of -Wall. The actual checks
will be added in a later patch.
2009-08-27 13:38:22 -07:00
Stephen Williams a4d8c61ef9 Remove dead filter code from functors.
All the filtering and forcing is now done in wire filters, so the
last vestiges of force/filter support in th variable functors can
be removed.
2009-08-26 21:51:18 -07:00
Stephen Williams 0705717efa reinterpret_cast is not the run-time-type safe way. Use dynamic_cast. 2009-08-26 21:30:38 -07:00
Stephen Williams 4da1ab3df7 Remove dead code. 2009-08-26 21:08:23 -07:00
Stephen Williams 912ec66d72 Add vvp_wire_vec8 value get methods.
In the process, redesign the interface to the filter_vecX methods
to be more rational.
2009-08-26 20:57:30 -07:00
Stephen Williams 04490703f7 Fix IX_GETVS and LOAD_X1P operations to use filters instead of functors. 2009-08-25 20:07:17 -07:00
Cary R ed4e2eb046 Ignore a zero MCD for $fflush, $fdisplay*, $fwrite* and $fstrobe*. 2009-08-25 10:28:56 -07:00
Martin Whitaker da010db739 Fix for pr2842185 and for genvar scopes.
When checking for name collisions, the compiler looks for genvar
declarations in the enclosing module rather than in the current
scope, which leads to false positives. The compiler also places
all genvar declarations in the enclosing module scope, even when
the declarations are inside a generate block which has its own
scope. This patch fixes both these faults. It also fixes some
typos and outdated information in comments.
2009-08-25 10:23:59 -07:00
Jared Casper b65a3691d6 Fix memory leak and gcc4.4 compilation.
There was a small memory leak in parm_to_defparam_list where space for
"key" and "value" was being allocated via strdup and never freed.
This was fixed by freeing them at each return point.

In that function, key and value were defined to be const char* but
were later mutated.  gcc4.4 is more strict with const-ness in some
functions than previous versions (see
http://gcc.gnu.org/gcc-4.4/porting_to.html section "Strict
null-terminated sequence utilities"), so this caused compilation to
fail.  Fixed by removing the const modifier in the declaration of
those two variables and related nkey variable.  This also necessitated
malloc'ing room for value in one path through the code, which made
memory management easier as well.
2009-08-25 10:16:46 -07:00
Stephen Williams 0490be6b19 Implement vvp_wire_real.
This brings real value variables into the vvp net rework.
2009-08-24 21:50:56 -07:00
Stephen Williams 9f11a23611 More robust creation of nets.
Handle the case where the input to a net is a constant. Since nets
do not exist anymore as nodes in their own right, we need to create
a driver to drive a net from a constant.

Handle forward references of net inputs.
2009-08-23 21:37:16 -07:00
Stephen Williams dc47c2b6e4 Split the filter out from under signals.
Signals in vvp should not derive from their filter, they should instead
share the vvp_net with a wire that acts as its filter.
2009-08-20 20:31:11 -07:00
Martin Whitaker 7c6176357f Fix for pr2837451.
pr2827132 changed the val_ field in vvp_fun_part_sa to only store
the bit values for the selected part, not the entire source vector,
but omitted to modify the recv_vec4_pv method to handle this change.
This patch rectifies that omission.
2009-08-18 17:30:00 -07:00
Cary R 35f3d7f60e Fix a few more minor memory leaks.
This patch fixes a few more memory leaks that can happen under
error conditions.
2009-08-18 14:15:36 -07:00
Cary R 2e820ca6f0 Do not schedule a new event if the previous event has the same value.
If the previous event has exactly the same value as this event then
we do not add this event to the event queue.
2009-08-18 14:10:45 -07:00
Stephen Williams e44247f82c Fix man page formatting for portability. 2009-08-10 06:40:50 -07:00
Stephen Williams 7b102b18fd Add function to define parameter from command line
This patch is based on one from "bruce <[email protected]>".
I've applied all but the elaboration code, which I rewrote to
properly work with the elaboration work queue. I also constrained
the implementation so that the parameter name must have exactly
two components: the root scope name and the parameter name. This
is necessary to keep the defparm processing sane. The comments
from bruce's original patch are as follows:
--
This patch would provide function to define parameter from command
line. This serves the same functionality as 'defparam' in Verilog
source code, but provide much more ease for using. Parameter
definition can be write in command file, with following syntax:

    +parameter+<scope>.<parameter>=<val>

*Do not apply any space between them*
The scope name should be full hierachical name with root name at
the begining. The following example would override test.T1 with
new value 2'b01:

    +parameter+test.T1=2'b01

'test' here is the root module name. The parameter value here
should be constant. Parameter definition can also be write in
the command line:

    iverilog -Ptest.T1=2'b01

This serves the same functionality with the previous example.
If we define the same parameter in command file and command line,
the one in command line would over-write all others.
2009-08-06 14:42:13 -07:00
Stephen Williams 37b11e0355 Fix index out of bounds error message.
When displaying an index out-of-bounds message, use the index
given in the source code, not the canonical (translated) value.
2009-08-06 11:59:34 -07:00
Cary R 88b18d4212 Warn that we do not support non-blocking assignment to real array words.
A while ago we changed how variable arrays were accessed. This change
did not get propagated to the non-blocking assignment for real array
words. This patch adds a warning that this is not currently supported.
We can add this to development, but not V0.9 (interface change).
2009-08-06 11:34:07 -07:00
Cary R cb5c4299fb UDPs need to evaluate their arguments before generation
When generating a .udp call the arguments need to be evaluated
before the .udp is. This allows things like .resolv to be built
correctly.
2009-08-06 11:28:38 -07:00
Cary R 7916e148f8 UDPs can only take two delay values.
Check in the compiler that a UDP is only given two delay values.
2009-08-06 11:15:43 -07:00
Cary R 2e166b7279 Fix some memory leaks/issues found with cppcheck.
I ran cppcheck on the code and it found a few obscure memory leaks and
a few other issues. This patch fixes most of them.
2009-08-06 10:50:08 -07:00
Stephen Williams aaddbdb0ec Merge branch 'master' into vvp-net-out-rework 2009-08-02 17:32:01 -07:00
Stephen Williams bb447af143 Threads load from signals / force propagates without refiltering.
Two small fixes: Threads should load signal values from signal_value
objects, not signal functors, and the force method should not run
its value through the filter.
2009-08-02 17:04:00 -07:00
Cary R ce89a68735 Add full $ferror() support, bug fixes, etc.
This patch adds $ferror() support. This is enhanced over what the standard
says needs to be supported. All file I/O routines set/clear the errno flag,
This allows $ferror() to check when an invalid fd/MCD is passed to a
system task. The $ferror() fd is only checked if errno is not set since
all the other routines will set EBADF when they are called. This allows us
to test the output from $fopen() which sets the fd to zero (an invalid fd)
when it has a problem.

The following bugs (changes) are also fixed:

Fix $fdisplay*, $fwrite*, $fstrobe*, $fflush, $fclose to not accept 0 as
a valid MCD.

For the $fdisplay*, $fwrite* and $fstrobe tasks an invalid fd/MCD is now
a warning instead of an error like the other file I/O routines.

Modify $fputc() to be a function and return a value like $ungetc().

Modify $ungetc() to return a value like the standard dictates (-1 on
error else 0) and pass the value as a full int to get EOF as an error.

Remove some extra checks that could not happen in $fseek() and to
be safe convert the numeric codes to the system symbolic values.

Skip $fstrobe callback when the fd/MCD is closed. The standard says
we need to cancel the callback, but we currently do not have the
ability to do that so just skipping this will work for now.

Free the argument handle when $fscanf() is called with an invalid fd
(memory leak).
2009-08-02 10:53:29 -07:00
Cary R b0ac550791 Add a warning when we reach 1024 files.
It's not too likely we will ever reach this, but we should be nice
and print a message instead of just failing. We could set errno,
but for now the warning will have to be enough.
2009-08-02 10:50:34 -07:00
Cary R 52fbb3f734 Fix memory leak, unneeded argument.
Very minor issues dosify was not closing files so memory leaks could
show up and vpi/sys_readmem.c was passing the file after it was
closed to the lexor cleanup code. The lexor cleanup code does not
need an argument.
2009-08-02 10:46:59 -07:00
Stephen Williams 11812d8074 LXT2 file size limit can be set by environment variable.
The LXT2 writer allows for splitting the output file into multiple
output files. The size of that output file was fixed, but needs to
be controlled by an environment variable.
2009-08-02 10:10:45 -07:00
Stephen Williams bbc0ee0ad0 Merge branch 'master' into vvp-net-out-rework
Conflicts:
	vvp/part.cc
2009-07-28 21:20:50 -07:00
Cary R 72a98e85cb Add full genvar support and name space checking.
This patch adds genvars to the elaboration process. It adds checks
that a genvar is defined for a generate loop and that a genvar does
not conflict with any other items in its name space.
2009-07-28 20:04:54 -07:00
Martin Whitaker d7fe9c613c Fix for pr2821633.
Currently, edge event functors declared in automatically allocated
scopes that are used to detect edges on signals declared in static
scopes are unable to correctly determine edge information for the
first signal delta they receive because they do not know the old
state of the signal. This patch causes the state of static signals
received by these event functors to be recorded as static state in
the functors, so the old state of the signals can be initialised
to the correct value when a new automatic context is created.
2009-07-28 20:01:19 -07:00
Martin Whitaker 1453c5b0bb Suppress unnecessary update of part select functor output.
Currently a part select functor will send updates to nodes connected
to its output whenever any part of its input vector changes. This
patch ensures updates are only sent when the selected part of the
input vector changes.
2009-07-28 19:57:04 -07:00
Cary R e98000426e Fix power operator width in self-determined context.
In a self determined context the width of the power operator
is defined to be the left argument width.
2009-07-28 19:52:10 -07:00
Cary R b629d913d2 Fix CA replication of zero issues.
This patch fixes a CA to evaluate and ignore a replication of zero.
It also fixes a minor glitch in the data type calculation code. This
was causing a problem if a zero width replication was the first
element in a concatenation/replication since the data type was hard
coded to the first element of the concatenation/replication. It now
uses the first defined element in the concatenation/replication to
determine the data type.
2009-07-28 19:45:40 -07:00
Cary R e362a86b16 Fix procedural concatenation/repetition problems
This patch evaluates the whole concatenation expression and
makes the concatenation padding sign aware. This is needed
when $signed({...}) is passed as an argument.

A repetition is just N copies of the base expression not N
evaluations of the base expression. This is only a problem
when functions have side effects. It's also faster to copy.
The evaluation must also be done when the replication count
is zero (see 1364-2005).
2009-07-28 19:45:26 -07:00
Cary R c5ee1fdbf5 The scanf functions must return EOF if source starts at the end of input.
The $fscanf() and $sscanf() functions are defined to return EOF when
the end of input is reached before any matches or match failures have
occurred.
2009-07-28 19:40:46 -07:00
Cary R e932c41587 When skipping C-style comments in a skipped `ifdef include the '\n'
When a C-style comment /* */ is being skipped because it is in a
skipped `ifdef, `ifndef, etc. directive then we need to output a
'\n' at any comment end of line.
2009-07-28 19:31:04 -07:00
Cary R 212bd4134a Find the width of net arrays correctly.
Add code to the generic get_array_word_size() function to correctly
find the width of net arrays and use this routine in the _vthr_
code as needed.
2009-07-28 19:27:51 -07:00
Cary R ddfdd492b3 base if for ivl pbase is for ivlpp 2009-07-28 19:24:17 -07:00
Cary R 9dce6496fb Fix up original SV timeunit/timeprecision patch.
This patch modifies the original SystemVerilog timeunit/timeprecision
patch in the following way:

Removed trailing space.

Reworked some code to use standard spacing rules.

Added some comments.

Combined some code.

Major rework of local/global timeunit/timeprecision logic.

Major rework of timeunit/timeprecision declaration/check code.
This was needed to remove the shift/reduce warnings.

Add a number of checks for invalid combinations.
2009-07-28 19:18:09 -07:00
Sreeraj R c2feeb03df System Verilog timeunit and timeprecision addition
This patch adds timeunit and timeprecision keywords.Use -gsystem-verilog
generation flag to use this feature
2009-07-28 19:18:01 -07:00
Cary R e191cf7f55 Add check for prec > unit in `timescale directive. 2009-07-28 19:14:08 -07:00
Cary R 6116078d9f Real constants are always signed.
Set the signed_flag_ for real constants.
2009-07-28 19:10:53 -07:00
Stephen Williams 8bbb7ff7db Create the vvp_wire_base class to handle wires.
Take wires out of the signals/variables and move them into a filter
instead. This is a big shift, and finally starts us on the path to
divide wires out of signals.
2009-07-27 21:42:04 -07:00
Stephen Williams 6ef9243a10 vthread no longer accesses any signal methods.
We want the entire force/release subsystem to only reference the
vvp_net_t or vvp_net_fil_t objects in a net. This gives us the
latitude to take wire implementations out of the vvp_net_fun classes.
2009-07-05 16:27:14 -07:00
Stephen Williams 9fe28e09a6 Merge branch 'master' into vvp-net-out-rework 2009-07-03 19:53:03 -07:00
Cary R c9f6bd68b9 Add compiler warnings for more constant out of bounds array accesses.
This patch adds compiler warning messages for all/most constant out
of bounds array access.
2009-07-03 19:43:00 -07:00
Cary R 067fcc07a1 More VCD enhancements.
Make the code smarter so it can keep fewer items in the lists.
Scopes and explicitly given variables are all that is kept.
Includes a few other refinements.
2009-07-03 19:38:35 -07:00
Cary R 7e3a7b87ff Add basic support for events and cleanup VCD dumper.
This patch adds support for dumping named events to the VCD
dumper only. The LXT and LXT2 will be added once this has
been tested more. It also reworks the $dumpvars routine
to be more consistent concerning warning messages for duplicate
signal dump requests and fixes some bugs.

For events you will get extra events at T0 and at $dumpon. I
plan to fix this, but that is much more involved.

For duplicate signal warnings. Implicit duplicates loaded
automatically from a scope will not display a warning. Only
an explicit signal request will print a warning if it was
already included. All other will be silently ignored. This
should limit the warning to only what the user cares about.

For example:

  $dumpvars(0, var, scope_that_includes_var);

Will work without a warning message.

  $dumpvars(0, scope_that_includes_var, var);

Will generate a warning since the var was already included
by the scope request.

Other enhancements include the start of including type
information in the output. For now integer is added, the
other type information will require changes to the code
generator and hence will only be done in development.
2009-07-03 19:38:15 -07:00
Cary R 236f56949f Use correct sign for signal and constant addition.
This was incorrectly using the expression sign not checking if
the two sub-expressions are both signed. This likely used to
work, but in the context of $signed which sets the expression
to signed so we can have a signed expression without both
sub-expressions being signed.
2009-07-03 19:33:35 -07:00
Cary R 354d600453 Use the correct suffix default for 0.10. 2009-07-03 19:29:48 -07:00
Stephen Williams ac78ae347b Make force_fil_* methods virtual and part of vvp_net_fil_t.
These methods are type specific, but the code that invokes them
get at them from pointers to filter objects, so it makes sense to
make them abstract methods of the vvp_net_fil_t class.
2009-06-28 20:54:20 -07:00
Stephen Williams 7df9d60761 Collapse vvp_filter_wire_base into vvp_net_fil_t.
The vvp_filter_wire_base class was not really used, and by
collapsing into vvp_net_fil_t some casts are eliminated.
2009-06-25 22:13:03 -07:00
Stephen Williams 1940de0110 Fix some merge errors. 2009-06-25 20:43:09 -07:00
Stephen Williams b5271137cf Merge branch 'master' into vvp-net-out-rework
Conflicts:
	vvp/array.cc
2009-06-19 22:31:47 -07:00
Cary R 291dc52651 Print a warning for an implicit sensitivity list that has selects.
An implicit sensitivity list that has selects (bit, part, indexed
part or array) will include more than the user expects so print a
warning to let them know what will happen. Other simulators have
the same behavior, but I believe this is incorrect and needs to
be fixed to only include the appropriate parts. The warnings can
go when we fix this functionality, but we need them now to warn
the user that they may not be getting what they expect. One other
simulator warns for array selects.

This patch also adds the array index to the sensitivity list.
2009-06-19 22:12:15 -07:00
Cary R b22dc5f621 Fix real variable array and net array bugs.
This patch fixes a number of bugs related to real variable and net
arrays. Specifically the following:

1. When iterating over (scanning) a net array start at base index 0
   not index 1.

2. Don't fail when iterating over (scanning) a real variable array.

3. Run the array_word_change() routine when a real variable array
   word is changed. This allows array ports and value change
   callbacks to work correctly.

4. Update the array_word_change() routine to work with real variable
   arrays.

5. Update the array port code to support real variable arrays.

6. find_name() needs to also iterate over net array words just like
   memory array words.

7. Initialize all real array words to 0.0 when the array is created.
2009-06-19 22:03:48 -07:00
Cary R 95ba25b9be Make the dumpers match better (VCD, LXT, LXT2).
This patch removes some of the unneeded differences in the
various dumper routines. This is the start of a complete
refactoring, but the first task is to make them as common
as possible and this is the start of that.
2009-06-19 22:02:15 -07:00
Cary R e592b52515 For real expressions evaluate non-real sub-exprs as bits and convert.
When processing procedural real expressions we need to evaluate
non-real sub-expressions as bit based expressions and then
convert the result to a real value. This is particularly import
for integer division.
2009-06-19 21:58:13 -07:00
Cary R 1d2577b2fd Use a default buffer size of 512 vs 256 for displaying.
This patch changes the initial buffer size when displaying results
to 512 from 256. This initial buffer is used as the default for the
floating point results and failed when %f is given a large, but
valid value. To make this even more safe we add the precision to
the size to make sure we do not overflow the buffer.
2009-06-19 21:51:19 -07:00
Cary R 81822c2d50 Parse the config declarations and report they will be ignored.
This patch adds code to parse config declarations and reports
that they are not currently supported and will be ignored.
2009-06-19 21:45:53 -07:00
Cary R d98c925f53 Some compiler cleanup and minor memory leak fixes.
This patch cleans up some unneeded code. Releases some allocated
memory before the compiler quits and fixes a couple minor memory
leaks in the compiler and vvp code generator.
2009-06-19 21:42:07 -07:00
Patrick Doyle f379cd0a14 Teach vvp about -N
Added support for the -N option, which causes $stop and ^C to behave
like $finish with an exit code of 1.

While I was at it, I noticed that the summary line in the man page for
vvp was missing a couple of options, so I fixed that.
2009-06-19 21:30:33 -07:00
Stephen Williams 42b503a24a Threads force to a net, not a signal.
This mostly gets the public force methods out of the signal functor
and into the vvp_net_t object.
2009-06-19 21:15:08 -07:00
Stephen Williams a3f16c9fba Indexed force of vector8 wire. 2009-06-11 21:18:08 -07:00
Stephen Williams 23f7d606f8 Force functor support for vec4 values. 2009-06-11 20:48:37 -07:00
Stephen Williams 90941648bf Implemented %force/x0 instruction using force filter. 2009-06-08 17:58:59 -07:00
Stephen Williams 307121d1af Merge branch 'master' into vvp-net-out-rework 2009-06-07 18:00:55 -07:00
Cary R 5153bfc1f7 Ignore specify pulsestyle_* and *showcancelled directives.
This patch adds code to silently ignore the specify directives:
  pulsestyle_onevent
  pulsestyle_ondetect
  showcancelled
  noshowcancelled.
2009-06-07 16:56:30 -07:00
Cary R aeac491cfc Some delay expressions need to probe their width (ternary)
The ternary operator requires that the expression width be defined.
This requires that the delay expression has test_width() run on it.
2009-06-07 16:51:47 -07:00
Cary R 1942327ae2 Allocate the fd table dynamically in 32 entry chunks.
The fd table used to be statically allocated with only 32 entries.
Three of these were preallocated for stdin, stdout and stderr
leaving only 29 for the user.  This patch makes the allocation of
this table dynamic with a hard limit at 1024 total fds. The table
is increased in 32 bit chunks.
2009-06-07 16:48:05 -07:00
Cary R 17decb3bb7 Fix bugs in &= and |= for vvp_vector4_t
Someone got a bit too creative in reducing the original equations
I wrote to handle this. This patch reverts the previous code and
uses my original equations. This passes for both wide and narrow
vectors. The equations are slightly more complicated, but the old
z2x conversion had some overhead. I would expect the time to be
about the same, but you now get the correct results.
2009-06-07 16:45:02 -07:00
Cary R 4479471278 Parse all the 1364-1995 and 1364-2001 timing checks.
This patch adds code to parse and ignore the following timing checks:

$nochange  1364-1995
$skew      1364-1995
$fullskew  1364-2001
$removal   1364-2001
$timeskew  1364-2001

The other checks were already supported. These have not been tested,
but they use the same basic terms as the other checks. We can fully
test these when we actually implement them.
2009-06-07 16:39:25 -07:00
Cary R ca7e64afaf Fix some keywords, add -g2001-noconfig and fix up uwire/wone.
This patch adds -g2001-noconfig command line flag. The compiler
already supported this with `begin_keywords. Document this in
the manual page and fix a few other issues.

Fix endgenerate to be a 2001 keyword and add a few missing
keywords at the appropriate standard level e.g.(unsigned).

Add uwire and deprecate wone. wone used to just convert without
a warning to a wire. uwire will display a warning that it is
being converted to a wire without a check. wone is converted to
a uwire with a warning and then prints the uwire message. The
uwire message will be replaced with a real check fairly soon.
2009-06-07 16:31:34 -07:00
nog c842cdbdc4 Avoid stepping on free'd memory during recursive macro expansion
During macro expansion (with arguments), there is one global buffer
(exp_buf) that keeps getting reallocated to fit all the macro's text
that's currently being expanded.  The problem with this scheme is that if
a macro with arguments needs to be expanded from the macro text of another
macro with arguments, it may happen that the second expansion forces
the above exp_buf buffer to be reallocated.  Which is fine until the
previous macro processing resumes where (struct include_stack_t *)->str
now points to uninitialised memory.  Basically, the code that can trigger
such behaviour is as follows:

`define FOO(a)	(a+3)
`define BAR(b)	(`FOO(b)+2)

`BAR(x)

Ofcourse, you need to get lucky to get the exp_buf to be realloced at the
right point, but it's possible.

I don't see the advantage in keeping all the expanding macro's text
together, so my solution is to simply allocate a new buffer and pass it
as (struct include_stack_t *)->str to the flex parsing function and free
it at the end.
2009-06-07 16:24:49 -07:00
Cary R 80c21adb4a Allow devel to parse a .scope statements with out the `celldefine info.
This change allows us to test V0.9 files under V0.10.devel.
2009-06-07 16:19:10 -07:00
Cary R d06f6dfc51 Add support for unconnected_drive.
Icarus has recognized this directive, but it did not do anything
with the information. This patch adds the functionality for most
common cases. It adds this by changing the input net type from
wire/tri to tri1 or tri0 depending on the pull. The issue is that
if the input net is not a wire or tri this is not safe and should
really be done as an external pull gate connected to the input.
We will need to handle this is it ever comes up. For now a sorry
message is printed.
2009-06-07 16:14:52 -07:00
Cary R 364cf99a67 Add more default net types
Previously Icarus only supported a default net type of wire or none.
This patch adds the rest of the supported net types (all except
uwire and trireg) to the `default_nettype directive. It also fixes
make_implicit_net_() to use the default_nettype instead of always
using implicit (the same as wire).
2009-06-07 16:09:00 -07:00
Cary R 6297422427 Rework the timescale directive and cleanup line a bit.
This patch reworks the `timescale directive to do a better
job of parsing the line, it refactors some of the code and
should produce better error messages. It also tightens up
parsing the numeric constant, etc. to better match the
Verilog standard.

The parsing of `line has been enhanced to only allow 0, 1 or
2 for the level and a single line comment at the end of the
line is ignored.
2009-06-07 16:03:04 -07:00
Cary R 5fc236accc Use strchr() instead of index().
strchr() is more portable and index() is not available under
MinGW so replace index() with strchr().
2009-06-06 11:15:22 -07:00
Stephen Williams bc6f3cc905 Re-implement force/link to use a vvp_fun_force node.
The vvp_fun_force node converts its input to a call to the
force method of the target node. This eliminates the need for
linking a net to a force input of a signal.
2009-06-06 11:01:12 -07:00
Stephen Williams 29a47efa81 Remove the signal functor force-2 input port hack.
The vvp_net_t port 2 was used to implement force behavior, but that
is no longer how we plan to implement force, so remove it from the
implementation of signal nodes. This currently breaks much of the
force/release functionality, but we'll get it back by other means.
2009-05-27 20:37:46 -07:00
Stephen Williams 30ee9a104e Merge branch 'master' into vvp-net-out-rework 2009-05-23 14:57:42 -07:00
Cary R 4affc6e412 Make ivl warn that it does not support ifndef or elsif
We added support for these two directives some time ago,
but ivl was never updated to warn that it did not support
them and you needed to use ivlpp.
2009-05-23 14:32:31 -07:00
Cary R 1bce6ec726 Add better error checking to the two line directives.
Icarus supports both a #line and `line directive. This patch
reworks the parsing of these to provide better error detection
and full checking.
2009-05-23 14:27:58 -07:00
Cary R 4991711672 Add support for `resetall and other directive changes.
This patch adds support for the `resetall directive.

It also changes `celldefine, `endcelldefine and `resetall
to no longer grab text following them. These directives do
not take an argument so they should not be grabbing any
text and silently discarding it.

The `timescale processing was reworked to handle being
reset and hooks were added to easily change the default
time units and precision when we add that feature request.
2009-05-23 14:21:39 -07:00
Cary R 636758f66d Add support for `celldefine, vpiCellInstance
This patch adds real functionality for `celldefine and pushes this
property to the run time which can access this with vpiCellInstance.
This is technically only available for a module, but all scopes
have the property and only modules should return true when the
'endmodule' is between a `celldefine and `endcelldefine directive.
2009-05-23 14:13:47 -07:00
Cary R 22416b4d01 Print a better error message for a '~' token in front of ('&' | '|' | '^')
Some users may expect this to work so this patch catches these
specific cases and tells the user to use the singe unary operators
'~&', etc. instead.
2009-05-23 14:08:22 -07:00
Cary R 9c02c7d7a4 Cleanup if an invalid option is given.
Cleanup the temporary files and memory if iverilog is given
an invalid option.
2009-05-23 14:04:10 -07:00
Cary R 79578f20d1 Fix memory leak when parsing command files.
These are not leaks in the true sense of the word, but it is
memory that is not being freed before the program finishes
so valgrind will complain about this.
2009-05-23 14:04:01 -07:00
Larry Doolittle 9619eb3a0d Remove fresh const lint
It looks pretty stupid and non-c++-y, but it does remove two compiler warnings
vvp/stop.cc: In function 'void stop_handler(int)':
vvp/stop.cc:492: warning: deprecated conversion from string constant to 'char*'
vvp/stop.cc:493: warning: deprecated conversion from string constant to 'char*'
2009-05-23 14:00:47 -07:00
Stephen Williams 9a348e2174 Split type-specific filters into type-specific derived classes.
The wire base class cannot carry all the overhead for handling all
the different net types, so split it out into derived classes. This
will also move me closer to splitting wires away from variables.
2009-05-23 10:55:07 -07:00
Stephen Williams 6e1d7b6210 Merge branch 'master' into vvp-net-out-rework 2009-05-18 19:46:13 -07:00
Cary R 90d9debe81 Display and error for hierarchical references in a parameter r-value expr.
Display and error message when the user uses a hierarchical reference
in a parameter r-value expression.
2009-05-18 17:52:49 -07:00
Cary R 7f20f8c768 Add support for displaying a real parameter using %d.
This patch modifies the real parameter get_value routine to use
the standard vpip_real_get_value() routine. This routine has
support for an integer and a decimal string value.
2009-05-18 17:49:35 -07:00
Cary R fe3dd3a559 Add support for initializing outputs declared as output reg.
The standard allows an output declared as "output reg" to be
given an initialization assignment in the output declaration.
this patch adds that functionality. Specifically:

  output reg out = 1'b0;

works as expected.
2009-05-18 17:43:54 -07:00
Cary R 9a04f1c380 Add escaping to the stringification of macros.
Icarus support returning a string version of a macro ``<MACRO>.
The problem was that it did not escape '\' or '"' so if the
macro to be escaped had either of these it would create an
invalid string. This patch fixes this by translating these two
codes to their octal equivalent when the macro is converted.
2009-05-18 17:40:52 -07:00
Cary R fd2e27fe0f Document -gsystem-verilog and add -gno-system-verilog 2009-05-18 17:38:48 -07:00
Cary R 6c0e1480ff Fix the %assign/v0/x1 operators for width equal negative offset case.
This patch fixes the three %assign/v0/x1 operators to correctly
notice that the select has fallen off the start of the vector
for the case that the negative offset equaled the width.
2009-05-18 17:34:56 -07:00
Stephen Williams 682ab886d8 Implement release and deassign more directly.
There is no use implementing the release and deassign methods as
port commands. It's confusing and a waste of vvp_net_t functionality.
It also obscures what needs to be done to more force/release into
the filter object.
2009-05-15 20:49:07 -07:00
Stephen Williams d780af1eca Merge branch 'master' into vvp-net-out-rework 2009-05-05 20:09:51 -07:00
Cary R eba5d12deb Fix %t to work with real system functions.
Fix %t to get the real value when the argument comes from a real
valued system function.
2009-05-05 19:36:15 -07:00
Stephen Williams a5046bd8c6 Filters need to let through the forced value.
When the forced value is first set, the filter needs to let that
value through. Otherwise, the forced value will not propagate out
from the net.
2009-05-04 20:39:26 -07:00
Stephen Williams ba00c6caf7 Change implementation of force/release to use filters.
This is moving towards moving force/release out of the signal
class. The end-game is to remove all of the wire implementation
out of the functor and into the filter. Variables will remain in
the functor.
2009-05-04 20:26:41 -07:00
Stephen Williams 79a5dde7c4 Merge branch 'master' into vvp-net-out-rework 2009-04-28 19:34:31 -07:00
Cary R c768805d9f Add a warning message for some array words when dumping.
When dumping an array word the name is implicitly converted to
an escaped identifier. If this implicit name conflicts with an
explicitly created escaped identifier this patch will print a
warning message warning that the array word will conflict with
an escaped identifier.
2009-04-28 19:02:22 -07:00
Cary R bbb132aaa7 Vec8 delays should schedule like vec4 delays.
This patch adds code to calculate the vec8 delays using the
same method that is used to calculate the vec4 delays.
2009-04-28 18:57:23 -07:00
Cary R 31fae351d2 Calculate the width of an array word correctly.
When finding the width of an array word we need to skip any word
selects for the array dimensions.
2009-04-28 18:04:57 -07:00
Cary R 192522b3d8 Check for name space collisions.
This patch adds code to check for most of the name space
collisions. genvars are not checked correctly since they
are not completely implemented.
2009-04-27 17:24:36 -07:00
Stephen Williams 7e9e50d3b0 The vvp_vpi_callback belongs with the vvp_set_sig stuff.
Move the vvp_vpi_callback to the vvp_net_sig.h header file, and
collapse some useless hierarchy. (Specifically, all callbackable
items are also wordable.)

Move the run_vpi_callback invocation for wires/variables from the
output generator to the newly implemented filter object. This is
starting to get the filter class working.
2009-04-24 21:50:00 -07:00
Stephen Williams 53051be2d4 Merge branch 'master' into vvp-net-out-rework 2009-04-17 18:48:16 -07:00
Cary R c685911653 Update manual pages to be 0.10.devel.
This patch updates the manual pages to reference 0.10.devel
and fixes a few things in the main iverilog manual page.
2009-04-17 18:33:56 -07:00
Cary R e23d14269a Dump the streams when entering interactive mode.
This patch adds code to automatically dump the output stream
including any dump file when entering interactive mode. When
the user typed ^C or $stop was executed.
2009-04-17 18:30:25 -07:00
Cary R 278e2060a8 Add support for dumping non-constant array selects as a constant select.
Dumping array words is an enhancement that we have added to Icarus.
The problem was that if you wanted to dump the whole array you would
like to use a for loop as follows:

for (lp = 0; lp < max ; lp = lp + 1) $dumpvars(0, array[lp]);

This used to work, but some of the VPI rework broke it because it
counted on the word select to be constant. This patch restores the
functionality by converting the variable word select into a constant
word select in the calltf routine. This is done without warning and
only for the $dumpvars() routine.

Adding this functionality necessitated adding support for vpiIndex
to the &A<> routines.
2009-04-17 18:23:43 -07:00
Cary R b1dd0b1f6d It is an error to select part of a scalar value.
In 1364-2005 it is an explicit error to take the select of a scalar
or real value. We added the checks for real a while ago. This patch
adds the functionality for scalar values. In the future we may want
to push the scalar property to the run time.
2009-04-17 18:18:22 -07:00
Cary R 5d5c7e88f9 Warn the user if they use both a default and `timescale based delay.
This patch add code to print a warning message if it finds both a
default and `timescale based delays. The -Wall or more specifically
the -Wtimescale flag can be used to find the module with the missing
`timescale directive.
2009-04-17 18:12:27 -07:00
Cary R 1ef6c405c3 Handle $stop and $finish at the interactive prompt.
This patch adds interactive support for $stop and $finish.
$stop displays a message that the simulator is already stopped.
$finish acts exactly like (calls) the interactive "finish"
command. Having $stop do nothing and $finish not finish until
you exit interactive mode is not very intuitive.
2009-04-17 18:08:55 -07:00
Cary R ad604253f2 Print a better error message for the optional system tasks/funcs
This patch adds better error messages (compiletf) for the optional
system tasks and functions (Annex C 1364-2005). Doing this also
makes calling them fail more gracefully (it is no longer a RE).
2009-04-17 18:05:31 -07:00
Cary R d0457a1ac2 Generate better error messages for concat. with indefinite width.
This patch generates a more user friendly error message for a
concatenation with an indefinite width operand.
2009-04-17 17:59:28 -07:00
Cary R fc8549c9f8 Add $readmempath to set a search path for $readmem{b,h}.
This patch add a new system function $readmempath. It accepts
a ":" separated list of directories that $readmem{b,h} will
use when trying to open a given file. If the file given to
$readmem{b,h} starts with a '/' (an absolute path) the search
list will not be used. A new call to $readmempath will replace
the previous search list with the given list. The search list
elements are check to see if they exist and are directories.
If not a warning will be displayed and they will not be added
to the list.
2009-04-17 17:44:52 -07:00
Stephen Williams 5529182f1f Spread the vvp_net.h contents out a bit.
the vvp_net.h header file is getting pretty huge. This divides
the obviously separable signal functor code out into its own
header and source files.

Also, fill out the use of the filter member of the vvp_net_t
object. Test the output of the vvp_net_t against the filter.
2009-04-15 19:08:37 -07:00
Stephen Williams 8310babdfe Merge branch 'master' into vvp-net-out-rework 2009-04-08 21:05:30 -07:00
Cary R 047828ded0 Allow macro expansions to take arguments with multiple arguments.
This patch allows a macro expansion to have an argument which
itself has multiple arguments (handle nested ",").
2009-04-08 17:55:45 -07:00
Cary R 5e723bfd61 Add support for recursive modules inside generate blocks
This patch adds support for recursive module loops if the
loop contains a generate block. The assumption is that the
user is doing the right thing in the generate block to make
the loop terminate. For this case there is also a check
that limits the number of loops (default 10). This prevents
the system from crashing when the user did not correctly
terminate the looping structure. The limit can be changed
by the user if needed.
2009-04-08 17:49:12 -07:00
Cary R a7741d2bd5 Use the port that has already been fetched.
This patch reuses the port that has already been fetched vs
fetching it again.
2009-04-08 17:45:25 -07:00
Cary R 4b2e5e5914 Check for both the library and include file when adding history.
When adding history (add_history) use both the existence of the
library and the header file to determine if history can be
supported. Add a new USE_HISTORY that is the and of these two.
2009-04-08 17:43:00 -07:00
Cary R d074a37a2d For div/mod only sign extend if both arguments are signed.
Only sign extend the operands for division or modulus if
both of them are signed. Previously only the individual
operand signedness was being considered.
2009-04-08 17:37:32 -07:00
Cary R 46350da5f0 Add support for empty task port lists with a warning.
The standard does not allow this, but it appears that other
simulators do. This patch adds the functionality, but prints
a warning message for the invalid task definition.
2009-04-08 17:31:47 -07:00
Stephen Williams 6f8b229646 Remove peek_out() access to the vvp_net_t out member.
Fix up the last bits of code that accessed the ->out member of the
vvp_net_t class. Now the out member is only accessed by send_* methods.
2009-04-06 21:47:21 -07:00
Stephen Williams 6d34b41dce Hide the "out" member of the vvp_net_t object.
The out pointer of a vvp_net_t object is going to be a bit more
sophisticated when we redo the handling of net signals. Take a step
towards this rework by making the pointer private and implementing
methods needed to access it.
2009-04-03 20:40:26 -07:00
Cary R e987162cb9 Skip leading space for some codes in scanf routines.
Most conversion codes in the scanf routines are supposed to
skip leading space. This patch adds that functionality.
2009-04-03 17:46:29 -07:00
Cary R b1cb80b32e Fix constant CA delays to support two/three values.
This patch fixes the code generator to correctly create three value
constant delays. It also fixes a bug in the compiler related to the
precalculation of the high-Z delay when only two delays are given.
Previously if was using a pointer not a value comparison to find
the minimum value.

Variable delays should work when one or three values are given.
For the two value case we need to do a comparison at run time and
that will require changing the compiler/run time interface so that
can only go into the V0.10 branch. This patch can be applied to
both development and V0.9. I have added a sorry message and an
assert for this case. I will add the variable two delay case at a
later time. We also do not support mixing constant and variable
delays on a single statement. That is a much bigger change and
can wait until someone asks for it.
2009-04-03 17:36:42 -07:00
Cary R 337c9e7577 Add support for getting the size of a real array word.
This patch adds code to get the size of a real array word.
We currently define the size if a real to be 1.
2009-04-02 18:34:41 -07:00
Cary R 85e2bf3e55 If a PGAssign is driven by a select then make a driver.
When a PGAssign is driven by (r-value) a bit, part or indexed
select and the strength is not the default (supply). Then
we need to create a driver (BUFZ) to convey the strength
information.
2009-04-02 18:30:26 -07:00
Cary R 74ea0ecb4a Show verireal constants with a decimal point.
When displaying a verireal constant value force the display
of the decimal point and trailing zeros. This prevents 2.0,
etc. from being display as "2". which can be confused with
decimal two.
2009-04-02 18:26:02 -07:00
Cary R 464310f522 Report an error when trying to take the concatenation of a real value.
This patch adds checks in various places to prevent the user from
taking a concatenation of a real value.
2009-04-02 18:20:50 -07:00
Cary R 3517f11c2c Enhance the real selection is invalid error messages.
This patch enhances the error messages emitted when trying to
select part of a real value. It now includes the signal name
so it is easier to debug.
2009-04-02 18:13:38 -07:00
Cary R 5852f1eb7a Report an error when trying to take the select of a real value.
This patch adds checks in various places to prevent the user from
taking a select of a real value (bit, part and indexed selects).
2009-04-02 18:00:36 -07:00
Cary R caab6cab9d A right shift is only signed for an ARS.
The signed_flag should only be set when the expression is signed
and an ARS is used a normal RS should never be signed.
2009-04-02 17:48:08 -07:00
Cary R 1dbc517164 Add limited support for getting and putting to real array words
This patch adds basic support for getting and putting values to
real array words. This will be finished during the VPI rework.
2009-04-02 17:33:58 -07:00
Cary R ad39445eed Arrays can have bit selects of individual words.
The l-value code was not handling the case of a bit select for
an individual array word.
2009-03-30 19:53:34 -07:00
Cary R 3d449f60a2 When determining if a signal is an array use array_dimensions_
The previous code looked for more than one array word to determine
if the given signal was an array or not. The problem with this is
that a single word memory was considered a signal. This is fixed
here by looking for an array_dimension to be greater than zero.
2009-03-30 19:47:10 -07:00
Cary R d7f272d14c Fix problems in rshift code.
This patch fixes the following problems in the right shift code.

The >>> result is only signed if the l-arg is also signed.

The r-arg is always unsigned.

Only sign extend the l-arg when the >>> operator is used.
This relates to an optimization for certain constant shifts.

Removed some obsoleted/outdated code.
2009-03-30 19:39:26 -07:00
Larry Doolittle a05ac4b5f4 Make VHDL code generator skip over virtual pins
Fixes pr2701438
2009-03-30 19:36:11 -07:00
Stephen Williams 82d9b18cc4 BUFZ devices are strength-aware
When vvp_vector8_t objects come in, pass them out as vec8. The
BUFZ device is used in situations where this acts much like a
simple wire.
2009-03-27 17:19:30 -07:00
Cary R a8716cf759 Add message the the $dumpports* task are not available
These are in the standard and we did not have error messages
for them. This patch make calling these tasks a compiletf
fatal error.
2009-03-27 16:10:53 -07:00
Cary R db3ff1643b We are deprecating the $log function in favor of $log10.
When the VAMS math functions were originally built we did a
straight copy of the log() function to $log(). This can
conflict with other Verilog-D definitions of $log. We
need to deprecate this function and remove it before the
next major release.
2009-03-26 19:37:45 -07:00
Cary R 86c22dec4f Use AC_HELP_STRING instead of AS_HELP_STRING.
The later causes a warning under MinGW. The former appears
to work everywhere.
2009-03-26 19:34:50 -07:00
Cary R a6529c2c59 Add the $fread() system function.
This patch adds the $fread() system function. Icarus does not
currently allow missing arguments in functions so the following
standard specified functionality is not supported:

  res = $fread(mem, fd,,count);

It also fixes a memory leak in fopen related to the get_filename
refactoring I recently did.
(cherry picked from commit 036c176e8b)
2009-03-26 14:06:31 -07:00
Cary R 72c2e3f0ac Use a single = in configure.in test
The ability to use == is an extension so use the more common =.
(cherry picked from commit 327e8d0ec0)
2009-03-26 14:04:50 -07:00
Cary R a2ec51c411 Add guards in CREATE_VERSION script.
This patch adds the same guards that the other two scripts
create for the version_tag.h file.
(cherry picked from commit 809044cbf8)
2009-03-26 14:02:43 -07:00
Larry Doolittle d7b34b53b5 Add support for virtual reg arrays to tgt-stub
This patch adds support for virtualized register arrays to the
tgt-stub back end.

Based Cary's patch, but with a slightly different style.
Both work fine.
2009-03-26 11:35:50 -07:00
Stephen Williams 4fb14523c8 Clean up release builder scripts.
The version.h file is generated by the Makefile, we should
prefill the version_tag.h file.
(cherry picked from commit 4205752bb0)
2009-03-24 08:14:58 -07:00
Stephen Williams a2efe4be0d Move on to 0.10 devel.
This was cherry-picked from the v0_9_1 branch commit:

  "Get ready for the 0.9 first release"

and modified to reflect that this is now the new devel branch
headed for the future 0.10 release.
2009-03-24 08:13:54 -07:00
Cary R 10f106f354 Make vvp use inttypes for the 64 bit printing info.
To get the correct print format for a 64 bit value it is much
better to use <inttypes.h> (when available) than building our
own value. This allows MinGW to use the non-standard I64.
(cherry picked from commit d237e35076)
2009-03-24 07:59:26 -07:00
Stephen Williams ff450cdcb8 Slightly more portable version of configure test.
(cherry picked from commit 90f37fe3cb)
2009-03-24 07:59:05 -07:00
Purdea Andrei c9d2400dd0 fixing: %0b format prints nothing for a 0 input
the following example returns ||. This patch fixes it to return |0|.
module t();
wire [3:0] b;
initial
    $monitor("|%0b|", b);
assign b = 0;
endmodule
2009-03-19 09:07:02 -07:00
Cary R be158dd45f Cleanup lxt and lxt2 EOS data.
This patch cleans up the memory allocated in the lxt and lxt2
$dumpvars routines.
2009-03-19 08:59:10 -07:00
Cary R fa8a3d6c2e Handle zero repetition in a synthesized concatenation.
It is valid to have a repetition of zero inside a concatenation
that has other elements with a defined width. This patch adds
this functionality to the synthesize method. It also prints
an error if you try to synthesize a zero width constant.
2009-03-17 15:58:07 -07:00
Stephen Williams 6715426833 fix the arithmetic of multi-word division.
The Multiword division was not handling some degenerate high
guesses for the intermediate division result guess. The end result
was an assertion. Recover from this case.

(Does the addinb back of bp need to be optimized better?)
2009-03-13 21:59:44 -07:00
Stephen Williams c4a62dee0d Pass unsigned-ness of arithmetic operators through operands.
The arithmetic operands are signed only if both operands are signed.
If the expression is unsigned, then the expression as a whole needs
to be processed as unsigned in order to get padding right.
2009-03-11 13:22:11 -07:00
Larry Doolittle 86bf6c447b Drop useless CVS stuff in .txt files
Remove useless, redundant, misleading, and misspelled $Id$ and $Log$
cruft from all .txt files.
2009-03-11 10:34:52 -07:00
Larry Doolittle 3a18bda8ee Don't make useless arrays of nexa
When a pin array is virtual, dll_target::signal() doesn't need
to make a corresponding set of stub nexa.

This patch includes new detection of oversized arrays, configurable
with the ARRAY_SIZE_LIMIT flag.  This limit only applies to devirtualized
arrays; virtual arrays are only limited by your architecture's
unsigned int type.

The concept and earlier versions of this patch have been successfully
stress-tested by multiple people.  This one causes no testsuite
regressions on my machine.

Closes: pr2023076
2009-03-11 10:30:37 -07:00
Larry Doolittle 932aa49b38 Detect overflows converting to long
The code is ugly, but the results are good.
No regressions in existing testsuite, needs a new entry.
2009-03-11 10:26:52 -07:00
Cary R ac4cb1bbe9 You must assert a logical not NULL.
This fixes a small problem where an assert was being called
with NULL instead of 0.
2009-03-09 19:54:44 -07:00
Larry Doolittle b0c4a87133 Spelling fixes
Mostly comments, but includes user-visible debug messages.
2009-03-09 14:39:36 -07:00
Larry Doolittle 67381431ed Add user interface to pin virtualization
Flag is DISABLE_VIRTUAL_PINS.  Try to give a helpful hint for
how to work around any problems our regression testing might
have missed.
2009-03-09 14:37:47 -07:00
Larry Doolittle f344515e38 Remove valgrind errors triggered by virtual pins
NetBus wasn't initializing pin direction.
I hope Link::PASSIVE is correct for busses!
No test suite regressions.
2009-03-09 14:34:30 -07:00
Stephen Williams fff2598709 Fix broken definition of is_linked(). 2009-03-06 10:19:46 -08:00
Larry Doolittle 5bc41e1a17 Virtualize Pins until needed
Reduces resource usage when compiling large memories.
Normal usage patterns still create large nexus arrays
in t-dll.cc:dll_target::signal().

This patch is extensively tested; it shouldn't break anything.

The existing debug "optimizer" flag is (ab)used to control
message printing when large (>1000 element) arrays are
devirtualized or nexus-ized.

The new global variable disable_virtual_pins is available
to force allocation of Pin arrays when they are declared,
but no user interface is provided.

See extensive discussion on iverilog-devel, March 4-5 2009,
title "pr2023076: large memories".
2009-03-05 18:39:38 -08:00
Larry Doolittle d21cd18e3f Minor tweaks ahead of memory virtualization
Limit memory sizes to whatever fits in unsigned; crash if
the conversion from unsigned long to unsigned overflows,
instead of just wrapping.  I don't know what happens on
a 32-bit machine if you ask for an 8 Gig memory, but with
a 64-bit machine and this patch, it crashes with an assert.

Set direction on PartSelect Links before connecting them.

May or may not be considered orthogonal to upcoming
memory virtualization patches.
2009-03-05 17:15:10 -08:00
Cary R 944495b94e More constant function not supported warnings.
This patch adds more places that need to warn about constant
functions not being available.
2009-03-05 17:03:32 -08:00
Cary R d143597996 Add better constant user functions are not supported messages.
This patch adds messages in various places to warn that constant
user functions are not supported. It uses a global variable to
indicate when we are in a constant context. This is a bit of a
kludge, but works well without needing to change a bunch of code.

It is interesting to note that ports are elaborated late enough
that if we had the constant function evaluation code they would
evaluate correctly. This also applies to the function return
range, the concatenation repeat, specparams and initial values.

Signal definitions are early enough that elaboration is what is
failing because the function body is not available (has not been
elaborated). The same thing applies to both parameters and
localparms.
2009-02-27 21:29:54 -08:00
Cary R 82805b9351 Add compiletf routines for the scanf functions.
This patch adds compiletf routines for the $sscanf/$fscanf
functions. It does not enhance the conversion routines it
only adds better error/warning messages.

It also removed the redundant IS_MCD in some of the fileio
calltf routines. This is already checked in vpi_get_file().

I also added the vpiNetArray type to allow us to distinguish
arrays of nets from other arrays (memories). Much more is
needed here, but this solved the problem of the day. The
problem was that we needed to make sure we could assign to
the word of a variable array, but not the word of a net array.
It's actually probably not needed since Icarus converts the
net array word reference to just the net, but I thought it
prudent to make sure things didn't slip by.
2009-02-27 18:00:59 -08:00
Cary R ddea64445c More compiletf cleanup and refactoring.
This patch adds compiletf routines for the mti random functions
and adds a common routine to check for extra arguments. It also
adds file and line information to the rest of the compiletf
routines that were missing them.
2009-02-26 21:42:32 -08:00
Cary R fa1160c4ab Fix/enhance readmem/writemem routines, etc.
This patch adds compilef routines for the readmemb/h and
writememb/h system tasks. It also fixes some errors related
to arrays with negative range values. You can not specify a
negative address in the file, but arrays with negative range
values or negative start/finish argument to the tasks are
supported. It also generates an error when reading invalid
character from the input file.

A significant amount of the code is common between the two
styles of tasks so this has been grouped into common
routines.

It also adds a common routine for getting a string that will
be used as a file name. This routine is used by any task
that requires a file name value. If a filename has a
non-printable character it will be displayed as a \octal
constant to show what the character is.

Updates the dumping routines to match each other better,
improves some error messages and fixes a bug in the LXT2
dumper when dumping greater than 32 bit delays.
2009-02-26 20:46:02 -08:00
Stephen Williams fa02455f36 Delays expressions are 64bit integers.
Fix the PDelay processing to account for the fact that delay expressions
are 64bits. Use int64_t instead of unsigned long.
2009-02-25 21:30:05 -08:00
Stephen Williams c6ed0a9d2c Update the rpm spec file to handle package suffixes.
If the builder wants to build the package with an install suffix,
the %{suff} variable makes that easy. Just define that value as
needed, and there you go.
2009-02-25 14:49:16 -08:00
Stephen Williams a10bd139ab Fix dependency file (-M) generation.
The dependency file may be written by ivlpp as it loads its own
dependencies. Make sure this doesn't mess up the dependencies that
are already written by the main program. This requires that ivl,
ivlpp and iverilog (driver) cooperate on the opening of the
dependency file.
2009-02-25 13:59:28 -08:00
Stephen Williams 1c17412223 Allow constant delay literals to be handled as 64bits.
This is mostly a minor definition change in the parsing of literal
numbers by the vvp lexor. Allow for 64bit numbers in the .delay
records, and have the code generator also able to cope with the
situation.
2009-02-24 13:50:18 -08:00
Stephen Williams 2d6105a3f2 At configure time, make sure prefix, exec_prefix and libdir are OK.
Icarus Verilog internally is not white-space clean. We need to make
sure the configured paths that cause the most trouble are clean and
usable. It is still possible to mess things up downstream, but at least
this should help.
2009-02-24 09:10:10 -08:00
Cary R 158e9fd2be Keep the left and right array range value order information.
Previously Icarus normalized the results so array [7:0] would
be the same as array [0:7]. This works just fine for
simulation, but the VPI calls can select the left or right
value and this was incorrect for the [7:0] case since it was
being normalized to [0:7]. This patch swaps the two values in
the a.out file and from this creates the previous first/last
values and a new flag that can be used to get the correct
left and right values for the VPI interface.
2009-02-24 07:33:42 -08:00
Stephen Williams f1e702bdd5 Blind support for "integer foreign" attributes. (Stefan Theide)
Allows iverilog to parse attribute like syntax that a common
simuator puts into automatically generated verilog code. This
syntax cannot be found in any of the IEEE standards.
2009-02-23 16:37:34 -08:00
Nick Gasson 64e85304b5 VHDL translation for timescale
This patch generates delays with the correct VHDL units. Taking
into account the source module's timescale and precision.
2009-02-23 16:23:56 -08:00
Cary R 66ce204771 The default type of a signal is a vector.
In Icarus all signals are vectors so when asking for the vpiObjTypeVal
we need to return the vpiVectorVal.
2009-02-23 16:19:48 -08:00
Nick Gasson 5660e67b8b Support IVL_EX_DELAY in VHDL target
This patch adds a translation of 64-bit delay expressions to
vhdl_const_time objects.
2009-02-23 15:30:51 -08:00
Stephen Williams 6828620977 Properly detect wire arrays in l-values.
Wires are not allowed as l-values of procedural assignments, even if
the wire is an array. Fix the checker to detect this case event when
the l-value is an array.
2009-02-19 09:32:53 -08:00
Stephen Williams 8e4952d753 Shift of zero always returns zero.
This is an optimization that also avoids some code generator
problems downstream.
2009-02-19 09:22:56 -08:00
Stephen Williams b23825e45d Make certain all index expressions have their width probed.
It is possible for an identifier to have multiple index expressions.
(For example, a part select of a memory word.) Make sure all the
index expressions are probed for width and type.

And also, note that the unary ! returns BOOL or LOGIC, not just
the type of its operand. It is slightly different from the other
unary operators in that way.
2009-02-18 16:02:58 -08:00
Stephen Williams d94e65de4f Handle some cases of self-determined repeat concatenations.
The test_width for repeat-concatenations is tricky because it
requires the evaluated value for the repeat expression. It should
be OK to call elab_and_eval on that expression even during the
test_width for the containing expression. We'll see.
2009-02-17 11:17:32 -08:00
Cary R 5ae86bd6b4 Add support for 64 bit delays in procedural non-blocking assignments.
This patch adds support for 64 bit non-blocking delays in procedural
code. We fixed the procedural delay operator (blocking delays) earlier.
This patch mostly mimics what was done there. The continuous assignment
delay operator still needs to be fixed.
2009-02-17 10:32:11 -08:00
Cary R 93ad8ff95f Add logical support for real values and error for invalid real arguments.
This patch adds logical support for real values (!, && and ||). It
also prints an appropriate error message when a real value is
incorrectly given to an operator that does not allow real arguments
(bit-wise, reduction, shift and repeat/concatenation).
2009-02-16 12:12:15 -08:00
Stephen Williams c2d1038c29 Fix propagation of calculated TRAN values through the island.
Two bugs:
(1) propagating values through the branch accidentally also
did a part select.
(2) Not all nodes of the branch nexus didn't receive a calculated
values, even though they were all marked as done.

In the process, I cleaned up the code a bit, and documented it for
better understanding.
2009-02-16 12:07:29 -08:00
Cary R 9f0e0c6c55 Add support for the other edges in a SDF file.
This patch adds support for the other edges 01, 10, etc. These still
need to be verified in the context of IOPATHs, but they are ignored
in the timing checks and that's what was needed.
2009-02-10 11:51:36 -08:00
Cary R bb799e7e8f SDF files can have null delays.
A SDF file can have null delays and for that case you are to use
the existing delay value (do not change it). This patch adds that
functionality.
2009-02-10 11:47:04 -08:00
Nick Gasson a931eaa586 Fix another case where VHDL input may be driven
This fixes another corner case where the VHDL code generator
would incorrectly generate code that drives an input with an
output.
2009-02-09 13:44:43 -08:00
Cary R bb37607a30 Add island EOS cleanup code
This cleans up most of the memory allocated when building and
island and the branches that connect to it.
2009-02-09 13:41:54 -08:00
Cary R 284ba55764 Update the $sdf_annotate() compiletf and other fixes.
This patch updates the compiletf for $sdf_annotate() to better
check the arguments and to display the file and line location
when an error/warning does occur. It does the same for the
calltf messages. It also fixes a couple of subtle bugs.

First we need to look for a NULL string not a NULL value. The
result buffer should always be defined so will never be NULL.

Next if a scope has no modules we should return like the module
was not found (return 0) vs asserting.
2009-02-05 16:29:02 -08:00
Nick Gasson 2115e87f78 Fix VHDL naming collisions with modules
This fixes a bug where the renaming rules for modules
would generate entity names that collided with already
existing module names.
2009-02-05 14:40:47 -08:00
Cary R 0ea0bffd9a Make the addition of the local directory optional (include path).
In the past we automatically added the local directory to
the beginning of the include search path. This was found to
conflict with what other tools do so this functionality is
now only available when the -grelative-include option is
given to iverilog.
2009-02-05 08:37:33 -08:00
Cary R 87541ce335 vpi_free_object() is just a stub for vpiCallback objects.
The code was using vpi_free_object() to free a vpiCallback
object and that was creating a memory leak since this is a
do nothing routine. You need to explicitly use delete.
2009-02-05 08:23:12 -08:00
Stephen Williams 99a5d4ca9e Update mkinstalldirs to handle paths with spaces.
The newer mkinstalldirs can handle paths that have spaces in them.
While I'm at it, I also updated the Makefiles so that installation
can also work to DESTDIR directories that have spaces.
2009-02-04 08:44:22 -08:00
Cary R b959f473dc Cast away const to avoid a warning when cleaning up const data.
When cleaning up the vcd_list make sure to remove the const
qualifier before freeing the ident. This is created with strdup.
2009-02-03 14:14:25 -08:00
Cary R ec1ca8509d The cleanup of &A and &PV can nest and cleanup some VCD memory.
When cleaning up the &A<> and &PV<> we need to check if the handle
argument is a nested call to another &A<> or &PV<> if it is then
we need to also delete that construct.

We also need to cleanup the vcd_info information list.
2009-02-02 19:48:34 -08:00
Nick Gasson f89f3dcbaf More VHDL naming fixes
This handles the cases where:
    * Instance names contain leading/trailing underscores
    * Instance names contain consecutive underscores
    * Module names contain consecutive underscores
    * Module names contain leading/trailing underscores
	* Ports may be inconsistently renamed
2009-02-02 19:41:50 -08:00
Nick Gasson 501106dc92 Support named blocks with local variables in VHDL target
This patch adds code to generate process-local variables
for scopes of type IVL_SCT_BLOCK. This also handles using
the correct assignment operator (:=) for the local VHDL
variables.
2009-02-01 07:08:55 -08:00
Cary R 3f0b798ef6 More vvp EOS memory cleanup.
This patch cleans up callbacks for arrays, named events and
real variables. It also cleans up the decimal index constants
for net array words.
2009-02-01 07:05:41 -08:00
Cary R d2f4edbfbd Add a message when omitting a $Ssdf_annotate() call. 2009-02-01 07:01:49 -08:00
Cary R c8cb024cb2 Move the vvp private properties to vvp/vpi_priv.h
This patch moves the vvp private properties from vpi_user.h to
vvp/vpi_priv.h.
2009-02-01 06:55:51 -08:00
Cary R 7b1905b997 Add memory freeing and pool management for valgrind.
This patch adds code to free most of the memory when vvp
finishes. It also adds valgrind hooks to manage the various
memory pools. The functionality is enabled by passing
--with-valgrind to configure. It requires that the
valgrind/memcheck.h header from a recent version of
valgrind be available. It check for the existence of this
file, but not that it is new enough (version 3.1.3 is known
to not work and version 3.4.0 is known to work).

You can still use valgrind when this option is not given,
but you will have memory that is not released and the
memory pools show as a single block.

With this vvp is 100% clean for many of the tests in the
test suite. There are still a few things that need to be
cleaned up, but it should be much easier to find any real
leaks now.

Enabling this causes a negligible increase in run time and
memory. The memory could be a problem for very large
simulations. The increase in run time is only noticeable on
very short simulations where it should not matter.
2009-02-01 06:55:28 -08:00
Larry Doolittle 51307c0a3e Lint removal
elaborate.cc:2456: warning: suggest parentheses around comparison in operand of &
vpi/vcd_priv.c:210: warning: operation on 'idx' may be undefined

Probable behavior change.  Passes testsuite.
2009-01-29 17:35:28 -08:00
Cary R 761a15515d Cleanup allocated memory in the math functions and veriusertfs.
This patch cleans up the V-2005 and V-analog math functions to
free their allocated memory at the end of simulation. It also
modifies the veriusertfs code to do the same thing.

It also closes the VCD file at EOS.
2009-01-29 17:32:53 -08:00
Stephen Williams d4d7c14b36 Elide $sdf_anotate when specify is turned off.
Not only does this have a trivial performance benefit, it also will
prevent annotation warnings when the user turns of specify support.
2009-01-28 21:01:49 -08:00
Stephen Williams 03c31808e1 Make $sdf_annotate resilient to missing delay paths.
The $sdf_annotate function needs to handle the special (and probably
ver rare) case that there are no paths in the target module.
2009-01-28 20:44:15 -08:00
Stephen Williams cb1f4f781f Merge branch 'master' of ssh://[email protected]/~steve-icarus/git/verilog 2009-01-28 20:12:46 -08:00
Stephen Williams d7a67d6d17 Better error message about part selects on invalid objects.
Not all identifier types may have a part select, even when a bit
select is OK. Better handle that case.
2009-01-28 20:12:10 -08:00
Nick Gasson 3dadedf9b5 Fix VHDL bug where constant is assigned to input
This fixes a bug where the VHDL target would not
map ports in cases where the port was driven by
a constant.
2009-01-28 17:45:24 -08:00
Nick Gasson babc9c1352 Various signal naming fixes for VHDL target
This avoids generating invalid VHDL signal names in the
following cases:
	- The name begins or ends with an underscore
	- The name contains two consecutive underscores
	- The name is the same as a component declaration
	- The name differs from another only in case
2009-01-28 17:44:14 -08:00
Nick Gasson 497e095277 Avoid multiple declaration of VHDL temporaries
This fixes a bug where temporary variables could be declared
more than once.

It also takes out a debugging print statement I accidentally
left in the last patch.
2009-01-25 08:03:43 -08:00
Nick Gasson 308688f190 VHDL fix concatenation of std_logics
This fixes an assertion failure when taking a slice of
the result of concatenating several single-element vectors.
2009-01-25 07:59:06 -08:00
Nick Gasson 2107125545 Handle %m in VHDL $display code
Just prints a warning that it's not supported.
2009-01-25 07:55:20 -08:00
Nick Gasson ee5302cf33 Fix some more errors when reading from VHDL outputs
I forgot to modify the LPM generating code with the
last patch. This *should* now always ensure a signal
is readable before code is generated to read from it.
2009-01-25 07:50:03 -08:00
Nick Gasson 69e91e4065 Fix various problems with VHDL `buffer' port generation
This patch corrects several bugs with the generation of
VHDL `buffer' ports. The code generator should now
generate a buffer only if the port needs to be read inside
the architecture, otherwise it will stay `out'.

This also correct a bug where an output port is connected
directly to the output of an instantiated component. Generating
`buffer's would work here, but a more idiomatic VHDL approach is
to declare an intermediate signal which both outputs are connected
to. This is implemented in the patch (fixes the regression of
readout.v in the testsuite).
2009-01-25 07:49:54 -08:00
Martin Whitaker b8e350188e Fix for vvp assertion error on forward reference to array.
If an &A() operator contains a label for an array that has not
yet been declared, vvp fails with an assertion error. This
patch delays the calls to array_find() in the functions that
compile &A() operators, using the usual resolve list mechanism.
2009-01-25 07:46:36 -08:00
Cary R c419e77710 More end of simulation memory cleanup.
This patch adds some more memory freeing routines to vvp and
the vpi library. Much more to do before this is finished.
2009-01-25 07:40:28 -08:00
Nick Gasson e5ce88304e Fix mapping of VHDL expressions to function arguments
Noticed this as part of the test case for pr2516774b. Under some
circumstances the input arguments would be cast to the wrong type.
This patch ensures that all the arguments have the correct type.
2009-01-22 17:39:50 -08:00
Nick Gasson 3cc2018346 Emit VHDL hex constants for some unsigned bits strings
This patch changes the output of VHDL unsigned bit strings
which are 4, 8, 16, 32, or 64 bits to use VHDL hex string
constants.

So the following:
  "00000001"
Becomes
  X"01"

Which is much easier to read
2009-01-22 17:39:41 -08:00
Nick Gasson c787e1acd8 Fix VHDL bug where input may be driven by input
This is a fix for pr2527366 where draw_nexus would sometimes
generate code to drive an input from in an input (where they
should have been left unconnected)
2009-01-22 17:38:38 -08:00
Cary R ad3fcf3455 Fix a few memory leaks in vvp.
This patch fixes two memory leaks in the compile stage and one easy
fix in vpi/sys_display.c.
2009-01-21 19:35:47 -08:00
Nick Gasson ba8688c0d1 Fix regression of always3.1.8A with VHDL target
The patch for pr2516774 exposed a bug which caused
always3.1.8A to fail. This patch corrects that.

The test to decide when to use a sensitivity list
rather than an explicit wait statement wasn't tight enough.
2009-01-19 19:54:56 -08:00
Nick Gasson 78bc4b5d47 Fix assignment to VHDL function arguments
This patch is a fix for pr2516774.

The idea is to generate a local variable inside
a function whenever an argument is assigned to. The
variable has an initial value of the argument value
and is used in its place for the remainder of the
function. This patch also handles the case where the
argument is assigned to inside a while loop.
2009-01-19 19:50:48 -08:00
Nick Gasson e6846ea3a7 Improve memory management in VHDL target
Previously the VHDL code generator managed memory for
the AST objects by requiring that each AST element be
responsible for deleting its children. The disadvantages
of this are that it's quite easy to accidentally leak
memory by forgetting to delete a child, and no AST pointers
may be shared by multiple parents (or we'd end up with
double-deletes) -- this results in unnecessary copies of
objects being made.

There's no real need for fine-grained memory management of
AST objects since once they're allocated they tend to
persist until the code generator is about to terminate, when
they should all be freed.

This patch provides a custom new/delete operator for
vhdl_element which logs the vhdl_element objects allocated
in a std::vector (after calling the default operator new).
Once the code generator is finished a single free_all_objects
call deletes all the AST objects in one go. The custom delete
operator is required so that we can still explicitly deallocate
vhdl_element objects before the code generator completes.

There are also some allocation statistics printed at the end
when -pdebug=1 is specified.
2009-01-18 16:42:10 -08:00
Nick Gasson f9448b9dd7 Clean up VHDL debug messages
This won't produce so many useless messages, and the messages
produced should be more relevant.
2009-01-17 09:19:58 -08:00
Nick Gasson f1f9274bb9 Move VHDL global state management to a single file
The new state.cc/hh file now manages all the global
state that we maintain while generating VHDL. This
should make the code a bit tidier.
2009-01-17 09:19:58 -08:00
Nick Gasson 8043629231 Fix some cases where VHDL `buffer' ports were generated incorrectly
This actually removes generation of `buffer' for now.
2009-01-17 09:19:58 -08:00
Nick Gasson ede6acca77 Store only a single VHDL entity for each Verilog module 2009-01-17 09:19:57 -08:00
Nick Gasson 3c2080e502 Start improving performace of VHDL hierarchy generation
This should prune a large amount of the visits to scopes
in the hierarchy. In particular, only one instance of each
scope type should be visited.
2009-01-17 09:19:57 -08:00
Cary R 4b114ff783 Fix for add valid FD/MCD check to $fflush and $fclose.
This patch fixes some issues in the previous patch. Specifically
I need to use vpi_mcd_printf and some trickery was needed to
prevent the compiler from complaining about the format string.
2009-01-16 19:26:47 -08:00
Cary R c2d7ac61c2 Add valid FD/MCD checks to $fflush and $fclose.
This patch adds a check to verify the the FD/MCD is valid in these
two tasks. It displays a warning for invalid descriptors.
2009-01-16 19:26:38 -08:00
Cary R e8f91780e4 Factor out some common compiletf code in vpi/sys_display.c
This patch just factors out the common code for two of the
compiletf routines.
2009-01-16 19:20:21 -08:00
Cary R 71fdf0c849 Add/modify compiletf routines for $timeformat and $printtimescale.
Update/add compiletf routines for these two tasks. The
$printtimescale task was updated to work with more types
of objects.
2009-01-16 19:14:33 -08:00
Cary R 3e2c828778 Add missing vpiModule handle code.
Most named objects should have a vpiModule handle to get a handle
to the enclosing module. This patch adds code to get this for all
the elements that I could find that needed it.

It also adds a three more names to vpi_get_str(vpiType, ...) and
fixes a problem in the vpiLeftRange for PV signals.
2009-01-16 18:32:27 -08:00
Cary R 6f9ddea07f Keep parameters as a parameters reference for vpi calls.
For most cases just using the value of a parameter is fine, but
a vpi call can access more than the value so we want to use a
parameter reference instead of the value for vpi calls.

Strings were working correctly, integer values need some minor
code generator changes and real values needed to be pushed from
elaboration to the code generators. I also changed the default
real value comment from %g to %#g so that it is more obvious
that the value is a real value.
2009-01-16 18:21:50 -08:00
Cary R d2e7ea0b68 Convert $monitor to use string based formatting.
This completes the transition to the new string based formatting.
All the tasks now use the string formatting routines. Better
compile time checking and better messages were also added.

Also a couple of types were added to vpi_get_str(vpiType, ...)
and the calculation for vpiConstantSelect was fixed for both
the &A<> and &PV<> constructs. If the value is a plain variable
or if it is calculated in thread space we assume it is not a
constant.  This may not be true because of limitations/bugs in
the compiler (constant user functions are one known problem).
2009-01-15 19:42:42 -08:00
Cary R 22cc681073 Handle old style scope declarations correctly.
I forgot to modify the old style scope declarations so the
code was trying to free a constant string. Found in the vvp
test examples/hello.vvp.
2009-01-15 19:39:10 -08:00
Stephen Williams 8c07d3b51c Fix memory leak in vpi_put_value.
Certain paths through vpi_put_value cause a vpip_put_value_event to
be created with no path for deleting in. Add the capability in the
schedule_generic method, so that it can be delete as soon as it is
executed.
2009-01-14 20:15:50 -08:00
Cary R 185860a4f1 Make $strobe and $fstrobe use the string based formatting.
This patch modifies $strobe and $fstrobe to use the string
formatting routines. It also combines the $display/$write
and $fdisplay/$fwrite routines into one and removes the
old routines that are no longer needed.
2009-01-14 18:55:03 -08:00
Cary R 4b66ffd08c Use a static buffer when returning the vector value of a const. string.
This patch fixes vvp to use the standard static result buffer
when returning the vector value of a constant string. The
previous calloc method was creating a memory leak.
2009-01-14 18:51:36 -08:00
Cary R eddfa12569 Cleanup the lexor state information when done parsing.
This patch frees the lexor buffers when we are done parsing
the input file.
2009-01-14 18:48:44 -08:00
Larry Doolittle c6336d621e Allow building with gcc-4.4
With this small patch, building succeeds with Debian's current gcc-snapshot,
gcc (Debian 20090107-1) 4.4.0 20090107 (experimental) [trunk revision 143170]

That build shows no regressions in the test suite.  The patch does not
break building, or show test suite regressions, with gcc-4.3.

That new gcc version still emits a pile of new and arguably bogus warnings
 "dereferencing pointer '<anonymous>' does break strict-aliasing rules" for
   elaborate.cc:3422
   StringHeap.h:31
   vvp/vvp_net.h:687  (really vvp/vvp_net.h:825)
2009-01-14 18:47:06 -08:00
Cary R fb6e1c202a Update some copyright dates.
Update tgt-stub to have a 2009 copyright and a few individual files.
2009-01-14 18:45:40 -08:00
Cary R 2707a68d1b Fix more memory leaks in vvp and one in ivlpp.
This patch fixes some more memory leaks in vvp. Mostly related
to UDP compilation and one in find_scope() that was found when
testing the VPI code. The leak in ivlpp was that the define
temporary buffer not being freed when the lexor was finished.
2009-01-14 18:40:54 -08:00
Stephen Williams ea954a7ccc Merge branch 'master' of ssh://[email protected]/~steve-icarus/git/verilog 2009-01-13 17:46:49 -08:00
Stephen Williams b1aa4496ec Stub no longer references ivl_nexus_name.
The ivl_nexus_name function is deprecated.
2009-01-13 17:45:36 -08:00
Cary R c2605a5c9b Fix memory leaks in vvp and change vvp T_STRING token to be new based.
This patch fixes a bunch of memory leaks in vvp and converts the
T_STRING lexical token to be new based. There are still two
known leaks that I need to find a way to fix and likely some
unknown leaks that still need to be found and fixed.
2009-01-13 10:53:23 -08:00
Stephen Williams 8ca3ea2e83 Better handle right shift of unsized expressions.
When doing right shift of unsized expressions, pad the left operand
so that the right shift does not lose. This better accounts for the
lossless expectations of unsized arguments.
2009-01-12 19:19:00 -08:00
Larry Doolittle 5b9857fe76 Refactor two NetPins related methods
Seemingly does nothing, just refactors to create two new methods:
   bool NetPins::is_linked(void)
   void NetNet::initialize_value_and_dir(verinum::V init_value, Link::DIR dir)
and rearranges netlist.h.

This patch causes no regression in the testsuite.
It smooths the way for any attempt to address pr2023076.
2009-01-12 18:21:06 -08:00
Sreeraj.R bd5c48eccd Added gsystem-verilog gen flag and 4 additional keywords
For future system-verilog additions
2009-01-10 11:05:48 -08:00
Cary R 4f26c62207 Make the $fdisplay/$fwrite family use the string formatting.
This patch makes the $fdisplay() and $fwrite() family of task
use the string formatting code. It also adds a compiletf routine
for the tasks and a run time check that the FD or MCD is correct.
If not it fails instead of just dropping the output.

It also cleans up a couple of memory leaks and adds no argument
compiletf routines for the $monitoron/$monitoroff tasks.
2009-01-10 10:38:51 -08:00
Cary R edc4bc1923 Add the $abstime() system function from VASM-2.3.
This patch adds the $abstime() system function from VAM-2.3.
It returns the current time as a real value scaled to seconds.
2009-01-09 17:26:52 -08:00
Cary R 5cf7e26acf Finish real modulus in verireal.
Verireal had hooks for this, but had an assert(0). This patch
replaces the assert(0) with assert(gn_icarus_misc_flag) and
then used fmod() to calculate the modulus. It is the callers
responsibility to verify and report a message to the user
if the current state should not support real modulus.
2009-01-09 17:21:50 -08:00
Cary R cba8b42580 Make a plain $stime print in 10 digits (32 bits).
This patch makes $stime a unique call in display and returns
the lower 32 bits in a 10 digit field when it is called.
2009-01-09 16:58:13 -08:00
Cary R 5d7f8c9706 Update copyright in files changed in 2009
This patch updates the copyright notice in the files that
were modified in 2009. It also updates the normal programs
and the vvp target.
2009-01-08 20:03:34 -08:00
Cary R f993e78185 Make eval_tree mixed case div/mod work.
This patch makes constant mixed case division or modulus
optimize correctly. The modulus is only done if the
gn_icarus_misc_flag is set.
2009-01-08 19:56:28 -08:00
Cary R f2f7933708 Make lexical token STRING new based.
The STRING lexical token was malloc based, but then was passed
to routines that are expecting a new based result. This patch
standardizes on a new/delete based approach.
2009-01-08 19:40:50 -08:00
Cary R 7ccc9d4484 Fix some valgrind warnings and display a real parameter as a real.
This patch fixes some technically benign problems found by valgrind,
but we may as well give the values a default to make sure things
work correctly. I believe that the default I choose is the
appropriate value for the context.

The other problem is that real valued (local)parameters should be
printed as a real value like a real variable, etc. Trying to
do this as a decimal with the string formatting was causing a
memory problem. I could have fixed the routine to handle this,
but the better solution was to just display things the right way.
2009-01-08 19:34:10 -08:00
Stephen Williams a2aff77ca2 Avoid creating Nexus objects until they are really needed.
By not creating Nexus objects until necessary, we avoid creating a
lot of spurious objects. In fact, it is true that almost every
link that is created and connected to another link will create a
spurious Nexus object without this patch.
2009-01-07 22:07:08 -08:00
Cary R 2353f91693 Make the CREATE_VERSION script create the correct file.
The version tag is now stored in the version_tag.h file
and is then copied along with the VERSION into the master
version.h file by the Makefile.
2009-01-06 20:48:54 -08:00
Nick Gasson 50f11390b2 Fix VHDL value of undriven net
This ensures an undriven net has the correct value in
the generated VHDL (either '1', '0', or 'Z').

This is a fix for pr2489116.
2009-01-06 20:36:33 -08:00
Nick Gasson 02b58f6ae8 Remove some redundant code from draw_synthesisable_wait
The default draw_wait now produces code for FFs with sync
waits that should synthesise OK.
2009-01-06 20:33:34 -08:00
Nick Gasson 6047eab005 Try to generate VHDL sensitivity lists whereever possible
This patch generates VHDL sensitivity lists for sequential
as well as combinatorial processes which do not contain
a wait statement. Otherwise it falls back on the original
wait-on/until behaviour.

This should make the generated VHDL more acceptable to
synthesisers.
2009-01-06 20:33:21 -08:00
Nick Gasson 19720a0f9d Prefer sensitivity list for VHDL combinatorial processes
This patch generates a sensitivity list for combinatorial
VHDL processes if they don't contain a wait statement, and
a wait-on statement if they do contain another wait statement.

This should help synthesisers correctly identifier
level-sensitive latches.
2009-01-06 20:33:08 -08:00
Nick Gasson a0489e9208 Generate more idiomatic VHDL for some Verilog templates
In particular this improves the code generated for flip-flops
so the output can be synthesised with certain tools (e.g. Synopsis).

See the comments above draw_synthesisable_wait for more details.
2009-01-06 20:32:54 -08:00
Cary R 80e596b212 Add leading 0 support to $swrite/$sformat and $display uses this code.
This patch does a number of things.

It adds file and line number information to the strobe_cb_info
structure. This allows the $swrite and $sformat calls to reference
their location in warning/error messages.

Their compiletf and calltf routines also display file and line
number information in messages.

The $display routine was converted to use the string formatting
routine. This can be reverted by defining USE_OLD_DISPLAY. The
old code will be removed once there has been more testing.

A number of bugs were fixed that were discovered with the
$display code.

The output of some conversions, variables and system functions
were changed to match the original display code or to better
match expectation.

Leading zero support was added to the %b/%b, %o/%O, %h/%H, %x/%X,
%c/%C and %d/%D. The floating point conversions already supported
adding a leading zero.

This is the start of converting all the various display tasks to use
the string formatting code and a cleanup/update of the sys_display.c
file in general.
2009-01-06 20:23:17 -08:00
Cary R 24f2b08d08 Add verion_tag.h to the .gitignore file 2009-01-06 20:19:30 -08:00
Stephen Williams 90a4ddebba Keep source code version information in version files.
Rather then spread VERSION= defines throughout all the makefiles, put
the base version in version_base.in. Use that to generate a version.h
that includes the base version as well as the detailed version.
2009-01-05 21:43:21 -08:00
Stephen Williams eaea529c28 Delay statement times are 64bit.
In certain special cases, the compiler did not properly work with
long64 while handling delay statement times.
2009-01-05 20:22:54 -08:00
Stephen Williams 707a3ebe27 Handle ternary expressions with mixed argument types.
If the true and false alternatives are mixed types, then vectored
arguments are treated as if in a self-determined context then cast
to REAL.
2009-01-05 19:44:52 -08:00
Cary R 8eb7e4b3d4 Set real nets with no driver to 0.0.
In VAMS 2.3 real nets with no driver are defined to have a value of 0.0.
Setting them to High-Z was crashing the run time.
2009-01-02 20:56:30 -08:00
Michael Strelnikov d56bf3a5eb Added type setting of "lval" unary expressions (fix for 2459681)
Unary expressions used in left side should
   have type other IVL_VT_NO_TYPE.
   This patch solves mem[~indx] = 1'b1;
2009-01-02 20:51:12 -08:00
Stephen Williams 0b3bc81b76 Remove .cvsignore files.
We are in git now, get rid of this CVS cruft.
2009-01-02 16:06:19 -08:00
Stephen Williams b45834f074 Handle part selects with bad (xz) bits.
Part selects need to be fully defined. If not, then the resulting
expression is 'bx no matter what. The same for bit selects, when
the bit select expression is constant.
2009-01-01 16:20:41 -08:00
Stephen Williams ea938b7907 Revert "Enable -Wshadow by default"
This reverts commit 31d67fcd3e.
The concensus has been that this causes too many build problems in
the general case and what is needed instead is a way to turn on the
extra warnings for developers only.
2009-01-01 08:33:26 -08:00
Cary R f1b0a77e0f In the MinGW iverilog-vpi driver use $CFLAGS instead of CXXFLAGS.
CFLAGS has the appropriate -W flags defined while CXXFLAGS is
just the default. The script iverilog-vpi uses CXXFLAGS because
it is defined in the Makefile to have the -W flags. This
directory is C based so does not define CXXFLAGS.
2009-01-01 08:29:03 -08:00
Michael Strelnikov 1fe6c1941b Improved $display task
Added a proper zero padding to formats like %04d
2009-01-01 08:05:24 -08:00
Cary R 5b840bcd96 Add ivl_lpm_trigger to ivl.def
This is needed to allow Cygwin and MinGW to compile.
2008-12-30 09:12:22 -08:00
Cary R 24f98905aa Support a delay without a statement in nex_input().
Add code to check for a plain delay statement (just a delay).
When one is found generate a null statement and do not add it
(the null statement) to result.
2008-12-29 16:32:33 -08:00
Martin Whitaker 21f33085f0 Fix for pr2123173.
Functions that appear in continuous assignment expressions and that
have hidden dependencies or side effects need to be re-evaluated
whenever any input to the expression changes. This patch adds support
in the compiler and vvp runtime to enable this. This is currently
activated for any system function call that has no arguments. The
user may also force it to be used for any user function by passing
the option -gstrict-ca-eval to the compiler driver.

This patch also removes the -dautomatic option which was used for
gaining confidence in the code that supports automatic tasks and
functions. It is believed that the testsuite provides reasonable
fault coverage, and further tests can be added if bugs are found.
2008-12-29 16:09:33 -08:00
Larry Doolittle 31d67fcd3e Enable -Wshadow by default
The code base is almost shadow-free now, so this won't add much noise to the compiles.
Problems I know about:
 lxt{,2}_write.c:  patch sent upstream
 cflexor.c:  exposes gray area of name space boundary
2008-12-29 16:03:16 -08:00
Larry Doolittle b76c14e452 Shadow reduction part 6
Finish cleaning up shadowed variables, flagged by turning on -Wshadow.
No intended change in functionality.  Patch looks right, and is tested
to compile and run on my machine.  No regressions in the test suite.

This is the end of the simple, coordination-free patches.
The remaining shadows are special cases that will need extra attention.
2008-12-29 16:00:03 -08:00
Stephen Williams adbaaa9352 Add some more human readable strings for operand codes. 2008-12-19 17:17:39 -08:00
Stephen Williams 17c2d304b9 Merge branch 'master' into elaborate_pexor_rework 2008-12-19 16:34:11 -08:00
Stephen Williams 33044876dd Handle errors in parameter handling.
Don't crash if the user typed in an invalid parameter.
2008-12-19 16:32:44 -08:00
Cary R 9da9ed243a Make parameter up index use the real value not a pointer to the value.
When the parameter up index was being reworked someone mistakenly
used the pointer value instead of the actual value in the MSB/LSB
comparison. This obviously could give incorrect results.
2008-12-19 15:17:36 -08:00
Stephen Williams d1ce6d2535 Fix the signed-ness calculations of +- in parameter expressions.
This fixes up the elaboration of binary expressions found in
parameter expressions. Parameter expressions are special because
they elaborate early, before all the other parameters are necessarily
completed.
2008-12-18 21:33:31 -08:00
Stephen Williams cadfb2e4eb Create .gitignore file with the contents of info/exclude.
Having our users manually edit their .git/info/exclude is
tedious and this information belongs in the code repository.
So this patch creates a file .gitignore that contains the
appropriate information to exclude all the normal files
that should never be tracked in git..
2008-12-18 18:51:31 -08:00
Cary R 2288694217 Fix MinGW compilation of driver-vpi.
The Makefile.in was incorrectly changed and this broke compilation
on MinGW.  This patch basically reverts the previous changes and
uses a few more $(srcdir) paths.
2008-12-18 18:37:36 -08:00
Larry Doolittle 9ff319b39b Shadow reduction part 5
Continue cleaning up shadowed variables, flagged by turning on -Wshadow.
No intended change in functionality.  Patch looks right, and is tested
to compile and run on my machine.  No regressions in test suite.

This patch set covers C code, with the notable exception of
vpi/lxt_write{,2}.c.
2008-12-18 16:42:55 -08:00
Cary R a3a3485c85 Make casex/z conditional x/z aware.
Previously only the X/Z state of the label expression was
considered to be a don't care. This patch adds that
functionality to the conditional expression as well.
2008-12-18 16:32:08 -08:00
Cary R 09c7578d1e Clean up Makefile.in make check targets.
Some of the Makefile.in files were missing a check target.
This patch adds them where needed.
2008-12-16 19:44:29 -08:00
Cary R 26ee14c7dd Clean up Makefile.in files.
This patch cleans up the Makefile.in files.

We only need to delete config.log in the lower directories.

We reference the *.in files at $(srcdir)/

We need to make distclean for the tgt-(fpga,pal,verilog) directories.
This is to cleanup the Makefile.

Add some missing "rm -r f dep"
2008-12-16 19:42:53 -08:00
Cary R 45d46da443 Move driver/main.d to dep directory.
The driver/main.o target was missing the command to move the
depend file to the dep directory.
2008-12-16 19:41:18 -08:00
Cary R 10490029e3 Fix datarootdir and Makefile in tgt-fpga
I know we are not currently using this, but configure is building
the Makefile so it would be best if it didn't complain. This patch
adds a datarootdir target and fixes the Makefile and distclean
targets.
2008-12-16 19:40:21 -08:00
Cary R 2ce2fab1d6 cadpli.c needs to include config.h to get one of the DL defs.
cadpli will not compile correctly unless it knows which DL
interface to use. This patch makes it include config.h to get
this definition. It also cleans up the Makefile.in.
2008-12-16 19:38:38 -08:00
Cary R eea7693539 VHDL: Add initial support for non-constant casex/z label expressions.
This patch adds support for concatenation/repetition, signals and
part and bit select of signals for casez/x expression labels.
These along with the original constants can be mixed in almost any
order. Only constant selects are currently supported.
2008-12-16 19:20:04 -08:00
Cary R 8cd50c163b Make the procedural shifts work with undefined shift values.
This patch adds code to check for an undefined shift value in
the procedural opcodes. When an undefined value is found 'bx
is returned.
2008-12-16 09:11:37 -08:00
Nick Gasson 4f4191ecdd Add VHDL flag to specify maximum module depth
Specifying -pdepth=N only outputs entities that correspond
to Verilog modules found at depth < N in the hierarchy.

Setting -pdepth=0 (the default) outputs all entities.

This is for feature request 2391457
2008-12-16 09:05:33 -08:00
Stephen Williams 8e8b36ee36 Add automatic dependencies to subdirs that lack them.
The driver/ and driver-vpi/ directories lacked the -MD method of
automatic dependencies. Add it to them.
2008-12-16 09:05:17 -08:00
Stephen Williams 6b45f8899e Flatten the tree of configure scripts.
Collapse all the configure checks to a single configure script in
the root of the source tree. This makes the configure process run
a lot faster, expecially on Windows systems that are slower in general.
2008-12-13 21:42:55 -08:00
Cary R 7796a839aa Rewrite the check for windows and MinGW.
It is recommended that AC_CYGWIN not be used and under MinGW
the previous test was complaining about multiple calls to
AC_CANONICAL_HOST. The new test performs the same function
and also displays the MinGW status if we are compiling on
windows.

Also removed a AX_CCP_IDENT call in the vpi directory and
tgt-null is built by the top configure so there is no need
to try to run configure in that directory.
2008-12-12 21:10:50 -08:00
Cary R 65d5620086 Fix MinGW shared, PIC and rdynamic flags.
A native MinGW compile was not setting these to the correct
value. This patch makes them match what Cygwin uses. Adding
the -Wl,--enable-auto-image-base should make vvp load
slightly faster since it loads multiple DLL files.
2008-12-12 21:09:38 -08:00
Cary R f1e2f373ae Fix MinGW make distclean and add <file>.in dependencies.
This patch fixes the crash in MinGW make distclean. The problem
was that vpi/ and driver-vpi/ were being called twice and the
MinGW make was failing on the second call since the Makefile
was already removed.

Add a dependency on config.h and _pli_types.h in the make all
target. It is likely that only _pli_types.h was needed, but
this makes it clear that they need to be rebuilt if the .in
files change.

The lower directories that depend on the top level config.status
now have a target to rebuild the local Makefile file it the
corresponding Makefile.in changes.
2008-12-12 20:58:50 -08:00
Nick Gasson b6c4560fdc Avoid assertion failure in VHDL translate_select
This avoids triggering an assertion failure by trying to
select bits from a std_logic (which isn't a vector type).
2008-12-12 20:52:50 -08:00
Stephen Williams f7ee3fe173 Fix elaboration of part-select ports.
Verilog-1995 allows ports to be part selects of signals in the module.
Handle those cases with part select or TranVP as needed.
2008-12-11 21:35:28 -08:00
Stephen Williams dbe45159ab Merge branch 'master' into verilog-ams 2008-12-10 19:45:35 -08:00
Cary R f3c2916e1a Make a copy of the local include directory so that it doesn't get lost.
Some compilers when optimizing can overwrite the path before it is
read so make a copy of the local include directory and free it when
we are done.
2008-12-10 19:17:48 -08:00
Cary R 87972adb04 Check system() return when getting version information.
We were not checking the return of the two system calls used
to get the version information from ivlpp and ivl. This patch
adds checks and prints an appropriate message if they fail.
2008-12-10 19:12:55 -08:00
Stephen Williams d4c62309eb Treat assignment into a task port exactly like blocking assignment.
Reuse the code that the blocking assignment uses. This fixes makes
the task port input assignment work better.
2008-12-09 21:52:15 -08:00
Cary R e8b4c5be85 Check for too few buf/not port expressions.
This patch adds code to check that buf and not primitives have
at least two port expressions. An error message is printed for
this case.
2008-12-08 21:04:30 -08:00
Nick Gasson 651d208451 Remove some uneccessary zero-time waits from VHDL outputs
This patch optimises away straight line sequences like:

wait for 0 ns;
wait for X ns;

to:

wait for X ns;

This tidies up the output a bit.

It also has the effect of removing all code from initial
processes where the assignments have been extracted as
VHDL signal intialisers. (c.f. pr2391337)
2008-12-07 16:53:47 -08:00
Nick Gasson 712e08ebe8 Emit useful error message for pr2362211
This prints out an error message rather than crashing out with
an assertion failure when a function assigns to a non-local
variable, which cannot be done in VHDL.
2008-12-07 16:50:07 -08:00
Nick Gasson d689c93879 Rework VHDL assignment statement generation
This changes the assignment statement generator so that
each VHDL declaration "knows" which type of assignment
statement can/should be used on (i.e. signals must be
assigned with <=). This will help us catch cases when
we try to use, for example, := with signals. This occurs
in pr2362211 where we try to assign to a signal within
a function (where only := can be used).
2008-12-07 16:49:57 -08:00
Nick Gasson c06c49c992 Fix assignment of constant to input
If a module's input was connected to a nexus that contained
a constant driver. That constant would be incorrectly generated
as an assignment to the input *inside* the child module (instead
of an assignment inside the instantiating module).
2008-12-07 16:45:05 -08:00
Stephen Williams bcaf7355ca Remove most of the lingering CVS droppings.
Remove the #ident and $Log$ strings from all the header files and
almost all of the C/C++ source files. I think it is better to get
this done all at once, then to wait for each of the files to be
touched and edited in unrelated patches.
2008-12-05 21:48:28 -08:00
Larry Doolittle 4948875230 Allow building with gcc-4.4
With this small patch, building succeeds with Debian's current gcc-snapshot,
gcc (Debian 20081130-1) 4.4.0 20081130 (experimental) [trunk revision 142292]

That gcc also warns about the remaining #idents in
  vvp/concat.cc
  vvp/dff.h

The resulting build shows some regressions in the test suite, that
I am still investigating.  The patch does not break building, or show
test suite regressions, with gcc-4.3.
2008-12-05 20:48:25 -08:00
Cary R 0abefc61fb Fix out of range indexed part selects and negative verinum width calc.
This patch fixes fully out of range constant indexed part selects
to just return 'bx. It also adds support for constant undefined
base values which also just return 'bx.

A bug in the bit width calculation when building an unsized, signed
negative integer value was also fixed (-3 needs 3 bits not 2, etc.)
2008-12-01 21:11:33 -08:00
Cary R a84682e07d Add two missing function definitions.
This patch adds the function definitions for ivl_expr_branch and
ivl_expr_nature to the ivl.def file. This is needed to get Cygwin
and MinGW to compile correctly.
2008-12-01 21:06:18 -08:00
Stephen Williams d272a93a40 Case statements need their expresions probed.
Probe the widths of the case statement expressions. The expressions
are self-determined in that context, but the probe is needed to
setup the expression types.
2008-11-29 20:38:40 -08:00
Nick Gasson 1cc5586c4d Add debugging output to VHDL target
Prints progress when -pdebug=1 specified.

Adds a new debug_msg function to print progress messages.
2008-11-29 20:16:09 -08:00
Stephen Williams d5f1d0e9eb Seperate islands from tran/switch islands
Tran islands are a kinds of island, so seperate the tran handling
from the core island concept. This will allow for creating new
kinds of islands. (Think analog.)
2008-11-29 10:05:31 -08:00
Stephen Williams fc00bd9a5b probe expression widths of analog contribution expressions.
The expressions of a contribution statement are real valued by
definition, but we need to do the width probing anyhow in order
to resolve types and the widths of subexpressions.
2008-11-28 18:40:47 -08:00
Stephen Williams 17b937740a Merge branch 'master' into verilog-ams 2008-11-28 16:29:50 -08:00
Stephen Williams 82143edf2c Rework shift and power PExpr nodes for their special needs.
The power (**) and shift operators are different from other binary
operators because their expression width calculations rely only on
their left operand, with their right operand self-determined. Get
the handling of these operators out of the PEBinary base class to
prevent confusion.
2008-11-28 14:40:25 -08:00
Stephen Williams 69726a56b0 More self-determined expressions need width probed.
Find and fix some more expressions that are self-determined, that
nevertheless need their widths probled.
2008-11-28 11:24:42 -08:00
Cary R 2ce9841354 A power needs to use the signed (real pow) if either argument is signed.
The power operator is different in that it uses the signed version
if either of it's arguments are signed. This patch fixes the code
generator to do this correctly.
2008-11-28 10:44:31 -08:00
Cary R 6b76f76a3a Add the procedural signed power function.
This patch adds the procedural power function %pow/s for signed
values. This has bit based inputs and outputs, but uses the double
pow() function to calculate the value.
2008-11-28 10:33:45 -08:00
Stephen Williams 38abe7185d Fix calculation of verinum==verinum
This test was way to picky about the widths of the arguments. In real
tests, the arguments may have different widths. This especially matter
when comparing unsized values.
2008-11-27 20:14:27 -08:00
Stephen Williams bd754b24f4 Support direct nesting of conditional generate schemes.
Verilog generate schemes support a special case where conditional
generate schemes that contain only a nested conditional generate
scheme do not create a new scope. Instead, it relies on the nested
generate scheme to generate the scope.
2008-11-27 19:45:22 -08:00
Stephen Williams 90bfebd578 During test_width is not the time to assert on no_type
unary expressions that have problems should not assert in the
test_width method. Instead, let the error propagate back and be
handled during expression elaboration. This found a few places
where expression widths/types weren't probed before elaboration.
2008-11-26 15:37:38 -08:00
Nick Gasson 4263f791f6 Fix part select of width-1 vector
Signals of width 1 are declared in VHDL as std_logic, as this
is the usual way to represent them. Unfortunately, we cannot
distinguish between

reg [0:0] a;

and

reg a;

This patch avoids trying to slice a std_logic so a[0] is equivalent to a.
2008-11-26 13:14:27 -08:00
Stephen Williams 21552447a1 The iverilog-vpi script depends on the Makefile
Building the iverilog-vpi script involves editing commands in the
Makefile, so it makes sense for iverilog-vpi to depend on it.
2008-11-25 18:55:36 -08:00
Cary R 4c28af4c36 Update Makefile.in to have current version by default.
This patch removes the CVS ident information from the Makefile.in
files it also puts in the current version 0.9.devel for the default
VERSION definition. This is normally passed down, but a local make
will use the value from the local Makefile. This will eventually be
replaced with a file based version to give us just one place to
reliably modify the version.
2008-11-25 16:42:32 -08:00
Stephen Williams 34eb3e55cd Merge branch 'master' of ssh://[email protected]/home/u/icarus/steve/git/verilog 2008-11-25 16:38:44 -08:00
Stephen Williams 5660e0ed8b Install header files in includedir/iverilog
Move the header files from includedir/verilog to .../iverilog
because the verilog name is a little too generic. The iverilog-vpi
command should handle the changes.
2008-11-25 16:38:09 -08:00
Cary R 8c4a080754 Put a version in the vvp file and have vvp verify compatibility.
This patch makes the code generator put the compiler version
information in the vvp output file. It also adds checks in vvp
to verify that this version is compatible with the run time.
I am assuming that a base release 0.9.0, etc. will have a
blank VERSION_TAG. Any change relative to the release will have
a VERSION_TAG.
2008-11-25 08:01:06 -08:00
Larry Doolittle fcd39fd0a1 Restore pristine builds
Commit 24827c4b42 broke
pristine builds.  Touch up CPPFLAGS so tgt-vvp/vvp.c
and tgt-vhdl/vhdl.c can find version.h when building
out-of-tree.
2008-11-24 22:07:51 -08:00
Stephen Williams 16e5197325 Branches are parts of islands.
Expose the island information for branches to the ivl_target API.
2008-11-24 22:00:33 -08:00
Stephen Williams 87177087c4 ivl_target.h access branch terminals
Fill in the functions to add branch terminals, and add code in the
stub to check that the terminals are present and reasonable.
2008-11-23 22:38:33 -08:00
Stephen Williams d8ec6fc42a Add functions for targets to scan disciplines.
The disciplines are, from the perspective of the ivl target, collected
into the design. Add functions for the target to scan the disciplines
in the design.

In the process, also clean up the handlng of design constants.
2008-11-23 21:29:54 -08:00
Stephen Williams 6185556ef5 Merge branch 'master' into verilog-ams 2008-11-23 08:24:34 -08:00
Stephen Williams 4de891d096 Support drawing some select expressions in place.
Select of signals is natural for evaluating in place, if possible.
Doing so can save instructions for certain expressions.
2008-11-22 21:17:05 -08:00
Stephen Williams 83a7497912 Lor takes advantave of STUFF_OK_47
It is ot uncommon for the arguments to logical or to leave stuff
in bit registers 4-7. Allow the lor itself to take advantage of
that to save some %mov instructions.
2008-11-22 10:45:15 -08:00
Stephen Williams bc8b97dbcd Pad expression in place
When padding expressions, pre-allocate the target space and calculate
the sub-expression directly into the target. Then pad from there. This
saves a move into the result space.
2008-11-21 21:12:40 -08:00
Stephen Williams f502d4c8ad Specify support off by default.
The specify support has some interesting bugs, and anyhow is rarely
used. Leave it OFF by default.
2008-11-20 21:01:33 -08:00
Cary R 45f2d68d33 Add verilog<suffix> to MinGW iverilog-vpi tool
When changing where the include files were located the MinGW
iverilog-vpi tool was missed.
2008-11-20 19:59:05 -08:00
Cary R 6f1887bf1c Remover @ident_support@ fro tgt-null/Makefile.in
This was missed in the previous patch.
2008-11-20 09:51:43 -08:00
Stephen Williams 27f4ba2e38 Remove the unused CVS ident support in the configure scripts. 2008-11-19 21:07:34 -08:00
Cary R 4fa2223832 Fix NULL and STUB -V output.
Fix the NULL and STUB target -V output to match the other targets.
2008-11-19 20:45:42 -08:00
Cary R e416fb6486 Add converter info to VHDL output.
This patch adds some converter information to the VHDL output.
2008-11-19 20:44:34 -08:00
Cary R 24827c4b42 Add a -V flag to the runtime and update the manual pages.
This patch adds a -V flag to the runtime to print version information.
It also updates the manual page to document this and makes some minor
changes to the iverilog an iverilog-vpi manual pages.
2008-11-19 20:40:30 -08:00
Cary R c9077bd0be For scheduled put values save the string and free it after the put.
Users expect that vpi_put_value() will keep a copy of the string
that is passed to it. This patch implements this buy copying the
string and then freeing it after the actual put_value call.
2008-11-19 20:21:03 -08:00
Stephen Williams a288b0180c Fix concatenations losing track of its repeat values.
In some cases, it was possible for the NetEConcat expression to
lose track of the repeat expression, causing the output result to
have a broken concatenation expression.

This also adds some internal checks that the concatenation widths
add up properly.
2008-11-19 13:28:50 -08:00
Cary R 5eaea58209 Update GNU address in -V output and add -V stub to VHDL target.
This patch updates the GNU address in the -V output, adds the
VERSION_TAG info to the tgt-vvp back end and adds the whole -V
hook to the tgt-vhdl back end.
2008-11-18 20:33:22 -08:00
Cary R cedbdb63fa VHDL make comment for temporaries unique.
Make the comment for local signals (temporaries) unique from
normal signals.
2008-11-18 20:28:28 -08:00
Cary R 3c4b9692a6 Pads and local signal file/line should be related to creation location.
When padding a signal or when creating a local signal the file and
line information should be related to where the new object was
created not the signal value it is being created from.

This patch modifies the NetE* pad_to_width() routines to take a
LineInfo object to set the location to the correct value.

It fixes some set_line() calls to use the correct location.

It fixes ports to not set the file/line information if it is
already defined. Doing this was causing the definition of
signals to become the instantiation instead of the real
module declaration.
2008-11-18 20:24:19 -08:00
Stephen Williams 1630c41d5f Merge branch 'master' of ssh://[email protected]/~steve-icarus/git/verilog 2008-11-18 20:10:43 -08:00
Stephen Williams 5e174f54ee Elaborate signals in generated named blocks.
Named blocks create scopes, and generated named blocks' scopes can
have signals declared in them. So the elaborate_sig for the generate
scheme needs to call the elaborate_sig for the processes as well as
the obvious gates and tasks/functions.
2008-11-18 20:10:10 -08:00
Stephen Williams 7ec86757c5 Elaborate concatenation expression put tested widths to use.
Concatenation expressions need to use the tested widths of its
argument expressions during elaboration.
2008-11-18 16:52:05 -08:00
Stephen Williams dafe61b0f9 Update for s20081118 snapshot 2008-11-18 15:37:42 -08:00
Nick Gasson 7529034c7a Fix incorrect temporary size with padding
Fix for pr2224949

The compiler generates a concatenation LPM to zero-pad ports when the
signal widths don't match up. However, when the VHDL generator generated
the input signals to this LPM it incorrectly sized them to be the width
of the result.
2008-11-18 15:00:00 -08:00
Cary R ec0e718151 VHDL: make casez support 'x' and handle a full don't care case.
The VHDL converter erroneously treated a casez and casex exactly
the same. In reality a casez compares a 'x' value (it is not a
don't care). It also adds support for a full don't care case by
just returning True for the condition.
2008-11-18 14:42:36 -08:00
Stephen Williams 35e0a98732 Improve error message about signal type conflict.
When the parser detects a signal type conflict, print a more useful
error message. In the process, be more careful with what line number
is actually attributed to the declaration.
2008-11-18 14:34:34 -08:00
Cary R 3190066013 Remove old real array word debug message.
This message appears to be left over from the original implementation
of real array words.
2008-11-18 13:28:08 -08:00
Cary R 95065819f1 Evaluate constant negated reductions.
This patch adds support for calculating the negated reductions
(~&, ~| and ~^) in the compiler when given a constant argument.
2008-11-17 19:55:41 -08:00
Cary R e191fcdd28 A non-negated reduction needs to change a 1'bz into a 1'bx.
In a procedural single bit non-negated reduction (&, | or ^)
we need to translate a 1'bz to a 1'bx. The easiest way to do
that is with two %inv opcodes. This patch modifies the code
generator to do this for this very special case.
2008-11-17 19:55:25 -08:00
Cary R a8a8d3ce5b Fix MinGW suffix configuration.
In the driver-vpi file we need to use g for the suffix replacement
so that both libraries get changed.

Also added an end line to the config.h.in file.
2008-11-17 19:45:21 -08:00
Stephen Williams 4bc90f7cfd Create support for the --enable-suffix configuration option.
This configure option causes the installed commands to have
a suffix string that makes them distinct from other versions
that also have a suffix string. This allows for multiple
installed versions of Icarus Verilog.

Also, move installed C/C++ header files into a subdirectory of
their own under the target include directory, to make clearer
the purpose and source of those files.
2008-11-17 07:22:46 -08:00
Stephen Williams e98f29e96f Merge branch 'master' into verilog-ams 2008-11-16 18:42:06 -08:00
Stephen Williams da85c4fe00 Give the branch access expression type some meat.
In the ivl_target API, the IVL_EX_BACCESS expression type gets some meat,
specifically references to the branch it accesses and the the nature to
be accessed on that branch.
2008-11-11 20:41:14 -08:00
Stephen Williams 35a8d42741 Merge implicit branches.
Implicit branches all really are the same branch, so be careful to not
create a new branch if it already exists.
2008-11-10 21:19:30 -08:00
Stephen Williams 00df651c5f Branch references all the way down to the stub generator.
This includes enough API to get the branch nexus bits and signals
and show them in the dump. This also includes creating the reference
ground for branch access functions that use the implicit ground.
2008-11-09 21:42:12 -08:00
Stephen Williams 25201954d3 Bring branches forward as far as the emit method and target_t. 2008-11-09 17:11:04 -08:00
Stephen Williams 0da27a2f45 Collect analog branches into islands.
Discipline islands all along were intended to carry collections of
analog branches, as well as the current switch modeling support.
2008-11-09 15:32:50 -08:00
Stephen Williams 988fc70368 Merge branch 'master' into verilog-ams 2008-11-07 20:14:43 -08:00
Stephen Williams 4879b98b3a Merge branch 'master' into verilog-ams 2008-11-07 19:49:52 -08:00
Stephen Williams 13aaaab783 Bring analog contribution statements to the ivl_target API.
Add support for analog processes with analog contributation statements
all the way down to the ivl_target code generator API.
2008-11-06 21:31:34 -08:00
Stephen Williams 0d88d3a798 Enforce that l-value of contribution is an access function. 2008-11-03 21:58:16 -08:00
Stephen Williams eb240ddb73 Bring discipline natures all the way to the ivl_target API.
The natures of disciplines were already available, this just brings
the information forward to the ivl_target.h API and exposes them via
access functions.
2008-11-03 21:10:10 -08:00
Stephen Williams c73199942b Proper test_width implementation for nature access functions.
Nature access functions have fixed output width and type. Implement
the test_width handling for access functions to reflect this.
2008-11-02 21:46:27 -08:00
382 changed files with 25554 additions and 18911 deletions
-27
View File
@@ -1,27 +0,0 @@
lexor_keyword.cc
parse.h
parse.cc
parse.cc.output
parse.output
syn-rules.cc
syn-rules.cc.output
syn-rules.output
lexor.cc
iverilog-vpi
iverilog-vpi.pdf
iverilog-vpi.ps
ivl
ivl.exp
dep
configure
Makefile
check
check.cc
check.vvp
config.status
config.log
config.cache
autom4te.cache
config.h
_pli_types.h
dosify
+82
View File
@@ -0,0 +1,82 @@
# Lines that start with '#' are comments.
#
# This file is for the development branch of Icarus Verilog.
#
# The following files will be ignored by git.
# Object files and libraries
*.[oa]
# From autoconf
configure
config.log
config.status
Makefile
/_pli_types.h
config.h
/tgt-vvp/vvp_config.h
/tgt-vhdl/vhdl_config.h
/vpi/vpi_config.h
stamp-*-h
/version.h
/version_tag.h
# Directories
autom4te.cache
dep
# Compiler back end and library files
/tgt-vvp/*.conf
*.tgt
*.vpi
/cadpli/cadpli.vpl
# lex, yacc and gperf output
/driver/cflexor.c
/driver/cfparse.c
/driver/cfparse.h
/driver/cfparse.output
/ivlpp/lexor.c
/lexor.cc
/lexor_keyword.cc
/parse.cc
/parse.h
/parse.output
/syn-rules.cc
/syn-rules.output
/vpi/sdf_lexor.c
/vpi/sdf_parse.c
/vpi/sdf_parse.h
/vpi/sdf_parse.output
/vpi/sys_readmem_lex.c
/vvp/lexor.cc
/vvp/parse.cc
/vvp/parse.h
/vvp/parse.output
# Program created files
/vvp/tables.cc
/iverilog-vpi.man
/driver-vpi/res.rc
/driver/iverilog.man
/vvp/vvp.man
# The executables.
*.exe
/driver/iverilog
/iverilog-vpi
/ivl
/ivlpp/ivlpp
/vvp/vvp
/ivl.exp
/vvp/vvp.exp
# Check output
/check.vvp
-37
View File
@@ -16,9 +16,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: Attrib.cc,v 1.6 2004/02/20 18:53:33 steve Exp $"
#endif
# include "config.h"
@@ -102,37 +99,3 @@ const verinum& Attrib::attr_value(unsigned idx) const
assert(idx < nlist_);
return list_[idx].val;
}
/*
* $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.
*
* Revision 1.4 2002/05/26 01:39:02 steve
* Carry Verilog 2001 attributes with processes,
* all the way through to the ivl_target API.
*
* Divide signal reference counts between rval
* and lval references.
*
* Revision 1.3 2002/05/23 03:08:50 steve
* Add language support for Verilog-2001 attribute
* syntax. Hook this support into existing $attribute
* handling, and add number and void value types.
*
* Add to the ivl_target API new functions for access
* of complex attributes attached to gates.
*
* Revision 1.2 2001/07/25 03:10:48 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
*
* Revision 1.1 2000/12/04 17:37:03 steve
* Add Attrib class for holding NetObj attributes.
*
*/
+2 -32
View File
@@ -1,7 +1,7 @@
#ifndef __Attrib_H
#define __Attrib_H
/*
* Copyright (c) 2000 Stephen Williams ([email protected])
* Copyright (c) 2000-2009 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
@@ -18,9 +18,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: Attrib.h,v 1.5 2004/02/20 18:53:33 steve Exp $"
#endif
# include "StringHeap.h"
# include "verinum.h"
@@ -33,7 +30,7 @@ class Attrib {
public:
Attrib();
~Attrib();
virtual ~Attrib();
const verinum&attribute(perm_string key) const;
void attribute(perm_string key, const verinum&value);
@@ -60,31 +57,4 @@ class Attrib {
Attrib& operator= (const 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.
*
* Revision 1.3 2002/05/26 01:39:02 steve
* Carry Verilog 2001 attributes with processes,
* all the way through to the ivl_target API.
*
* Divide signal reference counts between rval
* and lval references.
*
* Revision 1.2 2002/05/23 03:08:50 steve
* Add language support for Verilog-2001 attribute
* syntax. Hook this support into existing $attribute
* handling, and add number and void value types.
*
* Add to the ivl_target API new functions for access
* of complex attributes attached to gates.
*
* Revision 1.1 2000/12/04 17:37:03 steve
* Add Attrib class for holding NetObj attributes.
*
*/
#endif
-55
View File
@@ -16,9 +16,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: HName.cc,v 1.8 2007/06/02 03:42:12 steve Exp $"
#endif
# include "config.h"
# include "HName.h"
@@ -61,25 +58,6 @@ hname_t& hname_t::operator = (const hname_t&that)
return *this;
}
hname_t::~hname_t()
{
}
perm_string hname_t::peek_name(void) const
{
return name_;
}
bool hname_t::has_number() const
{
return number_ != INT_MIN;
}
int hname_t::peek_number() const
{
return number_;
}
bool operator < (const hname_t&l, const hname_t&r)
{
int cmp = strcmp(l.peek_name(), r.peek_name());
@@ -103,9 +81,6 @@ bool operator == (const hname_t&l, const hname_t&r)
return false;
}
bool operator != (const hname_t&l, const hname_t&r)
{ return ! (l==r); }
ostream& operator<< (ostream&out, const hname_t&that)
{
if (that.peek_name() == 0) {
@@ -120,33 +95,3 @@ ostream& operator<< (ostream&out, const hname_t&that)
return out;
}
/*
* $Log: HName.cc,v $
* Revision 1.8 2007/06/02 03:42:12 steve
* Properly evaluate scope path expressions.
*
* Revision 1.7 2007/05/16 19:12:33 steve
* Fix hname_t use of space for 1 perm_string.
*
* Revision 1.6 2007/04/26 03:06:21 steve
* Rework hname_t to use perm_strings.
*
* Revision 1.5 2002/11/02 03:27:52 steve
* Allow named events to be referenced by
* hierarchical names.
*
* Revision 1.4 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.3 2002/01/05 04:36:06 steve
* include malloc.h only when available.
*
* Revision 1.2 2001/12/18 04:52:45 steve
* Include config.h for namespace declaration.
*
* Revision 1.1 2001/12/03 04:47:14 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
*
*/
+23 -1
View File
@@ -22,6 +22,7 @@
# include <iostream>
# include <list>
# include "StringHeap.h"
# include <climits>
#ifdef __GNUC__
#if __GNUC__ > 2
using namespace std;
@@ -63,11 +64,32 @@ class hname_t {
private: // not implemented
};
inline hname_t::~hname_t()
{
}
inline perm_string hname_t::peek_name(void) const
{
return name_;
}
inline int hname_t::peek_number() const
{
return number_;
}
inline bool hname_t::has_number() const
{
return number_ != INT_MIN;
}
extern bool operator < (const hname_t&, const hname_t&);
extern bool operator == (const hname_t&, const hname_t&);
extern bool operator != (const hname_t&, const hname_t&);
extern ostream& operator<< (ostream&, const hname_t&);
inline bool operator != (const hname_t&l, const hname_t&r)
{ return ! (l == r); }
inline ostream& operator<< (ostream&out, const list<hname_t>&ll)
{
list<hname_t>::const_iterator cur = ll.begin();
+2 -2
View File
@@ -1,7 +1,7 @@
#ifndef __LineInfo_H
#define __LineInfo_H
/*
* Copyright (c) 1999 Stephen Williams ([email protected])
* Copyright (c) 1999-2009 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
@@ -36,7 +36,7 @@ using namespace std;
class LineInfo {
public:
LineInfo();
~LineInfo();
virtual ~LineInfo();
// Get a fully formatted file/lineno
string get_fileline() const;
+147 -123
View File
@@ -18,46 +18,53 @@
#
SHELL = /bin/sh
# Normally, the "make" will build all the files only by dependencies.
# The MODE, however, can control your rebuild intentions. The proper way
# to use the MODE is on the make command like, this this:
# The interesting make targets are:
#
# make MODE=XXXX all
# make version
# Force the version_tag.h file to be rebuilt. Otherwise, it will only
# be built if it is missing.
#
# The possible MODE= values are:
# make all
# make install
#
# regular
# Build as normal
#
# full
# Do some extra builds. in particular:
# Build version.h again, even if it already exists.
#
MODE=regular
# This version string is only used in the version message printed
# 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.9.devel
# The "suffix" is used as an installation suffix. It modifies certain
# key install paths/files such that a build and install of Icarus Verilog
# with the same $(prefix) but a different $(suffix) will not interfere.
# The normal configuratin leaves suffix empty
suffix = @install_suffix@
prefix = @prefix@
exec_prefix = @exec_prefix@
srcdir = @srcdir@
datarootdir = @datarootdir@
SUBDIRS = @subdirs@
SUBDIRS = ivlpp vvp vpi libveriuser cadpli tgt-null tgt-stub tgt-vvp \
tgt-vhdl driver
# Only run distclean for these directories.
NOTUSED = tgt-fpga tgt-pal tgt-verilog
VPATH = $(srcdir)
ifeq (@MINGW32@,yes)
SUBDIRS += driver-vpi
else
NOTUSED += driver-vpi
endif
# To get the version headers to build correctly we only want to look
# for C++ files in the source directory. All other files will require
# an explicit $(srcdir).
vpath %.cc $(srcdir)
bindir = @bindir@
libdir = @libdir@
includedir = @includedir@
# This is actually the directory where we install our own header files.
# It is a little different from the generic includedir.
includedir = @includedir@/iverilog$(suffix)
mandir = @mandir@
dllib=@DLLIB@
CC = @CC@
HOSTCC = @CC@
CXX = @CXX@
INSTALL = @INSTALL@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
@@ -69,51 +76,64 @@ MAN = @MAN@
PS2PDF = @PS2PDF@
GIT = @GIT@
CPPFLAGS = @ident_support@ @DEFS@ -I. -I$(srcdir) -DVERSION='"$(VERSION)"' @CPPFLAGS@
CPPFLAGS = @DEFS@ -I. -I$(srcdir) @CPPFLAGS@
CXXFLAGS = -Wall @CXXFLAGS@
PICFLAGS = @PICFLAG@
LDFLAGS = @rdynamic@ @LDFLAGS@
all: dep version.h ivl@EXEEXT@
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) VERSION=$(VERSION) $@); done
for dir in ivlpp ; \
do (cd $$dir ; $(MAKE) VERSION=$(VERSION) $@); done
cd driver ; $(MAKE) VERSION=$(VERSION) $@
all: dep config.h _pli_types.h version_tag.h ivl@EXEEXT@ version.exe iverilog-vpi.man
$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true
# In the windows world, the installer will need a dosify program to
# dosify text files.
ifeq (@MINGW32@,yes)
all: dep dosify.exe
dosify.exe: dosify.c
$(CC) -o dosify.exe dosify.c
dosify.exe: $(srcdir)/dosify.c
$(CC) -o dosify.exe $(srcdir)/dosify.c
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
$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true
test -r check.conf || cp $(srcdir)/check.conf .
driver/iverilog -B. -BPivlpp -tcheck -ocheck.vvp $(srcdir)/examples/hello.vl
ifeq (@WIN32@,yes)
ifeq (@install_suffix@,)
vvp/vvp -M- -M./vpi ./check.vvp | grep 'Hello, World'
else
# On Windows if we have a suffix we must run the vvp part of
# the test with a suffix since it was built/linked that way.
ln vvp/vvp.exe vvp/vvp$(suffix).exe
vvp/vvp$(suffix) -M- -M./vpi ./check.vvp | grep 'Hello, World'
rm vvp/vvp$(suffix).exe
endif
else
vvp/vvp -M- -M./vpi ./check.vvp | grep 'Hello, World'
endif
clean:
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) $@); done
for dir in vpi ivlpp tgt-verilog tgt-pal driver driver-vpi; \
do (cd $$dir ; $(MAKE) $@); done
rm -f *.o parse.cc parse.cc.output parse.h lexor.cc
rm -f ivl.exp iverilog-vpi.pdf iverilog-vpi.ps parse.output
$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true
rm -f *.o parse.cc parse.h lexor.cc
rm -f ivl.exp iverilog-vpi.man iverilog-vpi.pdf iverilog-vpi.ps parse.output
rm -f syn-rules.output dosify.exe ivl@EXEEXT@ check.vvp
rm -f lexor_keyword.cc libivl.a libvpi.a iverilog-vpi syn-rules.cc*
rm -f lexor_keyword.cc libivl.a libvpi.a iverilog-vpi syn-rules.cc
rm -rf dep
rm -f version.exe
distclean: clean
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) $@); done
for dir in vpi ivlpp tgt-verilog tgt-pal driver driver-vpi; \
do (cd $$dir ; $(MAKE) $@); done
rm -f Makefile config.status config.log config.cache config.h
rm -f _pli_types.h
$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true
$(foreach dir,$(NOTUSED),$(MAKE) -C $(dir) $@ && ) true
rm -f Makefile config.status config.log config.cache
rm -f stamp-config-h config.h
rm -f stamp-_pli_types-h _pli_types.h
ifneq (@srcdir@,.)
rm -f version.h version_tag.h check.conf
rmdir $(SUBDIRS) $(NOTUSED)
endif
rm -rf autom4te.cache
TT = t-dll.o t-dll-api.o t-dll-expr.o t-dll-proc.o
TT = t-dll.o t-dll-api.o t-dll-expr.o t-dll-proc.o t-dll-analog.o
FF = cprop.o nodangle.o synth.o synth2.o syn-rules.o
O = main.o async.o design_dump.o discipline.o dup_expr.o \
@@ -134,9 +154,25 @@ PExpr.o PGate.o PGenerate.o PScope.o PSpec.o \
PTask.o PUdp.o PFunction.o PWire.o Statement.o AStatement.o StringHeap.o \
$(FF) $(TT)
Makefile: Makefile.in config.h.in config.status
./config.status
Makefile: $(srcdir)/Makefile.in config.status
./config.status --file=$@
stamp-config-h: $(srcdir)/config.h.in config.status
@rm -f $@
./config.status config.h
config.h: stamp-config-h
stamp-_pli_types-h: $(srcdir)/_pli_types.h.in config.status
@rm -f $@
./config.status _pli_types.h
_pli_types.h: stamp-_pli_types-h
$(srcdir)/configure: $(srcdir)/configure.in $(srcdir)/aclocal.m4
cd $(srcdir) && autoconf
config.status: $(srcdir)/configure
./config.status --recheck
./config.status
ifeq (@WIN32@,yes)
# Under Windows (mingw) I need to make the ivl.exe in two steps.
@@ -153,28 +189,32 @@ ivl@EXEEXT@: $O
$(CXX) $(LDFLAGS) -o ivl@EXEEXT@ $O $(dllib)
endif
ifeq (@MINGW32@,yes)
SUBDIRS += driver-vpi
else
ifeq (@MINGW32@,no)
all: dep iverilog-vpi
iverilog-vpi: iverilog-vpi.sh
iverilog-vpi: $(srcdir)/iverilog-vpi.sh Makefile
sed -e 's;@SHARED@;@shared@;' -e 's;@PIC@;@PICFLAG@;' \
-e 's;@SUFFIX@;$(suffix);' \
-e 's;@IVCC@;$(CC);' \
-e 's;@IVCXX@;$(CXX);' \
-e 's;@IVCFLAGS@;$(CXXFLAGS);' \
-e 's;@INCLUDEDIR@;@includedir@;' \
-e 's;@INCLUDEDIR@;$(includedir);' \
-e 's;@LIBDIR@;@libdir@;' $< > $@
chmod +x $@
endif
version.exe: $(srcdir)/version.c $(srcdir)/version_base.h version_tag.h
$(HOSTCC) -Wall -o version.exe -I. -I$(srcdir) $(srcdir)/version.c
dep:
mkdir dep
%.o: %.cc
%.o: %.cc config.h
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -MD -c $< -o $*.o
mv $*.d dep/$*.d
# Here are some explicit dependencies needed to get things going.
main.o: main.cc version_tag.h
lexor.o: lexor.cc parse.h
@@ -192,11 +232,15 @@ lexor.cc: $(srcdir)/lexor.lex
lexor_keyword.o: lexor_keyword.cc parse.h
lexor_keyword.cc: lexor_keyword.gperf
gperf -o -i 7 -C -k 1-4,$$ -L ANSI-C -H keyword_hash -N check_identifier -t $(srcdir)/lexor_keyword.gperf > lexor_keyword.cc || (rm -f lexor_keyword.cc ; false)
lexor_keyword.cc: $(srcdir)/lexor_keyword.gperf
gperf -o -i 7 -C -k 1-4,6,9,$$ -L ANSI-C -H keyword_hash -N check_identifier -t $(srcdir)/lexor_keyword.gperf > lexor_keyword.cc || (rm -f lexor_keyword.cc ; false)
iverilog-vpi.ps: $(srcdir)/iverilog-vpi.man
$(MAN) -t $(srcdir)/iverilog-vpi.man > iverilog-vpi.ps
iverilog-vpi.man: $(srcdir)/iverilog-vpi.man.in version.exe
./version.exe `head -1 $(srcdir)/iverilog-vpi.man.in`'\n' > $@
tail -n +2 $(srcdir)/iverilog-vpi.man.in >> $@
iverilog-vpi.ps: iverilog-vpi.man
$(MAN) -t iverilog-vpi.man > iverilog-vpi.ps
iverilog-vpi.pdf: iverilog-vpi.ps
$(PS2PDF) iverilog-vpi.ps iverilog-vpi.pdf
@@ -204,127 +248,107 @@ iverilog-vpi.pdf: iverilog-vpi.ps
# For VERSION_TAG in driver/main.c, first try git-describe, then look for a
# version.h file in the source tree (included in snapshots and releases), and
# finally use nothing.
ifeq ($(MODE),full)
.PHONY: version.h
endif
# "true" and "false" in the next few lines are Unix shell command names
ifeq ($(GIT),none)
GIT_PRESENT = false
else
GIT_PRESENT = true
endif
version.h:
version_tag.h version:
@if $(GIT_PRESENT) && test -d $(srcdir)/.git; then \
echo "Using git-describe for VERSION_TAG"; \
tmp=`$(GIT) --git-dir $(srcdir)/.git describe \
| sed -e 's;\(.*\);#define VERSION_TAG "\1";'`; \
echo "$$tmp" | diff - $@ > /dev/null 2>&1 || echo "$$tmp" > $@ || exit 1; \
elif test -r $(srcdir)/$@; then \
echo "Using $(srcdir)/$@ for VERSION_TAG"; \
diff $(srcdir)/$@ $@ > /dev/null 2>&1 || cp $(srcdir)/$@ $@; \
echo "$$tmp" | diff - version_tag.h > /dev/null 2>&1 || echo "$$tmp" > version_tag.h || exit 1; \
elif test -r $(srcdir)/version_tag.h; then \
echo "Using $(srcdir)/version_tag.h for VERSION_TAG"; \
diff $(srcdir)/version_tag.h version_tag.h > /dev/null 2>&1 || cp $(srcdir)/version_tag.h version_tag.h; \
else \
echo "Using empty VERSION_TAG"; \
echo '#define VERSION_TAG ""' > $@; \
echo '#define VERSION_TAG ""' > version_tag.h; \
fi
ifeq (@MINGW32@,yes)
ifeq ($(MAN),none)
INSTALL_DOC = $(mandir)/man1/iverilog-vpi.1
INSTALL_DOC = $(mandir)/man1/iverilog-vpi$(suffix).1
else
ifeq ($(PS2PDF),none)
INSTALL_DOC = $(mandir)/man1/iverilog-vpi.1
INSTALL_DOC = $(mandir)/man1/iverilog-vpi$(suffix).1
else
INSTALL_DOC = $(prefix)/iverilog-vpi.pdf $(mandir)/man1/iverilog-vpi.1
INSTALL_DOC = $(prefix)/iverilog-vpi$(suffix).pdf $(mandir)/man1/iverilog-vpi$(suffix).1
all: dep iverilog-vpi.pdf
endif
endif
INSTALL_DOCDIR = $(mandir)/man1
else
INSTALL_DOC = $(mandir)/man1/iverilog-vpi.1
INSTALL_DOC = $(mandir)/man1/iverilog-vpi$(suffix).1
INSTALL_DOCDIR = $(mandir)/man1
endif
ifeq (@MINGW32@,yes)
WIN32_INSTALL = $(prefix)/hello.vl $(prefix)/sqrt.vl $(prefix)/sqrt-virtex.v $(prefix)/QUICK_START.txt
WIN32_INSTALL =
else
WIN32_INSTALL = $(bindir)/iverilog-vpi
WIN32_INSTALL = $(bindir)/iverilog-vpi$(suffix)
endif
install: all installdirs $(libdir)/ivl/ivl@EXEEXT@ $(libdir)/ivl/include/constants.vams $(libdir)/ivl/include/disciplines.vams $(includedir)/ivl_target.h $(includedir)/_pli_types.h $(includedir)/vpi_user.h $(includedir)/acc_user.h $(includedir)/veriuser.h $(WIN32_INSTALL) $(INSTALL_DOC)
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) $@); done
for dir in vpi ivlpp driver; \
do (cd $$dir ; $(MAKE) $@); done
install: all installdirs $(libdir)/ivl$(suffix)/ivl@EXEEXT@ $(libdir)/ivl$(suffix)/include/constants.vams $(libdir)/ivl$(suffix)/include/disciplines.vams $(includedir)/ivl_target.h $(includedir)/_pli_types.h $(includedir)/vpi_user.h $(includedir)/acc_user.h $(includedir)/veriuser.h $(WIN32_INSTALL) $(INSTALL_DOC)
$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true
$(bindir)/iverilog-vpi: ./iverilog-vpi
$(INSTALL_SCRIPT) ./iverilog-vpi $(DESTDIR)$(bindir)/iverilog-vpi
$(bindir)/iverilog-vpi$(suffix): ./iverilog-vpi
$(INSTALL_SCRIPT) ./iverilog-vpi "$(DESTDIR)$(bindir)/iverilog-vpi$(suffix)"
$(libdir)/ivl/ivl@EXEEXT@: ./ivl@EXEEXT@
$(INSTALL_PROGRAM) ./ivl@EXEEXT@ $(DESTDIR)$(libdir)/ivl/ivl@EXEEXT@
$(libdir)/ivl$(suffix)/ivl@EXEEXT@: ./ivl@EXEEXT@
$(INSTALL_PROGRAM) ./ivl@EXEEXT@ "$(DESTDIR)$(libdir)/ivl$(suffix)/ivl@EXEEXT@"
$(libdir)/ivl/include/constants.vams: $(srcdir)/constants.vams
$(INSTALL_DATA) $(srcdir)/constants.vams $(DESTDIR)$(libdir)/ivl/include/constants.vams
$(libdir)/ivl$(suffix)/include/constants.vams: $(srcdir)/constants.vams
$(INSTALL_DATA) $(srcdir)/constants.vams "$(DESTDIR)$(libdir)/ivl$(suffix)/include/constants.vams"
$(libdir)/ivl/include/disciplines.vams: $(srcdir)/disciplines.vams
$(INSTALL_DATA) $(srcdir)/disciplines.vams $(DESTDIR)$(libdir)/ivl/include/disciplines.vams
$(libdir)/ivl$(suffix)/include/disciplines.vams: $(srcdir)/disciplines.vams
$(INSTALL_DATA) $(srcdir)/disciplines.vams "$(DESTDIR)$(libdir)/ivl$(suffix)/include/disciplines.vams"
$(includedir)/ivl_target.h: $(srcdir)/ivl_target.h
$(INSTALL_DATA) $(srcdir)/ivl_target.h $(DESTDIR)$(includedir)/ivl_target.h
$(INSTALL_DATA) $(srcdir)/ivl_target.h "$(DESTDIR)$(includedir)/ivl_target.h"
$(includedir)/_pli_types.h: _pli_types.h
$(INSTALL_DATA) $< $(DESTDIR)$(includedir)/_pli_types.h
$(INSTALL_DATA) $< "$(DESTDIR)$(includedir)/_pli_types.h"
$(includedir)/vpi_user.h: $(srcdir)/vpi_user.h
$(INSTALL_DATA) $(srcdir)/vpi_user.h $(DESTDIR)$(includedir)/vpi_user.h
$(INSTALL_DATA) $(srcdir)/vpi_user.h "$(DESTDIR)$(includedir)/vpi_user.h"
$(includedir)/acc_user.h: $(srcdir)/acc_user.h
$(INSTALL_DATA) $(srcdir)/acc_user.h $(DESTDIR)$(includedir)/acc_user.h
$(INSTALL_DATA) $(srcdir)/acc_user.h "$(DESTDIR)$(includedir)/acc_user.h"
$(includedir)/veriuser.h: $(srcdir)/veriuser.h
$(INSTALL_DATA) $(srcdir)/veriuser.h $(DESTDIR)$(includedir)/veriuser.h
$(INSTALL_DATA) $(srcdir)/veriuser.h "$(DESTDIR)$(includedir)/veriuser.h"
$(mandir)/man1/iverilog-vpi.1: $(srcdir)/iverilog-vpi.man
$(INSTALL_DATA) $(srcdir)/iverilog-vpi.man $(DESTDIR)$(mandir)/man1/iverilog-vpi.1
$(mandir)/man1/iverilog-vpi$(suffix).1: iverilog-vpi.man
$(INSTALL_DATA) iverilog-vpi.man "$(DESTDIR)$(mandir)/man1/iverilog-vpi$(suffix).1"
$(prefix)/iverilog-vpi.pdf: iverilog-vpi.pdf
$(INSTALL_DATA) iverilog-vpi.pdf $(DESTDIR)$(prefix)/iverilog-vpi.pdf
$(prefix)/iverilog-vpi$(suffix).pdf: iverilog-vpi.pdf
$(INSTALL_DATA) iverilog-vpi.pdf "$(DESTDIR)$(prefix)/iverilog-vpi$(suffix).pdf"
# In windows installations, put a few examples and the quick_start
# into the destination directory.
ifeq (@MINGW32@,yes)
$(prefix)/hello.vl: $(srcdir)/examples/hello.vl
./dosify.exe $(srcdir)/examples/hello.vl tmp.vl
mv tmp.vl $(prefix)/hello.vl
$(prefix)/sqrt.vl: $(srcdir)/examples/sqrt.vl
./dosify.exe $(srcdir)/examples/sqrt.vl tmp.vl
mv tmp.vl $(prefix)/sqrt.vl
$(prefix)/sqrt-virtex.v: $(srcdir)/examples/sqrt-virtex.v
./dosify.exe $(srcdir)/examples/sqrt-virtex.v tmp.vl
mv tmp.vl $(prefix)/sqrt-virtex.v
$(prefix)/QUICK_START.txt: $(srcdir)/QUICK_START.txt
./dosify.exe $(srcdir)/QUICK_START.txt tmp.txt
mv tmp.txt $(prefix)/QUICK_START.txt
endif
installdirs: mkinstalldirs
$(srcdir)/mkinstalldirs $(DESTDIR)$(bindir) $(DESTDIR)$(includedir) $(DESTDIR)$(libdir)/ivl \
$(DESTDIR)$(libdir)/ivl/include $(DESTDIR)$(mandir) $(DESTDIR)$(mandir)/man1
installdirs: $(srcdir)/mkinstalldirs
$(srcdir)/mkinstalldirs "$(DESTDIR)$(bindir)" \
"$(DESTDIR)$(includedir)" \
"$(DESTDIR)$(libdir)/ivl$(suffix)" \
"$(DESTDIR)$(libdir)/ivl$(suffix)/include" \
"$(DESTDIR)$(mandir)" \
"$(DESTDIR)$(mandir)/man1"
uninstall:
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) $@); done
for dir in vpi ivlpp driver; \
do (cd $$dir ; $(MAKE) $@); done
$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true
for f in ivl@EXEEXT@ include/constants.vams include/disciplines.vams; \
do rm -f $(DESTDIR)$(libdir)/ivl/$$f; done
-rmdir $(DESTDIR)$(libdir)/ivl/include
-rmdir $(DESTDIR)$(libdir)/ivl
for f in verilog iverilog-vpi gverilog@EXEEXT@; \
do rm -f $(DESTDIR)$(bindir)/$$f; done
do rm -f "$(DESTDIR)$(libdir)/ivl$(suffix)/$$f"; done
-rmdir "$(DESTDIR)$(libdir)/ivl$(suffix)/include"
-rmdir "$(DESTDIR)$(libdir)/ivl$(suffix)"
for f in verilog$(suffix) iverilog-vpi$(suffix) gverilog$(suffix)@EXEEXT@; \
do rm -f "$(DESTDIR)$(bindir)/$$f"; done
for f in ivl_target.h vpi_user.h _pli_types.h acc_user.h veriuser.h; \
do rm -f $(DESTDIR)$(includedir)/$$f; done
rm -f $(DESTDIR)$(mandir)/man1/iverilog-vpi.1 $(DESTDIR)$(prefix)/iverilog-vpi.pdf
do rm -f "$(DESTDIR)$(includedir)/$$f"; done
-test X$(suffix) = X || rmdir "$(DESTDIR)/$(includedir)"
rm -f "$(DESTDIR)$(mandir)/man1/iverilog-vpi$(suffix).1" "$(DESTDIR)$(prefix)/iverilog-vpi$(suffix).pdf"
-include $(patsubst %.o, dep/%.d, $O)
+6 -3
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998-2008 Stephen Williams ([email protected])
* Copyright (c) 1998-2010 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
@@ -24,12 +24,16 @@
# include "PWire.h"
# include <assert.h>
list<Module::named_expr_t> Module::user_defparms;
/* n is a permallocated string. */
Module::Module(perm_string n)
: PScope(n)
{
library_flag = false;
default_nettype = NetNet::NONE;
is_cell = false;
uc_drive = UCD_NONE;
timescale_warn_done = false;
}
Module::~Module()
@@ -100,4 +104,3 @@ const list<PGate*>& Module::get_gates() const
{
return gates_;
}
+9 -7
View File
@@ -1,7 +1,7 @@
#ifndef __Module_H
#define __Module_H
/*
* Copyright (c) 1998-2008 Stephen Williams ([email protected])
* Copyright (c) 1998-2010 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
@@ -74,7 +74,10 @@ class Module : public PScope, public LineInfo {
other effect. */
bool library_flag;
NetNet::Type default_nettype;
bool is_cell;
enum UCDriveType { UCD_NONE, UCD_PULL0, UCD_PULL1 };
UCDriveType uc_drive;
/* specparams are simpler then other params, in that they have
no type information. They are merely constant
@@ -87,6 +90,7 @@ class Module : public PScope, public LineInfo {
instantiated modules. */
typedef pair<pform_name_t,PExpr*> named_expr_t;
list<named_expr_t>defparms;
static list<named_expr_t>user_defparms;
/* Parameters may be overridden at instantiation time;
the overrides do not contain explicit parameter names,
@@ -105,16 +109,14 @@ class Module : public PScope, public LineInfo {
/* These are the timescale for this module. The default is
set by the `timescale directive. */
int time_unit, time_precision;
bool time_from_timescale;
bool timescale_warn_done;
/* Task definitions within this module */
map<perm_string,PTask*> tasks;
map<perm_string,PFunction*> funcs;
/* The module has a list of genvars that may be used in
various generate schemes. */
map<perm_string,LineInfo*> genvars;
/* the module has a list of generate schemes that appear in
/* The module has a list of generate schemes that appear in
the module definition. These are used at elaboration time. */
list<PGenerate*> generate_schemes;
+47 -13
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1999-2008 Stephen Williams ([email protected])
* Copyright (c) 1999-2009 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
@@ -26,6 +26,11 @@
# include "verinum.h"
# include "netmisc.h"
bool dly_used_no_timescale = false;
bool dly_used_timescale = false;
bool display_ts_dly_warning = true;
PDelays::PDelays()
{
delete_flag_ = true;
@@ -60,12 +65,28 @@ void PDelays::set_delays(const svector<PExpr*>*del, bool df)
delete_flag_ = df;
}
static NetExpr*calculate_val(Design*des, NetScope*scope, const PExpr*expr)
static NetExpr*calculate_val(Design*des, NetScope*scope, PExpr*expr)
{
ivl_variable_type_t tmp_type = IVL_VT_NO_TYPE;
bool tmp_flag = false;
expr->test_width(des, scope, 0, 0, tmp_type, tmp_flag);
NetExpr*dex = expr->elaborate_expr(des, scope, -1, false);
eval_expr(dex);
/* Print a warning if we find default and `timescale based
* delays in the design, since this is likely an error. */
if (scope->time_from_timescale()) dly_used_timescale = true;
else dly_used_no_timescale = true;
if (display_ts_dly_warning &&
dly_used_no_timescale && dly_used_timescale) {
cerr << "warning: Found both default and "
"`timescale based delays. Use" << endl;
cerr << " -Wtimescale to find the "
"module(s) with no `timescale." << endl;
display_ts_dly_warning = false;
}
/* If the delay expression is a real constant or vector
constant, then evaluate it, scale it to the local time
units, and return an adjusted value. */
@@ -74,7 +95,7 @@ static NetExpr*calculate_val(Design*des, NetScope*scope, const PExpr*expr)
verireal fn = tmp->value();
int shift = scope->time_unit() - des->get_precision();
long delay = fn.as_long(shift);
int64_t delay = fn.as_long64(shift);
if (delay < 0)
delay = 0;
@@ -88,8 +109,7 @@ static NetExpr*calculate_val(Design*des, NetScope*scope, const PExpr*expr)
if (NetEConst*tmp = dynamic_cast<NetEConst*>(dex)) {
verinum fn = tmp->value();
unsigned long delay =
des->scale_to_precision(fn.as_ulong(), scope);
uint64_t delay = des->scale_to_precision(fn.as_ulong64(), scope);
delete tmp;
NetEConst*tmp2 = new NetEConst(verinum(delay));
@@ -109,7 +129,7 @@ static NetExpr* make_delay_nets(Design*des, NetScope*scope, NetExpr*expr)
if (dynamic_cast<NetEConst*> (expr))
return expr;
NetNet*sig = expr->synthesize(des, scope);
NetNet*sig = expr->synthesize(des, scope, expr);
if (sig == 0) {
cerr << expr->get_fileline() << ": error: Expression " << *expr
<< " is not suitable for delay expression." << endl;
@@ -120,6 +140,20 @@ static NetExpr* make_delay_nets(Design*des, NetScope*scope, NetExpr*expr)
return expr;
}
static NetExpr* calc_decay_time(NetExpr *rise, NetExpr *fall)
{
NetEConst *c_rise = dynamic_cast<NetEConst*>(rise);
NetEConst *c_fall = dynamic_cast<NetEConst*>(fall);
if (c_rise && c_fall) {
if (c_rise->value() < c_fall->value()) return rise;
else return fall;
}
cerr << fall->get_fileline() << ": sorry: can not calculate the "
<< "decay time from " << *rise << " and " << *fall << endl;
return 0;
}
void PDelays::eval_delays(Design*des, NetScope*scope,
NetExpr*&rise_time,
NetExpr*&fall_time,
@@ -141,14 +175,14 @@ void PDelays::eval_delays(Design*des, NetScope*scope,
if (delay_[2]) {
decay_time = calculate_val(des, scope, delay_[2]);
if (as_nets_flag)
decay_time = make_delay_nets(des, scope, decay_time);
if (as_nets_flag)
decay_time = make_delay_nets(des, scope,
decay_time);
} else {
if (rise_time < fall_time)
decay_time = rise_time;
else
decay_time = fall_time;
// If this is zero then we need to do the min()
// at run time.
decay_time = calc_decay_time(rise_time, fall_time);
}
} else {
assert(delay_[2] == 0);
-33
View File
@@ -18,9 +18,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: PDelays.h,v 1.9 2006/01/03 05:22:14 steve Exp $"
#endif
# include "svector.h"
# include <string>
@@ -72,34 +69,4 @@ class PDelays {
ostream& operator << (ostream&o, const PDelays&);
/*
* $Log: PDelays.h,v $
* Revision 1.9 2006/01/03 05:22:14 steve
* Handle complex net node delays.
*
* Revision 1.8 2006/01/02 05:33:19 steve
* Node delays can be more general expressions in structural contexts.
*
* Revision 1.7 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.6 2002/06/14 03:25:51 steve
* Compiler portability.
*
* Revision 1.5 2001/12/29 20:19:31 steve
* Do not delete delay expressions of UDP instances.
*
* Revision 1.4 2001/11/22 06:20:59 steve
* Use NetScope instead of string for scope path.
*
* Revision 1.3 2001/01/16 02:44:17 steve
* Use the iosfwd header if available.
*
* Revision 1.2 2000/02/23 02:56:53 steve
* Macintosh compilers do not support ident.
*
* Revision 1.1 1999/09/04 19:11:46 steve
* Add support for delayed non-blocking assignments.
*
*/
#endif
-26
View File
@@ -16,9 +16,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: PEvent.cc,v 1.5 2004/02/19 06:57:10 steve Exp $"
#endif
# include "config.h"
@@ -38,26 +35,3 @@ 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
* into this table. Also, permallocate event
* names from the beginning.
*
* Revision 1.3 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.2 2001/07/25 03:10:48 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
*
* Revision 1.1 2000/04/01 19:31:57 steve
* Named events as far as the pform.
*
*/
-37
View File
@@ -18,9 +18,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: PEvent.h,v 1.9 2004/02/19 06:57:10 steve Exp $"
#endif
# include "LineInfo.h"
# include "StringHeap.h"
@@ -54,38 +51,4 @@ class PEvent : public LineInfo {
PEvent& operator= (const PEvent&);
};
/*
* $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
* into this table. Also, permallocate event
* names from the beginning.
*
* Revision 1.7 2003/01/30 16:23:07 steve
* Spelling fixes.
*
* Revision 1.6 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.5 2001/12/03 04:47:14 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
*
* Revision 1.4 2001/01/16 02:44:18 steve
* Use the iosfwd header if available.
*
* Revision 1.3 2000/04/09 17:44:30 steve
* Catch event declarations during scope elaborate.
*
* Revision 1.2 2000/04/04 03:20:15 steve
* Simulate named event trigger and waits.
*
* Revision 1.1 2000/04/01 19:31:57 steve
* Named events as far as the pform.
*
*/
#endif
+101 -3
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998-2008 Stephen Williams <[email protected]>
* Copyright (c) 1998-2008,2010 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
@@ -23,6 +23,7 @@
# include "compiler.h"
# include "PExpr.h"
# include "PWire.h"
# include "Module.h"
# include "netmisc.h"
# include <typeinfo>
@@ -36,6 +37,10 @@ PExpr::~PExpr()
{
}
void PExpr::declare_implicit_nets(LexicalScope*scope, NetNet::Type type)
{
}
bool PExpr::has_aa_term(Design*, NetScope*) const
{
return false;
@@ -70,6 +75,13 @@ PEBinary::~PEBinary()
{
}
void PEBinary::declare_implicit_nets(LexicalScope*scope, NetNet::Type type)
{
assert(left_ && right_);
left_->declare_implicit_nets(scope, type);
right_->declare_implicit_nets(scope, type);
}
bool PEBinary::has_aa_term(Design*des, NetScope*scope) const
{
assert(left_ && right_);
@@ -95,11 +107,29 @@ PEBLogic::~PEBLogic()
{
}
PEBShift::PEBShift(char op, PExpr*l, PExpr*r)
PEBLeftWidth::PEBLeftWidth(char op, PExpr*l, PExpr*r)
: PEBinary(op, l, r)
{
}
PEBLeftWidth::~PEBLeftWidth()
{
}
PEBPower::PEBPower(char op, PExpr*l, PExpr*r)
: PEBLeftWidth(op, l, r)
{
}
PEBPower::~PEBPower()
{
}
PEBShift::PEBShift(char op, PExpr*l, PExpr*r)
: PEBLeftWidth(op, l, r)
{
}
PEBShift::~PEBShift()
{
}
@@ -142,6 +172,13 @@ PECallFunction::~PECallFunction()
{
}
void PECallFunction::declare_implicit_nets(LexicalScope*scope, NetNet::Type type)
{
for (unsigned idx = 0 ; idx < parms_.size() ; idx += 1) {
parms_[idx]->declare_implicit_nets(scope, type);
}
}
bool PECallFunction::has_aa_term(Design*des, NetScope*scope) const
{
bool flag = false;
@@ -152,7 +189,7 @@ bool PECallFunction::has_aa_term(Design*des, NetScope*scope) const
}
PEConcat::PEConcat(const svector<PExpr*>&p, PExpr*r)
: parms_(p), repeat_(r)
: parms_(p), tested_widths_(p.count()), repeat_(r)
{
}
@@ -161,6 +198,13 @@ PEConcat::~PEConcat()
delete repeat_;
}
void PEConcat::declare_implicit_nets(LexicalScope*scope, NetNet::Type type)
{
for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) {
parms_[idx]->declare_implicit_nets(scope, type);
}
}
bool PEConcat::has_aa_term(Design*des, NetScope*scope) const
{
bool flag = false;
@@ -227,6 +271,46 @@ PEIdent::~PEIdent()
{
}
void PEIdent::declare_implicit_nets(LexicalScope*scope, NetNet::Type type)
{
/* We create an implicit wire if this is a simple identifier and
if an identifier of that name has not already been declared in
any enclosing scope. */
if ((path_.size() == 1) && (path_.front().index.size() == 0)) {
perm_string name = path_.front().name;
LexicalScope*ss = scope;
while (ss) {
if (ss->wires.find(name) != ss->wires.end())
return;
if (ss->localparams.find(name) != ss->localparams.end())
return;
if (ss->parameters.find(name) != ss->parameters.end())
return;
if (ss->genvars.find(name) != ss->genvars.end())
return;
if (ss->events.find(name) != ss->events.end())
return;
/* Strictly speaking, we should also check for name clashes
with tasks, functions, named blocks, module instances,
and generate blocks. However, this information is not
readily available. As these names would not be legal in
this context, we can declare implicit nets here and rely
on later checks for name clashes to report the error. */
ss = ss->parent_scope();
}
PWire*net = new PWire(name, type, NetNet::NOT_A_PORT, IVL_VT_LOGIC);
net->set_file(get_file());
net->set_lineno(get_lineno());
net->set_range(0, 0, SR_NET, true);
scope->wires[name] = net;
if (warn_implicit) {
cerr << get_fileline() << ": warning: implicit "
"definition of wire '" << name << "'." << endl;
}
}
}
bool PEIdent::has_aa_term(Design*des, NetScope*scope) const
{
NetNet* net = 0;
@@ -292,6 +376,14 @@ PETernary::~PETernary()
{
}
void PETernary::declare_implicit_nets(LexicalScope*scope, NetNet::Type type)
{
assert(expr_ && tru_ && fal_);
expr_->declare_implicit_nets(scope, type);
tru_->declare_implicit_nets(scope, type);
fal_->declare_implicit_nets(scope, type);
}
bool PETernary::has_aa_term(Design*des, NetScope*scope) const
{
assert(expr_ && tru_ && fal_);
@@ -309,6 +401,12 @@ PEUnary::~PEUnary()
{
}
void PEUnary::declare_implicit_nets(LexicalScope*scope, NetNet::Type type)
{
assert(expr_);
expr_->declare_implicit_nets(scope, type);
}
bool PEUnary::has_aa_term(Design*des, NetScope*scope) const
{
assert(expr_);
+104 -34
View File
@@ -1,7 +1,7 @@
#ifndef __PExpr_H
#define __PExpr_H
/*
* Copyright (c) 1998-2008 Stephen Williams <[email protected]>
* Copyright (c) 1998-2010 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
@@ -21,6 +21,7 @@
# include <string>
# include <vector>
# include <valarray>
# include "netlist.h"
# include "verinum.h"
# include "LineInfo.h"
@@ -28,6 +29,7 @@
class Design;
class Module;
class LexicalScope;
class NetNet;
class NetExpr;
class NetScope;
@@ -46,6 +48,16 @@ class PExpr : public LineInfo {
virtual void dump(ostream&) const;
// This method tests whether the expression contains any identifiers
// that have not been previously declared in the specified scope or
// in any containing scope. Any such identifiers are added to the
// specified scope as scalar nets of the specified type.
//
// This operation must be performed by the parser, to ensure that
// subsequent declarations do not affect the decision to create an
// implicit net.
virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type);
// This method tests whether the expression contains any
// references to automatically allocated variables.
virtual bool has_aa_term(Design*des, NetScope*scope) const;
@@ -84,10 +96,6 @@ class PExpr : public LineInfo {
ivl_variable_type_t expr_type() const { return expr_type_; }
unsigned expr_width() const { return expr_width_; }
// During the elaborate_sig phase, we may need to scan
// expressions to find implicit net declarations.
virtual bool elaborate_sig(Design*des, NetScope*scope) const;
// Procedural elaboration of the expression. The expr_width is
// the width of the context of the expression (i.e. the
// l-value width of an assignment),
@@ -142,8 +150,6 @@ class PExpr : public LineInfo {
ivl_variable_type_t expr_type_;
unsigned expr_width_;
static void suppress_binary_operand_sign_if_needed_(NetExpr*lp, NetExpr*rp);
private: // not implemented
PExpr(const PExpr&);
PExpr& operator= (const PExpr&);
@@ -160,6 +166,8 @@ class PEConcat : public PExpr {
virtual verinum* eval_const(Design*des, NetScope*sc) const;
virtual void dump(ostream&) const;
virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type);
virtual bool has_aa_term(Design*des, NetScope*scope) const;
virtual unsigned test_width(Design*des, NetScope*scope,
@@ -167,7 +175,6 @@ class PEConcat : public PExpr {
ivl_variable_type_t&expr_type,
bool&unsized_flag);
virtual bool elaborate_sig(Design*des, NetScope*scope) const;
virtual NetNet* elaborate_lnet(Design*des, NetScope*scope) const;
virtual NetNet* elaborate_bi_net(Design*des, NetScope*scope) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
@@ -181,6 +188,8 @@ class PEConcat : public PExpr {
bool bidirectional_flag) const;
private:
svector<PExpr*>parms_;
std::valarray<unsigned>tested_widths_;
PExpr*repeat_;
};
@@ -256,6 +265,8 @@ class PEIdent : public PExpr {
virtual void dump(ostream&) const;
virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type);
virtual bool has_aa_term(Design*des, NetScope*scope) const;
virtual unsigned test_width(Design*des, NetScope*scope,
@@ -263,8 +274,6 @@ class PEIdent : public PExpr {
ivl_variable_type_t&expr_type,
bool&unsized_flag);
virtual bool elaborate_sig(Design*des, NetScope*scope) const;
// Identifiers are allowed (with restrictions) is assign l-values.
virtual NetNet* elaborate_lnet(Design*des, NetScope*scope) const;
@@ -291,12 +300,23 @@ class PEIdent : public PExpr {
pform_name_t path_;
private:
// Common functions to calculate parts of part/bit selects.
bool calculate_parts_(Design*, NetScope*, long&msb, long&lsb) const;
// Common functions to calculate parts of part/bit
// selects. These methods return true if the expressions
// elaborate/calculate, or false if there is some sort of
// source error.
// The calculate_parts_ method calculates the range
// expressions of a part select for the current object. The
// part select expressions are elaborated and evaluated, and
// the values written to the msb/lsb arguments. If there are
// invalid bits (xz) in either expression, then the defined
// flag is set to *false*.
bool calculate_parts_(Design*, NetScope*, long&msb, long&lsb, bool&defined) const;
NetExpr* calculate_up_do_base_(Design*, NetScope*) const;
bool calculate_param_range_(Design*, NetScope*,
const NetExpr*msb_ex, long&msb,
const NetExpr*lsb_ex, long&lsb) const;
const NetExpr*lsb_ex, long&lsb,
long length) const;
bool calculate_up_do_width_(Design*, NetScope*, unsigned long&wid) const;
@@ -327,6 +347,12 @@ class PEIdent : public PExpr {
NetScope*found,
const NetExpr*par_msb,
const NetExpr*par_lsb) const;
NetExpr*elaborate_expr_param_idx_do_(Design*des,
NetScope*scope,
const NetExpr*par,
NetScope*found,
const NetExpr*par_msb,
const NetExpr*par_lsb) const;
NetExpr*elaborate_expr_net(Design*des,
NetScope*scope,
NetNet*net,
@@ -358,8 +384,6 @@ class PEIdent : public PExpr {
NetNet* elaborate_lnet_common_(Design*des, NetScope*scope,
bool bidirectional_flag) const;
NetNet*make_implicit_net_(Design*des, NetScope*scope) const;
bool eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
long&midx, long&lidx) const;
};
@@ -431,6 +455,8 @@ class PEUnary : public PExpr {
virtual void dump(ostream&out) const;
virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type);
virtual bool has_aa_term(Design*des, NetScope*scope) const;
virtual unsigned test_width(Design*des, NetScope*scope,
@@ -438,8 +464,6 @@ class PEUnary : public PExpr {
ivl_variable_type_t&expr_type,
bool&unsized_flag);
virtual bool elaborate_sig(Design*des, NetScope*scope) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
int expr_width, bool sys_task_arg) const;
virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
@@ -461,6 +485,8 @@ class PEBinary : public PExpr {
virtual void dump(ostream&out) const;
virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type);
virtual bool has_aa_term(Design*des, NetScope*scope) const;
virtual unsigned test_width(Design*des, NetScope*scope,
@@ -468,8 +494,6 @@ class PEBinary : public PExpr {
ivl_variable_type_t&expr_type,
bool&unsized_flag);
virtual bool elaborate_sig(Design*des, NetScope*scope) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
int expr_width, bool sys_task_arg) const;
virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
@@ -480,15 +504,20 @@ class PEBinary : public PExpr {
PExpr*left_;
PExpr*right_;
NetExpr*elaborate_expr_base_(Design*, NetExpr*lp, NetExpr*rp, int use_wid) const;
NetExpr*elaborate_eval_expr_base_(Design*, NetExpr*lp, NetExpr*rp, int use_wid) const;
NetExpr*elaborate_expr_base_(Design*, NetExpr*lp, NetExpr*rp,
int use_wid, bool is_pexpr =false) const;
NetExpr*elaborate_eval_expr_base_(Design*, NetExpr*lp, NetExpr*rp,
int use_wid) const;
NetExpr*elaborate_expr_base_bits_(Design*, NetExpr*lp, NetExpr*rp, int use_wid) const;
NetExpr*elaborate_expr_base_div_(Design*, NetExpr*lp, NetExpr*rp, int use_wid) const;
NetExpr*elaborate_expr_base_div_(Design*, NetExpr*lp, NetExpr*rp,
int use_wid, bool is_pexpr) const;
NetExpr*elaborate_expr_base_lshift_(Design*, NetExpr*lp, NetExpr*rp, int use_wid) const;
NetExpr*elaborate_expr_base_rshift_(Design*, NetExpr*lp, NetExpr*rp, int use_wid) const;
NetExpr*elaborate_expr_base_mult_(Design*, NetExpr*lp, NetExpr*rp, int use_wid) const;
NetExpr*elaborate_expr_base_add_(Design*, NetExpr*lp, NetExpr*rp, int use_wid) const;
NetExpr*elaborate_expr_base_mult_(Design*, NetExpr*lp, NetExpr*rp,
int use_wid, bool is_pexpr) const;
NetExpr*elaborate_expr_base_add_(Design*, NetExpr*lp, NetExpr*rp,
int use_wid, bool is_pexpr) const;
};
@@ -531,18 +560,51 @@ class PEBLogic : public PEBinary {
NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
};
class PEBShift : public PEBinary {
/*
* A couple of the binary operands have a special sub-expression rule
* where the expression width is carried entirely by the left
* expression, and the right operand is self-determined.
*/
class PEBLeftWidth : public PEBinary {
public:
explicit PEBLeftWidth(char op, PExpr*l, PExpr*r);
~PEBLeftWidth() =0;
virtual NetExpr*elaborate_expr_leaf(Design*des, NetExpr*lp, NetExpr*rp,
int expr_wid) const =0;
protected:
virtual unsigned test_width(Design*des, NetScope*scope,
unsigned min, unsigned lval,
ivl_variable_type_t&expr_type,
bool&flag);
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
int expr_width, bool sys_task_arg) const;
virtual NetExpr*elaborate_pexpr(Design*des, NetScope*scope) const;
};
class PEBPower : public PEBLeftWidth {
public:
explicit PEBPower(char op, PExpr*l, PExpr*r);
~PEBPower();
NetExpr*elaborate_expr_leaf(Design*des, NetExpr*lp, NetExpr*rp,
int expr_wid) const;
};
class PEBShift : public PEBLeftWidth {
public:
explicit PEBShift(char op, PExpr*l, PExpr*r);
~PEBShift();
virtual unsigned test_width(Design*des, NetScope*scope,
unsigned min, unsigned lval,
ivl_variable_type_t&expr_type,
bool&flag);
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
int expr_width, bool sys_task_arg) const;
NetExpr*elaborate_expr_leaf(Design*des, NetExpr*lp, NetExpr*rp,
int expr_wid) const;
};
/*
@@ -557,6 +619,8 @@ class PETernary : public PExpr {
virtual void dump(ostream&out) const;
virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type);
virtual bool has_aa_term(Design*des, NetScope*scope) const;
virtual unsigned test_width(Design*des, NetScope*scope,
@@ -564,13 +628,15 @@ class PETernary : public PExpr {
ivl_variable_type_t&expr_type,
bool&unsized_flag);
virtual bool elaborate_sig(Design*des, NetScope*scope) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
int expr_width, bool sys_task_arg) const;
virtual NetETernary*elaborate_pexpr(Design*des, NetScope*sc) const;
virtual verinum* eval_const(Design*des, NetScope*sc) const;
private:
NetExpr* elab_and_eval_alternative_(Design*des, NetScope*scope,
PExpr*expr, int use_wid) const;
private:
PExpr*expr_;
PExpr*tru_;
@@ -597,6 +663,8 @@ class PECallFunction : public PExpr {
virtual void dump(ostream &) const;
virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type);
virtual bool has_aa_term(Design*des, NetScope*scope) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
@@ -614,8 +682,10 @@ class PECallFunction : public PExpr {
bool check_call_matches_definition_(Design*des, NetScope*dscope) const;
NetExpr* cast_to_width_(NetExpr*expr, int wid, bool signed_flag) const;
NetExpr* elaborate_sfunc_(Design*des, NetScope*scope, int expr_wid) const;
NetExpr* elaborate_access_func_(Design*des, NetScope*scope, int expr_wid) const;
NetExpr* elaborate_access_func_(Design*des, NetScope*scope, ivl_nature_t) const;
unsigned test_width_sfunc_(Design*des, NetScope*scope,
unsigned min, unsigned lval,
ivl_variable_type_t&expr_type,
+2 -2
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1999-2008 Stephen Williams ([email protected])
* Copyright (c) 1999-2008,2010 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
@@ -21,7 +21,7 @@
#include "PTask.h"
PFunction::PFunction(perm_string name, PScope*parent, bool is_auto__)
PFunction::PFunction(perm_string name, LexicalScope*parent, bool is_auto__)
: PScope(name, parent), ports_(0), statement_(0)
{
is_auto_ = is_auto__;
-53
View File
@@ -99,59 +99,6 @@ void PGate::eval_delays(Design*des, NetScope*scope,
as_net_flag);
}
void PGate::eval_delays(Design*des, NetScope*scope,
unsigned long&rise_time,
unsigned long&fall_time,
unsigned long&decay_time) const
{
NetExpr*rise_expr, *fall_expr, *decay_expr;
delay_.eval_delays(des, scope, rise_expr, fall_expr, decay_expr);
if (rise_expr == 0) {
rise_time = 0;
fall_time = 0;
decay_time = 0;
}
if (NetEConst*tmp = dynamic_cast<NetEConst*> (rise_expr)) {
rise_time = tmp->value().as_ulong();
} else {
cerr << get_fileline() << ": error: Delay expressions must be "
<< "constant here." << endl;
cerr << get_fileline() << ": : Cannot calculate "
<< *rise_expr << endl;
des->errors += 1;
rise_time = 0;
}
if (NetEConst*tmp = dynamic_cast<NetEConst*> (fall_expr)) {
fall_time = tmp->value().as_ulong();
} else {
if (fall_expr != rise_expr) {
cerr << get_fileline() << ": error: Delay expressions must be "
<< "constant here." << endl;
cerr << get_fileline() << ": : Cannot calculate "
<< *rise_expr << endl;
}
des->errors += 1;
fall_time = 0;
}
if (NetEConst*tmp = dynamic_cast<NetEConst*> (decay_expr)) {
decay_time = tmp->value().as_ulong();
} else {
cerr << get_fileline() << ": error: Delay expressions must be "
<< "constant here." << endl;
cerr << get_fileline() << ": : Cannot calculate "
<< *rise_expr << endl;
des->errors += 1;
decay_time = 0;
}
}
PGAssign::PGAssign(svector<PExpr*>*pins)
: PGate(perm_string(), pins)
{
-9
View File
@@ -62,15 +62,6 @@ class PGate : public LineInfo {
perm_string get_name() const { return name_; }
// This method evaluates the delays all the way to an
// integer. If the delay is non-constant, then set the times
// to 0, print an error message and mark an error to the
// design.
void eval_delays(Design*des, NetScope*scope,
unsigned long&rise_time,
unsigned long&fall_time,
unsigned long&decay_time) const;
// This evaluates the delays as far as possible, but returns
// an expression, and do not signal errors.
void eval_delays(Design*des, NetScope*scope,
+78 -8
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2006 Stephen Williams ([email protected])
* Copyright (c) 2006,2009,2010 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
@@ -16,18 +16,15 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: PGenerate.cc,v 1.4 2007/06/02 03:42:12 steve Exp $"
#endif
# include "PGenerate.h"
# include "PWire.h"
# include "ivl_assert.h"
PGenerate::PGenerate(unsigned id)
: id_number(id)
PGenerate::PGenerate(LexicalScope*parent, unsigned id)
: LexicalScope(parent), id_number(id)
{
parent = 0;
lexical_scope = 0;
direct_nested_ = false;
}
PGenerate::~PGenerate()
@@ -38,3 +35,76 @@ void PGenerate::add_gate(PGate*gate)
{
gates.push_back(gate);
}
void PGenerate::probe_for_direct_nesting_(void)
{
direct_nested_ = false;
ivl_assert(*this, scheme_type==GS_CASE_ITEM || scheme_type==GS_CONDIT || scheme_type==GS_ELSE);
// If this scheme has received an explicit name, then it
// cannot be direct nested.
if (scope_name[0] != '$') return;
if (tasks.size() > 0) return;
if (funcs.size() > 0) return;
if (gates.size() > 0) return;
if (parameters.size() > 0) return;
if (localparams.size() > 0) return;
if (events.size() > 0) return;
if (wires.size() > 0) return;
if (genvars.size() > 0) return;
if (behaviors.size() > 0) return;
if (analog_behaviors.size() > 0) return;
if (generate_schemes.size() == 0) return;
switch (generate_schemes.size()) {
case 1: {
PGenerate*child = generate_schemes.front();
if (child->scheme_type == GS_CONDIT)
direct_nested_ = true;
if (child->scheme_type == GS_CASE)
direct_nested_ = true;
break;
}
case 2: {
PGenerate*child1 = generate_schemes.front();
PGenerate*child2 = generate_schemes.back();
if (child1->scheme_type==GS_CONDIT && child2->scheme_type==GS_ELSE)
direct_nested_ = true;
if (child2->scheme_type==GS_CONDIT && child1->scheme_type==GS_ELSE)
direct_nested_ = true;
break;
}
}
}
ostream& operator << (ostream&out, PGenerate::scheme_t type)
{
switch (type) {
case PGenerate::GS_NONE:
out << "GS_NONE";
break;
case PGenerate::GS_LOOP:
out << "GS_LOOP";
break;
case PGenerate::GS_CONDIT:
out << "GS_CONDIT";
break;
case PGenerate::GS_ELSE:
out << "GS_ELSE";
break;
case PGenerate::GS_CASE:
out << "GS_CASE";
break;
case PGenerate::GS_CASE_ITEM:
out << "GS_CASE_ITEM";
break;
case PGenerate::GS_NBLOCK:
out << "GS_NBLOCK";
break;
}
return out;
}
+24 -4
View File
@@ -1,7 +1,7 @@
#ifndef __PGenerate_H
#define __PGenerate_H
/*
* Copyright (c) 2006-2008 Stephen Williams ([email protected])
* Copyright (c) 2006-2010 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
@@ -25,6 +25,7 @@
# include "PScope.h"
# include <list>
# include <map>
# include <valarray>
# include "pform_types.h"
class Design;
@@ -52,7 +53,7 @@ class PWire;
class PGenerate : public LineInfo, public LexicalScope {
public:
explicit PGenerate(unsigned id_number);
explicit PGenerate(LexicalScope*parent, unsigned id_number);
~PGenerate();
// Generate schemes have an ID number, for when the scope is
@@ -62,7 +63,7 @@ class PGenerate : public LineInfo, public LexicalScope {
// This is used during parsing to stack lexical scopes within
// this generate scheme.
PScope*lexical_scope;
// LexicalScope*lexical_scope;
enum scheme_t {GS_NONE, GS_LOOP, GS_CONDIT, GS_ELSE,
GS_CASE, GS_CASE_ITEM, GS_NBLOCK};
@@ -74,6 +75,10 @@ class PGenerate : public LineInfo, public LexicalScope {
PExpr*loop_init;
PExpr*loop_test;
PExpr*loop_step;
// Case items may have multiple guard expression values. It is
// enough for any on of the guards to match the case statement
// test value.
std::valarray<PExpr*> item_test;
list<PGate*> gates;
void add_gate(PGate*);
@@ -82,9 +87,12 @@ class PGenerate : public LineInfo, public LexicalScope {
map<perm_string,PTask*> tasks;
map<perm_string,PFunction*>funcs;
// genvars declared within this scheme.
map<perm_string,LineInfo*> genvars;
// Generate schemes can contain further generate schemes.
list<PGenerate*> generate_schemes;
PGenerate*parent;
// PGenerate*parent;
// This method is called by the elaboration of a module to
// generate scopes. the container is the scope that is to
@@ -104,18 +112,30 @@ class PGenerate : public LineInfo, public LexicalScope {
bool generate_scope_case_(Design*des, NetScope*container);
bool generate_scope_nblock_(Design*des, NetScope*container);
// Call probe during elaborate_scope to calculate the
// direct_nested_ flag. It is OK to store the direct_nested_
// information here because "direct nested" is a property of
// the lexical generate code.
void probe_for_direct_nesting_(void);
bool direct_nested_;
// Elaborate_scope within a generated scope.
void elaborate_subscope_(Design*des, NetScope*scope);
void elaborate_subscope_direct_(Design*des, NetScope*scope);
// These are the scopes created by generate_scope.
list<NetScope*>scope_list_;
// internal function called on each scope generated by this scheme.
bool elaborate_sig_(Design*des, NetScope*scope) const;
bool elaborate_sig_direct_(Design*des, NetScope*scope) const;
bool elaborate_(Design*des, NetScope*scope) const;
bool elaborate_direct_(Design*des, NetScope*scope) const;
private: // not implemented
PGenerate(const PGenerate&);
PGenerate& operator= (const PGenerate&);
};
extern std::ostream& operator << (std::ostream&, PGenerate::scheme_t);
#endif
+4 -4
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2008 Stephen Williams ([email protected])
* Copyright (c) 2008,2010 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,13 +19,13 @@
# include "PScope.h"
PScope::PScope(perm_string n, PScope*parent)
: name_(n), parent_(parent)
PScope::PScope(perm_string n, LexicalScope*parent)
: LexicalScope(parent), name_(n)
{
}
PScope::PScope(perm_string n)
: name_(n), parent_(0)
: LexicalScope(0), name_(n)
{
}
+11 -5
View File
@@ -1,7 +1,7 @@
#ifndef __PScope_H
#define __PScope_H
/*
* Copyright (c) 2008 Stephen Williams ([email protected])
* Copyright (c) 2008,2010 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
@@ -46,7 +46,7 @@ class NetScope;
class LexicalScope {
public:
explicit LexicalScope() { }
explicit LexicalScope(LexicalScope*parent) : parent_(parent) { }
// A virtual destructor is so that dynamic_cast can work.
virtual ~LexicalScope() { }
@@ -90,10 +90,17 @@ class LexicalScope {
map<perm_string,PWire*>wires;
PWire* wires_find(perm_string name);
// Genvars in the scope. These will only be present in module
// scopes, but are listed here to allow them to be found when
// creating implicit nets.
map<perm_string,LineInfo*> genvars;
// Behaviors (processes) in this scope
list<PProcess*> behaviors;
list<AProcess*> analog_behaviors;
LexicalScope* parent_scope() const { return parent_; }
protected:
void dump_parameters_(ostream&out, unsigned indent) const;
@@ -104,6 +111,7 @@ class LexicalScope {
void dump_wires_(ostream&out, unsigned indent) const;
private:
LexicalScope*parent_;
};
class PScope : public LexicalScope {
@@ -117,12 +125,11 @@ class PScope : public LexicalScope {
// modules do not nest in Verilog, the parent must be nil for
// modules. Scopes for tasks and functions point to their
// containing module.
PScope(perm_string name, PScope*parent);
PScope(perm_string name, LexicalScope*parent);
PScope(perm_string name);
virtual ~PScope();
perm_string pscope_name() const { return name_; }
PScope* pscope_parent() { return parent_; }
protected:
bool elaborate_sig_wires_(Design*des, NetScope*scope) const;
@@ -131,7 +138,6 @@ class PScope : public LexicalScope {
private:
perm_string name_;
PScope*parent_;
};
#endif
-3
View File
@@ -16,9 +16,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: PSpec.cc,v 1.2 2007/02/12 01:52:21 steve Exp $"
#endif
# include "PSpec.h"
-3
View File
@@ -18,9 +18,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: PSpec.h,v 1.3 2007/04/13 02:34:35 steve Exp $"
#endif
# include "LineInfo.h"
# include "StringHeap.h"
+2 -2
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1999-2008 Stephen Williams ([email protected])
* Copyright (c) 1999-2008,2010 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
@@ -21,7 +21,7 @@
# include "PTask.h"
PTask::PTask(perm_string name, PScope*parent, bool is_auto__)
PTask::PTask(perm_string name, LexicalScope*parent, bool is_auto__)
: PScope(name, parent), ports_(0), statement_(0)
{
is_auto_ = is_auto__;
+3 -3
View File
@@ -1,7 +1,7 @@
#ifndef __PTask_H
#define __PTask_H
/*
* Copyright (c) 1999-2008 Stephen Williams ([email protected])
* Copyright (c) 1999-2008,2010 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
@@ -51,7 +51,7 @@ struct PTaskFuncArg {
class PTask : public PScope, public LineInfo {
public:
explicit PTask(perm_string name, PScope*parent, bool is_auto);
explicit PTask(perm_string name, LexicalScope*parent, bool is_auto);
~PTask();
void set_ports(svector<PWire *>*p);
@@ -93,7 +93,7 @@ class PTask : public PScope, public LineInfo {
class PFunction : public PScope, public LineInfo {
public:
explicit PFunction(perm_string name, PScope*parent, bool is_auto);
explicit PFunction(perm_string name, LexicalScope*parent, bool is_auto);
~PFunction();
void set_ports(svector<PWire *>*p);
-16
View File
@@ -16,9 +16,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: PUdp.cc,v 1.3 2004/03/08 00:47:44 steve Exp $"
#endif
# include "PUdp.h"
@@ -38,16 +35,3 @@ unsigned PUdp::find_port(const char*name)
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.
*
*/
-52
View File
@@ -18,9 +18,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: PUdp.h,v 1.12 2004/03/08 00:47:44 steve Exp $"
#endif
# include <map>
# include "StringHeap.h"
@@ -78,53 +75,4 @@ class PUdp {
PUdp& operator= (const 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.
*
* Revision 1.9 2003/07/15 03:49:22 steve
* Spelling fixes.
*
* Revision 1.8 2003/01/30 16:23:07 steve
* Spelling fixes.
*
* Revision 1.7 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.6 2002/05/23 03:08:51 steve
* Add language support for Verilog-2001 attribute
* syntax. Hook this support into existing $attribute
* handling, and add number and void value types.
*
* Add to the ivl_target API new functions for access
* of complex attributes attached to gates.
*
* Revision 1.5 2001/04/22 23:09:45 steve
* More UDP consolidation from Stephan Boettcher.
*
* Revision 1.4 2000/02/23 02:56:53 steve
* Macintosh compilers do not support ident.
*
* Revision 1.3 1999/06/15 03:44:53 steve
* Get rid of the STL vector template.
*
* Revision 1.2 1998/12/01 00:42:13 steve
* Elaborate UDP devices,
* Support UDP type attributes, and
* pass those attributes to nodes that
* are instantiated by elaboration,
* Put modules into a map instead of
* a simple list.
*
* Revision 1.1 1998/11/25 02:35:53 steve
* Parse UDP primitives all the way to pform.
*
*/
#endif
+12 -4
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1999-2007 Stephen Williams ([email protected])
* Copyright (c) 1999-2009 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
@@ -29,8 +29,8 @@ PWire::PWire(perm_string n,
: name_(n), type_(t), port_type_(pt), data_type_(dt),
signed_(false), isint_(false),
port_msb_(0), port_lsb_(0), port_set_(false),
net_msb_(0), net_lsb_(0), net_set_(false), error_cnt_(0),
lidx_(0), ridx_(0), discipline_(0)
net_msb_(0), net_lsb_(0), net_set_(false), is_scalar_(false),
error_cnt_(0), lidx_(0), ridx_(0), discipline_(0)
{
if (t == NetNet::INTEGER) {
type_ = NetNet::REG;
@@ -135,7 +135,12 @@ bool PWire::get_isint() const
return isint_;
}
void PWire::set_range(PExpr*m, PExpr*l, PWSRType type)
bool PWire::get_scalar() const
{
return is_scalar_;
}
void PWire::set_range(PExpr*m, PExpr*l, PWSRType type, bool is_scalar)
{
switch (type) {
case SR_PORT:
@@ -147,6 +152,7 @@ void PWire::set_range(PExpr*m, PExpr*l, PWSRType type)
port_msb_ = m;
port_lsb_ = l;
port_set_ = true;
is_scalar_ = is_scalar;
}
return;
@@ -159,6 +165,7 @@ void PWire::set_range(PExpr*m, PExpr*l, PWSRType type)
net_msb_ = m;
net_lsb_ = l;
net_set_ = true;
is_scalar_ = is_scalar;
}
return;
@@ -181,6 +188,7 @@ void PWire::set_range(PExpr*m, PExpr*l, PWSRType type)
net_msb_ = m;
net_lsb_ = l;
net_set_ = true;
is_scalar_ = is_scalar;
}
return;
}
+4 -2
View File
@@ -1,7 +1,7 @@
#ifndef __PWire_H
#define __PWire_H
/*
* Copyright (c) 1998-2007 Stephen Williams ([email protected])
* Copyright (c) 1998-2009 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
@@ -70,11 +70,12 @@ class PWire : public LineInfo {
void set_signed(bool flag);
bool get_signed() const;
bool get_isint() const;
bool get_scalar() const;
bool set_data_type(ivl_variable_type_t dt);
ivl_variable_type_t get_data_type() const;
void set_range(PExpr*msb, PExpr*lsb, PWSRType type);
void set_range(PExpr*msb, PExpr*lsb, PWSRType type, bool is_scalar);
void set_memory_idx(PExpr*ldx, PExpr*rdx);
@@ -104,6 +105,7 @@ class PWire : public LineInfo {
PExpr*net_msb_;
PExpr*net_lsb_;
bool net_set_;
bool is_scalar_;
unsigned error_cnt_;
// If this wire is actually a memory, these indices will give
+10 -25
View File
@@ -85,10 +85,6 @@ Normally, this command automatically figures out everything it needs
to know. It generally works pretty well. There are a few flags to the
configure script that modify its behavior:
--without-ipal
This turns off support for Icarus PAL, whether ipal
libraries are installed or not.
--prefix=<root>
The default is /usr/local, which causes the tool suite to
be compiled for install in /usr/local/bin,
@@ -99,27 +95,16 @@ configure script that modify its behavior:
common to use --prefix=/opt. You can configure for a non-root
install with --prefix=$HOME.
--enable-vvp32 (experimental)
If compiling on AMD64 systems, this enables the
compilation of 32bit compatible vvp (vvp32) and the vpi
modules that match.
2.2.1 Special AMD64 Instructions
(The Icarus Verilog RPM for x86_64 is build using these instructions.)
If you are building for Linux/AMD64 (a.k.a x86_64) then to get the
most out of your install, first make sure you have both 64bit and
32bit development libraries installed. Then configure with this
somewhat more complicated command:
./configure libdir64='$(prefix)/lib64' vpidir1=vpi64 vpidir2=. --enable-vvp32
This reflects the convention on AMD64 systems that 64bit libraries go
into lib64 directories. The "--enable-vvp32" also turns on 32bit
compatibility files. A 32bit version of vvp (vvp32) will be created,
as well as 32bit versions of the development libraries and bundled VPI
libraries.
--enable-suffix
--enable-suffix=<your-suffix>
--disable-suffix
Enable/disable changing the names of install files to use
a suffix string so that this version or install can co-
exist with other versions. This renames the installed
commands (iverilog, iverilog-vpi, vvp) and the installed
library files and include directory so that installations
with the same prefix but different suffix are guaranteed
to not interfere with each other.
2.3 (Optional) Testing
+2 -2
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998-2008 Stephen Williams ([email protected])
* Copyright (c) 1998-2008,2010 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
@@ -93,7 +93,7 @@ PAssignNB::~PAssignNB()
{
}
PBlock::PBlock(perm_string n, PScope*parent, BL_TYPE t)
PBlock::PBlock(perm_string n, LexicalScope*parent, BL_TYPE t)
: PScope(n, parent), bl_type_(t)
{
}
+1 -1
View File
@@ -159,7 +159,7 @@ class PBlock : public PScope, public Statement {
enum BL_TYPE { BL_SEQ, BL_PAR };
// If the block has a name, it is a scope and also has a parent.
explicit PBlock(perm_string n, PScope*parent, BL_TYPE t);
explicit PBlock(perm_string n, LexicalScope*parent, BL_TYPE t);
// If it doesn't have a name, it's not a scope
explicit PBlock(BL_TYPE t);
~PBlock();
+28 -30
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2004 Stephen Williams ([email protected])
* Copyright (c) 2002-2009 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
@@ -16,9 +16,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: StringHeap.cc,v 1.6 2004/02/18 17:11:54 steve Exp $"
#endif
# include "StringHeap.h"
#ifdef HAVE_MALLOC_H
@@ -28,6 +25,11 @@
# include <string.h>
# include <assert.h>
#ifdef CHECK_WITH_VALGRIND
static char **string_pool = NULL;
static unsigned string_pool_count = 0;
#endif
StringHeap::StringHeap()
{
cell_base_ = 0;
@@ -49,6 +51,12 @@ const char* StringHeap::add(const char*text)
unsigned rem = HEAPCELL - cell_ptr_;
if (rem < (len+1)) {
cell_base_ = (char*)malloc(HEAPCELL);
#ifdef CHECK_WITH_VALGRIND
string_pool_count += 1;
string_pool = (char **) realloc(string_pool,
string_pool_count*sizeof(char **));
string_pool[string_pool_count-1] = cell_base_;
#endif
cell_ptr_ = 0;
cell_count_ += 1;
assert(cell_base_ != 0);
@@ -83,6 +91,22 @@ StringHeapLex::~StringHeapLex()
{
}
void StringHeapLex::cleanup()
{
#ifdef CHECK_WITH_VALGRIND
for (unsigned idx = 0 ; idx < string_pool_count ; idx += 1) {
free(string_pool[idx]);
}
free(string_pool);
string_pool = NULL;
string_pool_count = 0;
for (unsigned idx = 0 ; idx < HASH_SIZE ; idx += 1) {
hash_table_[idx] = 0;
}
#endif
}
unsigned StringHeapLex::add_hit_count() const
{
return hit_count_;
@@ -178,29 +202,3 @@ bool operator < (perm_string a, perm_string b)
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
* into this table. Also, permallocate event
* names from the beginning.
*
* Revision 1.4 2003/01/27 05:09:17 steve
* Spelling fixes.
*
* Revision 1.3 2003/01/16 21:44:46 steve
* Keep some debugging status.
*
* Revision 1.2 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.1 2002/08/04 19:13:16 steve
* dll uses StringHeap for named items.
*
*/
+2 -28
View File
@@ -1,7 +1,7 @@
#ifndef __StringHeap_H
#define __StringHeap_H
/*
* Copyright (c) 2002-2004 Stephen Williams ([email protected])
* Copyright (c) 2002-2009 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
@@ -18,9 +18,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: StringHeap.h,v 1.6 2005/06/14 19:13:43 steve Exp $"
#endif
# include "config.h"
# include <string>
@@ -107,6 +104,7 @@ class StringHeapLex : private StringHeap {
unsigned add_count() const;
unsigned add_hit_count() const;
void cleanup();
private:
enum { HASH_SIZE = 4096 };
@@ -120,28 +118,4 @@ class StringHeapLex : private StringHeap {
StringHeapLex& operator= (const StringHeapLex&);
};
/*
* $Log: StringHeap.h,v $
* Revision 1.6 2005/06/14 19:13:43 steve
* gcc3/4 compile errors.
*
* 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
* into this table. Also, permallocate event
* names from the beginning.
*
* Revision 1.3 2003/01/16 21:44:46 steve
* Keep some debugging status.
*
* Revision 1.2 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.1 2002/08/04 19:13:16 steve
* dll uses StringHeap for named items.
*
*/
#endif
-41
View File
@@ -18,9 +18,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: _pli_types.h.in,v 1.8 2007/06/05 21:32:30 steve Exp $"
#endif
# undef HAVE_INTTYPES_H
@@ -88,42 +85,4 @@ typedef char PLI_BYTE8;
typedef unsigned char PLI_UBYTE8;
#endif
/*
* $Log: _pli_types.h.in,v $
* Revision 1.8 2007/06/05 21:32:30 steve
* More standard PLI_BYTE8.
*
* Revision 1.7 2003/11/12 02:38:44 steve
* Clean up manual definitions of PLI_UINT64_FMT.
*
* Revision 1.6 2003/11/08 20:06:21 steve
* Spelling fixes in comments.
*
* Revision 1.5 2003/10/29 03:28:27 steve
* Add the PLU_UINT64_FMT string for formatting output.
*
* Revision 1.4 2003/10/29 03:23:12 steve
* Portably handle time format of VCD prints.
*
* Revision 1.3 2003/10/02 21:30:06 steve
* Use configured TIME_FMT in vcd dump printf.
*
* Revision 1.2 2003/10/02 19:33:44 steve
* Put libraries in libdir64.
*
* Revision 1.1 2003/09/30 01:33:13 steve
* Add PLI_UINT64 to _pli_types.h.
*
* Revision 1.2 2003/05/26 04:39:16 steve
* Typo type name.
*
* Revision 1.1 2003/02/17 06:39:47 steve
* Add at least minimal implementations for several
* acc_ functions. Add support for standard ACC
* string handling.
*
* Add the _pli_types.h header file to carry the
* IEEE1364-2001 standard PLI type declarations.
*
*/
#endif
-81
View File
@@ -18,9 +18,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: acc_user.h,v 1.20 2003/12/17 15:45:07 steve Exp $"
#endif
/*
* This header file contains the definitions and declarations needed
@@ -273,82 +270,4 @@ extern char* acc_version(void);
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.
*
* Revision 1.18 2003/06/13 19:23:41 steve
* Add a bunch more PLI1 routines.
*
* Revision 1.17 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
* tf_isetrealdelay, acc_handle_scope
* 3) makes acc_next reentrant
* 4) adds basic vpiWire type support
* 5) fills in some acc_object_of_type() and acc_fetch_{full}type()
* 6) add vpiLeftRange/RigthRange to signals
*
* Revision 1.16 2003/05/30 04:18:31 steve
* Add acc_next function.
*
* Revision 1.15 2003/05/29 02:35:41 steve
* acc_fetch_type supports module.
*
* Revision 1.14 2003/05/29 02:21:45 steve
* Implement acc_fetch_defname and its infrastructure in vvp.
*
* Revision 1.13 2003/05/24 03:02:04 steve
* Add implementation of acc_handle_by_name.
*
* Revision 1.12 2003/05/18 00:16:35 steve
* Add PLI_TRACE tracing of PLI1 modules.
*
* Add tf_isetdelay and friends, and add
* callback return values for acc_vcl support.
*
* Revision 1.11 2003/04/24 18:57:05 steve
* Add acc_fetch_fulltype function.
*
* Revision 1.10 2003/04/20 02:48:39 steve
* Support value change callbacks.
*
* Revision 1.9 2003/04/12 18:57:13 steve
* More acc_ function stubs.
*
* Revision 1.8 2003/03/13 04:35:09 steve
* Add a bunch of new acc_ and tf_ functions.
*
* Revision 1.7 2003/02/17 06:39:47 steve
* Add at least minimal implementations for several
* acc_ functions. Add support for standard ACC
* string handling.
*
* Add the _pli_types.h header file to carry the
* IEEE1364-2001 standard PLI type declarations.
*
* Revision 1.6 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.5 2002/06/11 15:19:12 steve
* Add acc_fetch_argc/argv/version (mruff)
*
* Revision 1.4 2002/06/07 02:58:58 steve
* Add a bunch of acc/tf functions. (mruff)
*
* Revision 1.3 2002/06/02 19:03:29 steve
* Add acc_handle_tfarg and acc_next_topmode
*
* Revision 1.2 2002/05/30 02:06:05 steve
* Implement acc_product_version.
*
* Revision 1.1 2002/05/23 03:46:42 steve
* Add the acc_user.h header file.
*
*/
#endif
Vendored
+58 -33
View File
@@ -1,29 +1,23 @@
# AX_CPP_IDENT
# ------------
# Check if the C compiler supports #ident
# Define and substitute ident_support if so.
#
# It would be simpler and more consistent with the rest of the autoconf
# structure to AC_DEFINE(HAVE_CPP_IDENT) instead of
# ident_support='-DHAVE_CVS_IDENT=1' and AC_SUBST(ident_support), but that
# change would require all C files in the icarus top level directory to
# put #include <config.h> before the #ifdef HAVE_CVS_IDENT (and change
# HAVE_CVS_IDENT to HAVE_CPP_IDENT). That would also remove all special
# ident_support handling from the Makefile. Manyana.
#
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.7 2007/05/16 23:59:12 steve Exp $"
],[while (0) {}],
[AS_VAR_SET(ax_cv_cpp_ident, yes)],
[AS_VAR_SET(ax_cv_cpp_ident, no)])])
if test $ax_cv_cpp_ident = yes; then
ident_support='-DHAVE_CVS_IDENT=1'
fi
AC_SUBST(ident_support)
])# AC_CPP_IDENT
# AX_ENABLE_SUFFIX
# ----------------
# Create the configure option --enable-suffix[=suffix] to generate suffix
# strings for the installed commands. This allows for shared installs of
# different builds. Remember to change the default suffix string to some
# value appropriate for the current version.
AC_DEFUN([AX_ENABLE_SUFFIX],
[AC_ARG_ENABLE([suffix],[AC_HELP_STRING([--enable-suffix],
[Use/set the installation command suffix])],
[true],[enable_suffix=no])
if test X$enable_suffix = Xyes; then
install_suffix='-0.10'
elif test X$enable_suffix = Xno; then
install_suffix=''
else
install_suffix="$enable_suffix"
fi
AC_SUBST(install_suffix)
])# AX_ENABLE_SUFFIX
# _AX_C_UNDERSCORES_MATCH_IFELSE(PATTERN, ACTION-IF-MATCH, ACTION-IF-NOMATCH)
# ------------------------------
@@ -72,17 +66,22 @@ fi
# 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_MSG_CHECKING([for Microsoft Windows])
AC_REQUIRE([AC_CANONICAL_HOST]) []dnl
case $host_os in
*cygwin*) MINGW32=no; WIN32=yes;;
*mingw*) MINGW32=yes; WIN32=yes;;
*) MINGW32=no; WIN32=no;;
esac
AC_SUBST(MINGW32)
AC_SUBST(WIN32)
AC_MSG_RESULT($WIN32)
if test $WIN32 = yes; then
AC_MSG_CHECKING([for MinGW])
AC_MSG_RESULT($MINGW32)
fi
])# AX_WIN32
# AX_LD_EXTRALIBS
@@ -113,6 +112,10 @@ case "${host}" in
shared="-shared -Wl,--enable-auto-image-base"
;;
*-*-mingw*)
shared="-shared -Wl,--enable-auto-image-base"
;;
*-*-hpux*)
shared="-b"
;;
@@ -142,6 +145,10 @@ case "${host}" in
PICFLAG=
;;
*-*-mingw*)
PICFLAG=
;;
*-*-hpux*)
PICFLAG=+z
;;
@@ -177,6 +184,10 @@ case "${host}" in
rdynamic=""
;;
*-*-mingw*)
rdynamic=""
;;
*-*-hpux*)
rdynamic="-E"
;;
@@ -205,3 +216,17 @@ case "${host}" in
;;
esac
])# AX_CPP_PRECOMP
# When config.status generates a header, we must update the stamp-h file.
# This file resides in the same directory as the config header
# that is generated. The stamp file name are based on the header name.
# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
# loop where config.status creates the headers, so we can generate
# our stamp files there.
AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
[
_config_header=$1
_stamp_name=stamp-`expr //$_config_header : '.*/\([[^./]]*\)\.[[^./]]*$'`-h
echo "timestamp for $_config_header" > `AS_DIRNAME(["$_config_header"])`/[]$_stamp_name
]) #_AC_AM_CONFIG_HEADER_HOOK
+1 -7
View File
@@ -9,11 +9,5 @@
echo "Autoconf in root..."
autoconf -f
for dir in vpi vvp tgt-vvp tgt-fpga tgt-stub tgt-vhdl libveriuser cadpli
do
echo "Autoconf in $dir..."
( cd ./$dir ; autoconf -f --include=.. )
done
echo "Precompiling lexor_keyword.gperf"
gperf -o -i 7 -C -k 1-4,\$ -L ANSI-C -H keyword_hash -N check_identifier -t ./lexor_keyword.gperf > lexor_keyword.cc
gperf -o -i 7 -C -k 1-4,6,9,\$ -L ANSI-C -H keyword_hash -N check_identifier -t ./lexor_keyword.gperf > lexor_keyword.cc
-7
View File
@@ -1,7 +0,0 @@
Makefile
cadpli.vpl
dep
configure
config.log
config.status
autom4te.cache
+13 -10
View File
@@ -18,7 +18,7 @@
#
SHELL = /bin/sh
VERSION = 0.9.devel
suffix = @install_suffix@
prefix = @prefix@
exec_prefix = @exec_prefix@
@@ -30,14 +30,14 @@ bindir = @bindir@
libdir = @libdir@
includedir = $(prefix)/include
vpidir = @libdir@/ivl
vpidir = @libdir@/ivl$(suffix)
CC = @CC@
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
CPPFLAGS = @ident_support@ -I$(srcdir) -I$(srcdir)/.. -I.. @CPPFLAGS@ @DEFS@ @PICFLAG@
CPPFLAGS = -I$(srcdir) -I$(srcdir)/.. -I.. @CPPFLAGS@ @DEFS@ @PICFLAG@
CFLAGS = -Wall @CFLAGS@
LDFLAGS = @LDFLAGS@
@@ -59,6 +59,9 @@ dep:
O = cadpli.o
Makefile: $(srcdir)/Makefile.in ../config.status
cd ..; ./config.status --file=cadpli/$@
SYSTEM_VPI_LDFLAGS = -L../vvp -lvpi
ifeq (@MINGW32@,yes)
SYSTEM_VPI_LDFLAGS += @EXTRALIBS@
@@ -68,21 +71,21 @@ 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 bin32
rm -rf *.o dep cadpli.vpl
distclean: clean
rm -f Makefile config.status config.log config.cache
rm -f Makefile config.log
install: all installdirs $(vpidir)/cadpli.vpl $(INSTALL32)
install: all installdirs $(vpidir)/cadpli.vpl
$(vpidir)/cadpli.vpl: ./cadpli.vpl
$(INSTALL_PROGRAM) ./cadpli.vpl $(DESTDIR)$(vpidir)/cadpli.vpl
$(INSTALL_PROGRAM) ./cadpli.vpl "$(DESTDIR)$(vpidir)/cadpli.vpl"
installdirs: ../mkinstalldirs
$(srcdir)/../mkinstalldirs $(DESTDIR)$(vpidir)
installdirs: $(srcdir)/../mkinstalldirs
$(srcdir)/../mkinstalldirs "$(DESTDIR)$(vpidir)"
uninstall: $(UNINSTALL32)
rm -f $(DESTDIR)$(vpidir)/cadpli.vpl
rm -f "$(DESTDIR)$(vpidir)/cadpli.vpl"
uninstall32:
+2 -35
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2003 Stephen Williams ([email protected])
* Copyright (c) 2003-2008 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
@@ -16,9 +16,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: cadpli.c,v 1.7 2004/09/10 00:15:45 steve Exp $"
#endif
# include <vpi_user.h>
# include <veriuser.h>
@@ -28,6 +25,7 @@
#endif
# include <string.h>
# include <assert.h>
# include "config.h"
# include "ivl_dlfcn.h"
typedef void* (*funcvp)(void);
@@ -87,34 +85,3 @@ void (*vlog_startup_routines[])() = {
thunker_register,
0
};
/*
* $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.
*
* Revision 1.4 2003/04/30 01:28:06 steve
* Remove veriusertfs stuf.
*
* Revision 1.3 2003/02/22 04:04:38 steve
* Only include malloc.h if it is present.
*
* Revision 1.2 2003/02/17 00:01:25 steve
* Use a variant of ivl_dlfcn to do dynamic loading
* from within the cadpli module.
*
* Change the +cadpli flag to -cadpli, to keep the
* plusargs namespace clear.
*
* Revision 1.1 2003/02/16 02:23:54 steve
* Add the cadpli interface module.
*
*/
-13
View File
@@ -2,7 +2,6 @@
CADENCE PLI1 MODULES
Copyright 2003 Stephen Williams
$Id: cadpli.txt,v 1.2 2003/02/17 00:01:25 steve Exp $
With the cadpli module, Icarus Verilog is able to load PLI1
applications that were compiled and linked to be dynamic loaded by
@@ -34,15 +33,3 @@ the +loadpli1= argument to Verilog-XL.
The integration from this point is seamless. The PLI application
hardly knows that it is being invoked by Icarus Verilog instead of
Verilog-XL, so operates as it would otherwise.
$Log: cadpli.txt,v $
Revision 1.2 2003/02/17 00:01:25 steve
Use a variant of ivl_dlfcn to do dynamic loading
from within the cadpli module.
Change the +cadpli flag to -cadpli, to keep the
plusargs namespace clear.
Revision 1.1 2003/02/16 02:44:47 steve
Add the cadpli HOWTO.
-61
View File
@@ -1,61 +0,0 @@
AC_INIT(Makefile.in)
AC_PROG_CC
AC_PROG_CXX
AC_CHECK_TOOL(STRIP, strip, true)
AC_EXEEXT
AC_SUBST(EXEEXT)
# Combined check for Microsoft-related bogosities; sets WIN32 if found
AX_WIN32
AC_PROG_INSTALL
AC_CHECK_HEADERS(malloc.h)
AC_CHECK_SIZEOF(unsigned long long)
AC_CHECK_SIZEOF(unsigned long)
AC_CHECK_SIZEOF(unsigned)
# --
# 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.
AC_CHECK_HEADERS(dlfcn.h dl.h, break)
DLLIB=''
AC_CHECK_LIB(dl,dlopen,[DLLIB=-ldl])
if test -z "$DLLIB" ; then
AC_CHECK_LIB(dld,shl_load,[DLLIB=-ldld])
fi
AC_SUBST(DLLIB)
AX_CPP_PRECOMP
# Compiler option for position independent code, needed when making shared objects.
AX_C_PICFLAG
# Linker option used when compiling the target
AX_LD_RDYNAMIC
# linker options when building a shared library
AX_LD_SHAREDLIB_OPTS
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.
#######################
AX_C_UNDERSCORES_LEADING
AX_C_UNDERSCORES_TRAILING
#######################
## end of test for underscores
#######################
AX_CPP_IDENT
AC_OUTPUT(Makefile)
-19
View File
@@ -18,9 +18,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: ivl_dlfcn.h,v 1.3 2004/10/04 01:10:56 steve Exp $"
#endif
#if defined(__MINGW32__)
# include <windows.h>
@@ -94,20 +91,4 @@ static __inline__ const char*dlerror(void)
{ return strerror( errno ); }
#endif
/*
* $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.
*
* Change the +cadpli flag to -cadpli, to keep the
* plusargs namespace clear.
*
*/
#endif
+36 -6
View File
@@ -1,7 +1,7 @@
#ifndef __compiler_H
#define __compiler_H
/*
* Copyright (c) 1999-2008 Stephen Williams ([email protected])
* Copyright (c) 1999-2010 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
@@ -36,6 +36,12 @@
*/
extern unsigned integer_width;
/*
* This is the maximum number of recursive module loops allowed within
* a generate block.
*/
extern unsigned recursive_mod_limit;
/* The TIME_WIDTH is the width of time variables. */
#ifndef TIME_WIDTH
# define TIME_WIDTH 64
@@ -68,7 +74,6 @@ extern unsigned integer_width;
/* Implicit definitions of wires. */
extern bool warn_implicit;
extern bool error_implicit;
/* inherit timescales across files. */
extern bool warn_timescale;
@@ -76,18 +81,32 @@ extern bool warn_timescale;
/* Warn about legal but questionable module port bindings. */
extern bool warn_portbinding;
/* Warn about constant out of bound selects. */
extern bool warn_ob_select;
/* Warn about structures that may have infinite loops. */
extern bool warn_inf_loop;
/* Warn about always @* statements where a part or word select causes
sensitivity to an entire vector or array. */
extern bool warn_sens_entire_vec;
extern bool warn_sens_entire_arr;
/* 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;
extern bool debug_elab_pexpr;
extern bool debug_synth2;
extern bool debug_optimizer;
extern bool debug_automatic;
/* Possibly temporary flag to control virtualization of pin arrays */
extern bool disable_virtual_pins;
/* Limit to size of devirtualized arrays */
extern unsigned long array_size_limit;
/* Path to a directory useful for finding subcomponents. */
extern const char*basedir;
@@ -101,9 +120,10 @@ extern int build_library_index(const char*path, bool key_case_sensitive);
specific language features. */
enum generation_t {
GN_VER1995 = 1,
GN_VER2001 = 2,
GN_VER2005 = 3,
GN_DEFAULT = 3
GN_VER2001_NOCONFIG = 2,
GN_VER2001 = 3,
GN_VER2005 = 4,
GN_DEFAULT = 4
};
extern generation_t generation_flag;
@@ -121,10 +141,18 @@ extern bool gn_specify_blocks_flag;
/* If this flag is true, then support/elaborate Verilog-AMS. */
extern bool gn_verilog_ams_flag;
/* If this flag is true, then support/elaborate SystemVerilog. */
extern bool gn_system_verilog_flag;
/* If this flag is false a warning is printed when the port declaration
is scalar and the net/register definition is vectored. */
extern bool gn_io_range_error_flag;
/* If this flag is true, then force re-evaluation of user functions
in a continuous assignment when any part of the expression is
re-evaluated. */
extern bool gn_strict_ca_eval_flag;
/* The bits of these GN_KEYWORDS_* constants define non-intersecting
sets of keywords. The compiler enables groups of keywords by setting
lexor_keyword_mask with the OR of the bits for the keywords to be
@@ -134,6 +162,7 @@ enum { GN_KEYWORDS_1364_1995 = 0x0001,
GN_KEYWORDS_1364_2001_CONFIG = 0x0004,
GN_KEYWORDS_1364_2005 = 0x0008,
GN_KEYWORDS_VAMS_2_3 = 0x0010,
GN_KEYWORDS_1800_2005 = 0x0020,
GN_KEYWORDS_ICARUS = 0x8000
};
extern int lexor_keyword_mask;
@@ -183,5 +212,6 @@ struct sfunc_return_type {
extern const struct sfunc_return_type* lookup_sys_func(const char*name);
extern int load_sys_func_table(const char*path);
extern void cleanup_sys_func_table();
#endif
+581 -384
View File
File diff suppressed because it is too large Load Diff
+5 -42
View File
@@ -1,7 +1,7 @@
#ifndef __config_H /* -*- c++ -*- */
#define __config_H
/*
* Copyright (c) 2001 Stephen Williams ([email protected])
* Copyright (c) 2001-2009 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
@@ -18,9 +18,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: config.h.in,v 1.12 2007/02/02 04:33:00 steve Exp $"
#endif
#if defined(__cplusplus)
# if !defined(__GNUC__)
@@ -54,43 +51,9 @@
#endif
/*
* $Log: config.h.in,v $
* Revision 1.12 2007/02/02 04:33:00 steve
* Use inttypes.h instead of stdint.h for portability.
*
* 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.
*
* Revision 1.9 2003/07/03 16:29:55 steve
* spemm WORDS_BIGENDIAN correctly.
*
* Revision 1.8 2003/03/07 02:44:33 steve
* Implement $realtobits.
*
* Revision 1.7 2003/02/20 00:49:24 steve
* detect -lz and -lbz2 libraries.
*
* Revision 1.6 2003/01/10 19:01:04 steve
* Only use libiberty.h if available.
*
* Revision 1.5 2002/08/11 23:39:33 steve
* Remove VVM option.
*
* Revision 1.4 2002/02/16 03:18:53 steve
* Make vvm optional, normally off.
*
* Revision 1.3 2001/10/18 16:16:23 steve
* Include HAVE_SYS_WAIT in config.h (PR#306)
*
* Revision 1.2 2001/09/15 18:27:04 steve
* Make configure detect malloc.h
*
* Revision 1.1 2001/07/25 03:10:48 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
*
* Define this if you want to compile vvp with memory freeing and
* special valgrind hooks for the memory pools.
*/
# undef CHECK_WITH_VALGRIND
#endif /* __config_H */
Vendored
+322 -93
View File
@@ -1,9 +1,10 @@
#! /bin/sh
# Configuration validation subroutine script.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
# 2000, 2001, 2002 Free Software Foundation, Inc.
# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
# Free Software Foundation, Inc.
timestamp='2002-07-03'
timestamp='2009-04-17'
# This file is (in principle) common to ALL GNU software.
# The presence of a machine in this file suggests that SOME GNU software
@@ -21,14 +22,15 @@ timestamp='2002-07-03'
#
# 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.
# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
# 02110-1301, USA.
#
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# Please send patches to <[email protected]>. Submit a context
# diff and a properly formatted ChangeLog entry.
#
@@ -70,8 +72,8 @@ Report bugs and patches to <[email protected]>."
version="\
GNU config.sub ($timestamp)
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
Free Software Foundation, Inc.
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -83,11 +85,11 @@ Try \`$me --help' for more information."
while test $# -gt 0 ; do
case $1 in
--time-stamp | --time* | -t )
echo "$timestamp" ; exit 0 ;;
echo "$timestamp" ; exit ;;
--version | -v )
echo "$version" ; exit 0 ;;
echo "$version" ; exit ;;
--help | --h* | -h )
echo "$usage"; exit 0 ;;
echo "$usage"; exit ;;
-- ) # Stop option processing
shift; break ;;
- ) # Use stdin as input.
@@ -99,7 +101,7 @@ while test $# -gt 0 ; do
*local*)
# First pass through any local machine types.
echo $1
exit 0;;
exit ;;
* )
break ;;
@@ -118,7 +120,10 @@ esac
# Here we must recognize all the valid KERNEL-OS combinations.
maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
case $maybe_os in
nto-qnx* | linux-gnu* | freebsd*-gnu* | storm-chaos* | os2-emx* | windows32-* | rtmk-nova*)
nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \
uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \
kopensolaris*-gnu* | \
storm-chaos* | os2-emx* | rtmk-nova*)
os=-$maybe_os
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
;;
@@ -144,7 +149,7 @@ case $os in
-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
-apple | -axis)
-apple | -axis | -knuth | -cray)
os=
basic_machine=$1
;;
@@ -169,6 +174,10 @@ case $os in
-hiux*)
os=-hiuxwe2
;;
-sco6)
os=-sco5v6
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-sco5)
os=-sco3.2v5
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
@@ -185,6 +194,10 @@ case $os in
# Don't forget version if it is 3.2v4 or newer.
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-sco5v6*)
# Don't forget version if it is 3.2v4 or newer.
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-sco*)
os=-sco3.2v2
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
@@ -228,40 +241,57 @@ case $basic_machine in
| a29k \
| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \
| am33_2.0 \
| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
| bfin \
| c4x | clipper \
| d10v | d30v | dlx | dsp16xx \
| fr30 | frv \
| fido | fr30 | frv \
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
| i370 | i860 | i960 | ia64 \
| ip2k \
| m32r | m68000 | m68k | m88k | mcore \
| ip2k | iq2000 \
| lm32 \
| m32c | m32r | m32rle | m68000 | m68k | m88k \
| maxq | mb | microblaze | mcore | mep | metag \
| mips | mipsbe | mipseb | mipsel | mipsle \
| mips16 \
| mips64 | mips64el \
| mips64octeon | mips64octeonel \
| mips64orion | mips64orionel \
| mips64r5900 | mips64r5900el \
| mips64vr | mips64vrel \
| mips64vr4100 | mips64vr4100el \
| mips64vr4300 | mips64vr4300el \
| mips64vr5000 | mips64vr5000el \
| mips64vr5900 | mips64vr5900el \
| mipsisa32 | mipsisa32el \
| mipsisa32r2 | mipsisa32r2el \
| mipsisa64 | mipsisa64el \
| mipsisa64r2 | mipsisa64r2el \
| mipsisa64sb1 | mipsisa64sb1el \
| mipsisa64sr71k | mipsisa64sr71kel \
| mipstx39 | mipstx39el \
| mn10200 | mn10300 \
| moxie \
| mt \
| msp430 \
| nios | nios2 \
| ns16k | ns32k \
| openrisc | or32 \
| or32 \
| pdp10 | pdp11 | pj | pjl \
| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
| pyramid \
| sh | sh[1234] | sh3e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \
| score \
| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
| sh64 | sh64le \
| sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv9 | sparcv9b \
| strongarm \
| tahoe | thumb | tic80 | tron \
| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
| sparcv8 | sparcv9 | sparcv9b | sparcv9v \
| spu | strongarm \
| tahoe | thumb | tic4x | tic80 | tron \
| v850 | v850e \
| we32k \
| x86 | xscale | xstormy16 | xtensa \
| z8k)
| x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \
| z8k | z80)
basic_machine=$basic_machine-unknown
;;
m6811 | m68hc11 | m6812 | m68hc12)
@@ -271,6 +301,9 @@ case $basic_machine in
;;
m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
;;
ms1)
basic_machine=mt-unknown
;;
# We use `pc' rather than `unknown'
# because (1) that's what they normally are, and
@@ -290,48 +323,67 @@ case $basic_machine in
| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
| arm-* | armbe-* | armle-* | armeb-* | armv*-* \
| avr-* \
| bs2000-* \
| c[123]* | c30-* | [cjt]90-* | c54x-* \
| clipper-* | cydra-* \
| avr-* | avr32-* \
| bfin-* | bs2000-* \
| c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
| clipper-* | craynv-* | cydra-* \
| d10v-* | d30v-* | dlx-* \
| elxsi-* \
| f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \
| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
| h8300-* | h8500-* \
| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
| i*86-* | i860-* | i960-* | ia64-* \
| ip2k-* \
| m32r-* \
| ip2k-* | iq2000-* \
| lm32-* \
| m32c-* | m32r-* | m32rle-* \
| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
| m88110-* | m88k-* | mcore-* \
| m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
| mips16-* \
| mips64-* | mips64el-* \
| mips64octeon-* | mips64octeonel-* \
| mips64orion-* | mips64orionel-* \
| mips64r5900-* | mips64r5900el-* \
| mips64vr-* | mips64vrel-* \
| mips64vr4100-* | mips64vr4100el-* \
| mips64vr4300-* | mips64vr4300el-* \
| mips64vr5000-* | mips64vr5000el-* \
| mips64vr5900-* | mips64vr5900el-* \
| mipsisa32-* | mipsisa32el-* \
| mipsisa32r2-* | mipsisa32r2el-* \
| mipsisa64-* | mipsisa64el-* \
| mipsisa64r2-* | mipsisa64r2el-* \
| mipsisa64sb1-* | mipsisa64sb1el-* \
| mipstx39 | mipstx39el \
| mipsisa64sr71k-* | mipsisa64sr71kel-* \
| mipstx39-* | mipstx39el-* \
| mmix-* \
| mt-* \
| msp430-* \
| nios-* | nios2-* \
| none-* | np1-* | ns16k-* | ns32k-* \
| orion-* \
| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
| pyramid-* \
| romp-* | rs6000-* \
| sh-* | sh[1234]-* | sh3e-* | sh[34]eb-* | shbe-* \
| sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
| sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \
| sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \
| tahoe-* | thumb-* | tic30-* | tic54x-* | tic80-* | tron-* \
| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
| sparclite-* \
| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \
| tahoe-* | thumb-* \
| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* | tile-* \
| tron-* \
| v850-* | v850e-* | vax-* \
| we32k-* \
| x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \
| xtensa-* \
| x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \
| xstormy16-* | xtensa*-* \
| ymp-* \
| z8k-*)
| z8k-* | z80-*)
;;
# Recognize the basic CPU types without company name, with glob match.
xtensa*)
basic_machine=$basic_machine-unknown
;;
# Recognize the various machine names and aliases which stand
# for a CPU type and a company and sometimes even an OS.
@@ -349,6 +401,9 @@ case $basic_machine in
basic_machine=a29k-amd
os=-udi
;;
abacus)
basic_machine=abacus-unknown
;;
adobe68k)
basic_machine=m68010-adobe
os=-scout
@@ -363,6 +418,12 @@ case $basic_machine in
basic_machine=a29k-none
os=-bsd
;;
amd64)
basic_machine=x86_64-pc
;;
amd64-*)
basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
amdahl)
basic_machine=580-amdahl
os=-sysv
@@ -386,6 +447,10 @@ case $basic_machine in
basic_machine=m68k-apollo
os=-bsd
;;
aros)
basic_machine=i386-pc
os=-aros
;;
aux)
basic_machine=m68k-apple
os=-aux
@@ -394,10 +459,22 @@ case $basic_machine in
basic_machine=ns32k-sequent
os=-dynix
;;
blackfin)
basic_machine=bfin-unknown
os=-linux
;;
blackfin-*)
basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
os=-linux
;;
c90)
basic_machine=c90-cray
os=-unicos
;;
cegcc)
basic_machine=arm-unknown
os=-cegcc
;;
convex-c1)
basic_machine=c1-convex
os=-bsd
@@ -422,12 +499,27 @@ case $basic_machine in
basic_machine=j90-cray
os=-unicos
;;
craynv)
basic_machine=craynv-cray
os=-unicosmp
;;
cr16)
basic_machine=cr16-unknown
os=-elf
;;
crds | unos)
basic_machine=m68k-crds
;;
crisv32 | crisv32-* | etraxfs*)
basic_machine=crisv32-axis
;;
cris | cris-* | etrax*)
basic_machine=cris-axis
;;
crx)
basic_machine=crx-unknown
os=-elf
;;
da30 | da30-*)
basic_machine=m68k-da30
;;
@@ -450,6 +542,14 @@ case $basic_machine in
basic_machine=m88k-motorola
os=-sysv3
;;
dicos)
basic_machine=i686-pc
os=-dicos
;;
djgpp)
basic_machine=i586-pc
os=-msdosdjgpp
;;
dpx20 | dpx20-*)
basic_machine=rs6000-bull
os=-bosx
@@ -600,6 +700,14 @@ case $basic_machine in
basic_machine=m68k-isi
os=-sysv
;;
m68knommu)
basic_machine=m68k-unknown
os=-linux
;;
m68knommu-*)
basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
os=-linux
;;
m88k-omron*)
basic_machine=m88k-omron
;;
@@ -615,6 +723,10 @@ case $basic_machine in
basic_machine=i386-pc
os=-mingw32
;;
mingw32ce)
basic_machine=arm-unknown
os=-mingw32ce
;;
miniframe)
basic_machine=m68000-convergent
;;
@@ -628,10 +740,6 @@ case $basic_machine in
mips3*)
basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
;;
mmix*)
basic_machine=mmix-knuth
os=-mmixware
;;
monitor)
basic_machine=m68k-rom68k
os=-coff
@@ -644,6 +752,9 @@ case $basic_machine in
basic_machine=i386-pc
os=-msdos
;;
ms1-*)
basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
;;
mvs)
basic_machine=i370-ibm
os=-mvs
@@ -719,9 +830,12 @@ case $basic_machine in
basic_machine=hppa1.1-oki
os=-proelf
;;
or32 | or32-*)
openrisc | openrisc-*)
basic_machine=or32-unknown
os=-coff
;;
os400)
basic_machine=powerpc-ibm
os=-os400
;;
OSE68000 | ose68000)
basic_machine=m68000-ericsson
@@ -739,55 +853,75 @@ case $basic_machine in
basic_machine=i860-intel
os=-osf
;;
parisc)
basic_machine=hppa-unknown
os=-linux
;;
parisc-*)
basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
os=-linux
;;
pbd)
basic_machine=sparc-tti
;;
pbb)
basic_machine=m68k-tti
;;
pc532 | pc532-*)
pc532 | pc532-*)
basic_machine=ns32k-pc532
;;
pc98)
basic_machine=i386-pc
;;
pc98-*)
basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
pentium | p5 | k5 | k6 | nexgen | viac3)
basic_machine=i586-pc
;;
pentiumpro | p6 | 6x86 | athlon)
pentiumpro | p6 | 6x86 | athlon | athlon_*)
basic_machine=i686-pc
;;
pentiumii | pentium2)
pentiumii | pentium2 | pentiumiii | pentium3)
basic_machine=i686-pc
;;
pentium4)
basic_machine=i786-pc
;;
pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
pentiumpro-* | p6-* | 6x86-* | athlon-*)
basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
pentiumii-* | pentium2-*)
pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
pentium4-*)
basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
pn)
basic_machine=pn-gould
;;
power) basic_machine=power-ibm
;;
ppc) basic_machine=powerpc-unknown
;;
;;
ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
ppcle | powerpclittle | ppc-le | powerpc-little)
basic_machine=powerpcle-unknown
;;
;;
ppcle-* | powerpclittle-*)
basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
ppc64) basic_machine=powerpc64-unknown
;;
;;
ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
ppc64le | powerpc64little | ppc64-le | powerpc64-little)
basic_machine=powerpc64le-unknown
;;
;;
ppc64le-* | powerpc64little-*)
basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
@@ -798,6 +932,10 @@ case $basic_machine in
basic_machine=i586-unknown
os=-pw32
;;
rdos)
basic_machine=i386-pc
os=-rdos
;;
rom68k)
basic_machine=m68k-rom68k
os=-coff
@@ -818,6 +956,20 @@ case $basic_machine in
basic_machine=a29k-amd
os=-udi
;;
sb1)
basic_machine=mipsisa64sb1-unknown
;;
sb1el)
basic_machine=mipsisa64sb1el-unknown
;;
sde)
basic_machine=mipsisa32-sde
os=-elf
;;
sei)
basic_machine=mips-sei
os=-seiux
;;
sequent)
basic_machine=i386-sequent
;;
@@ -825,6 +977,12 @@ case $basic_machine in
basic_machine=sh-hitachi
os=-hms
;;
sh5el)
basic_machine=sh5le-unknown
;;
sh64)
basic_machine=sh64-unknown
;;
sparclite-wrs | simso-wrs)
basic_machine=sparclite-wrs
os=-vxworks
@@ -883,7 +1041,7 @@ case $basic_machine in
sun386 | sun386i | roadrunner)
basic_machine=i386-sun
;;
sv1)
sv1)
basic_machine=sv1-cray
os=-unicos
;;
@@ -891,10 +1049,6 @@ case $basic_machine in
basic_machine=i386-sequent
os=-dynix
;;
t3d)
basic_machine=alpha-cray
os=-unicos
;;
t3e)
basic_machine=alphaev5-cray
os=-unicos
@@ -907,6 +1061,18 @@ case $basic_machine in
basic_machine=tic54x-unknown
os=-coff
;;
tic55x | c55x*)
basic_machine=tic55x-unknown
os=-coff
;;
tic6x | c6x*)
basic_machine=tic6x-unknown
os=-coff
;;
tile*)
basic_machine=tile-unknown
os=-linux-gnu
;;
tx39)
basic_machine=mipstx39-unknown
;;
@@ -920,6 +1086,10 @@ case $basic_machine in
tower | tower-32)
basic_machine=m68k-ncr
;;
tpf)
basic_machine=s390x-ibm
os=-tpf
;;
udi29k)
basic_machine=a29k-amd
os=-udi
@@ -941,8 +1111,8 @@ case $basic_machine in
os=-vms
;;
vpp*|vx|vx-*)
basic_machine=f301-fujitsu
;;
basic_machine=f301-fujitsu
;;
vxworks960)
basic_machine=i960-wrs
os=-vxworks
@@ -963,11 +1133,11 @@ case $basic_machine in
basic_machine=hppa1.1-winbond
os=-proelf
;;
windows32)
basic_machine=i386-pc
os=-windows32-msvcrt
xbox)
basic_machine=i686-pc
os=-mingw32
;;
xps | xps100)
xps | xps100)
basic_machine=xps100-honeywell
;;
ymp)
@@ -978,6 +1148,10 @@ case $basic_machine in
basic_machine=z8k-unknown
os=-sim
;;
z80-*-coff)
basic_machine=z80-unknown
os=-sim
;;
none)
basic_machine=none-none
os=-none
@@ -997,6 +1171,9 @@ case $basic_machine in
romp)
basic_machine=romp-ibm
;;
mmix)
basic_machine=mmix-knuth
;;
rs6000)
basic_machine=rs6000-ibm
;;
@@ -1013,16 +1190,13 @@ case $basic_machine in
we32k)
basic_machine=we32k-att
;;
sh3 | sh4 | sh3eb | sh4eb | sh[1234]le | sh3ele)
sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
basic_machine=sh-unknown
;;
sh64)
basic_machine=sh64-unknown
;;
sparc | sparcv9 | sparcv9b)
sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
basic_machine=sparc-sun
;;
cydra)
cydra)
basic_machine=cydra-cydrome
;;
orion)
@@ -1037,10 +1211,6 @@ case $basic_machine in
pmac | pmac-mpw)
basic_machine=powerpc-apple
;;
c4x*)
basic_machine=c4x-none
os=-coff
;;
*-unknown)
# Make sure to match an already-canonicalized machine name.
;;
@@ -1092,22 +1262,28 @@ case $os in
-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
| -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
| -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
| -kopensolaris* \
| -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
| -aos* \
| -aos* | -aros* \
| -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
| -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
| -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \
| -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
| -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
| -openbsd* | -solidbsd* \
| -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
| -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
| -chorusos* | -chorusrdb* \
| -chorusos* | -chorusrdb* | -cegcc* \
| -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
| -mingw32* | -linux* | -uxpv* | -beos* | -mpeix* | -udk* \
| -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \
| -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \
| -uxpv* | -beos* | -mpeix* | -udk* \
| -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
| -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
| -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
| -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
| -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* | -powermax*)
| -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
| -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
| -skyos* | -haiku* | -rdos* | -toppers* | -drops*)
# Remember, each alternative MUST END IN *, to match a version number.
;;
-qnx*)
@@ -1119,16 +1295,24 @@ case $os in
;;
esac
;;
-nto-qnx*)
;;
-nto*)
os=-nto-qnx
os=`echo $os | sed -e 's|nto|nto-qnx|'`
;;
-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
| -windows* | -osx | -abug | -netware* | -os9* | -beos* \
| -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
| -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
;;
-mac*)
os=`echo $os | sed -e 's|mac|macos|'`
;;
-linux-dietlibc)
os=-linux-dietlibc
;;
-linux*)
os=`echo $os | sed -e 's|linux|linux-gnu|'`
;;
-sunos5*)
os=`echo $os | sed -e 's|sunos5|solaris2|'`
;;
@@ -1138,6 +1322,9 @@ case $os in
-opened*)
os=-openedition
;;
-os400*)
os=-os400
;;
-wince*)
os=-wince
;;
@@ -1159,6 +1346,9 @@ case $os in
-atheos*)
os=-atheos
;;
-syllable*)
os=-syllable
;;
-386bsd)
os=-bsd
;;
@@ -1169,7 +1359,7 @@ case $os in
os=-rtmk-nova
;;
-ns2 )
os=-nextstep2
os=-nextstep2
;;
-nsk*)
os=-nsk
@@ -1181,6 +1371,9 @@ case $os in
-sinix*)
os=-sysv4
;;
-tpf*)
os=-tpf
;;
-triton*)
os=-sysv3
;;
@@ -1208,8 +1401,20 @@ case $os in
-xenix)
os=-xenix
;;
-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
os=-mint
-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
os=-mint
;;
-aros*)
os=-aros
;;
-kaos*)
os=-kaos
;;
-zvmoe)
os=-zvmoe
;;
-dicos*)
os=-dicos
;;
-none)
;;
@@ -1233,6 +1438,12 @@ else
# system, and we'll never get to this point.
case $basic_machine in
score-*)
os=-elf
;;
spu-*)
os=-elf
;;
*-acorn)
os=-riscix1.2
;;
@@ -1242,11 +1453,14 @@ case $basic_machine in
arm*-semi)
os=-aout
;;
c4x-* | tic4x-*)
os=-coff
;;
# This must come before the *-dec entry.
pdp10-*)
os=-tops20
;;
pdp11-*)
pdp11-*)
os=-none
;;
*-dec | vax-*)
@@ -1267,6 +1481,9 @@ case $basic_machine in
m68*-cisco)
os=-aout
;;
mep-*)
os=-elf
;;
mips*-cisco)
os=-elf
;;
@@ -1285,9 +1502,15 @@ case $basic_machine in
*-be)
os=-beos
;;
*-haiku)
os=-haiku
;;
*-ibm)
os=-aix
;;
*-knuth)
os=-mmixware
;;
*-wec)
os=-proelf
;;
@@ -1339,19 +1562,19 @@ case $basic_machine in
*-next)
os=-nextstep3
;;
*-gould)
*-gould)
os=-sysv
;;
*-highlevel)
*-highlevel)
os=-bsd
;;
*-encore)
os=-bsd
;;
*-sgi)
*-sgi)
os=-irix
;;
*-siemens)
*-siemens)
os=-sysv4
;;
*-masscomp)
@@ -1420,9 +1643,15 @@ case $basic_machine in
-mvs* | -opened*)
vendor=ibm
;;
-os400*)
vendor=ibm
;;
-ptx*)
vendor=sequent
;;
-tpf*)
vendor=ibm
;;
-vxsim* | -vxworks* | -windiss*)
vendor=wrs
;;
@@ -1447,7 +1676,7 @@ case $basic_machine in
esac
echo $basic_machine$os
exit 0
exit
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
+129 -3
View File
@@ -2,11 +2,24 @@ dnl Process this file with autoconf to produce a configure script.
AC_INIT(netlist.h)
AC_CONFIG_HEADER(config.h)
AC_CONFIG_HEADER(_pli_types.h)
AC_CONFIG_HEADER(vvp/config.h)
AC_CONFIG_HEADER(vpi/vpi_config.h)
AC_CONFIG_HEADER(libveriuser/config.h)
AC_CONFIG_HEADER(tgt-vvp/vvp_config.h)
AC_CONFIG_HEADER(tgt-vhdl/vhdl_config.h)
AC_CANONICAL_HOST
dnl Checks for programs.
AC_PROG_CC
# AC_PROG_CC_C99 is only available in autoconf version 2.60 and later.
# If you must use an older version then comment out the following two
# lines, but be warned that there could be issues with finding the
# nan(), etc. functions. It is really best to upgrade to a supported
# version of autoconf.
AC_PREREQ([2.60])
AC_PROG_CC_C99
AC_PROG_CXX
AC_PROG_RANLIB
AC_CHECK_TOOL(STRIP, strip, true)
AC_CHECK_PROGS(XGPERF,gperf,none)
AC_CHECK_PROGS(MAN,man,none)
@@ -49,6 +62,19 @@ AC_LANG_CPLUSPLUS
AC_CHECK_HEADERS(getopt.h malloc.h inttypes.h libiberty.h iosfwd sys/wait.h)
AC_CHECK_SIZEOF(unsigned long long)
AC_CHECK_SIZEOF(unsigned long)
AC_CHECK_SIZEOF(unsigned)
# vvp uses these...
AC_CHECK_LIB(termcap, tputs)
AC_CHECK_LIB(readline, readline)
AC_CHECK_LIB(history, add_history)
AC_CHECK_HEADERS(readline/readline.h readline/history.h sys/resource.h)
case "${host}" in *linux*) AC_DEFINE([LINUX], [1], [Host operating system is Linux.]) ;; esac
# vpi uses these
AC_CHECK_LIB(pthread, pthread_create)
AC_CHECK_LIB(z, gzwrite)
AC_CHECK_LIB(z, gzwrite, HAVE_LIBZ=yes, HAVE_LIBZ=no)
AC_SUBST(HAVE_LIBZ)
@@ -61,6 +87,23 @@ AC_CHECK_LIB(bz2, BZ2_bzdopen, HAVE_LIBBZ2=yes, HAVE_LIBBZ2=no)
fi
AC_SUBST(HAVE_LIBBZ2)
# The lxt/lxt2 files from GTKWave use these...
AC_FUNC_ALLOCA
AC_FUNC_FSEEKO
# valgrind checks
AC_ARG_WITH([valgrind], [AC_HELP_STRING([--with-valgrind],
[Add valgrind hooks])],
[], [check_valgrind=yes])
AS_IF([test "x$check_valgrind" = xyes],
[AC_MSG_NOTICE([Not using valgrind hooks])],
[AC_CHECK_HEADER([valgrind/memcheck.h],
[AC_DEFINE([CHECK_WITH_VALGRIND], [1],
[Define to one to use the valgrind hooks])],
[AC_MSG_ERROR([Could not find <valgrind/memcheck.h>])])])
AC_MSG_CHECKING(for sys/times)
AC_TRY_LINK(
#include <unistd.h>
@@ -92,6 +135,8 @@ AC_C_BIGENDIAN
# $host
AX_ENABLE_SUFFIX
AX_LD_EXTRALIBS
# Compiler option for position independent code, needed when making shared objects.
@@ -101,6 +146,65 @@ AX_C_PICFLAG
# may modify CPPFLAGS and CFLAGS
AX_CPP_PRECOMP
# Processor specific compile flags
case "${host}" in
alpha*-*-linux*)
CPPFLAGS="-mieee $CPPFLAGS"
CFLAGS="-mieee $CFLAGS"
;;
esac
# Do some more operating system specific setup. We put the file64_support
# define in a substitution instead of simply a define because there
# are source files (namely lxt support files) that don't include any
# config.h header file.
file64_support=''
case "${host}" in
*-*-linux*)
AC_DEFINE([_LARGEFILE_SOURCE], [1], [Indicates LFS (i.e. the ability to create files larger than 2 GiB on 32-bit operating systems).])
file64_support='-D_LARGEFILE_SOURCE=1 -D_FILE_OFFSET_BITS=64'
;;
esac
AC_SUBST(file64_support)
# Check that these functions exist. They are mostly C99
# functions that older compilers may not yet support.
AC_CHECK_FUNCS(fopen64)
# The following math functions may be defined in the math library so look
# in the default libraries first and then look in -lm for them. On some
# systems we may need to use the compiler in C99 mode to get a definition.
# We requested C99 mode earlier with AC_PROG_CC_C99.
AC_SEARCH_LIBS([lround], [m], [AC_DEFINE([HAVE_LROUND], [1])])
AC_SEARCH_LIBS([llround], [m], [AC_DEFINE([HAVE_LLROUND], [1])])
AC_SEARCH_LIBS([nan], [m], [AC_DEFINE([HAVE_NAN], [1])])
AC_SEARCH_LIBS([fmin], [m], [AC_DEFINE([HAVE_FMIN], [1])])
AC_SEARCH_LIBS([fmax], [m], [AC_DEFINE([HAVE_FMAX], [1])])
# Check to see if an unsigned long and uint64_t are the same from
# a compiler perspective. We can not just check that they are the
# same size since unsigned long and unsigned long long are not the
# same from an overloading perspective even though they could be
# the same size on some 64 bit machines. The result from this test
# is only used if inttypes.h is available, so if the test fails for
# that reason we don't care.
AC_LANG(C++)
AC_MSG_CHECKING(if uint64_t and unsigned long are identical)
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include "inttypes.h"
static bool check(unsigned long val)
{
return val != 0;
}
static bool check(uint64_t val)
{
return val != 0;
}]], [[unsigned long ulval = 1;
bool result = check(ulval);
uint64_t uival = 1;
result &= check(uival);
return !result;]])],
[AC_MSG_RESULT(no)],
[AC_DEFINE([UINT64_T_AND_ULONG_SAME], [1]) AC_MSG_RESULT(yes)])
# Linker option used when compiling the target
AX_LD_RDYNAMIC
@@ -119,9 +223,31 @@ AX_C_UNDERSCORES_TRAILING
## end of test for underscores
#######################
AX_CPP_IDENT
#######################
# Sanity check the configured results
#######################
AC_MSG_CHECKING(for sanity of prefix)
if test `echo "$prefix" | wc -w` != 1
then
AC_MSG_ERROR(cannot configure white space in prefix: $prefix)
fi
AC_MSG_RESULT(ok)
AC_MSG_CHECKING(for sanity of exec_prefix)
if test `echo "$exec_prefix" | wc -w` != 1
then
AC_MSG_ERROR(cannot configure white space in exec_prefix: $exec_prefix)
fi
AC_MSG_RESULT(ok)
AC_MSG_CHECKING(for sanity of libdir)
if test `echo "$libdir" | wc -w` != 1
then
AC_MSG_ERROR(cannot configure white space in libdir: $libdir)
fi
AC_MSG_RESULT(ok)
# XXX disable tgt-fpga for the moment
AC_CONFIG_SUBDIRS(vvp vpi tgt-stub tgt-null tgt-vvp tgt-vhdl libveriuser cadpli)
AC_OUTPUT(Makefile ivlpp/Makefile driver/Makefile driver-vpi/Makefile tgt-null/Makefile tgt-verilog/Makefile tgt-pal/Makefile)
AC_OUTPUT(Makefile ivlpp/Makefile vvp/Makefile vpi/Makefile driver/Makefile driver-vpi/Makefile cadpli/Makefile libveriuser/Makefile tgt-null/Makefile tgt-stub/Makefile tgt-vvp/Makefile tgt-vhdl/Makefile tgt-fpga/Makefile tgt-verilog/Makefile tgt-pal/Makefile)
+66 -760
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998-2008 Stephen Williams ([email protected])
* Copyright (c) 1998-2009 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
@@ -25,7 +25,7 @@
# include "functor.h"
# include "compiler.h"
# include "ivl_assert.h"
# include <vector>
/*
@@ -72,127 +72,6 @@ void cprop_functor::lpm_compare(Design*des, NetCompare*obj)
void cprop_functor::lpm_compare_eq_(Design*des, NetCompare*obj)
{
#if 0
/* XXXX Need to reimplement this code to account for vectors. */
NetScope*scope = obj->scope();
unsigned const_count = 0;
bool unknown_flag = false;
/* First, look for the case where constant bits on matching A
and B inputs are different. This this is so, the device can
be completely eliminated and replaced with a constant 0. */
for (unsigned idx = 0 ; idx < obj->width() ; idx += 1) {
if (! obj->pin_DataA(idx).nexus()->drivers_constant())
continue;
if (! obj->pin_DataB(idx).nexus()->drivers_constant())
continue;
const_count += 1;
verinum::V abit = obj->pin_DataA(idx).nexus()->driven_value();
verinum::V bbit = obj->pin_DataB(idx).nexus()->driven_value();
if ((abit == verinum::V0) && (bbit == verinum::V0))
continue;
if ((abit == verinum::V1) && (bbit == verinum::V1))
continue;
unknown_flag = true;
if ((abit == verinum::Vz) || (abit == verinum::Vx))
continue;
if ((bbit == verinum::Vz) || (bbit == verinum::Vx))
continue;
NetConst*zero = new NetConst(scope, obj->name(), verinum::V0);
connect(zero->pin(0), obj->pin_AEB());
delete obj;
des->add_node(zero);
count += 1;
return;
}
/* If all the inputs are constant, then at this point the
result is either V1 or Vx. */
if (const_count == obj->width()) {
NetConst*val = new NetConst(scope, obj->name(),
unknown_flag
? verinum::Vx
: verinum::V1);
connect(val->pin(0), obj->pin_AEB());
delete obj;
des->add_node(val);
count += 1;
return;
}
/* Still may need the gate. Run through the inputs again, and
look for pairs of constants. Those inputs can be removed. */
unsigned top = obj->width();
for (unsigned idx = 0 ; idx < top ; ) {
if (! obj->pin_DataA(idx).nexus()->drivers_constant()) {
idx += 1;
continue;
}
if (! obj->pin_DataB(idx).nexus()->drivers_constant()) {
idx += 1;
continue;
}
obj->pin_DataA(idx).unlink();
obj->pin_DataB(idx).unlink();
top -= 1;
for (unsigned jj = idx ; jj < top ; jj += 1) {
connect(obj->pin_DataA(jj), obj->pin_DataA(jj+1));
connect(obj->pin_DataB(jj), obj->pin_DataB(jj+1));
obj->pin_DataA(jj+1).unlink();
obj->pin_DataB(jj+1).unlink();
}
}
/* If we wound up disconnecting all the inputs, then remove
the device and replace it with a constant. */
if (top == 0) {
NetConst*one = new NetConst(scope, obj->name(), verinum::V1);
connect(one->pin(0), obj->pin_AEB());
delete obj;
des->add_node(one);
count += 1;
return;
}
/* If there is only one bit left, then replace the comparator
with a simple XOR gate. */
if (top == 1) {
NetLogic*tmp = new NetLogic(scope, obj->name(), 3,
NetLogic::XNOR, 1);
connect(tmp->pin(0), obj->pin_AEB());
connect(tmp->pin(1), obj->pin_DataA(0));
connect(tmp->pin(2), obj->pin_DataB(0));
delete obj;
des->add_node(tmp);
count += 1;
return;
}
if (top == obj->width())
return;
NetCompare*tmp = new NetCompare(scope, obj->name(), top);
connect(tmp->pin_AEB(), obj->pin_AEB());
for (unsigned idx = 0 ; idx < top ; idx += 1) {
connect(tmp->pin_DataA(idx), obj->pin_DataA(idx));
connect(tmp->pin_DataB(idx), obj->pin_DataB(idx));
}
delete obj;
des->add_node(tmp);
count += 1;
#endif
}
void cprop_functor::lpm_ff(Design*des, NetFF*obj)
@@ -214,575 +93,8 @@ void cprop_functor::lpm_ff(Design*des, NetFF*obj)
void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
{
#if 0
NetScope*scope = obj->scope();
#endif
switch (obj->type()) {
#if 0
/* XXXX This old code assumed that the individual bit
slices could be replaced with different gates. They
cannot when the device takes atomic vectors, so this
needs to be rewritten. XXXX */
case NetLogic::NAND:
case NetLogic::AND: {
unsigned top = obj->pin_count();
unsigned idx = 1;
unsigned xs = 0;
/* Eliminate all the 1 inputs. They have no effect
on the output of an AND gate. */
while (idx < top) {
if (! obj->pin(idx).nexus()->drivers_constant()) {
idx += 1;
continue;
}
if (obj->pin(idx).nexus()->driven_value()==verinum::V1) {
obj->pin(idx).unlink();
top -= 1;
if (idx < top) {
connect(obj->pin(idx), obj->pin(top));
obj->pin(top).unlink();
}
continue;
}
if (obj->pin(idx).nexus()->driven_value() != verinum::V0) {
idx += 1;
xs += 1;
continue;
}
/* Oops! We just stumbled on a driven-0 input
to the AND gate. That means we can replace
the whole bloody thing with a constant
driver and exit now. */
NetConst*tmp;
switch (obj->type()) {
case NetLogic::AND:
tmp = new NetConst(scope, obj->name(), verinum::V0);
break;
case NetLogic::NAND:
tmp = new NetConst(scope, obj->name(), verinum::V1);
break;
default:
assert(0);
}
tmp->rise_time(obj->rise_time());
tmp->fall_time(obj->fall_time());
tmp->decay_time(obj->decay_time());
des->add_node(tmp);
tmp->pin(0).drive0(obj->pin(0).drive0());
tmp->pin(0).drive1(obj->pin(0).drive1());
connect(obj->pin(0), tmp->pin(0));
delete obj;
count += 1;
return;
}
/* If all the inputs were eliminated, then replace
the gate with a constant 1 and I am done. */
if (top == 1) {
NetConst*tmp;
switch (obj->type()) {
case NetLogic::AND:
tmp = new NetConst(scope, obj->name(), verinum::V1);
break;
case NetLogic::NAND:
tmp = new NetConst(scope, obj->name(), verinum::V0);
break;
default:
assert(0);
}
tmp->rise_time(obj->rise_time());
tmp->fall_time(obj->fall_time());
tmp->decay_time(obj->decay_time());
des->add_node(tmp);
tmp->pin(0).drive0(obj->pin(0).drive0());
tmp->pin(0).drive1(obj->pin(0).drive1());
connect(obj->pin(0), tmp->pin(0));
delete obj;
count += 1;
return;
}
/* If all the inputs are unknowns, then replace the
gate with a Vx. */
if (xs == (top-1)) {
NetConst*tmp;
tmp = new NetConst(scope, obj->name(), verinum::Vx);
des->add_node(tmp);
tmp->pin(0).drive0(obj->pin(0).drive0());
tmp->pin(0).drive1(obj->pin(0).drive1());
connect(obj->pin(0), tmp->pin(0));
delete obj;
count += 1;
return;
}
/* If we are down to only one input, then replace
the AND with a BUF and exit now. */
if (top == 2) {
NetLogic*tmp;
switch (obj->type()) {
case NetLogic::AND:
tmp = new NetLogic(scope,
obj->name(), 2,
NetLogic::BUF, 1);
break;
case NetLogic::NAND:
tmp = new NetLogic(scope,
obj->name(), 2,
NetLogic::NOT, 1);
break;
default:
assert(0);
}
tmp->rise_time(obj->rise_time());
tmp->fall_time(obj->fall_time());
tmp->decay_time(obj->decay_time());
des->add_node(tmp);
tmp->pin(0).drive0(obj->pin(0).drive0());
tmp->pin(0).drive1(obj->pin(0).drive1());
connect(obj->pin(0), tmp->pin(0));
connect(obj->pin(1), tmp->pin(1));
delete obj;
count += 1;
return;
}
/* Finally, this cleans up the gate by creating a
new [N]AND gate that has the right number of
inputs, connected in the right place. */
if (top < obj->pin_count()) {
NetLogic*tmp = new NetLogic(scope,
obj->name(), top,
obj->type(), 1);
tmp->rise_time(obj->rise_time());
tmp->fall_time(obj->fall_time());
tmp->decay_time(obj->decay_time());
des->add_node(tmp);
tmp->pin(0).drive0(obj->pin(0).drive0());
tmp->pin(0).drive1(obj->pin(0).drive1());
for (unsigned idx = 0 ; idx < top ; idx += 1)
connect(tmp->pin(idx), obj->pin(idx));
delete obj;
count += 1;
return;
}
break;
}
#endif
#if 0
/* XXXX This old code assumed that the individual bit
slices could be replaced with different gates. They
cannot when the device takes atomic vectors, so this
needs to be rewritten. XXXX */
case NetLogic::NOR:
case NetLogic::OR: {
unsigned top = obj->pin_count();
unsigned idx = 1;
/* Eliminate all the 0 inputs. They have no effect
on the output of an OR gate. */
while (idx < top) {
if (! obj->pin(idx).nexus()->drivers_constant()) {
idx += 1;
continue;
}
if (obj->pin(idx).nexus()->driven_value() == verinum::V0) {
obj->pin(idx).unlink();
top -= 1;
if (idx < top) {
connect(obj->pin(idx), obj->pin(top));
obj->pin(top).unlink();
}
continue;
}
if (obj->pin(idx).nexus()->driven_value() != verinum::V1) {
idx += 1;
continue;
}
/* Oops! We just stumbled on a driven-1 input
to the OR gate. That means we can replace
the whole bloody thing with a constant
driver and exit now. */
NetConst*tmp;
switch (obj->type()) {
case NetLogic::OR:
tmp = new NetConst(scope, obj->name(), verinum::V1);
break;
case NetLogic::NOR:
tmp = new NetConst(scope, obj->name(), verinum::V0);
break;
default:
assert(0);
}
tmp->rise_time(obj->rise_time());
tmp->fall_time(obj->fall_time());
tmp->decay_time(obj->decay_time());
des->add_node(tmp);
tmp->pin(0).drive0(obj->pin(0).drive0());
tmp->pin(0).drive1(obj->pin(0).drive1());
connect(obj->pin(0), tmp->pin(0));
delete obj;
count += 1;
return;
}
/* If all the inputs were eliminated, then replace
the gate with a constant 0 and I am done. */
if (top == 1) {
NetConst*tmp;
switch (obj->type()) {
case NetLogic::OR:
tmp = new NetConst(scope, obj->name(), verinum::V0);
break;
case NetLogic::NOR:
tmp = new NetConst(scope, obj->name(), verinum::V1);
break;
default:
assert(0);
}
tmp->rise_time(obj->rise_time());
tmp->fall_time(obj->fall_time());
tmp->decay_time(obj->decay_time());
des->add_node(tmp);
tmp->pin(0).drive0(obj->pin(0).drive0());
tmp->pin(0).drive1(obj->pin(0).drive1());
connect(obj->pin(0), tmp->pin(0));
delete obj;
count += 1;
return;
}
/* If we are down to only one input, then replace
the OR with a BUF and exit now. */
if (top == 2) {
NetLogic*tmp;
switch (obj->type()) {
case NetLogic::OR:
tmp = new NetLogic(scope,
obj->name(), 2,
NetLogic::BUF, 1);
break;
case NetLogic::NOR:
tmp = new NetLogic(scope,
obj->name(), 2,
NetLogic::NOT, 1);
break;
default:
assert(0);
}
tmp->rise_time(obj->rise_time());
tmp->fall_time(obj->fall_time());
tmp->decay_time(obj->decay_time());
des->add_node(tmp);
tmp->pin(0).drive0(obj->pin(0).drive0());
tmp->pin(0).drive1(obj->pin(0).drive1());
connect(obj->pin(0), tmp->pin(0));
connect(obj->pin(1), tmp->pin(1));
delete obj;
count += 1;
return;
v }
/* Finally, this cleans up the gate by creating a
new [N]OR gate that has the right number of
inputs, connected in the right place. */
if (top < obj->pin_count()) {
NetLogic*tmp = new NetLogic(scope,
obj->name(), top,
obj->type(), 1);
tmp->rise_time(obj->rise_time());
tmp->fall_time(obj->fall_time());
tmp->decay_time(obj->decay_time());
des->add_node(tmp);
tmp->pin(0).drive0(obj->pin(0).drive0());
tmp->pin(0).drive1(obj->pin(0).drive1());
for (unsigned idx = 0 ; idx < top ; idx += 1)
connect(tmp->pin(idx), obj->pin(idx));
delete obj;
count += 1;
return;
}
break;
}
#endif
#if 0
/* XXXX This old code assumed that the individual bit
slices could be replaced with different gates. They
cannot when the device takes atomic vectors, so this
needs to be rewritten. XXXX */
case NetLogic::XNOR:
case NetLogic::XOR: {
unsigned top = obj->pin_count();
unsigned idx = 1;
/* Eliminate all the 0 inputs. They have no effect
on the output of an XOR gate. The eliminate works
by unlinking the current input and relinking the
last input to this position. It's like bubbling
all the 0 inputs to the end. */
while (idx < top) {
if (! obj->pin(idx).nexus()->drivers_constant()) {
idx += 1;
continue;
}
if (obj->pin(idx).nexus()->driven_value() == verinum::V0) {
obj->pin(idx).unlink();
top -= 1;
if (idx < top) {
connect(obj->pin(idx), obj->pin(top));
obj->pin(top).unlink();
}
} else {
idx += 1;
}
}
/* Look for pairs of constant 1 inputs. If I find a
pair, then eliminate both. Each iteration through
the loop, the `one' variable holds the index to
the previous V1, or 0 if there is none.
The `ones' variable counts the number of V1
inputs. After this loop completes, `ones' will be
0 or 1. */
unsigned one = 0, ones = 0;
idx = 1;
while (idx < top) {
if (! obj->pin(idx).nexus()->drivers_constant()) {
idx += 1;
continue;
}
if (obj->pin(idx).nexus()->driven_value() == verinum::V1) {
if (one == 0) {
one = idx;
ones += 1;
idx += 1;
continue;
}
/* Here we found two constant V1
inputs. Unlink both. */
obj->pin(idx).unlink();
top -= 1;
if (idx < top) {
connect(obj->pin(idx), obj->pin(top));
obj->pin(top).unlink();
}
obj->pin(one).unlink();
top -= 1;
if (one < top) {
connect(obj->pin(one), obj->pin(top));
obj->pin(top).unlink();
}
/* Reset ones counter and one index,
start looking for the next pair. */
assert(ones == 1);
ones = 0;
one = 0;
continue;
}
idx += 1;
}
/* If all the inputs were eliminated, then replace
the gate with a constant value and I am done. */
if (top == 1) {
verinum::V out = obj->type()==NetLogic::XNOR
? verinum::V1
: verinum::V0;
NetConst*tmp = new NetConst(scope, obj->name(), out);
tmp->rise_time(obj->rise_time());
tmp->fall_time(obj->fall_time());
tmp->decay_time(obj->decay_time());
des->add_node(tmp);
tmp->pin(0).drive0(obj->pin(0).drive0());
tmp->pin(0).drive1(obj->pin(0).drive1());
connect(obj->pin(0), tmp->pin(0));
delete obj;
count += 1;
return;
}
/* If there is a stray V1 input and only one other
input, then replace the gate with an inverter and
we are done. */
if ((top == 3) && (ones == 1)) {
unsigned save;
if (! obj->pin(1).nexus()->drivers_constant())
save = 1;
else if (obj->pin(1).nexus()->driven_value() != verinum::V1)
save = 1;
else
save = 2;
NetLogic*tmp;
if (obj->type() == NetLogic::XOR)
tmp = new NetLogic(scope,
obj->name(), 2,
NetLogic::NOT, 1);
else
tmp = new NetLogic(scope,
obj->name(), 2,
NetLogic::BUF, 1);
tmp->rise_time(obj->rise_time());
tmp->fall_time(obj->fall_time());
tmp->decay_time(obj->decay_time());
des->add_node(tmp);
tmp->pin(0).drive0(obj->pin(0).drive0());
tmp->pin(0).drive1(obj->pin(0).drive1());
connect(obj->pin(0), tmp->pin(0));
connect(obj->pin(save), tmp->pin(1));
delete obj;
count += 1;
return;
}
/* If we are down to only one input, then replace
the XOR with a BUF and exit now. */
if (top == 2) {
NetLogic*tmp;
if (obj->type() == NetLogic::XOR)
tmp = new NetLogic(scope,
obj->name(), 2,
NetLogic::BUF, 1);
else
tmp = new NetLogic(scope,
obj->name(), 2,
NetLogic::NOT, 1);
tmp->rise_time(obj->rise_time());
tmp->fall_time(obj->fall_time());
tmp->decay_time(obj->decay_time());
des->add_node(tmp);
tmp->pin(0).drive0(obj->pin(0).drive0());
tmp->pin(0).drive1(obj->pin(0).drive1());
connect(obj->pin(0), tmp->pin(0));
connect(obj->pin(1), tmp->pin(1));
delete obj;
count += 1;
return;
}
/* Finally, this cleans up the gate by creating a
new XOR gate that has the right number of
inputs, connected in the right place. */
if (top < obj->pin_count()) {
NetLogic*tmp = new NetLogic(scope,
obj->name(), top,
obj->type(), 1);
des->add_node(tmp);
tmp->pin(0).drive0(obj->pin(0).drive0());
tmp->pin(0).drive1(obj->pin(0).drive1());
for (unsigned idx = 0 ; idx < top ; idx += 1)
connect(tmp->pin(idx), obj->pin(idx));
delete obj;
count += 1;
return;
}
break;
}
#endif
default:
break;
}
}
#if 0
static void replace_with_mos(Design*des, NetMux*obj, NetLogic::TYPE type)
{
NetScope*scope = obj->scope();
NetLogic*tmp = new NetLogic(obj->scope(),
scope->local_symbol(),
3, type, obj->width());
des->add_node(tmp);
connect(obj->pin_Result(), tmp->pin(0));
connect(obj->pin_Data(type==NetLogic::PMOS? 0 : 1), tmp->pin(1));
if (obj->width() == 1) {
/* Special case that the expression is 1 bit
wide. Connect the select directly to the enable. */
connect(obj->pin_Sel(), tmp->pin(2));
} else {
/* General case that the expression is arbitrarily
wide. Replicate the enable signal (which we
assume is 1 bit wide) to match the expression,
and connect the enable vector to the enable
input of the gate. */
NetReplicate*rtmp = new NetReplicate(scope,
scope->local_symbol(),
obj->width(),
obj->width());
des->add_node(rtmp);
connect(obj->pin_Sel(), rtmp->pin(1));
connect(tmp->pin(2), rtmp->pin(0));
NetNet*rsig = new NetNet(scope, scope->local_symbol(),
NetNet::WIRE, obj->width());
rsig->local_flag(true);
rsig->data_type(IVL_VT_LOGIC);
connect(tmp->pin(2), rsig->pin(0));
}
delete obj;
}
#endif
/*
* This detects the case where the mux selects between a value and
* Vz. In this case, replace the device with a mos with the sel
@@ -795,57 +107,47 @@ void cprop_functor::lpm_mux(Design*des, NetMux*obj)
if (obj->sel_width() != 1)
return;
#if 0
/*
* This is slower than the actual MUXZ so we are skipping this for now.
* If we had a half mux functor this could be faster and more compact
* so I'm leaving the code for future reference.
*/
/* If the first input is all constant Vz, then replace the
NetMux with an array of NMOS devices, with the enable
connected to the select input. */
if (obj->pin_Data(0).nexus()->drivers_constant() &&
obj->pin_Data(0).nexus()->driven_value() == verinum::Vz) {
replace_with_mos(des, obj, NetLogic::NMOS);
count += 1;
return;
}
/* If instead the second input is all constant Vz, replace the
NetMux with an array of PMOS devices. */
if (obj->pin_Data(1).nexus()->drivers_constant() &&
obj->pin_Data(1).nexus()->driven_value() == verinum::Vz) {
replace_with_mos(des, obj, NetLogic::PMOS);
count += 1;
return;
}
#endif
Nexus*sel_nex = obj->pin_Sel().nexus();
/* If the select input is constant, then replace with a BUFZ */
bool flag = obj->pin_Sel().nexus()->drivers_constant();
verinum::V sel_val = flag? obj->pin_Sel().nexus()->driven_value() : verinum::Vx;
if ((sel_val != verinum::Vz) && (sel_val != verinum::Vx)) {
NetBUFZ*tmp = new NetBUFZ(obj->scope(), obj->name(), obj->width());
tmp->set_line(*obj);
if (debug_optimizer)
cerr << obj->get_fileline() << ": debug: "
<< "Replace binary MUX with constant select=" << sel_val
<< " with a BUFZ to the selected input." << endl;
// If the select is not constant, there is nothing we can do.
if (! sel_nex->drivers_constant())
return;
tmp->rise_time(obj->rise_time());
tmp->fall_time(obj->fall_time());
tmp->decay_time(obj->decay_time());
// If the select input is assigned or forced, then again there
// is nothing we can do here.
if (sel_nex->assign_lval())
return;
connect(tmp->pin(0), obj->pin_Result());
if (sel_val == verinum::V1)
connect(tmp->pin(1), obj->pin_Data(1));
else
connect(tmp->pin(1), obj->pin_Data(0));
delete obj;
des->add_node(tmp);
count += 1;
}
// If the constant select is 'bz or 'bx, then give up.
verinum::V sel_val = sel_nex->driven_value();
if (sel_val == verinum::Vz || sel_val == verinum::Vx)
return;
// The Select input must be a defined constant value, so we
// can replace the device with a BUFZ.
NetBUFZ*tmp = new NetBUFZ(obj->scope(), obj->name(), obj->width());
tmp->set_line(*obj);
if (debug_optimizer)
cerr << obj->get_fileline() << ": debug: "
<< "Replace binary MUX with constant select=" << sel_val
<< " with a BUFZ to the selected input." << endl;
tmp->rise_time(obj->rise_time());
tmp->fall_time(obj->fall_time());
tmp->decay_time(obj->decay_time());
connect(tmp->pin(0), obj->pin_Result());
if (sel_val == verinum::V1)
connect(tmp->pin(1), obj->pin_Data(1));
else
connect(tmp->pin(1), obj->pin_Data(0));
delete obj;
des->add_node(tmp);
count += 1;
}
/*
@@ -859,6 +161,12 @@ struct cprop_dc_functor : public functor_t {
virtual void lpm_const(Design*des, NetConst*obj);
};
struct nexus_info_s {
Nexus*nex;
unsigned inp;
unsigned out;
};
void cprop_dc_functor::lpm_const(Design*des, NetConst*obj)
{
// 'bz constant values drive high impedance to whatever is
@@ -878,40 +186,27 @@ void cprop_dc_functor::lpm_const(Design*des, NetConst*obj)
}
}
// For each bit, if this is the only driver, then set the
// initial value of all the signals to this value.
for (unsigned idx = 0 ; idx < obj->pin_count() ; idx += 1) {
if (count_outputs(obj->pin(idx)) > 1)
continue;
Nexus*nex = obj->pin(idx).nexus();
for (Link*clnk = nex->first_nlink()
; clnk ; clnk = clnk->next_nlink()) {
NetPins*cur;
unsigned pin;
clnk->cur_link(cur, pin);
NetNet*tmp = dynamic_cast<NetNet*>(cur);
if (tmp == 0)
continue;
tmp->pin(pin).set_init(obj->value(idx));
}
std::vector<nexus_info_s> nexus_info (obj->pin_count());
for (unsigned idx = 0 ; idx < obj->pin_count() ; idx += 1) {
nexus_info[idx].nex = obj->pin(idx).nexus();
unsigned inputs = 0, outputs = 0;
nexus_info[idx].nex -> count_io(inputs, outputs);
nexus_info[idx].inp = inputs;
nexus_info[idx].out = outputs;
}
// If there are any links that take input, the constant is
// used structurally somewhere.
for (unsigned idx = 0 ; idx < obj->pin_count() ; idx += 1)
if (count_inputs(obj->pin(idx)) > 0)
if (nexus_info[idx].inp > 0)
return;
// Look for signals that have NetESignal nodes attached to
// them. If I find any, then this constant is used by a
// behavioral expression somewhere.
for (unsigned idx = 0 ; idx < obj->pin_count() ; idx += 1) {
Nexus*nex = obj->pin(idx).nexus();
for (Link*clnk = nex->first_nlink()
for (Link*clnk = nexus_info[idx].nex->first_nlink()
; clnk ; clnk = clnk->next_nlink()) {
NetPins*cur;
@@ -947,7 +242,7 @@ void cprop_dc_functor::lpm_const(Design*des, NetConst*obj)
}
}
// Done. Delete me.
// Done. Found no reason to keep this object, so delete it.
delete obj;
}
@@ -960,8 +255,19 @@ void cprop(Design*des)
do {
prop.count = 0;
des->functor(&prop);
if (verbose_flag) {
cout << " ... Iteration detected "
<< prop.count << " optimizations." << endl << flush;
}
} while (prop.count > 0);
if (verbose_flag) {
cout << " ... Look for dangling constants" << endl << flush;
}
cprop_dc_functor dc;
des->functor(&dc);
if (verbose_flag) {
cout << " ... done" << endl << flush;
}
}
+37 -35
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998-2008 Stephen Williams ([email protected])
* Copyright (c) 1998-2009 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
@@ -136,6 +136,17 @@ ostream& operator <<(ostream&o, struct __ScopePathManip marg)
return o;
}
void NetBranch::dump(ostream&o, unsigned ind) const
{
static const char*pin_names[2] = {
"terminal0",
"terminal1" };
o << setw(ind) << "" << "branch island=" << get_island();
o << " // " << get_fileline() << endl;
dump_node_pins(o, ind+4, pin_names);
}
void NetDelaySrc::dump(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "specify delay";
@@ -197,15 +208,12 @@ void NetNet::dump_net(ostream&o, unsigned ind) const
o << " scope=" << scope_path(scope());
o << " #(" << rise_time() << "," << fall_time() << ","
<< decay_time() << ") vector_width=" << vector_width()
<< " pin_count=" << pin_count()
<< " init=";
for (unsigned idx = pin_count() ; idx > 0 ; idx -= 1)
o << pin(idx-1).get_init();
o << " (";
for (unsigned idx = pin_count() ; idx > 0 ; idx -= 1)
o << pin(idx-1).nexus()->get_init();
o << ")" << endl;
<< " pin_count=" << pin_count();
if (pins_are_virtual()) {
o << " pins_are_virtual" << endl;
return;
}
o << endl;
for (unsigned idx = 0 ; idx < pin_count() ; idx += 1) {
if (! pin(idx).is_linked())
@@ -678,7 +686,7 @@ void NetTaskDef::dump(ostream&o, unsigned ind) const
void NetTran::dump_node(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << type_ << " " << name()
<< " island " << island;
<< " island " << get_island();
if (type_ == IVL_SW_TRAN_VP) {
o << " width=" << vector_width()
<< " part=" << part_width()
@@ -1059,29 +1067,11 @@ void NetRepeat::dump(ostream&o, unsigned ind) const
void NetScope::dump(ostream&o) const
{
/* This is a constructed hierarchical name. */
o << scope_path(this);
o << scope_path(this) << " ";
switch (type_) {
case BEGIN_END:
o << " sequential block";
break;
case FORK_JOIN:
o << " parallel block";
break;
case FUNC:
o << " function";
break;
case MODULE:
o << " module <" << (module_name_? module_name_.str() : "") << ">";
break;
case TASK:
o << " task";
break;
case GENBLOCK:
o << " generate block";
break;
}
print_type(o);
if (is_auto()) o << " (automatic)";
if (is_cell()) o << " (cell)";
o << endl;
for (unsigned idx = 0 ; idx < attr_cnt() ; idx += 1)
@@ -1107,7 +1097,11 @@ void NetScope::dump(ostream&o) const
o << "[" << *(*pp).second.msb
<< ":" << *(*pp).second.lsb << "] ";
o << (*pp).first << " = " << *(*pp).second.expr;
o << (*pp).first << " = ";
if (pp->second.expr)
o << *(*pp).second.expr;
else
o << "<nil>";
for (range_t*ran = (*pp).second.range ; ran ; ran = ran->next) {
if (ran->exclude_flag)
@@ -1218,8 +1212,9 @@ void NetScope::dump(ostream&o) const
}
/* Dump any sub-scopes. */
for (NetScope*cur = sub_ ; cur ; cur = cur->sib_)
cur->dump(o);
for (map<hname_t,NetScope*>::const_iterator cur = children_.begin()
; cur != children_.end() ; cur ++)
cur->second->dump(o);
}
void NetSTask::dump(ostream&o, unsigned ind) const
@@ -1511,6 +1506,13 @@ void Design::dump(ostream&o) const
} while (cur != nodes_->node_next_);
}
o << "ELABORATED BRANCHES:" << endl;
if (branches_) {
for (NetBranch*cur = branches_ ; cur ; cur = cur->next_)
cur->dump(o, 0);
}
o << "ELABORATED PROCESSES:" << endl;
// Dump the processes.
+3 -3
View File
@@ -19,17 +19,17 @@
# include "discipline.h"
nature_t::nature_t(perm_string name__, perm_string access__)
ivl_nature_s::ivl_nature_s(perm_string name__, perm_string access__)
: name_(name__), access_(access__)
{
}
nature_t::~nature_t()
ivl_nature_s::~ivl_nature_s()
{
}
ivl_discipline_s::ivl_discipline_s(perm_string name__, ivl_dis_domain_t domain__,
nature_t*pot, nature_t*flow__)
ivl_nature_t pot, ivl_nature_t flow__)
: name_(name__), domain_(domain__), potential_(pot), flow_(flow__)
{
}
+10 -10
View File
@@ -33,10 +33,10 @@
extern std::ostream& operator << (std::ostream&, ivl_dis_domain_t);
class nature_t : public LineInfo {
class ivl_nature_s : public LineInfo {
public:
explicit nature_t(perm_string name, perm_string access);
~nature_t();
explicit ivl_nature_s(perm_string name, perm_string access);
~ivl_nature_s();
perm_string name() const { return name_; }
// Identifier for the access function for this nature
@@ -50,28 +50,28 @@ class nature_t : public LineInfo {
class ivl_discipline_s : public LineInfo {
public:
explicit ivl_discipline_s (perm_string name, ivl_dis_domain_t dom,
nature_t*pot, nature_t*flow);
ivl_nature_t pot, ivl_nature_t flow);
~ivl_discipline_s();
perm_string name() const { return name_; }
ivl_dis_domain_t domain() const { return domain_; }
const nature_t*potential() const { return potential_; }
const nature_t*flow() const { return flow_; }
const ivl_nature_t potential() const { return potential_; }
const ivl_nature_t flow() const { return flow_; }
private:
perm_string name_;
ivl_dis_domain_t domain_;
nature_t*potential_;
nature_t*flow_;
ivl_nature_t potential_;
ivl_nature_t flow_;
private: // not implemented
ivl_discipline_s(const ivl_discipline_s&);
ivl_discipline_s& operator = (const ivl_discipline_s&);
};
extern map<perm_string,nature_t*> natures;
extern map<perm_string,ivl_nature_t> natures;
extern map<perm_string,ivl_discipline_t> disciplines;
// Map access function name to the nature that it accesses.
extern map<perm_string,nature_t*> access_function_nature;
extern map<perm_string,ivl_nature_t> access_function_nature;
#endif
+4 -24
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
* Copyright (c) 2001-2009 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
@@ -16,9 +16,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: dosify.c,v 1.5 2003/07/15 16:17:47 steve Exp $"
#endif
/*
* This is a simple program to make a dosified copy of the
@@ -51,6 +48,7 @@ int main(int argc, char*argv[])
ofile = fopen(argv[2], "wb");
if (ofile == 0) {
fprintf(stderr, "Unable to open %s for output.\n", argv[2]);
fclose(ifile);
return 2;
}
@@ -64,25 +62,7 @@ int main(int argc, char*argv[])
pr = ch;
}
fclose(ifile);
fclose(ofile);
return 0;
}
/*
* $Log: dosify.c,v $
* Revision 1.5 2003/07/15 16:17:47 steve
* Fix spelling of ifdef.
*
* Revision 1.4 2003/07/15 03:49:22 steve
* Spelling fixes.
*
* Revision 1.3 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.2 2002/08/11 23:47:04 steve
* Add missing Log and Ident strings.
*
* Revision 1.1 2001/08/03 17:06:47 steve
* Add install of examples for Windows.
*
*/
-2
View File
@@ -1,2 +0,0 @@
Makefile
iverilog-vpi.exe
+24 -15
View File
@@ -18,7 +18,7 @@
#
SHELL = /bin/sh
VERSION = 0.9.devel
suffix = @install_suffix@
prefix = @prefix@
exec_prefix = @exec_prefix@
@@ -27,6 +27,8 @@ datarootdir = @datarootdir@
VPATH = $(srcdir)
suffix = @install_suffix@
bindir = $(exec_prefix)/bin
libdir = $(exec_prefix)/lib
includedir = $(prefix)/include
@@ -39,7 +41,7 @@ INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
CPPFLAGS = @ident_support@ -I. -I$(srcdir)/.. -DVERSION='"$(VERSION)"' @CPPFLAGS@ @DEFS@
CPPFLAGS = -I. -I$(srcdir)/.. @CPPFLAGS@ @DEFS@
CFLAGS = -Wall @CFLAGS@
LDFLAGS = @LDFLAGS@
@@ -48,38 +50,45 @@ all: iverilog-vpi@EXEEXT@
check: all
clean:
rm -f *.o config.h
rm -f iverilog-vpi@EXEEXT@
rm -f *.o config.h iverilog-vpi@EXEEXT@ res.rc
distclean: clean
rm -f Makefile
rm -f Makefile config.log
Makefile: $(srcdir)/Makefile.in ../config.status
cd ..; ./config.status --file=driver-vpi/$@
O = main.o res.o
iverilog-vpi@EXEEXT@: $O
$(CC) $(LDFLAGS) $O -o iverilog-vpi@EXEEXT@ @EXTRALIBS@
main.o: main.c config.h
main.o: $(srcdir)/main.c config.h
$(CC) $(CPPFLAGS) $(CFLAGS) -c $(srcdir)/main.c
config.h: config.h.in
config.h: $(srcdir)/config.h.in Makefile
sed -e 's;@IVLCC@;@CC@;' -e 's;@IVLCXX@;@CXX@;' \
-e 's;@IVLCFLAGS@;@CXXFLAGS@;' \
-e 's;@SUFFIX@;$(suffix);g' \
-e 's;@IVLCFLAGS@;$(CFLAGS);' \
-e 's;@SHARED@;@shared@;' $< > $@
# Windows specific...
res.rc: $(srcdir)/res.rc.in ../version.exe
sed -e 's;@PRODUCTVERSION@;'`../version.exe '%M,%m,%n,0'`';' \
$(srcdir)/res.rc.in > $@
res.o: res.rc
windres -i res.rc -o res.o
#
install: all installdirs $(bindir)/iverilog-vpi@EXEEXT@
install: all installdirs $(bindir)/iverilog-vpi$(suffix)@EXEEXT@
$(bindir)/iverilog-vpi@EXEEXT@: ./iverilog-vpi@EXEEXT@
$(INSTALL_PROGRAM) ./iverilog-vpi@EXEEXT@ $(bindir)/iverilog-vpi@EXEEXT@
$(bindir)/iverilog-vpi$(suffix)@EXEEXT@: ./iverilog-vpi@EXEEXT@
$(INSTALL_PROGRAM) ./iverilog-vpi@EXEEXT@ "$(bindir)/iverilog-vpi$(suffix)@EXEEXT@"
installdirs: ../mkinstalldirs
$(srcdir)/../mkinstalldirs $(bindir)
installdirs: $(srcdir)/../mkinstalldirs
$(srcdir)/../mkinstalldirs "$(bindir)"
uninstall:
rm -f $(bindir)/iverilog-vpi@EXEEXT@
rm -f $(bindir)/iverilog-vpi$(suffix)@EXEEXT@
+2 -1
View File
@@ -5,4 +5,5 @@
#define IVERILOG_VPI_CXX "@IVLCXX@"
#define IVERILOG_VPI_CFLAGS " @IVLCFLAGS@"
#define IVERILOG_VPI_LDFLAGS "@SHARED@"
#define IVERILOG_VPI_LDLIBS "-lveriuser -lvpi"
#define IVERILOG_VPI_LDLIBS "-lveriuser@SUFFIX@ -lvpi@SUFFIX@"
#define IVERILOG_SUFFIX "@SUFFIX@"
+26 -19
View File
@@ -87,9 +87,9 @@ static void myExit(int exitVal)
static void usage()
{
fprintf(stderr,"usage: iverilog-vpi [src and obj files]...\n");
fprintf(stderr," or iverilog-vpi -mingw=dir\n");
fprintf(stderr," or iverilog-vpi -ivl=dir\n");
fprintf(stderr,"usage: iverilog-vpi" IVERILOG_SUFFIX " [src and obj files]...\n");
fprintf(stderr," or iverilog-vpi" IVERILOG_SUFFIX " -mingw=dir\n");
fprintf(stderr," or iverilog-vpi" IVERILOG_SUFFIX " -ivl=dir\n");
myExit(1);
}
@@ -236,7 +236,9 @@ static int GetRegistryKey(char *key, char **value)
}
regKeyBuffer[regKeySize] = 0; /* makes sure there is a trailing NULL */
lrv = RegQueryValueEx(hkKey,key,NULL,&regKeyType,regKeyBuffer,&regKeySize);
/* This needs an unsigned char *, but for MinGW the char is signed. */
lrv = RegQueryValueEx(hkKey, key, NULL, &regKeyType,
(unsigned char *) regKeyBuffer, &regKeySize);
if ((lrv != ERROR_SUCCESS) || (regKeyType != REG_SZ) || (!regKeySize)) {
lrv = RegCloseKey(hkKey);
free(regKeyBuffer);
@@ -269,7 +271,9 @@ static void SetRegistryKey(char *key, char *value)
&res) != ERROR_SUCCESS)
return;
RegSetValueEx(hkKey,key,0,REG_SZ,value,strlen(value)+1);
/* This needs an unsigned char *, but for MinGW the char is signed. */
RegSetValueEx(hkKey, key, 0, REG_SZ, (unsigned char *) value,
strlen(value)+1);
RegCloseKey(hkKey);
printf("info: storing %s in Windows' registry entry\n",value);
@@ -384,7 +388,7 @@ static int parse(int argc, char *argv[])
/* Check for the --install-dir option */
else if (stricmp("--install-dir", argv[idx]) == 0) {
setup_ivl_environment();
printf("%s\\\\lib\\\\ivl\\\\.\n", gstr.pIVL);
printf("%s\\\\lib\\\\ivl" IVERILOG_SUFFIX "\\\\.\n", gstr.pIVL);
myExit(0);
}
/* This is different than iverilog-vpi.sh, we don't
@@ -413,11 +417,18 @@ static void checkMingwDir(char *root)
int irv;
struct _stat stat_buf;
char *path;
char *path, *comp, *cp;
initDynString(&path);
assign(&path,gstr.pMINGW);
appendBackSlash(&path);
append(&path,"bin\\" IVERILOG_VPI_CC ".exe");
append(&path,"bin\\");
/* Get just the compiler name (the first word) */
comp = strdup(IVERILOG_VPI_CC);
cp = strchr(comp, ' ');
if (cp != NULL) *cp = '\0';
append(&path, comp);
append(&path,".exe");
free(comp);
irv = _stat(path,&stat_buf);
deInitDynString(path);
@@ -444,14 +455,14 @@ static void checkIvlDir(char *root)
initDynString(&path);
assign(&path,gstr.pIVL);
appendBackSlash(&path);
append(&path,"bin\\vvp.exe");
append(&path,"bin\\vvp" IVERILOG_SUFFIX ".exe");
irv = _stat(path,&stat_buf);
deInitDynString(path);
if (irv) {
fprintf(stderr,"error: %s does not appear to be the valid root directory of\n",root);
fprintf(stderr," Icarus Verilog. Use the -ivl option of iverilog-vpi.exe to\n");
fprintf(stderr," Icarus Verilog. Use the -ivl option of iverilog-vpi" IVERILOG_SUFFIX " to\n");
fprintf(stderr," point to the Icarus Verilog root directory. For a Windows\n");
fprintf(stderr," command shell the option would be something like -ivl=c:\\iverilog\n");
fprintf(stderr," For a Cygwin shell the option would be something like\n");
@@ -503,7 +514,7 @@ static void setup_ivl_environment()
SetRegistryKey(IVL_REGKEY_IVL,gstr.pIVL);
} else if (!GetRegistryKey(IVL_REGKEY_IVL,&gstr.pIVL)) {
fprintf(stderr,"error: can not locate the Icarus Verilog root directory, use the -ivl option\n");
fprintf(stderr," of iverilog-vpi.exe to point to the Icarus Verilog root directory.\n");
fprintf(stderr," of iverilog-vpi" IVERILOG_SUFFIX " to point to the Icarus Verilog root directory.\n");
fprintf(stderr," For a Windows command shell the option would be something like\n");
fprintf(stderr," -ivl=c:\\iverilog For a Cygwin shell the option would be something\n");
fprintf(stderr," like -ivl=c:\\\\iverilog\n");
@@ -511,20 +522,16 @@ static void setup_ivl_environment()
}
/* Build up the CFLAGS option string */
assign(&gstr.pCFLAGS,IVERILOG_VPI_CFLAGS);
append(&gstr.pCFLAGS," -I");
assign(&gstr.pCFLAGS,IVERILOG_VPI_CFLAGS " -I\"");
append(&gstr.pCFLAGS,gstr.pIVL);
appendBackSlash(&gstr.pCFLAGS);
append(&gstr.pCFLAGS, "\\");
append(&gstr.pCFLAGS,"include");
append(&gstr.pCFLAGS,"\\include\\\\iverilog\"" IVERILOG_SUFFIX);
/* Build up the LDFLAGS option string */
assign(&gstr.pLDLIBS,"-L");
assign(&gstr.pLDLIBS,"-L\"");
append(&gstr.pLDLIBS,gstr.pIVL);
appendBackSlash(&gstr.pLDLIBS);
append(&gstr.pLDLIBS, "\\");
append(&gstr.pLDLIBS,"lib ");
append(&gstr.pLDLIBS,IVERILOG_VPI_LDLIBS);
append(&gstr.pLDLIBS,"\\lib\" " IVERILOG_VPI_LDLIBS);
}
/* compile source modules */
+2 -2
View File
@@ -10,7 +10,7 @@ LANGUAGE 9, 4
1 VERSIONINFO
FILEVERSION 2002,11,13,0
PRODUCTVERSION 0,7,0,0
PRODUCTVERSION @PRODUCTVERSION@
FILEFLAGSMASK 0x3fL
FILEFLAGS 0x2L
FILEOS 0x40004L
@@ -28,7 +28,7 @@ BEGIN
VALUE "LegalCopyright", "Copyright 2002 Gus Baldauf\0"
VALUE "OriginalFilename", "iverilog-vpi.exe\0"
VALUE "ProductName", "Icarus Verilog\0"
VALUE "ProductVersion", "0, 7, 0, 0\0"
VALUE "ProductVersion", "@PRODUCTVERSION@\0"
END
END
BLOCK "VarFileInfo"
-15
View File
@@ -1,15 +0,0 @@
a.out
Makefile
parse.c
parse.h
parse.output
lexor.c
cfparse.c
cfparse.h
cfparse.output
cflexor.c
foo.*
iverilog
iverilog.ps
iverilog.pdf
tmp.pdf
+45 -29
View File
@@ -18,7 +18,7 @@
#
SHELL = /bin/sh
VERSION = 0.9.devel
suffix = @install_suffix@
prefix = @prefix@
exec_prefix = @exec_prefix@
@@ -41,19 +41,24 @@ INSTALL_DATA = @INSTALL_DATA@
MAN = @MAN@
PS2PDF = @PS2PDF@
CPPFLAGS = @ident_support@ -I. -I.. -I$(srcdir)/.. -I$(srcdir) -DVERSION='"$(VERSION)"' @CPPFLAGS@ @DEFS@
CPPFLAGS = -I. -I.. -I$(srcdir)/.. -I$(srcdir) @CPPFLAGS@ @DEFS@
CFLAGS = -Wall @CFLAGS@
LDFLAGS = @LDFLAGS@
all: iverilog@EXEEXT@
all: dep iverilog@EXEEXT@ iverilog.man
check: all
clean:
rm -f *.o lexor.c parse.c parse.h parse.output
rm -f cflexor.c cfparse.c cfparse.h cfparse.output
rm -f iverilog@EXEEXT@ iverilog.pdf iverilog.ps
rm -f *.o cflexor.c cfparse.c cfparse.h cfparse.output
rm -f iverilog@EXEEXT@ iverilog.man iverilog.pdf iverilog.ps
rm -rf dep
distclean: clean
rm -f Makefile
rm -f Makefile config.log
Makefile: $(srcdir)/Makefile.in ../config.status
cd ..; ./config.status --file=driver/$@
O = main.o substit.o cflexor.o cfparse.o
@@ -66,51 +71,62 @@ cflexor.c: cflexor.lex
cfparse.h cfparse.c: cfparse.y
bison --verbose -t -d -o cfparse.c --name-prefix=cf $(srcdir)/cfparse.y
dep:
mkdir dep
main.o: main.c globals.h ../version.h
$(CC) $(CPPFLAGS) $(CFLAGS) -c -DIVL_ROOT='"@libdir@/ivl"' -DIVL_INC='"@includedir@"' -DIVL_LIB='"@libdir@"' -DDLLIB='"@DLLIB@"' $(srcdir)/main.c
%.o: %.c
$(CC) $(CPPFLAGS) $(CFLAGS) -MD -c $< -o $*.o
mv $*.d dep
build_string.o: build_string.c globals.h
cflexor.o: cflexor.c cfparse.h cfparse_misc.h globals.h
cfparse.o: cfparse.c globals.h cfparse_misc.h
main.o: main.c globals.h $(srcdir)/../version_base.h ../version_tag.h Makefile
$(CC) $(CPPFLAGS) $(CFLAGS) -MD -c -DIVL_ROOT='"@libdir@/ivl$(suffix)"' -DIVL_SUFFIX='"$(suffix)"' -DIVL_INC='"@includedir@"' -DIVL_LIB='"@libdir@"' -DDLLIB='"@DLLIB@"' $(srcdir)/main.c
mv $*.d dep
iverilog.ps: $(srcdir)/iverilog.man
$(MAN) -t $(srcdir)/iverilog.man > iverilog.ps
cflexor.o: cflexor.c cfparse.h
iverilog.man: $(srcdir)/iverilog.man.in ../version.exe
../version.exe `head -1 $(srcdir)/iverilog.man.in`'\n' > $@
tail -n +2 $(srcdir)/iverilog.man.in >> $@
iverilog.ps: iverilog.man
$(MAN) -t iverilog.man > iverilog.ps
iverilog.pdf: iverilog.ps
$(PS2PDF) iverilog.ps iverilog.pdf
ifeq (@MINGW32@,yes)
ifeq ($(MAN),none)
INSTALL_DOC = $(mandir)/man1/iverilog.1
INSTALL_DOC = $(mandir)/man1/iverilog$(suffix).1
else
ifeq ($(PS2PDF),none)
INSTALL_DOC = $(mandir)/man1/iverilog.1
INSTALL_DOC = $(mandir)/man1/iverilog$(suffix).1
else
INSTALL_DOC = $(prefix)/iverilog.pdf $(mandir)/man1/iverilog.1
INSTALL_DOC = $(prefix)/iverilog$(suffix).pdf $(mandir)/man1/iverilog$(suffix).1
all: iverilog.pdf
endif
endif
INSTALL_DOCDIR = $(mandir)/man1
else
INSTALL_DOC = $(mandir)/man1/iverilog.1
INSTALL_DOC = $(mandir)/man1/iverilog$(suffix).1
INSTALL_DOCDIR = $(mandir)/man1
endif
install: all installdirs $(bindir)/iverilog@EXEEXT@ $(INSTALL_DOC)
install: all installdirs $(bindir)/iverilog$(suffix)@EXEEXT@ $(INSTALL_DOC)
$(bindir)/iverilog@EXEEXT@: ./iverilog@EXEEXT@
$(INSTALL_PROGRAM) ./iverilog@EXEEXT@ $(DESTDIR)$(bindir)/iverilog@EXEEXT@
$(bindir)/iverilog$(suffix)@EXEEXT@: ./iverilog@EXEEXT@
$(INSTALL_PROGRAM) ./iverilog@EXEEXT@ "$(DESTDIR)$(bindir)/iverilog$(suffix)@EXEEXT@"
$(mandir)/man1/iverilog.1: $(srcdir)/iverilog.man
$(INSTALL_DATA) $(srcdir)/iverilog.man $(DESTDIR)$(mandir)/man1/iverilog.1
$(mandir)/man1/iverilog$(suffix).1: iverilog.man
$(INSTALL_DATA) iverilog.man "$(DESTDIR)$(mandir)/man1/iverilog$(suffix).1"
$(prefix)/iverilog.pdf: iverilog.pdf
$(INSTALL_DATA) iverilog.pdf $(prefix)/iverilog.pdf
$(prefix)/iverilog$(suffix).pdf: iverilog.pdf
$(INSTALL_DATA) iverilog.pdf "$(DESTDIR)$(prefix)/iverilog$(suffix).pdf"
installdirs: ../mkinstalldirs
$(srcdir)/../mkinstalldirs $(DESTDIR)$(bindir) $(DESTDIR)$(INSTALL_DOCDIR)
installdirs: $(srcdir)/../mkinstalldirs
$(srcdir)/../mkinstalldirs "$(DESTDIR)$(bindir)" "$(DESTDIR)$(INSTALL_DOCDIR)"
uninstall:
rm -f $(DESTDIR)$(bindir)/iverilog@EXEEXT@
rm -f $(DESTDIR)$(mandir)/man1/iverilog.1 $(DESTDIR)$(prefix)/iverilog.pdf
rm -f "$(DESTDIR)$(bindir)/iverilog$(suffix)@EXEEXT@"
rm -f "$(DESTDIR)$(mandir)/man1/iverilog$(suffix).1" "$(DESTDIR)$(prefix)/iverilog$(suffix).pdf"
-include $(patsubst %.o, dep/%.d, $O)
+20 -5
View File
@@ -4,7 +4,7 @@
%{
/*
* Copyright (c) 2001 Stephen Williams ([email protected])
* Copyright (c) 2001-2009 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
@@ -21,9 +21,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: cflexor.lex,v 1.11 2007/03/22 16:08:18 steve Exp $"
#endif
# include "cfparse.h"
# include "cfparse_misc.h"
@@ -79,13 +76,17 @@ int cmdfile_stack_ptr = 0;
"+incdir+" { BEGIN(PLUS_ARGS); return TOK_INCDIR; }
"+integer-width+" { BEGIN(PLUS_ARGS); return TOK_INTEGER_WIDTH; }
"+libdir+" { BEGIN(PLUS_ARGS); return TOK_LIBDIR; }
"+libdir-nocase+" { BEGIN(PLUS_ARGS); return TOK_LIBDIR_NOCASE; }
"+libext+" { BEGIN(PLUS_ARGS); return TOK_LIBEXT; }
"+integer-width+" { BEGIN(PLUS_ARGS); return TOK_INTEGER_WIDTH; }
"+parameter+" { BEGIN(PLUS_ARGS); return TOK_PARAMETER; }
"+timescale+" { BEGIN(PLUS_ARGS); return TOK_TIMESCALE; }
/* If it is not any known plus-flag, return the generic form. */
"+"[^\n \t\b\f\r+]* {
@@ -236,3 +237,17 @@ void cfreset(FILE*fd, const char*path)
current_file = strdup(path);
cflloc.first_line = 1;
}
/*
* Modern version of flex (>=2.5.9) can clean up the scanner data.
*/
void destroy_lexor()
{
# ifdef FLEX_SCANNER
# if YY_FLEX_MAJOR_VERSION >= 2 && YY_FLEX_MINOR_VERSION >= 5
# if defined(YY_FLEX_SUBMINOR_VERSION) && YY_FLEX_SUBMINOR_VERSION >= 9
yylex_destroy();
# endif
# endif
# endif
}
+19 -7
View File
@@ -1,6 +1,6 @@
%{
/*
* Copyright (c) 20001 Stephen Williams ([email protected])
* Copyright (c) 2001-2009 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,10 +17,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: cfparse.y,v 1.12 2007/04/19 02:52:53 steve Exp $"
#endif
# include "globals.h"
# include "cfparse_misc.h"
@@ -61,8 +57,8 @@ static void translate_file_name(char*text)
};
%token TOK_Da TOK_Dc TOK_Dv TOK_Dy
%token TOK_DEFINE TOK_INCDIR TOK_LIBDIR TOK_LIBDIR_NOCASE TOK_LIBEXT
%token TOK_INTEGER_WIDTH
%token TOK_DEFINE TOK_INCDIR TOK_INTEGER_WIDTH TOK_LIBDIR TOK_LIBDIR_NOCASE
%token TOK_LIBEXT TOK_PARAMETER TOK_TIMESCALE
%token <text> TOK_PLUSARG TOK_PLUSWORD TOK_STRING
%%
@@ -139,6 +135,22 @@ item
free(tmp);
}
| TOK_PARAMETER TOK_PLUSARG
{ char*tmp = substitutions($2);
process_parameter(tmp);
free($2);
free(tmp);
}
/* The +timescale token is used to set the default timescale for
the simulator. */
| TOK_TIMESCALE TOK_PLUSARG
{ char*tmp = substitutions($2);
process_timescale(tmp);
free($2);
free(tmp);
}
| TOK_DEFINE TOK_PLUSARG
{ process_define($2);
free($2);
+2 -1
View File
@@ -1,7 +1,7 @@
#ifndef __cfparse_misc_H
#define __cfparse_misc_H
/*
* Copyright (c) 2001 Picture Elements, Inc.
* Copyright (c) 2001-2009 Picture Elements, Inc.
* Stephen Williams (steve@picturel.com)
*
* This source code is free software; you can redistribute it
@@ -38,6 +38,7 @@ int cflex(void);
int cferror(const char *);
int cfparse(void);
void switch_to_command_file(const char *);
void destroy_lexor();
char *current_file;
#endif
+7 -70
View File
@@ -1,7 +1,7 @@
#ifndef __globals_H
#define __globals_H
/*
* Copyright (c) 2000 Stephen Williams (steve@icarus.com)
* Copyright (c) 2000-2009 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
@@ -18,37 +18,9 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: globals.h,v 1.21 2007/04/19 02:52:53 steve Exp $"
#endif
# include <stddef.h>
/* This is the base (i.e. -B<value>) of the Icarus Verilog files. */
extern const char*base;
/* This is the path to the iconfig file sent to ivl. */
extern char* iconfig_path;
extern char* iconfig_common_path;
/* This is the optional -M<dependfile> value, if one was supplied. */
extern const char*depfile;
/* This is the optional -N<path> value, if one was supplied. */
extern const char*npath;
/* This is the name of the output file that the user selected. */
extern const char*opath;
/* This pointer is set if there were -s<value> parameters. */
extern char*start;
/* This flag is true if the -S flag was used on the command line. */
extern int synth_flag;
/* This is the name of the selected target. */
extern const char*targ;
/* This is the integer-width argument that will be passed to ivl. */
extern unsigned integer_width;
@@ -68,46 +40,11 @@ extern void process_include_dir(const char*name);
/* Add a new -D define. */
extern void process_define(const char*name);
/* Add a new parameter definition */
extern void process_parameter(const char*name);
/* Set the default timescale for the simulator. */
extern void process_timescale(const char*ts_string);
/* -v */
extern int verbose_flag;
extern char warning_flags[];
/* -y and -Y flags from the command line. */
extern char* library_flags;
extern char* library_flags2;
/*
* $Log: globals.h,v $
* Revision 1.21 2007/04/19 02:52:53 steve
* Add support for -v flag in command file.
*
* Revision 1.20 2007/03/07 04:24:59 steve
* Make integer width controllable.
*
* Revision 1.19 2003/11/18 06:31:46 steve
* Remove the iverilog.conf file.
*
* Revision 1.18 2003/11/13 04:09:49 steve
* Pass flags through the temporary config file.
*
* Revision 1.17 2003/11/01 04:21:57 steve
* Add support for a target static config file.
*
* Revision 1.16 2002/08/12 01:35:01 steve
* conditional ident string using autoconfig.
*
* Revision 1.15 2002/06/23 20:10:51 steve
* Variable substitution in command files.
*
* Revision 1.14 2002/05/28 20:40:37 steve
* ivl indexes the search path for libraries, and
* supports case insensitive module-to-file lookup.
*
* Revision 1.13 2002/05/28 00:50:40 steve
* Add the ivl -C flag for bulk configuration
* from the driver, and use that to run library
* modules through the preprocessor.
*/
#endif
+130 -51
View File
@@ -1,13 +1,14 @@
.TH iverilog 1 "April 22nd, 2008" Version "0.9.devel"
.TH iverilog 1 "December 29th, 2009" "" "Version %M.%m.%n %E"
.SH NAME
iverilog - Icarus Verilog compiler
.SH SYNOPSIS
.B iverilog
[-ESVv] [-Bpath] [-ccmdfile|-fcmdfile] [-Dmacro[=defn]] [-pflag=value]
[-dname] [-g1995|-g2001|-g2005|-g<feature>]
[-Iincludedir] [-mmodule] [-Mfile] [-Nfile] [-ooutputfilename]
[-stopmodule] [-ttype] [-Tmin/typ/max] [-Wclass] [-ypath] sourcefile
[\-ESVv] [\-Bpath] [\-ccmdfile|\-fcmdfile] [\-Dmacro[=defn]]
[\-Pparameter=value] [\-pflag=value]
[\-dname] [\-g1995|\-g2001|\-g2005|\-g<feature>]
[\-Iincludedir] [\-mmodule] [\-M[mode=]file] [\-Nfile] [\-ooutputfilename]
[\-stopmodule] [\-ttype] [\-Tmin/typ/max] [\-Wclass] [\-ypath] sourcefile
.SH DESCRIPTION
.PP
@@ -18,14 +19,13 @@ simulation, and \fIfpga\fP for synthesis. Other target
types are added as code generators are implemented.
.SH OPTIONS
.l
\fIiverilog\fP accepts the following options:
.TP 8
.B -B\fIbase\fP
The \fIiverilog\fP program uses external programs and configuration
files to preprocess and compile the Verilog source. Normally, the path
used to locate these tools is built into the \fIiverilog\fP
program. However, the \fB-B\fP switch allows the user to select a
program. However, the \fB\-B\fP switch allows the user to select a
different set of programs. The path given is used to locate
\fIivlpp\fP, \fIivl\fP, code generators and the VPI modules.
.TP 8
@@ -43,8 +43,14 @@ Verilog source.
.B -D\fImacro=defn\fP
Defines macro \fImacro\fP as \fIdefn\fP.
.TP 8
.B -P\fIparameter=value\fP
Override (i.e. defparam) a parameter in a root module. This allows the
user to override at compile time (defparam) a parameter in a root
module instance. For example, \fB\-Pmain.foo=2\fP overrides the
parameter foo in the root instance main with the value 2.
.TP 8
.B -d\fIname\fP
Activate a class of compiler debugging messages. The \fB-d\fP switch may
Activate a class of compiler debugging messages. The \fB\-d\fP switch may
be used as often as necessary to activate all the desired messages.
Supported names are scopes, eval_tree, elaborate, and synth2;
any other names are ignored.
@@ -55,20 +61,25 @@ is the Verilog input, but with file inclusions and macro references
expanded and removed. This is useful, for example, to preprocess
Verilog source for use by other compilers.
.TP 8
.B -g1995\fI|\fP-g2001\fI|\fP-g2005
.B -g1995\fI|\fP-g2001\fI|\fP-g2001-noconfig\fI|\fP-g2005
Select the Verilog language \fIgeneration\fP to support in the
compiler. This selects between \fIIEEE1364-1995\fP,
\fIIEEE1364-2001\fP(2), or \fIIEEE1364-2005\fP. Normally,
compiler. This selects between \fIIEEE1364\-1995\fP,
\fIIEEE1364\-2001\fP, or \fIIEEE1364\-2005\fP. Normally,
Icarus Verilog defaults to the latest known generation of the
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 -gverilog-ams\fI|-fP-gno-verilog-ams
Enable or disable (default) support for Verilog-AMS.
.B -gverilog-ams\fI|\fP-gno-verilog-ams
Enable or disable (default) support for Verilog\-AMS.
Very little Verilog\-AMS specific functionality is currently supported.
.TP 8
.B -gsystem-verilog\fI|\fP-gno-system-verilog
Enable or disable (default) support for SystemVerilog.
Very little SystemVerilog specific functionality is currently supported.
.TP 8
.B -gspecify\fI|\fP-gno-specify
Enable (default) or disable specify block support. When enabled,
Enable or disable (default) specify block support. When enabled,
specify block code is elaborated. When disabled, specify blocks are
parsed but ignored. Specify blocks are commonly not needed for RTL
simulation, and in fact can hurt performance of the
@@ -81,6 +92,13 @@ include directory after all other explicit include directories. This
standard include directory is a convenient place to install standard
header files that a Verilog program may include.
.TP 8
.B -grelative-include\fI|\fP-gno-relative-include
Enable or disable (default) adding the local files directory to
the beginning of the include file search path. This allows files
to be included relative to the current file not the more common
files are only found in the working directory or in the specified
include file search path.
.TP 8
.B -gxtypes\fI|\fP-gno-xtypes
Enable (default) or disable support for extended types. Enabling
extended types allows for new types that are supported by Icarus
@@ -93,22 +111,42 @@ The standards requires that a vectored port have matching ranges for its
port declaration as well as any net/register declaration. It was common
practice in the past to only specify the range for the net/register
declaration and some tools still allow this. By default any mismatch is
reported as a error. Using \fI-gno-io-range-error\fP will produce a
reported as a error. Using \fB\-gno\-io\-range\-error\fP will produce a
warning instead of a fatal error for the case of a vectored net/register
and a scalar port declaration.
.TP 8
.B -gstrict-ca-eval\fI|\fP-gno-strict-ca-eval
The standard requires that if any input to a continuous assignment
expression changes value, the entire expression is re-evaluated. By
default, parts of the expression that do not depend on the changed
input value(s) are not re-evaluated. If an expression contains a call
to a function that doesn't depend solely on its input values or that
has side effects, the resulting behavior will differ from that
required by the standard. Using \fI\-gstrict\-ca\-eval\fP will force
standard compliant behavior (with some loss in performance).
.TP 8
.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
for Verilog include files. The \fB\-I\fP switch may be used many times
to specify several directories to search, the directories are searched
in the order they appear on the command line.
.TP 8
.B -M\fIpath\fP
Write into the file specified by path a list of files that contribute
to the compilation of the design. This includes files that are
included by include directives and files that are automatically loaded
by library support. The output is one file name per line, with no
leading or trailing space.
This is equivalent to \fB\-Mall=path\fP. Preserved for backwards
compatibility.
.TP 8
.B -M\fImode=path\fP
Write into the file specified by path a list of files that contribute to
the compilation of the design. If \fBmode\fP is \fBall\fP or \fBprefix\fP,
this includes files that are included by include directives and files
that are automatically loaded by library support as well as the files
explicitly specified by the user. If \fBmode\fP is \fBinclude\fP, only
files that are included by include directives are listed. If \fBmode\fP
is \fBmodule\fP, only files that are specified by the user or that are
automatically loaded by library support are listed. The output is one
file name per line, with no leading or trailing space. If \fBmode\fP
is \fBprefix\fP, files that are included by include directives are
prefixed by "I " and other files are prefixed by "M ".
.TP 8
.B -m\fImodule\fP
Add this module to the list of VPI modules to be loaded by the
@@ -128,7 +166,7 @@ Place output in the file \fIfilename\fP. If no output file name is
specified, \fIiverilog\fP uses the default name \fBa.out\fP.
.TP 8
.B -p\fIflag=value\fP
Assign a value to a target specific flag. The \fB-p\fP switch may be
Assign a value to a target specific flag. The \fB\-p\fP switch may be
used as often as necessary to specify all the desired flags. The flags
that are used depend on the target that is selected, and are described
in target specific documentation. Flags that are not used are ignored.
@@ -136,15 +174,15 @@ in target specific documentation. Flags that are not used are ignored.
.B -S
Synthesize. Normally, if the target can accept behavioral
descriptions the compiler will leave processes in behavioral
form. The \fB-S\fP switch causes the compiler to perform synthesis
form. The \fB\-S\fP switch causes the compiler to perform synthesis
even if it is not necessary for the target. If the target type is a
netlist format, the \fB-S\fP switch is unnecessary and has no effect.
netlist format, the \fB\-S\fP switch is unnecessary and has no effect.
.TP 8
.B -s \fItopmodule\fP
Specify the top level module to elaborate. Icarus Verilog will by default
choose modules that are not instantiated in any other modules, but
sometimes that is not sufficient, or instantiates too many modules. If
the user specifies one or more root modules with \fB-s\fP flags, then
the user specifies one or more root modules with \fB\-s\fP flags, then
they will be used as root modules instead.
.TP 8
.B -T\fImin|typ|max\fP
@@ -174,13 +212,18 @@ Print the version of the compiler, and exit.
.B -W\fIclass\fP
Turn on different classes of warnings. See the \fBWARNING TYPES\fP
section below for descriptions of the different warning groups. If
multiple \fB-W\fP switches are used, the warning set is the union of
multiple \fB\-W\fP switches are used, the warning set is the union of
all the requested classes.
.TP 8
.B -y\fIlibdir\fP
Append the directory to the library module search path. When the
compiler finds an undefined module, it looks in these directories for
files with the right name.
.TP 8
.B -Y\fIsuffix\fP
Add suffix to the list of accepted file name suffixes used when
searching a library for cells. The list defaults to the single
entry \fI.v\fP.
.SH MODULE LIBRARIES
@@ -199,7 +242,7 @@ library or in the main design.
.SH TARGETS
The Icarus Verilog compiler supports a variety of targets, for
different purposes, and the \fB-t\fP switch is used to select the
different purposes, and the \fB\-t\fP switch is used to select the
desired target.
.TP 8
@@ -217,7 +260,7 @@ This is a synthesis target that supports a variety of fpga devices,
mostly by EDIF format output. The Icarus Verilog fpga code generator
can generate complete designs or EDIF macros that can in turn be
imported into larger designs by other tools. The \fBfpga\fP target
implies the synthesis \fB-S\fP flag.
implies the synthesis \fB\-S\fP flag.
.TP 8
.B vhdl
This target produces a VHDL translation of the Verilog netlist. The
@@ -226,14 +269,15 @@ the modules in the Verilog source code. Note that only a subset of
the Verilog language is supported. See the wiki for more information.
.SH "WARNING TYPES"
These are the types of warnings that can be selected by the \fB-W\fP
These are the types of warnings that can be selected by the \fB\-W\fP
switch. All the warning types (other than \fBall\fP) can also be
prefixed with \fBno-\fP to turn off that warning. This is most useful
after a \fB-Wall\fP argument to suppress isolated warning types.
prefixed with \fBno\-\fP to turn off that warning. This is most useful
after a \fB\-Wall\fP argument to suppress isolated warning types.
.TP 8
.B all
This enables all supported warning categories.
This enables the implicit, portbind, select\-range, timescale, and
sensitivity\-entire\-array warning categories.
.TP 8
.B implicit
@@ -247,6 +291,12 @@ This enables warnings for ports of module instantiations that are not
connected but probably should be. Dangling input ports, for example,
will generate a warning.
.TP 8
.B select-range
This enables warnings for constant out of bound selects. This includes
partial or fully out of bound selects as well as a select containing
a 'bx or 'bz in the index.
.TP 8
.B timescale
This enables warnings for inconsistent use of the timescale
@@ -259,7 +309,7 @@ and dependent on compilation order.
.B infloop
This enables warnings for \fRalways\fP statements that may have runtime
infinite loops (has paths with no or zero delay). This class of warnings
is not included in \fB-Wall\fP and hence does not have a \fBno-\fP variant.
is not included in \fB\-Wall\fP and hence does not have a \fBno\-\fP variant.
A fatal error message will always be printed when the compiler can
determine that there will definitely be an infinite loop (all paths have
no or zero delay).
@@ -270,6 +320,22 @@ verified. It is expected that many of the warnings will be false
positives, since the code treats the value of all variables and signals
as indeterminate.
.TP 8
.B sensitivity-entire-vector
This enables warnings for when a part select within an "always @*"
statement results in the entire vector being added to the implicit
sensitivity list. Although this behaviour is prescribed by the IEEE
standard, it is not what might be expected and can have performance
implications if the vector is large.
.TP 8
.B sensitivity-entire-array
This enables warnings for when a word select within an "always @*"
statement results in the entire array being added to the implicit
sensitivity list. Although this behaviour is prescribed by the IEEE
standard, it is not what might be expected and can have performance
implications if the array is large.
.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
@@ -311,14 +377,14 @@ character. Variables are substituted in file names.
.TP 8
.B -c\ \fIcmdfile\fP -f\ \fIcmdfile\fP
A \fB-c\fP or \fB-f\fP token prefixes a command file, exactly like it
A \fB\-c\fP or \fB\-f\fP token prefixes a command file, exactly like it
does on the command line. The cmdfile may be on the same line or the
next non-comment line.
.TP 8
.B -y\ \fIlibdir\fP
A \fB-y\fP token prefixes a library directory in the command file,
exactly like it does on the command line. The parameter to the \fB-y\fP
A \fB\-y\fP token prefixes a library directory in the command file,
exactly like it does on the command line. The parameter to the \fB\-y\fP
flag may be on the same line or the next non-comment line.
Variables in the \fIlibdir\fP are substituted.
@@ -326,7 +392,7 @@ Variables in the \fIlibdir\fP are substituted.
.TP 8
.B +incdir+\fIincludedir\fP
The \fB+incdir+\fP token in command files gives directories to search
for include files in much the same way that \fB-I\fP flags work on the
for include files in much the same way that \fB\-I\fP flags work on the
command line. The difference is that multiple \fI+includedir\fP
directories are valid parameters to a single \fB+incdir+\fP token,
although you may also have multiple \fB+incdir+\fP lines.
@@ -337,12 +403,12 @@ Variables in the \fIincludedir\fP are substituted.
.B +libext+\fIext\fP
The \fB+libext\fP token in command files fives file extensions to try
when looking for a library file. This is useful in conjunction with
\fB-y\fP flags to list suffixes to try in each directory before moving
\fB\-y\fP flags to list suffixes to try in each directory before moving
on to the next library directory.
.TP 8
.B +libdir+\fIdir\fP
This is another way to specify library directories. See the -y flag.
This is another way to specify library directories. See the \-y flag.
.TP 8
.B +libdir-nocase+\fIdir\fP
@@ -354,19 +420,31 @@ letters are correct. For example, "foo" matches "Foo.v" but not
.TP 8
.B +define+\fINAME\fP=\fIvalue\fP
The \fB+define+\fP token is the same as the \fB-D\fP option on the
The \fB+define+\fP token is the same as the \fB\-D\fP option on the
command line. The value part of the token is optional.
.TP 8
.B +toupper-filename\fP
.B +parameter+\fINAME\fP=\fIvalue\fP
The \fB+parameter+\fP token is the same as the \fB\-P\fP option on the
command line.
.TP 8
.B +timescale+\fIvalue\fP
The \fB+timescale+\fP token is used to set the default timescale for
the simulation. This is the time units and precision before any
`timescale directive or after a `resetall directive. The default is
1s/1s.
.TP 8
.B +toupper-filename
This token causes file names after this in the command file to be
translated to uppercase. This helps with situations where a directory
has passed through a DOS machine, and in the process the file names
become munged.
.TP 8
.B +tolower-filename\fP
This is similar to the \fB+toupper-filename\fP hack described above.
.B +tolower-filename
This is similar to the \fB+toupper\-filename\fP hack described above.
.TP 8
.B +integer-width+\fIvalue\fP
@@ -377,7 +455,8 @@ integer value.
.SH "VARIABLES IN COMMAND FILES"
In certain cases, iverilog supports variables in command files. These
are strings of the form "$(\fIvarname\fP)", where \fIvarname\fP is the
are strings of the form "$(\fIvarname\fP)" or "${\fIvarname\fP}", where
\fIvarname\fP is the
name of the environment variable to read. The entire string is
replaced with the contents of that variable. Variables are only
substituted in contexts that explicitly support them, including file
@@ -390,12 +469,12 @@ from preprocessor defines elsewhere in the file or the command line.
The following macros are predefined by the compiler:
.TP 8
.B __ICARUS__ = 1\fP
This is defined always when compiling with Icarus Verilog.
.B __ICARUS__ = 1
This is always defined when compiling with Icarus Verilog.
.TP 8
.B __VAMS_ENABLE__ = 1\fp
This is defined if Verilog-AMS is enabled.
.B __VAMS_ENABLE__ = 1
This is defined if Verilog\-AMS is enabled.
.SH EXAMPLES
These examples assume that you have a Verilog source file called hello.v in
@@ -407,11 +486,11 @@ To compile hello.v to an executable file called a.out:
To compile hello.v to an executable file called hello:
iverilog -o hello hello.v
iverilog \-o hello hello.v
To compile and run explicitly using the vvp runtime:
iverilog -ohello.vvp -tvvp hello.v
iverilog \-ohello.vvp \-tvvp hello.v
.SH "AUTHOR"
.nf
@@ -426,7 +505,7 @@ Tips on using, debugging, and developing the compiler can be found at
.SH COPYRIGHT
.nf
Copyright \(co 2002-2008 Stephen Williams
Copyright \(co 2002\-2009 Stephen Williams
This document can be freely redistributed according to the terms of the
GNU General Public License version 2.0
+241 -64
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2000-2008 Stephen Williams (steve@icarus.com)
* Copyright (c) 2000-2009 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
@@ -18,7 +18,8 @@
*/
# include "config.h"
# include "version.h"
# include "version_base.h"
# include "version_tag.h"
const char NOTICE[] =
" This program is free software; you can redistribute it and/or modify\n"
@@ -31,14 +32,16 @@ const char NOTICE[] =
" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
" GNU General Public License for more details.\n"
"\n"
" You should have received a copy of the GNU General Public License\n"
" along with this program; if not, write to the Free Software\n"
" Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA\n"
" You should have received a copy of the GNU General Public License along\n"
" with this program; if not, write to the Free Software Foundation, Inc.,\n"
" 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n"
;
const char HELP[] =
"Usage: iverilog [-ESvV] [-B base] [-c cmdfile|-f cmdfile] [-g1|-g2|-g2x]\n"
" [-D macro[=defn]] [-I includedir] [-M depfile] [-m module]\n"
"Usage: iverilog [-ESvV] [-B base] [-c cmdfile|-f cmdfile]\n"
" [-g1995|-g2001|-g2005] [-g<feature>]\n"
" [-D macro[=defn]] [-I includedir]\n"
" [-M [mode=]depfile] [-m module]\n"
" [-N file] [-o filename] [-p flag=value]\n"
" [-s topmodule] [-t target] [-T min|typ|max]\n"
" [-W class] [-y dir] [-Y suf] source_file(s)\n"
@@ -107,16 +110,24 @@ const char*npath = 0;
const char*targ = "vvp";
const char*depfile = 0;
char depmode = 'a';
const char*generation = "2005";
const char*gen_specify = "specify";
const char*gen_specify = "no-specify";
const char*gen_xtypes = "xtypes";
const char*gen_icarus = "icarus-misc";
const char*gen_io_range_error = "io-range-error";
const char*gen_strict_ca_eval = "no-strict-ca-eval";
const char*gen_verilog_ams = "no-verilog-ams";
const char*gen_system_verilog = "no-system-verilog";
/* Boolean: true means use a default include dir, false means don't */
int gen_std_include = 1;
/* Boolean: true means add the local file directory to the start
of the include list. */
int gen_relative_include = 0;
char warning_flags[16] = "";
unsigned integer_width = 32;
@@ -139,8 +150,7 @@ FILE*iconfig_file = 0;
char*compiled_defines_path = 0;
static char iconfig_common_path_buf[4096] = "";
char*iconfig_common_path = iconfig_common_path_buf;
static char iconfig_common_path[4096] = "";
int synth_flag = 0;
int verbose_flag = 0;
@@ -160,6 +170,12 @@ typedef struct t_command_file {
p_command_file cmd_file_head = NULL; /* The FIFO head */
p_command_file cmd_file_tail = NULL; /* The FIFO tail */
/* Temprarily store parameter definition from command line and
* parse it after we have delt with command file
*/
static const char** defparm_base = 0;
static int defparm_size = 0;
/* Function to add a command file name to the FIFO. */
void add_cmd_file(const char* filename)
{
@@ -223,6 +239,23 @@ static FILE*fopen_safe(const char*path)
}
#endif
#ifdef __MINGW32__
/*
* The MinGW version of getenv() returns the path with a forward
* slash. This should be converted to a back slash to keep every
* thing in the code using a back slash. This function wraps the
* code for this in one place. The conversion can not be done
* directly on the getenv() result since it is const char*.
*/
static void convert_to_MS_path(char *path)
{
char *t;
for (t = path; *t; t++) {
if (*t == '/') *t = '\\';
}
}
#endif
static const char*my_tempfile(const char*str, FILE**fout)
{
FILE*file;
@@ -251,7 +284,11 @@ static const char*my_tempfile(const char*str, FILE**fout)
file = NULL;
while ((retry > 0) && (file == NULL)) {
unsigned code = rand();
sprintf(pathbuf, "%s%c%s%04x", tmpdir, sep, str, code);
snprintf(pathbuf, sizeof pathbuf, "%s%c%s%04x",
tmpdir, sep, str, code);
#ifdef __MINGW32__
convert_to_MS_path(pathbuf);
#endif
file = fopen_safe(pathbuf);
retry -= 1;
}
@@ -262,17 +299,24 @@ static const char*my_tempfile(const char*str, FILE**fout)
static int t_version_only(void)
{
int rc;
remove(source_path);
free(source_path);
fflush(0);
snprintf(tmp, sizeof tmp, "%s%civlpp -V", pbase, sep);
system(tmp);
rc = system(tmp);
if (rc != 0) {
fprintf(stderr, "Unable to get version from \"%s\"\n", tmp);
}
fflush(0);
snprintf(tmp, sizeof tmp, "%s%civl -V -C%s -C%s", pbase, sep,
snprintf(tmp, sizeof tmp, "%s%civl -V -C\"%s\" -C\"%s\"", base, sep,
iconfig_path, iconfig_common_path);
system(tmp);
rc = system(tmp);
if (rc != 0) {
fprintf(stderr, "Unable to get version from \"%s\"\n", tmp);
}
if ( ! getenv("IVERILOG_ICONFIG")) {
remove(iconfig_path);
@@ -288,8 +332,8 @@ static int t_version_only(void)
static void build_preprocess_command(int e_flag)
{
snprintf(tmp, sizeof tmp, "%s%civlpp %s%s -F%s -f%s -p%s ",
pbase,sep, verbose_flag?" -v":"",
snprintf(tmp, sizeof tmp, "%s%civlpp %s%s -F\"%s\" -f\"%s\" -p\"%s\" ",
pbase, sep, verbose_flag?" -v":"",
e_flag?"":" -L", defines_path, source_path,
compiled_defines_path);
}
@@ -307,7 +351,7 @@ static int t_preprocess_only(void)
strcpy(cmd, tmp);
if (strcmp(opath,"-") != 0) {
snprintf(tmp, sizeof tmp, " > %s", opath);
snprintf(tmp, sizeof tmp, " > \"%s\"", opath);
cmd = realloc(cmd, ncmd+strlen(tmp)+1);
strcpy(cmd+ncmd, tmp);
ncmd += strlen(tmp);
@@ -360,14 +404,12 @@ static int t_compile()
char*cmd = malloc(ncmd + 1);
strcpy(cmd, tmp);
#ifdef __MINGW32__
unsigned ncmd_start = ncmd;
#else
#ifndef __MINGW32__
int rtn;
#endif
/* Build the ivl command and pipe it to the preprocessor. */
snprintf(tmp, sizeof tmp, " | %s/ivl", base);
snprintf(tmp, sizeof tmp, " | %s%civl", base, sep);
rc = strlen(tmp);
cmd = realloc(cmd, ncmd+rc+1);
strcpy(cmd+ncmd, tmp);
@@ -382,35 +424,25 @@ static int t_compile()
}
if (npath != 0) {
snprintf(tmp, sizeof tmp, " -N%s", npath);
snprintf(tmp, sizeof tmp, " -N\"%s\"", npath);
rc = strlen(tmp);
cmd = realloc(cmd, ncmd+rc+1);
strcpy(cmd+ncmd, tmp);
ncmd += rc;
}
snprintf(tmp, sizeof tmp, " -C%s", iconfig_path);
snprintf(tmp, sizeof tmp, " -C\"%s\"", iconfig_path);
rc = strlen(tmp);
cmd = realloc(cmd, ncmd+rc+1);
strcpy(cmd+ncmd, tmp);
ncmd += rc;
snprintf(tmp, sizeof tmp, " -C%s -- -", iconfig_common_path);
snprintf(tmp, sizeof tmp, " -C\"%s\" -- -", iconfig_common_path);
rc = strlen(tmp);
cmd = realloc(cmd, ncmd+rc+1);
strcpy(cmd+ncmd, tmp);
ncmd += rc;
#ifdef __MINGW32__
{
char *t;
for (t = cmd+ncmd_start; *t; t++)
{
if (*t == '/') *t = '\\';
}
}
#endif
if (verbose_flag)
printf("translate: %s\n", cmd);
@@ -455,13 +487,18 @@ static void process_warning_switch(const char*name)
if (strcmp(name,"all") == 0) {
process_warning_switch("implicit");
process_warning_switch("portbind");
process_warning_switch("select-range");
process_warning_switch("timescale");
process_warning_switch("sensitivity-entire-array");
} else if (strcmp(name,"implicit") == 0) {
if (! strchr(warning_flags, 'i'))
strcat(warning_flags, "i");
} else if (strcmp(name,"portbind") == 0) {
if (! strchr(warning_flags, 'p'))
strcat(warning_flags, "p");
} else if (strcmp(name,"select-range") == 0) {
if (! strchr(warning_flags, 's'))
strcat(warning_flags, "s");
} else if (strcmp(name,"timescale") == 0) {
if (! strchr(warning_flags, 't'))
strcat(warning_flags, "t");
@@ -470,6 +507,12 @@ static void process_warning_switch(const char*name)
} else if (strcmp(name,"infloop") == 0) {
if (! strchr(warning_flags, 'l'))
strcat(warning_flags, "l");
} else if (strcmp(name,"sensitivity-entire-vector") == 0) {
if (! strchr(warning_flags, 'v'))
strcat(warning_flags, "v");
} else if (strcmp(name,"sensitivity-entire-array") == 0) {
if (! strchr(warning_flags, 'a'))
strcat(warning_flags, "a");
} else if (strcmp(name,"no-implicit") == 0) {
char*cp = strchr(warning_flags, 'i');
if (cp) while (*cp) {
@@ -482,12 +525,30 @@ static void process_warning_switch(const char*name)
cp[0] = cp[1];
cp += 1;
}
} else if (strcmp(name,"no-select-range") == 0) {
char*cp = strchr(warning_flags, 's');
if (cp) while (*cp) {
cp[0] = cp[1];
cp += 1;
}
} else if (strcmp(name,"no-timescale") == 0) {
char*cp = strchr(warning_flags, 't');
if (cp) while (*cp) {
cp[0] = cp[1];
cp += 1;
}
} else if (strcmp(name,"no-sensitivity-entire-vector") == 0) {
char*cp = strchr(warning_flags, 'v');
if (cp) while (*cp) {
cp[0] = cp[1];
cp += 1;
}
} else if (strcmp(name,"no-sensitivity-entire-array") == 0) {
char*cp = strchr(warning_flags, 'a');
if (cp) while (*cp) {
cp[0] = cp[1];
cp += 1;
}
}
}
@@ -516,6 +577,16 @@ void process_define(const char*name)
fprintf(defines_file,"D:%s\n", name);
}
void process_parameter(const char*name)
{
fprintf(iconfig_file,"defparam:%s\n", name);
}
void process_timescale(const char*ts_string)
{
fprintf(iconfig_file, "timescale:%s\n", ts_string);
}
/*
* 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
@@ -543,6 +614,9 @@ int process_generation(const char*name)
else if (strcmp(name,"2001") == 0)
generation = "2001";
else if (strcmp(name,"2001-noconfig") == 0)
generation = "2001-noconfig";
else if (strcmp(name,"2005") == 0)
generation = "2005";
@@ -584,6 +658,12 @@ int process_generation(const char*name)
else if (strcmp(name,"no-std-include") == 0)
gen_std_include = 0;
else if (strcmp(name,"relative-include") == 0)
gen_relative_include = 1;
else if (strcmp(name,"no-relative-include") == 0)
gen_relative_include = 0;
else if (strcmp(name,"io-range-error") == 0)
gen_io_range_error = "io-range-error";
@@ -591,11 +671,23 @@ int process_generation(const char*name)
else if (strcmp(name,"no-io-range-error") == 0)
gen_io_range_error = "no-io-range-error";
else if (strcmp(name,"strict-ca-eval") == 0)
gen_strict_ca_eval = "strict-ca-eval";
else if (strcmp(name,"no-strict-ca-eval") == 0)
gen_strict_ca_eval = "no-strict-ca-eval";
else if (strcmp(name,"verilog-ams") == 0)
gen_verilog_ams = "verilog-ams";
else if (strcmp(name,"no-verilog-ams") == 0)
gen_verilog_ams = "no-verilog-ams";
else if (strcmp(name,"system-verilog") == 0)
gen_system_verilog = "system-verilog";
else if (strcmp(name,"no-system-verilog") == 0)
gen_verilog_ams = "no-system-verilog";
else {
fprintf(stderr, "Unknown/Unsupported Language generation "
@@ -607,16 +699,51 @@ int process_generation(const char*name)
"Other generation flags:\n"
" specify | no-specify\n"
" verilog-ams | no-verilog-ams\n"
" system-verilog | no-system-verilog\n"
" std-include | no-std-include\n"
" relative-include | no-relative-include\n"
" xtypes | no-xtypes\n"
" icarus-misc | no-icarus-misc\n"
" io-range-error | no-io-range-error\n");
" io-range-error | no-io-range-error\n"
" strict-ca-eval | no-strict-ca-eval\n"
" system-verilog\n");
return 1;
}
return 0;
}
int process_depfile(const char*name)
{
const char*cp = strchr(name, '=');
if (cp) {
int match_length = (int)(cp - name) + 1;
if (strncmp(name, "all=", match_length) == 0) {
depmode = 'a';
} else if (strncmp(name, "include=", match_length) == 0) {
depmode = 'i';
} else if (strncmp(name, "module=", match_length) == 0) {
depmode = 'm';
} else if (strncmp(name, "prefix=", match_length) == 0) {
depmode = 'p';
} else {
fprintf(stderr, "Unknown dependency file mode '%.*s'\n\n",
match_length - 1, name);
fprintf(stderr, "Supported modes are:\n");
fprintf(stderr, " all\n");
fprintf(stderr, " include\n");
fprintf(stderr, " module\n");
fprintf(stderr, " prefix\n");
return -1;
}
depfile = cp + 1;
} else {
depmode = 'a';
depfile = name;
}
return 0;
}
/*
* If it exists add the SFT file for the given module.
*/
@@ -635,34 +762,34 @@ int main(int argc, char **argv)
{
int e_flag = 0;
int version_flag = 0;
int opt, idx, rc;
int opt, idx;
#ifdef __MINGW32__
{ char * s;
char basepath[1024];
GetModuleFileName(NULL,basepath,1024);
/* Calculate the ivl_root from the path to the command. This
is necessary because of the installation process on
Windows. Mostly, it is those darn drive letters, but oh
well. We know the command path is formed like this:
/* Calculate the ivl_root from the path to the command. This
is necessary because of the installation process in
Windows. Mostly, it is those darn drive letters, but oh
well. We know the command path is formed like this:
D:\iverilog\bin\iverilog.exe
D:\iverilog\bin\iverilog.exe
The module path in a Windows installation is the path:
The IVL_ROOT in a Windows installation is the path:
D:\iverilog\lib\ivl$(suffix)
D:\iverilog\lib\ivl
so we chop the file name and the last directory by
turning the last two \ characters to null. Then we append
the lib\ivl to finish. */
strncpy(ivl_root, basepath, MAXSIZE);
so we chop the file name and the last directory by
turning the last two \ characters to null. Then we append
the lib\ivl$(suffix) to finish. */
{ char *s;
char basepath[4096], tmp[4096];
GetModuleFileName(NULL, tmp, sizeof tmp);
/* Convert to a short name to remove any embedded spaces. */
GetShortPathName(tmp, basepath, sizeof basepath);
strncpy(ivl_root, basepath, MAXSIZE);
s = strrchr(ivl_root, sep);
if (s) *s = 0;
s = strrchr(ivl_root, sep);
if (s) *s = 0;
strcat(ivl_root, "\\lib\\ivl");
strcat(ivl_root, "\\lib\\ivl" IVL_SUFFIX);
base = ivl_root;
}
@@ -735,7 +862,7 @@ int main(int argc, char **argv)
}
}
while ((opt = getopt(argc, argv, "B:c:D:d:Ef:g:hI:M:m:N::o:p:Ss:T:t:vVW:y:Y:")) != EOF) {
while ((opt = getopt(argc, argv, "B:c:D:d:Ef:g:hI:M:m:N::o:P:p:Ss:T:t:vVW:y:Y:")) != EOF) {
switch (opt) {
case 'B':
@@ -759,6 +886,11 @@ int main(int argc, char **argv)
case 'E':
e_flag = 1;
break;
case 'P':
defparm_size += 1;
defparm_base = (const char**)realloc(defparm_base, defparm_size*sizeof(char*));
defparm_base[defparm_size-1] = optarg;
break;
case 'p':
fprintf(iconfig_file, "flag:%s\n", optarg);
break;
@@ -767,8 +899,7 @@ int main(int argc, char **argv)
break;
case 'g':
rc = process_generation(optarg);
if (rc != 0)
if (process_generation(optarg) != 0)
return -1;
break;
case 'h':
@@ -780,7 +911,8 @@ int main(int argc, char **argv)
break;
case 'M':
depfile = optarg;
if (process_depfile(optarg) != 0)
return -1;
break;
case 'm':
@@ -835,6 +967,20 @@ int main(int argc, char **argv)
break;
case '?':
default:
fclose(source_file);
remove(source_path);
free(source_path);
fclose(defines_file);
remove(defines_path);
free(defines_path);
fclose(iconfig_file);
remove(iconfig_path);
free(iconfig_path);
remove(compiled_defines_path);
free(compiled_defines_path);
while( (command_filename = get_cmd_file()) ) {
free(command_filename);
}
return 1;
}
}
@@ -844,13 +990,13 @@ int main(int argc, char **argv)
if (version_flag || verbose_flag) {
printf("Icarus Verilog version " VERSION " (" VERSION_TAG ")\n\n");
printf("Copyright 1998-2008 Stephen Williams\n");
printf("Copyright 1998-2009 Stephen Williams\n\n");
puts(NOTICE);
}
/* Make a common conf file path to reflect the target. */
sprintf(iconfig_common_path, "%s%c%s%s.conf",
base,sep, targ, synth_flag? "-s" : "");
snprintf(iconfig_common_path, sizeof iconfig_common_path, "%s%c%s%s.conf",
base, sep, targ, synth_flag? "-s" : "");
/* Write values to the iconfig file. */
fprintf(iconfig_file, "basedir:%s\n", base);
@@ -881,11 +1027,16 @@ int main(int argc, char **argv)
fprintf(iconfig_file, "generation:%s\n", gen_specify);
fprintf(iconfig_file, "generation:%s\n", gen_xtypes);
fprintf(iconfig_file, "generation:%s\n", gen_io_range_error);
fprintf(iconfig_file, "generation:%s\n", gen_strict_ca_eval);
fprintf(iconfig_file, "generation:%s\n", gen_verilog_ams);
fprintf(iconfig_file, "generation:%s\n", gen_icarus);
fprintf(iconfig_file, "generation:%s\n", gen_system_verilog);
fprintf(iconfig_file, "warnings:%s\n", warning_flags);
fprintf(iconfig_file, "out:%s\n", opath);
if (depfile) fprintf(iconfig_file, "depfile:%s\n", depfile);
if (depfile) {
fprintf(iconfig_file, "depfile:%s\n", depfile);
fprintf(iconfig_file, "depmode:%c\n", depmode);
}
while ( (command_filename = get_cmd_file()) ) {
int rc;
@@ -904,12 +1055,23 @@ int main(int argc, char **argv)
return 1;
}
free(command_filename);
fclose(fp);
}
destroy_lexor();
if (depfile) {
fprintf(defines_file, "M:%s\n", depfile);
fprintf(defines_file, "M%c:%s\n", depmode, depfile);
}
/* Process parameter definition from command line. The last
defined would override previous ones. */
int pitr;
for (pitr = 0; pitr < defparm_size; pitr++)
process_parameter(defparm_base[pitr]);
free(defparm_base);
defparm_base = 0;
defparm_size = 0;
/* Finally, process all the remaining words on the command
line as file names. */
for (idx = optind ; idx < argc ; idx += 1)
@@ -919,7 +1081,13 @@ int main(int argc, char **argv)
specifically disabled, then write that directory as the
very last include directory to use... always. */
if (gen_std_include) {
fprintf(defines_file, "I:%s%cinclude", base, sep);
fprintf(defines_file, "I:%s%cinclude\n", base, sep);
}
if (gen_relative_include) {
fprintf(defines_file, "relative include:true\n");
} else {
fprintf(defines_file, "relative include:false\n");
}
fclose(source_file);
@@ -928,6 +1096,15 @@ int main(int argc, char **argv)
fclose(defines_file);
defines_file = 0;
/* If we are planning on opening a dependencies file, then
open and truncate it here. The other phases of compilation
will append to the file, so this is necessray to make sure
it starts out empty. */
if (depfile) {
FILE*fd = fopen(depfile, "w");
fclose(fd);
}
if (source_count == 0 && !version_flag) {
fprintf(stderr, "%s: no source files.\n\n%s\n", argv[0], HELP);
return 1;
@@ -938,7 +1115,7 @@ int main(int argc, char **argv)
/* Write the preprocessor command needed to preprocess a
single file. This may be used to preprocess library
files. */
fprintf(iconfig_file, "ivlpp:%s%civlpp -L -F%s -P%s\n",
fprintf(iconfig_file, "ivlpp:%s%civlpp -L -F\"%s\" -P\"%s\"\n",
pbase, sep, defines_path, compiled_defines_path);
/* Done writing to the iconfig file. Close it now. */
+12 -30
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2002 Stephen Williams (steve@icarus.com)
* Copyright (c) 2002-2009 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
@@ -16,12 +16,10 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: substit.c,v 1.5 2003/12/19 01:27:10 steve Exp $"
#endif
# include <string.h>
# include <stdlib.h>
# include <stdio.h>
#ifdef HAVE_MALLOC_H
# include <malloc.h>
#endif
@@ -35,13 +33,13 @@ char* substitutions(const char*str)
while (*str) {
if ((str[0] == '$') && (str[1] == '(')) {
/* If I find a $(x) string in the source, replace
if ((str[0] == '$') && ((str[1] == '(') || str[1] == '{')) {
/* If I find a $(x) or ${x} string in the source, replace
it in the destination with the contents of the
environment variable x. */
char*name;
char*value;
const char*ep = strchr(str, ')');
const char*ep = strchr(str, (str[1]=='(') ? ')' : '}');
str += 2;
name = malloc(ep-str+1);
@@ -51,9 +49,14 @@ char* substitutions(const char*str)
str = ep + 1;
value = getenv(name);
free(name);
if (value == 0)
if (value == 0) {
fprintf(stderr, "Warning: environment variable "
"\"%s\" not found during command file "
"processing.\n", name);
free(name);
continue;
}
free(name);
if (strlen(value) >= (nbuf - (cp-buf))) {
size_t old_size = cp - buf;
@@ -92,24 +95,3 @@ char* substitutions(const char*str)
return buf;
}
/*
* $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.
*
* Revision 1.3 2002/08/11 23:47:04 steve
* Add missing Log and Ident strings.
*
* Revision 1.2 2002/06/25 01:33:01 steve
* include malloc.h only when available.
*
* Revision 1.1 2002/06/23 20:10:51 steve
* Variable substitution in command files.
*
*/
-47
View File
@@ -16,9 +16,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: elab_anet.cc,v 1.13 2007/03/22 16:08:14 steve Exp $"
#endif
# include "config.h"
@@ -167,47 +164,3 @@ NetNet* PEIdent::elaborate_anet(Design*des, NetScope*scope) const
return sig;
}
/*
* $Log: elab_anet.cc,v $
* Revision 1.13 2007/03/22 16:08:14 steve
* Spelling fixes from Larry
*
* Revision 1.12 2006/05/01 20:47:58 steve
* More explicit datatype setup.
*
* Revision 1.11 2005/07/11 16:56:50 steve
* Remove NetVariable and ivl_variable_t structures.
*
* 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.
*
* Revision 1.8 2003/06/21 01:21:43 steve
* Harmless fixup of warnings.
*
* Revision 1.7 2003/03/06 00:28:41 steve
* All NetObj objects have lex_string base names.
*
* Revision 1.6 2003/01/27 05:09:17 steve
* Spelling fixes.
*
* Revision 1.5 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.4 2001/12/03 04:47:14 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
*
* Revision 1.3 2001/07/25 03:10:48 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
*
* Revision 1.2 2001/01/06 02:29:36 steve
* Support arrays of integers.
*
* Revision 1.1 2000/12/06 06:31:09 steve
* Check lvalue of procedural continuous assign (PR#29)
*
*/
+1106 -323
View File
File diff suppressed because it is too large Load Diff
+146 -30
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2000-2008 Stephen Williams (steve@icarus.com)
* Copyright (c) 2000-2009 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
@@ -118,17 +118,20 @@ NetAssign_* PEConcat::elaborate_lval(Design*des,
NetAssign_*tmp = parms_[idx]->elaborate_lval(des, scope, is_force);
if (tmp->expr_type() == IVL_VT_REAL) {
cerr << parms_[idx]->get_fileline() << ": error: "
<< "concatenation operand can not be real: "
<< *parms_[idx] << endl;
des->errors += 1;
continue;
}
/* If the l-value doesn't elaborate, the error was
already detected and printed. We just skip it and let
the compiler catch more errors. */
if (tmp == 0)
continue;
assert(tmp);
if (tmp == 0) continue;
/* Link the new l-value to the previous one. */
NetAssign_*last = tmp;
while (last->more)
last = last->more;
@@ -179,9 +182,33 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
return 0;
}
/* Get the signal referenced by the identifier, and make sure
it is a register. Wires are not allows in this context,
unless this is the l-value of a force. */
if ((reg->type() != NetNet::REG) && !is_force) {
cerr << get_fileline() << ": error: " << path_ <<
" is not a valid l-value in " << scope_path(scope) <<
"." << endl;
cerr << reg->get_fileline() << ": : " << path_ <<
" is declared here as " << reg->type() << "." << endl;
des->errors += 1;
return 0;
}
if (reg->array_dimensions() > 0)
return elaborate_lval_net_word_(des, scope, reg);
// This must be after the array word elaboration above!
if (reg->get_scalar() &&
use_sel != index_component_t::SEL_NONE) {
cerr << get_fileline() << ": error: can not select part of ";
if (reg->data_type() == IVL_VT_REAL) cerr << "real: ";
else cerr << "scalar: ";
cerr << reg->name() << endl;
des->errors += 1;
return 0;
}
if (use_sel == index_component_t::SEL_PART) {
NetAssign_*lv = new NetAssign_(reg);
elaborate_lval_net_part_(des, scope, lv);
@@ -195,19 +222,6 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
return lv;
}
/* Get the signal referenced by the identifier, and make sure
it is a register. Wires are not allows in this context,
unless this is the l-value of a force. */
if ((reg->type() != NetNet::REG) && !is_force) {
cerr << get_fileline() << ": error: " << path_ <<
" is not a valid l-value in " << scope_path(scope) <<
"." << endl;
cerr << reg->get_fileline() << ": : " << path_ <<
" is declared here as " << reg->type() << "." << endl;
des->errors += 1;
return 0;
}
if (use_sel == index_component_t::SEL_BIT) {
NetAssign_*lv = new NetAssign_(reg);
@@ -243,6 +257,12 @@ NetAssign_* PEIdent::elaborate_lval_net_word_(Design*des,
ivl_assert(*this, index_head.msb != 0);
ivl_assert(*this, index_head.lsb == 0);
// These are not used, but they need to have a default value.
ivl_variable_type_t expr_type_tmp = IVL_VT_NO_TYPE;
bool unsized_flag_tmp = false;
index_head.msb->test_width(des, scope, integer_width, integer_width,
expr_type_tmp, unsized_flag_tmp);
NetExpr*word = elab_and_eval(des, scope, index_head.msb, -1);
// If there is a non-zero base to the memory, then build an
@@ -266,7 +286,7 @@ NetAssign_* PEIdent::elaborate_lval_net_word_(Design*des,
if (NetEConst*word_const = dynamic_cast<NetEConst*>(word)) {
verinum word_val = word_const->value();
long index = word_val.as_long();
assert (reg->array_count() <= LONG_MAX);
if (index < 0 || index >= (long) reg->array_count()) {
cerr << get_fileline() << ": warning: Constant array index "
<< (index + reg->array_first())
@@ -281,6 +301,20 @@ NetAssign_* PEIdent::elaborate_lval_net_word_(Design*des,
if (name_tail.index.size() > 1)
use_sel = name_tail.index.back().sel;
if (reg->get_scalar() &&
use_sel != index_component_t::SEL_NONE) {
cerr << get_fileline() << ": error: can not select part of ";
if (reg->data_type() == IVL_VT_REAL) cerr << "real";
else cerr << "scalar";
cerr << " array word: " << reg->name()
<< "[" << *word << "]" << endl;
des->errors += 1;
return 0;
}
if (use_sel == index_component_t::SEL_BIT)
elaborate_lval_net_bit_(des, scope, lv);
if (use_sel == index_component_t::SEL_PART)
elaborate_lval_net_part_(des, scope, lv);
@@ -302,6 +336,13 @@ bool PEIdent::elaborate_lval_net_bit_(Design*des,
NetNet*reg = lv->sig();
// These are not used, but they need to have a default value.
ivl_variable_type_t expr_type_tmp = IVL_VT_NO_TYPE;
bool unsized_flag_tmp = false;
index_tail.msb->test_width(des, scope, integer_width, integer_width,
expr_type_tmp, unsized_flag_tmp);
// Bit selects have a single select expression. Evaluate the
// constant value and treat it as a part select with a bit
// width of 1.
@@ -353,10 +394,13 @@ bool PEIdent::elaborate_lval_net_part_(Design*des,
// constant. The calculate_parts_ function calculates the
// values into msb and lsb.
long msb, lsb;
bool flag = calculate_parts_(des, scope, msb, lsb);
bool parts_defined_flag;
bool flag = calculate_parts_(des, scope, msb, lsb, parts_defined_flag);
if (!flag)
return false;
ivl_assert(*this, parts_defined_flag);
NetNet*reg = lv->sig();
assert(reg);
@@ -424,16 +468,88 @@ bool PEIdent::elaborate_lval_net_idx_(Design*des,
unsigned long wid;
calculate_up_do_width_(des, scope, wid);
// These are not used, but they need to have a default value.
ivl_variable_type_t expr_type_tmp = IVL_VT_NO_TYPE;
bool unsized_flag_tmp = false;
index_tail.msb->test_width(des, scope, integer_width, integer_width,
expr_type_tmp, unsized_flag_tmp);
NetExpr*base = elab_and_eval(des, scope, index_tail.msb, -1);
/* Correct the mux for the range of the vector. */
if (reg->msb() < reg->lsb())
base = make_sub_expr(reg->lsb(), base);
else if (reg->lsb() != 0)
base = make_add_expr(base, - reg->lsb());
if (use_sel == index_component_t::SEL_IDX_DO && wid > 1 ) {
base = make_add_expr(base, 1-(long)wid);
// Handle the special case that the base is constant. For this
// case we can reduce the expression.
if (NetEConst*base_c = dynamic_cast<NetEConst*> (base)) {
// For the undefined case just let the constant pass and
// we will handle it in the code generator.
if (base_c->value().is_defined()) {
long lsv = base_c->value().as_long();
long offset = 0;
if (((reg->msb() < reg->lsb()) &&
use_sel == index_component_t::SEL_IDX_UP) ||
((reg->msb() > reg->lsb()) &&
use_sel == index_component_t::SEL_IDX_DO)) {
offset = -wid + 1;
}
delete base;
long rel_base = reg->sb_to_idx(lsv) + offset;
/* If we cover the entire lvalue just skip the select. */
if (rel_base == 0 && wid == reg->vector_width()) return true;
base = new NetEConst(verinum(rel_base));
if (warn_ob_select) {
if (rel_base < 0) {
cerr << get_fileline() << ": warning: " << reg->name();
if (reg->array_dimensions() > 0) cerr << "[]";
cerr << "[" << lsv;
if (use_sel == index_component_t::SEL_IDX_UP) {
cerr << "+:";
} else {
cerr << "-:";
}
cerr << wid << "] is selecting before vector." << endl;
}
if (rel_base + wid > reg->vector_width()) {
cerr << get_fileline() << ": warning: " << reg->name();
if (reg->array_dimensions() > 0) cerr << "[]";
cerr << "[" << lsv;
if (use_sel == index_component_t::SEL_IDX_UP) {
cerr << "+:";
} else {
cerr << "-:";
}
cerr << wid << "] is selecting after vector." << endl;
}
}
} else {
if (warn_ob_select) {
cerr << get_fileline() << ": warning: " << reg->name();
if (reg->array_dimensions() > 0) cerr << "[]";
cerr << "['bx";
if (use_sel == index_component_t::SEL_IDX_UP) {
cerr << "+:";
} else {
cerr << "-:";
}
cerr << wid << "] is always outside vector." << endl;
}
}
} else {
/* Correct the mux for the range of the vector. */
if (use_sel == index_component_t::SEL_IDX_UP) {
if (reg->msb() > reg->lsb()) {
if (long offset = reg->lsb())
base = make_add_expr(base, -offset);
} else {
base = make_sub_expr(reg->lsb()-wid+1, base);
}
} else {
// This is assumed to be a SEL_IDX_DO.
if (reg->msb() > reg->lsb()) {
if (long offset = reg->lsb()+wid-1)
base = make_add_expr(base, -offset);
} else {
base = make_sub_expr(reg->lsb(), base);
}
}
}
if (debug_elaborate)
+149 -49
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1999-2008 Stephen Williams (steve@icarus.com)
* Copyright (c) 1999-2010 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
@@ -72,10 +72,16 @@ NetNet* PEConcat::elaborate_lnet_common_(Design*des, NetScope*scope,
} else {
nets[idx] = parms_[idx]->elaborate_lnet(des, scope);
}
if (nets[idx] == 0)
if (nets[idx] == 0) errors += 1;
else if (nets[idx]->data_type() == IVL_VT_REAL) {
cerr << parms_[idx]->get_fileline() << ": error: "
<< "concatenation operand can no be real: "
<< *parms_[idx] << endl;
errors += 1;
else
width += nets[idx]->vector_width();
continue;
} else width += nets[idx]->vector_width();
}
/* If any of the sub expressions failed to elaborate, then
@@ -164,29 +170,6 @@ NetNet* PEConcat::elaborate_bi_net(Design*des, NetScope*scope) const
return elaborate_lnet_common_(des, scope, true);
}
/*
* A private method to create an implicit net.
*/
NetNet* PEIdent::make_implicit_net_(Design*des, NetScope*scope) const
{
NetNet::Type nettype = scope->default_nettype();
assert(nettype != NetNet::NONE);
NetNet*sig = new NetNet(scope, peek_tail_name(path_),
NetNet::IMPLICIT, 1);
sig->set_line(*this);
/* Implicit nets are always scalar logic. */
sig->data_type(IVL_VT_LOGIC);
if (warn_implicit) {
cerr << get_fileline() << ": warning: implicit "
"definition of wire logic " << scope_path(scope)
<< "." << peek_tail_name(path_) << "." << endl;
}
return sig;
}
/*
* This private method evaluates the part selects (if any) for the
* signal. The sig argument is the NetNet already located for the
@@ -220,7 +203,9 @@ bool PEIdent::eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
case index_component_t::SEL_IDX_DO:
case index_component_t::SEL_IDX_UP: {
need_constant_expr = true;
NetExpr*tmp_ex = elab_and_eval(des, scope, index_tail.msb, -1);
need_constant_expr = false;
NetEConst*tmp = dynamic_cast<NetEConst*>(tmp_ex);
if (!tmp) {
cerr << get_fileline() << ": error: indexed part select of "
@@ -230,15 +215,33 @@ bool PEIdent::eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
return 0;
}
long midx_val = tmp->value().as_long();
midx = sig->sb_to_idx(midx_val);
delete tmp_ex;
/* The width (a constant) is calculated here. */
unsigned long wid = 0;
bool flag = calculate_up_do_width_(des, scope, wid);
if (! flag)
if (! flag) return false;
/* We have an undefined index and that is out of range. */
if (! tmp->value().is_defined()) {
if (warn_ob_select) {
cerr << get_fileline() << ": warning: "
<< sig->name();
if (sig->array_dimensions() > 0) cerr << "[]";
cerr << "['bx";
if (index_tail.sel ==
index_component_t::SEL_IDX_UP) {
cerr << "+:";
} else {
cerr << "-:";
}
cerr << wid << "] is always outside vector."
<< endl;
}
return false;
}
long midx_val = tmp->value().as_long();
midx = sig->sb_to_idx(midx_val);
delete tmp_ex;
if (index_tail.sel == index_component_t::SEL_IDX_UP)
lidx = sig->sb_to_idx(midx_val+wid-1);
@@ -252,9 +255,19 @@ bool PEIdent::eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
}
/* Warn about an indexed part select that is out of range. */
if (midx >= (long)sig->vector_width() || lidx < 0) {
cerr << get_fileline() << ": warning: Indexed part "
"select " << sig->name();
if (warn_ob_select && (lidx < 0)) {
cerr << get_fileline() << ": warning: " << sig->name();
if (sig->array_dimensions() > 0) cerr << "[]";
cerr << "[" << midx_val;
if (index_tail.sel == index_component_t::SEL_IDX_UP) {
cerr << "+:";
} else {
cerr << "-:";
}
cerr << wid << "] is selecting before vector." << endl;
}
if (warn_ob_select && (midx >= (long)sig->vector_width())) {
cerr << get_fileline() << ": warning: " << sig->name();
if (sig->array_dimensions() > 0) {
cerr << "[]";
}
@@ -264,7 +277,7 @@ bool PEIdent::eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
} else {
cerr << "-:";
}
cerr << wid << "] is out of range." << endl;
cerr << wid << "] is selecting after vector." << endl;
}
/* This is completely out side the signal so just skip it. */
@@ -278,7 +291,9 @@ bool PEIdent::eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
case index_component_t::SEL_PART: {
long msb, lsb;
/* bool flag = */ calculate_parts_(des, scope, msb, lsb);
bool part_defined_flag;
/* bool flag = */ calculate_parts_(des, scope, msb, lsb, part_defined_flag);
ivl_assert(*this, part_defined_flag);
long lidx_tmp = sig->sb_to_idx(lsb);
long midx_tmp = sig->sb_to_idx(msb);
@@ -403,17 +418,27 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
}
if (sig->port_type() == NetNet::PINPUT) {
cerr << get_fileline() << ": warning: L-value ``"
<< sig->name() << "'' is also an input port." << endl;
cerr << sig->get_fileline() << ": warning: input "
<< sig->name() << "; is coerced to inout." << endl;
sig->port_type(NetNet::PINOUT);
// This map mask prevents an error message being
// repeated endlessly.
static map<string,bool> mask_map;
bool&flag = mask_map[sig->get_fileline() + ":" + string(sig->name())];
if (! flag) {
cerr << get_fileline() << ": warning: L-value ``"
<< sig->name() << "'' is also an input port." << endl;
cerr << sig->get_fileline() << ": warning: input "
<< sig->name() << "; is coerced to inout." << endl;
flag = true;
}
}
// Default part select is the entire word.
unsigned midx = sig->vector_width()-1, lidx = 0;
// The default word select is the first.
unsigned widx = 0;
long widx = 0;
// The widx_val is the word select as entered in the source
// code. It's used for error messages.
long widx_val = 0;
const name_component_t&name_tail = path_.back();
@@ -435,7 +460,15 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
}
ivl_assert(*this, index_head.sel == index_component_t::SEL_BIT);
// These are not used, but they need to have a default value.
ivl_variable_type_t expr_type_tmp = IVL_VT_NO_TYPE;
bool unsized_flag_tmp = false;
index_head.msb->test_width(des, scope,
integer_width, integer_width,
expr_type_tmp, unsized_flag_tmp);
need_constant_expr = true;
NetExpr*tmp_ex = elab_and_eval(des, scope, index_head.msb, -1);
need_constant_expr = false;
NetEConst*tmp = dynamic_cast<NetEConst*>(tmp_ex);
if (!tmp) {
cerr << get_fileline() << ": error: array " << sig->name()
@@ -444,8 +477,11 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
return 0;
}
long widx_val = tmp->value().as_long();
widx = sig->array_index_to_address(widx_val);
widx_val = tmp->value().as_long();
if (sig->array_index_is_valid(widx_val))
widx = sig->array_index_to_address(widx_val);
else
widx = -1;
delete tmp_ex;
if (debug_elaborate)
@@ -454,6 +490,17 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
/* The array has a part/bit select at the end. */
if (name_tail.index.size() > sig->array_dimensions()) {
if (sig->get_scalar()) {
cerr << get_fileline() << ": error: "
<< "can not select part of ";
if (sig->data_type() == IVL_VT_REAL) cerr << "real";
else cerr << "scalar";
cerr << " array word: " << sig->name()
<< "[" << widx_val << "]" << endl;
des->errors += 1;
return 0;
}
long midx_tmp, lidx_tmp;
if (! eval_part_select_(des, scope, sig, midx_tmp, lidx_tmp))
return 0;
@@ -469,6 +516,16 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
lidx = lidx_tmp;
}
} else if (!name_tail.index.empty()) {
if (sig->get_scalar()) {
cerr << get_fileline() << ": error: "
<< "can not select part of ";
if (sig->data_type() == IVL_VT_REAL) cerr << "real: ";
else cerr << "scalar: ";
cerr << sig->name() << endl;
des->errors += 1;
return 0;
}
long midx_tmp, lidx_tmp;
if (! eval_part_select_(des, scope, sig, midx_tmp, lidx_tmp))
return 0;
@@ -487,7 +544,12 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
unsigned subnet_wid = midx-lidx+1;
if (sig->pin_count() > 1) {
assert(widx < sig->pin_count());
if (widx < 0 || widx >= (long) sig->pin_count()) {
cerr << get_fileline() << ": warning: ignoring out of "
"bounds l-value array access "
<< sig->name() << "[" << widx_val << "]." << endl;
return 0;
}
NetNet*tmp = new NetNet(scope, scope->local_symbol(),
sig->type(), sig->vector_width());
@@ -621,13 +683,51 @@ NetNet* PEIdent::elaborate_port(Design*des, NetScope*scope) const
if (! eval_part_select_(des, scope, sig, midx, lidx))
return 0;
/* If this is a part select of the entire signal (or no part
select at all) then we're done. */
if ((lidx == 0) && (midx == (long)sig->vector_width()-1))
return sig;
unsigned swid = midx - lidx + 1;
unsigned swid = abs(midx - lidx) + 1;
ivl_assert(*this, swid > 0 && swid < sig->vector_width());
if (swid < sig->vector_width()) {
cerr << get_fileline() << ": XXXX: Forgot to implement part select"
<< " of signal port." << endl;
NetNet*tmp = new NetNet(scope, scope->local_symbol(),
NetNet::WIRE, swid);
tmp->port_type(sig->port_type());
tmp->data_type(sig->data_type());
tmp->set_line(*this);
NetNode*ps = 0;
switch (sig->port_type()) {
case NetNet::PINPUT:
ps = new NetPartSelect(sig, sig->sb_to_idx(lidx), swid,
NetPartSelect::PV);
connect(tmp->pin(0), ps->pin(0));
sig = tmp;
break;
case NetNet::POUTPUT:
ps = new NetPartSelect(sig, sig->sb_to_idx(lidx), swid,
NetPartSelect::VP);
connect(tmp->pin(0), ps->pin(0));
sig = tmp;
break;
case NetNet::PINOUT:
ps = new NetTran(scope, scope->local_symbol(), sig->vector_width(),
swid, sig->sb_to_idx(lidx));
connect(sig->pin(0), ps->pin(0));
connect(tmp->pin(0), ps->pin(1));
sig = tmp;
break;
default:
ivl_assert(*this, 0);
break;
}
ps->set_line(*this);
des->add_node(ps);
return sig;
}
+89 -11
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2000-2008 Stephen Williams (steve@icarus.com)
* Copyright (c) 2000-2009 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
@@ -53,7 +53,7 @@ NetExpr*PEBinary::elaborate_pexpr (Design*des, NetScope*scope) const
return 0;
}
NetExpr*tmp = elaborate_expr_base_(des, lp, rp, -2);
NetExpr*tmp = elaborate_expr_base_(des, lp, rp, -2, true);
return tmp;
}
@@ -67,8 +67,6 @@ NetExpr*PEBComp::elaborate_pexpr(Design*des, NetScope*scope) const
return 0;
}
suppress_binary_operand_sign_if_needed_(lp, rp);
NetEBComp*tmp = new NetEBComp(op_, lp, rp);
tmp->set_line(*this);
bool flag = tmp->set_width(1);
@@ -81,6 +79,20 @@ NetExpr*PEBComp::elaborate_pexpr(Design*des, NetScope*scope) const
return tmp;
}
NetExpr*PEBLeftWidth::elaborate_pexpr (Design*des, NetScope*scope) const
{
NetExpr*lp = left_->elaborate_pexpr(des, scope);
NetExpr*rp = right_->elaborate_pexpr(des, scope);
if ((lp == 0) || (rp == 0)) {
delete lp;
delete rp;
return 0;
}
NetExpr*tmp = elaborate_expr_leaf(des, lp, rp, -2);
return tmp;
}
NetExpr*PEBLogic::elaborate_pexpr(Design*des, NetScope*scope) const
{
NetExpr*lp = left_->elaborate_pexpr(des, scope);
@@ -138,11 +150,19 @@ NetEConcat* PEConcat::elaborate_pexpr(Design*des, NetScope*scope) const
/* Elaborate all the operands and attach them to the concat
node. Use the elaborate_pexpr method instead of the
elaborate_expr method. */
bool fail = false;
for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) {
assert(parms_[idx]);
NetExpr*ex = parms_[idx]->elaborate_pexpr(des, scope);
if (ex == 0) continue;
if (ex->expr_type() == IVL_VT_REAL) {
cerr << ex->get_fileline() << ": error: concatenation "
<< "operand can not be real: " << *ex << endl;
des->errors += 1;
fail = true;
continue;
}
ex->set_line(*parms_[idx]);
if (dynamic_cast<NetEParam*>(ex)) {
@@ -155,13 +175,18 @@ NetEConcat* PEConcat::elaborate_pexpr(Design*des, NetScope*scope) const
<< "concatenation has indefinite width: "
<< *ex << endl;
des->errors += 1;
delete tmp;
return 0;
fail = true;
continue;
}
tmp->set(idx, ex);
}
if (fail) {
delete tmp;
return 0;
}
return tmp;
}
@@ -182,6 +207,14 @@ NetExpr*PEIdent::elaborate_pexpr(Design*des, NetScope*scope) const
name_component_t name_tail = path_.back();
oldpath.pop_back();
if (path_.size() > 1) {
cerr << get_fileline() << ": error: parameter r-value expression "
"does not support hierarchical references `" << path_
<< "`." << endl;
des->errors += 1;
return 0;
}
NetScope*pscope = scope;
if (path_.size() > 0) {
list<hname_t> tmp = eval_scope_path(des, scope, oldpath);
@@ -204,8 +237,9 @@ NetExpr*PEIdent::elaborate_pexpr(Design*des, NetScope*scope) const
ivl_assert(*this, pscope);
}
if (ex == 0) {
cerr << get_fileline() << ": error: identifier ``" << name_tail.name <<
"'' is not a parameter in "<< scope_path(scope)<< "." << endl;
cerr << get_fileline() << ": error: identifier `"
<< name_tail.name << "` is not a parameter in "
<< scope_path(scope)<< "." << endl;
des->errors += 1;
return 0;
}
@@ -426,15 +460,59 @@ NetExpr* PECallFunction::elaborate_pexpr(Design*des, NetScope*scope) const
return rtn;
}
cerr << get_fileline() << ": error: this is not a constant "
"system function (" << *this << ")." << endl;
cerr << get_fileline() << ": error: " << nm << "() is not a "
"constant system function." << endl;
des->errors += 1;
return 0;
}
/* Constant user function code goes here. */
cerr << get_fileline() << ": sorry: constant user functions are not "
"currently supported." << endl;
"currently supported: " << nm << "()." << endl;
des->errors += 1;
return 0;
}
void NetExpr::resolve_pexpr_type(void)
{
}
void NetEBinary::resolve_pexpr_type(void)
{
if (debug_elab_pexpr) {
cerr << get_fileline() << ": debug: "
<< "Resolve_pexpr_type for binary " << human_readable_op(op_)
<< "." << endl;
}
left_->resolve_pexpr_type();
right_->resolve_pexpr_type();
switch (op_) {
case '+':
case '-':
case '*':
case '/':
suppress_binary_operand_sign_if_needed(left_, right_);
cast_signed_base_(left_->has_sign() && right_->has_sign());
break;
default:
break;
}
}
void NetEParam::resolve_pexpr_type(void)
{
if (debug_elab_pexpr) {
cerr << get_fileline() << ": debug: "
<< "Resolve_pexpr_type for parameter " << reference_->first
<< "." << endl;
}
if (reference_->second.signed_flag) {
cast_signed_base_(true);
} else {
cast_signed_base_( reference_->second.expr->has_sign() );
}
}
+461 -70
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2000-2008 Stephen Williams (steve@icarus.com)
* Copyright (c) 2000-2010 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
@@ -114,6 +114,7 @@ static void elaborate_parm_item_(perm_string name,
tmp->high_open_flag = range->high_open_flag;
if (range->low_expr) {
probe_expr_width(des, scope, range->low_expr);
tmp->low_expr = elab_and_eval(des, scope, range->low_expr, -1);
ivl_assert(*range->low_expr, tmp->low_expr);
} else {
@@ -130,6 +131,7 @@ static void elaborate_parm_item_(perm_string name,
tmp->high_expr = tmp->low_expr;
} else if (range->high_expr) {
probe_expr_width(des, scope, range->high_expr);
tmp->high_expr = elab_and_eval(des, scope, range->high_expr, -1);
ivl_assert(*range->high_expr, tmp->high_expr);
} else {
@@ -172,6 +174,15 @@ static void elaborate_scope_parameters_(Design*des, NetScope*scope,
for (mparm_it_t cur = parameters.begin()
; cur != parameters.end() ; cur ++) {
// A parameter can not have the same name as a genvar.
if (scope->find_genvar((*cur).first)) {
cerr << cur->second.get_fileline()
<< ": error: parameter and genvar in '"
<< scope->fullname() << "' have the same name '"
<< (*cur).first << "'." << endl;
des->errors += 1;
}
elaborate_parm_item_((*cur).first, (*cur).second, des, scope);
}
}
@@ -182,6 +193,15 @@ static void elaborate_scope_localparams_(Design*des, NetScope*scope,
for (mparm_it_t cur = localparams.begin()
; cur != localparams.end() ; cur ++) {
// A localparam can not have the same name as a genvar.
if (scope->find_genvar((*cur).first)) {
cerr << cur->second.get_fileline()
<< ": error: localparam and genvar in '"
<< scope->fullname() << "' have the same name '"
<< (*cur).first << "'." << endl;
des->errors += 1;
}
elaborate_parm_item_((*cur).first, (*cur).second, des, scope);
}
}
@@ -196,7 +216,7 @@ static void replace_scope_parameters_(NetScope*scope, const LineInfo&loc,
if (val == 0) {
cerr << loc.get_fileline() << ": internal error: "
<< "Missing expression in parameter replacement for "
<< (*cur).first;
<< (*cur).first << endl;;
}
assert(val);
if (debug_scopes) {
@@ -236,13 +256,38 @@ static void elaborate_scope_tasks(Design*des, NetScope*scope,
; cur != tasks.end() ; cur ++ ) {
hname_t use_name( (*cur).first );
if (scope->child(use_name)) {
cerr << loc.get_fileline() << ": error: task/scope name "
<< use_name << " already used in this context."
<< endl;
// A task can not have the same name as another scope object.
const NetScope *child = scope->child(use_name);
if (child) {
cerr << cur->second->get_fileline() << ": error: task and ";
child->print_type(cerr);
cerr << " in '" << scope->fullname()
<< "' have the same name '" << use_name << "'." << endl;
des->errors += 1;
continue;
}
// A task can not have the same name as a genvar.
if (scope->find_genvar((*cur).first)) {
cerr << cur->second->get_fileline()
<< ": error: task and genvar in '"
<< scope->fullname() << "' have the same name '"
<< (*cur).first << "'." << endl;
des->errors += 1;
}
// A task can not have the same name as a parameter.
const NetExpr *ex_msb, *ex_lsb;
const NetExpr *parm = scope->get_parameter((*cur).first, ex_msb,
ex_lsb);
if (parm) {
cerr << cur->second->get_fileline()
<< ": error: task and parameter in '"
<< scope->fullname() << "' have the same name '"
<< (*cur).first << "'." << endl;
des->errors += 1;
}
NetScope*task_scope = new NetScope(scope, use_name,
NetScope::TASK);
task_scope->is_auto((*cur).second->is_auto());
@@ -266,13 +311,39 @@ static void elaborate_scope_funcs(Design*des, NetScope*scope,
; cur != funcs.end() ; cur ++ ) {
hname_t use_name( (*cur).first );
if (scope->child(use_name)) {
cerr << loc.get_fileline() << ": error: function/scope name "
<< use_name << " already used in this context."
<< endl;
// A function can not have the same name as another scope object.
const NetScope *child = scope->child(use_name);
if (child) {
cerr << cur->second->get_fileline()
<< ": error: function and ";
child->print_type(cerr);
cerr << " in '" << scope->fullname()
<< "' have the same name '" << use_name << "'." << endl;
des->errors += 1;
continue;
}
// A function can not have the same name as a genvar.
if (scope->find_genvar((*cur).first)) {
cerr << cur->second->get_fileline()
<< ": error: function and genvar in '"
<< scope->fullname() << "' have the same name '"
<< (*cur).first << "'." << endl;
des->errors += 1;
}
// A function can not have the same name as a parameter.
const NetExpr *ex_msb, *ex_lsb;
const NetExpr *parm = scope->get_parameter((*cur).first, ex_msb,
ex_lsb);
if (parm) {
cerr << cur->second->get_fileline()
<< ": error: function and parameter in '"
<< scope->fullname() << "' have the same name '"
<< (*cur).first << "'." << endl;
des->errors += 1;
}
NetScope*func_scope = new NetScope(scope, use_name,
NetScope::FUNC);
func_scope->is_auto((*cur).second->is_auto());
@@ -326,6 +397,12 @@ bool Module::elaborate_scope(Design*des, NetScope*scope,
<< scope_path(scope) << "." << endl;
}
// Add the genvars to the scope.
typedef map<perm_string,LineInfo*>::const_iterator genvar_it_t;
for (genvar_it_t cur = genvars.begin(); cur != genvars.end(); cur++ ) {
scope->add_genvar((*cur).first, (*cur).second);
}
// 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
@@ -444,6 +521,8 @@ bool Module::elaborate_scope(Design*des, NetScope*scope,
elaborate_scope_events_(des, scope, events);
scope->is_cell(is_cell);
return des->errors == 0;
}
@@ -484,8 +563,16 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
{
// Check that the loop_index variable was declared in a
// genvar statement.
// MISSING CODE!
NetScope*scope = container;
while (scope && !scope->find_genvar(loop_index))
scope = scope->parent();
if (!scope) {
cerr << get_fileline() << ": error: genvar is missing for "
"generate \"loop\" variable '" << loop_index << "'."
<< endl;
des->errors += 1;
return false;
}
// We're going to need a genvar...
int genvar;
@@ -493,7 +580,10 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
// The initial value for the genvar does not need (nor can it
// use) the genvar itself, so we can evaluate this expression
// the same way any other parameter value is evaluated.
probe_expr_width(des, container, loop_init);
need_constant_expr = true;
NetExpr*init_ex = elab_and_eval(des, container, loop_init, -1);
need_constant_expr = false;
NetEConst*init = dynamic_cast<NetEConst*> (init_ex);
if (init == 0) {
cerr << get_fileline() << ": error: Cannot evaluate genvar"
@@ -502,19 +592,53 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
return false;
}
// Since we will be adding the genvar value as a local parameter
// to each instances scope. We need to make sure a parameter does
// not already exist.
const NetExpr*tmsb;
const NetExpr*tlsb;
const NetExpr*texpr = container->get_parameter(loop_index, tmsb, tlsb);
if (texpr != 0) {
cerr << get_fileline() << ": error: Cannot have a genvar "
<< "and parameter with the same name: " << loop_index << endl;
// Check the generate block name.
// A generate "loop" can not have the same name as another scope object.
const NetScope *child = container->child(hname_t(scope_name));
if (child) {
cerr << get_fileline() << ": error: generate \"loop\" and ";
child->print_type(cerr);
cerr << " in '" << container->fullname()
<< "' have the same name '" << scope_name << "'." << endl;
des->errors += 1;
return false;
}
// A generate "loop" can not have the same name as a genvar.
if (container->find_genvar(scope_name)) {
cerr << get_fileline() << ": error: generate \"loop\" and "
"genvar in '" << container->fullname()
<< "' have the same name '" << scope_name << "'." << endl;
des->errors += 1;
}
// A generate "loop" can not have the same name as a named event.
const NetEvent *event = container->find_event(scope_name);
if (event) {
cerr << get_fileline() << ": error: generate \"loop\" and "
"named event in '" << container->fullname()
<< "' have the same name '" << scope_name << "'." << endl;
des->errors += 1;
}
// A generate "loop" can not have the same name as a parameter.
const NetExpr*tmsb;
const NetExpr*tlsb;
const NetExpr*texpr = container->get_parameter(scope_name, tmsb, tlsb);
if (texpr != 0) {
cerr << get_fileline() << ": error: generate \"loop\" and "
"parameter in '" << container->fullname()
<< "' have the same name '" << scope_name << "'." << endl;
des->errors += 1;
}
// These have all been checked so we just need to skip the actual
// generation for these name conflicts. Not skipping these two will
// cause the compiler to have problems (assert, inf. loop, etc.).
if (container->get_parameter(loop_index, tmsb, tlsb)) return false;
if (container->find_event(loop_index)) return false;
genvar = init->value().as_long();
delete init_ex;
@@ -522,7 +646,10 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
cerr << get_fileline() << ": debug: genvar init = " << genvar << endl;
container->genvar_tmp = loop_index;
container->genvar_tmp_val = genvar;
probe_expr_width(des, container, loop_test);
need_constant_expr = true;
NetExpr*test_ex = elab_and_eval(des, container, loop_test, -1);
need_constant_expr = false;
NetEConst*test = dynamic_cast<NetEConst*>(test_ex);
if (test == 0) {
cerr << get_fileline() << ": error: Cannot evaluate genvar"
@@ -537,13 +664,7 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
// container. The format of using [] is part of the
// Verilog standard.
hname_t use_name (scope_name, genvar);
if (container->child(use_name)) {
cerr << get_fileline() << ": error: block/scope name "
<< use_name << " already used in this context."
<< endl;
des->errors += 1;
return false;
}
if (debug_scopes)
cerr << get_fileline() << ": debug: "
<< "Create generated scope " << use_name << endl;
@@ -574,7 +695,10 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
elaborate_subscope_(des, scope);
// Calculate the step for the loop variable.
probe_expr_width(des, container, loop_step);
need_constant_expr = true;
NetExpr*step_ex = elab_and_eval(des, container, loop_step, -1);
need_constant_expr = false;
NetEConst*step = dynamic_cast<NetEConst*>(step_ex);
if (step == 0) {
cerr << get_fileline() << ": error: Cannot evaluate genvar"
@@ -590,13 +714,14 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
container->genvar_tmp_val = genvar;
delete step;
delete test_ex;
probe_expr_width(des, container, loop_test);
test_ex = elab_and_eval(des, container, loop_test, -1);
test = dynamic_cast<NetEConst*>(test_ex);
assert(test);
}
// Clear the genvar_tmp field in the scope to reflect that the
// genvar is no longer value for evaluating expressions.
// genvar is no longer valid for evaluating expressions.
container->genvar_tmp = perm_string();
return true;
@@ -604,7 +729,10 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
bool PGenerate::generate_scope_condit_(Design*des, NetScope*container, bool else_flag)
{
probe_expr_width(des, container, loop_test);
need_constant_expr = true;
NetExpr*test_ex = elab_and_eval(des, container, loop_test, -1);
need_constant_expr = false;
NetEConst*test = dynamic_cast<NetEConst*> (test_ex);
if (test == 0) {
cerr << get_fileline() << ": error: Cannot evaluate genvar"
@@ -627,21 +755,64 @@ bool PGenerate::generate_scope_condit_(Design*des, NetScope*container, bool else
}
hname_t use_name (scope_name);
if (container->child(use_name)) {
cerr << get_fileline() << ": error: block/scope name "
<< scope_name << " already used in this context."
<< endl;
// A generate "if" can not have the same name as another scope object.
const NetScope *child = container->child(use_name);
if (child) {
cerr << get_fileline() << ": error: generate \"if\" and ";
child->print_type(cerr);
cerr << " in '" << container->fullname()
<< "' have the same name '" << use_name << "'." << endl;
des->errors += 1;
return false;
}
// A generate "if" can not have the same name as a genvar.
if (container->find_genvar(scope_name)) {
cerr << get_fileline() << ": error: generate \"if\" and "
"genvar in '" << container->fullname()
<< "' have the same name '" << scope_name << "'." << endl;
des->errors += 1;
}
// A generate "if" can not have the same name as a named event.
const NetEvent *event = container->find_event(scope_name);
if (event) {
cerr << get_fileline() << ": error: generate \"if\" and "
"named event in '" << container->fullname()
<< "' have the same name '" << use_name << "'." << endl;
des->errors += 1;
}
// A generate "if" can not have the same name as a parameter.
const NetExpr *ex_msb, *ex_lsb;
const NetExpr *parm = container->get_parameter(scope_name, ex_msb,
ex_lsb);
if (parm) {
cerr << get_fileline() << ": error: generate \"if\" and "
"parameter in '" << container->fullname()
<< "' have the same name '" << use_name << "'." << endl;
des->errors += 1;
}
if (debug_scopes)
cerr << get_fileline() << ": debug: Generate condition "
<< (else_flag? "(else)" : "(if)")
<< " value=" << test->value() << ": Generate scope="
<< use_name << endl;
NetScope*scope = new NetScope(container, use_name,
NetScope::GENBLOCK);
probe_for_direct_nesting_();
if (direct_nested_) {
if (debug_scopes)
cerr << get_fileline() << ": debug: Generate condition "
<< (else_flag? "(else)" : "(if)")
<< " detected direct nesting." << endl;
elaborate_subscope_direct_(des, container);
return true;
}
// If this is not directly nested, then generate a scope
// for myself. That is what I will pass to the subscope.
NetScope*scope = new NetScope(container, use_name, NetScope::GENBLOCK);
scope->set_line(get_file(), get_lineno());
elaborate_subscope_(des, scope);
@@ -651,7 +822,10 @@ bool PGenerate::generate_scope_condit_(Design*des, NetScope*container, bool else
bool PGenerate::generate_scope_case_(Design*des, NetScope*container)
{
probe_expr_width(des, container, loop_test);
need_constant_expr = true;
NetExpr*case_value_ex = elab_and_eval(des, container, loop_test, -1);
need_constant_expr = false;
NetEConst*case_value_co = dynamic_cast<NetEConst*>(case_value_ex);
if (case_value_co == 0) {
cerr << get_fileline() << ": error: Cannot evaluate genvar case"
@@ -673,24 +847,40 @@ bool PGenerate::generate_scope_case_(Design*des, NetScope*container)
assert( item->scheme_type == PGenerate::GS_CASE_ITEM );
// Detect that the item is a default.
if (item->loop_test == 0) {
if (item->item_test.size() == 0) {
default_item = item;
cur ++;
continue;
}
NetExpr*item_value_ex = elab_and_eval(des, container, item->loop_test, -1);
NetEConst*item_value_co = dynamic_cast<NetEConst*>(item_value_ex);
assert(item_value_co);
bool match_flag = false;
for (unsigned idx = 0 ; idx < item->item_test.size() && !match_flag ; idx +=1 ) {
probe_expr_width(des, container, item->item_test[idx]);
need_constant_expr = true;
NetExpr*item_value_ex = elab_and_eval(des, container, item->item_test[idx], -1);
need_constant_expr = false;
NetEConst*item_value_co = dynamic_cast<NetEConst*>(item_value_ex);
if (item_value_co == 0) {
cerr << get_fileline() << ": error: Cannot evaluate "
<< " genvar case item expression: "
<< *item->item_test[idx] << endl;
des->errors += 1;
return false;
}
// If we stumble on the item that matches, then break
// out now.
if (case_value_co->value() == item_value_co->value()) {
if (debug_scopes)
cerr << get_fileline() << ": debug: Generate case "
<< "item value=" << item_value_co->value() << endl;
if (case_value_co->value() == item_value_co->value())
match_flag = true;
delete item_value_co;
break;
}
delete item_value_co;
// If we stumble on the item that matches, then break out now.
if (match_flag)
break;
cur ++;
}
@@ -711,6 +901,53 @@ bool PGenerate::generate_scope_case_(Design*des, NetScope*container)
// The name of the scope to generate, whatever that item is.
hname_t use_name (item->scope_name);
// A generate "case" can not have the same name as another scope object.
const NetScope *child = container->child(use_name);
if (child) {
cerr << get_fileline() << ": error: generate \"case\" and ";
child->print_type(cerr);
cerr << " in '" << container->fullname()
<< "' have the same name '" << use_name << "'." << endl;
des->errors += 1;
return false;
}
// A generate "case" can not have the same name as a genvar.
if (container->find_genvar(item->scope_name)) {
cerr << get_fileline() << ": error: generate \"case\" and "
"genvar in '" << container->fullname()
<< "' have the same name '" << use_name << "'." << endl;
des->errors += 1;
}
// A generate "case" can not have the same name as a named event.
const NetEvent *event = container->find_event(item->scope_name);
if (event) {
cerr << get_fileline() << ": error: generate \"case\" and "
"named event in '" << container->fullname()
<< "' have the same name '" << use_name << "'." << endl;
des->errors += 1;
}
// A generate "case" can not have the same name as a parameter.
const NetExpr *ex_msb, *ex_lsb;
const NetExpr *parm = container->get_parameter(item->scope_name, ex_msb,
ex_lsb);
if (parm) {
cerr << get_fileline() << ": error: generate \"case\" and "
"parameter in '" << container->fullname()
<< "' have the same name '" << use_name << "'." << endl;
des->errors += 1;
}
item->probe_for_direct_nesting_();
if (item->direct_nested_) {
if (debug_scopes)
cerr << get_fileline() << ": debug: Generate case item " << scope_name
<< " detected direct nesting." << endl;
item->elaborate_subscope_direct_(des, container);
return true;
}
NetScope*scope = new NetScope(container, use_name,
NetScope::GENBLOCK);
@@ -723,13 +960,46 @@ bool PGenerate::generate_scope_case_(Design*des, NetScope*container)
bool PGenerate::generate_scope_nblock_(Design*des, NetScope*container)
{
hname_t use_name (scope_name);
if (container->child(use_name)) {
cerr << get_fileline() << ": error: block/scope name "
<< scope_name << " already used in this context."
<< endl;
// A generate "block" can not have the same name as another scope
// object.
const NetScope *child = container->child(use_name);
if (child) {
cerr << get_fileline() << ": error: generate \"block\" and ";
child->print_type(cerr);
cerr << " in '" << container->fullname()
<< "' have the same name '" << use_name << "'." << endl;
des->errors += 1;
return false;
}
// A generate "block" can not have the same name as a genvar.
if (container->find_genvar(scope_name)) {
cerr << get_fileline() << ": error: generate \"block\" and "
"genvar in '" << container->fullname()
<< "' have the same name '" << scope_name << "'." << endl;
des->errors += 1;
}
// A generate "block" can not have the same name as a named event.
const NetEvent *event = container->find_event(scope_name);
if (event) {
cerr << get_fileline() << ": error: generate \"block\" and "
"named event in '" << container->fullname()
<< "' have the same name '" << use_name << "'." << endl;
des->errors += 1;
}
// A generate "block" can not have the same name as a parameter.
const NetExpr *ex_msb, *ex_lsb;
const NetExpr *parm = container->get_parameter(scope_name, ex_msb,
ex_lsb);
if (parm) {
cerr << get_fileline() << ": error: generate \"block\" and "
"parameter in '" << container->fullname()
<< "' have the same name '" << use_name << "'." << endl;
des->errors += 1;
}
if (debug_scopes)
cerr << get_fileline() << ": debug: Generate named block "
<< ": Generate scope=" << use_name << endl;
@@ -743,8 +1013,23 @@ bool PGenerate::generate_scope_nblock_(Design*des, NetScope*container)
return true;
}
void PGenerate::elaborate_subscope_direct_(Design*des, NetScope*scope)
{
typedef list<PGenerate*>::const_iterator generate_it_t;
for (generate_it_t cur = generate_schemes.begin()
; cur != generate_schemes.end() ; cur ++ ) {
(*cur) -> generate_scope(des, scope);
}
}
void PGenerate::elaborate_subscope_(Design*des, NetScope*scope)
{
// Add the genvars to this scope.
typedef map<perm_string,LineInfo*>::const_iterator genvar_it_t;
for (genvar_it_t cur = genvars.begin(); cur != genvars.end(); cur++ ) {
scope->add_genvar((*cur).first, (*cur).second);
}
// Scan the generated scope for nested generate schemes,
// and *generate* new scopes, which is slightly different
// from simple elaboration.
@@ -785,6 +1070,10 @@ void PGenerate::elaborate_subscope_(Design*des, NetScope*scope)
// Scan through all the named events in this scope.
elaborate_scope_events_(des, scope, events);
if (debug_scopes)
cerr << get_fileline() << ": debug: Generated scope " << scope_path(scope)
<< " by generate block " << scope_name << endl;
// Save the scope that we created, for future use.
scope_list_.push_back(scope);
}
@@ -836,36 +1125,77 @@ void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const
// Missing module instance names have already been rejected.
assert(get_name() != "");
// Check for duplicate scopes. Simply look up the scope I'm
// about to create, and if I find it then somebody beat me to
// it.
if (sc->child(hname_t(get_name()))) {
cerr << get_fileline() << ": error: Instance/Scope name " <<
get_name() << " already used in this context." <<
endl;
// A module instance can not have the same name as another scope object.
const NetScope *child = sc->child(hname_t(get_name()));
if (child) {
cerr << get_fileline() << ": error: module <" << mod->mod_name()
<< "> instance and ";
child->print_type(cerr);
cerr << " in '" << sc->fullname()
<< "' have the same name '" << get_name() << "'." << endl;
des->errors += 1;
return;
}
// A module instance can not have the same name as a genvar.
if (sc->find_genvar(get_name())) {
cerr << get_fileline() << ": error: module <" << mod->mod_name()
<< "> instance and genvar in '" << sc->fullname()
<< "' have the same name '" << get_name() << "'." << endl;
des->errors += 1;
}
// A module instance can not have the same name as a parameter.
const NetExpr *ex_msb, *ex_lsb;
const NetExpr *parm = sc->get_parameter(get_name(), ex_msb, ex_lsb);
if (parm) {
cerr << get_fileline() << ": error: module <" << mod->mod_name()
<< "> instance and parameter in '" << sc->fullname()
<< "' have the same name '" << get_name() << "'." << endl;
des->errors += 1;
}
// check for recursive instantiation by scanning the current
// scope and its parents. Look for a module instantiation of
// the same module, but farther up in the scope.
unsigned rl_count = 0;
bool in_genblk = false;
for (NetScope*scn = sc ; scn ; scn = scn->parent()) {
if (scn->type() != NetScope::MODULE)
// We need to know if we are inside a generate block to allow
// recursive instances.
if (scn->type() == NetScope::GENBLOCK) {
in_genblk = true;
continue;
}
if (strcmp(mod->mod_name(), scn->module_name()) != 0)
if (scn->type() != NetScope::MODULE) continue;
if (strcmp(mod->mod_name(), scn->module_name()) != 0) continue;
// We allow nested scopes if they are inside a generate block,
// but only to a certain nesting depth.
if (in_genblk) {
rl_count += 1;
if (rl_count > recursive_mod_limit) {
cerr << get_fileline() << ": error: instance "
<< scope_path(sc) << "." << get_name()
<< " of module " << mod->mod_name()
<< " is nested too deep." << endl;
cerr << get_fileline() << ": : check for "
"proper recursion termination or increase the "
"limit (" << recursive_mod_limit
<< ") with the -pRECURSIVE_MOD_LIMIT flag."
<< endl;
des->errors += 1;
return;
}
continue;
}
cerr << get_fileline() << ": error: You cannot instantiate "
<< "module " << mod->mod_name() << " within itself." << endl;
cerr << get_fileline() << ": : The offending instance is "
<< scope_path(sc) << "." << get_name() << " within "
<< scope_path(scn) << "." << endl;
<< get_name() << " within " << scope_path(scn) << "." << endl;
des->errors += 1;
return;
}
@@ -900,8 +1230,12 @@ void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const
*/
void PGModule::elaborate_scope_mod_instances_(Design*des, Module*mod, NetScope*sc) const
{
if (msb_) probe_expr_width(des, sc, msb_);
if (lsb_) probe_expr_width(des, sc, lsb_);
need_constant_expr = true;
NetExpr*mse = msb_ ? elab_and_eval(des, sc, msb_, -1) : 0;
NetExpr*lse = lsb_ ? elab_and_eval(des, sc, lsb_, -1) : 0;
need_constant_expr = false;
NetEConst*msb = dynamic_cast<NetEConst*> (mse);
NetEConst*lsb = dynamic_cast<NetEConst*> (lse);
@@ -960,13 +1294,13 @@ void PGModule::elaborate_scope_mod_instances_(Design*des, Module*mod, NetScope*s
my_scope->set_line(get_file(), mod->get_file(),
get_lineno(), mod->get_lineno());
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);
my_scope->time_from_timescale(mod->time_from_timescale);
des->set_precision(mod->time_precision);
// Look for module parameter replacements. The "replace" map
@@ -1023,9 +1357,9 @@ void PGModule::elaborate_scope_mod_instances_(Design*des, Module*mod, NetScope*s
PExpr*tmp = (*cur).second;
// No expression means that the parameter is not
// replaced at all.
if (tmp == 0)
continue;
if (tmp == 0) continue;
NetExpr*val = tmp->elaborate_pexpr(des, sc);
if (val == 0) continue;
replace_net[(*cur).first] = val;
}
@@ -1057,6 +1391,34 @@ void PGModule::elaborate_scope_mod_instances_(Design*des, Module*mod, NetScope*s
*/
void PEvent::elaborate_scope(Design*des, NetScope*scope) const
{
// A named event can not have the same name as another scope object.
const NetScope *child = scope->child(hname_t(name_));
if (child) {
cerr << get_fileline() << ": error: named event and ";
child->print_type(cerr);
cerr << " in '" << scope->fullname()
<< "' have the same name '" << name_ << "'." << endl;
des->errors += 1;
}
// A named event can not have the same name as a genvar.
if (scope->find_genvar(name_)) {
cerr << get_fileline() << ": error: named event and "
<< "genvar in '" << scope->fullname()
<< "' have the same name '" << name_ << "'." << endl;
des->errors += 1;
}
// A named event can not have the same name as a parameter.
const NetExpr *ex_msb, *ex_lsb;
const NetExpr *parm = scope->get_parameter(name_, ex_msb, ex_lsb);
if (parm) {
cerr << get_fileline() << ": error: named event and "
<< "parameter in '" << scope->fullname()
<< "' have the same name '" << name_ << "'." << endl;
des->errors += 1;
}
NetEvent*ev = new NetEvent(name_);
ev->set_line(*this);
scope->add_event(ev);
@@ -1137,13 +1499,42 @@ void PBlock::elaborate_scope(Design*des, NetScope*scope) const
if (pscope_name() != 0) {
hname_t use_name(pscope_name());
if (scope->child(use_name)) {
cerr << get_fileline() << ": error: block/scope name "
<< use_name << " already used in this context."
<< endl;
// A named block can not have the same name as another scope
// object.
const NetScope *child = scope->child(use_name);
if (child) {
cerr << get_fileline() << ": error: named block and ";
child->print_type(cerr);
cerr << " in '" << scope->fullname()
<< "' have the same name '" << use_name << "'." << endl;
des->errors += 1;
return;
}
// A named block can not have the same name as a genvar.
if (scope->find_genvar(pscope_name())) {
cerr << get_fileline() << ": error: named block and "
"genvar in '" << scope->fullname()
<< "' have the same name '" << use_name << "'." << endl;
des->errors += 1;
}
// A named block can not have the same name as a parameter.
const NetExpr *ex_msb, *ex_lsb;
const NetExpr *parm = scope->get_parameter(pscope_name(), ex_msb,
ex_lsb);
if (parm) {
cerr << get_fileline() << ": error: named block and "
"parameter in '" << scope->fullname()
<< "' have the same name '" << use_name << "'." << endl;
des->errors += 1;
}
if (debug_scopes)
cerr << get_fileline() << ": debug: "
<< "Elaborate block scope " << use_name
<< " within " << scope_path(scope) << endl;
my_scope = new NetScope(scope, use_name, bl_type_==BL_PAR
? NetScope::FORK_JOIN
: NetScope::BEGIN_END);
+135 -131
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2000-2008 Stephen Williams (steve@icarus.com)
* Copyright (c) 2000-2010 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
@@ -35,6 +35,14 @@
# include "util.h"
# include "ivl_assert.h"
/*
* Set the following to true when you need to process an expression
* that is being done in a constant context. This allows the
* elaboration to explicitly say we do not currently support constant
* user functions when the function is not found.
*/
bool need_constant_expr = false;
static bool get_const_argument(NetExpr*exp, verinum&res)
{
switch (exp->expr_type()) {
@@ -118,7 +126,7 @@ static void elaborate_sig_funcs(Design*des, NetScope*scope,
hname_t use_name ( (*cur).first );
NetScope*fscope = scope->child(use_name);
if (scope == 0) {
if (fscope == 0) {
cerr << (*cur).second->get_fileline() << ": internal error: "
<< "Child scope for function " << (*cur).first
<< " missing in " << scope_path(scope) << "." << endl;
@@ -240,68 +248,6 @@ bool Module::elaborate_sig(Design*des, NetScope*scope) const
return flag;
}
bool PExpr::elaborate_sig(Design*des, NetScope*scope) const
{
return true;
}
bool PEConcat::elaborate_sig(Design*des, NetScope*scope) const
{
bool flag = true;
for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1)
flag = parms_[idx]->elaborate_sig(des, scope) && flag;
return flag;
}
bool PEIdent::elaborate_sig(Design*des, NetScope*scope) const
{
NetNet* sig = 0;
const NetExpr*par = 0;
NetEvent* eve = 0;
// If implicit net creation is turned off, then stop now.
if (scope->default_nettype() == NetNet::NONE)
return true;
if (error_implicit)
return true;
symbol_search(this, des, scope, path_, sig, par, eve);
if (eve != 0)
return false;
if (par != 0)
return true;
if (sig == 0)
sig = make_implicit_net_(des, scope);
return sig != 0;
}
bool PEBinary::elaborate_sig(Design*des, NetScope*scope) const
{
bool flag = true;
flag = left_->elaborate_sig(des, scope) && flag;
flag = right_->elaborate_sig(des, scope) && flag;
return flag;
}
bool PETernary::elaborate_sig(Design*des, NetScope*scope) const
{
bool flag = true;
flag = tru_->elaborate_sig(des, scope) && flag;
flag = fal_->elaborate_sig(des, scope) && flag;
return flag;
}
bool PEUnary::elaborate_sig(Design*des, NetScope*scope) const
{
return expr_->elaborate_sig(des, scope);
}
bool PGate::elaborate_sig(Design*des, NetScope*scope) const
{
return true;
@@ -309,33 +255,11 @@ bool PGate::elaborate_sig(Design*des, NetScope*scope) const
bool PGBuiltin::elaborate_sig(Design*des, NetScope*scope) const
{
bool flag = true;
for (unsigned idx = 0 ; idx < pin_count() ; idx += 1) {
const PExpr* pin_expr = pin(idx);
if (pin_expr == 0) {
// If there is no pin expression for this port,
// then skip it. Do not bother generating an error
// message here, that will be done during
// elaboration where these semantic details are tested.
continue;
}
ivl_assert(*this, pin_expr);
flag = pin_expr->elaborate_sig(des, scope) && flag;
}
return flag;
return true;
}
bool PGAssign::elaborate_sig(Design*des, NetScope*scope) const
{
/* Normally, l-values to continuous assignments are NOT allowed
to implicitly declare nets. However, so many tools do allow
it that Icarus Verilog will allow it, at least if extensions
are enabled. */
if (gn_icarus_misc_flag)
return pin(0)->elaborate_sig(des, scope);
return true;
}
@@ -344,25 +268,6 @@ bool PGModule::elaborate_sig_mod_(Design*des, NetScope*scope,
{
bool flag = true;
// First, elaborate the signals that may be created implicitly
// by ports to this module instantiation. Handle the case that
// the ports are passed by name (pins_ != 0) or position.
if (pins_)
for (unsigned idx = 0 ; idx < npins_ ; idx += 1) {
const PExpr*tmp = pins_[idx].parm;
if (tmp == 0)
continue;
flag = tmp->elaborate_sig(des, scope) && flag;
}
else
for (unsigned idx = 0 ; idx < pin_count() ; idx += 1) {
const PExpr*tmp = pin(idx);
if (tmp == 0)
continue;
flag = tmp->elaborate_sig(des, scope) && flag;
}
NetScope::scope_vec_t instance = scope->instance_arrays[get_name()];
for (unsigned idx = 0 ; idx < instance.size() ; idx += 1) {
@@ -390,28 +295,14 @@ bool PGModule::elaborate_sig_mod_(Design*des, NetScope*scope,
bool PGModule::elaborate_sig_udp_(Design*des, NetScope*scope, PUdp*udp) const
{
bool flag = true;
if (pins_)
for (unsigned idx = 0 ; idx < npins_ ; idx += 1) {
const PExpr*tmp = pins_[idx].parm;
if (tmp == 0)
continue;
flag = tmp->elaborate_sig(des, scope) && flag;
}
else
for (unsigned idx = 0 ; idx < pin_count() ; idx += 1) {
const PExpr*tmp = pin(idx);
if (tmp == 0)
continue;
flag = tmp->elaborate_sig(des, scope) && flag;
}
return flag;
return true;
}
bool PGenerate::elaborate_sig(Design*des, NetScope*container) const
{
if (direct_nested_)
return elaborate_sig_direct_(des, container);
bool flag = true;
// Handle the special case that this is a CASE scheme. In this
@@ -428,7 +319,7 @@ bool PGenerate::elaborate_sig(Design*des, NetScope*container) const
for (generate_it_t cur = generate_schemes.begin()
; cur != generate_schemes.end() ; cur ++) {
PGenerate*item = *cur;
if (! item->scope_list_.empty()) {
if (item->direct_nested_ || !item->scope_list_.empty()) {
flag &= item->elaborate_sig(des, container);
}
}
@@ -454,6 +345,32 @@ bool PGenerate::elaborate_sig(Design*des, NetScope*container) const
return flag;
}
bool PGenerate::elaborate_sig_direct_(Design*des, NetScope*container) const
{
if (debug_elaborate)
cerr << get_fileline() << ": debug: "
<< "Direct nesting " << scope_name
<< " (scheme_type=" << scheme_type << ")"
<< " elaborate_sig in scope "
<< scope_path(container) << "." << endl;
// Elaborate_sig for a direct nested generated scheme knows
// that there are only sub_schemes to be elaborated. There
// should be exactly 1 active generate scheme, search for it
// using this loop.
bool flag = true;
typedef list<PGenerate*>::const_iterator generate_it_t;
for (generate_it_t cur = generate_schemes.begin()
; cur != generate_schemes.end() ; cur ++) {
PGenerate*item = *cur;
if (item->direct_nested_ || !item->scope_list_.empty()) {
// Found the item, and it is direct nested.
flag &= item->elaborate_sig(des, container);
}
}
return flag;
}
bool PGenerate::elaborate_sig_(Design*des, NetScope*scope) const
{
// Scan the declared PWires to elaborate the obvious signals
@@ -486,6 +403,13 @@ bool PGenerate::elaborate_sig_(Design*des, NetScope*scope) const
(*cur) ->elaborate_sig(des, scope);
}
typedef list<PProcess*>::const_iterator proc_it_t;
for (proc_it_t cur = behaviors.begin()
; cur != behaviors.end() ; cur ++ ) {
(*cur) -> statement() -> elaborate_sig(des, scope);
}
return true;
}
@@ -523,12 +447,17 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const
case PTF_REG:
case PTF_REG_S:
if (return_type_.range) {
probe_expr_width(des, scope, (*return_type_.range)[0]);
probe_expr_width(des, scope, (*return_type_.range)[1]);
need_constant_expr = true;
NetExpr*me = elab_and_eval(des, scope,
(*return_type_.range)[0], -1);
assert(me);
NetExpr*le = elab_and_eval(des, scope,
(*return_type_.range)[1], -1);
assert(le);
need_constant_expr = false;
long mnum = 0, lnum = 0;
if (NetEConst*tmp = dynamic_cast<NetEConst*>(me)) {
@@ -550,9 +479,11 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const
}
ret_sig = new NetNet(scope, fname, NetNet::REG, mnum, lnum);
ret_sig->set_scalar(false);
} else {
ret_sig = new NetNet(scope, fname, NetNet::REG);
ret_sig->set_scalar(true);
}
ret_sig->set_line(*this);
ret_sig->set_signed(return_type_.type == PTF_REG_S);
@@ -565,6 +496,7 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const
ret_sig->set_line(*this);
ret_sig->set_signed(true);
ret_sig->set_isint(true);
ret_sig->set_scalar(false);
ret_sig->port_type(NetNet::POUTPUT);
ret_sig->data_type(IVL_VT_LOGIC);
break;
@@ -574,6 +506,7 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const
ret_sig->set_line(*this);
ret_sig->set_signed(false);
ret_sig->set_isint(false);
ret_sig->set_scalar(false);
ret_sig->port_type(NetNet::POUTPUT);
ret_sig->data_type(IVL_VT_LOGIC);
break;
@@ -584,6 +517,7 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const
ret_sig->set_line(*this);
ret_sig->set_signed(true);
ret_sig->set_isint(false);
ret_sig->set_scalar(true);
ret_sig->port_type(NetNet::POUTPUT);
ret_sig->data_type(IVL_VT_REAL);
break;
@@ -794,29 +728,73 @@ void PWhile::elaborate_sig(Design*des, NetScope*scope) const
/*
* Elaborate a source wire. The "wire" is the declaration of wires,
* registers, ports and memories. The parser has already merged the
* multiple properties of a wire (i.e., "input wire") so come the
* elaboration this creates an object in the design that represent the
* multiple properties of a wire (i.e., "input wire"), so come the
* elaboration this creates an object in the design that represents the
* defined item.
*/
NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
{
NetNet::Type wtype = type_;
if (wtype == NetNet::IMPLICIT)
bool is_implicit_scalar = false;
if (wtype == NetNet::IMPLICIT) {
wtype = NetNet::WIRE;
if (wtype == NetNet::IMPLICIT_REG)
is_implicit_scalar = true;
}
if (wtype == NetNet::IMPLICIT_REG) {
wtype = NetNet::REG;
is_implicit_scalar = true;
}
unsigned wid = 1;
long lsb = 0, msb = 0;
des->errors += error_cnt_;
// A signal can not have the same name as a scope object.
const NetScope *child = scope->child(hname_t(name_));
if (child) {
cerr << get_fileline() << ": error: signal and ";
child->print_type(cerr);
cerr << " in '" << scope->fullname()
<< "' have the same name '" << name_ << "'." << endl;
des->errors += 1;
}
// A signal can not have the same name as a genvar.
const LineInfo *genvar = scope->find_genvar(name_);
if (genvar) {
cerr << get_fileline() << ": error: signal and genvar in '"
<< scope->fullname() << "' have the same name '" << name_
<< "'." << endl;
des->errors += 1;
}
// A signal can not have the same name as a parameter.
const NetExpr *ex_msb, *ex_lsb;
const NetExpr *parm = scope->get_parameter(name_, ex_msb, ex_lsb);
if (parm) {
cerr << get_fileline() << ": error: signal and parameter in '"
<< scope->fullname() << "' have the same name '" << name_
<< "'." << endl;
des->errors += 1;
}
// A signal can not have the same name as a named event.
const NetEvent *event = scope->find_event(name_);
if (event) {
cerr << get_fileline() << ": error: signal and named event in '"
<< scope->fullname() << "' have the same name '" << name_
<< "'." << endl;
des->errors += 1;
}
if (port_set_ || net_set_) {
long pmsb = 0, plsb = 0, nmsb = 0, nlsb = 0;
bool bad_lsb = false, bad_msb = false;
/* If they exist get the port definition MSB and LSB */
if (port_set_ && port_msb_ != 0) {
probe_expr_width(des, scope, port_msb_);
/* We do not currently support constant user function. */
need_constant_expr = true;
NetExpr*texpr = elab_and_eval(des, scope, port_msb_, -1);
need_constant_expr = false;
if (! eval_as_long(pmsb, texpr)) {
cerr << port_msb_->get_fileline() << ": error: "
@@ -830,7 +808,11 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
delete texpr;
probe_expr_width(des, scope, port_lsb_);
/* We do not currently support constant user function. */
need_constant_expr = true;
texpr = elab_and_eval(des, scope, port_lsb_, -1);
need_constant_expr = false;
if (! eval_as_long(plsb, texpr)) {
cerr << port_lsb_->get_fileline() << ": error: "
@@ -845,6 +827,8 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
delete texpr;
nmsb = pmsb;
nlsb = plsb;
/* An implicit port can have a range so note that here. */
is_implicit_scalar = false;
}
if (!port_set_) assert(port_msb_ == 0 && port_lsb_ == 0);
if (port_msb_ == 0) assert(port_lsb_ == 0);
@@ -852,7 +836,11 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
/* If they exist get the net/etc. definition MSB and LSB */
if (net_set_ && net_msb_ != 0 && !bad_msb && !bad_lsb) {
probe_expr_width(des, scope, net_msb_);
/* We do not currently support constant user function. */
need_constant_expr = true;
NetExpr*texpr = elab_and_eval(des, scope, net_msb_, -1);
need_constant_expr = false;
if (! eval_as_long(nmsb, texpr)) {
cerr << net_msb_->get_fileline() << ": error: "
@@ -866,7 +854,11 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
delete texpr;
probe_expr_width(des, scope, net_lsb_);
/* We do not currently support constant user function. */
need_constant_expr = true;
texpr = elab_and_eval(des, scope, net_lsb_, -1);
need_constant_expr = false;
if (! eval_as_long(nlsb, texpr)) {
cerr << net_lsb_->get_fileline() << ": error: "
@@ -957,8 +949,13 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
if (lidx_ || ridx_) {
assert(lidx_ && ridx_);
probe_expr_width(des, scope, lidx_);
probe_expr_width(des, scope, ridx_);
need_constant_expr = true;
NetExpr*lexp = elab_and_eval(des, scope, lidx_, -1);
NetExpr*rexp = elab_and_eval(des, scope, ridx_, -1);
need_constant_expr = false;
if ((lexp == 0) || (rexp == 0)) {
cerr << get_fileline() << ": internal error: There is "
@@ -1025,8 +1022,11 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
}
if (debug_elaborate) {
cerr << get_fileline() << ": debug: Create signal "
<< wtype << " ["<<msb<<":"<<lsb<<"] " << name_;
cerr << get_fileline() << ": debug: Create signal " << wtype;
if (!get_scalar()) {
cerr << " ["<<msb<<":"<<lsb<<"]";
}
cerr << " " << name_;
if (array_dimensions > 0) {
cerr << " [" << array_s0 << ":" << array_e0 << "]" << endl;
}
@@ -1038,6 +1038,8 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
? new NetNet(scope, name_, wtype, msb, lsb, array_s0, array_e0)
: new NetNet(scope, name_, wtype, msb, lsb);
if (wtype == NetNet::WIRE) sig->devirtualize_pins();
ivl_variable_type_t use_data_type = data_type_;
if (use_data_type == IVL_VT_NO_TYPE) {
use_data_type = IVL_VT_LOGIC;
@@ -1054,6 +1056,8 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
sig->port_type(port_type_);
sig->set_signed(get_signed());
sig->set_isint(get_isint());
if (is_implicit_scalar) sig->set_scalar(true);
else sig->set_scalar(get_scalar());
if (ivl_discipline_t dis = get_discipline()) {
sig->set_discipline(dis);
+291 -119
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998-2008 Stephen Williams (steve@icarus.com)
* Copyright (c) 1998-2010 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
@@ -119,10 +119,10 @@ void PGAssign::elaborate(Design*des, NetScope*scope) const
<< " expression is to small for l-value width "
<< lval->vector_width() << "." << endl;
}
rval_expr = pad_to_width(rval_expr, lval->vector_width());
rval_expr = pad_to_width(rval_expr, lval->vector_width(), *this);
}
NetNet*rval = rval_expr->synthesize(des, scope);
NetNet*rval = rval_expr->synthesize(des, scope, rval_expr);
if (rval == 0) {
cerr << get_fileline() << ": internal error: "
@@ -165,9 +165,10 @@ void PGAssign::elaborate(Design*des, NetScope*scope) const
of the l-value. */
if (lval->vector_width() > rval->vector_width()) {
if (rval->get_signed())
rval = pad_to_width_signed(des, rval, lval->vector_width());
rval = pad_to_width_signed(des, rval, lval->vector_width(),
*this);
else
rval = pad_to_width(des, rval, lval->vector_width());
rval = pad_to_width(des, rval, lval->vector_width(), *this);
}
/* If, on the other hand, the r-value insists on being
@@ -188,6 +189,14 @@ void PGAssign::elaborate(Design*des, NetScope*scope) const
need_driver_flag = false;
}
/* When we are given a non-default strength value and if the
* drive source is a bit, part or indexed select we need to
* add a driver (BUFZ) to convey the strength information. */
if ((drive0 != Link::STRONG || drive1 != Link::STRONG) &&
(dynamic_cast<NetESelect*>(rval_expr))) {
need_driver_flag = true;
}
if (need_driver_flag) {
NetBUFZ*driver = new NetBUFZ(scope, scope->local_symbol(),
rval->vector_width());
@@ -233,8 +242,10 @@ unsigned PGBuiltin::calculate_array_count_(Design*des, NetScope*scope,
gates, then I am expected to make more than one
gate. Figure out how many are desired. */
if (msb_) {
need_constant_expr = true;
NetExpr*msb_exp = elab_and_eval(des, scope, msb_, -1);
NetExpr*lsb_exp = elab_and_eval(des, scope, lsb_, -1);
need_constant_expr = false;
NetEConst*msb_con = dynamic_cast<NetEConst*>(msb_exp);
NetEConst*lsb_con = dynamic_cast<NetEConst*>(lsb_exp);
@@ -284,7 +295,8 @@ unsigned PGBuiltin::calculate_output_count_(void) const
switch (type()) {
case BUF:
case NOT:
output_count = pin_count() - 1;
if (pin_count() > 2) output_count = pin_count() - 1;
else output_count = 1;
break;
case PULLDOWN:
case PULLUP:
@@ -318,8 +330,14 @@ NetNode* PGBuiltin::create_gate_for_output_(Design*des, NetScope*scope,
break;
case BUF:
gate = new NetLogic(scope, gate_name, 2,
NetLogic::BUF, instance_width);
if (pin_count() < 2) {
cerr << get_fileline() << ": error: the BUF "
"primitive must have an input." << endl;
des->errors += 1;
} else {
gate = new NetLogic(scope, gate_name, 2,
NetLogic::BUF, instance_width);
}
break;
case BUFIF0:
@@ -389,8 +407,14 @@ NetNode* PGBuiltin::create_gate_for_output_(Design*des, NetScope*scope,
break;
case NOT:
gate = new NetLogic(scope, gate_name, 2,
NetLogic::NOT, instance_width);
if (pin_count() < 2) {
cerr << get_fileline() << ": error: the NOT "
"primitive must have an input." << endl;
des->errors += 1;
} else {
gate = new NetLogic(scope, gate_name, 2,
NetLogic::NOT, instance_width);
}
break;
case NOTIF0:
@@ -609,7 +633,9 @@ void PGBuiltin::elaborate(Design*des, NetScope*scope) const
return;
}
lval_sigs[idx] = pin(idx)->elaborate_lnet(des, scope);
ivl_assert(*this, lval_sigs[idx]);
// The only way this should return zero is if an error
// happened, so for that case just return.
if (lval_sigs[idx] == 0) return;
// For now, assume all the outputs are the same width.
ivl_assert(*this, idx == 0 || lval_sigs[idx]->vector_width() == lval_sigs[0]->vector_width());
@@ -699,7 +725,7 @@ void PGBuiltin::elaborate(Design*des, NetScope*scope) const
for (unsigned idx = 0 ; idx < pin_count() ; idx += 1) {
const PExpr*ex = pin(idx);
PExpr*ex = pin(idx);
if (ex == 0) {
cerr << get_fileline() << ": error: Logic gate port "
"expressions are not optional." << endl;
@@ -712,9 +738,12 @@ void PGBuiltin::elaborate(Design*des, NetScope*scope) const
} else {
unsigned use_width = array_count * instance_width;
ivl_variable_type_t tmp_type = IVL_VT_NO_TYPE;
bool flag = false;
ex->test_width(des, scope, 0, use_width, tmp_type, flag);
NetExpr*tmp = elab_and_eval(des, scope, ex,
use_width, use_width);
sig = tmp->synthesize(des, scope);
sig = tmp->synthesize(des, scope, tmp);
delete tmp;
}
@@ -861,7 +890,7 @@ NetNet*PGModule::resize_net_to_port_(Design*des, NetScope*scope,
NetNet*tmp = new NetNet(scope, scope->local_symbol(),
NetNet::WIRE, port_wid);
tmp->local_flag(true);
tmp->set_line(*sig);
tmp->set_line(*this);
// Handle the special case of a bi-directional part
// select. Create a NetTran(VP) instead of a uni-directional
@@ -903,9 +932,9 @@ NetNet*PGModule::resize_net_to_port_(Design*des, NetScope*scope,
} else {
NetNet*osig;
if (as_signed) {
osig = pad_to_width_signed(des, tmp, swidth);
osig = pad_to_width_signed(des, tmp, swidth, *this);
} else {
osig = pad_to_width(des, tmp, swidth);
osig = pad_to_width(des, tmp, swidth, *this);
}
connect(osig->pin(0), sig->pin(0));
}
@@ -915,9 +944,9 @@ NetNet*PGModule::resize_net_to_port_(Design*des, NetScope*scope,
if (pwidth > swidth) {
delete tmp;
if (as_signed) {
tmp = pad_to_width_signed(des, sig, pwidth);
tmp = pad_to_width_signed(des, sig, pwidth, *this);
} else {
tmp = pad_to_width(des, sig, pwidth);
tmp = pad_to_width(des, sig, pwidth, *this);
}
} else {
NetPartSelect*node = new NetPartSelect(sig, 0, pwidth,
@@ -949,6 +978,28 @@ static bool need_bufz_for_input_port(const vector<NetNet*>&prts)
return false;
}
/*
* Convert a wire or tri to a tri0 or tri1 as needed to make
* an unconnected drive pull for floating inputs.
*/
static void convert_net(Design*des, const LineInfo *line,
NetNet *net, NetNet::Type type)
{
// If the types already match just return.
if (net->type() == type) return;
// We can only covert a wire or tri to have a default pull.
if (net->type() == NetNet::WIRE || net->type() == NetNet::TRI) {
net->type(type);
return;
}
// We may have to support this at some point in time!
cerr << line->get_fileline() << ": sorry: Can not pull floating "
"input type '" << net->type() << "'." << endl;
des->errors += 1;
}
/*
* Instantiate a module by recursively elaborating it. Set the path of
* the recursive elaboration so that signal names get properly
@@ -1076,28 +1127,50 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
// null parameter is passed in.
if (pins[idx] == 0) {
// We need this information to support the
// unconnected_drive directive and for a
// unconnected input warning when asked for.
vector<PEIdent*> mport = rmod->get_port(idx);
if (mport.size() == 0) continue;
// While we're here, look to see if this
// unconnected (from the outside) port is an
// input. If so, consider printing a port binding
// warning.
if (warn_portbinding) {
vector<PEIdent*> mport = rmod->get_port(idx);
if (mport.size() == 0)
continue;
perm_string pname = peek_tail_name(mport[0]->path());
perm_string pname = peek_tail_name(mport[0]->path());
NetNet*tmp = instance[0]->find_signal(pname);
assert(tmp);
NetNet*tmp = instance[0]->find_signal(pname);
assert(tmp);
if (tmp->port_type() == NetNet::PINPUT) {
// If we have an unconnected input convert it
// as needed if an unconnected_drive directive
// was given. This only works for tri or wire!
switch (rmod->uc_drive) {
case Module::UCD_PULL0:
convert_net(des, this, tmp, NetNet::TRI0);
break;
case Module::UCD_PULL1:
convert_net(des, this, tmp, NetNet::TRI1);
break;
case Module::UCD_NONE:
break;
}
if (tmp->port_type() == NetNet::PINPUT) {
// Print a waring for an unconnected input.
if (warn_portbinding) {
cerr << get_fileline() << ": warning: "
<< "Instantiating module "
<< rmod->mod_name()
<< " with dangling input port "
<< rmod->ports[idx]->name
<< "." << endl;
<< " with dangling input port '"
<< rmod->ports[idx]->name;
switch (rmod->uc_drive) {
case Module::UCD_PULL0:
cerr << "' (pulled low)." << endl;
break;
case Module::UCD_PULL1:
cerr << "' (pulled high)." << endl;
break;
case Module::UCD_NONE:
cerr << "' (floating)." << endl;
break;
}
}
}
@@ -1170,10 +1243,14 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
width. We use that, then, to decide how to hook
it up.
v NOTE that this also handles the case that the
NOTE that this also handles the case that the
port is actually empty on the inside. We assume
in that case that the port is input. */
ivl_variable_type_t tmp_type = IVL_VT_NO_TYPE;
bool flag = false;
pins[idx]->test_width(des, scope, 0, desired_vector_width,
tmp_type, flag);
NetExpr*tmp_expr = elab_and_eval(des, scope, pins[idx],
desired_vector_width,
desired_vector_width);
@@ -1183,7 +1260,7 @@ v NOTE that this also handles the case that the
<< "too complicated for elaboration." << endl;
continue;
}
sig = tmp_expr->synthesize(des, scope);
sig = tmp_expr->synthesize(des, scope, tmp_expr);
if (sig == 0) {
cerr << pins[idx]->get_fileline()
<< ": internal error: Port expression "
@@ -1192,7 +1269,7 @@ v NOTE that this also handles the case that the
}
delete tmp_expr;
sig->set_line(*this);
if (!sig->get_lineno()) sig->set_line(*this);
if (need_bufz_for_input_port(prts)) {
NetBUFZ*tmp = new NetBUFZ(scope, scope->local_symbol(),
@@ -1494,43 +1571,34 @@ void PGModule::elaborate_udp_(Design*des, PUdp*udp, NetScope*scope) const
module or primitive, it interprets them as parameter
overrides. Correct that misconception here. */
if (overrides_) {
PDelays tmp_del;
tmp_del.set_delays(overrides_, false);
tmp_del.eval_delays(des, scope, rise_expr, fall_expr, decay_expr);
if (dynamic_cast<NetEConst*> (rise_expr)) {
} else {
cerr << get_fileline() << ": error: Delay expressions must be "
<< "constant for primitives." << endl;
cerr << get_fileline() << ": : Cannot calculate "
<< *rise_expr << endl;
if (overrides_->count() > 2) {
cerr << get_fileline() << ": error: UDPs take at most two "
"delay arguments." << endl;
des->errors += 1;
}
if (dynamic_cast<NetEConst*> (fall_expr)) {
} else {
cerr << get_fileline() << ": error: Delay expressions must be "
<< "constant for primitives." << endl;
cerr << get_fileline() << ": : Cannot calculate "
<< *rise_expr << endl;
des->errors += 1;
PDelays tmp_del;
tmp_del.set_delays(overrides_, false);
tmp_del.eval_delays(des, scope, rise_expr, fall_expr,
decay_expr);
if (! dynamic_cast<NetEConst*> (rise_expr)) {
cerr << get_fileline() << ": error: UDP rising delay "
"expression must be constant." << endl;
cerr << get_fileline() << ": : Cannot calculate "
<< *rise_expr << endl;
des->errors += 1;
}
if (! dynamic_cast<NetEConst*> (fall_expr)) {
cerr << get_fileline() << ": error: UDP falling delay "
"expression must be constant." << endl;
cerr << get_fileline() << ": : Cannot calculate "
<< *fall_expr << endl;
des->errors += 1;
}
}
if (dynamic_cast<NetEConst*> (decay_expr)) {
} else {
cerr << get_fileline() << ": error: Delay expressions must be "
<< "constant for primitives." << endl;
cerr << get_fileline() << ": : Cannot calculate "
<< *rise_expr << endl;
des->errors += 1;
}
}
assert(udp);
NetUDP*net = new NetUDP(scope, my_name, udp->ports.count(), udp);
net->rise_time(rise_expr);
@@ -1653,7 +1721,7 @@ void PGModule::elaborate_udp_(Design*des, PUdp*udp, NetScope*scope) const
"for elaboration:" << pins[idx] << endl;
continue;
}
NetNet*sig = expr_tmp->synthesize(des, scope);
NetNet*sig = expr_tmp->synthesize(des, scope, expr_tmp);
ivl_assert(*this, sig);
sig->set_line(*this);
@@ -1766,7 +1834,9 @@ NetExpr* PAssign_::elaborate_rval_(Design*des, NetScope*scope,
{
ivl_assert(*this, rval_);
need_constant_expr = is_constant_;
NetExpr*rv = elaborate_rval_expr(des, scope, lv_type, lv_width, rval());
need_constant_expr = false;
if (!is_constant_ || !rv) return rv;
@@ -1789,8 +1859,23 @@ NetExpr* PAssign_::elaborate_rval_(Design*des, NetScope*scope,
*/
static NetExpr*elaborate_delay_expr(PExpr*expr, Design*des, NetScope*scope)
{
probe_expr_width(des, scope, expr);
NetExpr*dex = elab_and_eval(des, scope, expr, -1);
/* Print a warning if we find default and `timescale based
* delays in the design, since this is likely an error. */
if (scope->time_from_timescale()) dly_used_timescale = true;
else dly_used_no_timescale = true;
if (display_ts_dly_warning &&
dly_used_no_timescale && dly_used_timescale) {
cerr << "warning: Found both default and "
"`timescale based delays. Use" << endl;
cerr << " -Wtimescale to find the "
"module(s) with no `timescale." << endl;
display_ts_dly_warning = false;
}
/* If the delay expression is a real constant or vector
constant, then evaluate it, scale it to the local time
units, and return an adjusted NetEConst. */
@@ -1830,6 +1915,7 @@ static NetExpr*elaborate_delay_expr(PExpr*expr, Design*des, NetScope*scope)
shift -= 1;
}
ivl_assert(*expr, dex);
NetExpr*scal_val = new NetEConst(verinum(scale));
dex = new NetEBMult('*', dex, scal_val);
}
@@ -1841,6 +1927,7 @@ static NetExpr*elaborate_delay_expr(PExpr*expr, Design*des, NetScope*scope)
shift += 1;
}
ivl_assert(*expr, dex);
NetExpr*scal_val = new NetEConst(verinum(scale));
dex = new NetEBDiv('/', dex, scal_val);
}
@@ -1890,7 +1977,7 @@ NetProc* PAssign::elaborate(Design*des, NetScope*scope) const
unsigned wid = count_lval_width(lv);
rv->set_width(wid);
rv = pad_to_width(rv, wid);
rv = pad_to_width(rv, wid, *this);
if (wid > rv->expr_width()) {
cerr << get_fileline() << ": error: Unable to match "
@@ -1999,7 +2086,7 @@ NetProc* PAssign::elaborate(Design*des, NetScope*scope) const
unsigned wid = count_lval_width(lv);
if (wid > rv->expr_width()) {
rv->set_width(wid);
rv = pad_to_width(rv, wid);
rv = pad_to_width(rv, wid, *this);
}
ivl_assert(*this, rv->expr_width() >= wid);
}
@@ -2053,7 +2140,7 @@ NetProc* PAssignNB::elaborate(Design*des, NetScope*scope) const
} else {
unsigned wid = count_lval_width(lv);
rv->set_width(wid);
rv = pad_to_width(rv, wid);
rv = pad_to_width(rv, wid, *this);
}
NetExpr*delay = 0;
@@ -2206,6 +2293,7 @@ NetProc* PCase::elaborate(Design*des, NetScope*scope) const
{
assert(scope);
probe_expr_width(des, scope, expr_);
NetExpr*expr = elab_and_eval(des, scope, expr_, -1);
if (expr == 0) {
cerr << get_fileline() << ": error: Unable to elaborate this case"
@@ -2258,6 +2346,7 @@ NetProc* PCase::elaborate(Design*des, NetScope*scope) const
NetExpr*gu = 0;
NetProc*st = 0;
assert(cur->expr[e]);
probe_expr_width(des, scope, cur->expr[e]);
gu = elab_and_eval(des, scope, cur->expr[e], -1);
if (cur->stat)
@@ -2279,17 +2368,8 @@ NetProc* PCondit::elaborate(Design*des, NetScope*scope) const
cerr << get_fileline() << ": debug: Elaborate condition statement"
<< " with conditional: " << *expr_ << endl;
// Run a test-width on the condition so that its types are
// worked out for elaboration later on.
ivl_variable_type_t rtype = IVL_VT_NO_TYPE;
bool rflag = false;
unsigned expr_wid = expr_->test_width(des, scope, 0, 0, rtype, rflag);
if (debug_elaborate)
cerr << get_fileline() << ": debug: Test width of condition expression"
<< " returns wid=" << expr_wid << ", type=" << rtype
<< ", flag=" << rflag << endl;
// Elaborate and try to evaluate the conditional expression.
probe_expr_width(des, scope, expr_);
NetExpr*expr = elab_and_eval(des, scope, expr_, -1);
if (expr == 0) {
cerr << get_fileline() << ": error: Unable to elaborate"
@@ -2389,6 +2469,12 @@ NetProc* PCallTask::elaborate_sys(Design*des, NetScope*scope) const
{
assert(scope);
if (path_.size() > 1) {
cerr << get_fileline() << ": error: Hierarchical system task names"
<< " make no sense: " << path_ << endl;
des->errors += 1;
}
unsigned parm_count = nparms();
/* Catch the special case that the system task has no
@@ -2427,6 +2513,20 @@ NetProc* PCallTask::elaborate_sys(Design*des, NetScope*scope) const
}
}
// Special case: Specify blocks are turned off, and this is an
// $sdf_annotate system task. There will be nothing for $sdf
// to annotate, and the user is intending to turn the behavior
// off anyhow, so replace the system task invocation with a no-op.
if (gn_specify_blocks_flag == false
&& peek_tail_name(path_) == "$sdf_annotate") {
cerr << get_fileline() << ": warning: Omitting $sdf_annotate() "
<< "since specify blocks are being omitted." << endl;
NetBlock*noop = new NetBlock(NetBlock::SEQU, scope);
noop->set_line(*this);
return noop;
}
NetSTask*cur = new NetSTask(peek_tail_name(path_), eparms);
cur->set_line(*this);
return cur;
@@ -2543,10 +2643,22 @@ NetProc* PCallTask::elaborate_usr(Design*des, NetScope*scope) const
NetAssign_*lv = new NetAssign_(port);
unsigned wid = count_lval_width(lv);
ivl_variable_type_t lv_type = lv->expr_type();
NetExpr*rv = elaborate_rval_expr(des, scope, lv_type, wid, parms_[idx]);
if (NetEEvent*evt = dynamic_cast<NetEEvent*> (rv)) {
cerr << evt->get_fileline() << ": error: An event '"
<< evt->event()->name() << "' can not be a user "
"task argument." << endl;
des->errors += 1;
continue;
}
if (wid > rv->expr_width()) {
rv->set_width(wid);
rv = pad_to_width(rv, wid, *this);
}
ivl_assert(*this, rv->expr_width() >= wid);
NetExpr*rv = elab_and_eval(des, scope, parms_[idx], wid);
rv->set_width(wid);
rv = pad_to_width(rv, wid);
NetAssign*pr = new NetAssign(lv, rv);
block->append(pr);
}
@@ -2599,7 +2711,7 @@ NetProc* PCallTask::elaborate_usr(Design*des, NetScope*scope) const
continue;
NetESignal*sig = new NetESignal(port);
NetExpr*rv = pad_to_width(sig, count_lval_width(lv));
NetExpr*rv = pad_to_width(sig, count_lval_width(lv), *this);
/* Generate the assignment statement. */
NetAssign*ass = new NetAssign(lv, rv);
@@ -2649,13 +2761,14 @@ NetCAssign* PCAssign::elaborate(Design*des, NetScope*scope) const
return 0;
unsigned lwid = count_lval_width(lval);
ivl_variable_type_t ltype = lval->expr_type();
NetExpr*rexp = elab_and_eval(des, scope, expr_, lwid);
NetExpr*rexp = elaborate_rval_expr(des, scope, ltype, lwid, expr_);
if (rexp == 0)
return 0;
rexp->set_width(lwid);
rexp = pad_to_width(rexp, lwid);
rexp = pad_to_width(rexp, lwid, *this);
dev = new NetCAssign(lval, rexp);
@@ -2720,7 +2833,7 @@ NetProc* PDelayStatement::elaborate(Design*des, NetScope*scope) const
return new NetPDelay(tmp->value().as_ulong64(),
statement_->elaborate(des, scope));
else
return new NetPDelay(tmp->value().as_ulong(), 0);
return new NetPDelay(tmp->value().as_ulong64(), 0);
delete dex;
@@ -2951,31 +3064,27 @@ NetProc* PEventStatement::elaborate_st(Design*des, NetScope*scope,
}
}
bool save_flag = error_implicit;
error_implicit = true;
probe_expr_width(des, scope, expr_[idx]->expr());
NetExpr*tmp = elab_and_eval(des, scope, expr_[idx]->expr(), 0);
if (tmp == 0) {
expr_[idx]->dump(cerr);
cerr << endl;
des->errors += 1;
error_implicit = save_flag;
continue;
}
NetNet*expr = tmp->synthesize(des, scope);
NetNet*expr = tmp->synthesize(des, scope, tmp);
expr->set_line(*this);
if (expr == 0) {
expr_[idx]->dump(cerr);
cerr << endl;
des->errors += 1;
error_implicit = save_flag;
continue;
}
assert(expr);
delete tmp;
error_implicit = save_flag;
unsigned pins = (expr_[idx]->type() == PEEvent::ANYEDGE)
? expr->pin_count() : 1;
@@ -2997,6 +3106,7 @@ NetProc* PEventStatement::elaborate_st(Design*des, NetScope*scope,
break;
default:
pr = NULL;
assert(0);
}
@@ -3053,10 +3163,12 @@ NetProc* PEventStatement::elaborate_wait(Design*des, NetScope*scope,
return 0;
}
const PExpr *pe = expr_[0]->expr();
PExpr *pe = expr_[0]->expr();
/* Elaborate wait expression. Don't eval yet, we will do that
shortly, after we apply a reduction or. */
probe_expr_width(des, scope, pe);
NetExpr*expr = pe->elaborate_expr(des, scope, -1, false);
if (expr == 0) {
cerr << get_fileline() << ": error: Unable to elaborate"
@@ -3247,13 +3359,14 @@ NetForce* PForce::elaborate(Design*des, NetScope*scope) const
return 0;
unsigned lwid = count_lval_width(lval);
ivl_variable_type_t ltype = lval->expr_type();
NetExpr*rexp = elab_and_eval(des, scope, expr_, lwid);
NetExpr*rexp = elaborate_rval_expr(des, scope, ltype, lwid, expr_);
if (rexp == 0)
return 0;
rexp->set_width(lwid, true);
rexp = pad_to_width(rexp, lwid);
rexp = pad_to_width(rexp, lwid, *this);
dev = new NetForce(lval, rexp);
@@ -3318,7 +3431,7 @@ NetProc* PForStatement::elaborate(Design*des, NetScope*scope) const
properly. Then use it to build the assignment statement. */
etmp = elab_and_eval(des, scope, expr1_, use_width);
etmp->set_width(use_width);
etmp = pad_to_width(etmp, use_width);
etmp = pad_to_width(etmp, use_width, *this);
if (debug_elaborate) {
cerr << get_fileline() << ": debug: FOR initial assign: "
@@ -3331,7 +3444,7 @@ NetProc* PForStatement::elaborate(Design*des, NetScope*scope) const
if (etmp->expr_type() != IVL_VT_REAL) {
unsigned wid = count_lval_width(lv);
etmp->set_width(wid);
etmp = pad_to_width(etmp, wid);
etmp = pad_to_width(etmp, wid, *this);
assert(etmp->expr_width() >= wid);
}
@@ -3378,6 +3491,7 @@ 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. */
probe_expr_width(des, scope, cond_);
NetExpr*ce = elab_and_eval(des, scope, cond_, -1);
if (ce == 0) {
delete top;
@@ -3590,8 +3704,9 @@ NetProc* PTrigger::elaborate(Design*des, NetScope*scope) const
*/
NetProc* PWhile::elaborate(Design*des, NetScope*scope) const
{
NetWhile*loop = new NetWhile(elab_and_eval(des, scope, cond_, -1),
statement_->elaborate(des, scope));
probe_expr_width(des, scope, cond_);
NetExpr*tmp = elab_and_eval(des, scope, cond_, -1);
NetWhile*loop = new NetWhile(tmp, statement_->elaborate(des, scope));
return loop;
}
@@ -3667,21 +3782,33 @@ void PSpecPath::elaborate(Design*des, NetScope*scope) const
/* Do not elaborate specify delay paths if this feature is
turned off. */
if (!gn_specify_blocks_flag)
return;
if (!gn_specify_blocks_flag) return;
ivl_assert(*this, conditional || (condition==0));
ndelays = delays.size();
if (ndelays > 12)
ndelays = 12;
if (ndelays > 12) ndelays = 12;
/* Print a warning if we find default and `timescale based
* delays in the design, since this is likely an error. */
if (scope->time_from_timescale()) dly_used_timescale = true;
else dly_used_no_timescale = true;
if (display_ts_dly_warning &&
dly_used_no_timescale && dly_used_timescale) {
cerr << "warning: Found both default and "
"`timescale based delays. Use" << endl;
cerr << " -Wtimescale to find the "
"module(s) with no `timescale." << endl;
display_ts_dly_warning = false;
}
int shift = scope->time_unit() - des->get_precision();
/* Elaborate the delay values themselves. Remember to scale
them for the timescale/precision of the scope. */
for (unsigned idx = 0 ; idx < ndelays ; idx += 1) {
PExpr*exp = delays[idx];
probe_expr_width(des, scope, exp);
NetExpr*cur = elab_and_eval(des, scope, exp, 0);
if (NetEConst*cur_con = dynamic_cast<NetEConst*> (cur)) {
@@ -3719,13 +3846,14 @@ void PSpecPath::elaborate(Design*des, NetScope*scope) const
NetNet*condit_sig = 0;
if (conditional && condition) {
probe_expr_width(des, scope, condition);
NetExpr*tmp = elab_and_eval(des, scope, condition, -1);
ivl_assert(*condition, tmp);
// FIXME: Look for constant expressions here?
// Get a net form.
condit_sig = tmp->synthesize(des, scope);
condit_sig = tmp->synthesize(des, scope, tmp);
ivl_assert(*condition, condit_sig);
}
@@ -3868,7 +3996,6 @@ static void elaborate_tasks(Design*des, NetScope*scope,
bool Module::elaborate(Design*des, NetScope*scope) const
{
bool result_flag = true;
error_implicit = true;
if (gn_specify_blocks_flag) {
// Elaborate specparams
@@ -3876,7 +4003,9 @@ bool Module::elaborate(Design*des, NetScope*scope) const
for (specparam_it_t cur = specparams.begin()
; cur != specparams.end() ; cur ++ ) {
need_constant_expr = true;
NetExpr*val = elab_and_eval(des, scope, (*cur).second, -1);
need_constant_expr = false;
NetScope::spec_val_t value;
if (NetECReal*val_cr = dynamic_cast<NetECReal*> (val)) {
@@ -3933,7 +4062,6 @@ bool Module::elaborate(Design*des, NetScope*scope) const
// complex.
const list<PGate*>&gl = get_gates();
error_implicit = false;
for (list<PGate*>::const_iterator gt = gl.begin()
; gt != gl.end()
; gt ++ ) {
@@ -3941,8 +4069,6 @@ bool Module::elaborate(Design*des, NetScope*scope) const
(*gt)->elaborate(des, scope);
}
error_implicit = true;
// Elaborate the behaviors, making processes out of them. This
// involves scanning the PProcess* list, creating a NetProcTop
// for each process.
@@ -3961,6 +4087,9 @@ bool Module::elaborate(Design*des, NetScope*scope) const
bool PGenerate::elaborate(Design*des, NetScope*container) const
{
if (direct_nested_)
return elaborate_direct_(des, container);
bool flag = true;
// Handle the special case that this is a CASE scheme. In this
@@ -3977,7 +4106,7 @@ bool PGenerate::elaborate(Design*des, NetScope*container) const
for (generate_it_t cur = generate_schemes.begin()
; cur != generate_schemes.end() ; cur ++) {
PGenerate*item = *cur;
if (! item->scope_list_.empty()) {
if (item->direct_nested_ || !item->scope_list_.empty()) {
flag &= item->elaborate(des, container);
}
}
@@ -4015,6 +4144,30 @@ bool PGenerate::elaborate(Design*des, NetScope*container) const
return flag;
}
bool PGenerate::elaborate_direct_(Design*des, NetScope*container) const
{
if (debug_elaborate)
cerr << get_fileline() << ": debug: "
<< "Direct nesting elaborate in scope "
<< scope_path(container) << "." << endl;
// Elaborate for a direct nested generated scheme knows
// that there are only sub_schemes to be elaborated. There
// should be exactly 1 active generate scheme, search for it
// using this loop.
bool flag = true;
typedef list<PGenerate*>::const_iterator generate_it_t;
for (generate_it_t cur = generate_schemes.begin()
; cur != generate_schemes.end() ; cur ++) {
PGenerate*item = *cur;
if (item->direct_nested_ || !item->scope_list_.empty()) {
// Found the item, and it is direct nested.
flag &= item->elaborate(des, container);
}
}
return flag;
}
bool PGenerate::elaborate_(Design*des, NetScope*scope) const
{
elaborate_functions(des, scope, funcs);
@@ -4074,8 +4227,23 @@ class elaborate_root_scope_t : public elaborator_work_item_t {
virtual void elaborate_runrun()
{
Module::replace_t stub;
if (! rmod_->elaborate_scope(des, scope_, stub))
Module::replace_t root_repl;
for (list<Module::named_expr_t>::iterator cur = Module::user_defparms.begin()
; cur != Module::user_defparms.end() ; cur++) {
pform_name_t tmp_name = cur->first;
if (peek_head_name(tmp_name) != scope_->basename())
continue;
tmp_name.pop_front();
if (tmp_name.size() != 1)
continue;
NetExpr*tmp_expr = cur->second->elaborate_pexpr(des, scope_);
root_repl[peek_head_name(tmp_name)] = tmp_expr;
}
if (! rmod_->elaborate_scope(des, scope_, root_repl))
des->errors += 1;
}
@@ -4209,7 +4377,7 @@ Design* elaborate(list<perm_string>roots)
scope->set_line(rmod);
scope->time_unit(rmod->time_unit);
scope->time_precision(rmod->time_precision);
scope->default_nettype(rmod->default_nettype);
scope->time_from_timescale(rmod->time_from_timescale);
des->set_precision(rmod->time_precision);
@@ -4228,14 +4396,17 @@ Design* elaborate(list<perm_string>roots)
des->elaboration_work_list.push_back(es);
}
// After the work items for the root scope elaboration, push a
// work item to process the defparams.
des->elaboration_work_list.push_back(new top_defparams(des));
// Run the work list of scope elaborations until the list is
// empty. This list is initially populated above where the
// initial root scopes are primed.
while (! des->elaboration_work_list.empty()) {
// Push a work item to process the defparams of any scopes
// that are elaborated during this pass. For the first pass
// this will be all the root scopes. For subsequent passes
// it will be any scopes created during the previous pass
// by a generate construct or instance array.
des->elaboration_work_list.push_back(new top_defparams(des));
// Transfer the queue to a temporary queue.
list<elaborator_work_item_t*> cur_queue;
while (! des->elaboration_work_list.empty()) {
@@ -4289,6 +4460,7 @@ Design* elaborate(list<perm_string>roots)
NetScope *scope = root_elems[i]->scope;
rc &= rmod->elaborate(des, scope);
delete root_elems[i];
}
if (rc == false) {
+14 -4
View File
@@ -28,21 +28,31 @@
NetProc* AContrib::elaborate(Design*des, NetScope*scope) const
{
probe_expr_width(des, scope, lval_);
probe_expr_width(des, scope, rval_);
NetExpr*lval = elab_and_eval(des, scope, lval_, -1);
NetExpr*rval = elab_and_eval(des, scope, rval_, -1);
NetContribution*st = new NetContribution(lval, rval);
NetEAccess*lacc = dynamic_cast<NetEAccess*> (lval);
if (lacc == 0) {
cerr << get_fileline() << ": error: The l-value of a contribution"
<< " statement must be a branch probe access function." << endl;
des->errors += 1;
return 0;
}
NetContribution*st = new NetContribution(lacc, rval);
st->set_line(*this);
return st;
}
bool AProcess::elaborate(Design*des, NetScope*scope) const
{
NetProc*statement = statement_->elaborate(des, scope);
if (statement == 0)
NetProc*estatement = statement_->elaborate(des, scope);
if (estatement == 0)
return false;
NetAnalogTop*top = new NetAnalogTop(scope, type_, statement);
NetAnalogTop*top = new NetAnalogTop(scope, type_, estatement);
// Evaluate the attributes for this process, if there
// are any. These attributes are to be attached to the
+22 -9
View File
@@ -192,9 +192,7 @@ bool NetProcTop::emit(struct target_t*tgt) const
bool NetAnalogTop::emit(struct target_t*tgt) const
{
cerr << get_fileline() << ": sorry: "
<< "I don't know how to emit for analog processes." << endl;
return false;
return tgt->process(this);
}
bool NetProc::emit_proc(struct target_t*tgt) const
@@ -241,6 +239,11 @@ bool NetCondit::emit_proc(struct target_t*tgt) const
return tgt->proc_condit(this);
}
bool NetContribution::emit_proc(struct target_t*tgt) const
{
return tgt->proc_contribution(this);
}
bool NetDeassign::emit_proc(struct target_t*tgt) const
{
return tgt->proc_deassign(this);
@@ -377,8 +380,9 @@ void NetScope::emit_scope(struct target_t*tgt) const
for (NetEvent*cur = events_ ; cur ; cur = cur->snext_)
tgt->event(cur);
for (NetScope*cur = sub_ ; cur ; cur = cur->sib_)
cur->emit_scope(tgt);
for (map<hname_t,NetScope*>::const_iterator cur = children_.begin()
; cur != children_.end() ; cur ++)
cur->second->emit_scope(tgt);
for (signals_map_iter_t cur = signals_map_.begin()
; cur != signals_map_.end() ; cur ++) {
@@ -404,8 +408,9 @@ bool NetScope::emit_defs(struct target_t*tgt) const
switch (type_) {
case MODULE:
for (NetScope*cur = sub_ ; cur ; cur = cur->sib_)
flag &= cur->emit_defs(tgt);
for (map<hname_t,NetScope*>::const_iterator cur = children_.begin()
; cur != children_.end() ; cur ++)
flag &= cur->second->emit_defs(tgt);
break;
case FUNC:
@@ -415,8 +420,9 @@ bool NetScope::emit_defs(struct target_t*tgt) const
tgt->task_def(this);
break;
default: /* BEGIN_END and FORK_JOIN, GENERATE... */
for (NetScope*cur = sub_ ; cur ; cur = cur->sib_)
flag &= cur->emit_defs(tgt);
for (map<hname_t,NetScope*>::const_iterator cur = children_.begin()
; cur != children_.end() ; cur ++)
flag &= cur->second->emit_defs(tgt);
break;
}
@@ -452,6 +458,11 @@ int Design::emit(struct target_t*tgt) const
}
bool branches_rc = true;
for (NetBranch*cur = branches_ ; cur ; cur = cur->next_) {
branches_rc = tgt->branch(cur) && branches_rc;
}
// emit task and function definitions
bool tasks_rc = true;
for (list<NetScope*>::const_iterator scope = root_scopes_.begin();
@@ -474,6 +485,8 @@ int Design::emit(struct target_t*tgt) const
return -2;
if (proc_rc == false)
return -3;
if (branches_rc == false)
return -4;
return rc;
}
-38
View File
@@ -16,9 +16,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: eval_attrib.cc,v 1.9 2007/06/04 19:14:06 steve Exp $"
#endif
# include "config.h"
# include "util.h"
@@ -76,38 +73,3 @@ attrib_list_t* evaluate_attributes(const map<perm_string,PExpr*>&att,
return table;
}
/*
* $Log: eval_attrib.cc,v $
* Revision 1.9 2007/06/04 19:14:06 steve
* Build errors in picky GCC compilers.
*
* Revision 1.8 2005/11/27 17:01:57 steve
* Fix for stubborn compiler.
*
* 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.
*
* Revision 1.5 2002/08/12 01:34:59 steve
* conditional ident string using autoconfig.
*
* Revision 1.4 2002/08/10 21:59:39 steve
* The default attribute value is 1.
*
* Revision 1.3 2002/06/06 18:57:18 steve
* Use standard name for iostream.
*
* Revision 1.2 2002/06/03 03:55:14 steve
* compile warnings.
*
* Revision 1.1 2002/05/23 03:08:51 steve
* Add language support for Verilog-2001 attribute
* syntax. Hook this support into existing $attribute
* handling, and add number and void value types.
*
* Add to the ivl_target API new functions for access
* of complex attributes attached to gates.
*
*/
+102 -89
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1999-2008 Stephen Williams (steve@icarus.com)
* Copyright (c) 1999-2009 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
@@ -129,7 +129,14 @@ NetExpr* NetEBAdd::eval_tree(int prune_to_width)
lc = se? dynamic_cast<NetEConst*>(se->right_) : 0;
if (lc != 0 && rc != 0) {
assert(se != 0);
ivl_assert(*this, se != 0);
if (debug_eval_tree) {
cerr << get_fileline() << ": debug: "
<< "Partially evaluate " << *this
<< " using (a+2)-1 --> (a+1) transform." << endl;
}
verinum lval = lc->value();
verinum rval = rc->value();
@@ -374,6 +381,7 @@ NetEConst* NetEBComp::eval_leeq_real_(NetExpr*le, NetExpr*ri, bool eq_flag)
break;
default:
lv = 0.0;
cerr << get_fileline() << ": internal error: "
<< "Unexpected expression type? " << le->expr_type() << endl;
assert(0);
@@ -394,6 +402,7 @@ NetEConst* NetEBComp::eval_leeq_real_(NetExpr*le, NetExpr*ri, bool eq_flag)
break;
default:
rv = 0.0;
cerr << get_fileline() << ": internal error: "
<< "Unexpected expression type? " << ri->expr_type() << endl;
assert(0);
@@ -578,6 +587,7 @@ NetEConst* NetEBComp::eval_eqeq_real_(NetExpr*le, NetExpr*ri, bool ne_flag)
break;
default:
lv = 0.0;
cerr << get_fileline() << ": internal error: "
<< "Unexpected expression type? " << le->expr_type() << endl;
assert(0);
@@ -598,6 +608,7 @@ NetEConst* NetEBComp::eval_eqeq_real_(NetExpr*le, NetExpr*ri, bool ne_flag)
break;
default:
rv = 0.0;
cerr << get_fileline() << ": internal error: "
<< "Unexpected expression type? " << ri->expr_type() << endl;
assert(0);
@@ -811,6 +822,32 @@ NetEConst* NetEBComp::eval_tree(int prune_to_width)
}
}
NetExpr* NetEBDiv::eval_tree_real_()
{
verireal lval;
verireal rval;
bool flag = get_real_arguments_(lval, rval);
if (! flag) return 0;
NetECReal*res = 0;
switch (op_) {
case '/':
res = new NetECReal(lval / rval);
break;
case '%':
// Since this could/may be called early we don't want to
// leak functionality.
if (!gn_icarus_misc_flag) return 0;
res = new NetECReal(lval % rval);
break;
}
ivl_assert(*this, res);
res->set_line(*this);
return res;
}
/*
* The NetEBDiv operator includes the / and % operators. First evaluate
* the sub-expressions, then perform the required operation.
@@ -820,77 +857,31 @@ NetExpr* NetEBDiv::eval_tree(int prune_to_width)
eval_expr(left_);
eval_expr(right_);
if (expr_type() == IVL_VT_REAL) {
NetECReal*lc = dynamic_cast<NetECReal*>(left_);
if (lc == 0) return 0;
if (expr_type() == IVL_VT_REAL) return eval_tree_real_();
assert(expr_type() == IVL_VT_LOGIC);
verireal lval = lc->value();
NetEConst*lc = dynamic_cast<NetEConst*>(left_);
NetEConst*rc = dynamic_cast<NetEConst*>(right_);
if (lc == 0 || rc == 0) return 0;
if (NetECReal*rcr = dynamic_cast<NetECReal*>(right_)) {
NetECReal*tmp = 0;
verireal rval = rcr->value();
// Make sure the expression is evaluated at the
// expression width.
verinum lval = pad_to_width(lc->value(), expr_width());
verinum rval = pad_to_width(rc->value(), expr_width());
switch (op_) {
case '/':
tmp = new NetECReal(lval / rval);
break;
case '%':
tmp = new NetECReal(lval % rval);
}
assert(tmp);
tmp->set_line(*this);
return tmp;
} else if (NetEConst*rc = dynamic_cast<NetEConst*>(right_)) {
NetECReal*tmp = 0;
verinum rval = rc->value();
switch (op_) {
case '/':
tmp = new NetECReal(lval / rval);
break;
case '%':
tmp = new NetECReal(lval % rval);
}
assert(tmp);
tmp->set_line(*this);
return tmp;
}
} else {
assert(expr_type() == IVL_VT_LOGIC);
NetEConst*lc = dynamic_cast<NetEConst*>(left_);
if (lc == 0) return 0;
NetEConst*rc = dynamic_cast<NetEConst*>(right_);
if (rc == 0) return 0;
// Make sure the expression is evaluated at the
// expression width.
verinum lval = pad_to_width(lc->value(), expr_width());
verinum rval = pad_to_width(rc->value(), expr_width());
NetExpr*tmp = 0;
switch (op_) {
case '/':
tmp = new NetEConst(lval / rval);
break;
case '%':
tmp = new NetEConst(lval % rval);
break;
}
ivl_assert(*this, tmp);
tmp->set_line(*this);
return tmp;
NetExpr*tmp = 0;
switch (op_) {
case '/':
tmp = new NetEConst(lval / rval);
break;
case '%':
tmp = new NetEConst(lval % rval);
break;
}
return 0;
ivl_assert(*this, tmp);
tmp->set_line(*this);
return tmp;
}
NetEConst* NetEBLogic::eval_tree(int prune_to_width)
@@ -969,7 +960,6 @@ NetExpr* NetEBMult::eval_tree_real_()
bool flag = get_real_arguments_(lval, rval);
if (! flag) return 0;
NetECReal*res = new NetECReal(lval * rval);
res->set_line(*this);
return res;
@@ -980,8 +970,7 @@ NetExpr* NetEBMult::eval_tree(int prune_to_width)
eval_expr(left_);
eval_expr(right_);
if (expr_type() == IVL_VT_REAL)
return eval_tree_real_();
if (expr_type() == IVL_VT_REAL) return eval_tree_real_();
assert(expr_type() == IVL_VT_LOGIC);
@@ -1011,6 +1000,11 @@ NetExpr* NetEBPow::eval_tree_real_()
NetECReal*res = new NetECReal( pow(lval,rval) );
res->set_line(*this);
if (debug_eval_tree)
cerr << get_fileline() << ": debug: Evaluate (real) "
<< lval << " ** " << rval << " --> " << *res << endl;
return res;
}
@@ -1031,7 +1025,14 @@ NetExpr* NetEBPow::eval_tree(int prune_to_width)
verinum lval = lc->value();
verinum rval = rc->value();
return new NetEConst( pow(lval,rval) );
NetEConst*res = new NetEConst( pow(lval,rval) );
res->set_line(*this);
if (debug_eval_tree)
cerr << get_fileline() << ": debug: Evaluate "
<< lval << " ** " << rval << " --> " << *res << endl;
return res;
}
/*
@@ -1176,16 +1177,6 @@ NetEConst* NetEConcat::eval_tree(int prune_to_width)
if (local_errors > 0) return 0;
// Handle the special case that the repeat expression is
// zero. In this case, just return a 0 value with the expected
// width.
if (repeat_val == 0) {
verinum val (verinum::V0, expr_width());
NetEConst*res = new NetEConst(val);
res->set_width(val.len());
return res;
}
// At this point, the "gap" is the width of a single repeat of
// the concatenation. The total width of the result is the gap
// times the repeat count.
@@ -1477,7 +1468,9 @@ NetExpr* NetETernary::eval_tree(int prune_to_width)
<< "constant condition value: ";
print_ternary_cond(cond_);
cerr << get_fileline() << ": : Blending real cases "
<< "to get " << val << endl;
<< "true=" << tv.as_double()
<< ", false=" << fv.as_double()
<< ", to get " << val << endl;
}
NetECReal*rc = new NetECReal(val);
@@ -1604,6 +1597,7 @@ NetEConst* NetEUReduce::eval_tree(int prune_to_width)
verinum val = rval->value();
verinum::V res;
bool invert = false;
switch (op_) {
@@ -1632,6 +1626,8 @@ NetEConst* NetEUReduce::eval_tree(int prune_to_width)
break;
}
case 'A':
invert = true;
case '&': {
res = verinum::V1;
for (unsigned idx = 0 ; idx < val.len() ; idx += 1)
@@ -1639,6 +1635,8 @@ NetEConst* NetEUReduce::eval_tree(int prune_to_width)
break;
}
case 'N':
invert = true;
case '|': {
res = verinum::V0;
for (unsigned idx = 0 ; idx < val.len() ; idx += 1)
@@ -1646,6 +1644,8 @@ NetEConst* NetEUReduce::eval_tree(int prune_to_width)
break;
}
case 'X':
invert = true;
case '^': {
/* Reduction XOR. */
unsigned ones = 0, unknown = 0;
@@ -1661,17 +1661,17 @@ NetEConst* NetEUReduce::eval_tree(int prune_to_width)
break;
}
if (unknown)
return new NetEConst(verinum(verinum::Vx,1,true));
if (ones%2)
return new NetEConst(verinum(verinum::V1,1,true));
return new NetEConst(verinum(verinum::V0,1,true));
if (unknown) res = verinum::Vx;
else if (ones%2) res = verinum::V1;
else res = verinum::V0;
break;
}
default:
return 0;
}
if (invert) res = ~res;
return new NetEConst(verinum(res, 1));
}
@@ -1719,6 +1719,7 @@ NetExpr* evaluate_clog2(NetExpr*&arg_)
res = integer_width;
verinum tmp (res, integer_width);
tmp.has_sign(true);
NetEConst*rtn = new NetEConst(tmp);
return rtn;
}
@@ -1979,3 +1980,15 @@ NetExpr* NetESFunc::eval_tree(int prune_to_width)
return rtn;
}
NetExpr* NetEUFunc::eval_tree(int prune_to_width)
{
if (need_constant_expr) {
cerr << get_fileline() << ": sorry: constant user "
"functions are not currently supported: "
<< func_->basename() << "()." << endl;
}
return 0;
}
-3
View File
@@ -1,3 +0,0 @@
,*
hello_vpi.vpi
show_vcd.vcd
+219 -99
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1999-2008 Stephen Williams (steve@icarus.com)
* Copyright (c) 1999-2009 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
@@ -31,13 +31,13 @@ static NetNet* convert_to_real_const(Design*des, NetScope*scope, NetEConst*expr)
{
verireal vrl(expr->value().as_double());
NetECReal rlval(vrl);
NetNet* sig = rlval.synthesize(des, scope);
NetNet* sig = rlval.synthesize(des, scope, 0);
return sig;
}
/* Note that lsig, rsig and real_args are references. */
static bool process_binary_args(Design*des, NetScope*scope,
static bool process_binary_args(Design*des, NetScope*scope, NetExpr*root,
NetExpr*left, NetExpr*right,
NetNet*&lsig, NetNet*&rsig, bool&real_args,
NetExpr*obj)
@@ -49,27 +49,27 @@ static bool process_binary_args(Design*des, NetScope*scope,
/* Convert the arguments to real. Handle the special
cases of constants, which can be converted more directly. */
if (left->expr_type() == IVL_VT_REAL) {
lsig = left->synthesize(des, scope);
lsig = left->synthesize(des, scope, root);
} else if (NetEConst*tmpc = dynamic_cast<NetEConst*> (left)) {
lsig = convert_to_real_const(des, scope, tmpc);
} else {
NetNet*tmp = left->synthesize(des, scope);
NetNet*tmp = left->synthesize(des, scope, root);
lsig = cast_to_real(des, scope, tmp);
}
if (right->expr_type() == IVL_VT_REAL) {
rsig = right->synthesize(des, scope);
rsig = right->synthesize(des, scope, root);
} else if (NetEConst*tmpc = dynamic_cast<NetEConst*> (right)) {
rsig = convert_to_real_const(des, scope, tmpc);
} else {
NetNet*tmp = right->synthesize(des, scope);
NetNet*tmp = right->synthesize(des, scope, root);
rsig = cast_to_real(des, scope, tmp);
}
} else {
real_args = false;
lsig = left->synthesize(des, scope);
rsig = right->synthesize(des, scope);
lsig = left->synthesize(des, scope, root);
rsig = right->synthesize(des, scope, root);
}
@@ -77,7 +77,7 @@ static bool process_binary_args(Design*des, NetScope*scope,
else return false;
}
NetNet* NetExpr::synthesize(Design*des, NetScope*scope)
NetNet* NetExpr::synthesize(Design*des, NetScope*scope, NetExpr*root)
{
cerr << get_fileline() << ": internal error: cannot synthesize expression: "
<< *this << endl;
@@ -88,13 +88,13 @@ NetNet* NetExpr::synthesize(Design*des, NetScope*scope)
/*
* Make an LPM_ADD_SUB device from addition operators.
*/
NetNet* NetEBAdd::synthesize(Design*des, NetScope*scope)
NetNet* NetEBAdd::synthesize(Design*des, NetScope*scope, NetExpr*root)
{
ivl_assert(*this, (op()=='+') || (op()=='-'));
NetNet *lsig=0, *rsig=0;
bool real_args=false;
if (process_binary_args(des, scope, left_, right_, lsig, rsig,
if (process_binary_args(des, scope, root, left_, right_, lsig, rsig,
real_args, this)) {
return 0;
}
@@ -111,8 +111,8 @@ NetNet* NetEBAdd::synthesize(Design*des, NetScope*scope)
rsig = cast_to_real(des, scope, rsig);
} else {
lsig = pad_to_width(des, lsig, expr_width());
rsig = pad_to_width(des, rsig, expr_width());
lsig = pad_to_width(des, lsig, expr_width(), *this);
rsig = pad_to_width(des, rsig, expr_width(), *this);
assert(lsig->vector_width() == rsig->vector_width());
width=lsig->vector_width();
@@ -122,6 +122,7 @@ NetNet* NetEBAdd::synthesize(Design*des, NetScope*scope)
NetNet*osig = new NetNet(lsig->scope(), path, NetNet::IMPLICIT, width);
osig->local_flag(true);
osig->data_type(expr_type());
osig->set_signed(has_sign());
perm_string oname = osig->scope()->local_symbol();
NetAddSub *adder = new NetAddSub(lsig->scope(), oname, width);
@@ -148,10 +149,10 @@ NetNet* NetEBAdd::synthesize(Design*des, NetScope*scope)
* signals, then just connect a single gate to each bit of the vector
* of the expression.
*/
NetNet* NetEBBits::synthesize(Design*des, NetScope*scope)
NetNet* NetEBBits::synthesize(Design*des, NetScope*scope, NetExpr*root)
{
NetNet*lsig = left_->synthesize(des, scope);
NetNet*rsig = right_->synthesize(des, scope);
NetNet*lsig = left_->synthesize(des, scope, root);
NetNet*rsig = right_->synthesize(des, scope, root);
if (lsig == 0 || rsig == 0) return 0;
@@ -167,8 +168,8 @@ NetNet* NetEBBits::synthesize(Design*des, NetScope*scope)
unsigned width = expr_width();
if (rsig->vector_width() > width) width = rsig->vector_width();
lsig = pad_to_width(des, lsig, width);
rsig = pad_to_width(des, rsig, width);
lsig = pad_to_width(des, lsig, width, *this);
rsig = pad_to_width(des, rsig, width, *this);
assert(lsig->vector_width() == rsig->vector_width());
NetNet*osig = new NetNet(scope, scope->local_symbol(),
@@ -199,6 +200,7 @@ NetNet* NetEBBits::synthesize(Design*des, NetScope*scope)
gate = new NetLogic(scope, oname, 3, NetLogic::XNOR, width);
break;
default:
gate = NULL;
assert(0);
}
@@ -212,13 +214,13 @@ NetNet* NetEBBits::synthesize(Design*des, NetScope*scope)
return osig;
}
NetNet* NetEBComp::synthesize(Design*des, NetScope*scope)
NetNet* NetEBComp::synthesize(Design*des, NetScope*scope, NetExpr*root)
{
NetNet *lsig=0, *rsig=0;
unsigned width;
bool real_args=false;
if (process_binary_args(des, scope, left_, right_, lsig, rsig,
if (process_binary_args(des, scope, root, left_, right_, lsig, rsig,
real_args, this)) {
return 0;
}
@@ -230,13 +232,13 @@ NetNet* NetEBComp::synthesize(Design*des, NetScope*scope)
if (rsig->vector_width() > width) width = rsig->vector_width();
if (lsig->get_signed())
lsig = pad_to_width_signed(des, lsig, width);
lsig = pad_to_width_signed(des, lsig, width, *this);
else
lsig = pad_to_width(des, lsig, width);
lsig = pad_to_width(des, lsig, width, *this);
if (rsig->get_signed())
rsig = pad_to_width_signed(des, rsig, width);
rsig = pad_to_width_signed(des, rsig, width, *this);
else
rsig = pad_to_width(des, rsig, width);
rsig = pad_to_width(des, rsig, width, *this);
}
NetNet*osig = new NetNet(scope, scope->local_symbol(),
@@ -362,12 +364,12 @@ NetNet* NetEBComp::synthesize(Design*des, NetScope*scope)
return osig;
}
NetNet* NetEBPow::synthesize(Design*des, NetScope*scope)
NetNet* NetEBPow::synthesize(Design*des, NetScope*scope, NetExpr*root)
{
NetNet *lsig=0, *rsig=0;
unsigned width;
bool real_args=false;
if (process_binary_args(des, scope, left_, right_, lsig, rsig,
if (process_binary_args(des, scope, root, left_, right_, lsig, rsig,
real_args, this)) {
return 0;
}
@@ -390,6 +392,7 @@ NetNet* NetEBPow::synthesize(Design*des, NetScope*scope)
NetNet::IMPLICIT, width);
osig->set_line(*this);
osig->data_type(expr_type());
osig->set_signed(has_sign());
osig->local_flag(true);
connect(powr->pin_Result(), osig->pin(0));
@@ -397,12 +400,12 @@ NetNet* NetEBPow::synthesize(Design*des, NetScope*scope)
return osig;
}
NetNet* NetEBMult::synthesize(Design*des, NetScope*scope)
NetNet* NetEBMult::synthesize(Design*des, NetScope*scope, NetExpr*root)
{
NetNet *lsig=0, *rsig=0;
unsigned width;
bool real_args=false;
if (process_binary_args(des, scope, left_, right_, lsig, rsig,
if (process_binary_args(des, scope, root, left_, right_, lsig, rsig,
real_args, this)) {
return 0;
}
@@ -426,6 +429,7 @@ NetNet* NetEBMult::synthesize(Design*des, NetScope*scope)
NetNet::IMPLICIT, width);
osig->set_line(*this);
osig->data_type(expr_type());
osig->set_signed(has_sign());
osig->local_flag(true);
connect(mult->pin_Result(), osig->pin(0));
@@ -433,12 +437,12 @@ NetNet* NetEBMult::synthesize(Design*des, NetScope*scope)
return osig;
}
NetNet* NetEBDiv::synthesize(Design*des, NetScope*scope)
NetNet* NetEBDiv::synthesize(Design*des, NetScope*scope, NetExpr*root)
{
NetNet *lsig=0, *rsig=0;
unsigned width;
bool real_args=false;
if (process_binary_args(des, scope, left_, right_, lsig, rsig,
if (process_binary_args(des, scope, root, left_, right_, lsig, rsig,
real_args, this)) {
return 0;
}
@@ -507,10 +511,10 @@ NetNet* NetEBDiv::synthesize(Design*des, NetScope*scope)
return osig;
}
NetNet* NetEBLogic::synthesize(Design*des, NetScope*scope)
NetNet* NetEBLogic::synthesize(Design*des, NetScope*scope, NetExpr*root)
{
NetNet*lsig = left_->synthesize(des, scope);
NetNet*rsig = right_->synthesize(des, scope);
NetNet*lsig = left_->synthesize(des, scope, root);
NetNet*rsig = right_->synthesize(des, scope, root);
if (lsig == 0 || rsig == 0) return 0;
@@ -584,11 +588,11 @@ NetNet* NetEBLogic::synthesize(Design*des, NetScope*scope)
return osig;
}
NetNet* NetEBShift::synthesize(Design*des, NetScope*scope)
NetNet* NetEBShift::synthesize(Design*des, NetScope*scope, NetExpr*root)
{
eval_expr(right_);
NetNet*lsig = left_->synthesize(des, scope);
NetNet*lsig = left_->synthesize(des, scope, root);
if (lsig == 0) return 0;
@@ -601,8 +605,8 @@ NetNet* NetEBShift::synthesize(Design*des, NetScope*scope)
return 0;
}
const bool right_flag = op_ == 'r' || op_ == 'R';
const bool signed_flag = op_ == 'R';
const bool right_flag = op_ == 'r' || op_ == 'R';
const bool signed_flag = has_sign() && op_ == 'R';
/* Detect the special case where the shift amount is
constant. Evaluate the shift amount, and simply reconnect
@@ -690,7 +694,7 @@ NetNet* NetEBShift::synthesize(Design*des, NetScope*scope)
return osig;
}
NetNet*rsig = right_->synthesize(des, scope);
NetNet*rsig = right_->synthesize(des, scope, root);
if (rsig == 0) return 0;
@@ -716,69 +720,101 @@ NetNet* NetEBShift::synthesize(Design*des, NetScope*scope)
return osig;
}
NetNet* NetEConcat::synthesize(Design*des, NetScope*scope)
NetNet* NetEConcat::synthesize(Design*des, NetScope*scope, NetExpr*root)
{
/* First, synthesize the operands. */
unsigned nparms = parms_.count();
NetNet**tmp = new NetNet*[parms_.count()];
bool flag = true;
ivl_variable_type_t data_type = IVL_VT_NO_TYPE;
for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) {
tmp[idx] = parms_[idx]->synthesize(des, scope);
if (tmp[idx] == 0)
flag = false;
if (parms_[idx]->expr_width() == 0) {
/* We need to synthesize a replication of zero. */
tmp[idx] = parms_[idx]->synthesize(des, scope, root);
assert(tmp[idx] == 0);
nparms -= 1;
} else {
tmp[idx] = parms_[idx]->synthesize(des, scope, root);
if (tmp[idx] == 0) flag = false;
/* Set the data type to the first one found. */
if (data_type == IVL_VT_NO_TYPE) {
data_type = tmp[idx]->data_type();
}
}
}
if (flag == false)
return 0;
if (flag == false) return 0;
ivl_assert(*this, tmp[0]);
ivl_assert(*this, data_type != IVL_VT_NO_TYPE);
/* If this is a replication of zero just return 0. */
if (expr_width() == 0) return 0;
/* Make a NetNet object to carry the output vector. */
perm_string path = scope->local_symbol();
NetNet*osig = new NetNet(scope, path, NetNet::IMPLICIT, expr_width());
osig->local_flag(true);
osig->data_type(tmp[0]->data_type());
osig->data_type(data_type);
NetConcat*concat = new NetConcat(scope, scope->local_symbol(),
osig->vector_width(),
parms_.count() * repeat());
nparms * repeat());
concat->set_line(*this);
des->add_node(concat);
connect(concat->pin(0), osig->pin(0));
unsigned count_input_width = 0;
unsigned cur_pin = 1;
for (unsigned rpt = 0; rpt < repeat(); rpt += 1) {
for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) {
unsigned concat_item = parms_.count()-idx-1;
ivl_assert(*this, tmp[concat_item]);
if (tmp[concat_item] == 0) continue;
connect(concat->pin(cur_pin), tmp[concat_item]->pin(0));
cur_pin += 1;
count_input_width += tmp[concat_item]->vector_width();
}
}
if (count_input_width != osig->vector_width()) {
cerr << get_fileline() << ": internal error: "
<< "NetEConcat input width = " << count_input_width
<< ", expecting " << osig->vector_width()
<< " (repeat=" << repeat() << ")" << endl;
des->errors += 1;
}
delete[]tmp;
return osig;
}
NetNet* NetEConst::synthesize(Design*des, NetScope*scope)
NetNet* NetEConst::synthesize(Design*des, NetScope*scope, NetExpr*)
{
perm_string path = scope->local_symbol();
unsigned width=expr_width();
if (width == 0) {
cerr << get_fileline() << ": internal error: "
<< "Found a zero width constant!" << endl;
return 0;
}
NetNet*osig = new NetNet(scope, path, NetNet::IMPLICIT, width);
osig->local_flag(true);
osig->data_type(expr_type());
osig->set_signed(has_sign());
NetConst*con = new NetConst(scope, scope->local_symbol(), value());
connect(osig->pin(0), con->pin(0));
osig->set_line(*this);
NetConst*con = new NetConst(scope, scope->local_symbol(), value());
des->add_node(con);
con->set_line(*this);
connect(osig->pin(0), con->pin(0));
return osig;
}
/*
* Create a NetLiteral object to represent real valued constants.
*/
NetNet* NetECReal::synthesize(Design*des, NetScope*scope)
NetNet* NetECReal::synthesize(Design*des, NetScope*scope, NetExpr*)
{
perm_string path = scope->local_symbol();
@@ -800,9 +836,9 @@ NetNet* NetECReal::synthesize(Design*des, NetScope*scope)
* The bitwise unary logic operator (there is only one) is turned
* into discrete gates just as easily as the binary ones above.
*/
NetNet* NetEUBits::synthesize(Design*des, NetScope*scope)
NetNet* NetEUBits::synthesize(Design*des, NetScope*scope, NetExpr*root)
{
NetNet*isig = expr_->synthesize(des, scope);
NetNet*isig = expr_->synthesize(des, scope, root);
if (isig == 0) return 0;
@@ -828,6 +864,7 @@ NetNet* NetEUBits::synthesize(Design*des, NetScope*scope)
gate = new NetLogic(scope, oname, 2, NetLogic::NOT, width);
break;
default:
gate = NULL;
assert(0);
}
@@ -839,19 +876,19 @@ NetNet* NetEUBits::synthesize(Design*des, NetScope*scope)
return osig;
}
NetNet* NetEUnary::synthesize(Design*des, NetScope*scope)
NetNet* NetEUnary::synthesize(Design*des, NetScope*scope, NetExpr*root)
{
if (op_ == '+')
return expr_->synthesize(des, scope);
return expr_->synthesize(des, scope, root);
if (op_ == '-') {
NetNet*sig = expr_->synthesize(des, scope);
NetNet*sig = expr_->synthesize(des, scope, root);
sig = sub_net_from(des, scope, 0, sig);
return sig;
}
if (op_ == 'm') {
NetNet*sub = expr_->synthesize(des, scope);
NetNet*sub = expr_->synthesize(des, scope, root);
if (expr_->has_sign() == false)
return sub;
@@ -873,12 +910,12 @@ NetNet* NetEUnary::synthesize(Design*des, NetScope*scope)
cerr << get_fileline() << ": iternal error: "
<< "NetEUnary::synthesize cannot handle op_=" << op_ << endl;
des->errors += 1;
return expr_->synthesize(des, scope);
return expr_->synthesize(des, scope, root);
}
NetNet* NetEUReduce::synthesize(Design*des, NetScope*scope)
NetNet* NetEUReduce::synthesize(Design*des, NetScope*scope, NetExpr*root)
{
NetNet*isig = expr_->synthesize(des, scope);
NetNet*isig = expr_->synthesize(des, scope, root);
if (isig == 0) return 0;
@@ -896,11 +933,6 @@ NetNet* NetEUReduce::synthesize(Design*des, NetScope*scope)
return 0;
}
NetNet*osig = new NetNet(scope, scope->local_symbol(),
NetNet::IMPLICIT, 1);
osig->data_type(expr_type());
osig->local_flag(true);
NetUReduce::TYPE rtype = NetUReduce::NONE;
switch (op()) {
@@ -931,8 +963,13 @@ NetNet* NetEUReduce::synthesize(Design*des, NetScope*scope)
NetUReduce*gate = new NetUReduce(scope, scope->local_symbol(),
rtype, isig->vector_width());
des->add_node(gate);
NetNet*osig = new NetNet(scope, scope->local_symbol(),
NetNet::IMPLICIT, 1);
osig->data_type(expr_type());
osig->local_flag(true);
connect(gate->pin(0), osig->pin(0));
for (unsigned idx = 0 ; idx < isig->pin_count() ; idx += 1)
connect(gate->pin(1+idx), isig->pin(idx));
@@ -948,10 +985,10 @@ NetNet* NetEUReduce::synthesize(Design*des, NetScope*scope)
* - Expression elaboration already converted the offset expression into
* canonical form, so we don't have to worry about that here.
*/
NetNet* NetESelect::synthesize(Design *des, NetScope*scope)
NetNet* NetESelect::synthesize(Design *des, NetScope*scope, NetExpr*root)
{
NetNet*sub = expr_->synthesize(des, scope);
NetNet*sub = expr_->synthesize(des, scope, root);
if (sub == 0) return 0;
@@ -961,31 +998,51 @@ NetNet* NetESelect::synthesize(Design *des, NetScope*scope)
// it is constant. In this case we can generate fixed part selects.
if (NetEConst*base_const = dynamic_cast<NetEConst*>(base_)) {
verinum base_tmp = base_const->value();
ivl_assert(*this, base_tmp.is_defined());
unsigned select_width = expr_width();
// Return 'bx for a constant undefined selections.
if (!base_tmp.is_defined()) {
NetNet*result = make_const_x(des, scope, select_width);
result->set_line(*this);
return result;
}
long base_val = base_tmp.as_long();
unsigned select_width = expr_width();
unsigned below_width = 0;
// Any below X bits?
NetNet*below = 0;
if (base_val < 0) {
unsigned below_width = abs(base_val);
below_width = abs(base_val);
base_val = 0;
ivl_assert(*this, below_width < select_width);
select_width -= below_width;
if (below_width > select_width) {
below_width = select_width;
select_width = 0;
} else {
select_width -= below_width;
}
below = make_const_x(des, scope, below_width);
below->set_line(*this);
// All the selected bits are below the signal.
if (select_width == 0) return below;
}
// Any above bits?
NetNet*above = 0;
if ((unsigned)base_val+select_width > sub->vector_width()) {
select_width = sub->vector_width() - base_val;
unsigned above_width = expr_width() - select_width;
if (base_val > (long)sub->vector_width()) {
select_width = 0;
} else {
select_width = sub->vector_width() - base_val;
}
ivl_assert(*this, expr_width() > (select_width+below_width));
unsigned above_width = expr_width() - select_width - below_width;
above = make_const_x(des, scope, above_width);
above->set_line(*this);
// All the selected bits are above the signal.
if (select_width == 0) return above;
}
// Make the make part select.
@@ -1034,9 +1091,10 @@ NetNet* NetESelect::synthesize(Design *des, NetScope*scope)
// actual part/bit select. Generate a NetPartSelect object to
// do the work, and replace "sub" with the selected output.
if (base_ != 0) {
off = base_->synthesize(des, scope);
off = base_->synthesize(des, scope, root);
NetPartSelect*sel = new NetPartSelect(sub, off, expr_width());
NetPartSelect*sel = new NetPartSelect(sub, off, expr_width(),
base_->has_sign());
sel->set_line(*this);
des->add_node(sel);
@@ -1115,11 +1173,11 @@ NetNet* NetESelect::synthesize(Design *des, NetScope*scope)
* expressions to the B and A inputs. This way, when the select input
* is one, the B input, which is the true expression, is selected.
*/
NetNet* NetETernary::synthesize(Design *des, NetScope*scope)
NetNet* NetETernary::synthesize(Design *des, NetScope*scope, NetExpr*root)
{
NetNet*csig = cond_->synthesize(des, scope),
*tsig = true_val_->synthesize(des, scope),
*fsig = false_val_->synthesize(des, scope);
NetNet*csig = cond_->synthesize(des, scope, root),
*tsig = true_val_->synthesize(des, scope, root),
*fsig = false_val_->synthesize(des, scope, root);
if (csig == 0 || tsig == 0 || fsig == 0) return 0;
@@ -1153,12 +1211,21 @@ NetNet* NetETernary::synthesize(Design *des, NetScope*scope)
osig->data_type(expr_type());
osig->local_flag(true);
/* Make sure both value operands are the right width. */
tsig = crop_to_width(des, pad_to_width(des, tsig, width), width);
fsig = crop_to_width(des, pad_to_width(des, fsig, width), width);
/* Make sure the types match. */
if (expr_type() == IVL_VT_REAL) {
tsig = cast_to_real(des, scope, tsig);
fsig = cast_to_real(des, scope, fsig);
}
/* Make sure both value operands are the right width. */
if (type_is_vectorable(expr_type())) {
tsig = crop_to_width(des, pad_to_width(des, tsig, width, *this), width);
fsig = crop_to_width(des, pad_to_width(des, fsig, width, *this), width);
ivl_assert(*this, width == tsig->vector_width());
ivl_assert(*this, width == fsig->vector_width());
}
assert(width == tsig->vector_width());
assert(width == fsig->vector_width());
perm_string oname = csig->scope()->local_symbol();
NetMux *mux = new NetMux(csig->scope(), oname, width,
@@ -1178,7 +1245,7 @@ NetNet* NetETernary::synthesize(Design *des, NetScope*scope)
* a bit more work needs to be done. Return a temporary that represents
* the selected word.
*/
NetNet* NetESignal::synthesize(Design*des, NetScope*scope)
NetNet* NetESignal::synthesize(Design*des, NetScope*scope, NetExpr*root)
{
if (word_ == 0)
return net_;
@@ -1205,7 +1272,7 @@ NetNet* NetESignal::synthesize(Design*des, NetScope*scope)
mux->set_line(*this);
des->add_node(mux);
NetNet*index_net = word_->synthesize(des, scope);
NetNet*index_net = word_->synthesize(des, scope, root);
connect(mux->pin_Address(), index_net->pin(0));
connect(tmp->pin(0), mux->pin_Result());
@@ -1213,7 +1280,35 @@ NetNet* NetESignal::synthesize(Design*des, NetScope*scope)
return tmp;
}
NetNet* NetESFunc::synthesize(Design*des, NetScope*scope)
static NetEvWait* make_func_trigger(Design*des, NetScope*scope, NetExpr*root)
{
NetEvWait*trigger = 0;
NexusSet*nset = root->nex_input(false);
if (nset && (nset->count() > 0)) {
NetEvent*ev = new NetEvent(scope->local_symbol());
ev->set_line(*root);
NetEvProbe*pr = new NetEvProbe(scope, scope->local_symbol(),
ev, NetEvProbe::ANYEDGE,
nset->count());
for (unsigned idx = 0 ; idx < nset->count() ; idx += 1)
connect(nset[0][idx], pr->pin(idx));
des->add_node(pr);
scope->add_event(ev);
trigger = new NetEvWait(0);
trigger->set_line(*root);
trigger->add_event(ev);
}
delete nset;
return trigger;
}
NetNet* NetESFunc::synthesize(Design*des, NetScope*scope, NetExpr*root)
{
const struct sfunc_return_type*def = lookup_sys_func(name_);
@@ -1233,8 +1328,13 @@ NetNet* NetESFunc::synthesize(Design*des, NetScope*scope)
<< name_ << " returns " << def->type << endl;
}
NetEvWait*trigger = 0;
if (nparms_ == 0) {
trigger = make_func_trigger(des, scope, root);
}
NetSysFunc*net = new NetSysFunc(scope, scope->local_symbol(),
def, 1+nparms_);
def, 1+nparms_, trigger);
net->set_line(*this);
des->add_node(net);
@@ -1249,7 +1349,7 @@ NetNet* NetESFunc::synthesize(Design*des, NetScope*scope)
unsigned errors = 0;
for (unsigned idx = 0 ; idx < nparms_ ; idx += 1) {
NetNet*tmp = parms_[idx]->synthesize(des, scope);
NetNet*tmp = parms_[idx]->synthesize(des, scope, root);
if (tmp == 0) {
cerr << get_fileline() << ": error: Unable to elaborate "
<< "argument " << idx << " of call to " << name_ <<
@@ -1267,14 +1367,18 @@ NetNet* NetESFunc::synthesize(Design*des, NetScope*scope)
return osig;
}
NetNet* NetEUFunc::synthesize(Design*des, NetScope*scope)
NetNet* NetEUFunc::synthesize(Design*des, NetScope*scope, NetExpr*root)
{
svector<NetNet*> eparms (parms_.count());
/* Synthesize the arguments. */
bool errors = false;
for (unsigned idx = 0; idx < eparms.count(); idx += 1) {
NetNet*tmp = parms_[idx]->synthesize(des, scope);
if (dynamic_cast<NetEEvent*> (parms_[idx])) {
errors = true;
continue;
}
NetNet*tmp = parms_[idx]->synthesize(des, scope, root);
if (tmp == 0) {
cerr << get_fileline() << ": error: Unable to synthesize "
"port " << idx << " of call to "
@@ -1287,7 +1391,17 @@ NetNet* NetEUFunc::synthesize(Design*des, NetScope*scope)
}
if (errors) return 0;
NetUserFunc*net = new NetUserFunc(scope_, scope_->local_symbol(), func_);
NetEvWait*trigger = 0;
if (gn_strict_ca_eval_flag) {
/* Ideally we would only do this for functions that have hidden
dependencies or side effects. Once constant functions are
implemented, we may be able to reuse some code to achieve
this. */
trigger = make_func_trigger(des, scope, root);
}
NetUserFunc*net = new NetUserFunc(scope_, scope_->local_symbol(), func_,
trigger);
net->set_line(*this);
des->add_node(net);
@@ -1301,9 +1415,15 @@ NetNet* NetEUFunc::synthesize(Design*des, NetScope*scope)
/* Connect the pins to the arguments. */
NetFuncDef*def = func_->func_def();
for (unsigned idx = 0; idx < eparms.count(); idx += 1) {
NetNet*tmp = pad_to_width(des, eparms[idx],
def->port(idx)->vector_width());
connect(net->pin(idx+1), tmp->pin(0));
unsigned width = def->port(idx)->vector_width();
NetNet*tmp;
if (eparms[idx]->get_signed()) {
tmp = pad_to_width_signed(des, eparms[idx], width, *this);
} else {
tmp = pad_to_width(des, eparms[idx], width, *this);
}
NetNet*tmpc = crop_to_width(des, tmp, width);
connect(net->pin(idx+1), tmpc->pin(0));
}
return osig;
+3 -3
View File
@@ -99,9 +99,9 @@ void functor_t::lpm_ureduce(class Design*, class NetUReduce*)
void NetScope::run_functor(Design*des, functor_t*fun)
{
for (NetScope*cur = sub_ ; cur ; cur = cur->sib_) {
cur->run_functor(des, fun);
}
for (map<hname_t,NetScope*>::const_iterator cur = children_.begin()
; cur != children_.end() ; cur ++)
cur->second->run_functor(des, fun);
for (NetEvent*cur = events_ ; cur ; /* */) {
NetEvent*tmp = cur;
-62
View File
@@ -499,65 +499,3 @@ already seems to exist amongst VCD viewers in the wild, this behavior
seems to be acceptable according to the standard, is a better mirror
of 4-value behavior in the dead zone, and appears more user friendly
when viewed by reasonable viewers.
$Id: ieee1364-notes.txt,v 1.19 2007/04/18 02:36:13 steve Exp $
$Log: ieee1364-notes.txt,v $
Revision 1.19 2007/04/18 02:36:13 steve
Put to iverilog wiki for further notes.
Revision 1.18 2007/03/22 16:08:16 steve
Spelling fixes from Larry
Revision 1.17 2003/07/15 03:49:22 steve
Spelling fixes.
Revision 1.16 2003/04/14 03:40:21 steve
Make some effort to preserve bits while
operating on constant values.
Revision 1.15 2003/02/16 23:39:08 steve
NaN in dead zones of VCD dumps.
Revision 1.14 2003/02/06 17:51:36 steve
Edge of vectors notes.
Revision 1.13 2002/08/20 04:11:53 steve
Support parameters with defined ranges.
Revision 1.12 2002/06/11 03:34:33 steve
Spelling patch (Larry Doolittle)
Revision 1.11 2002/04/27 02:38:04 steve
Support selecting bits from parameters.
Revision 1.10 2002/03/31 01:54:13 steve
Notes about scheduling
Revision 1.9 2002/01/26 02:08:07 steve
Handle x in l-value of set/x
Revision 1.8 2001/08/01 05:17:31 steve
Accept empty port lists to module instantiation.
Revision 1.7 2001/02/17 05:27:31 steve
I allow function ports to have types.
Revision 1.6 2001/02/12 16:48:04 steve
Rant about bit widths.
Revision 1.5 2001/01/02 17:28:08 steve
Resolve repeat ambiguity in favor of loop.
Revision 1.4 2001/01/01 19:12:35 steve
repeat loops ambiguity.
Revision 1.3 2000/12/15 00:21:46 steve
rounding of time and x in primitives.
Revision 1.2 2000/11/19 22:03:04 steve
Integer parameter comments.
Revision 1.1 2000/07/23 18:06:31 steve
Document ieee1364 issues.
+10 -11
View File
@@ -1,15 +1,15 @@
.TH iverilog-vpi 1 "$Date: 2004/10/04 01:10:53 $" Version "$Date: 2004/10/04 01:10:53 $"
.TH iverilog-vpi 1 "April 17th, 2009" "" "Version %M.%m.%n %E"
.SH NAME
iverilog-vpi - Compile front end for VPI modules
.SH SYNOPSIS
.B iverilog-vpi
[--name=\fIname\fP]
[\-\-name=\fIname\fP]
\fIsourcefile\fP...
.SH DESCRIPTION
.PP
\fIiverilog-vpi\fP is a tool to simplify the compilation of VPI
\fIiverilog\-vpi\fP is a tool to simplify the compilation of VPI
modules for use with Icarus Verilog. It takes on the command line a
list of C or C++ source files, and generates as output a linked VPI
module. See the \fBvvp\fP(1) man page for a description of how the
@@ -20,8 +20,7 @@ first source file is named \fIfoo.c\fP, the output becomes
\fIfoo.vpi\fP.
.SH OPTIONS
.l
\fIiverilog-vpi\fP accepts the following options:
\fIiverilog\-vpi\fP accepts the following options:
.TP 8
.B -l\fIlibrary\fP
Include the named library in the link of the VPI module. This allows
@@ -54,7 +53,7 @@ These flags provide compile time information.
.SH "PC-ONLY OPTIONS"
The PC port of \fIiverilog-vpi\fP includes two special flags needed to
The PC port of \fIiverilog\-vpi\fP includes two special flags needed to
support the more intractable development environment. These flags help
the program locate parts that it needs.
@@ -62,7 +61,7 @@ the program locate parts that it needs.
.B -mingw=\fIpath\fP
Tell the program the root of the Mingw compiler tool suite. The
\fBvvp\fP runtime is compiled with this compiler, and this is the
compiler that \fIiverilog-vpi\fP expects to use to compile your source
compiler that \fIiverilog\-vpi\fP expects to use to compile your source
code. This is normally not needed, and if you do use it, it is only
needed once. The compiler will save the \fIpath\fP in the registry for
use later.
@@ -76,7 +75,7 @@ stored in the registry for future use.
.SH "UNIX-ONLY OPTIONS"
The UNIX version of \fIiverilog-vpi\fP includes additional flags to
The UNIX version of \fIiverilog\-vpi\fP includes additional flags to
let Makefile gurus peek at the configuration of the \fIiverilog\fP
installation. This way, Makefiles can be written that handle complex VPI
builds natively, and without hard-coding values that depend on the
@@ -104,9 +103,9 @@ requests a 32bit vpi binary instead of the default 64bit binary.
.P
Example GNU makefile that takes advantage of these flags:
.IP "" 4
CFLAGS = -Wall -O $(CFLAGS_$@)
CFLAGS = \-Wall \-O $(CFLAGS_$@)
.br
VPI_CFLAGS := $(shell iverilog-vpi --cflags)
VPI_CFLAGS := $(shell iverilog-vpi \-\-cflags)
.br
CFLAGS_messagev.o = $(VPI_CFLAGS)
.br
@@ -129,7 +128,7 @@ iverilog(1), vvp(1),
.SH COPYRIGHT
.nf
Copyright \(co 2002 Stephen Williams
Copyright \(co 2002\-2009 Stephen Williams
This document can be freely redistributed according to the terms of the
GNU General Public License version 2.0
+5 -4
View File
@@ -17,17 +17,18 @@
# 59 Temple Place - Suite 330
# Boston, MA 02111-1307, USA
#
#ident "$Id: iverilog-vpi.sh,v 1.17 2007/02/06 05:07:31 steve Exp $"
# These are the variables used for compiling files
CC=@IVCC@
CC="@IVCC@"
CXX=@IVCXX@
CFLAGS="@PIC@ @IVCFLAGS@ -I@INCLUDEDIR@"
SUFFIX=@SUFFIX@
# These are used for linking...
LD=$CC
LDFLAGS="@SHARED@ -L@LIBDIR@"
LDLIBS="-lveriuser -lvpi"
LDLIBS="-lveriuser$SUFFIX -lvpi$SUFFIX"
CCSRC=
CXSRC=
@@ -101,7 +102,7 @@ do
;;
--install-dir)
echo "@LIBDIR@/ivl"
echo "@LIBDIR@/ivl$SUFFIX"
exit
;;
esac
+19
View File
@@ -1,7 +1,12 @@
EXPORTS
ivl_branch_island
ivl_branch_terminal
ivl_design_const
ivl_design_consts
ivl_design_discipline
ivl_design_disciplines
ivl_design_flag
ivl_design_process
ivl_design_root
@@ -16,7 +21,9 @@ ivl_const_type
ivl_const_width
ivl_discipline_domain
ivl_discipline_flow
ivl_discipline_name
ivl_discipline_potential
ivl_event_any
ivl_event_basename
@@ -30,12 +37,15 @@ ivl_event_scope
ivl_expr_type
ivl_expr_bits
ivl_expr_branch
ivl_expr_def
ivl_expr_delay_val
ivl_expr_dvalue
ivl_expr_event
ivl_expr_file
ivl_expr_lineno
ivl_expr_name
ivl_expr_nature
ivl_expr_opcode
ivl_expr_oper1
ivl_expr_oper2
@@ -99,6 +109,7 @@ ivl_lpm_sset_value
ivl_lpm_string
ivl_lpm_sync_clr
ivl_lpm_sync_set
ivl_lpm_trigger
ivl_lpm_type
ivl_lpm_width
@@ -108,12 +119,15 @@ ivl_lval_part_off
ivl_lval_sig
ivl_lval_width
ivl_nature_name
ivl_nexus_get_private
ivl_nexus_name
ivl_nexus_ptrs
ivl_nexus_ptr
ivl_nexus_set_private
ivl_nexus_ptr_branch
ivl_nexus_ptr_con
ivl_nexus_ptr_drive0
ivl_nexus_ptr_drive1
@@ -147,6 +161,7 @@ ivl_scope_event
ivl_scope_events
ivl_scope_file
ivl_scope_is_auto
ivl_scope_is_cell
ivl_scope_lineno
ivl_scope_logs
ivl_scope_log
@@ -167,6 +182,7 @@ ivl_scope_time_units
ivl_scope_type
ivl_scope_tname
ivl_signal_array_addr_swapped
ivl_signal_array_base
ivl_signal_array_count
ivl_signal_attr
@@ -187,6 +203,7 @@ ivl_signal_nex
ivl_signal_npath
ivl_signal_path
ivl_signal_port
ivl_signal_scope
ivl_signal_signed
ivl_signal_type
ivl_signal_width
@@ -194,6 +211,7 @@ ivl_signal_width
ivl_path_delay
ivl_path_source
ivl_process_analog
ivl_process_attr_cnt
ivl_process_attr_val
ivl_process_file
@@ -219,6 +237,7 @@ ivl_stmt_delay_val
ivl_stmt_events
ivl_stmt_file
ivl_stmt_lineno
ivl_stmt_lexp
ivl_stmt_lval
ivl_stmt_lvals
ivl_stmt_lwidth
-3
View File
@@ -16,9 +16,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: ivl_assert.h,v 1.1 2007/01/31 04:21:10 steve Exp $"
#endif
#ifndef __ivl_assert_h
#define __ivl_assert_h
+85 -11
View File
@@ -1,7 +1,7 @@
#ifndef __ivl_target_H
#define __ivl_target_H
/*
* Copyright (c) 2000-2008 Stephen Williams (steve@icarus.com)
* Copyright (c) 2000-2009 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
@@ -29,6 +29,9 @@
#define _END_DECL
#endif
#ifndef __GNUC__
# define __attribute__(x)
#endif
_BEGIN_DECL
@@ -60,6 +63,9 @@ _BEGIN_DECL
* This object represent an array that can be a memory or a net
* array. (They are the same from the perspective of ivl_target.h.)
*
* ivl_branch_t
* this object represents an analog branch.
*
* ivl_design_t
* This object represents the entire elaborated design. Various
* global properties and methods are available from this.
@@ -149,6 +155,7 @@ _BEGIN_DECL
* throughout the design.
*/
typedef struct ivl_array_s *ivl_array_t;
typedef struct ivl_branch_s *ivl_branch_t;
typedef struct ivl_delaypath_s*ivl_delaypath_t;
typedef struct ivl_design_s *ivl_design_t;
typedef struct ivl_discipline_s*ivl_discipline_t;
@@ -169,7 +176,7 @@ typedef struct ivl_process_s *ivl_process_t;
typedef struct ivl_scope_s *ivl_scope_t;
typedef struct ivl_signal_s *ivl_signal_t;
typedef struct ivl_switch_s *ivl_switch_t;
typedef struct ivl_memory_s *ivl_memory_t; /* DEPRECATED */
typedef struct ivl_memory_s *ivl_memory_t; //XXXX __attribute__((deprecated));
typedef struct ivl_statement_s*ivl_statement_t;
/*
@@ -204,6 +211,7 @@ typedef enum ivl_expr_type_e {
IVL_EX_BACCESS= 19,
IVL_EX_BINARY = 2,
IVL_EX_CONCAT = 3,
IVL_EX_DELAY = 20,
IVL_EX_EVENT = 17,
IVL_EX_MEMORY = 4,
IVL_EX_NUMBER = 5,
@@ -361,6 +369,7 @@ typedef enum ivl_statement_type_e {
IVL_ST_CASEZ = 7,
IVL_ST_CASSIGN = 8,
IVL_ST_CONDIT = 9,
IVL_ST_CONTRIB = 27,
IVL_ST_DEASSIGN = 10,
IVL_ST_DELAY = 11,
IVL_ST_DELAYX = 12,
@@ -415,6 +424,20 @@ struct ivl_attribute_s {
};
typedef const struct ivl_attribute_s*ivl_attribute_t;
/* BRANCH
* Branches are analog constructs, a pair of terminals that is used in
* branch access functions. Terminal-1 is the reference node (The
* "ground") for the purposes of the access function that accesses it.
*
* SEMANTIC NOTES
* All the branches in an island are connected by terminals or by
* expressions. The island is the connection of branches that must be
* solved together.
*/
/* extern ivl_scope_t ivl_branch_scope(ivl_branch_t obj); */
extern ivl_nexus_t ivl_branch_terminal(ivl_branch_t obj, int idx);
extern ivl_island_t ivl_branch_island(ivl_branch_t obj);
/* DELAYPATH
* Delaypath objects represent delay paths called out by a specify
* block in the Verilog source file. The destination signal references
@@ -499,6 +522,9 @@ extern int ivl_design_time_precision(ivl_design_t des);
extern unsigned ivl_design_consts(ivl_design_t des);
extern ivl_net_const_t ivl_design_const(ivl_design_t, unsigned idx);
extern unsigned ivl_design_disciplines(ivl_design_t des);
extern ivl_discipline_t ivl_design_discipline(ivl_design_t des, unsigned idx);
/* LITERAL CONSTANTS
* Literal constants are nodes with no input and a single constant
* output. The form of the output depends on the type of the node.
@@ -572,6 +598,10 @@ extern double ivl_const_real(ivl_net_const_t net);
*/
extern const char*ivl_discipline_name(ivl_discipline_t net);
extern ivl_dis_domain_t ivl_discipline_domain(ivl_discipline_t net);
extern ivl_nature_t ivl_discipline_potential(ivl_discipline_t net);
extern ivl_nature_t ivl_discipline_flow(ivl_discipline_t net);
extern const char* ivl_nature_name(ivl_nature_t net);
/* EVENTS
*
@@ -716,12 +746,18 @@ extern unsigned ivl_expr_lineno(ivl_expr_t net);
/* IVL_EX_NUMBER */
extern const char* ivl_expr_bits(ivl_expr_t net);
/* IVL_EX_BACCESS */
extern ivl_branch_t ivl_expr_branch(ivl_expr_t net);
/* IVL_EX_UFUNC */
extern ivl_scope_t ivl_expr_def(ivl_expr_t net);
/* IVL_EX_DELAY */
extern uint64_t ivl_expr_delay_val(ivl_expr_t net);
/* IVL_EX_REALNUM */
extern double ivl_expr_dvalue(ivl_expr_t net);
/* IVL_EX_SIGNAL, IVL_EX_SFUNC, IVL_EX_VARIABLE */
extern const char* ivl_expr_name(ivl_expr_t net);
/* IVL_EX_BACCESS */
extern ivl_nature_t ivl_expr_nature(ivl_expr_t net);
/* IVL_EX_BINARY IVL_EX_UNARY */
extern char ivl_expr_opcode(ivl_expr_t net);
/* IVL_EX_BINARY IVL_EX_UNARY, IVL_EX_MEMORY IVL_EX_TERNARY */
@@ -994,6 +1030,10 @@ extern unsigned ivl_lpm_lineno(ivl_lpm_t net);
* often the number of inputs per out, i.e., the number of inputs
* per bit for a MUX.
*
* ivl_lpm_trigger
* SFUNC and UFUNC devices may have a trigger that forces the
* function output to be re-evaluated.
*
* SEMANTIC NOTES
*
* - Concatenation (IVL_LPM_CONCAT)
@@ -1156,6 +1196,11 @@ extern unsigned ivl_lpm_lineno(ivl_lpm_t net);
* function (i.e. "$display") that was found in the source code. The
* compiler does little checking of that name.
*
* The ivl_lpm_trigger function retrieves the trigger event that
* indicates when the system function needs to be re-evaluated. If
* there is no trigger event, the system function only needs to be
* re-evaluated when a change is detected on its input ports.
*
* - User Function Call (IVL_LPM_UFUNC)
* This device is special as it represents a call to a user defined
* function (behavioral code) within a netlist. The inputs to the
@@ -1174,6 +1219,11 @@ extern unsigned ivl_lpm_lineno(ivl_lpm_t net);
* ports. The ivl_lpm_size function returns the number of inputs for
* the device, and the ivl_lpm_data() function index argument selects
* the port to retrieve. Each port is sized independently.
*
* The ivl_lpm_trigger function retrieves the trigger event that
* indicates when the user function needs to be re-evaluated. If
* there is no trigger event, the user function only needs to be
* re-evaluated when a change is detected on its input ports.
*/
extern const char* ivl_lpm_name(ivl_lpm_t net); /* (Obsolete) */
@@ -1183,6 +1233,7 @@ extern ivl_scope_t ivl_lpm_scope(ivl_lpm_t net);
extern int ivl_lpm_signed(ivl_lpm_t net);
extern ivl_lpm_type_t ivl_lpm_type(ivl_lpm_t net);
extern unsigned ivl_lpm_width(ivl_lpm_t net);
extern ivl_event_t ivl_lpm_trigger(ivl_lpm_t net);
/* IVL_LPM_FF */
extern ivl_nexus_t ivl_lpm_async_clr(ivl_lpm_t net);
@@ -1369,7 +1420,7 @@ extern ivl_signal_t ivl_lval_sig(ivl_lval_t net);
* width. The compiler will insure this is so.
*/
extern const char* ivl_nexus_name(ivl_nexus_t net);
extern const char* ivl_nexus_name(ivl_nexus_t net) __attribute__((deprecated));
extern unsigned ivl_nexus_ptrs(ivl_nexus_t net);
extern ivl_nexus_ptr_t ivl_nexus_ptr(ivl_nexus_t net, unsigned idx);
@@ -1380,6 +1431,7 @@ extern void* ivl_nexus_get_private(ivl_nexus_t net);
extern ivl_drive_t ivl_nexus_ptr_drive0(ivl_nexus_ptr_t net);
extern ivl_drive_t ivl_nexus_ptr_drive1(ivl_nexus_ptr_t net);
extern unsigned ivl_nexus_ptr_pin(ivl_nexus_ptr_t net);
extern ivl_branch_t ivl_nexus_ptr_branch(ivl_nexus_ptr_t net);
extern ivl_net_const_t ivl_nexus_ptr_con(ivl_nexus_ptr_t net);
extern ivl_net_logic_t ivl_nexus_ptr_log(ivl_nexus_ptr_t net);
extern ivl_lpm_t ivl_nexus_ptr_lpm(ivl_nexus_ptr_t net);
@@ -1485,6 +1537,9 @@ extern unsigned ivl_parameter_lineno(ivl_parameter_t net);
* ivl_scope_is_auto
* Is the task or function declared to be automatic?
*
* ivl_scope_is_cell
* Is the module defined to be a cell?
*
* ivl_scope_var
* ivl_scope_vars
* REMOVED
@@ -1562,6 +1617,7 @@ extern unsigned ivl_scope_events(ivl_scope_t net);
extern ivl_event_t ivl_scope_event(ivl_scope_t net, unsigned idx);
extern const char* ivl_scope_file(ivl_scope_t net);
extern unsigned ivl_scope_is_auto(ivl_scope_t net);
extern unsigned ivl_scope_is_cell(ivl_scope_t net);
extern unsigned ivl_scope_lineno(ivl_scope_t net);
extern unsigned ivl_scope_logs(ivl_scope_t net);
extern ivl_net_logic_t ivl_scope_log(ivl_scope_t net, unsigned idx);
@@ -1602,10 +1658,12 @@ extern int ivl_scope_time_units(ivl_scope_t net);
*
* ivl_signal_array_base
* ivl_signal_array_count
* ivl_signal_array_addr_swapped
* The signal may be arrayed. If so, the array_count is >1. Each
* word of the array has its own nexus. The array_base is the
* address is the Verilog source for the canonical zero word. This
* may be negative, positive or zero.
* address in the Verilog source for the canonical zero word. This
* may be negative, positive or zero. The array addresses may be
* reversed/swapped.
*
* Note that arraying of the signal into words is distinct from the
* vectors. The width of a signal is the width of a WORD.
@@ -1681,9 +1739,11 @@ extern int ivl_scope_time_units(ivl_scope_t net);
* Returns the file and line where this signal is defined.
*/
extern ivl_scope_t ivl_signal_scope(ivl_signal_t net);
extern ivl_nexus_t ivl_signal_nex(ivl_signal_t net, unsigned word);
extern int ivl_signal_array_base(ivl_signal_t net);
extern unsigned ivl_signal_array_count(ivl_signal_t net);
extern unsigned ivl_signal_array_addr_swapped(ivl_signal_t net);
extern unsigned ivl_signal_dimensions(ivl_signal_t net);
extern ivl_discipline_t ivl_signal_discipline(ivl_signal_t net);
extern int ivl_signal_msb(ivl_signal_t net);
@@ -1716,12 +1776,16 @@ extern ivl_attribute_t ivl_signal_attr_val(ivl_signal_t net, unsigned idx);
* is translated into a type and a single statement. (The statement
* may be a compound statement.)
*
* The ivl_process_type function gets the type of the process,
* an "initial" or "always" statement.
* ivl_process_type
* ivl_process_analog
* The ivl_process_type function returns the type of the process,
* an "initial" or "always" statement. The ivl_process_analog
* returns true if the process is analog.
*
* A process is placed in a scope. The statement within the process
* operates within the scope of the process unless there are calls
* outside the scope.
* ivl_process_scope
* A process is placed in a scope. The statement within the process
* operates within the scope of the process unless there are calls
* outside the scope.
*
* The ivl_process_stmt function gets the statement that forms the
* process. See the statement related functions for how to manipulate
@@ -1731,6 +1795,7 @@ extern ivl_attribute_t ivl_signal_attr_val(ivl_signal_t net, unsigned idx);
* attr_val methods return those attributes.
*/
extern ivl_process_type_t ivl_process_type(ivl_process_t net);
extern int ivl_process_analog(ivl_process_t net);
extern ivl_scope_t ivl_process_scope(ivl_process_t net);
@@ -1826,6 +1891,12 @@ extern unsigned ivl_stmt_lineno(ivl_statement_t net);
* that constant value. If the expression is non-constant, the code
* generator is supposed to know what to do about that, too.
*
* - IVL_ST_CONTRIB
* This is an analog contribution statement. The ivl_stmt_lexp
* function returns the l-value expression which is guaranteed to be a
* branch access expression. The ivl_stmt_rval returns the r-value
* expression for the assignment.
*
* - IVL_ST_DELAY, IVL_ST_DELAYX
* These statement types are delay statements. They are a way to
* attach a delay to a statement. The ivl_stmt_sub_stmt() function
@@ -1891,6 +1962,8 @@ extern uint64_t ivl_stmt_delay_val(ivl_statement_t net);
/* IVL_ST_WAIT IVL_ST_TRIGGER */
extern unsigned ivl_stmt_nevent(ivl_statement_t net);
extern ivl_event_t ivl_stmt_events(ivl_statement_t net, unsigned idx);
/* IVL_ST_CONTRIB */
extern ivl_expr_t ivl_stmt_lexp(ivl_statement_t net);
/* IVL_ST_ASSIGN IVL_ST_ASSIGN_NB IVL_ST_CASSIGN IVL_ST_DEASSIGN
IVL_ST_FORCE IVL_ST_RELEASE */
extern ivl_lval_t ivl_stmt_lval(ivl_statement_t net, unsigned idx);
@@ -1905,7 +1978,8 @@ extern const char* ivl_stmt_name(ivl_statement_t net);
extern ivl_expr_t ivl_stmt_parm(ivl_statement_t net, unsigned idx);
/* IVL_ST_STASK */
extern unsigned ivl_stmt_parm_count(ivl_statement_t net);
/* IVL_ST_ASSIGN IVL_ST_ASSIGN_NB IVL_ST_CASSIGN IVL_ST_FORCE */
/* IVL_ST_ASSIGN IVL_ST_ASSIGN_NB IVL_ST_CASSIGN IVL_ST_CONTRIB
IVL_ST_FORCE */
extern ivl_expr_t ivl_stmt_rval(ivl_statement_t net);
/* IVL_ST_DELAY, IVL_ST_DELAYX, IVL_ST_FOREVER, IVL_ST_REPEAT
IVL_ST_WAIT, IVL_ST_WHILE */
-12
View File
@@ -2,7 +2,6 @@
Icarus Verilog LOADABLE TARGET API (ivl_target)
Copyright 2002 Stephen Williams <[email protected]>
$Id: ivl_target.txt,v 1.3 2002/06/11 03:34:33 steve Exp $
The ivl_target API is the interface available to modules that the
@@ -38,14 +37,3 @@ other LPM device with outputs.
There are ivl_lpm_size() input ports, each with the width
ivl_lpm_data2_width(). The actual nexus is indexed by ivl_lpm_data2().
$Log: ivl_target.txt,v $
Revision 1.3 2002/06/11 03:34:33 steve
Spelling patch (Larry Doolittle)
Revision 1.2 2002/03/17 19:31:17 steve
Add API to support user defined function.
Revision 1.1 2002/03/09 02:10:22 steve
Add the NetUserFunc netlist node.
+44 -6
View File
@@ -1,5 +1,5 @@
#ifndef __ivl_target_priv_H
#define __ivl_target_H
#define __ivl_target_priv_H
/*
* Copyright (c) 2008 Stephen Williams (steve@icarus.com)
*
@@ -19,26 +19,64 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
# include "ivl_target.h"
# include <inttypes.h>
# include <vector>
# include <valarray>
/*
* This deader has declarations related to the ivl_target.h API that
* This header has declarations related to the ivl_target.h API that
* are not to be exported outside of the core via the ivl_target.h
* interface.
*
* (NOTE: A lot of similar definitions exist in the t-dll.h header
* file. That is a legacy from an earlier time before the
* ivl_target_priv.h header file was started, and those definitions
* should gradually be moved over to this header file.)
*/
/*
* This is the root of a design, from the ivl_target point of few. The
* ivl_target API uses this as the root for getting at everything else
* in the design.
*/
struct ivl_design_s {
int time_precision;
ivl_process_t threads_;
ivl_scope_t *roots_;
unsigned nroots_;
// Keep an array of constants objects.
std::valarray<ivl_net_const_t> consts;
// Keep a handy array of all of the disciplines in the design.
std::valarray<ivl_discipline_t> disciplines;
const class Design*self;
};
/*
* A branch is a pair of terminals. The elaborator assures that the
* terminals have compatible disciplines.
*/
struct ivl_branch_s {
ivl_nexus_t pins[2];
ivl_island_t island;
};
/*
* Information about islands. Connected branches within a net are
* collected into islands. Branches that are purely ddiscrete do not
* have disciplines and do not belong to islands.
*/
class discipline_t;
struct ivl_island_s {
discipline_t*discipline;
ivl_discipline_t discipline;
// user accessible flags. They are initially false, always.
vector<bool> flags;
std::vector<bool> flags;
};
#endif
-3
View File
@@ -1,3 +0,0 @@
lexor.c
Makefile
ivlpp
+15 -13
View File
@@ -18,12 +18,9 @@
# 59 Temple Place - Suite 330
# Boston, MA 02111-1307, USA
#
#ident "$Id: Makefile.in,v 1.18 2006/10/30 22:45:37 steve Exp $"
#
#
SHELL = /bin/sh
VERSION = 0.0
suffix = @install_suffix@
prefix = @prefix@
exec_prefix = @exec_prefix@
@@ -40,17 +37,22 @@ INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
CPPFLAGS = @ident_support@ -I. -I.. -I$(srcdir)/.. -I$(srcdir) -DVERSION='"$(VERSION)"' @CPPFLAGS@ @DEFS@
CPPFLAGS = -I. -I.. -I$(srcdir)/.. -I$(srcdir) @CPPFLAGS@ @DEFS@
CFLAGS = -Wall @CFLAGS@
LDFLAGS = @LDFLAGS@
all: ivlpp@EXEEXT@
check: all
clean:
rm -f *.o lexor.c ivlpp@EXEEXT@
distclean: clean
rm -f Makefile
rm -f Makefile config.log
Makefile: $(srcdir)/Makefile.in ../config.status
cd ..; ./config.status --file=ivlpp/$@
O = main.o lexor.o
@@ -60,16 +62,16 @@ ivlpp@EXEEXT@: $O
lexor.c: lexor.lex
flex -olexor.c $(srcdir)/lexor.lex
install: all installdirs $(libdir)/ivl/ivlpp@EXEEXT@
install: all installdirs $(libdir)/ivl$(suffix)/ivlpp@EXEEXT@
$(libdir)/ivl/ivlpp@EXEEXT@: ivlpp@EXEEXT@
$(INSTALL_PROGRAM) ./ivlpp@EXEEXT@ $(DESTDIR)$(libdir)/ivl/ivlpp@EXEEXT@
$(libdir)/ivl$(suffix)/ivlpp@EXEEXT@: ivlpp@EXEEXT@
$(INSTALL_PROGRAM) ./ivlpp@EXEEXT@ "$(DESTDIR)$(libdir)/ivl$(suffix)/ivlpp@EXEEXT@"
installdirs: ../mkinstalldirs
$(srcdir)/../mkinstalldirs $(DESTDIR)$(libdir)/ivl
installdirs: $(srcdir)/../mkinstalldirs
$(srcdir)/../mkinstalldirs "$(DESTDIR)$(libdir)/ivl$(suffix)"
uninstall:
rm -f $(DESTDIR)$(libdir)/ivl/ivlpp@EXEEXT@
rm -f "$(DESTDIR)$(libdir)/ivl$(suffix)/ivlpp@EXEEXT@"
lexor.o: lexor.c globals.h
main.o: main.c globals.h
main.o: main.c globals.h $(srcdir)/../version_base.h ../version_tag.h
+4 -1
View File
@@ -1,7 +1,7 @@
#ifndef __globals_H
#define __globals_H
/*
* Copyright (c) 1999-2008 Stephen Williams (steve@icarus.com)
* Copyright (c) 1999-2009 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
@@ -34,12 +34,15 @@ extern void dump_precompiled_defines(FILE*out);
extern char**include_dir;
extern unsigned include_cnt;
extern int relative_include;
/* This flag is true if #line directives are to be generated. */
extern int line_direct_flag;
extern unsigned error_count;
extern FILE *depend_file;
extern char dep_mode;
/* This is the entry to the lexer. */
extern int yylex();
+85 -43
View File
@@ -1,6 +1,6 @@
%{
/*
* Copyright (c) 1999-2008 Stephen Williams ([email protected])
* Copyright (c) 1999-2009 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
@@ -64,13 +64,8 @@ struct include_stack_t
/* If we are reparsing a macro expansion, file is 0 and this
* member points to the string in progress
*/
const char* str;
/* If we are reparsing a macro expansion, this member indicates
* the amount of space it occupies in the macro expansion buffer.
* This will be zero for macros without arguments.
*/
int ebs;
char* str;
char* orig_str;
int stringify_flag;
@@ -462,7 +457,7 @@ keywords (include|define|undef|ifdef|ifndef|else|elseif|endif)
<IFCCOMMENT>\n\r |
<IFCCOMMENT>\r\n |
<IFCCOMMENT>\n |
<IFCCOMMENT>\r { istack->lineno += 1; }
<IFCCOMMENT>\r { istack->lineno += 1; fputc('\n', yyout); }
<IFCCOMMENT>"*/" { BEGIN(comment_enter); }
<IFDEF_FALSE,IFDEF_SUPR>[^\r\n] { }
@@ -599,7 +594,8 @@ keywords (include|define|undef|ifdef|ifndef|else|elseif|endif)
<MA_ADD>"(" { macro_add_to_arg(0); ma_parenthesis_level++; }
<MA_ADD>"," { macro_finish_arg(); }
<MA_ADD>"," { if (ma_parenthesis_level > 0) macro_add_to_arg(0);
else macro_finish_arg(); }
<MA_ADD>")" {
if (ma_parenthesis_level > 0) {
@@ -1352,10 +1348,17 @@ static void do_expand(int use_args)
struct include_stack_t*isp;
int head = 0;
int tail = 0;
const char *cp;
unsigned escapes = 0;
char *str_buf = 0;
if (cur_macro->keyword)
{
fprintf(yyout, "%s", cur_macro->value);
if (do_expand_stringify_flag) {
do_expand_stringify_flag = 0;
fputc('"', yyout);
}
return;
}
@@ -1364,6 +1367,7 @@ static void do_expand(int use_args)
head = exp_buf_size - exp_buf_free;
expand_using_args();
tail = exp_buf_size - exp_buf_free;
exp_buf_free += tail - head;
if (tail == head)
return;
@@ -1376,14 +1380,47 @@ static void do_expand(int use_args)
if (use_args)
{
isp->str = &exp_buf[head];
isp->ebs = tail - head;
}
else
{
isp->str = cur_macro->value;
isp->ebs = 0;
}
/* Escape some characters if we are making a string version. */
for (cp = isp->str; (cp = strpbrk(cp, "\"\\")); cp += 1, escapes += 1);
if (escapes && isp->stringify_flag) {
unsigned idx = 0;
str_buf = (char *) malloc(strlen(isp->str)+3*escapes+1);
for (cp = isp->str; *cp; cp += 1) {
if (*cp == '"') {
str_buf[idx] = '\\';
str_buf[idx+1] = '0';
str_buf[idx+2] = '4';
str_buf[idx+3] = '2';
idx += 4;
continue;
}
if (*cp == '\\') {
str_buf[idx] = '\\';
str_buf[idx+1] = '1';
str_buf[idx+2] = '3';
str_buf[idx+3] = '4';
idx += 4;
continue;
}
str_buf[idx] = *cp;
idx += 1;
}
str_buf[idx] = 0;
idx += 1;
exp_buf_free -= idx;
isp->str = str_buf;
} else
isp->str = strdup(isp->str);
isp->orig_str = isp->str;
isp->next = istack;
istack->yybs = YY_CURRENT_BUFFER;
istack = isp;
@@ -1422,8 +1459,7 @@ static void output_init()
static void include_filename()
{
if(standby)
{
if(standby) {
emit_pathline(istack);
fprintf
(
@@ -1443,14 +1479,11 @@ static void include_filename()
static void do_include()
{
/* standby is defined by include_filename() */
if (standby->path[0] == '/')
{
if (standby->path[0] == '/') {
if ((standby->file = fopen(standby->path, "r")))
goto code_that_switches_buffers;
}
else
{
unsigned idx, start = 0;
} else {
unsigned idx, start = 1;
char path[4096];
char *cp;
@@ -1458,25 +1491,18 @@ static void do_include()
strcpy(path, istack->path);
cp = strrchr(path, '/');
if (cp == 0)
start = 1; /* A base file so already in [1] */
else
{
/* I may need the relative path for a planned warning even when
* we are not in relative mode, so for now keep it around. */
if (cp != 0) {
*cp = '\0';
/* We do not need a strdup here since the path is read before
* it is overridden. If the search order is changed add a
* strdup here and a free below.
*/
include_dir[0] = path;
include_dir[0] = strdup(path);
if (relative_include) start = 0;
}
for (idx = start ; idx < include_cnt ; idx += 1)
{
for (idx = start ; idx < include_cnt ; idx += 1) {
sprintf(path, "%s/%s", include_dir[idx], standby->path);
if ((standby->file = fopen(path, "r")))
{
if ((standby->file = fopen(path, "r"))) {
/* Free the original path before we overwrite it. */
free(standby->path);
standby->path = strdup(path);
@@ -1491,10 +1517,16 @@ static void do_include()
code_that_switches_buffers:
/* Clear the current files path from the search list. */
free(include_dir[0]);
include_dir[0] = 0;
if(depend_file)
fprintf(depend_file, "%s\n", standby->path);
if (depend_file) {
if (dep_mode == 'p') {
fprintf(depend_file, "I %s\n", standby->path);
} else if (dep_mode != 'm') {
fprintf(depend_file, "%s\n", standby->path);
}
}
if (line_direct_flag)
fprintf(yyout, "\n`line 1 \"%s\" 1\n", standby->path);
@@ -1582,7 +1614,7 @@ static int load_next_input()
else
line_mask_flag = 1;
exp_buf_free += isp->ebs;
free(isp->orig_str);
}
if (isp->stringify_flag) {
@@ -1621,8 +1653,13 @@ static int load_next_input()
if (line_direct_flag)
fprintf(yyout, "\n`line 1 \"%s\" 0\n", istack->path);
if(depend_file)
fprintf(depend_file, "%s\n", istack->path);
if (depend_file) {
if (dep_mode == 'p') {
fprintf(depend_file, "M %s\n", istack->path);
} else if (dep_mode != 'i') {
fprintf(depend_file, "%s\n", istack->path);
}
}
/* This works around an issue in flex yyrestart() where it
* uses yyin to create a new buffer when one does not exist.
@@ -1759,7 +1796,6 @@ void reset_lexor(FILE* out, char* paths[])
isp->path = strdup(paths[0]);
isp->file = fopen(paths[0], "r");
isp->str = 0;
isp->ebs = 0;
isp->lineno = 0;
isp->stringify_flag = 0;
isp->comment = NULL;
@@ -1770,8 +1806,13 @@ void reset_lexor(FILE* out, char* paths[])
exit(1);
}
if(depend_file)
fprintf(depend_file, "%s\n", paths[0]);
if (depend_file) {
if (dep_mode == 'p') {
fprintf(depend_file, "M %s\n", paths[0]);
} else if (dep_mode != 'i') {
fprintf(depend_file, "%s\n", paths[0]);
}
}
yyout = out;
@@ -1789,7 +1830,6 @@ void reset_lexor(FILE* out, char* paths[])
isp->path = strdup(paths[idx]);
isp->file = 0;
isp->str = 0;
isp->ebs = 0;
isp->next = 0;
isp->lineno = 0;
isp->stringify_flag = 0;
@@ -1816,4 +1856,6 @@ void destroy_lexor()
# endif
# endif
# endif
free(def_buf);
free(exp_buf);
}
+61 -26
View File
@@ -1,5 +1,5 @@
const char COPYRIGHT[] =
"Copyright (c) 1999-2008 Stephen Williams ([email protected])";
"Copyright (c) 1999-2009 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
@@ -18,7 +18,8 @@ const char COPYRIGHT[] =
*/
# include "config.h"
# include "version.h"
# include "version_base.h"
# include "version_tag.h"
const char NOTICE[] =
" This program is free software; you can redistribute it and/or modify\n"
@@ -31,9 +32,9 @@ const char NOTICE[] =
" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
" GNU General Public License for more details.\n"
"\n"
" You should have received a copy of the GNU General Public License\n"
" along with this program; if not, write to the Free Software\n"
" Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA\n"
" You should have received a copy of the GNU General Public License along\n"
" with this program; if not, write to the Free Software Foundation, Inc.,\n"
" 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n"
;
# include <stdio.h>
@@ -56,6 +57,8 @@ extern const char*optarg;
#endif
/* Path to the dependency file, if there is one. */
char *dep_path = NULL;
/* Dependency file output mode */
char dep_mode = 'a';
/*
@@ -83,6 +86,8 @@ void add_source_file(const char*name)
char**include_dir = 0;
unsigned include_cnt = 0;
int relative_include = 0;
int line_direct_flag = 0;
unsigned error_count = 0;
@@ -144,13 +149,24 @@ static int flist_read_flags(const char*path)
define_macro(optarg, buf, 1, 0);
free(buf);
} else if (strcmp(cp,"M") == 0) {
} else if ((strcmp(cp,"Ma") == 0)
|| (strcmp(cp,"Mi") == 0)
|| (strcmp(cp,"Mm") == 0)
|| (strcmp(cp,"Mp") == 0)) {
if (dep_path) {
fprintf(stderr, "duplicate -M flag.\n");
} else {
} else {
dep_mode = cp[1];
dep_path = strdup(arg);
}
} else if (strcmp(cp,"relative include") == 0) {
if (strcmp(arg, "true") == 0) {
relative_include = 1;
} else {
relative_include = 0;
}
} else {
fprintf(stderr, "%s: Invalid keyword %s\n", path, cp);
}
@@ -205,26 +221,34 @@ int main(int argc, char*argv[])
FILE*precomp_out = NULL;
/* Define preprocessor keywords that I plan to just pass. */
/* From 1364-2005 Chapter 19. */
define_macro("begin_keywords", "`begin_keywords", 1, 0);
define_macro("celldefine", "`celldefine", 1, 0);
define_macro("default_decay_time", "`default_decay_time", 1, 0);
define_macro("default_nettype", "`default_nettype", 1, 0);
define_macro("default_trireg_strength", "`default_trireg_strength", 1, 0);
define_macro("delay_mode_distributed", "`delay_mode_distributed", 1, 0);
define_macro("delay_mode_unit", "`delay_mode_unit", 1, 0);
define_macro("delay_mode_path", "`delay_mode_path", 1, 0);
define_macro("delay_mode_zero", "`delay_mode_zero", 1, 0);
define_macro("disable_portfaults", "`disable_portfaults", 1, 0);
define_macro("enable_portfaults", "`enable_portfaults", 1, 0);
define_macro("end_keywords", "`end_keywords", 1, 0);
define_macro("endcelldefine", "`endcelldefine", 1, 0);
define_macro("endprotect", "`endprotect", 1, 0);
define_macro("line", "`line", 1, 0);
define_macro("nosuppress_faults", "`nosuppress_faults", 1, 0);
define_macro("nounconnected_drive", "`nounconnected_drive", 1, 0);
define_macro("protect", "`protect", 1, 0);
define_macro("pragma", "`pragma", 1, 0);
define_macro("resetall", "`resetall", 1, 0);
define_macro("suppress_faults", "`suppress_faults", 1, 0);
define_macro("timescale", "`timescale", 1, 0);
define_macro("unconnected_drive", "`unconnected_drive", 1, 0);
/* From 1364-2005 Annex D. */
define_macro("default_decay_time", "`default_decay_time", 1, 0);
define_macro("default_trireg_strength", "`default_trireg_strength", 1, 0);
define_macro("delay_mode_distributed", "`delay_mode_distributed", 1, 0);
define_macro("delay_mode_path", "`delay_mode_path", 1, 0);
define_macro("delay_mode_unit", "`delay_mode_unit", 1, 0);
define_macro("delay_mode_zero", "`delay_mode_zero", 1, 0);
/* From other places. */
define_macro("disable_portfaults", "`disable_portfaults", 1, 0);
define_macro("enable_portfaults", "`enable_portfaults", 1, 0);
define_macro("endprotect", "`endprotect", 1, 0);
define_macro("nosuppress_faults", "`nosuppress_faults", 1, 0);
define_macro("protect", "`protect", 1, 0);
define_macro("suppress_faults", "`suppress_faults", 1, 0);
define_macro("uselib", "`uselib", 1, 0);
include_cnt = 2;
@@ -289,7 +313,7 @@ int main(int argc, char*argv[])
case 'v':
fprintf(stderr, "Icarus Verilog Preprocessor version "
VERSION " (" VERSION_TAG ")\n\n");
fprintf(stderr, "%s\n", COPYRIGHT);
fprintf(stderr, "%s\n\n", COPYRIGHT);
fputs(NOTICE, stderr);
break;
@@ -348,14 +372,17 @@ int main(int argc, char*argv[])
if (precomp_out_path) {
precomp_out = fopen(precomp_out_path, "wb");
if (precomp_out == 0) {
if (out_path) fclose(out);
perror(precomp_out_path);
exit(1);
}
}
if(dep_path) {
depend_file = fopen(dep_path, "w");
if (dep_path) {
depend_file = fopen(dep_path, "a");
if (depend_file == 0) {
if (out_path) fclose(out);
if (precomp_out) fclose(precomp_out);
perror(dep_path);
exit(1);
}
@@ -363,24 +390,32 @@ int main(int argc, char*argv[])
if (source_cnt == 0) {
fprintf(stderr, "%s: No input files given.\n", argv[0]);
if (out_path) fclose(out);
if (depend_file) fclose(depend_file);
if (precomp_out) fclose(precomp_out);
return 1;
}
/* Pass to the lexical analyzer the list of input file, and
start scanning. */
reset_lexor(out, source_list);
if (yylex()) return -1;
if (yylex()) {
if (out_path) fclose(out);
if (depend_file) fclose(depend_file);
if (precomp_out) fclose(precomp_out);
return -1;
}
destroy_lexor();
if(depend_file) {
fclose(depend_file);
}
if (depend_file) fclose(depend_file);
if (precomp_out) {
dump_precompiled_defines(precomp_out);
fclose(precomp_out);
}
if (out_path) fclose(out);
/* Free the source and include directory lists. */
for (lp = 0; lp < source_cnt; lp += 1) {
free(source_list[lp]);
+446 -138
View File
@@ -4,7 +4,7 @@
%{
/*
* Copyright (c) 1998-2008 Stephen Williams ([email protected])
* Copyright (c) 1998-2009 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
@@ -67,27 +67,28 @@ static const char* set_file_name(char*text)
return path;
}
extern void pform_set_timescale(int, int, const char*file, unsigned line);
void reset_lexor();
static void line_directive();
static void line_directive2();
static verinum*make_unsized_binary(const char*txt);
static verinum*make_undef_highz_dec(const char*txt);
static verinum*make_unsized_dec(const char*txt);
static verinum*make_unsized_octal(const char*txt);
static verinum*make_unsized_hex(const char*txt);
verinum*make_unsized_binary(const char*txt);
verinum*make_undef_highz_dec(const char*txt);
verinum*make_unsized_dec(const char*txt);
verinum*make_unsized_octal(const char*txt);
verinum*make_unsized_hex(const char*txt);
static int dec_buf_div2(char *buf);
static void process_timescale(const char*txt);
static void process_ucdrive(const char*txt);
static list<int> keyword_mask_stack;
static int comment_enter;
static bool in_module = false;
static bool in_UDP = false;
bool in_celldefine = false;
UCDriveType uc_drive = UCD_NONE;
%}
%x CCOMMENT
@@ -96,6 +97,7 @@ static bool in_module = false;
%x CSTRING
%s UDPTABLE
%x PPTIMESCALE
%x PPUCDRIVE
%x PPDEFAULT_NETTYPE
%x PPBEGIN_KEYWORDS
%s EDGES
@@ -105,10 +107,13 @@ W [ \t\b\f\r]+
S [afpnumkKMGT]
TU [munpf]
%%
^"#line"[ ]+\"[^\"]*\"[ ]+[0-9]+.* { line_directive(); }
^"`line"[ ]+[0-9]+[ ]+\"[^\"]*\".* { line_directive2(); }
/* Recognize the various line directives. */
^"#line"[ \t]+.+ { line_directive(); }
^[ \t]?"`line"[ \t]+.+ { line_directive2(); }
[ \t\b\f\r] { ; }
\n { yylloc.first_line += 1; }
@@ -168,12 +173,12 @@ S [afpnumkKMGT]
<CSTRING>\\\\ { yymore(); /* Catch \\, which is a \ escaping itself */ }
<CSTRING>\\\" { yymore(); /* Catch \", which is an escaped quote */ }
<CSTRING>\n { BEGIN(0);
yylval.text = strdup(yytext);
yylval.text = strdupnew(yytext);
VLerror(yylloc, "Missing close quote of string.");
yylloc.first_line += 1;
return STRING; }
<CSTRING>\" { BEGIN(0);
yylval.text = strdup(yytext);
yylval.text = strdupnew(yytext);
yylval.text[strlen(yytext)-1] = 0;
return STRING; }
<CSTRING>. { yymore(); }
@@ -237,6 +242,23 @@ S [afpnumkKMGT]
in_module = false;
break;
case K_primitive:
in_UDP = true;
break;
case K_endprimitive:
in_UDP = false;
break;
/* Translate these to checks if we already have or are
* outside the declaration region. */
case K_timeunit:
if (have_timeunit_decl) rc = K_timeunit_check;
break;
case K_timeprecision:
if (have_timeprec_decl) rc = K_timeprecision_check;
break;
default:
yylval.text = 0;
break;
@@ -263,22 +285,35 @@ S [afpnumkKMGT]
return IDENTIFIER; }
\$([a-zA-Z0-9$_]+) {
if (strcmp(yytext,"$setuphold") == 0)
return K_Ssetuphold;
if (strcmp(yytext,"$attribute") == 0)
return KK_attribute;
/* The 1364-1995 timing checks. */
if (strcmp(yytext,"$hold") == 0)
return K_Shold;
if (strcmp(yytext,"$nochange") == 0)
return K_Snochange;
if (strcmp(yytext,"$period") == 0)
return K_Speriod;
if (strcmp(yytext,"$recovery") == 0)
return K_Srecovery;
if (strcmp(yytext,"$recrem") == 0)
return K_Srecrem;
if (strcmp(yytext,"$setup") == 0)
return K_Ssetup;
if (strcmp(yytext,"$setuphold") == 0)
return K_Ssetuphold;
if (strcmp(yytext,"$skew") == 0)
return K_Sskew;
if (strcmp(yytext,"$width") == 0)
return K_Swidth;
/* The new 1364-2001 timing checks. */
if (strcmp(yytext,"$fullskew") == 0)
return K_Sfullskew;
if (strcmp(yytext,"$recrem") == 0)
return K_Srecrem;
if (strcmp(yytext,"$removal") == 0)
return K_Sremoval;
if (strcmp(yytext,"$timeskew") == 0)
return K_Stimeskew;
if (strcmp(yytext,"$attribute") == 0)
return KK_attribute;
yylval.text = strdupnew(yytext);
return SYSTEM_IDENTIFIER; }
@@ -299,6 +334,13 @@ S [afpnumkKMGT]
based_size = yylval.number->as_ulong();
return DEC_NUMBER; }
/* This rule handles scaled time values for SystemVerilog. */
[0-9][0-9_]*(\.[0-9][0-9_]*)?{TU}?s {
if(gn_system_verilog_flag) {
yylval.text = strdupnew(yytext);
return TIME_LITERAL;
} else REJECT; }
/* These rules handle the scaled real literals from Verilog-AMS. The
value is a number with a single letter scale factor. If
verilog-ams is not enabled, then reject this rule. If it is
@@ -348,7 +390,7 @@ S [afpnumkKMGT]
return REALTIME; }
/* Notice and handle the timescale directive. */
/* Notice and handle the `timescale directive. */
^{W}?`timescale { BEGIN(PPTIMESCALE); }
<PPTIMESCALE>.* { process_timescale(yytext); }
@@ -362,28 +404,74 @@ S [afpnumkKMGT]
yylloc.first_line += 1;
BEGIN(0); }
/* Notice and handle the `celldefine and `endcelldefine directives. */
^{W}?`celldefine{W}? { in_celldefine = true; }
^{W}?`endcelldefine{W}? { in_celldefine = false; }
/* Notice and handle the resetall directive. */
^{W}?`resetall{W}? {
if (in_module) {
cerr << yylloc.text << ":" << yylloc.first_line << ": error: "
"`resetall directive can not be inside a module "
"definition." << endl;
error_count += 1;
} else if (in_UDP) {
cerr << yylloc.text << ":" << yylloc.first_line << ": error: "
"`resetall directive can not be inside a UDP "
"definition." << endl;
error_count += 1;
} else {
pform_set_default_nettype(NetNet::WIRE, yylloc.text,
yylloc.first_line);
in_celldefine = false;
uc_drive = UCD_NONE;
pform_set_timescale(def_ts_units, def_ts_prec, 0, 0);
} }
/* Notice and handle the `unconnected_drive directive. */
^{W}?`unconnected_drive { BEGIN(PPUCDRIVE); }
<PPUCDRIVE>.* { process_ucdrive(yytext); }
<PPUCDRIVE>\n {
if (in_module) {
cerr << yylloc.text << ":" << yylloc.first_line << ": error: "
"`unconnected_drive directive can not be inside a "
"module definition." << endl;
error_count += 1;
}
yylloc.first_line += 1;
BEGIN(0); }
^{W}?`nounconnected_drive{W}? {
if (in_module) {
cerr << yylloc.text << ":" << yylloc.first_line << ": error: "
"`nounconnected_drive directive can not be inside a "
"module definition." << endl;
error_count += 1;
}
uc_drive = UCD_NONE; }
/* These are directives that I do not yet support. I think that IVL
should handle these, not an external preprocessor. */
/* From 1364-2005 Chapter 19. */
^{W}?`pragme{W}?.* { }
^{W}?`celldefine{W}?.* { }
/* From 1364-2005 Annex D. */
^{W}?`default_decay_time{W}?.* { }
^{W}?`default_trireg_strength{W}?.* { }
^{W}?`delay_mode_distributed{W}?.* { }
^{W}?`delay_mode_unit{W}?.* { }
^{W}?`delay_mode_path{W}?.* { }
^{W}?`delay_mode_unit{W}?.* { }
^{W}?`delay_mode_zero{W}?.* { }
/* From other places. */
^{W}?`disable_portfaults{W}?.* { }
^{W}?`enable_portfaults{W}?.* { }
^{W}?`endcelldefine{W}?.* { }
`endprotect { }
^{W}?`line{W}?.* { }
^{W}?`nosuppress_faults{W}?.* { }
^{W}?`nounconnected_drive{W}?.* { }
`protect { }
^{W}?`resetall{W}?.* { }
^{W}?`suppress_faults{W}?.* { }
^{W}?`unconnected_drive{W}?.* { }
^{W}?`uselib{W}?.* { }
^{W}?`begin_keywords{W}? { BEGIN(PPBEGIN_KEYWORDS); }
@@ -447,16 +535,38 @@ S [afpnumkKMGT]
NetNet::Type net_type;
size_t wordlen = strcspn(yytext, " \t\f\r\n");
yytext[wordlen] = 0;
/* Add support for other wire types and better error detection. */
if (strcmp(yytext,"wire") == 0) {
net_type = NetNet::WIRE;
} else if (strcmp(yytext,"tri") == 0) {
net_type = NetNet::TRI;
} else if (strcmp(yytext,"tri0") == 0) {
net_type = NetNet::TRI0;
} else if (strcmp(yytext,"tri1") == 0) {
net_type = NetNet::TRI1;
} else if (strcmp(yytext,"wand") == 0) {
net_type = NetNet::WAND;
} else if (strcmp(yytext,"triand") == 0) {
net_type = NetNet::TRIAND;
} else if (strcmp(yytext,"wor") == 0) {
net_type = NetNet::WOR;
} else if (strcmp(yytext,"trior") == 0) {
net_type = NetNet::TRIOR;
} 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)"
<< " is not a valid (or supported)"
<< " default net type." << endl;
net_type = NetNet::WIRE;
error_count += 1;
@@ -483,6 +593,12 @@ S [afpnumkKMGT]
<< endl;
}
^{W}?`elsif{W}?.* {
cerr << yylloc.text << ":" << yylloc.first_line <<
": warning: `elsif not supported. Use an external preprocessor."
<< endl;
}
^{W}?`endif{W}?.* {
cerr << yylloc.text << ":" << yylloc.first_line <<
": warning: `endif not supported. Use an external preprocessor."
@@ -495,6 +611,12 @@ S [afpnumkKMGT]
<< endl;
}
^{W}?`ifndef{W}?.* {
cerr << yylloc.text << ":" << yylloc.first_line <<
": warning: `ifndef not supported. Use an external preprocessor."
<< endl;
}
^`include{W}?.* {
cerr << yylloc.text << ":" << yylloc.first_line <<
": warning: `include not supported. Use an external preprocessor."
@@ -545,7 +667,7 @@ void lex_end_table()
BEGIN(INITIAL);
}
static verinum*make_unsized_binary(const char*txt)
verinum*make_unsized_binary(const char*txt)
{
bool sign_flag = false;
const char*ptr = txt;
@@ -603,7 +725,7 @@ static verinum*make_unsized_binary(const char*txt)
}
static verinum*make_unsized_octal(const char*txt)
verinum*make_unsized_octal(const char*txt)
{
bool sign_flag = false;
const char*ptr = txt;
@@ -670,7 +792,7 @@ static verinum*make_unsized_octal(const char*txt)
}
static verinum*make_unsized_hex(const char*txt)
verinum*make_unsized_hex(const char*txt)
{
bool sign_flag = false;
const char*ptr = txt;
@@ -797,7 +919,7 @@ static int dec_buf_div2(char *buf)
}
/* Support a single x, z or ? as a decimal constant (from 1364-2005). */
static verinum* make_undef_highz_dec(const char* ptr)
verinum* make_undef_highz_dec(const char* ptr)
{
bool signed_flag = false;
@@ -850,7 +972,7 @@ static verinum* make_undef_highz_dec(const char* ptr)
* hard to calculate.
*/
static verinum*make_unsized_dec(const char*ptr)
verinum*make_unsized_dec(const char*ptr)
{
char buf[4096];
bool signed_flag = false;
@@ -936,6 +1058,128 @@ static verinum*make_unsized_dec(const char*ptr)
return res;
}
/*
* Convert the string to a time unit or precision.
* Returns true on failure.
*/
static bool get_timescale_const(const char *&cp, int &res, bool is_unit)
{
/* Check for the 1 digit. */
if (*cp != '1') {
if (is_unit) {
VLerror(yylloc, "Invalid `timescale unit constant "
"(1st digit)");
} else {
VLerror(yylloc, "Invalid `timescale precision constant "
"(1st digit)");
}
return true;
}
cp += 1;
/* Check the number of zeros after the 1. */
res = strspn(cp, "0");
if (res > 2) {
if (is_unit) {
VLerror(yylloc, "Invalid `timescale unit constant "
"(number of zeros)");
} else {
VLerror(yylloc, "Invalid `timescale precision constant "
"(number of zeros)");
}
return true;
}
cp += res;
/* Skip any space between the digits and the scaling string. */
cp += strspn(cp, " \t");
/* Now process the scaling string. */
if (strncmp("s", cp, 1) == 0) {
res -= 0;
cp += 1;
return false;
} else if (strncmp("ms", cp, 2) == 0) {
res -= 3;
cp += 2;
return false;
} else if (strncmp("us", cp, 2) == 0) {
res -= 6;
cp += 2;
return false;
} else if (strncmp("ns", cp, 2) == 0) {
res -= 9;
cp += 2;
return false;
} else if (strncmp("ps", cp, 2) == 0) {
res -= 12;
cp += 2;
return false;
} else if (strncmp("fs", cp, 2) == 0) {
res -= 15;
cp += 2;
return false;
}
if (is_unit) {
VLerror(yylloc, "Invalid `timescale unit scale");
} else {
VLerror(yylloc, "Invalid `timescale precision scale");
}
return true;
}
/*
* process either a pull0 or a pull1.
*/
static void process_ucdrive(const char*txt)
{
UCDriveType ucd = UCD_NONE;
const char*cp = txt + strspn(txt, " \t");
/* Skip the space after the `unconnected_drive directive. */
if (cp == txt) {
VLerror(yylloc, "Space required after `unconnected_drive "
"directive.");
return;
}
/* Check for the pull keyword. */
if (strncmp("pull", cp, 4) != 0) {
VLerror(yylloc, "pull required for `unconnected_drive "
"directive.");
return;
}
cp += 4;
if (*cp == '0') ucd = UCD_PULL0;
else if (*cp == '1') ucd = UCD_PULL1;
else {
cerr << yylloc.text << ":" << yylloc.first_line << ": error: "
"`unconnected_drive does not support 'pull" << *cp
<< "'." << endl;
error_count += 1;
return;
}
cp += 1;
/* Verify that only space and/or a single line comment is left. */
cp += strspn(cp, " \t");
if (strncmp(cp, "//", 2) != 0 &&
(size_t)(cp-yytext) != strlen(yytext)) {
VLerror(yylloc, "Invalid `unconnected_dirve directive (extra "
"garbage after precision).");
return;
}
uc_drive = ucd;
}
/*
* The timescale parameter has the form:
@@ -943,98 +1187,46 @@ static verinum*make_unsized_dec(const char*ptr)
*/
static void process_timescale(const char*txt)
{
unsigned num;
const char*cp = txt + strspn(txt, " \t");
char*tmp;
const char*ctmp;
/* Skip the space after the `timescale directive. */
if (cp == txt) {
VLerror(yylloc, "Space required after `timescale directive.");
return;
}
int unit = 0;
int prec = 0;
num = strtoul(cp, &tmp, 10);
if (num == 0) {
VLerror(yylloc, "Invalid timescale string.");
return;
}
/* Get the time units. */
if (get_timescale_const(cp, unit, true)) return;
while (num >= 10) {
unit += 1;
num /= 10;
}
if (num != 1) {
VLerror(yylloc, "Invalid timescale unit number.");
return;
}
cp = tmp;
/* Skip any space after the time units, the '/' and any
* space after the '/'. */
cp += strspn(cp, " \t");
ctmp = cp + strcspn(cp, " \t/");
if (strncmp("s", cp, ctmp-cp) == 0) {
unit -= 0;
} else if (strncmp("ms", cp, ctmp-cp) == 0) {
unit -= 3;
} else if (strncmp("us", cp, ctmp-cp) == 0) {
unit -= 6;
} else if (strncmp("ns", cp, ctmp-cp) == 0) {
unit -= 9;
} else if (strncmp("ps", cp, ctmp-cp) == 0) {
unit -= 12;
} else if (strncmp("fs", cp, ctmp-cp) == 0) {
unit -= 15;
} else {
VLerror(yylloc, "Invalid timescale unit of measurement");
if (*cp != '/') {
VLerror(yylloc, "`timescale separator '/' appears to be missing.");
return;
}
cp = ctmp;
cp += strspn(cp, " \t/");
num = strtoul(cp, &tmp, 10);
if (num == 0) {
VLerror(yylloc, "Invalid timescale string.");
return;
}
assert(num);
while (num >= 10) {
prec += 1;
num /= 10;
}
if (num != 1) {
VLerror(yylloc, "Invalid timescale precision number.");
return;
}
cp = tmp;
cp += 1;
cp += strspn(cp, " \t");
ctmp = cp + strcspn(cp, " \t\r");
if (strncmp("s", cp, ctmp-cp) == 0) {
prec -= 0;
/* Get the time precision. */
if (get_timescale_const(cp, prec, false)) return;
} else if (strncmp("ms", cp, ctmp-cp) == 0) {
prec -= 3;
/* Verify that only space and/or a single line comment is left. */
cp += strspn(cp, " \t");
if (strncmp(cp, "//", 2) != 0 &&
(size_t)(cp-yytext) != strlen(yytext)) {
VLerror(yylloc, "Invalid `timescale directive (extra garbage "
"after precision).");
return;
}
} else if (strncmp("us", cp, ctmp-cp) == 0) {
prec -= 6;
} else if (strncmp("ns", cp, ctmp-cp) == 0) {
prec -= 9;
} else if (strncmp("ps", cp, ctmp-cp) == 0) {
prec -= 12;
} else if (strncmp("fs", cp, ctmp-cp) == 0) {
prec -= 15;
} else {
VLerror(yylloc, "Invalid timescale precision units of measurement");
/* The time unit must be greater than or equal to the precision. */
if (unit < prec) {
VLerror(yylloc, "error: `timescale unit must not be less than "
"the precision.");
return;
}
@@ -1053,47 +1245,149 @@ int yywrap()
*/
static void line_directive()
{
char*qt1 = strchr(yytext, '"');
assert(qt1);
qt1 += 1;
char *cpr;
/* Skip any leading space. */
char *cp = strchr(yytext, '#');
/* Skip the #line directive. */
assert(strncmp(cp, "#line", 5) == 0);
cp += 5;
/* Skip the space after the #line directive. */
cp += strspn(cp, " \t");
char*qt2 = strchr(qt1, '"');
assert(qt2);
/* Find the starting " and skip it. */
char*fn_start = strchr(cp, '"');
if (cp != fn_start) {
VLerror(yylloc, "Invalid #line directive (file name start).");
return;
}
fn_start += 1;
char*buf = new char[qt2-qt1+1];
strncpy(buf, qt1, qt2-qt1);
buf[qt2-qt1] = 0;
/* Find the last ". */
char*fn_end = strrchr(fn_start, '"');
if (!fn_end) {
VLerror(yylloc, "Invalid #line directive (file name end).");
return;
}
/* Copy the file name and assign it to yylloc. */
char*buf = new char[fn_end-fn_start+1];
strncpy(buf, fn_start, fn_end-fn_start);
buf[fn_end-fn_start] = 0;
/* Skip the space after the file name. */
cp = fn_end;
cp += 1;
cpr = cp;
cpr += strspn(cp, " \t");
if (cp == cpr) {
VLerror(yylloc, "Invalid #line directive (missing space after "
"file name).");
return;
}
cp = cpr;
/* Get the line number and verify that it is correct. */
unsigned long lineno = strtoul(cp, &cpr, 10);
if (cp == cpr) {
VLerror(yylloc, "Invalid line number for #line directive.");
return;
}
cp = cpr;
/* Verify that only space is left. */
cpr += strspn(cp, " \t");
if ((size_t)(cpr-yytext) != strlen(yytext)) {
VLerror(yylloc, "Invalid #line directive (extra garbage after "
"line number).");
return;
}
/* Now we can assign the new values to yyloc. */
yylloc.text = set_file_name(buf);
qt2 += 1;
yylloc.first_line = strtoul(qt2,0,0);
yylloc.first_line = lineno;
}
/*
* The line directive matches lines of the form `line N "foo" M and
* calls this function. Here I parse out the file name and line
* number, and change the yylloc to suite. M is ignored.
*/
static void line_directive2()
{
assert(strncmp(yytext,"`line",5) == 0);
char*cp = yytext + strlen("`line");
cp += strspn(cp, " ");
yylloc.first_line = strtoul(cp,&cp,10);
char *cpr;
/* Skip any leading space. */
char *cp = strchr(yytext, '`');
/* Skip the `line directive. */
assert(strncmp(cp, "`line", 5) == 0);
cp += 5;
yylloc.first_line -= 1;
/* strtoul skips leading space. */
unsigned long lineno = strtoul(cp, &cpr, 10);
if (cp == cpr) {
VLerror(yylloc, "Invalid line number for `line directive.");
return;
}
lineno -= 1;
cp = cpr;
cp += strspn(cp, " ");
if (*cp == 0) return;
/* Skip the space between the line number and the file name. */
cpr += strspn(cp, " \t");
if (cp == cpr) {
VLerror(yylloc, "Invalid `line directive (missing space after "
"line number).");
return;
}
cp = cpr;
char*qt1 = strchr(yytext, '"');
assert(qt1);
qt1 += 1;
/* Find the starting " and skip it. */
char*fn_start = strchr(cp, '"');
if (cp != fn_start) {
VLerror(yylloc, "Invalid `line directive (file name start).");
return;
}
fn_start += 1;
char*qt2 = strchr(qt1, '"');
assert(qt2);
/* Find the last ". */
char*fn_end = strrchr(fn_start, '"');
if (!fn_end) {
VLerror(yylloc, "Invalid `line directive (file name end).");
return;
}
char*buf = new char[qt2-qt1+1];
strncpy(buf, qt1, qt2-qt1);
buf[qt2-qt1] = 0;
/* Skip the space after the file name. */
cp = fn_end + 1;
cpr = cp;
cpr += strspn(cp, " \t");
if (cp == cpr) {
VLerror(yylloc, "Invalid `line directive (missing space after "
"file name).");
return;
}
cp = cpr;
/* Check that the level is correct, we do not need the level. */
if (strspn(cp, "012") != 1) {
VLerror(yylloc, "Invalid level for `line directive.");
return;
}
cp += 1;
/* Verify that only space and/or a single line comment is left. */
cp += strspn(cp, " \t");
if (strncmp(cp, "//", 2) != 0 &&
(size_t)(cp-yytext) != strlen(yytext)) {
VLerror(yylloc, "Invalid `line directive (extra garbage after "
"level).");
return;
}
/* Copy the file name and assign it and the line number to yylloc. */
char*buf = new char[fn_end-fn_start+1];
strncpy(buf, fn_start, fn_end-fn_start);
buf[fn_end-fn_start] = 0;
yylloc.text = set_file_name(buf);
yylloc.first_line = lineno;
}
extern FILE*vl_input;
@@ -1105,3 +1399,17 @@ void reset_lexor()
/* Announce the first file name. */
yylloc.text = set_file_name(strdupnew(vl_file.c_str()));
}
/*
* Modern version of flex (>=2.5.9) can clean up the scanner data.
*/
void destroy_lexor()
{
# ifdef FLEX_SCANNER
# if YY_FLEX_MAJOR_VERSION >= 2 && YY_FLEX_MINOR_VERSION >= 5
# if defined(YY_FLEX_SUBMINOR_VERSION) && YY_FLEX_SUBMINOR_VERSION >= 9
yylex_destroy();
# endif
# endif
# endif
}
+311 -155
View File
@@ -11,161 +11,317 @@
%}
struct lexor_keyword { const char*name; int mask; int tokenType; };
%%
abs, GN_KEYWORDS_VAMS_2_3, K_abs
abstol, GN_KEYWORDS_VAMS_2_3, K_abstol
access, GN_KEYWORDS_VAMS_2_3, K_access
acos, GN_KEYWORDS_VAMS_2_3, K_acos
acosh, GN_KEYWORDS_VAMS_2_3, K_acosh
always, GN_KEYWORDS_1364_1995, K_always
analog, GN_KEYWORDS_VAMS_2_3, K_analog
and, GN_KEYWORDS_1364_1995, K_and
asin, GN_KEYWORDS_VAMS_2_3, K_asin
asinh, GN_KEYWORDS_VAMS_2_3, K_asinh
assign, GN_KEYWORDS_1364_1995, K_assign
atan, GN_KEYWORDS_VAMS_2_3, K_atan
atan2, GN_KEYWORDS_VAMS_2_3, K_atan2
atanh, GN_KEYWORDS_VAMS_2_3, K_atanh
automatic, GN_KEYWORDS_1364_2001, K_automatic
begin, GN_KEYWORDS_1364_1995, K_begin
bool, GN_KEYWORDS_ICARUS, K_bool
buf, GN_KEYWORDS_1364_1995, K_buf
bufif0, GN_KEYWORDS_1364_1995, K_bufif0
bufif1, GN_KEYWORDS_1364_1995, K_bufif1
case, GN_KEYWORDS_1364_1995, K_case
casex, GN_KEYWORDS_1364_1995, K_casex
casez, GN_KEYWORDS_1364_1995, K_casez
ceil, GN_KEYWORDS_VAMS_2_3, K_ceil
cmos, GN_KEYWORDS_1364_1995, K_cmos
continuous, GN_KEYWORDS_VAMS_2_3, K_continuous
cos, GN_KEYWORDS_VAMS_2_3, K_cos
cosh, GN_KEYWORDS_VAMS_2_3, K_cosh
ddt_nature, GN_KEYWORDS_VAMS_2_3, K_ddt_nature
deassign, GN_KEYWORDS_1364_1995, K_deassign
default, GN_KEYWORDS_1364_1995, K_default
defparam, GN_KEYWORDS_1364_1995, K_defparam
disable, GN_KEYWORDS_1364_1995, K_disable
discipline, GN_KEYWORDS_VAMS_2_3, K_discipline
discrete, GN_KEYWORDS_VAMS_2_3, K_discrete
domain, GN_KEYWORDS_VAMS_2_3, K_domain
edge, GN_KEYWORDS_1364_1995, K_edge
else, GN_KEYWORDS_1364_1995, K_else
end, GN_KEYWORDS_1364_1995, K_end
endcase, GN_KEYWORDS_1364_1995, K_endcase
enddiscipline, GN_KEYWORDS_VAMS_2_3, K_enddiscipline
endfunction, GN_KEYWORDS_1364_1995, K_endfunction
endgenerate, GN_KEYWORDS_1364_1995, K_endgenerate
endmodule, GN_KEYWORDS_1364_1995, K_endmodule
endnature, GN_KEYWORDS_VAMS_2_3, K_endnature
endprimitive, GN_KEYWORDS_1364_1995, K_endprimitive
endspecify, GN_KEYWORDS_1364_1995, K_endspecify
endtable, GN_KEYWORDS_1364_1995, K_endtable
endtask, GN_KEYWORDS_1364_1995, K_endtask
event, GN_KEYWORDS_1364_1995, K_event
exclude, GN_KEYWORDS_VAMS_2_3, K_exclude
exp, GN_KEYWORDS_VAMS_2_3, K_exp
floor, GN_KEYWORDS_VAMS_2_3, K_floor
flow, GN_KEYWORDS_VAMS_2_3, K_flow
for, GN_KEYWORDS_1364_1995, K_for
force, GN_KEYWORDS_1364_1995, K_force
forever, GN_KEYWORDS_1364_1995, K_forever
fork, GN_KEYWORDS_1364_1995, K_fork
from, GN_KEYWORDS_VAMS_2_3, K_from
function, GN_KEYWORDS_1364_1995, K_function
generate, GN_KEYWORDS_1364_2001, K_generate
genvar, GN_KEYWORDS_1364_2001, K_genvar
ground, GN_KEYWORDS_VAMS_2_3, K_ground
highz0, GN_KEYWORDS_1364_1995, K_highz0
highz1, GN_KEYWORDS_1364_1995, K_highz1
hypot, GN_KEYWORDS_VAMS_2_3, K_hypot
idt_nature, GN_KEYWORDS_VAMS_2_3, K_idt_nature
if, GN_KEYWORDS_1364_1995, K_if
ifnone, GN_KEYWORDS_1364_1995, K_ifnone
inf, GN_KEYWORDS_VAMS_2_3, K_inf
initial, GN_KEYWORDS_1364_1995, K_initial
inout, GN_KEYWORDS_1364_1995, K_inout
input, GN_KEYWORDS_1364_1995, K_input
integer, GN_KEYWORDS_1364_1995, K_integer
join, GN_KEYWORDS_1364_1995, K_join
large, GN_KEYWORDS_1364_1995, K_large
ln, GN_KEYWORDS_VAMS_2_3, K_ln
localparam, GN_KEYWORDS_1364_2001, K_localparam
log, GN_KEYWORDS_VAMS_2_3, K_log
logic, GN_KEYWORDS_ICARUS, K_logic
macromodule, GN_KEYWORDS_1364_1995, K_macromodule
max, GN_KEYWORDS_VAMS_2_3, K_max
medium, GN_KEYWORDS_1364_1995, K_medium
min, GN_KEYWORDS_VAMS_2_3, K_min
module, GN_KEYWORDS_1364_1995, K_module
nand, GN_KEYWORDS_1364_1995, K_nand
nature, GN_KEYWORDS_VAMS_2_3, K_nature
negedge, GN_KEYWORDS_1364_1995, K_negedge
nmos, GN_KEYWORDS_1364_1995, K_nmos
nor, GN_KEYWORDS_1364_1995, K_nor
not, GN_KEYWORDS_1364_1995, K_not
notif0, GN_KEYWORDS_1364_1995, K_notif0
notif1, GN_KEYWORDS_1364_1995, K_notif1
or, GN_KEYWORDS_1364_1995, K_or
output, GN_KEYWORDS_1364_1995, K_output
parameter, GN_KEYWORDS_1364_1995, K_parameter
pmos, GN_KEYWORDS_1364_1995, K_pmos
posedge, GN_KEYWORDS_1364_1995, K_posedge
potential, GN_KEYWORDS_VAMS_2_3, K_potential
pow, GN_KEYWORDS_VAMS_2_3, K_pow
primitive, GN_KEYWORDS_1364_1995, K_primitive
pull0, GN_KEYWORDS_1364_1995, K_pull0
pull1, GN_KEYWORDS_1364_1995, K_pull1
pulldown, GN_KEYWORDS_1364_1995, K_pulldown
pullup, GN_KEYWORDS_1364_1995, K_pullup
rcmos, GN_KEYWORDS_1364_1995, K_rcmos
real, GN_KEYWORDS_1364_1995, K_real
realtime, GN_KEYWORDS_1364_1995, K_realtime
reg, GN_KEYWORDS_1364_1995, K_reg
release, GN_KEYWORDS_1364_1995, K_release
repeat, GN_KEYWORDS_1364_1995, K_repeat
rnmos, GN_KEYWORDS_1364_1995, K_rnmos
rpmos, GN_KEYWORDS_1364_1995, K_rpmos
rtran, GN_KEYWORDS_1364_1995, K_rtran
rtranif0, GN_KEYWORDS_1364_1995, K_rtranif0
rtranif1, GN_KEYWORDS_1364_1995, K_rtranif1
scalared, GN_KEYWORDS_1364_1995, K_scalared
signed, GN_KEYWORDS_1364_2001, K_signed
sin, GN_KEYWORDS_VAMS_2_3, K_sin
sinh, GN_KEYWORDS_VAMS_2_3, K_sinh
small, GN_KEYWORDS_1364_1995, K_small
specify, GN_KEYWORDS_1364_1995, K_specify
specparam, GN_KEYWORDS_1364_1995, K_specparam
sqrt, GN_KEYWORDS_VAMS_2_3, K_sqrt
string, GN_KEYWORDS_VAMS_2_3, K_string
strong0, GN_KEYWORDS_1364_1995, K_strong0
strong1, GN_KEYWORDS_1364_1995, K_strong1
supply0, GN_KEYWORDS_1364_1995, K_supply0
supply1, GN_KEYWORDS_1364_1995, K_supply1
table, GN_KEYWORDS_1364_1995, K_table
tan, GN_KEYWORDS_VAMS_2_3, K_tan
tanh, GN_KEYWORDS_VAMS_2_3, K_tanh
task, GN_KEYWORDS_1364_1995, K_task
time, GN_KEYWORDS_1364_1995, K_time
tran, GN_KEYWORDS_1364_1995, K_tran
tranif0, GN_KEYWORDS_1364_1995, K_tranif0
tranif1, GN_KEYWORDS_1364_1995, K_tranif1
tri, GN_KEYWORDS_1364_1995, K_tri
tri0, GN_KEYWORDS_1364_1995, K_tri0
tri1, GN_KEYWORDS_1364_1995, K_tri1
triand, GN_KEYWORDS_1364_1995, K_triand
trior, GN_KEYWORDS_1364_1995, K_trior
trireg, GN_KEYWORDS_1364_1995, K_trireg
units, GN_KEYWORDS_VAMS_2_3, K_units
vectored, GN_KEYWORDS_1364_1995, K_vectored
wait, GN_KEYWORDS_1364_1995, K_wait
wand, GN_KEYWORDS_1364_1995, K_wand
weak0, GN_KEYWORDS_1364_1995, K_weak0
weak1, GN_KEYWORDS_1364_1995, K_weak1
while, GN_KEYWORDS_1364_1995, K_while
wire, GN_KEYWORDS_1364_1995, K_wire
wone, GN_KEYWORDS_1364_1995, K_wone
wor, GN_KEYWORDS_1364_1995, K_wor
xnor, GN_KEYWORDS_1364_1995, K_xnor
xor, GN_KEYWORDS_1364_1995, K_xor
above, GN_KEYWORDS_VAMS_2_3, K_above
abs, GN_KEYWORDS_VAMS_2_3, K_abs
absdelay, GN_KEYWORDS_VAMS_2_3, K_absdelay
abstol, GN_KEYWORDS_VAMS_2_3, K_abstol
access, GN_KEYWORDS_VAMS_2_3, K_access
acos, GN_KEYWORDS_VAMS_2_3, K_acos
acosh, GN_KEYWORDS_VAMS_2_3, K_acosh
ac_stim, GN_KEYWORDS_VAMS_2_3, K_ac_stim
alias, GN_KEYWORDS_1800_2005, K_alias
aliasparam, GN_KEYWORDS_VAMS_2_3, K_aliasparam
always, GN_KEYWORDS_1364_1995, K_always
always_comb, GN_KEYWORDS_1800_2005, K_always_comb
always_ff, GN_KEYWORDS_1800_2005, K_always_ff
always_latch, GN_KEYWORDS_1800_2005, K_always_latch
analog, GN_KEYWORDS_VAMS_2_3, K_analog
analysis, GN_KEYWORDS_VAMS_2_3, K_analysis
and, GN_KEYWORDS_1364_1995, K_and
asin, GN_KEYWORDS_VAMS_2_3, K_asin
asinh, GN_KEYWORDS_VAMS_2_3, K_asinh
# This is defined by both SystemVerilog 1800-2005 and Verilog-AMS 2.3
assert, GN_KEYWORDS_1800_2005|GN_KEYWORDS_VAMS_2_3, K_assert
assign, GN_KEYWORDS_1364_1995, K_assign
assume, GN_KEYWORDS_1800_2005, K_assume
atan, GN_KEYWORDS_VAMS_2_3, K_atan
atan2, GN_KEYWORDS_VAMS_2_3, K_atan2
atanh, GN_KEYWORDS_VAMS_2_3, K_atanh
automatic, GN_KEYWORDS_1364_2001, K_automatic
before, GN_KEYWORDS_1800_2005, K_before
begin, GN_KEYWORDS_1364_1995, K_begin
bind, GN_KEYWORDS_1800_2005, K_bind
bins, GN_KEYWORDS_1800_2005, K_bins
binsof, GN_KEYWORDS_1800_2005, K_binsof
bit, GN_KEYWORDS_1800_2005, K_bit
branch, GN_KEYWORDS_VAMS_2_3, K_branch
break, GN_KEYWORDS_1800_2005, K_break
bool, GN_KEYWORDS_ICARUS, K_bool
buf, GN_KEYWORDS_1364_1995, K_buf
bufif0, GN_KEYWORDS_1364_1995, K_bufif0
bufif1, GN_KEYWORDS_1364_1995, K_bufif1
byte, GN_KEYWORDS_1800_2005, K_byte
case, GN_KEYWORDS_1364_1995, K_case
casex, GN_KEYWORDS_1364_1995, K_casex
casez, GN_KEYWORDS_1364_1995, K_casez
ceil, GN_KEYWORDS_VAMS_2_3, K_ceil
cell, GN_KEYWORDS_1364_2001_CONFIG, K_cell
chandle, GN_KEYWORDS_1800_2005, K_chandle
class, GN_KEYWORDS_1800_2005, K_class
clocking, GN_KEYWORDS_1800_2005, K_clocking
cmos, GN_KEYWORDS_1364_1995, K_cmos
config, GN_KEYWORDS_1364_2001_CONFIG, K_config
connect, GN_KEYWORDS_VAMS_2_3, K_connect
connectmodule, GN_KEYWORDS_VAMS_2_3, K_connectmodule
connectrules, GN_KEYWORDS_VAMS_2_3, K_connectrules
const, GN_KEYWORDS_1800_2005, K_const
constraint, GN_KEYWORDS_1800_2005, K_constraint
context, GN_KEYWORDS_1800_2005, K_context
continue, GN_KEYWORDS_1800_2005, K_continue
continuous, GN_KEYWORDS_VAMS_2_3, K_continuous
cos, GN_KEYWORDS_VAMS_2_3, K_cos
cosh, GN_KEYWORDS_VAMS_2_3, K_cosh
cover, GN_KEYWORDS_1800_2005, K_cover
covergroup, GN_KEYWORDS_1800_2005, K_covergroup
coverpoint, GN_KEYWORDS_1800_2005, K_coverpoint
cross, GN_KEYWORDS_1800_2005, K_cross
ddt, GN_KEYWORDS_VAMS_2_3, K_ddt
ddt_nature, GN_KEYWORDS_VAMS_2_3, K_ddt_nature
ddx, GN_KEYWORDS_VAMS_2_3, K_ddx
deassign, GN_KEYWORDS_1364_1995, K_deassign
default, GN_KEYWORDS_1364_1995, K_default
defparam, GN_KEYWORDS_1364_1995, K_defparam
design, GN_KEYWORDS_1364_2001_CONFIG, K_design
disable, GN_KEYWORDS_1364_1995, K_disable
discipline, GN_KEYWORDS_VAMS_2_3, K_discipline
discrete, GN_KEYWORDS_VAMS_2_3, K_discrete
dist, GN_KEYWORDS_1800_2005, K_dist
do, GN_KEYWORDS_1800_2005, K_do
domain, GN_KEYWORDS_VAMS_2_3, K_domain
driver_update, GN_KEYWORDS_VAMS_2_3, K_driver_update
edge, GN_KEYWORDS_1364_1995, K_edge
else, GN_KEYWORDS_1364_1995, K_else
end, GN_KEYWORDS_1364_1995, K_end
endcase, GN_KEYWORDS_1364_1995, K_endcase
endconfig, GN_KEYWORDS_1364_2001_CONFIG, K_endconfig
endclass, GN_KEYWORDS_1800_2005, K_endclass
endclocking, GN_KEYWORDS_1800_2005, K_endclocking
endconnectrules, GN_KEYWORDS_VAMS_2_3, K_endconnectrules
enddiscipline, GN_KEYWORDS_VAMS_2_3, K_enddiscipline
endfunction, GN_KEYWORDS_1364_1995, K_endfunction
endgenerate, GN_KEYWORDS_1364_2001, K_endgenerate
endgroup, GN_KEYWORDS_1800_2005, K_endgroup
endinterface, GN_KEYWORDS_1800_2005, K_endinterface
endmodule, GN_KEYWORDS_1364_1995, K_endmodule
endnature, GN_KEYWORDS_VAMS_2_3, K_endnature
endpackage, GN_KEYWORDS_1800_2005, K_endpackage
endparamset, GN_KEYWORDS_VAMS_2_3, K_endparamset
endprimitive, GN_KEYWORDS_1364_1995, K_endprimitive
endprogram, GN_KEYWORDS_1800_2005, K_endprogram
endproperty, GN_KEYWORDS_1800_2005, K_endproperty
endspecify, GN_KEYWORDS_1364_1995, K_endspecify
endsequence, GN_KEYWORDS_1800_2005, K_endsequence
endtable, GN_KEYWORDS_1364_1995, K_endtable
endtask, GN_KEYWORDS_1364_1995, K_endtask
enum, GN_KEYWORDS_1800_2005, K_enum
event, GN_KEYWORDS_1364_1995, K_event
exclude, GN_KEYWORDS_VAMS_2_3, K_exclude
exp, GN_KEYWORDS_VAMS_2_3, K_exp
expect, GN_KEYWORDS_1800_2005, K_expect
export, GN_KEYWORDS_1800_2005, K_export
extends, GN_KEYWORDS_1800_2005, K_extends
extern, GN_KEYWORDS_1800_2005, K_extern
final, GN_KEYWORDS_1800_2005, K_final
final_step, GN_KEYWORDS_VAMS_2_3, K_final_step
first_match, GN_KEYWORDS_1800_2005, K_first_match
flicker_noise, GN_KEYWORDS_VAMS_2_3, K_flicker_noise
floor, GN_KEYWORDS_VAMS_2_3, K_floor
flow, GN_KEYWORDS_VAMS_2_3, K_flow
for, GN_KEYWORDS_1364_1995, K_for
foreach, GN_KEYWORDS_1800_2005, K_foreach
force, GN_KEYWORDS_1364_1995, K_force
forever, GN_KEYWORDS_1364_1995, K_forever
fork, GN_KEYWORDS_1364_1995, K_fork
forkjoin, GN_KEYWORDS_1800_2005, K_forkjoin
from, GN_KEYWORDS_VAMS_2_3, K_from
function, GN_KEYWORDS_1364_1995, K_function
generate, GN_KEYWORDS_1364_2001, K_generate
genvar, GN_KEYWORDS_1364_2001, K_genvar
ground, GN_KEYWORDS_VAMS_2_3, K_ground
highz0, GN_KEYWORDS_1364_1995, K_highz0
highz1, GN_KEYWORDS_1364_1995, K_highz1
hypot, GN_KEYWORDS_VAMS_2_3, K_hypot
idt, GN_KEYWORDS_VAMS_2_3, K_idt
idtmod, GN_KEYWORDS_VAMS_2_3, K_idtmod
idt_nature, GN_KEYWORDS_VAMS_2_3, K_idt_nature
if, GN_KEYWORDS_1364_1995, K_if
iff, GN_KEYWORDS_1800_2005, K_iff
ifnone, GN_KEYWORDS_1364_1995, K_ifnone
ignore_bins, GN_KEYWORDS_1800_2005, K_ignore_bins
illegal_bins, GN_KEYWORDS_1800_2005, K_illegal_bins
import, GN_KEYWORDS_1800_2005, K_import
incdir, GN_KEYWORDS_1364_2001_CONFIG, K_incdir
include, GN_KEYWORDS_1364_2001_CONFIG, K_include
inf, GN_KEYWORDS_VAMS_2_3, K_inf
initial, GN_KEYWORDS_1364_1995, K_initial
initial_step, GN_KEYWORDS_VAMS_2_3, K_initial_step
inout, GN_KEYWORDS_1364_1995, K_inout
input, GN_KEYWORDS_1364_1995, K_input
inside, GN_KEYWORDS_1800_2005, K_inside
instance, GN_KEYWORDS_1364_2001_CONFIG, K_instance
int, GN_KEYWORDS_1800_2005, K_int
integer, GN_KEYWORDS_1364_1995, K_integer
interface, GN_KEYWORDS_1800_2005, K_interface
intersect, GN_KEYWORDS_1800_2005, K_intersect
join, GN_KEYWORDS_1364_1995, K_join
join_any, GN_KEYWORDS_1800_2005, K_join_any
join_none, GN_KEYWORDS_1800_2005, K_join_none
laplace_nd, GN_KEYWORDS_VAMS_2_3, K_laplace_nd
laplace_np, GN_KEYWORDS_VAMS_2_3, K_laplace_np
laplace_zd, GN_KEYWORDS_VAMS_2_3, K_laplace_zd
laplace_zp, GN_KEYWORDS_VAMS_2_3, K_laplace_zp
large, GN_KEYWORDS_1364_1995, K_large
last_crossing, GN_KEYWORDS_VAMS_2_3, K_last_crossing
liblist, GN_KEYWORDS_1364_2001_CONFIG, K_liblist
library, GN_KEYWORDS_1364_2001_CONFIG, K_library
limexp, GN_KEYWORDS_VAMS_2_3, K_limexp
ln, GN_KEYWORDS_VAMS_2_3, K_ln
local, GN_KEYWORDS_1800_2005, K_local
localparam, GN_KEYWORDS_1364_2001, K_localparam
log, GN_KEYWORDS_VAMS_2_3, K_log
# This is defined by SystemVerilog 1800-2005 and as an Icarus extension.
logic, GN_KEYWORDS_1800_2005|GN_KEYWORDS_ICARUS, K_logic
longint, GN_KEYWORDS_1800_2005, K_longint
macromodule, GN_KEYWORDS_1364_1995, K_macromodule
matches, GN_KEYWORDS_1800_2005, K_matches
max, GN_KEYWORDS_VAMS_2_3, K_max
medium, GN_KEYWORDS_1364_1995, K_medium
merged, GN_KEYWORDS_VAMS_2_3, K_merged
min, GN_KEYWORDS_VAMS_2_3, K_min
modport, GN_KEYWORDS_1800_2005, K_modport
module, GN_KEYWORDS_1364_1995, K_module
nand, GN_KEYWORDS_1364_1995, K_nand
nature, GN_KEYWORDS_VAMS_2_3, K_nature
negedge, GN_KEYWORDS_1364_1995, K_negedge
net_resolution, GN_KEYWORDS_VAMS_2_3, K_net_resolution
new, GN_KEYWORDS_1800_2005, K_new
nmos, GN_KEYWORDS_1364_1995, K_nmos
noise_table, GN_KEYWORDS_VAMS_2_3, K_noise_table
nor, GN_KEYWORDS_1364_1995, K_nor
noshowcancelled, GN_KEYWORDS_1364_2001, K_noshowcancelled
not, GN_KEYWORDS_1364_1995, K_not
notif0, GN_KEYWORDS_1364_1995, K_notif0
notif1, GN_KEYWORDS_1364_1995, K_notif1
null, GN_KEYWORDS_1800_2005, K_null
or, GN_KEYWORDS_1364_1995, K_or
output, GN_KEYWORDS_1364_1995, K_output
package, GN_KEYWORDS_1800_2005, K_package
packed, GN_KEYWORDS_1800_2005, K_packed
parameter, GN_KEYWORDS_1364_1995, K_parameter
paramset, GN_KEYWORDS_VAMS_2_3, K_paramset
pmos, GN_KEYWORDS_1364_1995, K_pmos
posedge, GN_KEYWORDS_1364_1995, K_posedge
potential, GN_KEYWORDS_VAMS_2_3, K_potential
pow, GN_KEYWORDS_VAMS_2_3, K_pow
primitive, GN_KEYWORDS_1364_1995, K_primitive
priority, GN_KEYWORDS_1800_2005, K_priority
program, GN_KEYWORDS_1800_2005, K_program
property, GN_KEYWORDS_1800_2005, K_property
protected, GN_KEYWORDS_1800_2005, K_protected
pull0, GN_KEYWORDS_1364_1995, K_pull0
pull1, GN_KEYWORDS_1364_1995, K_pull1
pulldown, GN_KEYWORDS_1364_1995, K_pulldown
pullup, GN_KEYWORDS_1364_1995, K_pullup
pulsestyle_onevent, GN_KEYWORDS_1364_2001, K_pulsestyle_onevent
pulsestyle_ondetect, GN_KEYWORDS_1364_2001, K_pulsestyle_ondetect
pure, GN_KEYWORDS_1800_2005, K_pure
rand, GN_KEYWORDS_1800_2005, K_rand
randc, GN_KEYWORDS_1800_2005, K_randc
randcase, GN_KEYWORDS_1800_2005, K_randcase
randsequence, GN_KEYWORDS_1800_2005, K_randsequence
rcmos, GN_KEYWORDS_1364_1995, K_rcmos
real, GN_KEYWORDS_1364_1995, K_real
realtime, GN_KEYWORDS_1364_1995, K_realtime
ref, GN_KEYWORDS_1800_2005, K_ref
reg, GN_KEYWORDS_1364_1995, K_reg
release, GN_KEYWORDS_1364_1995, K_release
repeat, GN_KEYWORDS_1364_1995, K_repeat
resolveto, GN_KEYWORDS_VAMS_2_3, K_resolveto
return, GN_KEYWORDS_1800_2005, K_return
rnmos, GN_KEYWORDS_1364_1995, K_rnmos
rpmos, GN_KEYWORDS_1364_1995, K_rpmos
rtran, GN_KEYWORDS_1364_1995, K_rtran
rtranif0, GN_KEYWORDS_1364_1995, K_rtranif0
rtranif1, GN_KEYWORDS_1364_1995, K_rtranif1
scalared, GN_KEYWORDS_1364_1995, K_scalared
sequence, GN_KEYWORDS_1800_2005, K_sequence
shortint, GN_KEYWORDS_1800_2005, K_shortint
shortreal, GN_KEYWORDS_1800_2005, K_shortreal
showcancelled, GN_KEYWORDS_1364_2001, K_showcancelled
signed, GN_KEYWORDS_1364_2001, K_signed
sin, GN_KEYWORDS_VAMS_2_3, K_sin
sinh, GN_KEYWORDS_VAMS_2_3, K_sinh
slew, GN_KEYWORDS_VAMS_2_3, K_slew
small, GN_KEYWORDS_1364_1995, K_small
solve, GN_KEYWORDS_1800_2005, K_solve
specify, GN_KEYWORDS_1364_1995, K_specify
specparam, GN_KEYWORDS_1364_1995, K_specparam
split, GN_KEYWORDS_VAMS_2_3, K_split
sqrt, GN_KEYWORDS_VAMS_2_3, K_sqrt
static, GN_KEYWORDS_1800_2005, K_static
# This is defined by both SystemVerilog 1800-2005 and Verilog-AMS 2.3
string, GN_KEYWORDS_1800_2005|GN_KEYWORDS_VAMS_2_3, K_string
strong0, GN_KEYWORDS_1364_1995, K_strong0
strong1, GN_KEYWORDS_1364_1995, K_strong1
struct, GN_KEYWORDS_1800_2005, K_struct
super, GN_KEYWORDS_1800_2005, K_super
supply0, GN_KEYWORDS_1364_1995, K_supply0
supply1, GN_KEYWORDS_1364_1995, K_supply1
table, GN_KEYWORDS_1364_1995, K_table
tagged, GN_KEYWORDS_1800_2005, K_tagged
tan, GN_KEYWORDS_VAMS_2_3, K_tan
tanh, GN_KEYWORDS_VAMS_2_3, K_tanh
task, GN_KEYWORDS_1364_1995, K_task
this, GN_KEYWORDS_1800_2005, K_this
throughout, GN_KEYWORDS_1800_2005, K_throughout
time, GN_KEYWORDS_1364_1995, K_time
timeprecision, GN_KEYWORDS_1800_2005, K_timeprecision
timer, GN_KEYWORDS_VAMS_2_3, K_timer
timeunit, GN_KEYWORDS_1800_2005, K_timeunit
tran, GN_KEYWORDS_1364_1995, K_tran
tranif0, GN_KEYWORDS_1364_1995, K_tranif0
tranif1, GN_KEYWORDS_1364_1995, K_tranif1
transition, GN_KEYWORDS_VAMS_2_3, K_transition
tri, GN_KEYWORDS_1364_1995, K_tri
tri0, GN_KEYWORDS_1364_1995, K_tri0
tri1, GN_KEYWORDS_1364_1995, K_tri1
triand, GN_KEYWORDS_1364_1995, K_triand
trior, GN_KEYWORDS_1364_1995, K_trior
trireg, GN_KEYWORDS_1364_1995, K_trireg
type, GN_KEYWORDS_1800_2005, K_type
typedef, GN_KEYWORDS_1800_2005, K_typedef
union, GN_KEYWORDS_1800_2005, K_union
unique, GN_KEYWORDS_1800_2005, K_unique
units, GN_KEYWORDS_VAMS_2_3, K_units
# Reserved for future use!
unsigned, GN_KEYWORDS_1364_2001, K_unsigned
use, GN_KEYWORDS_1364_2001_CONFIG, K_use
uwire, GN_KEYWORDS_1364_2005, K_uwire
var, GN_KEYWORDS_1800_2005, K_var
vectored, GN_KEYWORDS_1364_1995, K_vectored
virtual, GN_KEYWORDS_1800_2005, K_virtual
void, GN_KEYWORDS_1800_2005, K_void
wait, GN_KEYWORDS_1364_1995, K_wait
wait_order, GN_KEYWORDS_1800_2005, K_wait_order
wand, GN_KEYWORDS_1364_1995, K_wand
weak0, GN_KEYWORDS_1364_1995, K_weak0
weak1, GN_KEYWORDS_1364_1995, K_weak1
while, GN_KEYWORDS_1364_1995, K_while
white_noise, GN_KEYWORDS_VAMS_2_3, K_white_noise
wildcard, GN_KEYWORDS_1800_2005, K_wildcard
wire, GN_KEYWORDS_1364_1995, K_wire
with, GN_KEYWORDS_1800_2005, K_with
within, GN_KEYWORDS_1800_2005, K_within
# This is the name originally proposed for uwire and is deprecated!
wone, GN_KEYWORDS_1364_2005, K_wone
wor, GN_KEYWORDS_1364_1995, K_wor
wreal, GN_KEYWORDS_VAMS_2_3, K_wreal
xnor, GN_KEYWORDS_1364_1995, K_xnor
xor, GN_KEYWORDS_1364_1995, K_xor
zi_nd, GN_KEYWORDS_VAMS_2_3, K_zi_nd
zi_np, GN_KEYWORDS_VAMS_2_3, K_zi_np
zi_zd, GN_KEYWORDS_VAMS_2_3, K_zi_zd
zi_zp, GN_KEYWORDS_VAMS_2_3, K_zi_zp
%%
int lexor_keyword_mask = 0;

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