Compare commits

...

239 Commits

Author SHA1 Message Date
Stephen Williams a08de693d4 Step to the 0.9.2 release.
Advance version stamps.
2009-12-30 08:45:06 -08:00
Stephen Williams 37837f3904 Fix references to version_base.h in Makefiles.
(cherry picked from commit d2dd0daa3c)
2009-12-28 09:50:34 -08:00
Cary R daa01a05d8 A constant real number is not unsized.
We can have unsized bit values, but reals always have a size.
(cherry picked from commit ebac088511)
2009-12-28 09:34:57 -08:00
Cary R 9cd7a22dbe Having lround() does not mean llround() is available.
We need to check for both lround() and llround() for at
least Cygwin.
(cherry picked from commit a1e2bfc93c)
2009-12-25 18:16:52 -05:00
Martin Whitaker f733030b41 Add warning about casting large integer values to reals.
The compiler and vvp runtime don't correctly handle casts to reals
when the source value is more than 63 bits in magnitude. This is
fixed in devel, but can't be backported to v0.9 because it adds new
vvp instructions. This patch causes the compiler to output a warning
about potentiall incorrect results.
2009-12-25 17:53:08 -05:00
Martin Whitaker 99f7d1197c Make vvp thread word storage consistently 64 bits (backport to v0.9).
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-25 17:51:56 -05:00
Cary R 7817e479a4 V0.9 - 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-25 11:53:36 -05:00
Cary R 0c97cabe18 Use the correct line information in crop_to_width()
This was using its own information instead of the input nets information.
2009-12-25 11:37:50 -05:00
Cary R e56c142dff Reuse the number of input information.
This was already assigned to a variable so lets use that instead of
geting it again.
2009-12-25 11:37:35 -05:00
Cary R 7e06a87b8e 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-25 11:37:16 -05:00
Cary R 0c3eef4c41 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-25 11:33:12 -05:00
Cary R 3b22be5507 A ternary can be signed.
If the two branches of a ternary are signed then the result will
also be signed.
2009-12-25 11:28:03 -05:00
Nick Gasson 287b19f22d VHDL: fix spurious resize seen in pr2911213
Another case when ivl_scope_sig list was used instead of
ivl_scope_param.
2009-12-25 11:26:46 -05:00
Cary R 8de7fc6161 Add suffix support to MinGW.
This patch adds suffix support to the relative path that MinGW
calculates in both the iverilog and vvp executables.
2009-12-25 11:22:25 -05:00
Cary R 663ab34ae7 V0.9 Add casts/etc. in vvp directory to remove Cygwin compile warnings. 2009-12-15 07:29:06 -08:00
Cary R b5c819051b Fix out of bounds select warning text in man page.
(cherry picked from commit 8144283b0d)
2009-12-15 07:26:12 -08:00
Cary R fdbc212349 Fixe .cast documentation.
(cherry picked from commit a228d53cc2)
2009-12-15 07:24:42 -08:00
Nick Gasson d35d542b9e 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.
(cherry picked from commit 9c568d8f47)
2009-12-15 07:22:26 -08:00
Cary R 8139551908 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.
(cherry picked from commit 1a25b3deda)
2009-12-12 08:36:02 -08:00
Nick Gasson 021ae6c08f 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.
(cherry picked from commit a9c85cf5b6)
2009-12-12 08:34:47 -08:00
Cary R b8b1bc4a36 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.
(cherry picked from commit 6ae1f64c3c)
2009-12-12 08:31:31 -08:00
Cary R 327cdc77a3 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.
(cherry picked from commit 3f12a401eb)
2009-12-12 08:31:15 -08:00
Cary R a8e1643ae9 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.
(cherry picked from commit f31a4e6d20)
2009-12-12 08:30:40 -08:00
Cary R 02a986b35d 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.
(cherry picked from commit 81d4cbc4bd)
2009-12-12 08:26:55 -08:00
Cary R 8759eaf720 Remove extra MinGW only varaible in t-dll.cc.
(cherry picked from commit 1f375ef16a)
2009-12-12 08:26:34 -08:00
Cary R daff9ed30d 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.
(cherry picked from commit 05a3929b1a)
2009-12-12 08:26:09 -08:00
Martin Whitaker e4a319cfe2 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.
(cherry picked from commit e2be397aa8)
2009-12-12 08:22:09 -08:00
Cary R 3d5c6c6f30 Remove unused MinGW variable.
There was an unused variable in driver/main.c under MinGW.
(cherry picked from commit 392ac1200c)
2009-12-11 09:25:07 -08:00
Cary R c44ce66a87 Add debug_eval_tree code for the pow operator.
The power operator was missing eval_tree debug information.
This patch fixes that deficiency.
(cherry picked from commit a85880a8bb)
2009-12-09 19:10:12 -08:00
Cary R ce8a84db3c 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 '/').
(cherry picked from commit e9c653dfa3)
2009-12-09 19:08:59 -08:00
Martin Whitaker 33c852d2b4 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.
(cherry picked from commit c7b0aef414)
2009-12-09 19:05:26 -08:00
Cary R 1eb593e8ad 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.
(cherry picked from commit eea816e423)
2009-12-09 19:02:28 -08:00
Cary R 8ef7344ea5 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().
(cherry picked from commit 59ebd47ba6)
2009-12-09 19:00:53 -08:00
Stephen Williams 5479aaf721 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.
2009-12-04 15:20:03 -08:00
Stephen Williams b85b2d8a26 More portable use of tail.
Apparently, tail +2 is not portable, but tail -n +2 should work.
2009-12-04 14:57:36 -08:00
Cary R 8b7ffa1a17 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.
(cherry picked from commit b6f7354cee)
2009-12-03 08:21:12 -08:00
Cary R 9b6e9f5832 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.
(cherry picked from commit dba2a6e434)
2009-12-03 08:19:32 -08:00
Cary R ab926ccee4 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.
(cherry picked from commit f44c1cadde)
2009-12-03 08:18:20 -08:00
Cary R 3351004945 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-03 08:15:24 -08:00
Cary R 7684814593 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.
(cherry picked from commit 145133bdb0)
2009-12-03 08:08:41 -08:00
Stephen Williams 3f29f96695 Fix delays in continuous assignment to support 64bit delays.
Remove the 32bit restriction on a few cases of delays in continuous
assignment expressions.
(cherry picked from commit de1f17d429)
2009-12-01 10:21:57 -08:00
Stephen Williams 7210061f2c 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.
(cherry picked from commit 2e60a181c0)
2009-12-01 07:40:48 -08:00
Cary R 2396faac39 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.
(cherry picked from commit dd425e8945)
2009-12-01 07:40:13 -08:00
Cary R c7126c3c1f 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.
(cherry picked from commit 6909737bf2)
2009-12-01 07:38:11 -08:00
Cary R 14bc857c54 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.
(cherry picked from commit 8abe0d7d71)
2009-12-01 07:37:58 -08:00
Stephen Williams f49f3f56cf Make version.exe so that subdirs can get access to it.
(cherry picked from commit 342ec152bc)
2009-12-01 07:37:33 -08:00
Cary R c89ae29bf2 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.
(cherry picked from commit 74634864cf)
2009-12-01 07:34:19 -08:00
Stephen Williams d570437a17 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.
(cherry picked from commit 966e29db3b)

Conflicts:

	driver/iverilog.man.in
	iverilog-vpi.man.in
	version_base.in
	vpi/vams_simparam.c
	vvp/vvp.man.in
2009-11-27 12:37:11 -08:00
Stephen Williams 0cc8285a01 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.
(cherry picked from commit f07577db11)
2009-11-25 07:50:35 -08:00
Stephen Williams d090fd7a17 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.
(cherry picked from commit 711365521d)
2009-11-05 06:41:51 -08:00
Cary R 09cdf5268e 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:47:12 -08:00
Martin Whitaker c1f750ff98 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.
(cherry picked from commit 9950704735)
2009-11-01 11:09:07 -08:00
Cary R c7414f79b0 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.
(cherry picked from commit a5060b8adc)
2009-11-01 11:02:15 -08:00
Cary R 95eec69102 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.
(cherry picked from commit ae49197a14)
2009-11-01 11:00:53 -08:00
Stephen Williams 23ea74a126 Implement cbAtStartOfSimTime callback.
(cherry picked from commit 1b7a42ffcd)
2009-11-01 10:53:13 -08:00
Stephen Williams 70f15b472f 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.
(cherry picked from commit 5fb89262df)
2009-11-01 10:52:43 -08:00
Cary R 73d9a37020 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.
(cherry picked from commit cf2f99ec3d)
2009-10-29 10:55:20 -07:00
Cary R 13921f0c0c 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.
(cherry picked from commit 83aa1363ea)
2009-10-29 10:54:12 -07:00
Cary R 29f5c882eb Add support for ${var} substitutions in the command file.
We still support $(var).

(cherry picked from commit 4cb39f584d)

Conflicts:

	driver/iverilog.man
2009-10-29 10:52:25 -07:00
Stephen Williams 98c3391acb 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.
(cherry picked from commit 37b11e0355)
2009-10-28 19:20:00 -07:00
Stephen Williams f5728c4a39 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.
(cherry picked from commit 33158355ba)

Conflicts:

	tgt-vvp/draw_net_input.c
	vvp/island_tran.cc
2009-10-28 16:32:40 -07:00
Cary R cca3b0ed5a V0.9: 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:16:50 -07:00
Cary R 391ef78d42 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.
(cherry picked from commit 1f0857606a)
2009-10-26 11:14:19 -07:00
Jared Casper ab5b9271f3 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
(cherry picked from commit c167b3a01f)
2009-10-26 11:12:04 -07:00
Jared Casper 7eb4825435 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'
(cherry picked from commit 7ead2aa88b)
2009-10-20 10:04:01 -07:00
Cary R 58511ab212 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.

(Cherry picked from dec524a151)
2009-10-20 10:00:05 -07:00
Cary R b3ca7e1774 Update the simulator subversion. 2009-10-20 09:51:14 -07:00
Jared Casper 5e8e59484b 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.
(cherry picked from commit d098db0a06)
2009-10-19 07:57:55 -07:00
Stephen Williams 517b4e3248 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.
(cherry picked from commit 6b17dcc587)
2009-10-14 10:14:37 -07:00
Cary R a6fdb4b6e6 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.
(cherry picked from commit 02ca7fe7fc)
2009-10-14 10:11:06 -07:00
Cary R ad786a2aa3 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.
(cherry picked from commit 8abf303753)
2009-10-14 10:05:20 -07:00
Cary R e92c4638ed $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.
(cherry picked from commit bc60536eb9)
2009-10-14 10:02:20 -07:00
Cary R fd4b849091 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.
(cherry picked from commit d9d8d4b093)
2009-10-14 09:59:39 -07:00
Cary R 98e5e36f03 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.
(cherry picked from commit ff39575dc0)
2009-10-14 09:57:44 -07:00
Cary R 1a0d475907 Fix obscure valgrind memory leak.
(cherry picked from commit 3303cc144f)
2009-10-14 09:55:57 -07:00
Cary R 807a66f0a2 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).
(cherry picked from commit 39f243b18e)
2009-10-08 16:43:02 -07:00
Cary R 92e7587320 Format the --enable-suffix help correctly.
(cherry picked from commit 537ba93fe4)
2009-10-08 11:42:31 -07:00
Stephen Williams 04be3a6323 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.
(cherry picked from commit abc4eb9d52)
2009-10-06 07:20:44 -07:00
Cary R d2a900d187 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.
(cherry picked from commit 9ea6604439)
2009-10-03 09:01:44 -07:00
Cary R eb9d79ec61 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.
(cherry picked from commit ed7e9f8be5)
2009-10-01 12:01:11 -07:00
Cary R e8dada7337 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.
(cherry picked from commit 3259354d29)
2009-10-01 12:00:39 -07:00
Cary R 3dfc1d5097 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<>.
(cherry picked from commit 4b50473939)
2009-09-24 16:06:21 -07:00
Cary R 6bbf97a05d 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.
(cherry picked from commit e1af002a32)
2009-09-24 13:44:22 -07:00
Cary R e7815c3984 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.
(cherry picked from commit 09fa57742a)
2009-09-24 13:32:57 -07:00
Cary R fb01245501 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.
(cherry picked from commit c82baa2793)
2009-09-24 13:29:50 -07:00
Cary R d0a45ffe9d 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.
(cherry picked from commit 1851cba955)
2009-09-24 12:16:54 -07:00
Stephen Williams 9c624a2403 Better portability for rpm install section.
(cherry picked from commit d3d84dde6a)
2009-09-23 15:56:16 -07:00
Stephen Williams 4d4a693248 Improve some assert messages
Replace some assert functions with ivl_assert.
2009-09-16 14:45:55 -07:00
Cary R 1872652019 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.
(cherry picked from commit 0b6bd343e8)
2009-09-15 20:51:11 -07:00
Cary R d68fea3f58 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.
(cherry picked from commit 4d57ede0e5)
2009-09-15 20:45:49 -07:00
Cary R b0e2185ade 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.
(cherry picked from commit 43f41572cb)
2009-09-15 20:40:14 -07:00
Cary R 6aaf2f84a8 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.
(cherry picked from commit 6d5d06cae4)
2009-09-15 20:38:57 -07:00
Cary R 7ad50f4454 Revert one change from previous patch.
I was mistaken in changing the cast in the comparison.
(cherry picked from commit 5a11a8a9c2)
2009-09-15 20:35:48 -07:00
Cary R 19b0d5b7c9 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.
(cherry picked from commit 1b300cb2f6)
2009-09-15 20:35:35 -07:00
Cary R ae87aff745 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.
(cherry picked from commit 27f032760e)
2009-09-15 20:35:24 -07:00
Cary R 9c09394785 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.
(cherry picked from commit 1b0dd8c8e5)
2009-09-13 08:38:08 -07:00
Cary R 3f8f81568a 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.
(cherry picked from commit dff6a1ebff)
2009-09-13 08:34:59 -07:00
Martin Whitaker bb5d30ead5 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.
(cherry picked from commit fc49420cb5)
2009-09-13 08:27:54 -07:00
Nick Gasson 4e77abca44 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.
(cherry picked from commit face1a1d15)
2009-09-03 18:16:47 -07:00
Nick Gasson 902ae19bbf 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.
(cherry picked from commit 388c9c6747)
2009-09-03 18:16:35 -07:00
Nick Gasson 5587e42e2e Translate simple generate loops to VHDL
This handles generate loops and genvars with no local variables
(cherry picked from commit bc7ec04cab)
2009-09-03 18:16:18 -07:00
Cary R f8f363a0b6 Remove old configure files in vvp directory.
(cherry picked from commit 5f08f40cad)
2009-09-03 18:15:23 -07:00
Cary R f34485d415 Support negative index for %assign/av opcodes.
If the array index is negative these opcodes need to just return.
(cherry picked from commit 9d765820bf)
2009-09-03 18:12:40 -07:00
Cary R df177e9e14 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.
(cherry picked from commit 2b17366ad5)
2009-09-03 18:07:51 -07:00
Cary R 5d4c8d616a Propagate sign in synthesize for math operators.
The sign of the expression needs to be propagated for the
math operators when they are synthesized.
(cherry picked from commit a49463e728)
2009-09-03 18:02:40 -07:00
Cary R 72c02a8285 Pass file/line information for part selects.
Propagate the file and line information for a part select
expression and LPM (continuous assign).
(cherry picked from commit 06997c63ed)
2009-09-03 18:02:24 -07:00
Cary R 043c86ba02 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.
(cherry picked from commit ecb00017cb)
2009-09-03 18:02:02 -07:00
Cary R b9d0783ad9 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.
(cherry picked from commit d108221fef)
2009-09-03 18:01:43 -07:00
Cary R 047ee137ed 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.
(cherry picked from commit 1306a6db81)
2009-09-03 18:01:27 -07:00
Cary R ef814a9ef4 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.

Cherry-picked from e576e1eb2c
2009-09-03 18:00:31 -07:00
Cary R fa0ecb3761 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.
(cherry picked from commit 4cd790a2d2)
2009-09-03 17:52:35 -07:00
Cary R f2a81cf660 Fix subtle bug in scope checking.
This check looks to be defined to check the child scope not the
top level scope.
(cherry picked from commit 872962ef18)
2009-09-03 17:49:18 -07:00
Cary R e1b4d531a1 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.
(cherry picked from commit 9669ccd011)
2009-09-03 17:48:17 -07:00
Cary R a418995988 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.
(cherry picked from commit a51f2dca50)
2009-09-03 17:46:53 -07:00
Cary R 8c36e20fd4 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.
(cherry picked from commit 8623f804f2)
2009-09-03 17:40:01 -07:00
Cary R 2c982a6edb Add missing limits.h include in vpi_signal.cc
(cherry picked from commit 83c7a24cff)
2009-09-03 17:37:52 -07:00
Cary R a298bfb22a 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.
(cherry picked from commit e31b6bd20c)
2009-09-03 17:35:16 -07:00
Cary R cce61d7134 Ignore a zero MCD for $fflush, $fdisplay*, $fwrite* and $fstrobe*.
(cherry picked from commit ed4e2eb046)
2009-09-03 17:30:12 -07:00
Martin Whitaker aad5443a36 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.
(cherry picked from commit da010db739)
2009-09-03 17:24:45 -07:00
Martin Whitaker f5f104f8a6 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.
(cherry picked from commit 7c6176357f)
2009-08-18 17:33:30 -07:00
Cary R b7ff68c3f4 Fix a few more minor memory leaks.
This patch fixes a few more memory leaks that can happen under
error conditions.
(cherry picked from commit 35f3d7f60e)
2009-08-18 15:00:12 -07:00
Cary R 69986a5bc7 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.
(cherry picked from commit 2e820ca6f0)
2009-08-18 14:56:14 -07:00
Cary R c0f4b0374a 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).
(cherry picked from commit 88b18d4212)
2009-08-18 14:52:35 -07:00
Cary R 817b1ef3d4 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.
(cherry picked from commit cb5c4299fb)
2009-08-18 14:48:30 -07:00
Cary R f9774758a3 UDPs can only take two delay values.
Check in the compiler that a UDP is only given two delay values.
(cherry picked from commit 7916e148f8)
2009-08-18 14:45:31 -07:00
Cary R eb2fed7015 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.
(cherry picked from commit 2e166b7279)
2009-08-18 14:36:32 -07:00
Stephen Williams 5af47cda12 Fix man page formatting for portability. 2009-08-10 06:34:18 -07:00
Cary R 0aad444bbf 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).
(cherry picked from commit ce89a68735)
2009-08-02 11:07:23 -07:00
Cary R e63c75d1a3 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.
(cherry picked from commit b0ac550791)
2009-08-02 11:04:24 -07:00
Cary R a5b0872016 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.
(cherry picked from commit 52fbb3f734)
2009-08-02 11:01:31 -07:00
Cary R f6b9db1c78 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.
(cherry picked from commit 72a98e85cb)
2009-07-29 08:56:01 -07:00
Martin Whitaker 597097eaef 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.
(cherry picked from commit d7fe9c613c)
2009-07-29 08:52:50 -07:00
Martin Whitaker 47512e351f 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.
(cherry picked from commit 1453c5b0bb)
2009-07-29 08:50:28 -07:00
Cary R 506c09f5f8 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.
(cherry picked from commit e98000426e)
2009-07-29 08:47:25 -07:00
Cary R 693fb93962 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.
(cherry picked from commit b629d913d2)
2009-07-29 08:44:15 -07:00
Cary R 8ca5926db9 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).
(cherry picked from commit e362a86b16)
2009-07-29 08:44:05 -07:00
Cary R 7acafd128f 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.
(cherry picked from commit c5ee1fdbf5)
2009-07-29 08:40:47 -07:00
Cary R d0a12f5b14 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.
(cherry picked from commit e932c41587)
2009-07-29 08:37:59 -07:00
Cary R 8964a175f8 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.
(cherry picked from commit 212bd4134a)
2009-07-29 08:34:49 -07:00
Cary R 97d70f9069 base if for ivl pbase is for ivlpp 2009-07-29 08:31:43 -07:00
Cary R 0dc0fbf78d Add check for prec > unit in `timescale directive. 2009-07-29 08:28:14 -07:00
Cary R 786b3a0ca9 Real constants are always signed.
Set the signed_flag_ for real constants.
2009-07-29 08:21:36 -07:00
Cary R 24a60ce6af 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-06 15:08:56 -07:00
Cary R 4c640f67cb 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-06 15:06:15 -07:00
Cary R cfe68fe6b4 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-06 15:06:02 -07:00
Cary R 78149e9d15 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-06 15:01:23 -07:00
Cary R bbe037bf9f 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-23 09:53:31 -07:00
Cary R d3bf6be7b2 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-23 09:50:13 -07:00
Cary R 6146a98278 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-23 09:43:22 -07:00
Cary R 63c7285113 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-23 09:37:41 -07:00
Cary R 79e0203280 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-23 09:31:18 -07:00
Cary R ad419dfbe4 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-23 09:25:21 -07:00
Cary R 75d71fe312 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-23 09:14:03 -07:00
Cary R 5a30355faf Ignore specify pulsestyle_* and *showcancelled directives.
This patch adds code to silently ignore the specify directives:
  pulsestyle_onevent
  pulsestyle_ondetect
  showcancelled
  noshowcancelled.
2009-06-08 11:12:04 -07:00
Cary R 623e897e55 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-08 11:09:10 -07:00
Cary R 0bb6360ac7 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-08 11:06:43 -07:00
Cary R 4b850e1e74 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-08 09:45:25 -07:00
Cary R 8ce807a263 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-08 09:26:54 -07:00
Cary R cc9524bd89 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-08 09:20:27 -07:00
nog 13e07d6b7c 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-08 08:51:31 -07:00
Cary R bbf11b830b 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-08 08:42:12 -07:00
Cary R d345fb7654 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-08 08:25:21 -07:00
Cary R 3186e3dc54 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 21:45:31 -07:00
Cary R d4d50fd97d Use strchr() instead of index().
strchr() is more portable and index() is not available under
MinGW so replace index() with strchr().
2009-06-07 21:30:42 -07:00
Cary R 3337c9d51a 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-24 10:36:33 -07:00
Cary R dfda202f14 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-24 10:34:06 -07:00
Cary R 5ca440dc1c 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-24 10:28:42 -07:00
Cary R 96908e2fc5 Add compiler support for `celldefine, vpiCellInstance
This patch adds support to the compiler and stub backend for
`celldefine. This matches the compiler portion of the full
support that was added to 0.10.devel. This does not change
vvp or the vvp interface since changing the interface is not
allowed in a stable branch.
2009-05-24 10:21:37 -07:00
Cary R 9f07e3c16e 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-24 10:18:51 -07:00
Cary R 3ae3e34732 Cleanup if an invalid option is given.
Cleanup the temporary files and memory if iverilog is given
an invalid option.
2009-05-24 10:16:13 -07:00
Cary R 372efd8c30 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-24 10:15:45 -07:00
Larry Doolittle ac7f55f22a 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-24 10:14:01 -07:00
Cary R b74736c784 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-19 08:38:46 -07:00
Cary R 7988ef04d8 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-19 08:33:02 -07:00
Cary R 61214108fe 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-19 08:28:39 -07:00
Cary R 356a19c918 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-19 08:25:41 -07:00
Cary R f1c5b58845 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-19 08:22:12 -07:00
Cary R fad37da1dc 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-06 14:25:03 -07:00
Cary R 80f74d0d24 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-05-06 14:22:26 -07:00
Cary R d25f689f55 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-05-06 14:19:37 -07:00
Cary R 42618741d9 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-05-06 14:16:21 -07:00
Cary R 9bcfc8ab6d 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 18:07:03 -07:00
Cary R de75e71152 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-21 15:11:25 -07:00
Cary R 5f8f7bc6fc 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-21 15:09:01 -07:00
Cary R f7fb754ee8 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-21 15:02:14 -07:00
Cary R e59a6b8df7 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-21 14:56:25 -07:00
Cary R f149a30045 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-21 14:54:44 -07:00
Cary R ddaba5b017 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-21 14:42:12 -07:00
Cary R dff535923f 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-21 14:38:52 -07:00
Cary R d66471c449 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-21 14:35:29 -07:00
Cary R b16e3ab59e 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 ",").
(cherry picked from commit 047828ded0)
2009-04-08 19:16:26 -07:00
Cary R d7b76e9390 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.
(cherry picked from commit 5e723bfd61)
2009-04-08 19:12:39 -07:00
Cary R 6f692e7984 Use the port that has already been fetched.
This patch reuses the port that has already been fetched vs
fetching it again.
(cherry picked from commit a7741d2bd5)
2009-04-08 19:11:22 -07:00
Cary R dfe7279488 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.
(cherry picked from commit 4b2e5e5914)
2009-04-08 19:09:52 -07:00
Cary R b9ea0036de 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.
(cherry picked from commit d074a37a2d)
2009-04-08 19:07:24 -07:00
Cary R fc24624fa2 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.
(cherry picked from commit 46350da5f0)
2009-04-08 19:05:03 -07:00
Cary R cca3d5907c 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.
(cherry picked from commit e987162cb9)
2009-04-05 14:01:53 -07:00
Cary R ec809c9137 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.
(cherry picked from commit b1cb80b32e)
2009-04-05 13:58:22 -07:00
Cary R 682e54841c 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.
(cherry picked from commit 337c9e7577)
2009-04-03 06:56:54 -07:00
Cary R 7d2734c9cc 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.
(cherry picked from commit 85e2bf3e55)
2009-04-03 06:54:20 -07:00
Cary R 74df582c73 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.
(cherry picked from commit 74ea0ecb4a)
2009-04-03 06:51:32 -07:00
Cary R 10b8055a38 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.
(cherry picked from commit 464310f522)
2009-04-03 06:48:59 -07:00
Cary R 95848eb2f8 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.
(cherry picked from commit 3517f11c2c)
2009-04-03 06:45:28 -07:00
Cary R efc3bbd29e 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).
(cherry picked from commit 5852f1eb7a)
2009-04-03 06:45:04 -07:00
Cary R c56f21a20c 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.
(cherry picked from commit caab6cab9d)
2009-04-03 06:41:50 -07:00
Cary R 17210d5423 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.
(cherry picked from commit 1dbc517164)
2009-04-03 06:36:31 -07:00
Cary R b1af2f8535 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.
(cherry picked from commit ad39445eed)
2009-03-31 08:05:16 -07:00
Cary R aa28430832 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.
(cherry picked from commit 3d449f60a2)
2009-03-31 07:54:27 -07:00
Cary R ceea5d568c 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.
(cherry picked from commit d7f272d14c)
2009-03-31 07:40:28 -07:00
Larry Doolittle 710ad582ed Make VHDL code generator skip over virtual pins
Fixes pr2701438
(cherry picked from commit a05ac4b5f4)
2009-03-31 07:34:19 -07:00
Stephen Williams 183137b60c 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-28 10:08:39 -07:00
Cary R 9c7c719cac Use AC_HELP_STRING instead of AS_HELP_STRING.
The later causes a warning under MinGW. The former appears
to work everywhere.
2009-03-27 06:37:21 -07:00
Cary R 2f3061c158 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-27 06:32:46 -07:00
Cary R af08ff64c7 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 06:29:44 -07:00
Cary R 036c176e8b 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.
2009-03-26 11:51:22 -07:00
Cary R 327e8d0ec0 Use a single = in configure.in test
The ability to use == is an extension so use the more common =.
2009-03-26 11:45:11 -07:00
Larry Doolittle cfb45e56e2 Address pr2710081, version_tag.h guards
Tested with both bash and dash on Debian, has the desired effect.
No promises for cygwin.
2009-03-26 11:42:42 -07:00
Cary R 809044cbf8 Add guards in CREATE_VERSION script.
This patch adds the same guards that the other two scripts
create for the version_tag.h file.
2009-03-26 11:38:32 -07:00
Larry Doolittle 2a53255445 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:03:42 -07:00
Stephen Williams 4205752bb0 Clean up release builder scripts.
The version.h file is generated by the Makefile, we should
prefill the version_tag.h file.
2009-03-20 14:29:18 -07:00
Cary R d237e35076 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.
2009-03-20 13:58:32 -07:00
Stephen Williams 90f37fe3cb Slightly more portable version of configure test. 2009-03-19 18:31:21 -07:00
Stephen Williams 4be2f61b53 Get ready for the 0.9 first release. 2009-03-19 10:17:12 -07:00
Purdea Andrei f8aa9073ac 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
(cherry picked from commit c9d2400dd0)
2009-03-19 09:11:49 -07:00
Cary R 9ea20d6677 Cleanup lxt and lxt2 EOS data.
This patch cleans up the memory allocated in the lxt and lxt2
$dumpvars routines.
(cherry picked from commit be158dd45f)
2009-03-19 09:05:05 -07:00
Cary R 9fec1f7e45 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.
(cherry picked from commit fa8a3d6c2e)
2009-03-17 16:04:49 -07:00
Stephen Williams c47ea0721c 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?)
(cherry picked from commit 6715426833)
2009-03-17 16:04:28 -07:00
Stephen Williams ef12137931 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.
(cherry picked from commit c4a62dee0d)
2009-03-17 16:04:09 -07:00
Larry Doolittle 0e8a12eebf 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
(cherry picked from commit 3a18bda8ee)
2009-03-15 13:54:08 -07:00
Cary R 9473e823ed You must assert a logical not NULL.
This fixes a small problem where an assert was being called
with NULL instead of 0.
(cherry picked from commit ac4cb1bbe9)
2009-03-15 13:53:55 -07:00
Larry Doolittle c75f9db315 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.
(cherry picked from commit 67381431ed)
2009-03-15 13:53:41 -07:00
Larry Doolittle 1d31a91b4f 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.
(cherry picked from commit f344515e38)
2009-03-15 13:53:28 -07:00
Larry Doolittle b795d8c1d8 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".
(cherry picked from commit 5bc41e1a17)
2009-03-15 13:52:57 -07:00
Larry Doolittle 5ec7731e04 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-13 15:17:51 -07:00
Larry Doolittle bb29e1d588 Drop useless CVS stuff in .txt files
Remove useless, redundant, misleading, and misspelled $Id$ and $Log$
cruft from all .txt files.
(cherry picked from commit 86bf6c447b)
2009-03-13 09:42:17 -07:00
Larry Doolittle 74fd1865cb 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-09 14:46:13 -07:00
Larry Doolittle b40b6fb50d Spelling fixes
Mostly comments, but includes user-visible debug messages.
(cherry picked from commit b0c4a87133)
2009-03-09 14:44:07 -07:00
Stephen Williams 19b68f6332 Fix broken definition of is_linked().
(cherry picked from commit fff2598709)
2009-03-09 14:43:18 -07:00
Cary R c96e4da9e4 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:09:43 -08:00
207 changed files with 8020 additions and 6633 deletions

6
.gitignore vendored
View File

@ -18,6 +18,7 @@ config.h
/tgt-vvp/vvp_config.h /tgt-vvp/vvp_config.h
/tgt-vhdl/vhdl_config.h /tgt-vhdl/vhdl_config.h
/vpi/vpi_config.h /vpi/vpi_config.h
stamp-*-h
/version.h /version.h
/version_tag.h /version_tag.h
@ -61,6 +62,11 @@ dep
# Program created files # Program created files
/vvp/tables.cc /vvp/tables.cc
/iverilog-vpi.man
/driver-vpi/res.rc
/driver/iverilog.man
/vvp/vvp.man
# The executables. # The executables.
*.exe *.exe
/driver/iverilog /driver/iverilog

View File

@ -1,7 +1,7 @@
#ifndef __Attrib_H #ifndef __Attrib_H
#define __Attrib_H #define __Attrib_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 * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -30,7 +30,7 @@ class Attrib {
public: public:
Attrib(); Attrib();
~Attrib(); virtual ~Attrib();
const verinum&attribute(perm_string key) const; const verinum&attribute(perm_string key) const;
void attribute(perm_string key, const verinum&value); void attribute(perm_string key, const verinum&value);

View File

@ -1,7 +1,7 @@
#ifndef __LineInfo_H #ifndef __LineInfo_H
#define __LineInfo_H #define __LineInfo_H
/* /*
* Copyright (c) 1999 Stephen Williams (steve@icarus.com) * Copyright (c) 1999-2009 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -36,7 +36,7 @@ using namespace std;
class LineInfo { class LineInfo {
public: public:
LineInfo(); LineInfo();
~LineInfo(); virtual ~LineInfo();
// Get a fully formatted file/lineno // Get a fully formatted file/lineno
string get_fileline() const; string get_fileline() const;

View File

@ -40,10 +40,19 @@ datarootdir = @datarootdir@
SUBDIRS = ivlpp vvp vpi libveriuser cadpli tgt-null tgt-stub tgt-vvp \ SUBDIRS = ivlpp vvp vpi libveriuser cadpli tgt-null tgt-stub tgt-vvp \
tgt-vhdl driver tgt-vhdl driver
# Only run distclean for these driectories. # Only run distclean for these directories.
NOTUSED = tgt-fpga tgt-pal tgt-verilog 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@ bindir = @bindir@
libdir = @libdir@ libdir = @libdir@
@ -55,6 +64,7 @@ mandir = @mandir@
dllib=@DLLIB@ dllib=@DLLIB@
CC = @CC@ CC = @CC@
HOSTCC = @CC@
CXX = @CXX@ CXX = @CXX@
INSTALL = @INSTALL@ INSTALL = @INSTALL@
INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_SCRIPT = @INSTALL_SCRIPT@
@ -71,44 +81,57 @@ CXXFLAGS = -Wall @CXXFLAGS@
PICFLAGS = @PICFLAG@ PICFLAGS = @PICFLAG@
LDFLAGS = @rdynamic@ @LDFLAGS@ LDFLAGS = @rdynamic@ @LDFLAGS@
all: dep config.h _pli_types.h version.h ivl@EXEEXT@ all: dep config.h _pli_types.h version_tag.h ivl@EXEEXT@ version.exe iverilog-vpi.man
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) $@); done $(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true
# In the windows world, the installer will need a dosify program to # In the windows world, the installer will need a dosify program to
# dosify text files. # dosify text files.
ifeq (@MINGW32@,yes) ifeq (@MINGW32@,yes)
all: dep dosify.exe all: dep dosify.exe
dosify.exe: dosify.c dosify.exe: $(srcdir)/dosify.c
$(CC) -o dosify.exe dosify.c $(CC) -o dosify.exe $(srcdir)/dosify.c
endif endif
# This rule rules the compiler in the trivial hello.vl program to make # This rule rules the compiler in the trivial hello.vl program to make
# sure the basics were compiled properly. # sure the basics were compiled properly.
check: all 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 . test -r check.conf || cp $(srcdir)/check.conf .
driver/iverilog -B. -BPivlpp -tcheck -ocheck.vvp $(srcdir)/examples/hello.vl 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' 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: clean:
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) $@); done $(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true
ifeq (@MINGW32@,no) rm -f *.o parse.cc parse.h lexor.cc
(cd driver-vpi ; $(MAKE) $@) rm -f ivl.exp iverilog-vpi.man iverilog-vpi.pdf iverilog-vpi.ps parse.output
endif
rm -f *.o parse.cc parse.cc.output parse.h lexor.cc
rm -f ivl.exp iverilog-vpi.pdf iverilog-vpi.ps parse.output
rm -f syn-rules.output dosify.exe ivl@EXEEXT@ check.vvp 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 -rf dep
rm -f version.exe
distclean: clean distclean: clean
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) $@); done $(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true
ifeq (@MINGW32@,no) $(foreach dir,$(NOTUSED),$(MAKE) -C $(dir) $@ && ) true
(cd driver-vpi ; $(MAKE) $@) 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 endif
for dir in $(NOTUSED); do (cd $$dir ; $(MAKE) $@); done rm -rf autom4te.cache
rm -f Makefile config.status config.log config.cache config.h
rm -f _pli_types.h
TT = t-dll.o t-dll-api.o t-dll-expr.o t-dll-proc.o t-dll-analog.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 FF = cprop.o nodangle.o synth.o synth2.o syn-rules.o
@ -134,12 +157,22 @@ $(FF) $(TT)
Makefile: $(srcdir)/Makefile.in config.status Makefile: $(srcdir)/Makefile.in config.status
./config.status --file=$@ ./config.status --file=$@
config.h: $(srcdir)/config.h.in stamp-config-h: $(srcdir)/config.h.in config.status
./config.status --header=$@ @rm -f $@
./config.status config.h
config.h: stamp-config-h
_pli_types.h: $(srcdir)/_pli_types.h.in stamp-_pli_types-h: $(srcdir)/_pli_types.h.in config.status
./config.status --header=$@ @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) ifeq (@WIN32@,yes)
# Under Windows (mingw) I need to make the ivl.exe in two steps. # Under Windows (mingw) I need to make the ivl.exe in two steps.
@ -156,12 +189,10 @@ ivl@EXEEXT@: $O
$(CXX) $(LDFLAGS) -o ivl@EXEEXT@ $O $(dllib) $(CXX) $(LDFLAGS) -o ivl@EXEEXT@ $O $(dllib)
endif endif
ifeq (@MINGW32@,yes) ifeq (@MINGW32@,no)
SUBDIRS += driver-vpi
else
all: dep iverilog-vpi all: dep iverilog-vpi
iverilog-vpi: iverilog-vpi.sh Makefile iverilog-vpi: $(srcdir)/iverilog-vpi.sh Makefile
sed -e 's;@SHARED@;@shared@;' -e 's;@PIC@;@PICFLAG@;' \ sed -e 's;@SHARED@;@shared@;' -e 's;@PIC@;@PICFLAG@;' \
-e 's;@SUFFIX@;$(suffix);' \ -e 's;@SUFFIX@;$(suffix);' \
-e 's;@IVCC@;$(CC);' \ -e 's;@IVCC@;$(CC);' \
@ -172,13 +203,18 @@ iverilog-vpi: iverilog-vpi.sh Makefile
chmod +x $@ chmod +x $@
endif 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: dep:
mkdir dep mkdir dep
%.o: %.cc %.o: %.cc config.h
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -MD -c $< -o $*.o $(CXX) $(CPPFLAGS) $(CXXFLAGS) -MD -c $< -o $*.o
mv $*.d dep/$*.d 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 lexor.o: lexor.cc parse.h
@ -196,20 +232,19 @@ lexor.cc: $(srcdir)/lexor.lex
lexor_keyword.o: lexor_keyword.cc parse.h lexor_keyword.o: lexor_keyword.cc parse.h
lexor_keyword.cc: lexor_keyword.gperf lexor_keyword.cc: $(srcdir)/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) 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)
iverilog-vpi.ps: $(srcdir)/iverilog-vpi.man iverilog-vpi.man: $(srcdir)/iverilog-vpi.man.in version.exe
$(MAN) -t $(srcdir)/iverilog-vpi.man > iverilog-vpi.ps ./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 iverilog-vpi.pdf: iverilog-vpi.ps
$(PS2PDF) iverilog-vpi.ps iverilog-vpi.pdf $(PS2PDF) iverilog-vpi.ps iverilog-vpi.pdf
# The version.h header file is the concatenation of a relatively static
# base version and the detailed version tag.
version.h: $(srcdir)/version_base.in version_tag.h
cat $(srcdir)/version_base.in version_tag.h > version.h
# For VERSION_TAG in driver/main.c, first try git-describe, then look for a # 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 # version.h file in the source tree (included in snapshots and releases), and
# finally use nothing. # finally use nothing.
@ -223,15 +258,16 @@ endif
version_tag.h version: version_tag.h version:
@if $(GIT_PRESENT) && test -d $(srcdir)/.git; then \ @if $(GIT_PRESENT) && test -d $(srcdir)/.git; then \
echo "Using git-describe for VERSION_TAG"; \ echo "Using git-describe for VERSION_TAG"; \
tmp=`$(GIT) --git-dir $(srcdir)/.git describe \ tag=`$(GIT) --git-dir $(srcdir)/.git describe`; \
| sed -e 's;\(.*\);#define VERSION_TAG "\1";'`; \ tmp=`printf "#ifndef VERSION_TAG\n#define VERSION_TAG \"$$tag\"\n#endif\n"`; \
echo "$$tmp" | diff - version_tag.h > /dev/null 2>&1 || echo "$$tmp" > version_tag.h || exit 1; \ 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 \ elif test -r $(srcdir)/version_tag.h; then \
echo "Using $(srcdir)/version_tag.h for VERSION_TAG"; \ 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; \ diff $(srcdir)/version_tag.h version_tag.h > /dev/null 2>&1 || cp $(srcdir)/version_tag.h version_tag.h; \
else \ else \
echo "Using empty VERSION_TAG"; \ echo "Using empty VERSION_TAG"; \
echo '#define VERSION_TAG ""' > version_tag.h; \ tmp=`printf "#ifndef VERSION_TAG\n#define VERSION_TAG \"\"\n#endif\n"`; \
echo "$$tmp" | diff - version_tag.h > /dev/null 2>&1 || echo "$$tmp" > version_tag.h || exit 1; \
fi fi
ifeq (@MINGW32@,yes) ifeq (@MINGW32@,yes)
@ -258,7 +294,7 @@ WIN32_INSTALL = $(bindir)/iverilog-vpi$(suffix)
endif endif
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) 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)
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) $@); done $(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true
$(bindir)/iverilog-vpi$(suffix): ./iverilog-vpi $(bindir)/iverilog-vpi$(suffix): ./iverilog-vpi
$(INSTALL_SCRIPT) ./iverilog-vpi "$(DESTDIR)$(bindir)/iverilog-vpi$(suffix)" $(INSTALL_SCRIPT) ./iverilog-vpi "$(DESTDIR)$(bindir)/iverilog-vpi$(suffix)"
@ -287,8 +323,8 @@ $(includedir)/acc_user.h: $(srcdir)/acc_user.h
$(includedir)/veriuser.h: $(srcdir)/veriuser.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$(suffix).1: $(srcdir)/iverilog-vpi.man $(mandir)/man1/iverilog-vpi$(suffix).1: iverilog-vpi.man
$(INSTALL_DATA) $(srcdir)/iverilog-vpi.man "$(DESTDIR)$(mandir)/man1/iverilog-vpi$(suffix).1" $(INSTALL_DATA) iverilog-vpi.man "$(DESTDIR)$(mandir)/man1/iverilog-vpi$(suffix).1"
$(prefix)/iverilog-vpi$(suffix).pdf: iverilog-vpi.pdf $(prefix)/iverilog-vpi$(suffix).pdf: iverilog-vpi.pdf
$(INSTALL_DATA) iverilog-vpi.pdf "$(DESTDIR)$(prefix)/iverilog-vpi$(suffix).pdf" $(INSTALL_DATA) iverilog-vpi.pdf "$(DESTDIR)$(prefix)/iverilog-vpi$(suffix).pdf"
@ -303,7 +339,7 @@ installdirs: $(srcdir)/mkinstalldirs
"$(DESTDIR)$(mandir)/man1" "$(DESTDIR)$(mandir)/man1"
uninstall: uninstall:
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) $@); done $(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true
for f in ivl@EXEEXT@ include/constants.vams include/disciplines.vams; \ for f in ivl@EXEEXT@ include/constants.vams include/disciplines.vams; \
do rm -f "$(DESTDIR)$(libdir)/ivl$(suffix)/$$f"; done do rm -f "$(DESTDIR)$(libdir)/ivl$(suffix)/$$f"; done
-rmdir "$(DESTDIR)$(libdir)/ivl$(suffix)/include" -rmdir "$(DESTDIR)$(libdir)/ivl$(suffix)/include"

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1998-2008 Stephen Williams (steve@icarus.com) * Copyright (c) 1998-2009 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -29,7 +29,10 @@ Module::Module(perm_string n)
: PScope(n) : PScope(n)
{ {
library_flag = false; library_flag = false;
is_cell = false;
uc_drive = UCD_NONE;
default_nettype = NetNet::NONE; default_nettype = NetNet::NONE;
timescale_warn_done = false;
} }
Module::~Module() Module::~Module()

View File

@ -1,7 +1,7 @@
#ifndef __Module_H #ifndef __Module_H
#define __Module_H #define __Module_H
/* /*
* Copyright (c) 1998-2008 Stephen Williams (steve@icarus.com) * Copyright (c) 1998-2009 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -74,6 +74,11 @@ class Module : public PScope, public LineInfo {
other effect. */ other effect. */
bool library_flag; bool library_flag;
bool is_cell;
enum UCDriveType { UCD_NONE, UCD_PULL0, UCD_PULL1 };
UCDriveType uc_drive;
NetNet::Type default_nettype; NetNet::Type default_nettype;
/* specparams are simpler then other params, in that they have /* specparams are simpler then other params, in that they have
@ -105,6 +110,8 @@ class Module : public PScope, public LineInfo {
/* These are the timescale for this module. The default is /* These are the timescale for this module. The default is
set by the `timescale directive. */ set by the `timescale directive. */
int time_unit, time_precision; int time_unit, time_precision;
bool time_from_timescale;
bool timescale_warn_done;
/* Task definitions within this module */ /* Task definitions within this module */
map<perm_string,PTask*> tasks; map<perm_string,PTask*> tasks;

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 * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -26,6 +26,11 @@
# include "verinum.h" # include "verinum.h"
# include "netmisc.h" # include "netmisc.h"
bool dly_used_no_timescale = false;
bool dly_used_timescale = false;
bool display_ts_dly_warning = true;
PDelays::PDelays() PDelays::PDelays()
{ {
delete_flag_ = true; delete_flag_ = true;
@ -60,12 +65,28 @@ void PDelays::set_delays(const svector<PExpr*>*del, bool df)
delete_flag_ = 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); NetExpr*dex = expr->elaborate_expr(des, scope, -1, false);
eval_expr(dex); 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 /* If the delay expression is a real constant or vector
constant, then evaluate it, scale it to the local time constant, then evaluate it, scale it to the local time
units, and return an adjusted value. */ units, and return an adjusted value. */
@ -119,6 +140,20 @@ static NetExpr* make_delay_nets(Design*des, NetScope*scope, NetExpr*expr)
return 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, void PDelays::eval_delays(Design*des, NetScope*scope,
NetExpr*&rise_time, NetExpr*&rise_time,
NetExpr*&fall_time, NetExpr*&fall_time,
@ -140,14 +175,14 @@ void PDelays::eval_delays(Design*des, NetScope*scope,
if (delay_[2]) { if (delay_[2]) {
decay_time = calculate_val(des, scope, delay_[2]); decay_time = calculate_val(des, scope, delay_[2]);
if (as_nets_flag) if (as_nets_flag)
decay_time = make_delay_nets(des, scope, decay_time); decay_time = make_delay_nets(des, scope,
decay_time);
} else { } else {
if (rise_time < fall_time) // If this is zero then we need to do the min()
decay_time = rise_time; // at run time.
else decay_time = calc_decay_time(rise_time, fall_time);
decay_time = fall_time;
} }
} else { } else {
assert(delay_[2] == 0); assert(delay_[2] == 0);

View File

@ -183,7 +183,6 @@ class PEConcat : public PExpr {
std::valarray<unsigned>tested_widths_; std::valarray<unsigned>tested_widths_;
PExpr*repeat_; PExpr*repeat_;
NetExpr*repeat_expr_;
}; };
/* /*
@ -339,6 +338,12 @@ class PEIdent : public PExpr {
NetScope*found, NetScope*found,
const NetExpr*par_msb, const NetExpr*par_msb,
const NetExpr*par_lsb) const; 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, NetExpr*elaborate_expr_net(Design*des,
NetScope*scope, NetScope*scope,
NetNet*net, NetNet*net,

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2006 Stephen Williams (steve@icarus.com) * Copyright (c) 2006,2009 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -55,6 +55,7 @@ void PGenerate::probe_for_direct_nesting_(void)
if (localparams.size() > 0) return; if (localparams.size() > 0) return;
if (events.size() > 0) return; if (events.size() > 0) return;
if (wires.size() > 0) return; if (wires.size() > 0) return;
if (genvars.size() > 0) return;
if (behaviors.size() > 0) return; if (behaviors.size() > 0) return;
if (analog_behaviors.size() > 0) return; if (analog_behaviors.size() > 0) return;

View File

@ -1,7 +1,7 @@
#ifndef __PGenerate_H #ifndef __PGenerate_H
#define __PGenerate_H #define __PGenerate_H
/* /*
* Copyright (c) 2006-2008 Stephen Williams (steve@icarus.com) * Copyright (c) 2006-2009 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -87,6 +87,9 @@ class PGenerate : public LineInfo, public LexicalScope {
map<perm_string,PTask*> tasks; map<perm_string,PTask*> tasks;
map<perm_string,PFunction*>funcs; map<perm_string,PFunction*>funcs;
// genvars declared within this scheme.
map<perm_string,LineInfo*> genvars;
// Generate schemes can contain further generate schemes. // Generate schemes can contain further generate schemes.
list<PGenerate*> generate_schemes; list<PGenerate*> generate_schemes;
PGenerate*parent; PGenerate*parent;
@ -109,8 +112,8 @@ class PGenerate : public LineInfo, public LexicalScope {
bool generate_scope_case_(Design*des, NetScope*container); bool generate_scope_case_(Design*des, NetScope*container);
bool generate_scope_nblock_(Design*des, NetScope*container); bool generate_scope_nblock_(Design*des, NetScope*container);
// Call probe during elaborate_scope to calulate the // Call probe during elaborate_scope to calculate the
// directed_nested_ flag. It is OK to store the direct_nested_ // direct_nested_ flag. It is OK to store the direct_nested_
// information here because "direct nested" is a property of // information here because "direct nested" is a property of
// the lexical generate code. // the lexical generate code.
void probe_for_direct_nesting_(void); void probe_for_direct_nesting_(void);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1999-2007 Stephen Williams (steve@icarus.com) * Copyright (c) 1999-2009 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * 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), : name_(n), type_(t), port_type_(pt), data_type_(dt),
signed_(false), isint_(false), signed_(false), isint_(false),
port_msb_(0), port_lsb_(0), port_set_(false), port_msb_(0), port_lsb_(0), port_set_(false),
net_msb_(0), net_lsb_(0), net_set_(false), error_cnt_(0), net_msb_(0), net_lsb_(0), net_set_(false), is_scalar_(false),
lidx_(0), ridx_(0), discipline_(0) error_cnt_(0), lidx_(0), ridx_(0), discipline_(0)
{ {
if (t == NetNet::INTEGER) { if (t == NetNet::INTEGER) {
type_ = NetNet::REG; type_ = NetNet::REG;
@ -135,7 +135,12 @@ bool PWire::get_isint() const
return isint_; 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) { switch (type) {
case SR_PORT: case SR_PORT:
@ -147,6 +152,7 @@ void PWire::set_range(PExpr*m, PExpr*l, PWSRType type)
port_msb_ = m; port_msb_ = m;
port_lsb_ = l; port_lsb_ = l;
port_set_ = true; port_set_ = true;
is_scalar_ = is_scalar;
} }
return; return;
@ -159,6 +165,7 @@ void PWire::set_range(PExpr*m, PExpr*l, PWSRType type)
net_msb_ = m; net_msb_ = m;
net_lsb_ = l; net_lsb_ = l;
net_set_ = true; net_set_ = true;
is_scalar_ = is_scalar;
} }
return; return;
@ -181,6 +188,7 @@ void PWire::set_range(PExpr*m, PExpr*l, PWSRType type)
net_msb_ = m; net_msb_ = m;
net_lsb_ = l; net_lsb_ = l;
net_set_ = true; net_set_ = true;
is_scalar_ = is_scalar;
} }
return; return;
} }

View File

@ -1,7 +1,7 @@
#ifndef __PWire_H #ifndef __PWire_H
#define __PWire_H #define __PWire_H
/* /*
* Copyright (c) 1998-2007 Stephen Williams (steve@icarus.com) * Copyright (c) 1998-2009 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * 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); void set_signed(bool flag);
bool get_signed() const; bool get_signed() const;
bool get_isint() const; bool get_isint() const;
bool get_scalar() const;
bool set_data_type(ivl_variable_type_t dt); bool set_data_type(ivl_variable_type_t dt);
ivl_variable_type_t get_data_type() const; 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); void set_memory_idx(PExpr*ldx, PExpr*rdx);
@ -104,6 +105,7 @@ class PWire : public LineInfo {
PExpr*net_msb_; PExpr*net_msb_;
PExpr*net_lsb_; PExpr*net_lsb_;
bool net_set_; bool net_set_;
bool is_scalar_;
unsigned error_cnt_; unsigned error_cnt_;
// If this wire is actually a memory, these indices will give // If this wire is actually a memory, these indices will give

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2002-2004 Stephen Williams (steve@icarus.com) * Copyright (c) 2002-2009 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -25,6 +25,11 @@
# include <string.h> # include <string.h>
# include <assert.h> # include <assert.h>
#ifdef CHECK_WITH_VALGRIND
static char **string_pool = NULL;
static unsigned string_pool_count = 0;
#endif
StringHeap::StringHeap() StringHeap::StringHeap()
{ {
cell_base_ = 0; cell_base_ = 0;
@ -46,6 +51,12 @@ const char* StringHeap::add(const char*text)
unsigned rem = HEAPCELL - cell_ptr_; unsigned rem = HEAPCELL - cell_ptr_;
if (rem < (len+1)) { if (rem < (len+1)) {
cell_base_ = (char*)malloc(HEAPCELL); 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_ptr_ = 0;
cell_count_ += 1; cell_count_ += 1;
assert(cell_base_ != 0); assert(cell_base_ != 0);
@ -80,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 unsigned StringHeapLex::add_hit_count() const
{ {
return hit_count_; return hit_count_;
@ -175,4 +202,3 @@ bool operator < (perm_string a, perm_string b)
return false; return false;
} }

View File

@ -1,7 +1,7 @@
#ifndef __StringHeap_H #ifndef __StringHeap_H
#define __StringHeap_H #define __StringHeap_H
/* /*
* Copyright (c) 2002-2004 Stephen Williams (steve@icarus.com) * Copyright (c) 2002-2009 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -104,6 +104,7 @@ class StringHeapLex : private StringHeap {
unsigned add_count() const; unsigned add_count() const;
unsigned add_hit_count() const; unsigned add_hit_count() const;
void cleanup();
private: private:
enum { HASH_SIZE = 4096 }; enum { HASH_SIZE = 4096 };

18
aclocal.m4 vendored
View File

@ -6,7 +6,9 @@
# different builds. Remember to change the default suffix string to some # different builds. Remember to change the default suffix string to some
# value appropriate for the current version. # value appropriate for the current version.
AC_DEFUN([AX_ENABLE_SUFFIX], AC_DEFUN([AX_ENABLE_SUFFIX],
[AC_ARG_ENABLE([suffix],[Set the installation command suffix],[true],[enable_suffix=no]) [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 if test X$enable_suffix = Xyes; then
install_suffix='-0.9' install_suffix='-0.9'
elif test X$enable_suffix = Xno; then elif test X$enable_suffix = Xno; then
@ -214,3 +216,17 @@ case "${host}" in
;; ;;
esac esac
])# AX_CPP_PRECOMP ])# 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

View File

@ -60,7 +60,7 @@ dep:
O = cadpli.o O = cadpli.o
Makefile: $(srcdir)/Makefile.in ../config.status Makefile: $(srcdir)/Makefile.in ../config.status
../config.status --file=$@ cd ..; ./config.status --file=cadpli/$@
SYSTEM_VPI_LDFLAGS = -L../vvp -lvpi SYSTEM_VPI_LDFLAGS = -L../vvp -lvpi
ifeq (@MINGW32@,yes) ifeq (@MINGW32@,yes)
@ -71,7 +71,7 @@ cadpli.vpl: $O ../vvp/libvpi.a ../libveriuser/libveriuser.o
$(CC) @shared@ -o $@ $O ../libveriuser/libveriuser.o $(SYSTEM_VPI_LDFLAGS) $(CC) @shared@ -o $@ $O ../libveriuser/libveriuser.o $(SYSTEM_VPI_LDFLAGS)
clean: clean:
rm -rf *.o dep cadpli.vpl bin32 rm -rf *.o dep cadpli.vpl
distclean: clean distclean: clean
rm -f Makefile config.log rm -f Makefile config.log

View File

@ -2,7 +2,6 @@
CADENCE PLI1 MODULES CADENCE PLI1 MODULES
Copyright 2003 Stephen Williams 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 With the cadpli module, Icarus Verilog is able to load PLI1
applications that were compiled and linked to be dynamic loaded by 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 The integration from this point is seamless. The PLI application
hardly knows that it is being invoked by Icarus Verilog instead of hardly knows that it is being invoked by Icarus Verilog instead of
Verilog-XL, so operates as it would otherwise. 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.

View File

@ -1,7 +1,7 @@
#ifndef __compiler_H #ifndef __compiler_H
#define __compiler_H #define __compiler_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 * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -36,6 +36,12 @@
*/ */
extern unsigned integer_width; 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. */ /* The TIME_WIDTH is the width of time variables. */
#ifndef TIME_WIDTH #ifndef TIME_WIDTH
# define TIME_WIDTH 64 # define TIME_WIDTH 64
@ -76,9 +82,17 @@ extern bool warn_timescale;
/* Warn about legal but questionable module port bindings. */ /* Warn about legal but questionable module port bindings. */
extern bool warn_portbinding; extern bool warn_portbinding;
/* Warn about constant out of bound selects. */
extern bool warn_ob_select;
/* Warn about structures that may have infinite loops. */ /* Warn about structures that may have infinite loops. */
extern bool warn_inf_loop; 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. */ /* This is true if verbose output is requested. */
extern bool verbose_flag; extern bool verbose_flag;
@ -89,6 +103,12 @@ extern bool debug_elab_pexpr;
extern bool debug_synth2; extern bool debug_synth2;
extern bool debug_optimizer; extern bool debug_optimizer;
/* 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. */ /* Path to a directory useful for finding subcomponents. */
extern const char*basedir; extern const char*basedir;
@ -101,9 +121,10 @@ extern int build_library_index(const char*path, bool key_case_sensitive);
specific language features. */ specific language features. */
enum generation_t { enum generation_t {
GN_VER1995 = 1, GN_VER1995 = 1,
GN_VER2001 = 2, GN_VER2001_NOCONFIG = 2,
GN_VER2005 = 3, GN_VER2001 = 3,
GN_DEFAULT = 3 GN_VER2005 = 4,
GN_DEFAULT = 4
}; };
extern generation_t generation_flag; extern generation_t generation_flag;
@ -189,5 +210,6 @@ struct sfunc_return_type {
extern const struct sfunc_return_type* lookup_sys_func(const char*name); extern const struct sfunc_return_type* lookup_sys_func(const char*name);
extern int load_sys_func_table(const char*path); extern int load_sys_func_table(const char*path);
extern void cleanup_sys_func_table();
#endif #endif

965
config.guess vendored

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
#ifndef __config_H /* -*- c++ -*- */ #ifndef __config_H /* -*- c++ -*- */
#define __config_H #define __config_H
/* /*
* 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 * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -50,4 +50,10 @@
# include <inttypes.h> # include <inttypes.h>
#endif #endif
/*
* 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 */ #endif /* __config_H */

415
config.sub vendored
View File

@ -1,9 +1,10 @@
#! /bin/sh #! /bin/sh
# Configuration validation subroutine script. # Configuration validation subroutine script.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 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. # This file is (in principle) common to ALL GNU software.
# The presence of a machine in this file suggests that SOME 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 # You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software # along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, # Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
# Boston, MA 02111-1307, USA. # 02110-1301, USA.
#
# As a special exception to the GNU General Public License, if you # As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a # distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under # configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program. # the same distribution terms that you use for the rest of that program.
# Please send patches to <config-patches@gnu.org>. Submit a context # Please send patches to <config-patches@gnu.org>. Submit a context
# diff and a properly formatted ChangeLog entry. # diff and a properly formatted ChangeLog entry.
# #
@ -70,8 +72,8 @@ Report bugs and patches to <config-patches@gnu.org>."
version="\ version="\
GNU config.sub ($timestamp) GNU config.sub ($timestamp)
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
Free Software Foundation, Inc. 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." 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 while test $# -gt 0 ; do
case $1 in case $1 in
--time-stamp | --time* | -t ) --time-stamp | --time* | -t )
echo "$timestamp" ; exit 0 ;; echo "$timestamp" ; exit ;;
--version | -v ) --version | -v )
echo "$version" ; exit 0 ;; echo "$version" ; exit ;;
--help | --h* | -h ) --help | --h* | -h )
echo "$usage"; exit 0 ;; echo "$usage"; exit ;;
-- ) # Stop option processing -- ) # Stop option processing
shift; break ;; shift; break ;;
- ) # Use stdin as input. - ) # Use stdin as input.
@ -99,7 +101,7 @@ while test $# -gt 0 ; do
*local*) *local*)
# First pass through any local machine types. # First pass through any local machine types.
echo $1 echo $1
exit 0;; exit ;;
* ) * )
break ;; break ;;
@ -118,7 +120,10 @@ esac
# Here we must recognize all the valid KERNEL-OS combinations. # Here we must recognize all the valid KERNEL-OS combinations.
maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
case $maybe_os in 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 os=-$maybe_os
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
;; ;;
@ -144,7 +149,7 @@ case $os in
-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
-apple | -axis) -apple | -axis | -knuth | -cray)
os= os=
basic_machine=$1 basic_machine=$1
;; ;;
@ -169,6 +174,10 @@ case $os in
-hiux*) -hiux*)
os=-hiuxwe2 os=-hiuxwe2
;; ;;
-sco6)
os=-sco5v6
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-sco5) -sco5)
os=-sco3.2v5 os=-sco3.2v5
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` 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. # Don't forget version if it is 3.2v4 or newer.
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` 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*) -sco*)
os=-sco3.2v2 os=-sco3.2v2
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
@ -228,40 +241,57 @@ case $basic_machine in
| a29k \ | a29k \
| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[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 \ | c4x | clipper \
| d10v | d30v | dlx | dsp16xx \ | d10v | d30v | dlx | dsp16xx \
| fr30 | frv \ | fido | fr30 | frv \
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
| i370 | i860 | i960 | ia64 \ | i370 | i860 | i960 | ia64 \
| ip2k \ | ip2k | iq2000 \
| m32r | m68000 | m68k | m88k | mcore \ | lm32 \
| m32c | m32r | m32rle | m68000 | m68k | m88k \
| maxq | mb | microblaze | mcore | mep | metag \
| mips | mipsbe | mipseb | mipsel | mipsle \ | mips | mipsbe | mipseb | mipsel | mipsle \
| mips16 \ | mips16 \
| mips64 | mips64el \ | mips64 | mips64el \
| mips64octeon | mips64octeonel \
| mips64orion | mips64orionel \ | mips64orion | mips64orionel \
| mips64r5900 | mips64r5900el \
| mips64vr | mips64vrel \
| mips64vr4100 | mips64vr4100el \ | mips64vr4100 | mips64vr4100el \
| mips64vr4300 | mips64vr4300el \ | mips64vr4300 | mips64vr4300el \
| mips64vr5000 | mips64vr5000el \ | mips64vr5000 | mips64vr5000el \
| mips64vr5900 | mips64vr5900el \
| mipsisa32 | mipsisa32el \ | mipsisa32 | mipsisa32el \
| mipsisa32r2 | mipsisa32r2el \
| mipsisa64 | mipsisa64el \ | mipsisa64 | mipsisa64el \
| mipsisa64r2 | mipsisa64r2el \
| mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sb1 | mipsisa64sb1el \
| mipsisa64sr71k | mipsisa64sr71kel \
| mipstx39 | mipstx39el \ | mipstx39 | mipstx39el \
| mn10200 | mn10300 \ | mn10200 | mn10300 \
| moxie \
| mt \
| msp430 \
| nios | nios2 \
| ns16k | ns32k \ | ns16k | ns32k \
| openrisc | or32 \ | or32 \
| pdp10 | pdp11 | pj | pjl \ | pdp10 | pdp11 | pj | pjl \
| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
| pyramid \ | 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 \ | sh64 | sh64le \
| sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv9 | sparcv9b \ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
| strongarm \ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \
| tahoe | thumb | tic80 | tron \ | spu | strongarm \
| tahoe | thumb | tic4x | tic80 | tron \
| v850 | v850e \ | v850 | v850e \
| we32k \ | we32k \
| x86 | xscale | xstormy16 | xtensa \ | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \
| z8k) | z8k | z80)
basic_machine=$basic_machine-unknown basic_machine=$basic_machine-unknown
;; ;;
m6811 | m68hc11 | m6812 | m68hc12) m6811 | m68hc11 | m6812 | m68hc12)
@ -271,6 +301,9 @@ case $basic_machine in
;; ;;
m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
;; ;;
ms1)
basic_machine=mt-unknown
;;
# We use `pc' rather than `unknown' # We use `pc' rather than `unknown'
# because (1) that's what they normally are, and # because (1) that's what they normally are, and
@ -290,48 +323,67 @@ case $basic_machine in
| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
| arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \
| avr-* \ | avr-* | avr32-* \
| bs2000-* \ | bfin-* | bs2000-* \
| c[123]* | c30-* | [cjt]90-* | c54x-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
| clipper-* | cydra-* \ | clipper-* | craynv-* | cydra-* \
| d10v-* | d30v-* | dlx-* \ | d10v-* | d30v-* | dlx-* \
| elxsi-* \ | elxsi-* \
| f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
| h8300-* | h8500-* \ | h8300-* | h8500-* \
| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
| i*86-* | i860-* | i960-* | ia64-* \ | i*86-* | i860-* | i960-* | ia64-* \
| ip2k-* \ | ip2k-* | iq2000-* \
| m32r-* \ | lm32-* \
| m32c-* | m32r-* | m32rle-* \
| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
| m88110-* | m88k-* | mcore-* \ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
| mips16-* \ | mips16-* \
| mips64-* | mips64el-* \ | mips64-* | mips64el-* \
| mips64octeon-* | mips64octeonel-* \
| mips64orion-* | mips64orionel-* \ | mips64orion-* | mips64orionel-* \
| mips64r5900-* | mips64r5900el-* \
| mips64vr-* | mips64vrel-* \
| mips64vr4100-* | mips64vr4100el-* \ | mips64vr4100-* | mips64vr4100el-* \
| mips64vr4300-* | mips64vr4300el-* \ | mips64vr4300-* | mips64vr4300el-* \
| mips64vr5000-* | mips64vr5000el-* \ | mips64vr5000-* | mips64vr5000el-* \
| mips64vr5900-* | mips64vr5900el-* \
| mipsisa32-* | mipsisa32el-* \ | mipsisa32-* | mipsisa32el-* \
| mipsisa32r2-* | mipsisa32r2el-* \
| mipsisa64-* | mipsisa64el-* \ | mipsisa64-* | mipsisa64el-* \
| mipsisa64r2-* | mipsisa64r2el-* \
| mipsisa64sb1-* | mipsisa64sb1el-* \ | mipsisa64sb1-* | mipsisa64sb1el-* \
| mipstx39 | mipstx39el \ | mipsisa64sr71k-* | mipsisa64sr71kel-* \
| mipstx39-* | mipstx39el-* \
| mmix-* \
| mt-* \
| msp430-* \
| nios-* | nios2-* \
| none-* | np1-* | ns16k-* | ns32k-* \ | none-* | np1-* | ns16k-* | ns32k-* \
| orion-* \ | orion-* \
| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
| pyramid-* \ | pyramid-* \
| romp-* | rs6000-* \ | 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-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
| sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
| sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \ | sparclite-* \
| tahoe-* | thumb-* | tic30-* | tic54x-* | tic80-* | tron-* \ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \
| tahoe-* | thumb-* \
| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* | tile-* \
| tron-* \
| v850-* | v850e-* | vax-* \ | v850-* | v850e-* | vax-* \
| we32k-* \ | we32k-* \
| x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \ | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \
| xtensa-* \ | xstormy16-* | xtensa*-* \
| ymp-* \ | 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 # Recognize the various machine names and aliases which stand
# for a CPU type and a company and sometimes even an OS. # for a CPU type and a company and sometimes even an OS.
@ -349,6 +401,9 @@ case $basic_machine in
basic_machine=a29k-amd basic_machine=a29k-amd
os=-udi os=-udi
;; ;;
abacus)
basic_machine=abacus-unknown
;;
adobe68k) adobe68k)
basic_machine=m68010-adobe basic_machine=m68010-adobe
os=-scout os=-scout
@ -363,6 +418,12 @@ case $basic_machine in
basic_machine=a29k-none basic_machine=a29k-none
os=-bsd os=-bsd
;; ;;
amd64)
basic_machine=x86_64-pc
;;
amd64-*)
basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
amdahl) amdahl)
basic_machine=580-amdahl basic_machine=580-amdahl
os=-sysv os=-sysv
@ -386,6 +447,10 @@ case $basic_machine in
basic_machine=m68k-apollo basic_machine=m68k-apollo
os=-bsd os=-bsd
;; ;;
aros)
basic_machine=i386-pc
os=-aros
;;
aux) aux)
basic_machine=m68k-apple basic_machine=m68k-apple
os=-aux os=-aux
@ -394,10 +459,22 @@ case $basic_machine in
basic_machine=ns32k-sequent basic_machine=ns32k-sequent
os=-dynix os=-dynix
;; ;;
blackfin)
basic_machine=bfin-unknown
os=-linux
;;
blackfin-*)
basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
os=-linux
;;
c90) c90)
basic_machine=c90-cray basic_machine=c90-cray
os=-unicos os=-unicos
;; ;;
cegcc)
basic_machine=arm-unknown
os=-cegcc
;;
convex-c1) convex-c1)
basic_machine=c1-convex basic_machine=c1-convex
os=-bsd os=-bsd
@ -422,12 +499,27 @@ case $basic_machine in
basic_machine=j90-cray basic_machine=j90-cray
os=-unicos os=-unicos
;; ;;
craynv)
basic_machine=craynv-cray
os=-unicosmp
;;
cr16)
basic_machine=cr16-unknown
os=-elf
;;
crds | unos) crds | unos)
basic_machine=m68k-crds basic_machine=m68k-crds
;; ;;
crisv32 | crisv32-* | etraxfs*)
basic_machine=crisv32-axis
;;
cris | cris-* | etrax*) cris | cris-* | etrax*)
basic_machine=cris-axis basic_machine=cris-axis
;; ;;
crx)
basic_machine=crx-unknown
os=-elf
;;
da30 | da30-*) da30 | da30-*)
basic_machine=m68k-da30 basic_machine=m68k-da30
;; ;;
@ -450,6 +542,14 @@ case $basic_machine in
basic_machine=m88k-motorola basic_machine=m88k-motorola
os=-sysv3 os=-sysv3
;; ;;
dicos)
basic_machine=i686-pc
os=-dicos
;;
djgpp)
basic_machine=i586-pc
os=-msdosdjgpp
;;
dpx20 | dpx20-*) dpx20 | dpx20-*)
basic_machine=rs6000-bull basic_machine=rs6000-bull
os=-bosx os=-bosx
@ -600,6 +700,14 @@ case $basic_machine in
basic_machine=m68k-isi basic_machine=m68k-isi
os=-sysv os=-sysv
;; ;;
m68knommu)
basic_machine=m68k-unknown
os=-linux
;;
m68knommu-*)
basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
os=-linux
;;
m88k-omron*) m88k-omron*)
basic_machine=m88k-omron basic_machine=m88k-omron
;; ;;
@ -615,6 +723,10 @@ case $basic_machine in
basic_machine=i386-pc basic_machine=i386-pc
os=-mingw32 os=-mingw32
;; ;;
mingw32ce)
basic_machine=arm-unknown
os=-mingw32ce
;;
miniframe) miniframe)
basic_machine=m68000-convergent basic_machine=m68000-convergent
;; ;;
@ -628,10 +740,6 @@ case $basic_machine in
mips3*) mips3*)
basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
;; ;;
mmix*)
basic_machine=mmix-knuth
os=-mmixware
;;
monitor) monitor)
basic_machine=m68k-rom68k basic_machine=m68k-rom68k
os=-coff os=-coff
@ -644,6 +752,9 @@ case $basic_machine in
basic_machine=i386-pc basic_machine=i386-pc
os=-msdos os=-msdos
;; ;;
ms1-*)
basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
;;
mvs) mvs)
basic_machine=i370-ibm basic_machine=i370-ibm
os=-mvs os=-mvs
@ -719,9 +830,12 @@ case $basic_machine in
basic_machine=hppa1.1-oki basic_machine=hppa1.1-oki
os=-proelf os=-proelf
;; ;;
or32 | or32-*) openrisc | openrisc-*)
basic_machine=or32-unknown basic_machine=or32-unknown
os=-coff ;;
os400)
basic_machine=powerpc-ibm
os=-os400
;; ;;
OSE68000 | ose68000) OSE68000 | ose68000)
basic_machine=m68000-ericsson basic_machine=m68000-ericsson
@ -739,55 +853,75 @@ case $basic_machine in
basic_machine=i860-intel basic_machine=i860-intel
os=-osf os=-osf
;; ;;
parisc)
basic_machine=hppa-unknown
os=-linux
;;
parisc-*)
basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
os=-linux
;;
pbd) pbd)
basic_machine=sparc-tti basic_machine=sparc-tti
;; ;;
pbb) pbb)
basic_machine=m68k-tti basic_machine=m68k-tti
;; ;;
pc532 | pc532-*) pc532 | pc532-*)
basic_machine=ns32k-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) pentium | p5 | k5 | k6 | nexgen | viac3)
basic_machine=i586-pc basic_machine=i586-pc
;; ;;
pentiumpro | p6 | 6x86 | athlon) pentiumpro | p6 | 6x86 | athlon | athlon_*)
basic_machine=i686-pc basic_machine=i686-pc
;; ;;
pentiumii | pentium2) pentiumii | pentium2 | pentiumiii | pentium3)
basic_machine=i686-pc basic_machine=i686-pc
;; ;;
pentium4)
basic_machine=i786-pc
;;
pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
;; ;;
pentiumpro-* | p6-* | 6x86-* | athlon-*) pentiumpro-* | p6-* | 6x86-* | athlon-*)
basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
;; ;;
pentiumii-* | pentium2-*) pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
;; ;;
pentium4-*)
basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
pn) pn)
basic_machine=pn-gould basic_machine=pn-gould
;; ;;
power) basic_machine=power-ibm power) basic_machine=power-ibm
;; ;;
ppc) basic_machine=powerpc-unknown ppc) basic_machine=powerpc-unknown
;; ;;
ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
;; ;;
ppcle | powerpclittle | ppc-le | powerpc-little) ppcle | powerpclittle | ppc-le | powerpc-little)
basic_machine=powerpcle-unknown basic_machine=powerpcle-unknown
;; ;;
ppcle-* | powerpclittle-*) ppcle-* | powerpclittle-*)
basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
;; ;;
ppc64) basic_machine=powerpc64-unknown ppc64) basic_machine=powerpc64-unknown
;; ;;
ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
;; ;;
ppc64le | powerpc64little | ppc64-le | powerpc64-little) ppc64le | powerpc64little | ppc64-le | powerpc64-little)
basic_machine=powerpc64le-unknown basic_machine=powerpc64le-unknown
;; ;;
ppc64le-* | powerpc64little-*) ppc64le-* | powerpc64little-*)
basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
;; ;;
@ -798,6 +932,10 @@ case $basic_machine in
basic_machine=i586-unknown basic_machine=i586-unknown
os=-pw32 os=-pw32
;; ;;
rdos)
basic_machine=i386-pc
os=-rdos
;;
rom68k) rom68k)
basic_machine=m68k-rom68k basic_machine=m68k-rom68k
os=-coff os=-coff
@ -818,6 +956,20 @@ case $basic_machine in
basic_machine=a29k-amd basic_machine=a29k-amd
os=-udi 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) sequent)
basic_machine=i386-sequent basic_machine=i386-sequent
;; ;;
@ -825,6 +977,12 @@ case $basic_machine in
basic_machine=sh-hitachi basic_machine=sh-hitachi
os=-hms os=-hms
;; ;;
sh5el)
basic_machine=sh5le-unknown
;;
sh64)
basic_machine=sh64-unknown
;;
sparclite-wrs | simso-wrs) sparclite-wrs | simso-wrs)
basic_machine=sparclite-wrs basic_machine=sparclite-wrs
os=-vxworks os=-vxworks
@ -883,7 +1041,7 @@ case $basic_machine in
sun386 | sun386i | roadrunner) sun386 | sun386i | roadrunner)
basic_machine=i386-sun basic_machine=i386-sun
;; ;;
sv1) sv1)
basic_machine=sv1-cray basic_machine=sv1-cray
os=-unicos os=-unicos
;; ;;
@ -891,10 +1049,6 @@ case $basic_machine in
basic_machine=i386-sequent basic_machine=i386-sequent
os=-dynix os=-dynix
;; ;;
t3d)
basic_machine=alpha-cray
os=-unicos
;;
t3e) t3e)
basic_machine=alphaev5-cray basic_machine=alphaev5-cray
os=-unicos os=-unicos
@ -907,6 +1061,18 @@ case $basic_machine in
basic_machine=tic54x-unknown basic_machine=tic54x-unknown
os=-coff 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) tx39)
basic_machine=mipstx39-unknown basic_machine=mipstx39-unknown
;; ;;
@ -920,6 +1086,10 @@ case $basic_machine in
tower | tower-32) tower | tower-32)
basic_machine=m68k-ncr basic_machine=m68k-ncr
;; ;;
tpf)
basic_machine=s390x-ibm
os=-tpf
;;
udi29k) udi29k)
basic_machine=a29k-amd basic_machine=a29k-amd
os=-udi os=-udi
@ -941,8 +1111,8 @@ case $basic_machine in
os=-vms os=-vms
;; ;;
vpp*|vx|vx-*) vpp*|vx|vx-*)
basic_machine=f301-fujitsu basic_machine=f301-fujitsu
;; ;;
vxworks960) vxworks960)
basic_machine=i960-wrs basic_machine=i960-wrs
os=-vxworks os=-vxworks
@ -963,11 +1133,11 @@ case $basic_machine in
basic_machine=hppa1.1-winbond basic_machine=hppa1.1-winbond
os=-proelf os=-proelf
;; ;;
windows32) xbox)
basic_machine=i386-pc basic_machine=i686-pc
os=-windows32-msvcrt os=-mingw32
;; ;;
xps | xps100) xps | xps100)
basic_machine=xps100-honeywell basic_machine=xps100-honeywell
;; ;;
ymp) ymp)
@ -978,6 +1148,10 @@ case $basic_machine in
basic_machine=z8k-unknown basic_machine=z8k-unknown
os=-sim os=-sim
;; ;;
z80-*-coff)
basic_machine=z80-unknown
os=-sim
;;
none) none)
basic_machine=none-none basic_machine=none-none
os=-none os=-none
@ -997,6 +1171,9 @@ case $basic_machine in
romp) romp)
basic_machine=romp-ibm basic_machine=romp-ibm
;; ;;
mmix)
basic_machine=mmix-knuth
;;
rs6000) rs6000)
basic_machine=rs6000-ibm basic_machine=rs6000-ibm
;; ;;
@ -1013,16 +1190,13 @@ case $basic_machine in
we32k) we32k)
basic_machine=we32k-att 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 basic_machine=sh-unknown
;; ;;
sh64) sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
basic_machine=sh64-unknown
;;
sparc | sparcv9 | sparcv9b)
basic_machine=sparc-sun basic_machine=sparc-sun
;; ;;
cydra) cydra)
basic_machine=cydra-cydrome basic_machine=cydra-cydrome
;; ;;
orion) orion)
@ -1037,10 +1211,6 @@ case $basic_machine in
pmac | pmac-mpw) pmac | pmac-mpw)
basic_machine=powerpc-apple basic_machine=powerpc-apple
;; ;;
c4x*)
basic_machine=c4x-none
os=-coff
;;
*-unknown) *-unknown)
# Make sure to match an already-canonicalized machine name. # Make sure to match an already-canonicalized machine name.
;; ;;
@ -1092,22 +1262,28 @@ case $os in
-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
| -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
| -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
| -kopensolaris* \
| -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
| -aos* \ | -aos* | -aros* \
| -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
| -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
| -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
| -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -openbsd* | -solidbsd* \
| -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
| -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
| -chorusos* | -chorusrdb* \ | -chorusos* | -chorusrdb* | -cegcc* \
| -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
| -mingw32* | -linux* | -uxpv* | -beos* | -mpeix* | -udk* \ | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \
| -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \ | -uxpv* | -beos* | -mpeix* | -udk* \
| -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
| -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
| -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
| -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | -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. # Remember, each alternative MUST END IN *, to match a version number.
;; ;;
-qnx*) -qnx*)
@ -1119,16 +1295,24 @@ case $os in
;; ;;
esac esac
;; ;;
-nto-qnx*)
;;
-nto*) -nto*)
os=-nto-qnx os=`echo $os | sed -e 's|nto|nto-qnx|'`
;; ;;
-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ -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*) | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
;; ;;
-mac*) -mac*)
os=`echo $os | sed -e 's|mac|macos|'` os=`echo $os | sed -e 's|mac|macos|'`
;; ;;
-linux-dietlibc)
os=-linux-dietlibc
;;
-linux*)
os=`echo $os | sed -e 's|linux|linux-gnu|'`
;;
-sunos5*) -sunos5*)
os=`echo $os | sed -e 's|sunos5|solaris2|'` os=`echo $os | sed -e 's|sunos5|solaris2|'`
;; ;;
@ -1138,6 +1322,9 @@ case $os in
-opened*) -opened*)
os=-openedition os=-openedition
;; ;;
-os400*)
os=-os400
;;
-wince*) -wince*)
os=-wince os=-wince
;; ;;
@ -1159,6 +1346,9 @@ case $os in
-atheos*) -atheos*)
os=-atheos os=-atheos
;; ;;
-syllable*)
os=-syllable
;;
-386bsd) -386bsd)
os=-bsd os=-bsd
;; ;;
@ -1169,7 +1359,7 @@ case $os in
os=-rtmk-nova os=-rtmk-nova
;; ;;
-ns2 ) -ns2 )
os=-nextstep2 os=-nextstep2
;; ;;
-nsk*) -nsk*)
os=-nsk os=-nsk
@ -1181,6 +1371,9 @@ case $os in
-sinix*) -sinix*)
os=-sysv4 os=-sysv4
;; ;;
-tpf*)
os=-tpf
;;
-triton*) -triton*)
os=-sysv3 os=-sysv3
;; ;;
@ -1208,8 +1401,20 @@ case $os in
-xenix) -xenix)
os=-xenix os=-xenix
;; ;;
-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
os=-mint os=-mint
;;
-aros*)
os=-aros
;;
-kaos*)
os=-kaos
;;
-zvmoe)
os=-zvmoe
;;
-dicos*)
os=-dicos
;; ;;
-none) -none)
;; ;;
@ -1233,6 +1438,12 @@ else
# system, and we'll never get to this point. # system, and we'll never get to this point.
case $basic_machine in case $basic_machine in
score-*)
os=-elf
;;
spu-*)
os=-elf
;;
*-acorn) *-acorn)
os=-riscix1.2 os=-riscix1.2
;; ;;
@ -1242,11 +1453,14 @@ case $basic_machine in
arm*-semi) arm*-semi)
os=-aout os=-aout
;; ;;
c4x-* | tic4x-*)
os=-coff
;;
# This must come before the *-dec entry. # This must come before the *-dec entry.
pdp10-*) pdp10-*)
os=-tops20 os=-tops20
;; ;;
pdp11-*) pdp11-*)
os=-none os=-none
;; ;;
*-dec | vax-*) *-dec | vax-*)
@ -1267,6 +1481,9 @@ case $basic_machine in
m68*-cisco) m68*-cisco)
os=-aout os=-aout
;; ;;
mep-*)
os=-elf
;;
mips*-cisco) mips*-cisco)
os=-elf os=-elf
;; ;;
@ -1285,9 +1502,15 @@ case $basic_machine in
*-be) *-be)
os=-beos os=-beos
;; ;;
*-haiku)
os=-haiku
;;
*-ibm) *-ibm)
os=-aix os=-aix
;; ;;
*-knuth)
os=-mmixware
;;
*-wec) *-wec)
os=-proelf os=-proelf
;; ;;
@ -1339,19 +1562,19 @@ case $basic_machine in
*-next) *-next)
os=-nextstep3 os=-nextstep3
;; ;;
*-gould) *-gould)
os=-sysv os=-sysv
;; ;;
*-highlevel) *-highlevel)
os=-bsd os=-bsd
;; ;;
*-encore) *-encore)
os=-bsd os=-bsd
;; ;;
*-sgi) *-sgi)
os=-irix os=-irix
;; ;;
*-siemens) *-siemens)
os=-sysv4 os=-sysv4
;; ;;
*-masscomp) *-masscomp)
@ -1420,9 +1643,15 @@ case $basic_machine in
-mvs* | -opened*) -mvs* | -opened*)
vendor=ibm vendor=ibm
;; ;;
-os400*)
vendor=ibm
;;
-ptx*) -ptx*)
vendor=sequent vendor=sequent
;; ;;
-tpf*)
vendor=ibm
;;
-vxsim* | -vxworks* | -windiss*) -vxsim* | -vxworks* | -windiss*)
vendor=wrs vendor=wrs
;; ;;
@ -1447,7 +1676,7 @@ case $basic_machine in
esac esac
echo $basic_machine$os echo $basic_machine$os
exit 0 exit
# Local variables: # Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp) # eval: (add-hook 'write-file-hooks 'time-stamp)

View File

@ -11,6 +11,13 @@ AC_CONFIG_HEADER(tgt-vhdl/vhdl_config.h)
AC_CANONICAL_HOST AC_CANONICAL_HOST
dnl Checks for programs. dnl Checks for programs.
AC_PROG_CC 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_CXX
AC_PROG_RANLIB AC_PROG_RANLIB
AC_CHECK_TOOL(STRIP, strip, true) AC_CHECK_TOOL(STRIP, strip, true)
@ -79,12 +86,17 @@ AC_CHECK_LIB(bz2, BZ2_bzdopen, HAVE_LIBBZ2=yes, HAVE_LIBBZ2=no)
fi fi
AC_SUBST(HAVE_LIBBZ2) AC_SUBST(HAVE_LIBBZ2)
# The lxt/lxt2 files from GTKWave use these...
AC_FUNC_ALLOCA
AC_FUNC_FSEEKO
# valgrind checks # valgrind checks
AC_ARG_WITH([valgrind], [AS_HELP_STRING([--with-valgrind], AC_ARG_WITH([valgrind], [AC_HELP_STRING([--with-valgrind],
[Add valgrind hooks])], [Add valgrind hooks])],
[], [check_valgrind=yes]) [], [check_valgrind=yes])
AS_IF([test "x$check_valgrind" == xyes], AS_IF([test "x$check_valgrind" = xyes],
[AC_MSG_NOTICE([Not using valgrind hooks])], [AC_MSG_NOTICE([Not using valgrind hooks])],
[AC_CHECK_HEADER([valgrind/memcheck.h], [AC_CHECK_HEADER([valgrind/memcheck.h],
[AC_DEFINE([CHECK_WITH_VALGRIND], [1], [AC_DEFINE([CHECK_WITH_VALGRIND], [1],
@ -156,7 +168,41 @@ AC_SUBST(file64_support)
# Check that these functions exist. They are mostly C99 # Check that these functions exist. They are mostly C99
# functions that older compilers may not yet support. # functions that older compilers may not yet support.
AC_CHECK_FUNCS(lround nan fmin fmax fopen64) 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 # Linker option used when compiling the target
AX_LD_RDYNAMIC AX_LD_RDYNAMIC
@ -181,21 +227,21 @@ AX_C_UNDERSCORES_TRAILING
####################### #######################
AC_MSG_CHECKING(for sanity of prefix) AC_MSG_CHECKING(for sanity of prefix)
if test X`echo "$prefix" | wc -w` != X1 if test `echo "$prefix" | wc -w` != 1
then then
AC_MSG_ERROR(cannot configure white space in prefix: $prefix) AC_MSG_ERROR(cannot configure white space in prefix: $prefix)
fi fi
AC_MSG_RESULT(ok) AC_MSG_RESULT(ok)
AC_MSG_CHECKING(for sanity of exec_prefix) AC_MSG_CHECKING(for sanity of exec_prefix)
if test X`echo "$exec_prefix" | wc -w` != X1 if test `echo "$exec_prefix" | wc -w` != 1
then then
AC_MSG_ERROR(cannot configure white space in exec_prefix: $exec_prefix) AC_MSG_ERROR(cannot configure white space in exec_prefix: $exec_prefix)
fi fi
AC_MSG_RESULT(ok) AC_MSG_RESULT(ok)
AC_MSG_CHECKING(for sanity of libdir) AC_MSG_CHECKING(for sanity of libdir)
if test X`echo "$libdir" | wc -w` != X1 if test `echo "$libdir" | wc -w` != 1
then then
AC_MSG_ERROR(cannot configure white space in libdir: $libdir) AC_MSG_ERROR(cannot configure white space in libdir: $libdir)
fi fi

View File

@ -823,6 +823,10 @@ void cprop_functor::lpm_mux(Design*des, NetMux*obj)
/* If the select input is constant, then replace with a BUFZ */ /* If the select input is constant, then replace with a BUFZ */
bool flag = obj->pin_Sel().nexus()->drivers_constant(); bool flag = obj->pin_Sel().nexus()->drivers_constant();
/* Note that this cannot be constant if there are assignments
to this nexus. (Assignments include "force" to nets.) */
flag &= !obj->pin_Sel().nexus()->assign_lval();
verinum::V sel_val = flag? obj->pin_Sel().nexus()->driven_value() : verinum::Vx; verinum::V sel_val = flag? obj->pin_Sel().nexus()->driven_value() : verinum::Vx;
if ((sel_val != verinum::Vz) && (sel_val != verinum::Vx)) { if ((sel_val != verinum::Vz) && (sel_val != verinum::Vx)) {
NetBUFZ*tmp = new NetBUFZ(obj->scope(), obj->name(), obj->width()); NetBUFZ*tmp = new NetBUFZ(obj->scope(), obj->name(), obj->width());

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1998-2008 Stephen Williams (steve@icarus.com) * Copyright (c) 1998-2009 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -208,8 +208,12 @@ void NetNet::dump_net(ostream&o, unsigned ind) const
o << " scope=" << scope_path(scope()); o << " scope=" << scope_path(scope());
o << " #(" << rise_time() << "," << fall_time() << "," o << " #(" << rise_time() << "," << fall_time() << ","
<< decay_time() << ") vector_width=" << vector_width() << decay_time() << ") vector_width=" << vector_width()
<< " pin_count=" << pin_count() << " pin_count=" << pin_count();
<< " init="; if (pins_are_virtual()) {
o << " pins_are_virtual" << endl;
return;
}
o << " init=";
for (unsigned idx = pin_count() ; idx > 0 ; idx -= 1) for (unsigned idx = pin_count() ; idx > 0 ; idx -= 1)
o << pin(idx-1).get_init(); o << pin(idx-1).get_init();
@ -1073,29 +1077,11 @@ void NetRepeat::dump(ostream&o, unsigned ind) const
void NetScope::dump(ostream&o) const void NetScope::dump(ostream&o) const
{ {
/* This is a constructed hierarchical name. */ /* This is a constructed hierarchical name. */
o << scope_path(this); o << scope_path(this) << " ";
switch (type_) { print_type(o);
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;
}
if (is_auto()) o << " (automatic)"; if (is_auto()) o << " (automatic)";
if (is_cell()) o << " (cell)";
o << endl; o << endl;
for (unsigned idx = 0 ; idx < attr_cnt() ; idx += 1) for (unsigned idx = 0 ; idx < attr_cnt() ; idx += 1)

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 * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * 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 * 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., 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 * 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"); ofile = fopen(argv[2], "wb");
if (ofile == 0) { if (ofile == 0) {
fprintf(stderr, "Unable to open %s for output.\n", argv[2]); fprintf(stderr, "Unable to open %s for output.\n", argv[2]);
fclose(ifile);
return 2; return 2;
} }
@ -64,25 +62,7 @@ int main(int argc, char*argv[])
pr = ch; pr = ch;
} }
fclose(ifile);
fclose(ofile);
return 0; 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.
*
*/

View File

@ -50,20 +50,20 @@ all: iverilog-vpi@EXEEXT@
check: all check: all
clean: clean:
rm -f *.o config.h iverilog-vpi@EXEEXT@ rm -f *.o config.h iverilog-vpi@EXEEXT@ res.rc
distclean: clean distclean: clean
rm -f Makefile config.log rm -f Makefile config.log
Makefile: $(srcdir)/Makefile.in ../config.status Makefile: $(srcdir)/Makefile.in ../config.status
../config.status --file=$@ cd ..; ./config.status --file=driver-vpi/$@
O = main.o res.o O = main.o res.o
iverilog-vpi@EXEEXT@: $O iverilog-vpi@EXEEXT@: $O
$(CC) $(LDFLAGS) $O -o iverilog-vpi@EXEEXT@ @EXTRALIBS@ $(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 $(CC) $(CPPFLAGS) $(CFLAGS) -c $(srcdir)/main.c
@ -74,6 +74,10 @@ config.h: $(srcdir)/config.h.in Makefile
-e 's;@SHARED@;@shared@;' $< > $@ -e 's;@SHARED@;@shared@;' $< > $@
# Windows specific... # 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 res.o: res.rc
windres -i res.rc -o res.o windres -i res.rc -o res.o
# #

View File

@ -413,11 +413,18 @@ static void checkMingwDir(char *root)
int irv; int irv;
struct _stat stat_buf; struct _stat stat_buf;
char *path; char *path, *comp, *cp;
initDynString(&path); initDynString(&path);
assign(&path,gstr.pMINGW); assign(&path,gstr.pMINGW);
appendBackSlash(&path); 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); irv = _stat(path,&stat_buf);
deInitDynString(path); deInitDynString(path);
@ -511,16 +518,16 @@ static void setup_ivl_environment()
} }
/* Build up the CFLAGS option string */ /* Build up the CFLAGS option string */
assign(&gstr.pCFLAGS,IVERILOG_VPI_CFLAGS " -I"); assign(&gstr.pCFLAGS,IVERILOG_VPI_CFLAGS " -I\"");
append(&gstr.pCFLAGS,gstr.pIVL); append(&gstr.pCFLAGS,gstr.pIVL);
appendBackSlash(&gstr.pCFLAGS); appendBackSlash(&gstr.pCFLAGS);
append(&gstr.pCFLAGS,"\\include\\\\iverilog" IVERILOG_SUFFIX); append(&gstr.pCFLAGS,"\\include\\\\iverilog\"" IVERILOG_SUFFIX);
/* Build up the LDFLAGS option string */ /* Build up the LDFLAGS option string */
assign(&gstr.pLDLIBS,"-L"); assign(&gstr.pLDLIBS,"-L\"");
append(&gstr.pLDLIBS,gstr.pIVL); append(&gstr.pLDLIBS,gstr.pIVL);
appendBackSlash(&gstr.pLDLIBS); appendBackSlash(&gstr.pLDLIBS);
append(&gstr.pLDLIBS,"\\lib " IVERILOG_VPI_LDLIBS); append(&gstr.pLDLIBS,"\\lib\" " IVERILOG_VPI_LDLIBS);
} }
/* compile source modules */ /* compile source modules */

View File

@ -10,7 +10,7 @@ LANGUAGE 9, 4
1 VERSIONINFO 1 VERSIONINFO
FILEVERSION 2002,11,13,0 FILEVERSION 2002,11,13,0
PRODUCTVERSION 0,7,0,0 PRODUCTVERSION @PRODUCTVERSION@
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
FILEFLAGS 0x2L FILEFLAGS 0x2L
FILEOS 0x40004L FILEOS 0x40004L
@ -28,7 +28,7 @@ BEGIN
VALUE "LegalCopyright", "Copyright 2002 Gus Baldauf\0" VALUE "LegalCopyright", "Copyright 2002 Gus Baldauf\0"
VALUE "OriginalFilename", "iverilog-vpi.exe\0" VALUE "OriginalFilename", "iverilog-vpi.exe\0"
VALUE "ProductName", "Icarus Verilog\0" VALUE "ProductName", "Icarus Verilog\0"
VALUE "ProductVersion", "0, 7, 0, 0\0" VALUE "ProductVersion", "@PRODUCTVERSION@\0"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"

View File

@ -45,21 +45,20 @@ CPPFLAGS = -I. -I.. -I$(srcdir)/.. -I$(srcdir) @CPPFLAGS@ @DEFS@
CFLAGS = -Wall @CFLAGS@ CFLAGS = -Wall @CFLAGS@
LDFLAGS = @LDFLAGS@ LDFLAGS = @LDFLAGS@
all: dep iverilog@EXEEXT@ all: dep iverilog@EXEEXT@ iverilog.man
check: all check: all
clean: clean:
rm -f *.o lexor.c parse.c parse.h parse.output rm -f *.o cflexor.c cfparse.c cfparse.h cfparse.output
rm -f cflexor.c cfparse.c cfparse.h cfparse.output rm -f iverilog@EXEEXT@ iverilog.man iverilog.pdf iverilog.ps
rm -f iverilog@EXEEXT@ iverilog.pdf iverilog.ps
rm -rf dep rm -rf dep
distclean: clean distclean: clean
rm -f Makefile config.log rm -f Makefile config.log
Makefile: $(srcdir)/Makefile.in ../config.status Makefile: $(srcdir)/Makefile.in ../config.status
../config.status --file=$@ cd ..; ./config.status --file=driver/$@
O = main.o substit.o cflexor.o cfparse.o O = main.o substit.o cflexor.o cfparse.o
@ -79,14 +78,18 @@ dep:
$(CC) $(CPPFLAGS) $(CFLAGS) -MD -c $< -o $*.o $(CC) $(CPPFLAGS) $(CFLAGS) -MD -c $< -o $*.o
mv $*.d dep mv $*.d dep
main.o: main.c globals.h ../version.h Makefile 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_INC='"@includedir@"' -DIVL_LIB='"@libdir@"' -DDLLIB='"@DLLIB@"' $(srcdir)/main.c $(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 mv $*.d dep
cflexor.o: cflexor.c cfparse.h cflexor.o: cflexor.c cfparse.h
iverilog.ps: $(srcdir)/iverilog.man iverilog.man: $(srcdir)/iverilog.man.in ../version.exe
$(MAN) -t $(srcdir)/iverilog.man > iverilog.ps ../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 iverilog.pdf: iverilog.ps
$(PS2PDF) iverilog.ps iverilog.pdf $(PS2PDF) iverilog.ps iverilog.pdf
@ -113,8 +116,8 @@ install: all installdirs $(bindir)/iverilog$(suffix)@EXEEXT@ $(INSTALL_DOC)
$(bindir)/iverilog$(suffix)@EXEEXT@: ./iverilog@EXEEXT@ $(bindir)/iverilog$(suffix)@EXEEXT@: ./iverilog@EXEEXT@
$(INSTALL_PROGRAM) ./iverilog@EXEEXT@ "$(DESTDIR)$(bindir)/iverilog$(suffix)@EXEEXT@" $(INSTALL_PROGRAM) ./iverilog@EXEEXT@ "$(DESTDIR)$(bindir)/iverilog$(suffix)@EXEEXT@"
$(mandir)/man1/iverilog$(suffix).1: $(srcdir)/iverilog.man $(mandir)/man1/iverilog$(suffix).1: iverilog.man
$(INSTALL_DATA) $(srcdir)/iverilog.man "$(DESTDIR)$(mandir)/man1/iverilog$(suffix).1" $(INSTALL_DATA) iverilog.man "$(DESTDIR)$(mandir)/man1/iverilog$(suffix).1"
$(prefix)/iverilog$(suffix).pdf: iverilog.pdf $(prefix)/iverilog$(suffix).pdf: iverilog.pdf
$(INSTALL_DATA) iverilog.pdf "$(DESTDIR)$(prefix)/iverilog$(suffix).pdf" $(INSTALL_DATA) iverilog.pdf "$(DESTDIR)$(prefix)/iverilog$(suffix).pdf"

View File

@ -4,7 +4,7 @@
%{ %{
/* /*
* 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 * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * 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 * 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., 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.h"
# include "cfparse_misc.h" # include "cfparse_misc.h"
@ -236,3 +233,17 @@ void cfreset(FILE*fd, const char*path)
current_file = strdup(path); current_file = strdup(path);
cflloc.first_line = 1; 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
}

View File

@ -1,6 +1,6 @@
%{ %{
/* /*
* Copyright (c) 20001 Stephen Williams (steve@icarus.com) * Copyright (c) 2001-2009 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * 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 * 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., 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 "globals.h"
# include "cfparse_misc.h" # include "cfparse_misc.h"

View File

@ -1,7 +1,7 @@
#ifndef __cfparse_misc_H #ifndef __cfparse_misc_H
#define __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) * Stephen Williams (steve@picturel.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
@ -38,6 +38,7 @@ int cflex(void);
int cferror(const char *); int cferror(const char *);
int cfparse(void); int cfparse(void);
void switch_to_command_file(const char *); void switch_to_command_file(const char *);
void destroy_lexor();
char *current_file; char *current_file;
#endif #endif

View File

@ -1,7 +1,7 @@
#ifndef __globals_H #ifndef __globals_H
#define __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 * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -21,31 +21,6 @@
# include <stddef.h> # 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. */ /* This is the integer-width argument that will be passed to ivl. */
extern unsigned integer_width; extern unsigned integer_width;
@ -66,13 +41,4 @@ extern void process_include_dir(const char*name);
/* Add a new -D define. */ /* Add a new -D define. */
extern void process_define(const char*name); extern void process_define(const char*name);
/* -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;
#endif #endif

View File

@ -1,13 +1,13 @@
.TH iverilog 1 "February 4th, 2009" "" "Version 0.9.devel" .TH iverilog 1 "October 28th, 2009" "" "Version %M.%m.%n %E"
.SH NAME .SH NAME
iverilog - Icarus Verilog compiler iverilog - Icarus Verilog compiler
.SH SYNOPSIS .SH SYNOPSIS
.B iverilog .B iverilog
[-ESVv] [-Bpath] [-ccmdfile|-fcmdfile] [-Dmacro[=defn]] [-pflag=value] [\-ESVv] [\-Bpath] [\-ccmdfile|\-fcmdfile] [\-Dmacro[=defn]] [\-pflag=value]
[-dname] [-g1995|-g2001|-g2005|-g<feature>] [\-dname] [\-g1995|\-g2001|\-g2005|\-g<feature>]
[-Iincludedir] [-mmodule] [-Mfile] [-Nfile] [-ooutputfilename] [\-Iincludedir] [\-mmodule] [\-Mfile] [\-Nfile] [\-ooutputfilename]
[-stopmodule] [-ttype] [-Tmin/typ/max] [-Wclass] [-ypath] sourcefile [\-stopmodule] [\-ttype] [\-Tmin/typ/max] [\-Wclass] [\-ypath] sourcefile
.SH DESCRIPTION .SH DESCRIPTION
.PP .PP
@ -18,14 +18,13 @@ simulation, and \fIfpga\fP for synthesis. Other target
types are added as code generators are implemented. types are added as code generators are implemented.
.SH OPTIONS .SH OPTIONS
.l
\fIiverilog\fP accepts the following options: \fIiverilog\fP accepts the following options:
.TP 8 .TP 8
.B -B\fIbase\fP .B -B\fIbase\fP
The \fIiverilog\fP program uses external programs and configuration The \fIiverilog\fP program uses external programs and configuration
files to preprocess and compile the Verilog source. Normally, the path files to preprocess and compile the Verilog source. Normally, the path
used to locate these tools is built into the \fIiverilog\fP 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 different set of programs. The path given is used to locate
\fIivlpp\fP, \fIivl\fP, code generators and the VPI modules. \fIivlpp\fP, \fIivl\fP, code generators and the VPI modules.
.TP 8 .TP 8
@ -44,7 +43,7 @@ Verilog source.
Defines macro \fImacro\fP as \fIdefn\fP. Defines macro \fImacro\fP as \fIdefn\fP.
.TP 8 .TP 8
.B -d\fIname\fP .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. be used as often as necessary to activate all the desired messages.
Supported names are scopes, eval_tree, elaborate, and synth2; Supported names are scopes, eval_tree, elaborate, and synth2;
any other names are ignored. any other names are ignored.
@ -55,17 +54,18 @@ is the Verilog input, but with file inclusions and macro references
expanded and removed. This is useful, for example, to preprocess expanded and removed. This is useful, for example, to preprocess
Verilog source for use by other compilers. Verilog source for use by other compilers.
.TP 8 .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 Select the Verilog language \fIgeneration\fP to support in the
compiler. This selects between \fIIEEE1364-1995\fP, compiler. This selects between \fIIEEE1364\-1995\fP,
\fIIEEE1364-2001\fP(2), or \fIIEEE1364-2005\fP. Normally, \fIIEEE1364\-2001\fP, or \fIIEEE1364\-2005\fP. Normally,
Icarus Verilog defaults to the latest known generation of the Icarus Verilog defaults to the latest known generation of the
language. This flag is most useful to restrict the language to a set language. This flag is most useful to restrict the language to a set
supported by tools of specific generations, for compatibility with supported by tools of specific generations, for compatibility with
other tools. other tools.
.TP 8 .TP 8
.B -gverilog-ams\fI|-fP-gno-verilog-ams .B -gverilog-ams\fI|\fP-gno-verilog-ams
Enable or disable (default) support for Verilog-AMS. Enable or disable (default) support for Verilog\-AMS.
Very little Verilog\-AMS specific functionality is currently supported.
.TP 8 .TP 8
.B -gspecify\fI|\fP-gno-specify .B -gspecify\fI|\fP-gno-specify
Enable or disable (default) specify block support. When enabled, Enable or disable (default) specify block support. When enabled,
@ -100,7 +100,7 @@ The standards requires that a vectored port have matching ranges for its
port declaration as well as any net/register declaration. It was common 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 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 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 warning instead of a fatal error for the case of a vectored net/register
and a scalar port declaration. and a scalar port declaration.
.TP 8 .TP 8
@ -110,13 +110,13 @@ expression changes value, the entire expression is re-evaluated. By
default, parts of the expression that do not depend on the changed 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 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 to a function that doesn't depend solely on its input values or that
has side effects, the resulting behaviour will differ from that has side effects, the resulting behavior will differ from that
required by the standard. Using \fI-gstrict-ca-eval\fP will force required by the standard. Using \fI\-gstrict\-ca\-eval\fP will force
standard compliant behaviour (with some loss in performance). standard compliant behavior (with some loss in performance).
.TP 8 .TP 8
.B -I\fIincludedir\fP .B -I\fIincludedir\fP
Append directory \fIincludedir\fP to list of directories searched 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 to specify several directories to search, the directories are searched
in the order they appear on the command line. in the order they appear on the command line.
.TP 8 .TP 8
@ -145,7 +145,7 @@ Place output in the file \fIfilename\fP. If no output file name is
specified, \fIiverilog\fP uses the default name \fBa.out\fP. specified, \fIiverilog\fP uses the default name \fBa.out\fP.
.TP 8 .TP 8
.B -p\fIflag=value\fP .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 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 that are used depend on the target that is selected, and are described
in target specific documentation. Flags that are not used are ignored. in target specific documentation. Flags that are not used are ignored.
@ -153,15 +153,15 @@ in target specific documentation. Flags that are not used are ignored.
.B -S .B -S
Synthesize. Normally, if the target can accept behavioral Synthesize. Normally, if the target can accept behavioral
descriptions the compiler will leave processes in 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 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 .TP 8
.B -s \fItopmodule\fP .B -s \fItopmodule\fP
Specify the top level module to elaborate. Icarus Verilog will by default Specify the top level module to elaborate. Icarus Verilog will by default
choose modules that are not instantiated in any other modules, but choose modules that are not instantiated in any other modules, but
sometimes that is not sufficient, or instantiates too many modules. If 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. they will be used as root modules instead.
.TP 8 .TP 8
.B -T\fImin|typ|max\fP .B -T\fImin|typ|max\fP
@ -191,13 +191,18 @@ Print the version of the compiler, and exit.
.B -W\fIclass\fP .B -W\fIclass\fP
Turn on different classes of warnings. See the \fBWARNING TYPES\fP Turn on different classes of warnings. See the \fBWARNING TYPES\fP
section below for descriptions of the different warning groups. If 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. all the requested classes.
.TP 8 .TP 8
.B -y\fIlibdir\fP .B -y\fIlibdir\fP
Append the directory to the library module search path. When the Append the directory to the library module search path. When the
compiler finds an undefined module, it looks in these directories for compiler finds an undefined module, it looks in these directories for
files with the right name. 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 .SH MODULE LIBRARIES
@ -216,7 +221,7 @@ library or in the main design.
.SH TARGETS .SH TARGETS
The Icarus Verilog compiler supports a variety of targets, for 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. desired target.
.TP 8 .TP 8
@ -234,7 +239,7 @@ This is a synthesis target that supports a variety of fpga devices,
mostly by EDIF format output. The Icarus Verilog fpga code generator mostly by EDIF format output. The Icarus Verilog fpga code generator
can generate complete designs or EDIF macros that can in turn be can generate complete designs or EDIF macros that can in turn be
imported into larger designs by other tools. The \fBfpga\fP target 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 .TP 8
.B vhdl .B vhdl
This target produces a VHDL translation of the Verilog netlist. The This target produces a VHDL translation of the Verilog netlist. The
@ -243,14 +248,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. the Verilog language is supported. See the wiki for more information.
.SH "WARNING TYPES" .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 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 prefixed with \fBno\-\fP to turn off that warning. This is most useful
after a \fB-Wall\fP argument to suppress isolated warning types. after a \fB\-Wall\fP argument to suppress isolated warning types.
.TP 8 .TP 8
.B all .B all
This enables all supported warning categories. This enables the implicit, portbind, select\-range, timescale, and
sensitivity\-entire\-array warning categories.
.TP 8 .TP 8
.B implicit .B implicit
@ -264,6 +270,12 @@ This enables warnings for ports of module instantiations that are not
connected but probably should be. Dangling input ports, for example, connected but probably should be. Dangling input ports, for example,
will generate a warning. 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 .TP 8
.B timescale .B timescale
This enables warnings for inconsistent use of the timescale This enables warnings for inconsistent use of the timescale
@ -276,7 +288,7 @@ and dependent on compilation order.
.B infloop .B infloop
This enables warnings for \fRalways\fP statements that may have runtime This enables warnings for \fRalways\fP statements that may have runtime
infinite loops (has paths with no or zero delay). This class of warnings 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 A fatal error message will always be printed when the compiler can
determine that there will definitely be an infinite loop (all paths have determine that there will definitely be an infinite loop (all paths have
no or zero delay). no or zero delay).
@ -287,6 +299,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 positives, since the code treats the value of all variables and signals
as indeterminate. 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" .SH "SYSTEM FUNCTION TABLE FILES"
If the source file name as a \fB.sft\fP suffix, then it is taken to be 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 a system function table file. A System function table file is used to
@ -328,14 +356,14 @@ character. Variables are substituted in file names.
.TP 8 .TP 8
.B -c\ \fIcmdfile\fP -f\ \fIcmdfile\fP .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 does on the command line. The cmdfile may be on the same line or the
next non-comment line. next non-comment line.
.TP 8 .TP 8
.B -y\ \fIlibdir\fP .B -y\ \fIlibdir\fP
A \fB-y\fP token prefixes a library directory in the command file, 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 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. flag may be on the same line or the next non-comment line.
Variables in the \fIlibdir\fP are substituted. Variables in the \fIlibdir\fP are substituted.
@ -343,7 +371,7 @@ Variables in the \fIlibdir\fP are substituted.
.TP 8 .TP 8
.B +incdir+\fIincludedir\fP .B +incdir+\fIincludedir\fP
The \fB+incdir+\fP token in command files gives directories to search 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 command line. The difference is that multiple \fI+includedir\fP
directories are valid parameters to a single \fB+incdir+\fP token, directories are valid parameters to a single \fB+incdir+\fP token,
although you may also have multiple \fB+incdir+\fP lines. although you may also have multiple \fB+incdir+\fP lines.
@ -354,12 +382,12 @@ Variables in the \fIincludedir\fP are substituted.
.B +libext+\fIext\fP .B +libext+\fIext\fP
The \fB+libext\fP token in command files fives file extensions to try 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 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. on to the next library directory.
.TP 8 .TP 8
.B +libdir+\fIdir\fP .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 .TP 8
.B +libdir-nocase+\fIdir\fP .B +libdir-nocase+\fIdir\fP
@ -371,19 +399,19 @@ letters are correct. For example, "foo" matches "Foo.v" but not
.TP 8 .TP 8
.B +define+\fINAME\fP=\fIvalue\fP .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. command line. The value part of the token is optional.
.TP 8 .TP 8
.B +toupper-filename\fP .B +toupper-filename
This token causes file names after this in the command file to be This token causes file names after this in the command file to be
translated to uppercase. This helps with situations where a directory translated to uppercase. This helps with situations where a directory
has passed through a DOS machine, and in the process the file names has passed through a DOS machine, and in the process the file names
become munged. become munged.
.TP 8 .TP 8
.B +tolower-filename\fP .B +tolower-filename
This is similar to the \fB+toupper-filename\fP hack described above. This is similar to the \fB+toupper\-filename\fP hack described above.
.TP 8 .TP 8
.B +integer-width+\fIvalue\fP .B +integer-width+\fIvalue\fP
@ -394,7 +422,8 @@ integer value.
.SH "VARIABLES IN COMMAND FILES" .SH "VARIABLES IN COMMAND FILES"
In certain cases, iverilog supports variables in command files. These 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 name of the environment variable to read. The entire string is
replaced with the contents of that variable. Variables are only replaced with the contents of that variable. Variables are only
substituted in contexts that explicitly support them, including file substituted in contexts that explicitly support them, including file
@ -407,12 +436,12 @@ from preprocessor defines elsewhere in the file or the command line.
The following macros are predefined by the compiler: The following macros are predefined by the compiler:
.TP 8 .TP 8
.B __ICARUS__ = 1\fP .B __ICARUS__ = 1
This is defined always when compiling with Icarus Verilog. This is always defined when compiling with Icarus Verilog.
.TP 8 .TP 8
.B __VAMS_ENABLE__ = 1\fp .B __VAMS_ENABLE__ = 1
This is defined if Verilog-AMS is enabled. This is defined if Verilog\-AMS is enabled.
.SH EXAMPLES .SH EXAMPLES
These examples assume that you have a Verilog source file called hello.v in These examples assume that you have a Verilog source file called hello.v in
@ -424,11 +453,11 @@ To compile hello.v to an executable file called a.out:
To compile hello.v to an executable file called hello: 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: To compile and run explicitly using the vvp runtime:
iverilog -ohello.vvp -tvvp hello.v iverilog \-ohello.vvp \-tvvp hello.v
.SH "AUTHOR" .SH "AUTHOR"
.nf .nf
@ -443,7 +472,7 @@ Tips on using, debugging, and developing the compiler can be found at
.SH COPYRIGHT .SH COPYRIGHT
.nf .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 This document can be freely redistributed according to the terms of the
GNU General Public License version 2.0 GNU General Public License version 2.0

View File

@ -18,7 +18,8 @@
*/ */
# include "config.h" # include "config.h"
# include "version.h" # include "version_base.h"
# include "version_tag.h"
const char NOTICE[] = const char NOTICE[] =
" This program is free software; you can redistribute it and/or modify\n" " This program is free software; you can redistribute it and/or modify\n"
@ -146,8 +147,7 @@ FILE*iconfig_file = 0;
char*compiled_defines_path = 0; char*compiled_defines_path = 0;
static char iconfig_common_path_buf[4096] = ""; static char iconfig_common_path[4096] = "";
char*iconfig_common_path = iconfig_common_path_buf;
int synth_flag = 0; int synth_flag = 0;
int verbose_flag = 0; int verbose_flag = 0;
@ -230,6 +230,23 @@ static FILE*fopen_safe(const char*path)
} }
#endif #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) static const char*my_tempfile(const char*str, FILE**fout)
{ {
FILE*file; FILE*file;
@ -258,7 +275,11 @@ static const char*my_tempfile(const char*str, FILE**fout)
file = NULL; file = NULL;
while ((retry > 0) && (file == NULL)) { while ((retry > 0) && (file == NULL)) {
unsigned code = rand(); 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); file = fopen_safe(pathbuf);
retry -= 1; retry -= 1;
} }
@ -281,7 +302,7 @@ static int t_version_only(void)
} }
fflush(0); 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); iconfig_path, iconfig_common_path);
rc = system(tmp); rc = system(tmp);
if (rc != 0) { if (rc != 0) {
@ -302,8 +323,8 @@ static int t_version_only(void)
static void build_preprocess_command(int e_flag) static void build_preprocess_command(int e_flag)
{ {
snprintf(tmp, sizeof tmp, "%s%civlpp %s%s -F%s -f%s -p%s ", snprintf(tmp, sizeof tmp, "%s%civlpp %s%s -F\"%s\" -f\"%s\" -p\"%s\" ",
pbase,sep, verbose_flag?" -v":"", pbase, sep, verbose_flag?" -v":"",
e_flag?"":" -L", defines_path, source_path, e_flag?"":" -L", defines_path, source_path,
compiled_defines_path); compiled_defines_path);
} }
@ -321,7 +342,7 @@ static int t_preprocess_only(void)
strcpy(cmd, tmp); strcpy(cmd, tmp);
if (strcmp(opath,"-") != 0) { if (strcmp(opath,"-") != 0) {
snprintf(tmp, sizeof tmp, " > %s", opath); snprintf(tmp, sizeof tmp, " > \"%s\"", opath);
cmd = realloc(cmd, ncmd+strlen(tmp)+1); cmd = realloc(cmd, ncmd+strlen(tmp)+1);
strcpy(cmd+ncmd, tmp); strcpy(cmd+ncmd, tmp);
ncmd += strlen(tmp); ncmd += strlen(tmp);
@ -374,14 +395,12 @@ static int t_compile()
char*cmd = malloc(ncmd + 1); char*cmd = malloc(ncmd + 1);
strcpy(cmd, tmp); strcpy(cmd, tmp);
#ifdef __MINGW32__ #ifndef __MINGW32__
unsigned ncmd_start = ncmd;
#else
int rtn; int rtn;
#endif #endif
/* Build the ivl command and pipe it to the preprocessor. */ /* 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); rc = strlen(tmp);
cmd = realloc(cmd, ncmd+rc+1); cmd = realloc(cmd, ncmd+rc+1);
strcpy(cmd+ncmd, tmp); strcpy(cmd+ncmd, tmp);
@ -396,35 +415,25 @@ static int t_compile()
} }
if (npath != 0) { if (npath != 0) {
snprintf(tmp, sizeof tmp, " -N%s", npath); snprintf(tmp, sizeof tmp, " -N\"%s\"", npath);
rc = strlen(tmp); rc = strlen(tmp);
cmd = realloc(cmd, ncmd+rc+1); cmd = realloc(cmd, ncmd+rc+1);
strcpy(cmd+ncmd, tmp); strcpy(cmd+ncmd, tmp);
ncmd += rc; ncmd += rc;
} }
snprintf(tmp, sizeof tmp, " -C%s", iconfig_path); snprintf(tmp, sizeof tmp, " -C\"%s\"", iconfig_path);
rc = strlen(tmp); rc = strlen(tmp);
cmd = realloc(cmd, ncmd+rc+1); cmd = realloc(cmd, ncmd+rc+1);
strcpy(cmd+ncmd, tmp); strcpy(cmd+ncmd, tmp);
ncmd += rc; ncmd += rc;
snprintf(tmp, sizeof tmp, " -C%s -- -", iconfig_common_path); snprintf(tmp, sizeof tmp, " -C\"%s\" -- -", iconfig_common_path);
rc = strlen(tmp); rc = strlen(tmp);
cmd = realloc(cmd, ncmd+rc+1); cmd = realloc(cmd, ncmd+rc+1);
strcpy(cmd+ncmd, tmp); strcpy(cmd+ncmd, tmp);
ncmd += rc; ncmd += rc;
#ifdef __MINGW32__
{
char *t;
for (t = cmd+ncmd_start; *t; t++)
{
if (*t == '/') *t = '\\';
}
}
#endif
if (verbose_flag) if (verbose_flag)
printf("translate: %s\n", cmd); printf("translate: %s\n", cmd);
@ -469,13 +478,18 @@ static void process_warning_switch(const char*name)
if (strcmp(name,"all") == 0) { if (strcmp(name,"all") == 0) {
process_warning_switch("implicit"); process_warning_switch("implicit");
process_warning_switch("portbind"); process_warning_switch("portbind");
process_warning_switch("select-range");
process_warning_switch("timescale"); process_warning_switch("timescale");
process_warning_switch("sensitivity-entire-array");
} else if (strcmp(name,"implicit") == 0) { } else if (strcmp(name,"implicit") == 0) {
if (! strchr(warning_flags, 'i')) if (! strchr(warning_flags, 'i'))
strcat(warning_flags, "i"); strcat(warning_flags, "i");
} else if (strcmp(name,"portbind") == 0) { } else if (strcmp(name,"portbind") == 0) {
if (! strchr(warning_flags, 'p')) if (! strchr(warning_flags, 'p'))
strcat(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) { } else if (strcmp(name,"timescale") == 0) {
if (! strchr(warning_flags, 't')) if (! strchr(warning_flags, 't'))
strcat(warning_flags, "t"); strcat(warning_flags, "t");
@ -484,6 +498,12 @@ static void process_warning_switch(const char*name)
} else if (strcmp(name,"infloop") == 0) { } else if (strcmp(name,"infloop") == 0) {
if (! strchr(warning_flags, 'l')) if (! strchr(warning_flags, 'l'))
strcat(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) { } else if (strcmp(name,"no-implicit") == 0) {
char*cp = strchr(warning_flags, 'i'); char*cp = strchr(warning_flags, 'i');
if (cp) while (*cp) { if (cp) while (*cp) {
@ -496,12 +516,30 @@ static void process_warning_switch(const char*name)
cp[0] = cp[1]; cp[0] = cp[1];
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) { } else if (strcmp(name,"no-timescale") == 0) {
char*cp = strchr(warning_flags, 't'); char*cp = strchr(warning_flags, 't');
if (cp) while (*cp) { if (cp) while (*cp) {
cp[0] = cp[1]; cp[0] = cp[1];
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;
}
} }
} }
@ -557,6 +595,9 @@ int process_generation(const char*name)
else if (strcmp(name,"2001") == 0) else if (strcmp(name,"2001") == 0)
generation = "2001"; generation = "2001";
else if (strcmp(name,"2001-noconfig") == 0)
generation = "2001-noconfig";
else if (strcmp(name,"2005") == 0) else if (strcmp(name,"2005") == 0)
generation = "2005"; generation = "2005";
@ -670,31 +711,31 @@ int main(int argc, char **argv)
int opt, idx; int opt, idx;
#ifdef __MINGW32__ #ifdef __MINGW32__
{ char * s; /* Calculate the ivl_root from the path to the command. This
char basepath[1024]; is necessary because of the installation process on
GetModuleFileName(NULL,basepath,1024); 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 D:\iverilog\bin\iverilog.exe
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 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
so we chop the file name and the last directory by the lib\ivl$(suffix) to finish. */
turning the last two \ characters to null. Then we append { char *s;
the lib\ivl to finish. */ char basepath[4096], tmp[4096];
GetModuleFileName(NULL, tmp, sizeof tmp);
strncpy(ivl_root, basepath, MAXSIZE); /* 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); s = strrchr(ivl_root, sep);
if (s) *s = 0; if (s) *s = 0;
s = strrchr(ivl_root, sep); s = strrchr(ivl_root, sep);
if (s) *s = 0; if (s) *s = 0;
strcat(ivl_root, "\\lib\\ivl"); strcat(ivl_root, "\\lib\\ivl" IVL_SUFFIX);
base = ivl_root; base = ivl_root;
} }
@ -866,6 +907,20 @@ int main(int argc, char **argv)
break; break;
case '?': case '?':
default: 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; return 1;
} }
} }
@ -880,8 +935,8 @@ int main(int argc, char **argv)
} }
/* Make a common conf file path to reflect the target. */ /* Make a common conf file path to reflect the target. */
sprintf(iconfig_common_path, "%s%c%s%s.conf", snprintf(iconfig_common_path, sizeof iconfig_common_path, "%s%c%s%s.conf",
base,sep, targ, synth_flag? "-s" : ""); base, sep, targ, synth_flag? "-s" : "");
/* Write values to the iconfig file. */ /* Write values to the iconfig file. */
fprintf(iconfig_file, "basedir:%s\n", base); fprintf(iconfig_file, "basedir:%s\n", base);
@ -937,7 +992,9 @@ int main(int argc, char **argv)
return 1; return 1;
} }
free(command_filename); free(command_filename);
fclose(fp);
} }
destroy_lexor();
if (depfile) { if (depfile) {
fprintf(defines_file, "M:%s\n", depfile); fprintf(defines_file, "M:%s\n", depfile);
@ -986,7 +1043,7 @@ int main(int argc, char **argv)
/* Write the preprocessor command needed to preprocess a /* Write the preprocessor command needed to preprocess a
single file. This may be used to preprocess library single file. This may be used to preprocess library
files. */ 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); pbase, sep, defines_path, compiled_defines_path);
/* Done writing to the iconfig file. Close it now. */ /* Done writing to the iconfig file. Close it now. */

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 * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * 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 * 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., 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 <string.h>
# include <stdlib.h> # include <stdlib.h>
# include <stdio.h>
#ifdef HAVE_MALLOC_H #ifdef HAVE_MALLOC_H
# include <malloc.h> # include <malloc.h>
#endif #endif
@ -35,13 +33,13 @@ char* substitutions(const char*str)
while (*str) { while (*str) {
if ((str[0] == '$') && (str[1] == '(')) { if ((str[0] == '$') && ((str[1] == '(') || str[1] == '{')) {
/* If I find a $(x) string in the source, replace /* If I find a $(x) or ${x} string in the source, replace
it in the destination with the contents of the it in the destination with the contents of the
environment variable x. */ environment variable x. */
char*name; char*name;
char*value; char*value;
const char*ep = strchr(str, ')'); const char*ep = strchr(str, (str[1]=='(') ? ')' : '}');
str += 2; str += 2;
name = malloc(ep-str+1); name = malloc(ep-str+1);
@ -51,9 +49,13 @@ char* substitutions(const char*str)
str = ep + 1; str = ep + 1;
value = getenv(name); 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; continue;
free(name);
if (strlen(value) >= (nbuf - (cp-buf))) { if (strlen(value) >= (nbuf - (cp-buf))) {
size_t old_size = cp - buf; size_t old_size = cp - buf;
@ -92,24 +94,3 @@ char* substitutions(const char*str)
return buf; 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.
*
*/

View File

@ -419,10 +419,8 @@ NetExpr* PEBinary::elaborate_expr_base_bits_(Design*des,
// If either of the arguments is unsigned, then process both // If either of the arguments is unsigned, then process both
// of them as unsigned. This only impacts the padding that is // of them as unsigned. This only impacts the padding that is
// done to get the operands to the expr_wid. // done to get the operands to the expr_wid.
if (! lp->has_sign()) if (! lp->has_sign()) rp->cast_signed(false);
rp->cast_signed(false); if (! rp->has_sign()) lp->cast_signed(false);
if (! rp->has_sign())
lp->cast_signed(false);
if (expr_wid > 0) { if (expr_wid > 0) {
if (type_is_vectorable(lp->expr_type())) if (type_is_vectorable(lp->expr_type()))
@ -453,6 +451,12 @@ NetExpr* PEBinary::elaborate_expr_base_div_(Design*des,
} }
} }
// If either of the arguments is unsigned, then process both
// of them as unsigned. This only impacts the padding that is
// done to get the operands to the expr_wid.
if (! lp->has_sign()) rp->cast_signed(false);
if (! rp->has_sign()) lp->cast_signed(false);
/* The original elaboration of the left and right expressions /* The original elaboration of the left and right expressions
already tried to elaborate to the expr_wid. If the already tried to elaborate to the expr_wid. If the
expressions are not that width by now, then they need to be expressions are not that width by now, then they need to be
@ -643,13 +647,13 @@ NetExpr* PEBinary::elaborate_expr_base_rshift_(Design*des,
} }
if (NetEConst*rpc = dynamic_cast<NetEConst*> (rp)) { if (NetEConst*rpc = dynamic_cast<NetEConst*> (rp)) {
long shift = rpc->value().as_long(); unsigned long shift = rpc->value().as_ulong();
// Special case: The shift is the size of the entire // Special case: The shift is the size of the entire
// left operand, and the shift is unsigned. Elaborate as // left operand, and the shift is unsigned. Elaborate as
// a constant-0. // a constant-0.
if ((op_=='r' || (lp->has_sign()==false)) if ((op_=='r' || (lp->has_sign()==false)) &&
&& shift >= (long)lp->expr_width()) { shift >= lp->expr_width()) {
if (debug_elaborate) if (debug_elaborate)
cerr << get_fileline() << ": debug: " cerr << get_fileline() << ": debug: "
@ -666,7 +670,11 @@ NetExpr* PEBinary::elaborate_expr_base_rshift_(Design*des,
// Special case: the shift is the size of the entire // Special case: the shift is the size of the entire
// left operand, and the shift is signed. Elaborate as a // left operand, and the shift is signed. Elaborate as a
// replication of the top bit of the left expression. // replication of the top bit of the left expression.
if (shift >= (long)lp->expr_width()) { //
// The above test assures us that op_ == 'R' && the left
// argument is signed when the shift is greater than the
// expression width.
if (shift >= lp->expr_width()) {
if (debug_elaborate) if (debug_elaborate)
cerr << get_fileline() << ": debug: " cerr << get_fileline() << ": debug: "
@ -685,34 +693,10 @@ NetExpr* PEBinary::elaborate_expr_base_rshift_(Design*des,
return tmp; return tmp;
} }
// Special case: shift is negative (so do a left shift)
// and is greater then the output width. Replace the
// expression with a constant-0.
if (shift < 0 && (0-shift) >= use_wid) {
if (debug_elaborate)
cerr << get_fileline() << ": debug: "
<< "Value signed-right-shifted " << shift
<< " beyond width of " << use_wid
<< "." << endl;
tmp = make_const_0(use_wid);
tmp->set_line(*this);
return tmp;
}
ivl_assert(*this, shift >= 0);
if (debug_elaborate)
cerr << get_fileline() << ": debug: "
<< "Value signed-right-shifted " << shift
<< " beyond width of " << lp->expr_width()
<< ". shift=" << shift
<< ", expr_wid=" << expr_wid
<< ", expr=" << *lp << endl;
// If this is lossless, then pad the left expression // If this is lossless, then pad the left expression
// enough to cover the right shift. // enough to cover the right shift.
if (expr_wid == -2 && use_wid+shift > (long)lp->expr_width()) { if (expr_wid == -2 && use_wid+shift > lp->expr_width()) {
lp->cast_signed(lp->has_sign() && op_=='R');
lp = pad_to_width(lp, use_wid + shift, *this); lp = pad_to_width(lp, use_wid + shift, *this);
} }
@ -1504,6 +1488,12 @@ NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope,
def->port(idx)->data_type(), def->port(idx)->data_type(),
def->port(idx)->vector_width(), def->port(idx)->vector_width(),
tmp); tmp);
if (NetEEvent*evt = dynamic_cast<NetEEvent*> (parms[idx])) {
cerr << evt->get_fileline() << ": error: An event '"
<< evt->event()->name() << "' can not be a user "
"function argument." << endl;
des->errors += 1;
}
if (debug_elaborate) if (debug_elaborate)
cerr << get_fileline() << ": debug:" cerr << get_fileline() << ": debug:"
<< " function " << path_ << " function " << path_
@ -1574,8 +1564,8 @@ unsigned PEConcat::test_width(Design*des, NetScope*scope,
// Try to evaluate the repeat expression now, so // Try to evaluate the repeat expression now, so
// that we can give the caller an accurate // that we can give the caller an accurate
// expression width. // expression width.
repeat_expr_ = elab_and_eval(des, scope, repeat_, -1); NetExpr*tmp = elab_and_eval(des, scope, repeat_, -1);
if (NetEConst*tmp_c = dynamic_cast<NetEConst*> (repeat_expr_)) { if (NetEConst*tmp_c = dynamic_cast<NetEConst*> (tmp)) {
repeat_count = tmp_c->value().as_ulong(); repeat_count = tmp_c->value().as_ulong();
} else { } else {
@ -1615,25 +1605,13 @@ NetExpr* PEConcat::elaborate_expr(Design*des, NetScope*scope,
/* If there is a repeat expression, then evaluate the constant /* If there is a repeat expression, then evaluate the constant
value and set the repeat count. */ value and set the repeat count. */
if (repeat_) { if (repeat_) {
NetExpr*tmp; need_constant_expr = true;
if (repeat_expr_ == 0) { NetExpr*tmp = elab_and_eval(des, scope, repeat_, -1);
// If the expression has not yet been elaborated, need_constant_expr = false;
// then try now. assert(tmp);
need_constant_expr = true;
tmp = elab_and_eval(des, scope, repeat_, -1);
need_constant_expr = false;
assert(tmp);
} else {
// If it has been elaborated, make sure it is
// fully evaluated.
tmp = repeat_expr_;
need_constant_expr = true;
eval_expr(tmp);
need_constant_expr = false;
}
if (tmp->expr_type() == IVL_VT_REAL) { if (tmp->expr_type() == IVL_VT_REAL) {
cerr << tmp->get_fileline() << ": error: concatenation " cerr << tmp->get_fileline() << ": error: Concatenation "
<< "repeat expression can not be REAL." << endl; << "repeat expression can not be REAL." << endl;
des->errors += 1; des->errors += 1;
return 0; return 0;
@ -1643,7 +1621,7 @@ NetExpr* PEConcat::elaborate_expr(Design*des, NetScope*scope,
if (rep == 0) { if (rep == 0) {
cerr << get_fileline() << ": error: " cerr << get_fileline() << ": error: "
"concatenation repeat expression cannot be evaluated." "Concatenation repeat expression cannot be evaluated."
<< endl; << endl;
cerr << get_fileline() << ": : The expression is: " cerr << get_fileline() << ": : The expression is: "
<< *tmp << endl; << *tmp << endl;
@ -1702,18 +1680,20 @@ NetExpr* PEConcat::elaborate_expr(Design*des, NetScope*scope,
ex->set_line(*parms_[idx]); ex->set_line(*parms_[idx]);
if (! ex->has_width()) {
cerr << ex->get_fileline() << ": error: "
<< "concatenation operand has indefinite width: "
<< *ex << endl;
des->errors += 1;
}
if (ex->expr_type() == IVL_VT_REAL) { if (ex->expr_type() == IVL_VT_REAL) {
cerr << ex->get_fileline() << ": error: " cerr << ex->get_fileline() << ": error: "
<< "concatenation operand can not be REAL: " << "Concatenation operand can not be real: "
<< *ex << endl; << *parms_[idx] << endl;
des->errors += 1; des->errors += 1;
continue;
}
if (! ex->has_width()) {
cerr << ex->get_fileline() << ": error: "
<< "Concatenation operand \"" << *parms_[idx]
<< "\" has indefinite width." << endl;
des->errors += 1;
continue;
} }
wid_sum += ex->expr_width(); wid_sum += ex->expr_width();
@ -1727,6 +1707,7 @@ NetExpr* PEConcat::elaborate_expr(Design*des, NetScope*scope,
<< "have zero width in this context." << endl; << "have zero width in this context." << endl;
des->errors += 1; des->errors += 1;
concat_depth -= 1; concat_depth -= 1;
delete tmp;
return 0; return 0;
} }
@ -1748,7 +1729,7 @@ unsigned PEFNumber::test_width(Design*des, NetScope*scope,
{ {
expr_type_ = IVL_VT_REAL; expr_type_ = IVL_VT_REAL;
expr_width_ = 1; expr_width_ = 1;
unsized_flag = true; unsized_flag = false;
expr_type__ = expr_type_; expr_type__ = expr_type_;
return 1; return 1;
@ -1790,7 +1771,9 @@ bool PEIdent::calculate_parts_(Design*des, NetScope*scope,
two bit select expressions, and both must be two bit select expressions, and both must be
constant. Evaluate them and pass the results back to constant. Evaluate them and pass the results back to
the caller. */ the caller. */
need_constant_expr = true;
NetExpr*lsb_ex = elab_and_eval(des, scope, index_tail.lsb, lsb_wid); NetExpr*lsb_ex = elab_and_eval(des, scope, index_tail.lsb, lsb_wid);
need_constant_expr = false;
NetEConst*lsb_c = dynamic_cast<NetEConst*>(lsb_ex); NetEConst*lsb_c = dynamic_cast<NetEConst*>(lsb_ex);
if (lsb_c == 0) { if (lsb_c == 0) {
cerr << index_tail.lsb->get_fileline() << ": error: " cerr << index_tail.lsb->get_fileline() << ": error: "
@ -1808,7 +1791,9 @@ bool PEIdent::calculate_parts_(Design*des, NetScope*scope,
lsb = lsb_c->value().as_long(); lsb = lsb_c->value().as_long();
} }
need_constant_expr = true;
NetExpr*msb_ex = elab_and_eval(des, scope, index_tail.msb, msb_wid); NetExpr*msb_ex = elab_and_eval(des, scope, index_tail.msb, msb_wid);
need_constant_expr = false;
NetEConst*msb_c = dynamic_cast<NetEConst*>(msb_ex); NetEConst*msb_c = dynamic_cast<NetEConst*>(msb_ex);
if (msb_c == 0) { if (msb_c == 0) {
cerr << index_tail.msb->get_fileline() << ": error: " cerr << index_tail.msb->get_fileline() << ": error: "
@ -1845,7 +1830,9 @@ bool PEIdent::calculate_up_do_width_(Design*des, NetScope*scope,
/* Calculate the width expression (in the lsb_ position) /* Calculate the width expression (in the lsb_ position)
first. If the expression is not constant, error but guess 1 first. If the expression is not constant, error but guess 1
so we can keep going and find more errors. */ so we can keep going and find more errors. */
need_constant_expr = true;
NetExpr*wid_ex = elab_and_eval(des, scope, index_tail.lsb, -1); NetExpr*wid_ex = elab_and_eval(des, scope, index_tail.lsb, -1);
need_constant_expr = false;
NetEConst*wid_c = dynamic_cast<NetEConst*>(wid_ex); NetEConst*wid_c = dynamic_cast<NetEConst*>(wid_ex);
if (wid_c == 0) { if (wid_c == 0) {
@ -1943,7 +1930,10 @@ unsigned PEIdent::test_width(Design*des, NetScope*scope,
if (!name_tail.index.empty()) { if (!name_tail.index.empty()) {
probe_index_expr_width(des, scope, name_tail); probe_index_expr_width(des, scope, name_tail);
const index_component_t&index_tail = name_tail.index.back(); const index_component_t&index_tail = name_tail.index.back();
use_sel = index_tail.sel; // Skip full array word net selects.
if (!net || (name_tail.index.size() > net->array_dimensions())) {
use_sel = index_tail.sel;
}
} }
unsigned use_width = UINT_MAX; unsigned use_width = UINT_MAX;
@ -2214,12 +2204,12 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
} }
static verinum param_part_select_bits(const verinum&par_val, long wid, static verinum param_part_select_bits(const verinum&par_val, long wid,
long lsv, long par_lsv) long lsv)
{ {
verinum result (verinum::Vx, wid, true); verinum result (verinum::Vx, wid, true);
for (long idx = 0 ; idx < wid ; idx += 1) { for (long idx = 0 ; idx < wid ; idx += 1) {
long off = idx + lsv - par_lsv; long off = idx + lsv;
if (off < 0) if (off < 0)
result.set(idx, verinum::Vx); result.set(idx, verinum::Vx);
else if (off < (long)par_val.len()) else if (off < (long)par_val.len())
@ -2234,7 +2224,7 @@ static verinum param_part_select_bits(const verinum&par_val, long wid,
// If the input is a string, and the part select is working on // If the input is a string, and the part select is working on
// byte boundaries, then make the result into a string. // byte boundaries, then make the result into a string.
if (par_val.is_string() && (labs(lsv-par_lsv)%8 == 0) && (wid%8 == 0)) if (par_val.is_string() && (labs(lsv)%8 == 0) && (wid%8 == 0))
return result.as_string(); return result.as_string();
return result; return result;
@ -2259,7 +2249,7 @@ NetExpr* PEIdent::elaborate_expr_param_part_(Design*des, NetScope*scope,
if (! parts_defined_flag) { if (! parts_defined_flag) {
if (debug_elaborate) if (debug_elaborate)
cerr << get_fileline() << ": debug: Part select of paramter " cerr << get_fileline() << ": debug: Part select of parameter "
<< "has x/z bits, so resorting to 'bx result." << endl; << "has x/z bits, so resorting to 'bx result." << endl;
long wid = 1 + labs(par_msv-par_lsv); long wid = 1 + labs(par_msv-par_lsv);
@ -2290,28 +2280,56 @@ NetExpr* PEIdent::elaborate_expr_param_part_(Design*des, NetScope*scope,
const NetEConst*par_ex = dynamic_cast<const NetEConst*> (par); const NetEConst*par_ex = dynamic_cast<const NetEConst*> (par);
ivl_assert(*this, par_ex); ivl_assert(*this, par_ex);
verinum result = param_part_select_bits(par_ex->value(), wid, lsv, par_lsv); verinum result = param_part_select_bits(par_ex->value(), wid, lsv-par_lsv);
NetEConst*result_ex = new NetEConst(result); NetEConst*result_ex = new NetEConst(result);
result_ex->set_line(*this); result_ex->set_line(*this);
return result_ex; return result_ex;
} }
static void warn_param_ob(long par_msv, long par_lsv, bool defined,
long par_base, unsigned long wid, long pwid,
const LineInfo *info, perm_string name, bool up)
{
long par_max;
if (defined) {
if (par_msv < par_lsv) par_max = par_lsv-par_msv;
else par_max = par_msv-par_lsv;
} else {
if (pwid < 0) par_max = integer_width;
else par_max = pwid;
}
/* Is this a select before the start of the parameter? */
if (par_base < 0) {
cerr << info->get_fileline() << ": warning: " << name << "["
<< par_base;
if (up) cerr << "+:";
else cerr << "-:";
cerr << wid << "] is selecting before vector." << endl;
}
/* Is this a select after the end of the parameter? */
if (par_base + (long)wid - 1 > par_max) {
cerr << info->get_fileline() << ": warning: " << name << "["
<< par_base << "+:" << wid << "] is selecting after vector."
<< endl;
}
}
NetExpr* PEIdent::elaborate_expr_param_idx_up_(Design*des, NetScope*scope, NetExpr* PEIdent::elaborate_expr_param_idx_up_(Design*des, NetScope*scope,
const NetExpr*par, const NetExpr*par,
NetScope*found_in, NetScope*found_in,
const NetExpr*par_msb, const NetExpr*par_msb,
const NetExpr*par_lsb) const const NetExpr*par_lsb) const
{ {
long par_msv, par_lsv; long par_msv, par_lsv;
bool flag = calculate_param_range_(des, scope, par_msb, par_msv, par_lsb, par_lsv); if(! calculate_param_range_(des, scope, par_msb, par_msv,
if (!flag) par_lsb, par_lsv)) return 0;
return 0;
NetExpr*base = calculate_up_do_base_(des, scope); NetExpr*base = calculate_up_do_base_(des, scope);
if (base == 0) if (base == 0) return 0;
return 0;
unsigned long wid = 0; unsigned long wid = 0;
calculate_up_do_width_(des, scope, wid); calculate_up_do_width_(des, scope, wid);
@ -2327,22 +2345,139 @@ NetExpr* PEIdent::elaborate_expr_param_idx_up_(Design*des, NetScope*scope,
// Handle the special case that the base is constant. In this // Handle the special case that the base is constant. In this
// case, just precalculate the entire constant result. // case, just precalculate the entire constant result.
if (NetEConst*base_c = dynamic_cast<NetEConst*> (base)) { if (NetEConst*base_c = dynamic_cast<NetEConst*> (base)) {
if (! base_c->value().is_defined()) {
NetEConst *ex;
ex = new NetEConst(verinum(verinum::Vx, wid, true));
ex->set_line(*this);
if (warn_ob_select) {
perm_string name = peek_tail_name(path_);
cerr << get_fileline() << ": warning: " << name
<< "['bx+:" << wid
<< "] is always outside vector." << endl;
}
return ex;
}
long lsv = base_c->value().as_long(); long lsv = base_c->value().as_long();
long par_base = par_lsv;
// Watch out for reversed bit numbering. We're making // Watch out for reversed bit numbering. We're making
// the part select from LSB to MSB. // the part select from LSB to MSB.
if (par_msv < par_lsv) if (par_msv < par_lsv) {
lsv = lsv - wid + 1; par_base = lsv;
lsv = par_lsv - wid + 1;
}
if (warn_ob_select) {
bool defined = true;
// Check to see if the parameter has a defined range.
if (par_msb == 0) {
assert(par_lsb == 0);
defined = false;
}
// Get the parameter values width.
long pwid = -1;
if (par_ex->has_width()) pwid = par_ex->expr_width()-1;
perm_string name = peek_tail_name(path_);
warn_param_ob(par_msv, par_lsv, defined, lsv-par_base, wid,
pwid, this, name, true);
}
verinum result = param_part_select_bits(par_ex->value(), wid, verinum result = param_part_select_bits(par_ex->value(), wid,
lsv, par_lsv); lsv-par_base);
NetEConst*result_ex = new NetEConst(result); NetEConst*result_ex = new NetEConst(result);
result_ex->set_line(*this); result_ex->set_line(*this);
return result_ex; return result_ex;
} }
if ((par_msv < par_lsv) && (wid>1)) if (par_msv >= par_lsv) {
base = make_add_expr(base, 1-(long)wid); if (par_lsv != 0) base = make_add_expr(base, -par_lsv);
} else {
base = make_sub_expr(par_lsv-wid+1, base);
}
NetExpr*tmp = par->dup_expr();
tmp = new NetESelect(tmp, base, wid);
tmp->set_line(*this);
return tmp;
}
NetExpr* PEIdent::elaborate_expr_param_idx_do_(Design*des, NetScope*scope,
const NetExpr*par,
NetScope*found_in,
const NetExpr*par_msb,
const NetExpr*par_lsb) const
{
long par_msv, par_lsv;
if(! calculate_param_range_(des, scope, par_msb, par_msv,
par_lsb, par_lsv)) return 0;
NetExpr*base = calculate_up_do_base_(des, scope);
if (base == 0) return 0;
unsigned long wid = 0;
calculate_up_do_width_(des, scope, wid);
const NetEConst*par_ex = dynamic_cast<const NetEConst*> (par);
ivl_assert(*this, par_ex);
if (debug_elaborate)
cerr << get_fileline() << ": debug: Calculate part select "
<< "[" << *base << "-:" << wid << "] from range "
<< "[" << par_msv << ":" << par_lsv << "]." << endl;
// Handle the special case that the base is constant. In this
// case, just precalculate the entire constant result.
if (NetEConst*base_c = dynamic_cast<NetEConst*> (base)) {
if (! base_c->value().is_defined()) {
NetEConst *ex;
ex = new NetEConst(verinum(verinum::Vx, wid, true));
ex->set_line(*this);
if (warn_ob_select) {
perm_string name = peek_tail_name(path_);
cerr << get_fileline() << ": warning: " << name
<< "['bx-:" << wid
<< "] is always outside vector." << endl;
}
return ex;
}
long lsv = base_c->value().as_long();
long par_base = par_lsv + wid - 1;
// Watch out for reversed bit numbering. We're making
// the part select from LSB to MSB.
if (par_msv < par_lsv) {
par_base = lsv;
lsv = par_lsv;
}
if (warn_ob_select) {
bool defined = true;
// Check to see if the parameter has a defined range.
if (par_msb == 0) {
assert(par_lsb == 0);
defined = false;
}
// Get the parameter values width.
long pwid = -1;
if (par_ex->has_width()) pwid = par_ex->expr_width()-1;
perm_string name = peek_tail_name(path_);
warn_param_ob(par_msv, par_lsv, defined, lsv-par_base, wid,
pwid, this, name, false);
}
verinum result = param_part_select_bits(par_ex->value(), wid,
lsv-par_base);
NetEConst*result_ex = new NetEConst(result);
result_ex->set_line(*this);
return result_ex;
}
if (par_msv >= par_lsv) {
if (long offset = par_lsv+wid-1) {
base = make_add_expr(base, -offset);
}
} else {
base = make_sub_expr(par_lsv, base);
}
NetExpr*tmp = par->dup_expr(); NetExpr*tmp = par->dup_expr();
tmp = new NetESelect(tmp, base, wid); tmp = new NetESelect(tmp, base, wid);
@ -2368,6 +2503,15 @@ NetExpr* PEIdent::elaborate_expr_param_(Design*des,
if (!name_tail.index.empty()) if (!name_tail.index.empty())
use_sel = name_tail.index.back().sel; use_sel = name_tail.index.back().sel;
if (par->expr_type() == IVL_VT_REAL &&
use_sel != index_component_t::SEL_NONE) {
perm_string name = peek_tail_name(path_);
cerr << get_fileline() << ": error: "
<< "can not select part of real parameter: " << name << endl;
des->errors += 1;
return 0;
}
// NOTE TO SELF: This is the way I want to see this code // NOTE TO SELF: This is the way I want to see this code
// structured. This closely follows the structure of the // structured. This closely follows the structure of the
// elaborate_expr_net_ code, which splits all the various // elaborate_expr_net_ code, which splits all the various
@ -2380,47 +2524,16 @@ NetExpr* PEIdent::elaborate_expr_param_(Design*des,
return elaborate_expr_param_idx_up_(des, scope, par, found_in, return elaborate_expr_param_idx_up_(des, scope, par, found_in,
par_msb, par_lsb); par_msb, par_lsb);
if (use_sel == index_component_t::SEL_IDX_DO)
return elaborate_expr_param_idx_do_(des, scope, par, found_in,
par_msb, par_lsb);
// NOTE TO SELF (continued): The code below should be // NOTE TO SELF (continued): The code below should be
// rewritten in the above format, as I get to it. // rewritten in the above format, as I get to it.
NetExpr*tmp = par->dup_expr(); NetExpr*tmp = par->dup_expr();
if (use_sel == index_component_t::SEL_IDX_DO) { if (use_sel == index_component_t::SEL_BIT) {
ivl_assert(*this, !name_tail.index.empty());
const index_component_t&index_tail = name_tail.index.back();
ivl_assert(*this, index_tail.msb);
ivl_assert(*this, index_tail.lsb);
/* Get and evaluate the width of the index
select. This must be constant. */
NetExpr*wid_ex = elab_and_eval(des, scope, index_tail.lsb, -1);
NetEConst*wid_ec = dynamic_cast<NetEConst*> (wid_ex);
if (wid_ec == 0) {
cerr << index_tail.lsb->get_fileline() << ": error: "
<< "Second expression of indexed part select "
<< "most be constant." << endl;
des->errors += 1;
return 0;
}
unsigned wid = wid_ec->value().as_ulong();
NetExpr*idx_ex = elab_and_eval(des, scope, index_tail.msb, -1);
if (idx_ex == 0) {
return 0;
}
if (use_sel == index_component_t::SEL_IDX_DO && wid > 1) {
idx_ex = make_add_expr(idx_ex, 1-(long)wid);
}
/* Wrap the param expression with a part select. */
tmp = new NetESelect(tmp, idx_ex, wid);
} else if (use_sel == index_component_t::SEL_BIT) {
ivl_assert(*this, !name_tail.index.empty()); ivl_assert(*this, !name_tail.index.empty());
const index_component_t&index_tail = name_tail.index.back(); const index_component_t&index_tail = name_tail.index.back();
ivl_assert(*this, index_tail.msb); ivl_assert(*this, index_tail.msb);
@ -2603,6 +2716,9 @@ NetExpr* PEIdent::elaborate_expr_net_word_(Design*des, NetScope*scope,
// Special case: The index is out of range, so the value // Special case: The index is out of range, so the value
// of this expression is a 'bx vector the width of a word. // of this expression is a 'bx vector the width of a word.
if (!net->array_index_is_valid(addr)) { if (!net->array_index_is_valid(addr)) {
cerr << get_fileline() << ": warning: returning 'bx for out "
"of bounds array access " << net->name()
<< "[" << addr << "]." << endl;
NetEConst*resx = make_const_x(net->vector_width()); NetEConst*resx = make_const_x(net->vector_width());
resx->set_line(*this); resx->set_line(*this);
delete word_index; delete word_index;
@ -2638,6 +2754,18 @@ NetExpr* PEIdent::elaborate_expr_net_word_(Design*des, NetScope*scope,
if (name_tail.index.size() > 1) if (name_tail.index.size() > 1)
word_sel = name_tail.index.back().sel; word_sel = name_tail.index.back().sel;
if (net->get_scalar() &&
word_sel != index_component_t::SEL_NONE) {
cerr << get_fileline() << ": error: can not select part of ";
if (res->expr_type() == IVL_VT_REAL) cerr << "real";
else cerr << "scalar";
cerr << " array word: " << net->name()
<<"[" << *word_index << "]" << endl;
des->errors += 1;
delete res;
return 0;
}
if (word_sel == index_component_t::SEL_PART) if (word_sel == index_component_t::SEL_PART)
return elaborate_expr_net_part_(des, scope, res, found_in); return elaborate_expr_net_part_(des, scope, res, found_in);
@ -2651,6 +2779,7 @@ NetExpr* PEIdent::elaborate_expr_net_word_(Design*des, NetScope*scope,
return elaborate_expr_net_bit_(des, scope, res, found_in); return elaborate_expr_net_bit_(des, scope, res, found_in);
ivl_assert(*this, word_sel == index_component_t::SEL_NONE); ivl_assert(*this, word_sel == index_component_t::SEL_NONE);
return res; return res;
} }
@ -2745,15 +2874,47 @@ NetExpr* PEIdent::elaborate_expr_net_idx_up_(Design*des, NetScope*scope,
if (net->sig()->sb_to_idx(lsv) == 0 && if (net->sig()->sb_to_idx(lsv) == 0 &&
wid == net->vector_width()) { wid == net->vector_width()) {
delete base; delete base;
net->cast_signed(false);
return net; return net;
} }
long offset = 0;
if (net->msi() < net->lsi()) {
offset = -wid + 1;
}
// Otherwise, make a part select that covers the right // Otherwise, make a part select that covers the right
// range. // range.
ex = new NetEConst(verinum(net->sig()->sb_to_idx(lsv))); ex = new NetEConst(verinum(net->sig()->sb_to_idx(lsv) +
offset));
if (warn_ob_select) {
long rel_base = net->sig()->sb_to_idx(lsv) + offset;
if (rel_base < 0) {
cerr << get_fileline() << ": warning: "
<< net->name();
if (net->word_index()) cerr << "[]";
cerr << "[" << lsv << "+:" << wid
<< "] is selecting before vector." << endl;
}
if (rel_base + wid > net->vector_width()) {
cerr << get_fileline() << ": warning: "
<< net->name();
if (net->word_index()) cerr << "[]";
cerr << "[" << lsv << "+:" << wid
<< "] is selecting after vector." << endl;
}
}
} else { } else {
// Return 'bx for an undefined base. // Return 'bx for an undefined base.
ex = new NetEConst(verinum(verinum::Vx, 1, false)); ex = new NetEConst(verinum(verinum::Vx, wid, true));
ex->set_line(*this);
delete base;
if (warn_ob_select) {
cerr << get_fileline() << ": warning: " << net->name();
if (net->word_index()) cerr << "[]";
cerr << "['bx+:" << wid
<< "] is always outside vector." << endl;
}
return ex;
} }
NetESelect*ss = new NetESelect(net, ex, wid); NetESelect*ss = new NetESelect(net, ex, wid);
ss->set_line(*this); ss->set_line(*this);
@ -2764,11 +2925,9 @@ NetExpr* PEIdent::elaborate_expr_net_idx_up_(Design*des, NetScope*scope,
if (net->msi() > net->lsi()) { if (net->msi() > net->lsi()) {
if (long offset = net->lsi()) if (long offset = net->lsi())
base = make_add_expr(base, 0-offset); base = make_add_expr(base, -offset);
} else { } else {
long vwid = net->lsi() - net->msi() + 1; base = make_sub_expr(net->lsi()-wid+1, base);
long offset = net->msi();
base = make_sub_expr(vwid-offset-wid, base);
} }
NetESelect*ss = new NetESelect(net, base, wid); NetESelect*ss = new NetESelect(net, base, wid);
@ -2807,15 +2966,47 @@ NetExpr* PEIdent::elaborate_expr_net_idx_do_(Design*des, NetScope*scope,
if (net->sig()->sb_to_idx(lsv) == (signed) (wid-1) && if (net->sig()->sb_to_idx(lsv) == (signed) (wid-1) &&
wid == net->vector_width()) { wid == net->vector_width()) {
delete base; delete base;
net->cast_signed(false);
return net; return net;
} }
long offset = 0;
if (net->msi() > net->lsi()) {
offset = -wid + 1;
}
// Otherwise, make a part select that covers the right // Otherwise, make a part select that covers the right
// range. // range.
ex = new NetEConst(verinum(net->sig()->sb_to_idx(lsv)-wid+1)); ex = new NetEConst(verinum(net->sig()->sb_to_idx(lsv) +
offset));
if (warn_ob_select) {
long rel_base = net->sig()->sb_to_idx(lsv) + offset;
if (rel_base < 0) {
cerr << get_fileline() << ": warning: "
<< net->name();
if (net->word_index()) cerr << "[]";
cerr << "[" << lsv << "+:" << wid
<< "] is selecting before vector." << endl;
}
if (rel_base + wid > net->vector_width()) {
cerr << get_fileline() << ": warning: "
<< net->name();
if (net->word_index()) cerr << "[]";
cerr << "[" << lsv << "-:" << wid
<< "] is selecting after vector." << endl;
}
}
} else { } else {
// Return 'bx for an undefined base. // Return 'bx for an undefined base.
ex = new NetEConst(verinum(verinum::Vx, 1, false)); ex = new NetEConst(verinum(verinum::Vx, wid, true));
ex->set_line(*this);
delete base;
if (warn_ob_select) {
cerr << get_fileline() << ": warning: " << net->name();
if (net->word_index()) cerr << "[]";
cerr << "['bx-:" << wid
<< "] is always outside vector." << endl;
}
return ex;
} }
NetESelect*ss = new NetESelect(net, ex, wid); NetESelect*ss = new NetESelect(net, ex, wid);
ss->set_line(*this); ss->set_line(*this);
@ -2824,16 +3015,19 @@ NetExpr* PEIdent::elaborate_expr_net_idx_do_(Design*des, NetScope*scope,
return ss; return ss;
} }
long offset = net->lsi(); if (net->msi() > net->lsi()) {
NetExpr*base_adjusted = wid > 1 if (long offset = net->lsi()+wid-1)
? make_add_expr(base,1-(long)wid-offset) base = make_add_expr(base, -offset);
: (offset == 0? base : make_add_expr(base, 0-offset)); } else {
NetESelect*ss = new NetESelect(net, base_adjusted, wid); base = make_sub_expr(net->lsi(), base);
}
NetESelect*ss = new NetESelect(net, base, wid);
ss->set_line(*this); ss->set_line(*this);
if (debug_elaborate) { if (debug_elaborate) {
cerr << get_fileline() << ": debug: Elaborate part " cerr << get_fileline() << ": debug: Elaborate part "
<< "select base="<< *base_adjusted << ", wid="<< wid << endl; << "select base="<< *base << ", wid="<< wid << endl;
} }
return ss; return ss;
@ -2932,6 +3126,16 @@ NetExpr* PEIdent::elaborate_expr_net(Design*des, NetScope*scope,
if (! path_.back().index.empty()) if (! path_.back().index.empty())
use_sel = path_.back().index.back().sel; use_sel = path_.back().index.back().sel;
if (net->get_scalar() &&
use_sel != index_component_t::SEL_NONE) {
cerr << get_fileline() << ": error: can not select part of ";
if (node->expr_type() == IVL_VT_REAL) cerr << "real: ";
else cerr << "scalar: ";
cerr << net->name() << endl;
des->errors += 1;
return 0;
}
// If this is a part select of a signal, then make a new // If this is a part select of a signal, then make a new
// temporary signal that is connected to just the // temporary signal that is connected to just the
// selected bits. The lsb_ and msb_ expressions are from // selected bits. The lsb_ and msb_ expressions are from
@ -3213,6 +3417,7 @@ NetExpr*PETernary::elaborate_expr(Design*des, NetScope*scope,
fal = pad_to_width(fal, use_wid, *this); fal = pad_to_width(fal, use_wid, *this);
NetETernary*res = new NetETernary(con, tru, fal); NetETernary*res = new NetETernary(con, tru, fal);
res->cast_signed(tru->has_sign() && fal->has_sign());
res->set_line(*this); res->set_line(*this);
return res; return res;
} }

View File

@ -118,17 +118,20 @@ NetAssign_* PEConcat::elaborate_lval(Design*des,
NetAssign_*tmp = parms_[idx]->elaborate_lval(des, scope, is_force); 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 /* If the l-value doesn't elaborate, the error was
already detected and printed. We just skip it and let already detected and printed. We just skip it and let
the compiler catch more errors. */ the compiler catch more errors. */
if (tmp == 0) if (tmp == 0) continue;
continue;
assert(tmp);
/* Link the new l-value to the previous one. */ /* Link the new l-value to the previous one. */
NetAssign_*last = tmp; NetAssign_*last = tmp;
while (last->more) while (last->more)
last = last->more; last = last->more;
@ -195,6 +198,17 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
if (reg->array_dimensions() > 0) if (reg->array_dimensions() > 0)
return elaborate_lval_net_word_(des, scope, reg); 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) { if (use_sel == index_component_t::SEL_PART) {
NetAssign_*lv = new NetAssign_(reg); NetAssign_*lv = new NetAssign_(reg);
elaborate_lval_net_part_(des, scope, lv); elaborate_lval_net_part_(des, scope, lv);
@ -243,13 +257,11 @@ NetAssign_* PEIdent::elaborate_lval_net_word_(Design*des,
ivl_assert(*this, index_head.msb != 0); ivl_assert(*this, index_head.msb != 0);
ivl_assert(*this, index_head.lsb == 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; ivl_variable_type_t expr_type_tmp = IVL_VT_NO_TYPE;
// This not used, but it needs to have a default value.
bool unsized_flag_tmp = false; bool unsized_flag_tmp = false;
index_head.msb->test_width(des, scope, index_head.msb->test_width(des, scope, integer_width, integer_width,
reg->vector_width(), reg->vector_width(), expr_type_tmp, unsized_flag_tmp);
expr_type_tmp,
unsized_flag_tmp);
NetExpr*word = elab_and_eval(des, scope, index_head.msb, -1); NetExpr*word = elab_and_eval(des, scope, index_head.msb, -1);
@ -289,6 +301,20 @@ NetAssign_* PEIdent::elaborate_lval_net_word_(Design*des,
if (name_tail.index.size() > 1) if (name_tail.index.size() > 1)
use_sel = name_tail.index.back().sel; 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) if (use_sel == index_component_t::SEL_PART)
elaborate_lval_net_part_(des, scope, lv); elaborate_lval_net_part_(des, scope, lv);
@ -310,16 +336,14 @@ bool PEIdent::elaborate_lval_net_bit_(Design*des,
NetNet*reg = lv->sig(); 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; ivl_variable_type_t expr_type_tmp = IVL_VT_NO_TYPE;
// This not used, but it needs to have a default value.
bool unsized_flag_tmp = false; bool unsized_flag_tmp = false;
index_tail.msb->test_width(des, scope, index_tail.msb->test_width(des, scope, integer_width, integer_width,
lv->lwidth(), lv->lwidth(), expr_type_tmp, unsized_flag_tmp);
expr_type_tmp,
unsized_flag_tmp);
// Bit selects have a single select expression. Evaluate the // Bit selects have a single select expression. Evaluate the
// constant value and treat it as a part select with a bit // constant value and treat it as a part select with a bit
// width of 1. // width of 1.
NetExpr*mux = elab_and_eval(des, scope, index_tail.msb, -1); NetExpr*mux = elab_and_eval(des, scope, index_tail.msb, -1);
@ -444,24 +468,88 @@ bool PEIdent::elaborate_lval_net_idx_(Design*des,
unsigned long wid; unsigned long wid;
calculate_up_do_width_(des, scope, 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; ivl_variable_type_t expr_type_tmp = IVL_VT_NO_TYPE;
// This not used, but it needs to have a default value.
bool unsized_flag_tmp = false; bool unsized_flag_tmp = false;
index_tail.msb->test_width(des, scope, index_tail.msb->test_width(des, scope, integer_width, integer_width,
wid, wid, expr_type_tmp, unsized_flag_tmp);
expr_type_tmp,
unsized_flag_tmp);
NetExpr*base = elab_and_eval(des, scope, index_tail.msb, -1); NetExpr*base = elab_and_eval(des, scope, index_tail.msb, -1);
/* Correct the mux for the range of the vector. */ // Handle the special case that the base is constant. For this
if (reg->msb() < reg->lsb()) // case we can reduce the expression.
base = make_sub_expr(reg->lsb(), base); if (NetEConst*base_c = dynamic_cast<NetEConst*> (base)) {
else if (reg->lsb() != 0) // For the undefined case just let the constant pass and
base = make_add_expr(base, - reg->lsb()); // we will handle it in the code generator.
if (base_c->value().is_defined()) {
if (use_sel == index_component_t::SEL_IDX_DO && wid > 1 ) { long lsv = base_c->value().as_long();
base = make_add_expr(base, 1-(long)wid); 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) if (debug_elaborate)

View File

@ -72,10 +72,16 @@ NetNet* PEConcat::elaborate_lnet_common_(Design*des, NetScope*scope,
} else { } else {
nets[idx] = parms_[idx]->elaborate_lnet(des, scope); 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; errors += 1;
else continue;
width += nets[idx]->vector_width(); } else width += nets[idx]->vector_width();
} }
/* If any of the sub expressions failed to elaborate, then /* If any of the sub expressions failed to elaborate, then
@ -173,7 +179,7 @@ NetNet* PEIdent::make_implicit_net_(Design*des, NetScope*scope) const
assert(nettype != NetNet::NONE); assert(nettype != NetNet::NONE);
NetNet*sig = new NetNet(scope, peek_tail_name(path_), NetNet*sig = new NetNet(scope, peek_tail_name(path_),
NetNet::IMPLICIT, 1); nettype, 1);
sig->set_line(*this); sig->set_line(*this);
/* Implicit nets are always scalar logic. */ /* Implicit nets are always scalar logic. */
sig->data_type(IVL_VT_LOGIC); sig->data_type(IVL_VT_LOGIC);
@ -220,7 +226,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_DO:
case index_component_t::SEL_IDX_UP: { case index_component_t::SEL_IDX_UP: {
need_constant_expr = true;
NetExpr*tmp_ex = elab_and_eval(des, scope, index_tail.msb, -1); NetExpr*tmp_ex = elab_and_eval(des, scope, index_tail.msb, -1);
need_constant_expr = false;
NetEConst*tmp = dynamic_cast<NetEConst*>(tmp_ex); NetEConst*tmp = dynamic_cast<NetEConst*>(tmp_ex);
if (!tmp) { if (!tmp) {
cerr << get_fileline() << ": error: indexed part select of " cerr << get_fileline() << ": error: indexed part select of "
@ -230,15 +238,33 @@ bool PEIdent::eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
return 0; 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. */ /* The width (a constant) is calculated here. */
unsigned long wid = 0; unsigned long wid = 0;
bool flag = calculate_up_do_width_(des, scope, wid); 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; 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) if (index_tail.sel == index_component_t::SEL_IDX_UP)
lidx = sig->sb_to_idx(midx_val+wid-1); lidx = sig->sb_to_idx(midx_val+wid-1);
@ -252,9 +278,19 @@ bool PEIdent::eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
} }
/* Warn about an indexed part select that is out of range. */ /* Warn about an indexed part select that is out of range. */
if (midx >= (long)sig->vector_width() || lidx < 0) { if (warn_ob_select && (lidx < 0)) {
cerr << get_fileline() << ": warning: Indexed part " cerr << get_fileline() << ": warning: " << sig->name();
"select " << 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) { if (sig->array_dimensions() > 0) {
cerr << "[]"; cerr << "[]";
} }
@ -264,7 +300,7 @@ bool PEIdent::eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
} else { } else {
cerr << "-:"; 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. */ /* This is completely out side the signal so just skip it. */
@ -415,7 +451,10 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
// Default part select is the entire word. // Default part select is the entire word.
unsigned midx = sig->vector_width()-1, lidx = 0; unsigned midx = sig->vector_width()-1, lidx = 0;
// The default word select is the first. // 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(); const name_component_t&name_tail = path_.back();
@ -437,7 +476,15 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
} }
ivl_assert(*this, index_head.sel == index_component_t::SEL_BIT); 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); NetExpr*tmp_ex = elab_and_eval(des, scope, index_head.msb, -1);
need_constant_expr = false;
NetEConst*tmp = dynamic_cast<NetEConst*>(tmp_ex); NetEConst*tmp = dynamic_cast<NetEConst*>(tmp_ex);
if (!tmp) { if (!tmp) {
cerr << get_fileline() << ": error: array " << sig->name() cerr << get_fileline() << ": error: array " << sig->name()
@ -446,8 +493,11 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
return 0; return 0;
} }
long widx_val = tmp->value().as_long(); widx_val = tmp->value().as_long();
widx = sig->array_index_to_address(widx_val); if (sig->array_index_is_valid(widx_val))
widx = sig->array_index_to_address(widx_val);
else
widx = -1;
delete tmp_ex; delete tmp_ex;
if (debug_elaborate) if (debug_elaborate)
@ -456,6 +506,17 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
/* The array has a part/bit select at the end. */ /* The array has a part/bit select at the end. */
if (name_tail.index.size() > sig->array_dimensions()) { 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; long midx_tmp, lidx_tmp;
if (! eval_part_select_(des, scope, sig, midx_tmp, lidx_tmp)) if (! eval_part_select_(des, scope, sig, midx_tmp, lidx_tmp))
return 0; return 0;
@ -471,6 +532,16 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
lidx = lidx_tmp; lidx = lidx_tmp;
} }
} else if (!name_tail.index.empty()) { } 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; long midx_tmp, lidx_tmp;
if (! eval_part_select_(des, scope, sig, midx_tmp, lidx_tmp)) if (! eval_part_select_(des, scope, sig, midx_tmp, lidx_tmp))
return 0; return 0;
@ -489,7 +560,12 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
unsigned subnet_wid = midx-lidx+1; unsigned subnet_wid = midx-lidx+1;
if (sig->pin_count() > 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(), NetNet*tmp = new NetNet(scope, scope->local_symbol(),
sig->type(), sig->vector_width()); sig->type(), sig->vector_width());

View File

@ -150,11 +150,19 @@ NetEConcat* PEConcat::elaborate_pexpr(Design*des, NetScope*scope) const
/* Elaborate all the operands and attach them to the concat /* Elaborate all the operands and attach them to the concat
node. Use the elaborate_pexpr method instead of the node. Use the elaborate_pexpr method instead of the
elaborate_expr method. */ elaborate_expr method. */
bool fail = false;
for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) { for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) {
assert(parms_[idx]); assert(parms_[idx]);
NetExpr*ex = parms_[idx]->elaborate_pexpr(des, scope); NetExpr*ex = parms_[idx]->elaborate_pexpr(des, scope);
if (ex == 0) continue; 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]); ex->set_line(*parms_[idx]);
if (dynamic_cast<NetEParam*>(ex)) { if (dynamic_cast<NetEParam*>(ex)) {
@ -167,13 +175,18 @@ NetEConcat* PEConcat::elaborate_pexpr(Design*des, NetScope*scope) const
<< "concatenation has indefinite width: " << "concatenation has indefinite width: "
<< *ex << endl; << *ex << endl;
des->errors += 1; des->errors += 1;
delete tmp; fail = true;
return 0; continue;
} }
tmp->set(idx, ex); tmp->set(idx, ex);
} }
if (fail) {
delete tmp;
return 0;
}
return tmp; return tmp;
} }
@ -194,6 +207,14 @@ NetExpr*PEIdent::elaborate_pexpr(Design*des, NetScope*scope) const
name_component_t name_tail = path_.back(); name_component_t name_tail = path_.back();
oldpath.pop_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; NetScope*pscope = scope;
if (path_.size() > 0) { if (path_.size() > 0) {
list<hname_t> tmp = eval_scope_path(des, scope, oldpath); list<hname_t> tmp = eval_scope_path(des, scope, oldpath);
@ -216,8 +237,9 @@ NetExpr*PEIdent::elaborate_pexpr(Design*des, NetScope*scope) const
ivl_assert(*this, pscope); ivl_assert(*this, pscope);
} }
if (ex == 0) { if (ex == 0) {
cerr << get_fileline() << ": error: identifier ``" << name_tail.name << cerr << get_fileline() << ": error: identifier `"
"'' is not a parameter in "<< scope_path(scope)<< "." << endl; << name_tail.name << "` is not a parameter in "
<< scope_path(scope)<< "." << endl;
des->errors += 1; des->errors += 1;
return 0; return 0;
} }

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 * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -174,6 +174,15 @@ static void elaborate_scope_parameters_(Design*des, NetScope*scope,
for (mparm_it_t cur = parameters.begin() for (mparm_it_t cur = parameters.begin()
; cur != parameters.end() ; cur ++) { ; 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); elaborate_parm_item_((*cur).first, (*cur).second, des, scope);
} }
} }
@ -184,6 +193,15 @@ static void elaborate_scope_localparams_(Design*des, NetScope*scope,
for (mparm_it_t cur = localparams.begin() for (mparm_it_t cur = localparams.begin()
; cur != localparams.end() ; cur ++) { ; 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); elaborate_parm_item_((*cur).first, (*cur).second, des, scope);
} }
} }
@ -198,7 +216,7 @@ static void replace_scope_parameters_(NetScope*scope, const LineInfo&loc,
if (val == 0) { if (val == 0) {
cerr << loc.get_fileline() << ": internal error: " cerr << loc.get_fileline() << ": internal error: "
<< "Missing expression in parameter replacement for " << "Missing expression in parameter replacement for "
<< (*cur).first; << (*cur).first << endl;;
} }
assert(val); assert(val);
if (debug_scopes) { if (debug_scopes) {
@ -238,13 +256,38 @@ static void elaborate_scope_tasks(Design*des, NetScope*scope,
; cur != tasks.end() ; cur ++ ) { ; cur != tasks.end() ; cur ++ ) {
hname_t use_name( (*cur).first ); hname_t use_name( (*cur).first );
if (scope->child(use_name)) { // A task can not have the same name as another scope object.
cerr << loc.get_fileline() << ": error: task/scope name " const NetScope *child = scope->child(use_name);
<< use_name << " already used in this context." if (child) {
<< endl; 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; des->errors += 1;
continue; 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_scope = new NetScope(scope, use_name,
NetScope::TASK); NetScope::TASK);
task_scope->is_auto((*cur).second->is_auto()); task_scope->is_auto((*cur).second->is_auto());
@ -268,13 +311,39 @@ static void elaborate_scope_funcs(Design*des, NetScope*scope,
; cur != funcs.end() ; cur ++ ) { ; cur != funcs.end() ; cur ++ ) {
hname_t use_name( (*cur).first ); hname_t use_name( (*cur).first );
if (scope->child(use_name)) { // A function can not have the same name as another scope object.
cerr << loc.get_fileline() << ": error: function/scope name " const NetScope *child = scope->child(use_name);
<< use_name << " already used in this context." if (child) {
<< endl; 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; des->errors += 1;
continue; 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_scope = new NetScope(scope, use_name,
NetScope::FUNC); NetScope::FUNC);
func_scope->is_auto((*cur).second->is_auto()); func_scope->is_auto((*cur).second->is_auto());
@ -328,6 +397,12 @@ bool Module::elaborate_scope(Design*des, NetScope*scope,
<< scope_path(scope) << "." << endl; << 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 // Generate all the parameters that this instance of this
// module introduces to the design. This loop elaborates the // module introduces to the design. This loop elaborates the
// parameters, but doesn't evaluate references to // parameters, but doesn't evaluate references to
@ -446,6 +521,8 @@ bool Module::elaborate_scope(Design*des, NetScope*scope,
elaborate_scope_events_(des, scope, events); elaborate_scope_events_(des, scope, events);
scope->is_cell(is_cell);
return des->errors == 0; return des->errors == 0;
} }
@ -486,8 +563,16 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
{ {
// Check that the loop_index variable was declared in a // Check that the loop_index variable was declared in a
// genvar statement. // genvar statement.
NetScope*scope = container;
// MISSING CODE! 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... // We're going to need a genvar...
int genvar; int genvar;
@ -496,7 +581,9 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
// use) the genvar itself, so we can evaluate this expression // use) the genvar itself, so we can evaluate this expression
// the same way any other parameter value is evaluated. // the same way any other parameter value is evaluated.
probe_expr_width(des, container, loop_init); probe_expr_width(des, container, loop_init);
need_constant_expr = true;
NetExpr*init_ex = elab_and_eval(des, container, loop_init, -1); NetExpr*init_ex = elab_and_eval(des, container, loop_init, -1);
need_constant_expr = false;
NetEConst*init = dynamic_cast<NetEConst*> (init_ex); NetEConst*init = dynamic_cast<NetEConst*> (init_ex);
if (init == 0) { if (init == 0) {
cerr << get_fileline() << ": error: Cannot evaluate genvar" cerr << get_fileline() << ": error: Cannot evaluate genvar"
@ -505,19 +592,53 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
return false; return false;
} }
// Since we will be adding the genvar value as a local parameter // Check the generate block name.
// to each instances scope. We need to make sure a parameter does
// not already exist. // A generate "loop" can not have the same name as another scope object.
const NetExpr*tmsb; const NetScope *child = container->child(hname_t(scope_name));
const NetExpr*tlsb; if (child) {
const NetExpr*texpr = container->get_parameter(loop_index, tmsb, tlsb); cerr << get_fileline() << ": error: generate \"loop\" and ";
if (texpr != 0) { child->print_type(cerr);
cerr << get_fileline() << ": error: Cannot have a genvar " cerr << " in '" << container->fullname()
<< "and parameter with the same name: " << loop_index << endl; << "' have the same name '" << scope_name << "'." << endl;
des->errors += 1; des->errors += 1;
return false; 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(); genvar = init->value().as_long();
delete init_ex; delete init_ex;
@ -526,7 +647,9 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
container->genvar_tmp = loop_index; container->genvar_tmp = loop_index;
container->genvar_tmp_val = genvar; container->genvar_tmp_val = genvar;
probe_expr_width(des, container, loop_test); probe_expr_width(des, container, loop_test);
need_constant_expr = true;
NetExpr*test_ex = elab_and_eval(des, container, loop_test, -1); NetExpr*test_ex = elab_and_eval(des, container, loop_test, -1);
need_constant_expr = false;
NetEConst*test = dynamic_cast<NetEConst*>(test_ex); NetEConst*test = dynamic_cast<NetEConst*>(test_ex);
if (test == 0) { if (test == 0) {
cerr << get_fileline() << ": error: Cannot evaluate genvar" cerr << get_fileline() << ": error: Cannot evaluate genvar"
@ -541,13 +664,7 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
// container. The format of using [] is part of the // container. The format of using [] is part of the
// Verilog standard. // Verilog standard.
hname_t use_name (scope_name, genvar); 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) if (debug_scopes)
cerr << get_fileline() << ": debug: " cerr << get_fileline() << ": debug: "
<< "Create generated scope " << use_name << endl; << "Create generated scope " << use_name << endl;
@ -579,7 +696,9 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
// Calculate the step for the loop variable. // Calculate the step for the loop variable.
probe_expr_width(des, container, loop_step); probe_expr_width(des, container, loop_step);
need_constant_expr = true;
NetExpr*step_ex = elab_and_eval(des, container, loop_step, -1); NetExpr*step_ex = elab_and_eval(des, container, loop_step, -1);
need_constant_expr = false;
NetEConst*step = dynamic_cast<NetEConst*>(step_ex); NetEConst*step = dynamic_cast<NetEConst*>(step_ex);
if (step == 0) { if (step == 0) {
cerr << get_fileline() << ": error: Cannot evaluate genvar" cerr << get_fileline() << ": error: Cannot evaluate genvar"
@ -602,7 +721,7 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
} }
// Clear the genvar_tmp field in the scope to reflect that the // 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(); container->genvar_tmp = perm_string();
return true; return true;
@ -611,7 +730,9 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
bool PGenerate::generate_scope_condit_(Design*des, NetScope*container, bool else_flag) bool PGenerate::generate_scope_condit_(Design*des, NetScope*container, bool else_flag)
{ {
probe_expr_width(des, container, loop_test); probe_expr_width(des, container, loop_test);
need_constant_expr = true;
NetExpr*test_ex = elab_and_eval(des, container, loop_test, -1); NetExpr*test_ex = elab_and_eval(des, container, loop_test, -1);
need_constant_expr = false;
NetEConst*test = dynamic_cast<NetEConst*> (test_ex); NetEConst*test = dynamic_cast<NetEConst*> (test_ex);
if (test == 0) { if (test == 0) {
cerr << get_fileline() << ": error: Cannot evaluate genvar" cerr << get_fileline() << ": error: Cannot evaluate genvar"
@ -634,14 +755,45 @@ bool PGenerate::generate_scope_condit_(Design*des, NetScope*container, bool else
} }
hname_t use_name (scope_name); hname_t use_name (scope_name);
if (container->child(use_name)) { // A generate "if" can not have the same name as another scope object.
cerr << get_fileline() << ": error: block/scope name " const NetScope *child = container->child(use_name);
<< scope_name << " already used in this context." if (child) {
<< endl; 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; des->errors += 1;
return false; 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) if (debug_scopes)
cerr << get_fileline() << ": debug: Generate condition " cerr << get_fileline() << ": debug: Generate condition "
<< (else_flag? "(else)" : "(if)") << (else_flag? "(else)" : "(if)")
@ -671,7 +823,9 @@ bool PGenerate::generate_scope_condit_(Design*des, NetScope*container, bool else
bool PGenerate::generate_scope_case_(Design*des, NetScope*container) bool PGenerate::generate_scope_case_(Design*des, NetScope*container)
{ {
probe_expr_width(des, container, loop_test); probe_expr_width(des, container, loop_test);
need_constant_expr = true;
NetExpr*case_value_ex = elab_and_eval(des, container, loop_test, -1); 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); NetEConst*case_value_co = dynamic_cast<NetEConst*>(case_value_ex);
if (case_value_co == 0) { if (case_value_co == 0) {
cerr << get_fileline() << ": error: Cannot evaluate genvar case" cerr << get_fileline() << ": error: Cannot evaluate genvar case"
@ -702,9 +856,17 @@ bool PGenerate::generate_scope_case_(Design*des, NetScope*container)
bool match_flag = false; bool match_flag = false;
for (unsigned idx = 0 ; idx < item->item_test.size() && !match_flag ; idx +=1 ) { for (unsigned idx = 0 ; idx < item->item_test.size() && !match_flag ; idx +=1 ) {
probe_expr_width(des, container, item->item_test[idx]); 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); 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); NetEConst*item_value_co = dynamic_cast<NetEConst*>(item_value_ex);
assert(item_value_co); 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 (debug_scopes) if (debug_scopes)
cerr << get_fileline() << ": debug: Generate case " cerr << get_fileline() << ": debug: Generate case "
@ -739,6 +901,44 @@ bool PGenerate::generate_scope_case_(Design*des, NetScope*container)
// The name of the scope to generate, whatever that item is. // The name of the scope to generate, whatever that item is.
hname_t use_name (item->scope_name); 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_(); item->probe_for_direct_nesting_();
if (item->direct_nested_) { if (item->direct_nested_) {
@ -760,13 +960,46 @@ bool PGenerate::generate_scope_case_(Design*des, NetScope*container)
bool PGenerate::generate_scope_nblock_(Design*des, NetScope*container) bool PGenerate::generate_scope_nblock_(Design*des, NetScope*container)
{ {
hname_t use_name (scope_name); hname_t use_name (scope_name);
if (container->child(use_name)) { // A generate "block" can not have the same name as another scope
cerr << get_fileline() << ": error: block/scope name " // object.
<< scope_name << " already used in this context." const NetScope *child = container->child(use_name);
<< endl; 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; des->errors += 1;
return false; 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) if (debug_scopes)
cerr << get_fileline() << ": debug: Generate named block " cerr << get_fileline() << ": debug: Generate named block "
<< ": Generate scope=" << use_name << endl; << ": Generate scope=" << use_name << endl;
@ -791,6 +1024,12 @@ void PGenerate::elaborate_subscope_direct_(Design*des, NetScope*scope)
void PGenerate::elaborate_subscope_(Design*des, NetScope*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, // Scan the generated scope for nested generate schemes,
// and *generate* new scopes, which is slightly different // and *generate* new scopes, which is slightly different
// from simple elaboration. // from simple elaboration.
@ -886,36 +1125,77 @@ void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const
// Missing module instance names have already been rejected. // Missing module instance names have already been rejected.
assert(get_name() != ""); assert(get_name() != "");
// Check for duplicate scopes. Simply look up the scope I'm // A module instance can not have the same name as another scope object.
// about to create, and if I find it then somebody beat me to const NetScope *child = sc->child(hname_t(get_name()));
// it. if (child) {
cerr << get_fileline() << ": error: module <" << mod->mod_name()
if (sc->child(hname_t(get_name()))) { << "> instance and ";
cerr << get_fileline() << ": error: Instance/Scope name " << child->print_type(cerr);
get_name() << " already used in this context." << cerr << " in '" << sc->fullname()
endl; << "' have the same name '" << get_name() << "'." << endl;
des->errors += 1; des->errors += 1;
return; 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 // check for recursive instantiation by scanning the current
// scope and its parents. Look for a module instantiation of // scope and its parents. Look for a module instantiation of
// the same module, but farther up in the scope. // 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()) { 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; 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; continue;
}
cerr << get_fileline() << ": error: You cannot instantiate " cerr << get_fileline() << ": error: You cannot instantiate "
<< "module " << mod->mod_name() << " within itself." << endl; << "module " << mod->mod_name() << " within itself." << endl;
cerr << get_fileline() << ": : The offending instance is " cerr << get_fileline() << ": : The offending instance is "
<< scope_path(sc) << "." << get_name() << " within " << get_name() << " within " << scope_path(scn) << "." << endl;
<< scope_path(scn) << "." << endl;
des->errors += 1; des->errors += 1;
return; return;
} }
@ -952,8 +1232,10 @@ void PGModule::elaborate_scope_mod_instances_(Design*des, Module*mod, NetScope*s
{ {
if (msb_) probe_expr_width(des, sc, msb_); if (msb_) probe_expr_width(des, sc, msb_);
if (lsb_) probe_expr_width(des, sc, lsb_); if (lsb_) probe_expr_width(des, sc, lsb_);
need_constant_expr = true;
NetExpr*mse = msb_ ? elab_and_eval(des, sc, msb_, -1) : 0; NetExpr*mse = msb_ ? elab_and_eval(des, sc, msb_, -1) : 0;
NetExpr*lse = lsb_ ? elab_and_eval(des, sc, lsb_, -1) : 0; NetExpr*lse = lsb_ ? elab_and_eval(des, sc, lsb_, -1) : 0;
need_constant_expr = false;
NetEConst*msb = dynamic_cast<NetEConst*> (mse); NetEConst*msb = dynamic_cast<NetEConst*> (mse);
NetEConst*lsb = dynamic_cast<NetEConst*> (lse); NetEConst*lsb = dynamic_cast<NetEConst*> (lse);
@ -1019,6 +1301,7 @@ void PGModule::elaborate_scope_mod_instances_(Design*des, Module*mod, NetScope*s
// Set time units and precision. // Set time units and precision.
my_scope->time_unit(mod->time_unit); my_scope->time_unit(mod->time_unit);
my_scope->time_precision(mod->time_precision); my_scope->time_precision(mod->time_precision);
my_scope->time_from_timescale(mod->time_from_timescale);
des->set_precision(mod->time_precision); des->set_precision(mod->time_precision);
// Look for module parameter replacements. The "replace" map // Look for module parameter replacements. The "replace" map
@ -1075,9 +1358,9 @@ void PGModule::elaborate_scope_mod_instances_(Design*des, Module*mod, NetScope*s
PExpr*tmp = (*cur).second; PExpr*tmp = (*cur).second;
// No expression means that the parameter is not // No expression means that the parameter is not
// replaced at all. // replaced at all.
if (tmp == 0) if (tmp == 0) continue;
continue;
NetExpr*val = tmp->elaborate_pexpr(des, sc); NetExpr*val = tmp->elaborate_pexpr(des, sc);
if (val == 0) continue;
replace_net[(*cur).first] = val; replace_net[(*cur).first] = val;
} }
@ -1109,6 +1392,34 @@ void PGModule::elaborate_scope_mod_instances_(Design*des, Module*mod, NetScope*s
*/ */
void PEvent::elaborate_scope(Design*des, NetScope*scope) const 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_); NetEvent*ev = new NetEvent(name_);
ev->set_line(*this); ev->set_line(*this);
scope->add_event(ev); scope->add_event(ev);
@ -1189,13 +1500,37 @@ void PBlock::elaborate_scope(Design*des, NetScope*scope) const
if (pscope_name() != 0) { if (pscope_name() != 0) {
hname_t use_name(pscope_name()); hname_t use_name(pscope_name());
if (scope->child(use_name)) { // A named block can not have the same name as another scope
cerr << get_fileline() << ": error: block/scope name " // object.
<< use_name << " already used in this context." const NetScope *child = scope->child(use_name);
<< endl; 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; des->errors += 1;
return; 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) if (debug_scopes)
cerr << get_fileline() << ": debug: " cerr << get_fileline() << ": debug: "
<< "Elaborate block scope " << use_name << "Elaborate block scope " << use_name

View File

@ -126,7 +126,7 @@ static void elaborate_sig_funcs(Design*des, NetScope*scope,
hname_t use_name ( (*cur).first ); hname_t use_name ( (*cur).first );
NetScope*fscope = scope->child(use_name); NetScope*fscope = scope->child(use_name);
if (scope == 0) { if (fscope == 0) {
cerr << (*cur).second->get_fileline() << ": internal error: " cerr << (*cur).second->get_fileline() << ": internal error: "
<< "Child scope for function " << (*cur).first << "Child scope for function " << (*cur).first
<< " missing in " << scope_path(scope) << "." << endl; << " missing in " << scope_path(scope) << "." << endl;
@ -599,9 +599,11 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const
} }
ret_sig = new NetNet(scope, fname, NetNet::REG, mnum, lnum); ret_sig = new NetNet(scope, fname, NetNet::REG, mnum, lnum);
ret_sig->set_scalar(false);
} else { } else {
ret_sig = new NetNet(scope, fname, NetNet::REG); ret_sig = new NetNet(scope, fname, NetNet::REG);
ret_sig->set_scalar(true);
} }
ret_sig->set_line(*this); ret_sig->set_line(*this);
ret_sig->set_signed(return_type_.type == PTF_REG_S); ret_sig->set_signed(return_type_.type == PTF_REG_S);
@ -614,6 +616,7 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const
ret_sig->set_line(*this); ret_sig->set_line(*this);
ret_sig->set_signed(true); ret_sig->set_signed(true);
ret_sig->set_isint(true); ret_sig->set_isint(true);
ret_sig->set_scalar(false);
ret_sig->port_type(NetNet::POUTPUT); ret_sig->port_type(NetNet::POUTPUT);
ret_sig->data_type(IVL_VT_LOGIC); ret_sig->data_type(IVL_VT_LOGIC);
break; break;
@ -623,6 +626,7 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const
ret_sig->set_line(*this); ret_sig->set_line(*this);
ret_sig->set_signed(false); ret_sig->set_signed(false);
ret_sig->set_isint(false); ret_sig->set_isint(false);
ret_sig->set_scalar(false);
ret_sig->port_type(NetNet::POUTPUT); ret_sig->port_type(NetNet::POUTPUT);
ret_sig->data_type(IVL_VT_LOGIC); ret_sig->data_type(IVL_VT_LOGIC);
break; break;
@ -633,6 +637,7 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const
ret_sig->set_line(*this); ret_sig->set_line(*this);
ret_sig->set_signed(true); ret_sig->set_signed(true);
ret_sig->set_isint(false); ret_sig->set_isint(false);
ret_sig->set_scalar(true);
ret_sig->port_type(NetNet::POUTPUT); ret_sig->port_type(NetNet::POUTPUT);
ret_sig->data_type(IVL_VT_REAL); ret_sig->data_type(IVL_VT_REAL);
break; break;
@ -843,23 +848,63 @@ void PWhile::elaborate_sig(Design*des, NetScope*scope) const
/* /*
* Elaborate a source wire. The "wire" is the declaration of wires, * Elaborate a source wire. The "wire" is the declaration of wires,
* registers, ports and memories. The parser has already merged the * registers, ports and memories. The parser has already merged the
* multiple properties of a wire (i.e., "input wire") so come the * multiple properties of a wire (i.e., "input wire"), so come the
* elaboration this creates an object in the design that represent the * elaboration this creates an object in the design that represents the
* defined item. * defined item.
*/ */
NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
{ {
NetNet::Type wtype = type_; NetNet::Type wtype = type_;
if (wtype == NetNet::IMPLICIT) bool is_implicit_scalar = false;
if (wtype == NetNet::IMPLICIT) {
wtype = NetNet::WIRE; wtype = NetNet::WIRE;
if (wtype == NetNet::IMPLICIT_REG) is_implicit_scalar = true;
}
if (wtype == NetNet::IMPLICIT_REG) {
wtype = NetNet::REG; wtype = NetNet::REG;
is_implicit_scalar = true;
}
unsigned wid = 1; unsigned wid = 1;
long lsb = 0, msb = 0; long lsb = 0, msb = 0;
des->errors += error_cnt_; 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_) { if (port_set_ || net_set_) {
long pmsb = 0, plsb = 0, nmsb = 0, nlsb = 0; long pmsb = 0, plsb = 0, nmsb = 0, nlsb = 0;
bool bad_lsb = false, bad_msb = false; bool bad_lsb = false, bad_msb = false;
@ -902,6 +947,8 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
delete texpr; delete texpr;
nmsb = pmsb; nmsb = pmsb;
nlsb = plsb; 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_set_) assert(port_msb_ == 0 && port_lsb_ == 0);
if (port_msb_ == 0) assert(port_lsb_ == 0); if (port_msb_ == 0) assert(port_lsb_ == 0);
@ -1095,8 +1142,11 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
} }
if (debug_elaborate) { if (debug_elaborate) {
cerr << get_fileline() << ": debug: Create signal " cerr << get_fileline() << ": debug: Create signal " << wtype;
<< wtype << " ["<<msb<<":"<<lsb<<"] " << name_; if (!get_scalar()) {
cerr << " ["<<msb<<":"<<lsb<<"]";
}
cerr << " " << name_;
if (array_dimensions > 0) { if (array_dimensions > 0) {
cerr << " [" << array_s0 << ":" << array_e0 << "]" << endl; cerr << " [" << array_s0 << ":" << array_e0 << "]" << endl;
} }
@ -1108,6 +1158,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, array_s0, array_e0)
: new NetNet(scope, name_, wtype, msb, lsb); : new NetNet(scope, name_, wtype, msb, lsb);
if (wtype == NetNet::WIRE) sig->devirtualize_pins();
ivl_variable_type_t use_data_type = data_type_; ivl_variable_type_t use_data_type = data_type_;
if (use_data_type == IVL_VT_NO_TYPE) { if (use_data_type == IVL_VT_NO_TYPE) {
use_data_type = IVL_VT_LOGIC; use_data_type = IVL_VT_LOGIC;
@ -1124,6 +1176,8 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
sig->port_type(port_type_); sig->port_type(port_type_);
sig->set_signed(get_signed()); sig->set_signed(get_signed());
sig->set_isint(get_isint()); 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()) { if (ivl_discipline_t dis = get_discipline()) {
sig->set_discipline(dis); sig->set_discipline(dis);

View File

@ -189,6 +189,14 @@ void PGAssign::elaborate(Design*des, NetScope*scope) const
need_driver_flag = false; 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) { if (need_driver_flag) {
NetBUFZ*driver = new NetBUFZ(scope, scope->local_symbol(), NetBUFZ*driver = new NetBUFZ(scope, scope->local_symbol(),
rval->vector_width()); rval->vector_width());
@ -234,8 +242,10 @@ unsigned PGBuiltin::calculate_array_count_(Design*des, NetScope*scope,
gates, then I am expected to make more than one gates, then I am expected to make more than one
gate. Figure out how many are desired. */ gate. Figure out how many are desired. */
if (msb_) { if (msb_) {
need_constant_expr = true;
NetExpr*msb_exp = elab_and_eval(des, scope, msb_, -1); NetExpr*msb_exp = elab_and_eval(des, scope, msb_, -1);
NetExpr*lsb_exp = elab_and_eval(des, scope, lsb_, -1); NetExpr*lsb_exp = elab_and_eval(des, scope, lsb_, -1);
need_constant_expr = false;
NetEConst*msb_con = dynamic_cast<NetEConst*>(msb_exp); NetEConst*msb_con = dynamic_cast<NetEConst*>(msb_exp);
NetEConst*lsb_con = dynamic_cast<NetEConst*>(lsb_exp); NetEConst*lsb_con = dynamic_cast<NetEConst*>(lsb_exp);
@ -623,7 +633,9 @@ void PGBuiltin::elaborate(Design*des, NetScope*scope) const
return; return;
} }
lval_sigs[idx] = pin(idx)->elaborate_lnet(des, scope); 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. // 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()); ivl_assert(*this, idx == 0 || lval_sigs[idx]->vector_width() == lval_sigs[0]->vector_width());
@ -966,6 +978,28 @@ static bool need_bufz_for_input_port(const vector<NetNet*>&prts)
return false; 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 * Instantiate a module by recursively elaborating it. Set the path of
* the recursive elaboration so that signal names get properly * the recursive elaboration so that signal names get properly
@ -1058,7 +1092,7 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
// No named bindings, just use the positional list I // No named bindings, just use the positional list I
// already have. // already have.
assert(pin_count() == rmod->port_count()); ivl_assert(*this, pin_count() == rmod->port_count());
pins = get_pins(); pins = get_pins();
} }
@ -1093,28 +1127,50 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
// null parameter is passed in. // null parameter is passed in.
if (pins[idx] == 0) { 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 perm_string pname = peek_tail_name(mport[0]->path());
// 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()); NetNet*tmp = instance[0]->find_signal(pname);
ivl_assert(*this, tmp);
NetNet*tmp = instance[0]->find_signal(pname); if (tmp->port_type() == NetNet::PINPUT) {
assert(tmp); // 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: " cerr << get_fileline() << ": warning: "
<< "Instantiating module " << "Instantiating module "
<< rmod->mod_name() << rmod->mod_name()
<< " with dangling input port " << " with dangling input port '"
<< rmod->ports[idx]->name << rmod->ports[idx]->name;
<< "." << endl; 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;
}
} }
} }
@ -1146,13 +1202,13 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
for (unsigned ldx = 0 ; ldx < mport.size() ; ldx += 1) { for (unsigned ldx = 0 ; ldx < mport.size() ; ldx += 1) {
unsigned lbase = inst * mport.size(); unsigned lbase = inst * mport.size();
PEIdent*pport = mport[ldx]; PEIdent*pport = mport[ldx];
assert(pport); ivl_assert(*this, pport);
prts[lbase + ldx] prts[lbase + ldx]
= pport->elaborate_port(des, inst_scope); = pport->elaborate_port(des, inst_scope);
if (prts[lbase + ldx] == 0) if (prts[lbase + ldx] == 0)
continue; continue;
assert(prts[lbase + ldx]); ivl_assert(*this, prts[lbase + ldx]);
prts_vector_width += prts[lbase + ldx]->vector_width(); prts_vector_width += prts[lbase + ldx]->vector_width();
} }
} }
@ -1167,7 +1223,7 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
// We know by design that each instance has the same // We know by design that each instance has the same
// width port. Therefore, the prts_pin_count must be an // width port. Therefore, the prts_pin_count must be an
// even multiple of the instance count. // even multiple of the instance count.
assert(prts_vector_width % instance.size() == 0); ivl_assert(*this, prts_vector_width % instance.size() == 0);
unsigned desired_vector_width = prts_vector_width; unsigned desired_vector_width = prts_vector_width;
if (instance.size() != 1) if (instance.size() != 1)
@ -1284,12 +1340,12 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
} }
assert(sig); ivl_assert(*this, sig);
#ifndef NDEBUG #ifndef NDEBUG
if ((prts.size() >= 1) if ((prts.size() >= 1)
&& (prts[0]->port_type() != NetNet::PINPUT)) { && (prts[0]->port_type() != NetNet::PINPUT)) {
assert(sig->type() != NetNet::REG); ivl_assert(*this, sig->type() != NetNet::REG);
} }
#endif #endif
@ -1515,43 +1571,34 @@ void PGModule::elaborate_udp_(Design*des, PUdp*udp, NetScope*scope) const
module or primitive, it interprets them as parameter module or primitive, it interprets them as parameter
overrides. Correct that misconception here. */ overrides. Correct that misconception here. */
if (overrides_) { if (overrides_) {
PDelays tmp_del; if (overrides_->count() > 2) {
tmp_del.set_delays(overrides_, false); cerr << get_fileline() << ": error: UDPs take at most two "
tmp_del.eval_delays(des, scope, rise_expr, fall_expr, decay_expr); "delay arguments." << endl;
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;
des->errors += 1; des->errors += 1;
}
if (dynamic_cast<NetEConst*> (fall_expr)) {
} else { } else {
cerr << get_fileline() << ": error: Delay expressions must be " PDelays tmp_del;
<< "constant for primitives." << endl; tmp_del.set_delays(overrides_, false);
cerr << get_fileline() << ": : Cannot calculate " tmp_del.eval_delays(des, scope, rise_expr, fall_expr,
<< *rise_expr << endl; decay_expr);
des->errors += 1;
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); assert(udp);
NetUDP*net = new NetUDP(scope, my_name, udp->ports.count(), udp); NetUDP*net = new NetUDP(scope, my_name, udp->ports.count(), udp);
net->rise_time(rise_expr); net->rise_time(rise_expr);
@ -1815,6 +1862,20 @@ static NetExpr*elaborate_delay_expr(PExpr*expr, Design*des, NetScope*scope)
probe_expr_width(des, scope, expr); probe_expr_width(des, scope, expr);
NetExpr*dex = elab_and_eval(des, scope, expr, -1); 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 /* If the delay expression is a real constant or vector
constant, then evaluate it, scale it to the local time constant, then evaluate it, scale it to the local time
units, and return an adjusted NetEConst. */ units, and return an adjusted NetEConst. */
@ -2583,6 +2644,13 @@ NetProc* PCallTask::elaborate_usr(Design*des, NetScope*scope) const
ivl_variable_type_t lv_type = lv->expr_type(); ivl_variable_type_t lv_type = lv->expr_type();
NetExpr*rv = elaborate_rval_expr(des, scope, lv_type, wid, parms_[idx]); 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()) { if (wid > rv->expr_width()) {
rv->set_width(wid); rv->set_width(wid);
rv = pad_to_width(rv, wid, *this); rv = pad_to_width(rv, wid, *this);
@ -3041,6 +3109,7 @@ NetProc* PEventStatement::elaborate_st(Design*des, NetScope*scope,
break; break;
default: default:
pr = NULL;
assert(0); assert(0);
} }
@ -3716,15 +3785,26 @@ void PSpecPath::elaborate(Design*des, NetScope*scope) const
/* Do not elaborate specify delay paths if this feature is /* Do not elaborate specify delay paths if this feature is
turned off. */ turned off. */
if (!gn_specify_blocks_flag) if (!gn_specify_blocks_flag) return;
return;
ivl_assert(*this, conditional || (condition==0)); ivl_assert(*this, conditional || (condition==0));
ndelays = delays.size(); ndelays = delays.size();
if (ndelays > 12) if (ndelays > 12) 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(); int shift = scope->time_unit() - des->get_precision();
/* Elaborate the delay values themselves. Remember to scale /* Elaborate the delay values themselves. Remember to scale
@ -4289,6 +4369,7 @@ Design* elaborate(list<perm_string>roots)
scope->set_line(rmod); scope->set_line(rmod);
scope->time_unit(rmod->time_unit); scope->time_unit(rmod->time_unit);
scope->time_precision(rmod->time_precision); scope->time_precision(rmod->time_precision);
scope->time_from_timescale(rmod->time_from_timescale);
scope->default_nettype(rmod->default_nettype); scope->default_nettype(rmod->default_nettype);
des->set_precision(rmod->time_precision); des->set_precision(rmod->time_precision);
@ -4308,14 +4389,17 @@ Design* elaborate(list<perm_string>roots)
des->elaboration_work_list.push_back(es); 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 // Run the work list of scope elaborations until the list is
// empty. This list is initially populated above where the // empty. This list is initially populated above where the
// initial root scopes are primed. // initial root scopes are primed.
while (! des->elaboration_work_list.empty()) { 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. // Transfer the queue to a temporary queue.
list<elaborator_work_item_t*> cur_queue; list<elaborator_work_item_t*> cur_queue;
while (! des->elaboration_work_list.empty()) { while (! des->elaboration_work_list.empty()) {
@ -4369,6 +4453,7 @@ Design* elaborate(list<perm_string>roots)
NetScope *scope = root_elems[i]->scope; NetScope *scope = root_elems[i]->scope;
rc &= rmod->elaborate(des, scope); rc &= rmod->elaborate(des, scope);
delete root_elems[i];
} }
if (rc == false) { if (rc == false) {

View File

@ -133,7 +133,7 @@ NetExpr* NetEBAdd::eval_tree(int prune_to_width)
if (debug_eval_tree) { if (debug_eval_tree) {
cerr << get_fileline() << ": debug: " cerr << get_fileline() << ": debug: "
<< "Partially evalutate " << *this << "Partially evaluate " << *this
<< " using (a+2)-1 --> (a+1) transform." << endl; << " using (a+2)-1 --> (a+1) transform." << endl;
} }
@ -381,6 +381,7 @@ NetEConst* NetEBComp::eval_leeq_real_(NetExpr*le, NetExpr*ri, bool eq_flag)
break; break;
default: default:
lv = 0.0;
cerr << get_fileline() << ": internal error: " cerr << get_fileline() << ": internal error: "
<< "Unexpected expression type? " << le->expr_type() << endl; << "Unexpected expression type? " << le->expr_type() << endl;
assert(0); assert(0);
@ -401,6 +402,7 @@ NetEConst* NetEBComp::eval_leeq_real_(NetExpr*le, NetExpr*ri, bool eq_flag)
break; break;
default: default:
rv = 0.0;
cerr << get_fileline() << ": internal error: " cerr << get_fileline() << ": internal error: "
<< "Unexpected expression type? " << ri->expr_type() << endl; << "Unexpected expression type? " << ri->expr_type() << endl;
assert(0); assert(0);
@ -585,6 +587,7 @@ NetEConst* NetEBComp::eval_eqeq_real_(NetExpr*le, NetExpr*ri, bool ne_flag)
break; break;
default: default:
lv = 0.0;
cerr << get_fileline() << ": internal error: " cerr << get_fileline() << ": internal error: "
<< "Unexpected expression type? " << le->expr_type() << endl; << "Unexpected expression type? " << le->expr_type() << endl;
assert(0); assert(0);
@ -605,6 +608,7 @@ NetEConst* NetEBComp::eval_eqeq_real_(NetExpr*le, NetExpr*ri, bool ne_flag)
break; break;
default: default:
rv = 0.0;
cerr << get_fileline() << ": internal error: " cerr << get_fileline() << ": internal error: "
<< "Unexpected expression type? " << ri->expr_type() << endl; << "Unexpected expression type? " << ri->expr_type() << endl;
assert(0); assert(0);
@ -996,6 +1000,11 @@ NetExpr* NetEBPow::eval_tree_real_()
NetECReal*res = new NetECReal( pow(lval,rval) ); NetECReal*res = new NetECReal( pow(lval,rval) );
res->set_line(*this); res->set_line(*this);
if (debug_eval_tree)
cerr << get_fileline() << ": debug: Evaluate (real) "
<< lval << " ** " << rval << " --> " << *res << endl;
return res; return res;
} }
@ -1016,7 +1025,14 @@ NetExpr* NetEBPow::eval_tree(int prune_to_width)
verinum lval = lc->value(); verinum lval = lc->value();
verinum rval = rc->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;
} }
/* /*
@ -1161,16 +1177,6 @@ NetEConst* NetEConcat::eval_tree(int prune_to_width)
if (local_errors > 0) return 0; 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 // At this point, the "gap" is the width of a single repeat of
// the concatenation. The total width of the result is the gap // the concatenation. The total width of the result is the gap
// times the repeat count. // times the repeat count.
@ -1713,6 +1719,7 @@ NetExpr* evaluate_clog2(NetExpr*&arg_)
res = integer_width; res = integer_width;
verinum tmp (res, integer_width); verinum tmp (res, integer_width);
tmp.has_sign(true);
NetEConst*rtn = new NetEConst(tmp); NetEConst*rtn = new NetEConst(tmp);
return rtn; return rtn;
} }

View File

@ -122,6 +122,7 @@ NetNet* NetEBAdd::synthesize(Design*des, NetScope*scope, NetExpr*root)
NetNet*osig = new NetNet(lsig->scope(), path, NetNet::IMPLICIT, width); NetNet*osig = new NetNet(lsig->scope(), path, NetNet::IMPLICIT, width);
osig->local_flag(true); osig->local_flag(true);
osig->data_type(expr_type()); osig->data_type(expr_type());
osig->set_signed(has_sign());
perm_string oname = osig->scope()->local_symbol(); perm_string oname = osig->scope()->local_symbol();
NetAddSub *adder = new NetAddSub(lsig->scope(), oname, width); NetAddSub *adder = new NetAddSub(lsig->scope(), oname, width);
@ -199,6 +200,7 @@ NetNet* NetEBBits::synthesize(Design*des, NetScope*scope, NetExpr*root)
gate = new NetLogic(scope, oname, 3, NetLogic::XNOR, width); gate = new NetLogic(scope, oname, 3, NetLogic::XNOR, width);
break; break;
default: default:
gate = NULL;
assert(0); assert(0);
} }
@ -390,6 +392,7 @@ NetNet* NetEBPow::synthesize(Design*des, NetScope*scope, NetExpr*root)
NetNet::IMPLICIT, width); NetNet::IMPLICIT, width);
osig->set_line(*this); osig->set_line(*this);
osig->data_type(expr_type()); osig->data_type(expr_type());
osig->set_signed(has_sign());
osig->local_flag(true); osig->local_flag(true);
connect(powr->pin_Result(), osig->pin(0)); connect(powr->pin_Result(), osig->pin(0));
@ -426,6 +429,7 @@ NetNet* NetEBMult::synthesize(Design*des, NetScope*scope, NetExpr*root)
NetNet::IMPLICIT, width); NetNet::IMPLICIT, width);
osig->set_line(*this); osig->set_line(*this);
osig->data_type(expr_type()); osig->data_type(expr_type());
osig->set_signed(has_sign());
osig->local_flag(true); osig->local_flag(true);
connect(mult->pin_Result(), osig->pin(0)); connect(mult->pin_Result(), osig->pin(0));
@ -601,8 +605,8 @@ NetNet* NetEBShift::synthesize(Design*des, NetScope*scope, NetExpr*root)
return 0; return 0;
} }
const bool right_flag = op_ == 'r' || op_ == 'R'; const bool right_flag = op_ == 'r' || op_ == 'R';
const bool signed_flag = op_ == 'R'; const bool signed_flag = has_sign() && op_ == 'R';
/* Detect the special case where the shift amount is /* Detect the special case where the shift amount is
constant. Evaluate the shift amount, and simply reconnect constant. Evaluate the shift amount, and simply reconnect
@ -719,28 +723,42 @@ NetNet* NetEBShift::synthesize(Design*des, NetScope*scope, NetExpr*root)
NetNet* NetEConcat::synthesize(Design*des, NetScope*scope, NetExpr*root) NetNet* NetEConcat::synthesize(Design*des, NetScope*scope, NetExpr*root)
{ {
/* First, synthesize the operands. */ /* First, synthesize the operands. */
unsigned nparms = parms_.count();
NetNet**tmp = new NetNet*[parms_.count()]; NetNet**tmp = new NetNet*[parms_.count()];
bool flag = true; bool flag = true;
ivl_variable_type_t data_type = IVL_VT_NO_TYPE;
for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) { for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) {
tmp[idx] = parms_[idx]->synthesize(des, scope, root); if (parms_[idx]->expr_width() == 0) {
if (tmp[idx] == 0) /* We need to synthesize a replication of zero. */
flag = false; 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) if (flag == false) return 0;
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. */ /* Make a NetNet object to carry the output vector. */
perm_string path = scope->local_symbol(); perm_string path = scope->local_symbol();
NetNet*osig = new NetNet(scope, path, NetNet::IMPLICIT, expr_width()); NetNet*osig = new NetNet(scope, path, NetNet::IMPLICIT, expr_width());
osig->local_flag(true); osig->local_flag(true);
osig->data_type(tmp[0]->data_type()); osig->data_type(data_type);
NetConcat*concat = new NetConcat(scope, scope->local_symbol(), NetConcat*concat = new NetConcat(scope, scope->local_symbol(),
osig->vector_width(), osig->vector_width(),
parms_.count() * repeat()); nparms * repeat());
concat->set_line(*this); concat->set_line(*this);
des->add_node(concat); des->add_node(concat);
connect(concat->pin(0), osig->pin(0)); connect(concat->pin(0), osig->pin(0));
@ -750,7 +768,7 @@ NetNet* NetEConcat::synthesize(Design*des, NetScope*scope, NetExpr*root)
for (unsigned rpt = 0; rpt < repeat(); rpt += 1) { for (unsigned rpt = 0; rpt < repeat(); rpt += 1) {
for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) { for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) {
unsigned concat_item = 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)); connect(concat->pin(cur_pin), tmp[concat_item]->pin(0));
cur_pin += 1; cur_pin += 1;
count_input_width += tmp[concat_item]->vector_width(); count_input_width += tmp[concat_item]->vector_width();
@ -773,6 +791,11 @@ NetNet* NetEConst::synthesize(Design*des, NetScope*scope, NetExpr*)
{ {
perm_string path = scope->local_symbol(); perm_string path = scope->local_symbol();
unsigned width=expr_width(); 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); NetNet*osig = new NetNet(scope, path, NetNet::IMPLICIT, width);
osig->local_flag(true); osig->local_flag(true);
@ -841,6 +864,7 @@ NetNet* NetEUBits::synthesize(Design*des, NetScope*scope, NetExpr*root)
gate = new NetLogic(scope, oname, 2, NetLogic::NOT, width); gate = new NetLogic(scope, oname, 2, NetLogic::NOT, width);
break; break;
default: default:
gate = NULL;
assert(0); assert(0);
} }
@ -909,11 +933,6 @@ NetNet* NetEUReduce::synthesize(Design*des, NetScope*scope, NetExpr*root)
return 0; 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; NetUReduce::TYPE rtype = NetUReduce::NONE;
switch (op()) { switch (op()) {
@ -944,8 +963,13 @@ NetNet* NetEUReduce::synthesize(Design*des, NetScope*scope, NetExpr*root)
NetUReduce*gate = new NetUReduce(scope, scope->local_symbol(), NetUReduce*gate = new NetUReduce(scope, scope->local_symbol(),
rtype, isig->vector_width()); rtype, isig->vector_width());
des->add_node(gate); 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)); connect(gate->pin(0), osig->pin(0));
for (unsigned idx = 0 ; idx < isig->pin_count() ; idx += 1) for (unsigned idx = 0 ; idx < isig->pin_count() ; idx += 1)
connect(gate->pin(1+idx), isig->pin(idx)); connect(gate->pin(1+idx), isig->pin(idx));
@ -1067,7 +1091,8 @@ NetNet* NetESelect::synthesize(Design *des, NetScope*scope, NetExpr*root)
if (base_ != 0) { if (base_ != 0) {
off = base_->synthesize(des, scope, root); 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); sel->set_line(*this);
des->add_node(sel); des->add_node(sel);
@ -1347,6 +1372,10 @@ NetNet* NetEUFunc::synthesize(Design*des, NetScope*scope, NetExpr*root)
/* Synthesize the arguments. */ /* Synthesize the arguments. */
bool errors = false; bool errors = false;
for (unsigned idx = 0; idx < eparms.count(); idx += 1) { for (unsigned idx = 0; idx < eparms.count(); idx += 1) {
if (dynamic_cast<NetEEvent*> (parms_[idx])) {
errors = true;
continue;
}
NetNet*tmp = parms_[idx]->synthesize(des, scope, root); NetNet*tmp = parms_[idx]->synthesize(des, scope, root);
if (tmp == 0) { if (tmp == 0) {
cerr << get_fileline() << ": error: Unable to synthesize " cerr << get_fileline() << ": error: Unable to synthesize "
@ -1384,9 +1413,15 @@ NetNet* NetEUFunc::synthesize(Design*des, NetScope*scope, NetExpr*root)
/* Connect the pins to the arguments. */ /* Connect the pins to the arguments. */
NetFuncDef*def = func_->func_def(); NetFuncDef*def = func_->func_def();
for (unsigned idx = 0; idx < eparms.count(); idx += 1) { for (unsigned idx = 0; idx < eparms.count(); idx += 1) {
NetNet*tmp = pad_to_width(des, eparms[idx], unsigned width = def->port(idx)->vector_width();
def->port(idx)->vector_width(), *this); NetNet*tmp;
connect(net->pin(idx+1), tmp->pin(0)); 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; return osig;

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 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 of 4-value behavior in the dead zone, and appears more user friendly
when viewed by reasonable viewers. 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.

View File

@ -1,15 +1,15 @@
.TH iverilog-vpi 1 "November 19th, 2008" "" "Version 0.9.devel" .TH iverilog-vpi 1 "April 17th, 2009" "" "Version %M.%m.%n %E"
.SH NAME .SH NAME
iverilog-vpi - Compile front end for VPI modules iverilog-vpi - Compile front end for VPI modules
.SH SYNOPSIS .SH SYNOPSIS
.B iverilog-vpi .B iverilog-vpi
[--name=\fIname\fP] [\-\-name=\fIname\fP]
\fIsourcefile\fP... \fIsourcefile\fP...
.SH DESCRIPTION .SH DESCRIPTION
.PP .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 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 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 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. \fIfoo.vpi\fP.
.SH OPTIONS .SH OPTIONS
.l \fIiverilog\-vpi\fP accepts the following options:
\fIiverilog-vpi\fP accepts the following options:
.TP 8 .TP 8
.B -l\fIlibrary\fP .B -l\fIlibrary\fP
Include the named library in the link of the VPI module. This allows 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" .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 support the more intractable development environment. These flags help
the program locate parts that it needs. the program locate parts that it needs.
@ -62,7 +61,7 @@ the program locate parts that it needs.
.B -mingw=\fIpath\fP .B -mingw=\fIpath\fP
Tell the program the root of the Mingw compiler tool suite. The Tell the program the root of the Mingw compiler tool suite. The
\fBvvp\fP runtime is compiled with this compiler, and this is 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 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 needed once. The compiler will save the \fIpath\fP in the registry for
use later. use later.
@ -76,7 +75,7 @@ stored in the registry for future use.
.SH "UNIX-ONLY OPTIONS" .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 let Makefile gurus peek at the configuration of the \fIiverilog\fP
installation. This way, Makefiles can be written that handle complex VPI installation. This way, Makefiles can be written that handle complex VPI
builds natively, and without hard-coding values that depend on the 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 .P
Example GNU makefile that takes advantage of these flags: Example GNU makefile that takes advantage of these flags:
.IP "" 4 .IP "" 4
CFLAGS = -Wall -O $(CFLAGS_$@) CFLAGS = \-Wall \-O $(CFLAGS_$@)
.br .br
VPI_CFLAGS := $(shell iverilog-vpi --cflags) VPI_CFLAGS := $(shell iverilog-vpi \-\-cflags)
.br .br
CFLAGS_messagev.o = $(VPI_CFLAGS) CFLAGS_messagev.o = $(VPI_CFLAGS)
.br .br
@ -129,7 +128,7 @@ iverilog(1), vvp(1),
.SH COPYRIGHT .SH COPYRIGHT
.nf .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 This document can be freely redistributed according to the terms of the
GNU General Public License version 2.0 GNU General Public License version 2.0

View File

@ -19,7 +19,7 @@
# #
# These are the variables used for compiling files # These are the variables used for compiling files
CC=@IVCC@ CC="@IVCC@"
CXX=@IVCXX@ CXX=@IVCXX@
CFLAGS="@PIC@ @IVCFLAGS@ -I@INCLUDEDIR@" CFLAGS="@PIC@ @IVCFLAGS@ -I@INCLUDEDIR@"

View File

@ -161,6 +161,7 @@ ivl_scope_event
ivl_scope_events ivl_scope_events
ivl_scope_file ivl_scope_file
ivl_scope_is_auto ivl_scope_is_auto
ivl_scope_is_cell
ivl_scope_lineno ivl_scope_lineno
ivl_scope_logs ivl_scope_logs
ivl_scope_log ivl_scope_log

View File

@ -1537,6 +1537,9 @@ extern unsigned ivl_parameter_lineno(ivl_parameter_t net);
* ivl_scope_is_auto * ivl_scope_is_auto
* Is the task or function declared to be automatic? * 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_var
* ivl_scope_vars * ivl_scope_vars
* REMOVED * REMOVED
@ -1614,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 ivl_event_t ivl_scope_event(ivl_scope_t net, unsigned idx);
extern const char* ivl_scope_file(ivl_scope_t net); 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_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_lineno(ivl_scope_t net);
extern unsigned ivl_scope_logs(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); extern ivl_net_logic_t ivl_scope_log(ivl_scope_t net, unsigned idx);

View File

@ -2,7 +2,6 @@
Icarus Verilog LOADABLE TARGET API (ivl_target) Icarus Verilog LOADABLE TARGET API (ivl_target)
Copyright 2002 Stephen Williams <steve@icarus.com> Copyright 2002 Stephen Williams <steve@icarus.com>
$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 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 There are ivl_lpm_size() input ports, each with the width
ivl_lpm_data2_width(). The actual nexus is indexed by ivl_lpm_data2(). 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.

View File

@ -52,7 +52,7 @@ distclean: clean
rm -f Makefile config.log rm -f Makefile config.log
Makefile: $(srcdir)/Makefile.in ../config.status Makefile: $(srcdir)/Makefile.in ../config.status
../config.status --file=$@ cd ..; ./config.status --file=ivlpp/$@
O = main.o lexor.o O = main.o lexor.o
@ -74,4 +74,4 @@ uninstall:
rm -f "$(DESTDIR)$(libdir)/ivl$(suffix)/ivlpp@EXEEXT@" rm -f "$(DESTDIR)$(libdir)/ivl$(suffix)/ivlpp@EXEEXT@"
lexor.o: lexor.c globals.h lexor.o: lexor.c globals.h
main.o: main.c globals.h ../version.h main.o: main.c globals.h $(srcdir)/../version_base.h ../version_tag.h

View File

@ -64,13 +64,8 @@ struct include_stack_t
/* If we are reparsing a macro expansion, file is 0 and this /* If we are reparsing a macro expansion, file is 0 and this
* member points to the string in progress * member points to the string in progress
*/ */
const char* str; char* str;
char* orig_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;
int stringify_flag; int stringify_flag;
@ -462,7 +457,7 @@ keywords (include|define|undef|ifdef|ifndef|else|elseif|endif)
<IFCCOMMENT>\n\r | <IFCCOMMENT>\n\r |
<IFCCOMMENT>\r\n | <IFCCOMMENT>\r\n |
<IFCCOMMENT>\n | <IFCCOMMENT>\n |
<IFCCOMMENT>\r { istack->lineno += 1; } <IFCCOMMENT>\r { istack->lineno += 1; fputc('\n', yyout); }
<IFCCOMMENT>"*/" { BEGIN(comment_enter); } <IFCCOMMENT>"*/" { BEGIN(comment_enter); }
<IFDEF_FALSE,IFDEF_SUPR>[^\r\n] { } <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_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>")" { <MA_ADD>")" {
if (ma_parenthesis_level > 0) { if (ma_parenthesis_level > 0) {
@ -1352,10 +1348,17 @@ static void do_expand(int use_args)
struct include_stack_t*isp; struct include_stack_t*isp;
int head = 0; int head = 0;
int tail = 0; int tail = 0;
const char *cp;
unsigned escapes = 0;
char *str_buf = 0;
if (cur_macro->keyword) if (cur_macro->keyword)
{ {
fprintf(yyout, "%s", cur_macro->value); fprintf(yyout, "%s", cur_macro->value);
if (do_expand_stringify_flag) {
do_expand_stringify_flag = 0;
fputc('"', yyout);
}
return; return;
} }
@ -1364,6 +1367,7 @@ static void do_expand(int use_args)
head = exp_buf_size - exp_buf_free; head = exp_buf_size - exp_buf_free;
expand_using_args(); expand_using_args();
tail = exp_buf_size - exp_buf_free; tail = exp_buf_size - exp_buf_free;
exp_buf_free += tail - head;
if (tail == head) if (tail == head)
return; return;
@ -1376,14 +1380,47 @@ static void do_expand(int use_args)
if (use_args) if (use_args)
{ {
isp->str = &exp_buf[head]; isp->str = &exp_buf[head];
isp->ebs = tail - head;
} }
else else
{ {
isp->str = cur_macro->value; 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; isp->next = istack;
istack->yybs = YY_CURRENT_BUFFER; istack->yybs = YY_CURRENT_BUFFER;
istack = isp; istack = isp;
@ -1572,7 +1609,7 @@ static int load_next_input()
else else
line_mask_flag = 1; line_mask_flag = 1;
exp_buf_free += isp->ebs; free(isp->orig_str);
} }
if (isp->stringify_flag) { if (isp->stringify_flag) {
@ -1749,7 +1786,6 @@ void reset_lexor(FILE* out, char* paths[])
isp->path = strdup(paths[0]); isp->path = strdup(paths[0]);
isp->file = fopen(paths[0], "r"); isp->file = fopen(paths[0], "r");
isp->str = 0; isp->str = 0;
isp->ebs = 0;
isp->lineno = 0; isp->lineno = 0;
isp->stringify_flag = 0; isp->stringify_flag = 0;
isp->comment = NULL; isp->comment = NULL;
@ -1779,7 +1815,6 @@ void reset_lexor(FILE* out, char* paths[])
isp->path = strdup(paths[idx]); isp->path = strdup(paths[idx]);
isp->file = 0; isp->file = 0;
isp->str = 0; isp->str = 0;
isp->ebs = 0;
isp->next = 0; isp->next = 0;
isp->lineno = 0; isp->lineno = 0;
isp->stringify_flag = 0; isp->stringify_flag = 0;
@ -1807,4 +1842,5 @@ void destroy_lexor()
# endif # endif
# endif # endif
free(def_buf); free(def_buf);
free(exp_buf);
} }

View File

@ -18,7 +18,8 @@ const char COPYRIGHT[] =
*/ */
# include "config.h" # include "config.h"
# include "version.h" # include "version_base.h"
# include "version_tag.h"
const char NOTICE[] = const char NOTICE[] =
" This program is free software; you can redistribute it and/or modify\n" " This program is free software; you can redistribute it and/or modify\n"
@ -214,26 +215,34 @@ int main(int argc, char*argv[])
FILE*precomp_out = NULL; FILE*precomp_out = NULL;
/* Define preprocessor keywords that I plan to just pass. */ /* 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("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_nettype", "`default_nettype", 1, 0);
define_macro("default_trireg_strength", "`default_trireg_strength", 1, 0); define_macro("end_keywords", "`end_keywords", 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("endcelldefine", "`endcelldefine", 1, 0); define_macro("endcelldefine", "`endcelldefine", 1, 0);
define_macro("endprotect", "`endprotect", 1, 0);
define_macro("line", "`line", 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("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("resetall", "`resetall", 1, 0);
define_macro("suppress_faults", "`suppress_faults", 1, 0);
define_macro("timescale", "`timescale", 1, 0); define_macro("timescale", "`timescale", 1, 0);
define_macro("unconnected_drive", "`unconnected_drive", 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); define_macro("uselib", "`uselib", 1, 0);
include_cnt = 2; include_cnt = 2;
@ -357,14 +366,17 @@ int main(int argc, char*argv[])
if (precomp_out_path) { if (precomp_out_path) {
precomp_out = fopen(precomp_out_path, "wb"); precomp_out = fopen(precomp_out_path, "wb");
if (precomp_out == 0) { if (precomp_out == 0) {
if (out_path) fclose(out);
perror(precomp_out_path); perror(precomp_out_path);
exit(1); exit(1);
} }
} }
if(dep_path) { if (dep_path) {
depend_file = fopen(dep_path, "a"); depend_file = fopen(dep_path, "a");
if (depend_file == 0) { if (depend_file == 0) {
if (out_path) fclose(out);
if (precomp_out) fclose(precomp_out);
perror(dep_path); perror(dep_path);
exit(1); exit(1);
} }
@ -372,24 +384,32 @@ int main(int argc, char*argv[])
if (source_cnt == 0) { if (source_cnt == 0) {
fprintf(stderr, "%s: No input files given.\n", argv[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; return 1;
} }
/* Pass to the lexical analyzer the list of input file, and /* Pass to the lexical analyzer the list of input file, and
start scanning. */ start scanning. */
reset_lexor(out, source_list); 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(); destroy_lexor();
if(depend_file) { if (depend_file) fclose(depend_file);
fclose(depend_file);
}
if (precomp_out) { if (precomp_out) {
dump_precompiled_defines(precomp_out); dump_precompiled_defines(precomp_out);
fclose(precomp_out); fclose(precomp_out);
} }
if (out_path) fclose(out);
/* Free the source and include directory lists. */ /* Free the source and include directory lists. */
for (lp = 0; lp < source_cnt; lp += 1) { for (lp = 0; lp < source_cnt; lp += 1) {
free(source_list[lp]); free(source_list[lp]);

540
lexor.lex
View File

@ -67,9 +67,6 @@ static const char* set_file_name(char*text)
return path; return path;
} }
extern void pform_set_timescale(int, int, const char*file, unsigned line);
void reset_lexor(); void reset_lexor();
static void line_directive(); static void line_directive();
static void line_directive2(); static void line_directive2();
@ -83,11 +80,15 @@ static verinum*make_unsized_hex(const char*txt);
static int dec_buf_div2(char *buf); static int dec_buf_div2(char *buf);
static void process_timescale(const char*txt); static void process_timescale(const char*txt);
static void process_ucdrive(const char*txt);
static list<int> keyword_mask_stack; static list<int> keyword_mask_stack;
static int comment_enter; static int comment_enter;
static bool in_module = false; static bool in_module = false;
static bool in_UDP = false;
bool in_celldefine = false;
UCDriveType uc_drive = UCD_NONE;
%} %}
%x CCOMMENT %x CCOMMENT
@ -96,6 +97,7 @@ static bool in_module = false;
%x CSTRING %x CSTRING
%s UDPTABLE %s UDPTABLE
%x PPTIMESCALE %x PPTIMESCALE
%x PPUCDRIVE
%x PPDEFAULT_NETTYPE %x PPDEFAULT_NETTYPE
%x PPBEGIN_KEYWORDS %x PPBEGIN_KEYWORDS
%s EDGES %s EDGES
@ -107,8 +109,9 @@ S [afpnumkKMGT]
%% %%
^"#line"[ ]+\"[^\"]*\"[ ]+[0-9]+.* { line_directive(); } /* Recognize the various line directives. */
^"`line"[ ]+[0-9]+[ ]+\"[^\"]*\".* { line_directive2(); } ^"#line"[ \t]+.+ { line_directive(); }
^[ \t]?"`line"[ \t]+.+ { line_directive2(); }
[ \t\b\f\r] { ; } [ \t\b\f\r] { ; }
\n { yylloc.first_line += 1; } \n { yylloc.first_line += 1; }
@ -237,6 +240,14 @@ S [afpnumkKMGT]
in_module = false; in_module = false;
break; break;
case K_primitive:
in_UDP = true;
break;
case K_endprimitive:
in_UDP = false;
break;
default: default:
yylval.text = 0; yylval.text = 0;
break; break;
@ -263,22 +274,35 @@ S [afpnumkKMGT]
return IDENTIFIER; } return IDENTIFIER; }
\$([a-zA-Z0-9$_]+) { \$([a-zA-Z0-9$_]+) {
if (strcmp(yytext,"$setuphold") == 0) /* The 1364-1995 timing checks. */
return K_Ssetuphold;
if (strcmp(yytext,"$attribute") == 0)
return KK_attribute;
if (strcmp(yytext,"$hold") == 0) if (strcmp(yytext,"$hold") == 0)
return K_Shold; return K_Shold;
if (strcmp(yytext,"$nochange") == 0)
return K_Snochange;
if (strcmp(yytext,"$period") == 0) if (strcmp(yytext,"$period") == 0)
return K_Speriod; return K_Speriod;
if (strcmp(yytext,"$recovery") == 0) if (strcmp(yytext,"$recovery") == 0)
return K_Srecovery; return K_Srecovery;
if (strcmp(yytext,"$recrem") == 0)
return K_Srecrem;
if (strcmp(yytext,"$setup") == 0) if (strcmp(yytext,"$setup") == 0)
return K_Ssetup; return K_Ssetup;
if (strcmp(yytext,"$setuphold") == 0)
return K_Ssetuphold;
if (strcmp(yytext,"$skew") == 0)
return K_Sskew;
if (strcmp(yytext,"$width") == 0) if (strcmp(yytext,"$width") == 0)
return K_Swidth; 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); yylval.text = strdupnew(yytext);
return SYSTEM_IDENTIFIER; } return SYSTEM_IDENTIFIER; }
@ -348,7 +372,7 @@ S [afpnumkKMGT]
return REALTIME; } return REALTIME; }
/* Notice and handle the timescale directive. */ /* Notice and handle the `timescale directive. */
^{W}?`timescale { BEGIN(PPTIMESCALE); } ^{W}?`timescale { BEGIN(PPTIMESCALE); }
<PPTIMESCALE>.* { process_timescale(yytext); } <PPTIMESCALE>.* { process_timescale(yytext); }
@ -362,28 +386,74 @@ S [afpnumkKMGT]
yylloc.first_line += 1; yylloc.first_line += 1;
BEGIN(0); } 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 /* These are directives that I do not yet support. I think that IVL
should handle these, not an external preprocessor. */ 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_decay_time{W}?.* { }
^{W}?`default_trireg_strength{W}?.* { } ^{W}?`default_trireg_strength{W}?.* { }
^{W}?`delay_mode_distributed{W}?.* { } ^{W}?`delay_mode_distributed{W}?.* { }
^{W}?`delay_mode_unit{W}?.* { }
^{W}?`delay_mode_path{W}?.* { } ^{W}?`delay_mode_path{W}?.* { }
^{W}?`delay_mode_unit{W}?.* { }
^{W}?`delay_mode_zero{W}?.* { } ^{W}?`delay_mode_zero{W}?.* { }
/* From other places. */
^{W}?`disable_portfaults{W}?.* { } ^{W}?`disable_portfaults{W}?.* { }
^{W}?`enable_portfaults{W}?.* { } ^{W}?`enable_portfaults{W}?.* { }
^{W}?`endcelldefine{W}?.* { }
`endprotect { } `endprotect { }
^{W}?`line{W}?.* { }
^{W}?`nosuppress_faults{W}?.* { } ^{W}?`nosuppress_faults{W}?.* { }
^{W}?`nounconnected_drive{W}?.* { }
`protect { } `protect { }
^{W}?`resetall{W}?.* { }
^{W}?`suppress_faults{W}?.* { } ^{W}?`suppress_faults{W}?.* { }
^{W}?`unconnected_drive{W}?.* { }
^{W}?`uselib{W}?.* { } ^{W}?`uselib{W}?.* { }
^{W}?`begin_keywords{W}? { BEGIN(PPBEGIN_KEYWORDS); } ^{W}?`begin_keywords{W}? { BEGIN(PPBEGIN_KEYWORDS); }
@ -447,16 +517,38 @@ S [afpnumkKMGT]
NetNet::Type net_type; NetNet::Type net_type;
size_t wordlen = strcspn(yytext, " \t\f\r\n"); size_t wordlen = strcspn(yytext, " \t\f\r\n");
yytext[wordlen] = 0; yytext[wordlen] = 0;
/* Add support for other wire types and better error detection. */
if (strcmp(yytext,"wire") == 0) { if (strcmp(yytext,"wire") == 0) {
net_type = NetNet::WIRE; 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) { } else if (strcmp(yytext,"none") == 0) {
net_type = NetNet::NONE; net_type = NetNet::NONE;
} else { } else {
cerr << yylloc.text << ":" << yylloc.first_line cerr << yylloc.text << ":" << yylloc.first_line
<< ": error: Net type " << yytext << ": error: Net type " << yytext
<< " is not a valid (and supported)" << " is not a valid (or supported)"
<< " default net type." << endl; << " default net type." << endl;
net_type = NetNet::WIRE; net_type = NetNet::WIRE;
error_count += 1; error_count += 1;
@ -483,6 +575,12 @@ S [afpnumkKMGT]
<< endl; << endl;
} }
^{W}?`elsif{W}?.* {
cerr << yylloc.text << ":" << yylloc.first_line <<
": warning: `elsif not supported. Use an external preprocessor."
<< endl;
}
^{W}?`endif{W}?.* { ^{W}?`endif{W}?.* {
cerr << yylloc.text << ":" << yylloc.first_line << cerr << yylloc.text << ":" << yylloc.first_line <<
": warning: `endif not supported. Use an external preprocessor." ": warning: `endif not supported. Use an external preprocessor."
@ -495,6 +593,12 @@ S [afpnumkKMGT]
<< endl; << endl;
} }
^{W}?`ifndef{W}?.* {
cerr << yylloc.text << ":" << yylloc.first_line <<
": warning: `ifndef not supported. Use an external preprocessor."
<< endl;
}
^`include{W}?.* { ^`include{W}?.* {
cerr << yylloc.text << ":" << yylloc.first_line << cerr << yylloc.text << ":" << yylloc.first_line <<
": warning: `include not supported. Use an external preprocessor." ": warning: `include not supported. Use an external preprocessor."
@ -936,6 +1040,128 @@ static verinum*make_unsized_dec(const char*ptr)
return res; 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: * The timescale parameter has the form:
@ -943,98 +1169,46 @@ static verinum*make_unsized_dec(const char*ptr)
*/ */
static void process_timescale(const char*txt) static void process_timescale(const char*txt)
{ {
unsigned num;
const char*cp = txt + strspn(txt, " \t"); 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 unit = 0;
int prec = 0; int prec = 0;
num = strtoul(cp, &tmp, 10); /* Get the time units. */
if (num == 0) { if (get_timescale_const(cp, unit, true)) return;
VLerror(yylloc, "Invalid timescale string.");
return;
}
while (num >= 10) { /* Skip any space after the time units, the '/' and any
unit += 1; * space after the '/'. */
num /= 10;
}
if (num != 1) {
VLerror(yylloc, "Invalid timescale unit number.");
return;
}
cp = tmp;
cp += strspn(cp, " \t"); cp += strspn(cp, " \t");
ctmp = cp + strcspn(cp, " \t/"); if (*cp != '/') {
VLerror(yylloc, "`timescale separator '/' appears to be missing.");
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");
return; return;
} }
cp += 1;
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 += strspn(cp, " \t"); cp += strspn(cp, " \t");
ctmp = cp + strcspn(cp, " \t\r");
if (strncmp("s", cp, ctmp-cp) == 0) { /* Get the time precision. */
prec -= 0; if (get_timescale_const(cp, prec, false)) return;
} else if (strncmp("ms", cp, ctmp-cp) == 0) { /* Verify that only space and/or a single line comment is left. */
prec -= 3; 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) { /* The time unit must be greater than or equal to the precision. */
prec -= 6; if (unit < prec) {
VLerror(yylloc, "error: `timescale unit must not be less than "
} else if (strncmp("ns", cp, ctmp-cp) == 0) { "the precision.");
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");
return; return;
} }
@ -1053,47 +1227,149 @@ int yywrap()
*/ */
static void line_directive() static void line_directive()
{ {
char*qt1 = strchr(yytext, '"'); char *cpr;
assert(qt1); /* Skip any leading space. */
qt1 += 1; 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, '"'); /* Find the starting " and skip it. */
assert(qt2); 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]; /* Find the last ". */
strncpy(buf, qt1, qt2-qt1); char*fn_end = strrchr(fn_start, '"');
buf[qt2-qt1] = 0; 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); yylloc.text = set_file_name(buf);
yylloc.first_line = lineno;
qt2 += 1;
yylloc.first_line = strtoul(qt2,0,0);
} }
/*
* 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() static void line_directive2()
{ {
assert(strncmp(yytext,"`line",5) == 0); char *cpr;
char*cp = yytext + strlen("`line"); /* Skip any leading space. */
cp += strspn(cp, " "); char *cp = strchr(yytext, '`');
yylloc.first_line = strtoul(cp,&cp,10); /* 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, " "); /* Skip the space between the line number and the file name. */
if (*cp == 0) return; cpr += strspn(cp, " \t");
if (cp == cpr) {
VLerror(yylloc, "Invalid `line directive (missing space after "
"line number).");
return;
}
cp = cpr;
char*qt1 = strchr(yytext, '"'); /* Find the starting " and skip it. */
assert(qt1); char*fn_start = strchr(cp, '"');
qt1 += 1; if (cp != fn_start) {
VLerror(yylloc, "Invalid `line directive (file name start).");
return;
}
fn_start += 1;
char*qt2 = strchr(qt1, '"'); /* Find the last ". */
assert(qt2); 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]; /* Skip the space after the file name. */
strncpy(buf, qt1, qt2-qt1); cp = fn_end + 1;
buf[qt2-qt1] = 0; 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.text = set_file_name(buf);
yylloc.first_line = lineno;
} }
extern FILE*vl_input; extern FILE*vl_input;
@ -1105,3 +1381,17 @@ void reset_lexor()
/* Announce the first file name. */ /* Announce the first file name. */
yylloc.text = set_file_name(strdupnew(vl_file.c_str())); 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
}

View File

@ -11,165 +11,183 @@
%} %}
struct lexor_keyword { const char*name; int mask; int tokenType; }; struct lexor_keyword { const char*name; int mask; int tokenType; };
%% %%
abs, GN_KEYWORDS_VAMS_2_3, K_abs abs, GN_KEYWORDS_VAMS_2_3, K_abs
abstol, GN_KEYWORDS_VAMS_2_3, K_abstol abstol, GN_KEYWORDS_VAMS_2_3, K_abstol
access, GN_KEYWORDS_VAMS_2_3, K_access access, GN_KEYWORDS_VAMS_2_3, K_access
acos, GN_KEYWORDS_VAMS_2_3, K_acos acos, GN_KEYWORDS_VAMS_2_3, K_acos
acosh, GN_KEYWORDS_VAMS_2_3, K_acosh acosh, GN_KEYWORDS_VAMS_2_3, K_acosh
always, GN_KEYWORDS_1364_1995, K_always always, GN_KEYWORDS_1364_1995, K_always
always_comb, GN_KEYWORDS_1800_2005, K_always_comb always_comb, GN_KEYWORDS_1800_2005, K_always_comb
always_ff, GN_KEYWORDS_1800_2005, K_always_ff always_ff, GN_KEYWORDS_1800_2005, K_always_ff
always_latch, GN_KEYWORDS_1800_2005, K_always_latch always_latch, GN_KEYWORDS_1800_2005, K_always_latch
analog, GN_KEYWORDS_VAMS_2_3, K_analog analog, GN_KEYWORDS_VAMS_2_3, K_analog
and, GN_KEYWORDS_1364_1995, K_and and, GN_KEYWORDS_1364_1995, K_and
asin, GN_KEYWORDS_VAMS_2_3, K_asin asin, GN_KEYWORDS_VAMS_2_3, K_asin
asinh, GN_KEYWORDS_VAMS_2_3, K_asinh asinh, GN_KEYWORDS_VAMS_2_3, K_asinh
assert, GN_KEYWORDS_1800_2005, K_assert assert, GN_KEYWORDS_1800_2005, K_assert
assign, GN_KEYWORDS_1364_1995, K_assign assign, GN_KEYWORDS_1364_1995, K_assign
atan, GN_KEYWORDS_VAMS_2_3, K_atan atan, GN_KEYWORDS_VAMS_2_3, K_atan
atan2, GN_KEYWORDS_VAMS_2_3, K_atan2 atan2, GN_KEYWORDS_VAMS_2_3, K_atan2
atanh, GN_KEYWORDS_VAMS_2_3, K_atanh atanh, GN_KEYWORDS_VAMS_2_3, K_atanh
automatic, GN_KEYWORDS_1364_2001, K_automatic automatic, GN_KEYWORDS_1364_2001, K_automatic
begin, GN_KEYWORDS_1364_1995, K_begin begin, GN_KEYWORDS_1364_1995, K_begin
bool, GN_KEYWORDS_ICARUS, K_bool bool, GN_KEYWORDS_ICARUS, K_bool
buf, GN_KEYWORDS_1364_1995, K_buf buf, GN_KEYWORDS_1364_1995, K_buf
bufif0, GN_KEYWORDS_1364_1995, K_bufif0 bufif0, GN_KEYWORDS_1364_1995, K_bufif0
bufif1, GN_KEYWORDS_1364_1995, K_bufif1 bufif1, GN_KEYWORDS_1364_1995, K_bufif1
case, GN_KEYWORDS_1364_1995, K_case case, GN_KEYWORDS_1364_1995, K_case
casex, GN_KEYWORDS_1364_1995, K_casex casex, GN_KEYWORDS_1364_1995, K_casex
casez, GN_KEYWORDS_1364_1995, K_casez casez, GN_KEYWORDS_1364_1995, K_casez
ceil, GN_KEYWORDS_VAMS_2_3, K_ceil ceil, GN_KEYWORDS_VAMS_2_3, K_ceil
cmos, GN_KEYWORDS_1364_1995, K_cmos cell, GN_KEYWORDS_1364_2001_CONFIG, K_cell
continuous, GN_KEYWORDS_VAMS_2_3, K_continuous cmos, GN_KEYWORDS_1364_1995, K_cmos
cos, GN_KEYWORDS_VAMS_2_3, K_cos config, GN_KEYWORDS_1364_2001_CONFIG, K_config
cosh, GN_KEYWORDS_VAMS_2_3, K_cosh continuous, GN_KEYWORDS_VAMS_2_3, K_continuous
ddt_nature, GN_KEYWORDS_VAMS_2_3, K_ddt_nature cos, GN_KEYWORDS_VAMS_2_3, K_cos
deassign, GN_KEYWORDS_1364_1995, K_deassign cosh, GN_KEYWORDS_VAMS_2_3, K_cosh
default, GN_KEYWORDS_1364_1995, K_default ddt_nature, GN_KEYWORDS_VAMS_2_3, K_ddt_nature
defparam, GN_KEYWORDS_1364_1995, K_defparam deassign, GN_KEYWORDS_1364_1995, K_deassign
disable, GN_KEYWORDS_1364_1995, K_disable default, GN_KEYWORDS_1364_1995, K_default
discipline, GN_KEYWORDS_VAMS_2_3, K_discipline defparam, GN_KEYWORDS_1364_1995, K_defparam
discrete, GN_KEYWORDS_VAMS_2_3, K_discrete design, GN_KEYWORDS_1364_2001_CONFIG, K_design
domain, GN_KEYWORDS_VAMS_2_3, K_domain disable, GN_KEYWORDS_1364_1995, K_disable
edge, GN_KEYWORDS_1364_1995, K_edge discipline, GN_KEYWORDS_VAMS_2_3, K_discipline
else, GN_KEYWORDS_1364_1995, K_else discrete, GN_KEYWORDS_VAMS_2_3, K_discrete
end, GN_KEYWORDS_1364_1995, K_end domain, GN_KEYWORDS_VAMS_2_3, K_domain
endcase, GN_KEYWORDS_1364_1995, K_endcase edge, GN_KEYWORDS_1364_1995, K_edge
enddiscipline, GN_KEYWORDS_VAMS_2_3, K_enddiscipline else, GN_KEYWORDS_1364_1995, K_else
endfunction, GN_KEYWORDS_1364_1995, K_endfunction end, GN_KEYWORDS_1364_1995, K_end
endgenerate, GN_KEYWORDS_1364_1995, K_endgenerate endcase, GN_KEYWORDS_1364_1995, K_endcase
endmodule, GN_KEYWORDS_1364_1995, K_endmodule endconfig, GN_KEYWORDS_1364_2001_CONFIG, K_endconfig
endnature, GN_KEYWORDS_VAMS_2_3, K_endnature enddiscipline, GN_KEYWORDS_VAMS_2_3, K_enddiscipline
endprimitive, GN_KEYWORDS_1364_1995, K_endprimitive endfunction, GN_KEYWORDS_1364_1995, K_endfunction
endspecify, GN_KEYWORDS_1364_1995, K_endspecify endgenerate, GN_KEYWORDS_1364_2001, K_endgenerate
endtable, GN_KEYWORDS_1364_1995, K_endtable endmodule, GN_KEYWORDS_1364_1995, K_endmodule
endtask, GN_KEYWORDS_1364_1995, K_endtask endnature, GN_KEYWORDS_VAMS_2_3, K_endnature
event, GN_KEYWORDS_1364_1995, K_event endprimitive, GN_KEYWORDS_1364_1995, K_endprimitive
exclude, GN_KEYWORDS_VAMS_2_3, K_exclude endspecify, GN_KEYWORDS_1364_1995, K_endspecify
exp, GN_KEYWORDS_VAMS_2_3, K_exp endtable, GN_KEYWORDS_1364_1995, K_endtable
floor, GN_KEYWORDS_VAMS_2_3, K_floor endtask, GN_KEYWORDS_1364_1995, K_endtask
flow, GN_KEYWORDS_VAMS_2_3, K_flow event, GN_KEYWORDS_1364_1995, K_event
for, GN_KEYWORDS_1364_1995, K_for exclude, GN_KEYWORDS_VAMS_2_3, K_exclude
force, GN_KEYWORDS_1364_1995, K_force exp, GN_KEYWORDS_VAMS_2_3, K_exp
forever, GN_KEYWORDS_1364_1995, K_forever floor, GN_KEYWORDS_VAMS_2_3, K_floor
fork, GN_KEYWORDS_1364_1995, K_fork flow, GN_KEYWORDS_VAMS_2_3, K_flow
from, GN_KEYWORDS_VAMS_2_3, K_from for, GN_KEYWORDS_1364_1995, K_for
function, GN_KEYWORDS_1364_1995, K_function force, GN_KEYWORDS_1364_1995, K_force
generate, GN_KEYWORDS_1364_2001, K_generate forever, GN_KEYWORDS_1364_1995, K_forever
genvar, GN_KEYWORDS_1364_2001, K_genvar fork, GN_KEYWORDS_1364_1995, K_fork
ground, GN_KEYWORDS_VAMS_2_3, K_ground from, GN_KEYWORDS_VAMS_2_3, K_from
highz0, GN_KEYWORDS_1364_1995, K_highz0 function, GN_KEYWORDS_1364_1995, K_function
highz1, GN_KEYWORDS_1364_1995, K_highz1 generate, GN_KEYWORDS_1364_2001, K_generate
hypot, GN_KEYWORDS_VAMS_2_3, K_hypot genvar, GN_KEYWORDS_1364_2001, K_genvar
idt_nature, GN_KEYWORDS_VAMS_2_3, K_idt_nature ground, GN_KEYWORDS_VAMS_2_3, K_ground
if, GN_KEYWORDS_1364_1995, K_if highz0, GN_KEYWORDS_1364_1995, K_highz0
ifnone, GN_KEYWORDS_1364_1995, K_ifnone highz1, GN_KEYWORDS_1364_1995, K_highz1
inf, GN_KEYWORDS_VAMS_2_3, K_inf hypot, GN_KEYWORDS_VAMS_2_3, K_hypot
initial, GN_KEYWORDS_1364_1995, K_initial idt_nature, GN_KEYWORDS_VAMS_2_3, K_idt_nature
inout, GN_KEYWORDS_1364_1995, K_inout if, GN_KEYWORDS_1364_1995, K_if
input, GN_KEYWORDS_1364_1995, K_input ifnone, GN_KEYWORDS_1364_1995, K_ifnone
integer, GN_KEYWORDS_1364_1995, K_integer incdir, GN_KEYWORDS_1364_2001_CONFIG, K_incdir
join, GN_KEYWORDS_1364_1995, K_join include, GN_KEYWORDS_1364_2001_CONFIG, K_include
large, GN_KEYWORDS_1364_1995, K_large inf, GN_KEYWORDS_VAMS_2_3, K_inf
ln, GN_KEYWORDS_VAMS_2_3, K_ln initial, GN_KEYWORDS_1364_1995, K_initial
localparam, GN_KEYWORDS_1364_2001, K_localparam inout, GN_KEYWORDS_1364_1995, K_inout
log, GN_KEYWORDS_VAMS_2_3, K_log input, GN_KEYWORDS_1364_1995, K_input
logic, GN_KEYWORDS_ICARUS, K_logic instance, GN_KEYWORDS_1364_2001_CONFIG, K_instance
macromodule, GN_KEYWORDS_1364_1995, K_macromodule integer, GN_KEYWORDS_1364_1995, K_integer
max, GN_KEYWORDS_VAMS_2_3, K_max join, GN_KEYWORDS_1364_1995, K_join
medium, GN_KEYWORDS_1364_1995, K_medium large, GN_KEYWORDS_1364_1995, K_large
min, GN_KEYWORDS_VAMS_2_3, K_min liblist, GN_KEYWORDS_1364_2001_CONFIG, K_liblist
module, GN_KEYWORDS_1364_1995, K_module library, GN_KEYWORDS_1364_2001_CONFIG, K_library
nand, GN_KEYWORDS_1364_1995, K_nand ln, GN_KEYWORDS_VAMS_2_3, K_ln
nature, GN_KEYWORDS_VAMS_2_3, K_nature localparam, GN_KEYWORDS_1364_2001, K_localparam
negedge, GN_KEYWORDS_1364_1995, K_negedge log, GN_KEYWORDS_VAMS_2_3, K_log
nmos, GN_KEYWORDS_1364_1995, K_nmos logic, GN_KEYWORDS_ICARUS, K_logic
nor, GN_KEYWORDS_1364_1995, K_nor macromodule, GN_KEYWORDS_1364_1995, K_macromodule
not, GN_KEYWORDS_1364_1995, K_not max, GN_KEYWORDS_VAMS_2_3, K_max
notif0, GN_KEYWORDS_1364_1995, K_notif0 medium, GN_KEYWORDS_1364_1995, K_medium
notif1, GN_KEYWORDS_1364_1995, K_notif1 min, GN_KEYWORDS_VAMS_2_3, K_min
or, GN_KEYWORDS_1364_1995, K_or module, GN_KEYWORDS_1364_1995, K_module
output, GN_KEYWORDS_1364_1995, K_output nand, GN_KEYWORDS_1364_1995, K_nand
parameter, GN_KEYWORDS_1364_1995, K_parameter nature, GN_KEYWORDS_VAMS_2_3, K_nature
pmos, GN_KEYWORDS_1364_1995, K_pmos negedge, GN_KEYWORDS_1364_1995, K_negedge
posedge, GN_KEYWORDS_1364_1995, K_posedge nmos, GN_KEYWORDS_1364_1995, K_nmos
potential, GN_KEYWORDS_VAMS_2_3, K_potential nor, GN_KEYWORDS_1364_1995, K_nor
pow, GN_KEYWORDS_VAMS_2_3, K_pow noshowcancelled, GN_KEYWORDS_1364_2001, K_noshowcancelled
primitive, GN_KEYWORDS_1364_1995, K_primitive not, GN_KEYWORDS_1364_1995, K_not
pull0, GN_KEYWORDS_1364_1995, K_pull0 notif0, GN_KEYWORDS_1364_1995, K_notif0
pull1, GN_KEYWORDS_1364_1995, K_pull1 notif1, GN_KEYWORDS_1364_1995, K_notif1
pulldown, GN_KEYWORDS_1364_1995, K_pulldown or, GN_KEYWORDS_1364_1995, K_or
pullup, GN_KEYWORDS_1364_1995, K_pullup output, GN_KEYWORDS_1364_1995, K_output
rcmos, GN_KEYWORDS_1364_1995, K_rcmos parameter, GN_KEYWORDS_1364_1995, K_parameter
real, GN_KEYWORDS_1364_1995, K_real pmos, GN_KEYWORDS_1364_1995, K_pmos
realtime, GN_KEYWORDS_1364_1995, K_realtime posedge, GN_KEYWORDS_1364_1995, K_posedge
reg, GN_KEYWORDS_1364_1995, K_reg potential, GN_KEYWORDS_VAMS_2_3, K_potential
release, GN_KEYWORDS_1364_1995, K_release pow, GN_KEYWORDS_VAMS_2_3, K_pow
repeat, GN_KEYWORDS_1364_1995, K_repeat primitive, GN_KEYWORDS_1364_1995, K_primitive
rnmos, GN_KEYWORDS_1364_1995, K_rnmos pull0, GN_KEYWORDS_1364_1995, K_pull0
rpmos, GN_KEYWORDS_1364_1995, K_rpmos pull1, GN_KEYWORDS_1364_1995, K_pull1
rtran, GN_KEYWORDS_1364_1995, K_rtran pulldown, GN_KEYWORDS_1364_1995, K_pulldown
rtranif0, GN_KEYWORDS_1364_1995, K_rtranif0 pullup, GN_KEYWORDS_1364_1995, K_pullup
rtranif1, GN_KEYWORDS_1364_1995, K_rtranif1 pulsestyle_onevent, GN_KEYWORDS_1364_2001, K_pulsestyle_onevent
scalared, GN_KEYWORDS_1364_1995, K_scalared pulsestyle_ondetect, GN_KEYWORDS_1364_2001, K_pulsestyle_ondetect
signed, GN_KEYWORDS_1364_2001, K_signed rcmos, GN_KEYWORDS_1364_1995, K_rcmos
sin, GN_KEYWORDS_VAMS_2_3, K_sin real, GN_KEYWORDS_1364_1995, K_real
sinh, GN_KEYWORDS_VAMS_2_3, K_sinh realtime, GN_KEYWORDS_1364_1995, K_realtime
small, GN_KEYWORDS_1364_1995, K_small reg, GN_KEYWORDS_1364_1995, K_reg
specify, GN_KEYWORDS_1364_1995, K_specify release, GN_KEYWORDS_1364_1995, K_release
specparam, GN_KEYWORDS_1364_1995, K_specparam repeat, GN_KEYWORDS_1364_1995, K_repeat
sqrt, GN_KEYWORDS_VAMS_2_3, K_sqrt rnmos, GN_KEYWORDS_1364_1995, K_rnmos
string, GN_KEYWORDS_VAMS_2_3, K_string rpmos, GN_KEYWORDS_1364_1995, K_rpmos
strong0, GN_KEYWORDS_1364_1995, K_strong0 rtran, GN_KEYWORDS_1364_1995, K_rtran
strong1, GN_KEYWORDS_1364_1995, K_strong1 rtranif0, GN_KEYWORDS_1364_1995, K_rtranif0
supply0, GN_KEYWORDS_1364_1995, K_supply0 rtranif1, GN_KEYWORDS_1364_1995, K_rtranif1
supply1, GN_KEYWORDS_1364_1995, K_supply1 scalared, GN_KEYWORDS_1364_1995, K_scalared
table, GN_KEYWORDS_1364_1995, K_table showcancelled, GN_KEYWORDS_1364_2001, K_showcancelled
tan, GN_KEYWORDS_VAMS_2_3, K_tan signed, GN_KEYWORDS_1364_2001, K_signed
tanh, GN_KEYWORDS_VAMS_2_3, K_tanh sin, GN_KEYWORDS_VAMS_2_3, K_sin
task, GN_KEYWORDS_1364_1995, K_task sinh, GN_KEYWORDS_VAMS_2_3, K_sinh
time, GN_KEYWORDS_1364_1995, K_time small, GN_KEYWORDS_1364_1995, K_small
tran, GN_KEYWORDS_1364_1995, K_tran specify, GN_KEYWORDS_1364_1995, K_specify
tranif0, GN_KEYWORDS_1364_1995, K_tranif0 specparam, GN_KEYWORDS_1364_1995, K_specparam
tranif1, GN_KEYWORDS_1364_1995, K_tranif1 sqrt, GN_KEYWORDS_VAMS_2_3, K_sqrt
tri, GN_KEYWORDS_1364_1995, K_tri string, GN_KEYWORDS_VAMS_2_3, K_string
tri0, GN_KEYWORDS_1364_1995, K_tri0 strong0, GN_KEYWORDS_1364_1995, K_strong0
tri1, GN_KEYWORDS_1364_1995, K_tri1 strong1, GN_KEYWORDS_1364_1995, K_strong1
triand, GN_KEYWORDS_1364_1995, K_triand supply0, GN_KEYWORDS_1364_1995, K_supply0
trior, GN_KEYWORDS_1364_1995, K_trior supply1, GN_KEYWORDS_1364_1995, K_supply1
trireg, GN_KEYWORDS_1364_1995, K_trireg table, GN_KEYWORDS_1364_1995, K_table
units, GN_KEYWORDS_VAMS_2_3, K_units tan, GN_KEYWORDS_VAMS_2_3, K_tan
vectored, GN_KEYWORDS_1364_1995, K_vectored tanh, GN_KEYWORDS_VAMS_2_3, K_tanh
wait, GN_KEYWORDS_1364_1995, K_wait task, GN_KEYWORDS_1364_1995, K_task
wand, GN_KEYWORDS_1364_1995, K_wand time, GN_KEYWORDS_1364_1995, K_time
weak0, GN_KEYWORDS_1364_1995, K_weak0 tran, GN_KEYWORDS_1364_1995, K_tran
weak1, GN_KEYWORDS_1364_1995, K_weak1 tranif0, GN_KEYWORDS_1364_1995, K_tranif0
while, GN_KEYWORDS_1364_1995, K_while tranif1, GN_KEYWORDS_1364_1995, K_tranif1
wire, GN_KEYWORDS_1364_1995, K_wire tri, GN_KEYWORDS_1364_1995, K_tri
wone, GN_KEYWORDS_1364_1995, K_wone tri0, GN_KEYWORDS_1364_1995, K_tri0
wor, GN_KEYWORDS_1364_1995, K_wor tri1, GN_KEYWORDS_1364_1995, K_tri1
xnor, GN_KEYWORDS_1364_1995, K_xnor triand, GN_KEYWORDS_1364_1995, K_triand
xor, GN_KEYWORDS_1364_1995, K_xor trior, GN_KEYWORDS_1364_1995, K_trior
trireg, GN_KEYWORDS_1364_1995, K_trireg
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
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
# 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
xnor, GN_KEYWORDS_1364_1995, K_xnor
xor, GN_KEYWORDS_1364_1995, K_xor
%% %%
int lexor_keyword_mask = 0; int lexor_keyword_mask = 0;

View File

@ -59,11 +59,13 @@ all: dep libveriuser.a $(ALL32)
check: all check: all
Makefile: $(srcdir)/Makefile.in ../config.status Makefile: $(srcdir)/Makefile.in
../config.status --file=$@ cd ..; ./config.status --file=libveriuser/$@
config.h: $(srcdir)/config.h.in ../config.status stamp-config-h: $(srcdir)/config.h.in ../config.status
../config.status --header=$@ @rm -f $@
cd ..; ./config.status --header=libveriuser/config.h
config.h: stamp-config-h
libveriuser.o: $O libveriuser.o: $O
$(LD) -r -o $@ $O $(LD) -r -o $@ $O
@ -76,16 +78,17 @@ libveriuser.a: libveriuser.o
dep: dep:
mkdir dep mkdir dep
%.o: %.c %.o: %.c config.h
$(CC) $(CPPFLAGS) $(CFLAGS) -MD -c $< -o $*.o $(CC) $(CPPFLAGS) $(CFLAGS) -MD -c $< -o $*.o
mv $*.d dep mv $*.d dep
clean: clean:
rm -rf *.o dep libveriuser.a libveriuser.o bin32 rm -rf *.o dep libveriuser.a libveriuser.o
distclean: clean distclean: clean
rm -f Makefile config.log config.h rm -f Makefile config.log
rm -f config.h stamp-config-h
install:: all installdirs $(libdir)/libveriuser$(suffix).a $(INSTALL32) install:: all installdirs $(libdir)/libveriuser$(suffix).a $(INSTALL32)

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2003 Stephen Williams (steve@icarus.com) * Copyright (c) 2003-2009 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * 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 * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#ifdef HAVE_CVS_IDENT
#ident "$Id: a_configure.c,v 1.4 2003/12/17 15:45:07 steve Exp $"
#endif
#include <acc_user.h> #include <acc_user.h>
#include <vpi_user.h> #include <vpi_user.h>
@ -70,41 +67,14 @@ int acc_configure(PLI_INT32 config_param, const char*value)
if (pli_trace) { if (pli_trace) {
fprintf(pli_trace, "acc_configure(config=%d, %s)\n", fprintf(pli_trace, "acc_configure(config=%d, %s)\n",
config_param, value); (int)config_param, value);
} }
vpi_printf("XXXX acc_configure(%d, %s)\n", config_param, value); vpi_printf("XXXX acc_configure(%d, %s)\n", (int)config_param,
value);
rc = 0; rc = 0;
break; break;
} }
return rc; return rc;
} }
/*
* $Log: a_configure.c,v $
* Revision 1.4 2003/12/17 15:45:07 steve
* Add acc_set_scope function.
*
* Revision 1.3 2003/06/17 16:55:07 steve
* 1) setlinebuf() for vpi_trace
* 2) Addes error checks for trace file opens
* 3) removes now extraneous flushes
* 4) fixes acc_next() bug
*
* Revision 1.2 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.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.
*
*/

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2003 Stephen Williams (steve@icarus.com) * Copyright (c) 2003-2009 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * 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 * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#ifdef HAVE_CVS_IDENT
#ident "$Id: a_fetch_param.c,v 1.4 2003/06/17 16:55:07 steve Exp $"
#endif
#include <assert.h> #include <assert.h>
#include <vpi_user.h> #include <vpi_user.h>
@ -43,31 +40,8 @@ double acc_fetch_paramval(handle object)
default: default:
vpi_printf("XXXX: parameter %s has type %d\n", vpi_printf("XXXX: parameter %s has type %d\n",
vpi_get_str(vpiName, object), val.format); vpi_get_str(vpiName, object), (int)val.format);
assert(0); assert(0);
return 0.0; return 0.0;
} }
} }
/*
* $Log: a_fetch_param.c,v $
* Revision 1.4 2003/06/17 16:55:07 steve
* 1) setlinebuf() for vpi_trace
* 2) Addes error checks for trace file opens
* 3) removes now extraneous flushes
* 4) fixes acc_next() bug
*
* Revision 1.3 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.2 2003/03/14 04:59:54 steve
* Better message when asserting funky value type.
*
* Revision 1.1 2003/03/13 04:35:09 steve
* Add a bunch of new acc_ and tf_ functions.
*
*/

View File

@ -1,5 +1,5 @@
/* vi:sw=6 /*
* Copyright (c) 2002,2003 Michael Ruff (mruff at chiaro.com) * Copyright (c) 2002-2009 Michael Ruff (mruff at chiaro.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * 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 * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#ifdef HAVE_CVS_IDENT
#ident "$Id: a_fetch_tfarg.c,v 1.10 2004/10/04 01:10:56 steve Exp $"
#endif
#include <vpi_user.h> #include <vpi_user.h>
#include <acc_user.h> #include <acc_user.h>
@ -50,7 +47,7 @@ double acc_fetch_itfarg(PLI_INT32 n, handle obj)
if (pli_trace) { if (pli_trace) {
fprintf(pli_trace, "%s: acc_fetch_itfarg(%d, %p) --> %f\n", fprintf(pli_trace, "%s: acc_fetch_itfarg(%d, %p) --> %f\n",
vpi_get_str(vpiName, obj), n, obj, rtn); vpi_get_str(vpiName, obj), (int)n, obj, rtn);
} }
return rtn; return rtn;
@ -85,7 +82,7 @@ PLI_INT32 acc_fetch_itfarg_int(PLI_INT32 n, handle obj)
if (pli_trace) { if (pli_trace) {
fprintf(pli_trace, "%s: acc_fetch_itfarg_int(%d, %p) --> %d\n", fprintf(pli_trace, "%s: acc_fetch_itfarg_int(%d, %p) --> %d\n",
vpi_get_str(vpiName, obj), n, obj, rtn); vpi_get_str(vpiName, obj), (int)n, obj, rtn);
} }
return rtn; return rtn;
@ -121,7 +118,7 @@ char *acc_fetch_itfarg_str(PLI_INT32 n, handle obj)
if (pli_trace) { if (pli_trace) {
fprintf(pli_trace, "%s: acc_fetch_itfarg_str(%d, %p) --> \"%s\"\n", fprintf(pli_trace, "%s: acc_fetch_itfarg_str(%d, %p) --> \"%s\"\n",
vpi_get_str(vpiName, obj), vpi_get_str(vpiName, obj),
n, obj, rtn? rtn : ""); (int)n, obj, rtn? rtn : "");
} }
return rtn; return rtn;
@ -131,45 +128,3 @@ char *acc_fetch_tfarg_str(PLI_INT32 n)
{ {
return acc_fetch_itfarg_str(n, vpi_handle(vpiSysTfCall,0)); return acc_fetch_itfarg_str(n, vpi_handle(vpiSysTfCall,0));
} }
/*
* $Log: a_fetch_tfarg.c,v $
* Revision 1.10 2004/10/04 01:10:56 steve
* Clean up spurious trailing white space.
*
* Revision 1.9 2004/02/18 02:51:59 steve
* Fix type mismatches of various VPI functions.
*
* Revision 1.8 2003/06/14 01:16:17 steve
* ihand is system task, not scope.
*
* Revision 1.7 2003/06/13 19:23:42 steve
* Add a bunch more PLI1 routines.
*
* Revision 1.6 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.5 2003/03/14 04:58:50 steve
* Free the iterator when Im done.
*
* Revision 1.4 2003/03/13 04:35:09 steve
* Add a bunch of new acc_ and tf_ functions.
*
* Revision 1.3 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.2 2002/08/12 01:35:02 steve
* conditional ident string using autoconfig.
*
* Revision 1.1 2002/06/07 02:58:58 steve
* Add a bunch of acc/tf functions. (mruff)
*
*/

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2003 Stephen Williams (steve@icarus.com) * Copyright (c) 2003-2009 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * 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 * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#ifdef HAVE_CVS_IDENT
#ident "$Id: a_fetch_type.c,v 1.8 2004/10/04 01:10:56 steve Exp $"
#endif
# include <acc_user.h> # include <acc_user.h>
# include <vpi_user.h> # include <vpi_user.h>
@ -62,7 +59,7 @@ PLI_INT32 acc_fetch_type(handle obj)
default: default:
vpi_printf("acc_fetch_type: vpiType %d is what accType?\n", vpi_printf("acc_fetch_type: vpiType %d is what accType?\n",
vpi_get(vpiType, obj)); (int)vpi_get(vpiType, obj));
return accUnknown; return accUnknown;
} }
@ -118,43 +115,3 @@ PLI_INT32 acc_fetch_fulltype(handle obj)
return accUnknown; return accUnknown;
} }
} }
/*
* $Log: a_fetch_type.c,v $
* Revision 1.8 2004/10/04 01:10:56 steve
* Clean up spurious trailing white space.
*
* Revision 1.7 2003/06/04 01:56:20 steve
* 1) Adds configure logic to clean up compiler warnings
* 2) adds acc_compare_handle, acc_fetch_range, acc_next_scope and
* 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.6 2003/05/30 04:18:31 steve
* Add acc_next function.
*
* Revision 1.5 2003/05/29 02:35:41 steve
* acc_fetch_type supports module.
*
* Revision 1.4 2003/04/24 18:57:06 steve
* Add acc_fetch_fulltype function.
*
* Revision 1.3 2003/04/12 18:57:14 steve
* More acc_ function stubs.
*
* Revision 1.2 2003/03/13 04:35:09 steve
* Add a bunch of new acc_ and tf_ functions.
*
* 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.
*
*/

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2003 Stephen Williams (steve@icarus.com) * Copyright (c) 2003-2009 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * 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 * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#ifdef HAVE_CVS_IDENT
#ident "$Id: a_fetch_type_str.c,v 1.5 2003/04/12 18:57:14 steve Exp $"
#endif
#include <assert.h> #include <assert.h>
#include <vpi_user.h> #include <vpi_user.h>
@ -41,34 +38,9 @@ char* acc_fetch_type_str(PLI_INT32 type)
return "accConstant"; return "accConstant";
default: default:
vpi_printf("XXXX acc_fetch_type_str(%d);\n", type); vpi_printf("XXXX acc_fetch_type_str(%d);\n", (int)type);
return "acc_fetch_type_str(unknown)"; return "acc_fetch_type_str(unknown)";
} }
return ""; return "";
} }
/*
* $Log: a_fetch_type_str.c,v $
* Revision 1.5 2003/04/12 18:57:14 steve
* More acc_ function stubs.
*
* Revision 1.4 2003/03/13 05:07:46 steve
* Declaration warnings.
*
* Revision 1.3 2003/03/13 04:35:09 steve
* Add a bunch of new acc_ and tf_ functions.
*
* Revision 1.2 2003/02/19 04:37:04 steve
* fullname for accConstant.
*
* 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.
*
*/

View File

@ -1,5 +1,5 @@
/* vi:sw=6 /*
* Copyright (c) 2003 Michael Ruff (mruff at chiaro.com) * Copyright (c) 2003-2009 Michael Ruff (mruff at chiaro.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * 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 * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#ifdef HAVE_CVS_IDENT
#ident "$Id: a_next.c,v 1.4 2006/10/30 22:45:37 steve Exp $"
#endif
#include <stdio.h> #include <stdio.h>
#include <acc_user.h> #include <acc_user.h>
@ -37,7 +34,7 @@ handle acc_next(PLI_INT32 *type, handle scope, handle prev)
PLI_INT32 *ip; PLI_INT32 *ip;
fprintf(pli_trace, "acc_next(%p <", type); fprintf(pli_trace, "acc_next(%p <", type);
for (ip = type; *ip; ip++) { for (ip = type; *ip; ip++) {
fprintf(pli_trace, "%s%d", ip != type ? "," : "", *ip); fprintf(pli_trace, "%s%d", ip != type ? "," : "", (int)*ip);
} }
fprintf(pli_trace, ">, %p", scope); fprintf(pli_trace, ">, %p", scope);
if (scope) if (scope)
@ -91,28 +88,3 @@ handle acc_next_scope(handle scope, handle prev)
PLI_INT32 type[2] = {accScope, 0}; PLI_INT32 type[2] = {accScope, 0};
return acc_next(type, scope, prev); return acc_next(type, scope, prev);
} }
/*
* $Log: a_next.c,v $
* Revision 1.4 2006/10/30 22:45:37 steve
* Updates for Cygwin portability (pr1585922)
*
* Revision 1.3 2003/06/17 16:55:07 steve
* 1) setlinebuf() for vpi_trace
* 2) Addes error checks for trace file opens
* 3) removes now extraneous flushes
* 4) fixes acc_next() bug
*
* Revision 1.2 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.1 2003/05/30 04:18:31 steve
* Add acc_next function.
*
*/

View File

@ -1,5 +1,5 @@
/* vi:sw=6 /*
* Copyright (c) 2002, 2003 Michael Ruff (mruff at chiaro.com) * Copyright (c) 2002-2009 Michael Ruff (mruff at chiaro.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * 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 * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#ifdef HAVE_CVS_IDENT
#ident "$Id: a_object_of_type.c,v 1.6 2004/02/18 02:51:59 steve Exp $"
#endif
#include <assert.h> #include <assert.h>
#include <vpi_user.h> #include <vpi_user.h>
@ -35,7 +32,7 @@ int acc_object_of_type(handle object, PLI_INT32 type)
if (pli_trace) { if (pli_trace) {
fprintf(pli_trace, "acc_object_of_type(%p \"%s\", %d)", fprintf(pli_trace, "acc_object_of_type(%p \"%s\", %d)",
object, vpi_get_str(vpiName, object), type); object, vpi_get_str(vpiName, object), (int)type);
fflush(pli_trace); fflush(pli_trace);
} }
@ -77,7 +74,8 @@ int acc_object_of_type(handle object, PLI_INT32 type)
break; break;
default: default:
vpi_printf("acc_object_of_type: Unknown type %d\n", type); vpi_printf("acc_object_of_type: Unknown type %d\n",
(int)type);
rtn = 0; rtn = 0;
} }
@ -98,36 +96,3 @@ int acc_object_in_typelist(handle object, PLI_INT32*typelist)
return 0; return 0;
} }
/*
* $Log: a_object_of_type.c,v $
* Revision 1.6 2004/02/18 02:51:59 steve
* Fix type mismatches of various VPI functions.
*
* Revision 1.5 2003/06/04 01:56:20 steve
* 1) Adds configure logic to clean up compiler warnings
* 2) adds acc_compare_handle, acc_fetch_range, acc_next_scope and
* 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.4 2003/05/30 04:18:31 steve
* Add acc_next function.
*
* Revision 1.3 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.2 2002/08/12 01:35:02 steve
* conditional ident string using autoconfig.
*
* Revision 1.1 2002/06/07 02:58:58 steve
* Add a bunch of acc/tf functions. (mruff)
*
*/

View File

@ -1,5 +1,5 @@
/* vi:sw=6 /*
* Copyright (c) 2002 Michael Ruff (mruff at chiaro.com) * Copyright (c) 2002-2009 Michael Ruff (mruff at chiaro.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * 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 * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#ifdef HAVE_CVS_IDENT
#ident "$Id: a_set_value.c,v 1.3 2003/05/18 00:16:35 steve Exp $"
#endif
#include <assert.h> #include <assert.h>
#include <acc_user.h> #include <acc_user.h>
@ -45,7 +42,7 @@ int acc_set_value(handle object, p_setval_value value, p_setval_delay delay)
case accPureTransportDelay: flags = vpiPureTransportDelay; break; case accPureTransportDelay: flags = vpiPureTransportDelay; break;
case accForceFlag: flags = vpiForceFlag; break; case accForceFlag: flags = vpiForceFlag; break;
case accReleaseFlag: flags = vpiReleaseFlag; break; case accReleaseFlag: flags = vpiReleaseFlag; break;
default: assert(0); break; default: flags = -1; assert(0); break;
} }
/* map acc_time to vpi_time */ /* map acc_time to vpi_time */
@ -113,19 +110,3 @@ int acc_set_value(handle object, p_setval_value value, p_setval_delay delay)
return 1; return 1;
} }
/*
* $Log: a_set_value.c,v $
* Revision 1.3 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.2 2002/08/12 01:35:02 steve
* conditional ident string using autoconfig.
*
* Revision 1.1 2002/06/07 02:58:59 steve
* Add a bunch of acc/tf functions. (mruff)
*
*/

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2003 Stephen Williams (steve@icarus.com) * Copyright (c) 2003-2009 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * 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 * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#ifdef HAVE_CVS_IDENT
#ident "$Id: a_vcl.c,v 1.7 2004/10/04 01:10:56 steve Exp $"
#endif
#include <vpi_user.h> #include <vpi_user.h>
#include <acc_user.h> #include <acc_user.h>
@ -185,13 +182,13 @@ void acc_vcl_add(handle obj, PLI_INT32(*consumer)(p_vc_record),
if (pli_trace) { if (pli_trace) {
fprintf(pli_trace, "acc_vcl_add(<%s>, ..., %p, %d)\n", fprintf(pli_trace, "acc_vcl_add(<%s>, ..., %p, %d)\n",
vpi_get_str(vpiFullName, obj), data, vcl_flag); vpi_get_str(vpiFullName, obj), data, (int)vcl_flag);
} }
break; break;
default: default:
vpi_printf("XXXX acc_vcl_add(<type=%d>, ..., %d);\n", vpi_printf("XXXX acc_vcl_add(<type=%d>, ..., %d);\n",
vpi_get(vpiType, obj), vcl_flag); (int)vpi_get(vpiType, obj), (int)vcl_flag);
break; break;
} }
@ -202,36 +199,3 @@ void acc_vcl_delete(handle obj, PLI_INT32(*consumer)(p_vc_record),
{ {
vpi_printf("XXXX acc_vcl_delete(...)\n"); vpi_printf("XXXX acc_vcl_delete(...)\n");
} }
/*
* $Log: a_vcl.c,v $
* Revision 1.7 2004/10/04 01:10:56 steve
* Clean up spurious trailing white space.
*
* Revision 1.6 2003/06/17 16:55:07 steve
* 1) setlinebuf() for vpi_trace
* 2) Addes error checks for trace file opens
* 3) removes now extraneous flushes
* 4) fixes acc_next() bug
*
* Revision 1.5 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.4 2003/04/30 01:09:29 steve
* Conditionally include malloc.h
*
* Revision 1.3 2003/04/24 02:02:37 steve
* Clean up some simple warnings.
*
* Revision 1.2 2003/04/20 02:48:39 steve
* Support value change callbacks.
*
* Revision 1.1 2003/04/12 18:57:14 steve
* More acc_ function stubs.
*
*/

View File

@ -43,7 +43,7 @@ int tf_isetdelay(PLI_INT32 delay, void*ss)
if (pli_trace) { if (pli_trace) {
fprintf(pli_trace, "%s: tf_isetdelay(%d, ...)" fprintf(pli_trace, "%s: tf_isetdelay(%d, ...)"
" <unit=%d, prec=%d>;\n", " <unit=%d, prec=%d>;\n",
vpi_get_str(vpiName, sys), delay, unit, prec); vpi_get_str(vpiName, sys), (int)delay, unit, prec);
} }

View File

@ -1,5 +1,5 @@
/* vi:sw=6 /*
* Copyright (c) 2002,2003 Michael Ruff (mruff at chiaro.com) * Copyright (c) 2002-2009 Michael Ruff (mruff at chiaro.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * 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 * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#ifdef HAVE_CVS_IDENT
#ident "$Id: getp.c,v 1.7 2004/10/04 01:10:56 steve Exp $"
#endif
# include <assert.h> # include <assert.h>
# include <ctype.h> # include <ctype.h>
@ -53,6 +50,8 @@ PLI_INT32 tf_igetp(PLI_INT32 n, void *obj)
{ {
value.format = vpiStringVal; value.format = vpiStringVal;
vpi_get_value(arg_h, &value); vpi_get_value(arg_h, &value);
/* The following may generate a compilation warning, but this
* functionality is required by some versions of the standard. */
rtn = (int) value.value.str; /* Oh my */ rtn = (int) value.value.str; /* Oh my */
} else { } else {
value.format = vpiIntVal; value.format = vpiIntVal;
@ -65,7 +64,7 @@ PLI_INT32 tf_igetp(PLI_INT32 n, void *obj)
out: out:
if (pli_trace) { if (pli_trace) {
fprintf(pli_trace, "tf_igetp(n=%d, obj=%p) --> %d\n", fprintf(pli_trace, "tf_igetp(n=%d, obj=%p) --> %d\n",
n, obj, rtn); (int)n, obj, rtn);
} }
return rtn; return rtn;
@ -112,7 +111,7 @@ double tf_igetrealp(PLI_INT32 n, void *obj)
out: out:
if (pli_trace) { if (pli_trace) {
fprintf(pli_trace, "tf_igetrealp(n=%d, obj=%p) --> %f\n", fprintf(pli_trace, "tf_igetrealp(n=%d, obj=%p) --> %f\n",
n, obj, rtn); (int)n, obj, rtn);
} }
return rtn; return rtn;
@ -169,7 +168,7 @@ char *tf_istrgetp(PLI_INT32 n, PLI_INT32 fmt, void *obj)
out: out:
if (pli_trace) { if (pli_trace) {
fprintf(pli_trace, "tf_istrgetp(n=%d, fmt=%c, obj=%p) --> \"%s\"\n", fprintf(pli_trace, "tf_istrgetp(n=%d, fmt=%c, obj=%p) --> \"%s\"\n",
n, fmt, obj, rtn); (int)n, (int)fmt, obj, rtn);
} }
return rtn; return rtn;
@ -181,34 +180,3 @@ char *tf_strgetp(PLI_INT32 n, PLI_INT32 fmt)
return rtn; return rtn;
} }
/*
* $Log: getp.c,v $
* Revision 1.7 2004/10/04 01:10:56 steve
* Clean up spurious trailing white space.
*
* Revision 1.6 2003/06/17 16:55:07 steve
* 1) setlinebuf() for vpi_trace
* 2) Addes error checks for trace file opens
* 3) removes now extraneous flushes
* 4) fixes acc_next() bug
*
* Revision 1.5 2003/05/30 04:22:13 steve
* Add tf_strgetp functions.
*
* Revision 1.4 2003/05/29 03:46:21 steve
* Add tf_getp/putp support for integers
* and real valued arguments.
*
* Add tf_mipname function.
*
* Revision 1.3 2003/03/15 05:42:39 steve
* free argument iterators.
*
* Revision 1.2 2002/08/12 01:35:02 steve
* conditional ident string using autoconfig.
*
* Revision 1.1 2002/06/07 02:58:59 steve
* Add a bunch of acc/tf functions. (mruff)
*
*/

View File

@ -1,5 +1,5 @@
/* vi:sw=6 /*
* Copyright (c) 2002,2003 Michael Ruff (mruff at chiaro.com) * Copyright (c) 2002-2009 Michael Ruff (mruff at chiaro.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * 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 * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#ifdef HAVE_CVS_IDENT
#ident "$Id: getsimtime.c,v 1.11 2003/06/21 23:40:15 steve Exp $"
#endif
#include <veriuser.h> #include <veriuser.h>
#include <vpi_user.h> #include <vpi_user.h>
@ -62,9 +59,10 @@ char *tf_strgettime(void)
time.type = vpiSimTime; time.type = vpiSimTime;
vpi_get_time (0, &time); vpi_get_time (0, &time);
if (time.high) if (time.high)
snprintf(buf, sizeof(buf)-1, "%u%08u", time.high, time.low); snprintf(buf, sizeof(buf)-1, "%u%08u", (unsigned int)time.high,
(unsigned int)time.low);
else else
snprintf(buf, sizeof(buf)-1, "%u", time.low); snprintf(buf, sizeof(buf)-1, "%u", (unsigned int)time.low);
return buf; return buf;
} }
@ -140,7 +138,7 @@ PLI_INT32 tf_gettimeprecision(void)
if (pli_trace) if (pli_trace)
fprintf(pli_trace, "tf_gettimeprecision(<%s>) --> %d\n", fprintf(pli_trace, "tf_gettimeprecision(<%s>) --> %d\n",
vpi_get_str(vpiName, sys), rc); vpi_get_str(vpiName, sys), (int)rc);
return rc; return rc;
} }
@ -163,7 +161,7 @@ PLI_INT32 tf_igettimeprecision(void*obj)
if (pli_trace) if (pli_trace)
fprintf(pli_trace, "tf_igettimeprecision(<%s>) --> %d\n", fprintf(pli_trace, "tf_igettimeprecision(<%s>) --> %d\n",
obj? vpi_get_str(vpiName, obj) : ".", rc); obj? vpi_get_str(vpiName, obj) : ".", (int)rc);
return rc; return rc;
} }
@ -179,47 +177,3 @@ PLI_INT32 tf_igettimeunit(void*obj)
{ {
return vpi_get(!obj ? vpiTimePrecision : vpiTimeUnit, (vpiHandle)obj); return vpi_get(!obj ? vpiTimePrecision : vpiTimeUnit, (vpiHandle)obj);
} }
/*
* $Log: getsimtime.c,v $
* Revision 1.11 2003/06/21 23:40:15 steve
* gettimeprecision will null argument has specific meaning.
*
* Revision 1.10 2003/06/13 19:23:42 steve
* Add a bunch more PLI1 routines.
*
* Revision 1.9 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.8 2003/05/30 04:01:55 steve
* Add tf_scale_longdelay.
*
* Revision 1.7 2003/05/28 03:14:20 steve
* Missing time related declarations.
*
* Revision 1.6 2003/05/27 16:22:10 steve
* PLI get time units/precision.
*
* Revision 1.5 2003/04/12 18:57:14 steve
* More acc_ function stubs.
*
* Revision 1.4 2003/03/13 04:35:09 steve
* Add a bunch of new acc_ and tf_ functions.
*
* Revision 1.3 2003/03/06 00:27:54 steve
* Fill in required fields when getting time.
*
* Revision 1.2 2002/08/12 01:35:02 steve
* conditional ident string using autoconfig.
*
* Revision 1.1 2002/05/31 18:25:51 steve
* Add tf_getlongtime (mruff)
*
*/

View File

@ -1,5 +1,5 @@
/* vi:sw=6 /*
* Copyright (c) 2002,2003 Michael Ruff (mruff at chiaro.com) * Copyright (c) 2002-2009 Michael Ruff (mruff at chiaro.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * 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 * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#ifdef HAVE_CVS_IDENT
#ident "$Id: putp.c,v 1.7 2004/09/10 23:13:05 steve Exp $"
#endif
# include <assert.h> # include <assert.h>
# include <veriuser.h> # include <veriuser.h>
@ -48,7 +45,7 @@ PLI_INT32 tf_iputp(PLI_INT32 n, PLI_INT32 value, void *obj)
if (pli_trace) { if (pli_trace) {
fprintf(pli_trace, "tf_iputp(<return>, value=%d, func=%s) " fprintf(pli_trace, "tf_iputp(<return>, value=%d, func=%s) "
"--> %d\n", value, vpi_get_str(vpiName, obj), 0); "--> %d\n", (int)value, vpi_get_str(vpiName, obj), 0);
} }
return 0; return 0;
@ -57,7 +54,7 @@ PLI_INT32 tf_iputp(PLI_INT32 n, PLI_INT32 value, void *obj)
if ((n == 0) && (type != vpiSysFuncCall)) { if ((n == 0) && (type != vpiSysFuncCall)) {
if (pli_trace) { if (pli_trace) {
fprintf(pli_trace, "tf_iputp(<ERROR>, value=%d, func=%s) " fprintf(pli_trace, "tf_iputp(<ERROR>, value=%d, func=%s) "
"--> %d\n", value, vpi_get_str(vpiName, obj), 1); "--> %d\n", (int)value, vpi_get_str(vpiName, obj), 1);
} }
return 1; return 1;
@ -82,7 +79,7 @@ PLI_INT32 tf_iputp(PLI_INT32 n, PLI_INT32 value, void *obj)
out: out:
if (pli_trace) { if (pli_trace) {
fprintf(pli_trace, "tf_iputp(n=%d, value=%d, obj=%p) --> %d\n", fprintf(pli_trace, "tf_iputp(n=%d, value=%d, obj=%p) --> %d\n",
n, value, obj, rtn); (int)n, (int)value, obj, rtn);
} }
return rtn; return rtn;
@ -131,7 +128,7 @@ free:
out: out:
if (pli_trace) { if (pli_trace) {
fprintf(pli_trace, "tf_iputrealp(n=%d, value=%f, obj=%p) --> %d\n", fprintf(pli_trace, "tf_iputrealp(n=%d, value=%f, obj=%p) --> %d\n",
n, value, obj, rtn); (int)n, value, obj, rtn);
} }
return rtn; return rtn;
@ -143,33 +140,3 @@ PLI_INT32 tf_putrealp(PLI_INT32 n, double value)
return rtn; return rtn;
} }
/*
* $Log: putp.c,v $
* Revision 1.7 2004/09/10 23:13:05 steve
* Compile cleanup of C code.
*
* Revision 1.6 2003/06/26 03:20:24 steve
* Correct handle of put to function return value.
*
* Revision 1.5 2003/06/17 16:55:08 steve
* 1) setlinebuf() for vpi_trace
* 2) Addes error checks for trace file opens
* 3) removes now extraneous flushes
* 4) fixes acc_next() bug
*
* Revision 1.4 2003/05/29 03:46:21 steve
* Add tf_getp/putp support for integers
* and real valued arguments.
*
* Add tf_mipname function.
*
* Revision 1.3 2003/03/15 05:42:39 steve
* free argument iterators.
*
* Revision 1.2 2002/08/12 01:35:02 steve
* conditional ident string using autoconfig.
*
* Revision 1.1 2002/06/07 16:21:13 steve
* Add tf_putlongp and tf_putp.
*
*/

View File

@ -1,4 +1,4 @@
/* vi:sw=6 /*
* Copyright (c) 2002-2009 Michael Ruff (mruff at chiaro.com) * Copyright (c) 2002-2009 Michael Ruff (mruff at chiaro.com)
* Michael Runyan (mrunyan at chiaro.com) * Michael Runyan (mrunyan at chiaro.com)
* *
@ -322,6 +322,7 @@ static PLI_INT32 callback(p_cb_data data)
reason = reason_reactivate; reason = reason_reactivate;
break; break;
default: default:
reason = -1;
assert(0); assert(0);
} }

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 * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -78,10 +78,11 @@ bool load_module(const char*type)
if (ivlpp_string) { if (ivlpp_string) {
char*cmdline = (char*)malloc(strlen(ivlpp_string) + char*cmdline = (char*)malloc(strlen(ivlpp_string) +
strlen(path) + 2); strlen(path) + 4);
strcpy(cmdline, ivlpp_string); strcpy(cmdline, ivlpp_string);
strcat(cmdline, " "); strcat(cmdline, " \"");
strcat(cmdline, path); strcat(cmdline, path);
strcat(cmdline, "\"");
FILE*file = popen(cmdline, "r"); FILE*file = popen(cmdline, "r");
if (verbose_flag) if (verbose_flag)

81
main.cc
View File

@ -20,7 +20,8 @@ const char COPYRIGHT[] =
*/ */
# include "config.h" # include "config.h"
# include "version.h" # include "version_base.h"
# include "version_tag.h"
const char NOTICE[] = const char NOTICE[] =
" This program is free software; you can redistribute it and/or modify\n" " This program is free software; you can redistribute it and/or modify\n"
@ -77,7 +78,7 @@ extern "C" const char*optarg;
/* Count errors detected in flag processing. */ /* Count errors detected in flag processing. */
unsigned flag_errors = 0; unsigned flag_errors = 0;
const char*basedir = "."; const char*basedir = strdup(".");
/* /*
* These are the language support control flags. These support which * These are the language support control flags. These support which
@ -115,6 +116,9 @@ bool warn_implicit = false;
bool warn_timescale = false; bool warn_timescale = false;
bool warn_portbinding = false; bool warn_portbinding = false;
bool warn_inf_loop = false; bool warn_inf_loop = false;
bool warn_ob_select = false;
bool warn_sens_entire_vec = false;
bool warn_sens_entire_arr = false;
bool error_implicit = false; bool error_implicit = false;
@ -128,6 +132,13 @@ bool debug_elab_pexpr = false;
bool debug_synth2 = false; bool debug_synth2 = false;
bool debug_optimizer = false; bool debug_optimizer = false;
/*
* Miscellaneous flags.
*/
bool disable_virtual_pins = false;
unsigned long array_size_limit = 16777216; // Minimum required by IEEE-1364?
unsigned recursive_mod_limit = 10;
/* /*
* Verbose messages enabled. * Verbose messages enabled.
*/ */
@ -135,6 +146,9 @@ bool verbose_flag = false;
unsigned integer_width = 32; unsigned integer_width = 32;
int def_ts_units = 0;
int def_ts_prec = 0;
/* /*
* Keep a heap of identifier strings that I encounter. This is a more * Keep a heap of identifier strings that I encounter. This is a more
* efficient way to allocate those strings. * efficient way to allocate those strings.
@ -214,6 +228,9 @@ static void process_generation_flag(const char*gen)
} else if (strcmp(gen,"2001") == 0) { } else if (strcmp(gen,"2001") == 0) {
generation_flag = GN_VER2001; generation_flag = GN_VER2001;
} else if (strcmp(gen,"2001-noconfig") == 0) {
generation_flag = GN_VER2001_NOCONFIG;
} else if (strcmp(gen,"2005") == 0) { } else if (strcmp(gen,"2005") == 0) {
generation_flag = GN_VER2005; generation_flag = GN_VER2005;
@ -267,7 +284,7 @@ static void parm_to_flagmap(const string&flag)
unsigned off = flag.find('='); unsigned off = flag.find('=');
if (off > flag.size()) { if (off > flag.size()) {
key = flag; key = flag;
value = ""; value = strdup("");
} else { } else {
key = flag.substr(0, off); key = flag.substr(0, off);
@ -386,6 +403,7 @@ static void read_iconfig_file(const char*ipath)
} }
if (strcmp(buf, "basedir") == 0) { if (strcmp(buf, "basedir") == 0) {
free((char *)basedir);
basedir = strdup(cp); basedir = strdup(cp);
} else if (strcmp(buf, "debug") == 0) { } else if (strcmp(buf, "debug") == 0) {
@ -459,6 +477,7 @@ static void read_iconfig_file(const char*ipath)
flags["VPI_MODULE_LIST"] = vpi_module_list; flags["VPI_MODULE_LIST"] = vpi_module_list;
} else if (strcmp(buf, "out") == 0) { } else if (strcmp(buf, "out") == 0) {
free((char *)flags["-o"]);
flags["-o"] = strdup(cp); flags["-o"] = strdup(cp);
} else if (strcmp(buf, "sys_func") == 0) { } else if (strcmp(buf, "sys_func") == 0) {
@ -476,12 +495,21 @@ static void read_iconfig_file(const char*ipath)
case 'l': case 'l':
warn_inf_loop = true; warn_inf_loop = true;
break; break;
case 's':
warn_ob_select = true;
break;
case 'p': case 'p':
warn_portbinding = true; warn_portbinding = true;
break; break;
case 't': case 't':
warn_timescale = true; warn_timescale = true;
break; break;
case 'v':
warn_sens_entire_vec = true;
break;
case 'a':
warn_sens_entire_arr = true;
break;
default: default:
break; break;
} }
@ -516,6 +544,7 @@ static void read_iconfig_file(const char*ipath)
} }
} }
fclose(ifile);
} }
extern Design* elaborate(list <perm_string> root); extern Design* elaborate(list <perm_string> root);
@ -542,6 +571,30 @@ inline static void times(struct tms *) { }
inline static double cycles_diff(struct tms *a, struct tms *b) { return 0; } inline static double cycles_diff(struct tms *a, struct tms *b) { return 0; }
#endif // ! defined(HAVE_TIMES) #endif // ! defined(HAVE_TIMES)
static void EOC_cleanup(void)
{
cleanup_sys_func_table();
for (list<const char*>::iterator suf = library_suff.begin() ;
suf != library_suff.end() ; suf ++ ) {
free((char *)*suf);
}
library_suff.clear();
free((char *) basedir);
free(ivlpp_string);
free(depfile_name);
for (map<string, const char*>::iterator flg = flags.begin() ;
flg != flags.end() ; flg ++ ) {
free((char *)flg->second);
}
flags.clear();
lex_strings.cleanup();
filename_strings.cleanup();
}
int main(int argc, char*argv[]) int main(int argc, char*argv[])
{ {
bool help_flag = false; bool help_flag = false;
@ -554,11 +607,11 @@ int main(int argc, char*argv[])
struct tms cycles[5]; struct tms cycles[5];
library_suff.push_back(".v"); library_suff.push_back(strdup(".v"));
vpi_module_list = strdup("system"); vpi_module_list = strdup("system");
flags["VPI_MODULE_LIST"] = vpi_module_list; flags["VPI_MODULE_LIST"] = vpi_module_list;
flags["-o"] = "a.out"; flags["-o"] = strdup("a.out");
min_typ_max_flag = TYP; min_typ_max_flag = TYP;
min_typ_max_warn = 10; min_typ_max_warn = 10;
@ -650,9 +703,10 @@ int main(int argc, char*argv[])
lexor_keyword_mask |= GN_KEYWORDS_1364_1995; lexor_keyword_mask |= GN_KEYWORDS_1364_1995;
break; break;
case GN_VER2001: case GN_VER2001:
lexor_keyword_mask |= GN_KEYWORDS_1364_2001_CONFIG;
case GN_VER2001_NOCONFIG:
lexor_keyword_mask |= GN_KEYWORDS_1364_1995; lexor_keyword_mask |= GN_KEYWORDS_1364_1995;
lexor_keyword_mask |= GN_KEYWORDS_1364_2001; lexor_keyword_mask |= GN_KEYWORDS_1364_2001;
lexor_keyword_mask |= GN_KEYWORDS_1364_2001_CONFIG;
break; break;
case GN_VER2005: case GN_VER2005:
lexor_keyword_mask |= GN_KEYWORDS_1364_1995; lexor_keyword_mask |= GN_KEYWORDS_1364_1995;
@ -680,6 +734,9 @@ int main(int argc, char*argv[])
case GN_VER1995: case GN_VER1995:
cout << "IEEE1364-1995"; cout << "IEEE1364-1995";
break; break;
case GN_VER2001_NOCONFIG:
cout << "IEEE1364-2001-noconfig";
break;
case GN_VER2001: case GN_VER2001:
cout << "IEEE1364-2001"; cout << "IEEE1364-2001";
break; break;
@ -709,7 +766,17 @@ int main(int argc, char*argv[])
cout << endl << "PARSING INPUT" << endl; cout << endl << "PARSING INPUT" << endl;
} }
const char *flag_tmp = flags["DISABLE_VIRTUAL_PINS"];
if (flag_tmp) disable_virtual_pins = strcmp(flag_tmp,"true")==0;
flag_tmp = flags["ARRAY_SIZE_LIMIT"];
if (flag_tmp) array_size_limit = strtoul(flag_tmp,NULL,0);
flag_tmp = flags["RECURSIVE_MOD_LIMIT"];
if (flag_tmp) recursive_mod_limit = strtoul(flag_tmp,NULL,0);
/* Parse the input. Make the pform. */ /* Parse the input. Make the pform. */
pform_set_timescale(def_ts_units, def_ts_prec, 0, 0);
int rc = pform_parse(argv[optind]); int rc = pform_parse(argv[optind]);
if (pf_path) { if (pf_path) {
@ -906,6 +973,8 @@ int main(int argc, char*argv[])
<< endl; << endl;
} }
delete des;
EOC_cleanup();
return 0; return 0;
errors_summary: errors_summary:

View File

@ -1,3 +1,8 @@
Please NOTE:
These directions are slightly outdated and need to be updated.
The plan is to rewrite all this using the latest MinGW at
some time in the not too distant future (CR Aug. 2009)
MINGW PORT OF ICARUS VERILOG MINGW PORT OF ICARUS VERILOG
@ -49,7 +54,7 @@ critical, but these are the versions I use.
Mingw32-5.x <http://www.mingw.org> Mingw32-5.x <http://www.mingw.org>
... including the sub-packages binutils, gcc-core and gcc-g++ ... including the sub-packages binutils, gcc-core and gcc-g++
if you are given the option. if you are given the option.
readline-4.2-20010727.zip <http://mingwrep.sourceforge.net> readline-5.0-1 <http://gnuwin32.sourceforge.net>
bzip2-1.0.3 <http://gnuwin32.sourceforge.net> bzip2-1.0.3 <http://gnuwin32.sourceforge.net>
zlib-1.2.3 <http://gnuwin32.sourceforge.net> zlib-1.2.3 <http://gnuwin32.sourceforge.net>
gperf-3.0.1 <http://gnuwin32.sourceforge.net> gperf-3.0.1 <http://gnuwin32.sourceforge.net>
@ -110,29 +115,6 @@ Finally, as part of installing the mingw32 compilers, remember to add
the mingw/bin directory to your path. You will need that to be able to the mingw/bin directory to your path. You will need that to be able to
find the compilers later. find the compilers later.
* Install Mingw32 Packages
There is a collection of precompiled libraries and add-on packages
that are intended for use with the Mingw32 compiler. These do not come
with simplified Windows installers, but they are pretty easy to
install by hand. Icarus Verilog uses the readline-4.2 package from
that collection.
Since I installed Mingw32 in c:\mingw, I also created a
Mingw-packages directory called c:\mingw-packages. The install, then,
is as easy as this:
<msys shell>
$ cd c:/mingw-packages
$ unzip readline-4.2-20010727.zip
[lots of inflating...]
There is no need to adjust your execution path for this package as we
are only using a library out of here. However, do remember the
directory name, as you will need it later.
Done. On to the next packages.
* Install GnuWin32 Packages * Install GnuWin32 Packages
The GnuWin32 project is a collections of open source programs and The GnuWin32 project is a collections of open source programs and
@ -148,6 +130,7 @@ You will need these gnuwin32 packages to compile Icarus Verilog:
gperf-3.0.1.exe gperf-3.0.1.exe
bison-2.1.exe bison-2.1.exe
flex-2.5.4a.exe flex-2.5.4a.exe
readline-5.0-1.exe
I suggest creating a common directory for holding all your gnuwin32 I suggest creating a common directory for holding all your gnuwin32
packages. I use C:\gnuwin32. The download page at the gnuwin32 site packages. I use C:\gnuwin32. The download page at the gnuwin32 site
@ -218,8 +201,8 @@ without white space.
Now, configure the source to make the makefiles and configuration Now, configure the source to make the makefiles and configuration
details. Run these commands: details. Run these commands:
$ CPPFLAGS="-Ic:/gnuwin32/include -Ic:/mingw-packages/include" $ CPPFLAGS="-Ic:/gnuwin32/include
$ LDFLAGS="-Lc:/gnuwin32/lib -Lc:/mingw-packages/lib" $ LDFLAGS="-Lc:/gnuwin32/lib
$ export CPPFLAGS LDFLAGS $ export CPPFLAGS LDFLAGS
$ ./configure --prefix=c:/iverilog $ ./configure --prefix=c:/iverilog
@ -271,7 +254,8 @@ You may find that you need to put some of the prerequisite DLLs into
the d:\iverilog\bin directory. These include: the d:\iverilog\bin directory. These include:
c:\mingw\bin\mingw10.dll c:\mingw\bin\mingw10.dll
c:\mingw-packages\bin\libreadline.dll c:\gnuwin32\bin\readline.dll
c:\gnuwin32\bin\history.dll
c:\gnuwin32\bin\bzip2.dll c:\gnuwin32\bin\bzip2.dll
c:\gnuwin32\bin\zlib.dll c:\gnuwin32\bin\zlib.dll

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2000-2007 Stephen Williams (steve@icarus.com) * Copyright (c) 2000-2009 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -490,7 +490,7 @@ void NetScope::evaluate_parameter_logic_(Design*des, param_ref_t cur)
void NetScope::evaluate_parameter_real_(Design*des, param_ref_t cur) void NetScope::evaluate_parameter_real_(Design*des, param_ref_t cur)
{ {
NetExpr*expr = (*cur).second.expr; NetExpr*expr = (*cur).second.expr;
assert(expr); if (expr == NULL) return; // This is an invalid parameter so return.
NetECReal*res = 0; NetECReal*res = 0;
eval_expr(expr); eval_expr(expr);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2002-2008 Stephen Williams (steve@icarus.com) * Copyright (c) 2002-2009 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -257,15 +257,13 @@ ivl_variable_type_t NetEBMinMax::expr_type() const
NetEBMult::NetEBMult(char op__, NetExpr*l, NetExpr*r) NetEBMult::NetEBMult(char op__, NetExpr*l, NetExpr*r)
: NetEBinary(op__, l, r) : NetEBinary(op__, l, r)
{ {
if (expr_type() == IVL_VT_REAL) if (expr_type() == IVL_VT_REAL) {
expr_width(1); expr_width(1);
else
expr_width(l->expr_width() + r->expr_width());
if (expr_type() == IVL_VT_REAL)
cast_signed(true); cast_signed(true);
else } else {
expr_width(l->expr_width() + r->expr_width());
cast_signed(l->has_sign() && r->has_sign()); cast_signed(l->has_sign() && r->has_sign());
}
} }
NetEBMult::~NetEBMult() NetEBMult::~NetEBMult()
@ -294,8 +292,8 @@ NetEBPow::NetEBPow(char op__, NetExpr*l, NetExpr*r)
: NetEBinary(op__, l, r) : NetEBinary(op__, l, r)
{ {
assert(op__ == 'p'); assert(op__ == 'p');
/* This is incorrect! a * (2^b - 1) is close. */ /* You could need up to a * (2^b - 1) bits. */
expr_width(l->expr_width()+r->expr_width()); expr_width(l->expr_width());
cast_signed(l->has_sign() || r->has_sign()); cast_signed(l->has_sign() || r->has_sign());
} }
@ -438,6 +436,7 @@ NetECReal::NetECReal(const verireal&val)
: value_(val) : value_(val)
{ {
expr_width(1); expr_width(1);
cast_signed(true);
} }
NetECReal::~NetECReal() NetECReal::~NetECReal()

View File

@ -173,7 +173,7 @@ void Link::unlink()
bool Link::is_equal(const Link&that) const bool Link::is_equal(const Link&that) const
{ {
return (node_ == that.node_) && (pin_ == that.pin_); return (get_obj() == that.get_obj()) && (get_pin() == that.get_pin());
} }
bool Link::is_linked() const bool Link::is_linked() const
@ -261,6 +261,25 @@ verinum::V Nexus::get_init() const
return verinum::Vz; return verinum::Vz;
} }
bool Nexus::assign_lval() const
{
assert(list_);
for (Link*cur = list_ ; cur ; cur = cur->next_) {
const NetPins*obj;
unsigned pin;
cur->cur_link(obj, pin);
const NetNet*net = dynamic_cast<const NetNet*> (obj);
if (net == 0)
continue;
if (net->peek_lref())
return true;
}
return false;
}
bool Nexus::drivers_present() const bool Nexus::drivers_present() const
{ {
assert(list_); assert(list_);

View File

@ -23,6 +23,7 @@
# include <cassert> # include <cassert>
# include <typeinfo> # include <typeinfo>
# include "compiler.h"
# include "netlist.h" # include "netlist.h"
# include "netmisc.h" # include "netmisc.h"
@ -114,6 +115,11 @@ NexusSet* NetESelect::nex_input(bool rem_out)
} }
result->add(*tmp); result->add(*tmp);
delete tmp; delete tmp;
/* See the comment for NetESignal below. */
if (base_ && warn_sens_entire_vec) {
cerr << get_fileline() << ": warning: @* is sensitive to all "
"bits in '" << *expr_ << "'." << endl;
}
return result; return result;
} }
@ -133,7 +139,25 @@ NexusSet* NetESFunc::nex_input(bool rem_out)
NexusSet* NetESignal::nex_input(bool rem_out) NexusSet* NetESignal::nex_input(bool rem_out)
{ {
/*
* This is not what I would expect for the various selects (bit,
* part, index, array). This code adds all the bits/array words
* instead of building the appropriate select and then using it
* as the trigger. Other simulators also add everything.
*/
NexusSet*result = new NexusSet; NexusSet*result = new NexusSet;
/* If we have an array index add it to the sensitivity list. */
if (word_) {
NexusSet*tmp;
tmp = word_->nex_input(rem_out);
result->add(*tmp);
delete tmp;
if (warn_sens_entire_arr) {
cerr << get_fileline() << ": warning: @* is sensitive to all "
<< net_->array_count() << " words in array '"
<< name() << "'." << endl;
}
}
for (unsigned idx = 0 ; idx < net_->pin_count() ; idx += 1) for (unsigned idx = 0 ; idx < net_->pin_count() ; idx += 1)
result->add(net_->pin(idx).nexus()); result->add(net_->pin(idx).nexus());

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 * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -41,17 +41,20 @@ NetScope::NetScope(NetScope*up, const hname_t&n, NetScope::TYPE t)
events_ = 0; events_ = 0;
lcounter_ = 0; lcounter_ = 0;
is_auto_ = false; is_auto_ = false;
is_cell_ = false;
if (up) { if (up) {
default_nettype_ = up->default_nettype(); default_nettype_ = up->default_nettype();
time_unit_ = up->time_unit(); time_unit_ = up->time_unit();
time_prec_ = up->time_precision(); time_prec_ = up->time_precision();
time_from_timescale_ = up->time_from_timescale();
sib_ = up_->sub_; sib_ = up_->sub_;
up_->sub_ = this; up_->sub_ = this;
} else { } else {
default_nettype_ = NetNet::NONE; default_nettype_ = NetNet::NONE;
time_unit_ = 0; time_unit_ = 0;
time_prec_ = 0; time_prec_ = 0;
time_from_timescale_ = false;
assert(t == MODULE); assert(t == MODULE);
} }
@ -230,6 +233,31 @@ NetScope::TYPE NetScope::type() const
return type_; return type_;
} }
void NetScope::print_type(ostream&stream) const
{
switch (type_) {
case BEGIN_END:
stream << "sequential block";
break;
case FORK_JOIN:
stream << "parallel block";
break;
case FUNC:
stream << "function";
break;
case MODULE:
stream << "module <" << (module_name_ ? module_name_.str() : "")
<< "> instance";
break;
case TASK:
stream << "task";
break;
case GENBLOCK:
stream << "generate block";
break;
}
}
void NetScope::set_task_def(NetTaskDef*def) void NetScope::set_task_def(NetTaskDef*def)
{ {
assert( type_ == TASK ); assert( type_ == TASK );
@ -295,6 +323,11 @@ void NetScope::time_precision(int val)
time_prec_ = val; time_prec_ = val;
} }
void NetScope::time_from_timescale(bool val)
{
time_from_timescale_ = val;
}
int NetScope::time_unit() const int NetScope::time_unit() const
{ {
return time_unit_; return time_unit_;
@ -305,6 +338,11 @@ int NetScope::time_precision() const
return time_prec_; return time_prec_;
} }
bool NetScope::time_from_timescale() const
{
return time_from_timescale_;
}
void NetScope::default_nettype(NetNet::Type nt) void NetScope::default_nettype(NetNet::Type nt)
{ {
default_nettype_ = nt; default_nettype_ = nt;
@ -357,6 +395,20 @@ NetEvent* NetScope::find_event(perm_string name)
return 0; return 0;
} }
void NetScope::add_genvar(perm_string name, LineInfo *li)
{
assert((type_ == MODULE) || (type_ == GENBLOCK));
genvars_[name] = li;
}
LineInfo* NetScope::find_genvar(perm_string name)
{
if (genvars_.find(name) != genvars_.end())
return genvars_[name];
else
return 0;
}
void NetScope::add_signal(NetNet*net) void NetScope::add_signal(NetNet*net)
{ {
signals_map_[net->name()]=net; signals_map_[net->name()]=net;

View File

@ -78,8 +78,8 @@ ostream& operator<< (ostream&o, NetNet::Type t)
case NetNet::WIRE: case NetNet::WIRE:
o << "wire"; o << "wire";
break; break;
case NetNet::WONE: case NetNet::UWIRE:
o << "wone"; o << "uwire";
} }
return o; return o;
} }
@ -172,26 +172,51 @@ Link* find_next_output(Link*lnk)
return 0; return 0;
} }
NetPins::NetPins(unsigned npins) void NetPins::devirtualize_pins(void)
: npins_(npins)
{ {
if (pins_) return;
if (npins_ > array_size_limit) {
cerr << get_fileline() << ": error: pin count " << npins_ <<
" exceeds " << array_size_limit <<
" (set by -pARRAY_SIZE_LIMIT)" << endl;
assert(0);
}
if (debug_optimizer && npins_ > 1000) cerr << "debug: devirtualizing " << npins_ << " pins." << endl;
pins_ = new Link[npins_]; pins_ = new Link[npins_];
pins_[0].pin_zero_ = true; pins_[0].pin_zero_ = true;
pins_[0].node_ = this; pins_[0].node_ = this;
pins_[0].dir_ = default_dir_;
pins_[0].init_ = default_init_;
for (unsigned idx = 1 ; idx < npins_ ; idx += 1) { for (unsigned idx = 1 ; idx < npins_ ; idx += 1) {
pins_[idx].pin_zero_ = false; pins_[idx].pin_zero_ = false;
pins_[idx].pin_ = idx; pins_[idx].pin_ = idx;
pins_[idx].dir_ = default_dir_;
pins_[idx].init_ = default_init_;
} }
} }
bool NetPins::pins_are_virtual(void) const
{
return pins_ == NULL;
}
NetPins::NetPins(unsigned npins)
: npins_(npins)
{
pins_ = NULL; // Wait until someone asks.
if (disable_virtual_pins) devirtualize_pins(); // Ask. Bummer.
}
NetPins::~NetPins() NetPins::~NetPins()
{ {
delete[]pins_; if (pins_) delete[]pins_;
} }
Link& NetPins::pin(unsigned idx) Link& NetPins::pin(unsigned idx)
{ {
if (!pins_) devirtualize_pins();
if (idx >= npins_) { if (idx >= npins_) {
cerr << get_fileline() << ": internal error: pin("<<idx<<")" cerr << get_fileline() << ": internal error: pin("<<idx<<")"
<< " out of bounds("<<npins_<<")" << endl; << " out of bounds("<<npins_<<")" << endl;
@ -207,11 +232,27 @@ Link& NetPins::pin(unsigned idx)
const Link& NetPins::pin(unsigned idx) const const Link& NetPins::pin(unsigned idx) const
{ {
if (!pins_ && !disable_virtual_pins) {
cerr << get_fileline() << ": internal error: pin is unexpectedly"
" virtual, try again with -pDISABLE_VIRTUAL_PINS=true" << endl;
assert(0);
}
assert(pins_);
assert(idx < npins_); assert(idx < npins_);
assert(idx == 0? pins_[0].pin_zero_ : pins_[idx].pin_==idx); assert(idx == 0? pins_[0].pin_zero_ : pins_[idx].pin_==idx);
return pins_[idx]; return pins_[idx];
} }
void NetPins::set_default_dir(Link::DIR d)
{
default_dir_ = d;
}
void NetPins::set_default_init(verinum::V val)
{
default_init_ = val;
}
bool NetPins::is_linked(void) bool NetPins::is_linked(void)
{ {
bool linked_flag = false; bool linked_flag = false;
@ -228,6 +269,11 @@ bool NetPins::is_linked(void)
NetObj::NetObj(NetScope*s, perm_string n, unsigned np) NetObj::NetObj(NetScope*s, perm_string n, unsigned np)
: NetPins(np), scope_(s), name_(n), delay1_(0), delay2_(0), delay3_(0) : NetPins(np), scope_(s), name_(n), delay1_(0), delay2_(0), delay3_(0)
{ {
/* Don't
ivl_assert(*this, np > 0);
* because it would happen before we get to print a useful
* message in the NetNet constructor
*/
} }
NetObj::~NetObj() NetObj::~NetObj()
@ -269,6 +315,9 @@ NetBranch::~NetBranch()
NetBus::NetBus(NetScope*s, unsigned pin_count__) NetBus::NetBus(NetScope*s, unsigned pin_count__)
: NetObj(s, perm_string::literal(""), pin_count__) : NetObj(s, perm_string::literal(""), pin_count__)
{ {
for (unsigned idx = 0 ; idx <pin_count__ ; idx += 1) {
pin(idx).set_dir(Link::PASSIVE);
}
} }
NetBus::~NetBus() NetBus::~NetBus()
@ -442,8 +491,8 @@ const Link& NetDelaySrc::condit_pin() const
NetNet::NetNet(NetScope*s, perm_string n, Type t, unsigned npins) NetNet::NetNet(NetScope*s, perm_string n, Type t, unsigned npins)
: NetObj(s, n, 1), : NetObj(s, n, 1),
type_(t), port_type_(NOT_A_PORT), data_type_(IVL_VT_NO_TYPE), type_(t), port_type_(NOT_A_PORT), data_type_(IVL_VT_NO_TYPE),
signed_(false), isint_(false), discipline_(0), msb_(npins-1), lsb_(0), signed_(false), isint_(false), is_scalar_(false),
dimensions_(0), discipline_(0), msb_(npins-1), lsb_(0), dimensions_(0),
s0_(0), e0_(0), local_flag_(false), eref_count_(0), lref_count_(0) s0_(0), e0_(0), local_flag_(false), eref_count_(0), lref_count_(0)
{ {
assert(s); assert(s);
@ -479,7 +528,11 @@ NetNet::NetNet(NetScope*s, perm_string n, Type t, unsigned npins)
void NetNet::initialize_value_and_dir(verinum::V init_value, Link::DIR dir) void NetNet::initialize_value_and_dir(verinum::V init_value, Link::DIR dir)
{ {
if (1) { if (pins_are_virtual()) {
if (0) cerr << "NetNet setting Link default value and dir" << endl;
set_default_init(init_value);
set_default_dir(dir);
} else {
for (unsigned idx = 0 ; idx < pin_count() ; idx += 1) { for (unsigned idx = 0 ; idx < pin_count() ; idx += 1) {
pin(idx).set_dir(dir); pin(idx).set_dir(dir);
pin(idx).set_init(init_value); pin(idx).set_init(init_value);
@ -491,7 +544,8 @@ NetNet::NetNet(NetScope*s, perm_string n, Type t,
long ms, long ls) long ms, long ls)
: NetObj(s, n, 1), type_(t), : NetObj(s, n, 1), type_(t),
port_type_(NOT_A_PORT), data_type_(IVL_VT_NO_TYPE), signed_(false), port_type_(NOT_A_PORT), data_type_(IVL_VT_NO_TYPE), signed_(false),
isint_(false), discipline_(0), msb_(ms), lsb_(ls), dimensions_(0), s0_(0), e0_(0), isint_(false), is_scalar_(false), discipline_(0), msb_(ms), lsb_(ls),
dimensions_(0), s0_(0), e0_(0),
local_flag_(false), eref_count_(0), lref_count_(0) local_flag_(false), eref_count_(0), lref_count_(0)
{ {
assert(s); assert(s);
@ -524,10 +578,16 @@ NetNet::NetNet(NetScope*s, perm_string n, Type t,
static unsigned calculate_count(long s, long e) static unsigned calculate_count(long s, long e)
{ {
if (s >= e) unsigned long r;
return s - e + 1; if (s >= e) {
else r = s - e;
return e - s + 1; } else {
r = e - s;
}
if (r >= UINT_MAX) {
return 0;
}
return r + 1;
} }
NetNet::NetNet(NetScope*s, perm_string n, Type t, NetNet::NetNet(NetScope*s, perm_string n, Type t,
@ -535,10 +595,15 @@ NetNet::NetNet(NetScope*s, perm_string n, Type t,
: NetObj(s, n, calculate_count(array_s, array_e)), : NetObj(s, n, calculate_count(array_s, array_e)),
type_(t), port_type_(NOT_A_PORT), type_(t), port_type_(NOT_A_PORT),
data_type_(IVL_VT_NO_TYPE), signed_(false), isint_(false), data_type_(IVL_VT_NO_TYPE), signed_(false), isint_(false),
discipline_(0), msb_(ms), lsb_(ls), dimensions_(1), s0_(array_s), e0_(array_e), is_scalar_(false), discipline_(0), msb_(ms), lsb_(ls),
dimensions_(1), s0_(array_s), e0_(array_e),
local_flag_(false), eref_count_(0), lref_count_(0) local_flag_(false), eref_count_(0), lref_count_(0)
{ {
assert(s); ivl_assert(*this, s);
if (pin_count() == 0) {
cerr << "Array too big [" << array_s << ":" << array_e << "]" << endl;
ivl_assert(*this, 0);
}
verinum::V init_value = verinum::Vz; verinum::V init_value = verinum::Vz;
Link::DIR dir = Link::PASSIVE; Link::DIR dir = Link::PASSIVE;
@ -664,6 +729,16 @@ void NetNet::set_isint(bool flag)
isint_ = flag; isint_ = flag;
} }
bool NetNet::get_scalar() const
{
return is_scalar_;
}
void NetNet::set_scalar(bool flag)
{
is_scalar_ = flag;
}
ivl_discipline_t NetNet::get_discipline() const ivl_discipline_t NetNet::get_discipline() const
{ {
return discipline_; return discipline_;
@ -732,7 +807,9 @@ bool NetNet::array_addr_swapped() const
unsigned NetNet::array_count() const unsigned NetNet::array_count() const
{ {
return calculate_count(s0_, e0_); unsigned c = calculate_count(s0_, e0_);
ivl_assert(*this, c > 0);
return c;
} }
bool NetNet::array_index_is_valid(long sb) const bool NetNet::array_index_is_valid(long sb) const
@ -808,9 +885,8 @@ const NetDelaySrc* NetNet::delay_path(unsigned idx) const
NetPartSelect::NetPartSelect(NetNet*sig, unsigned off, unsigned wid, NetPartSelect::NetPartSelect(NetNet*sig, unsigned off, unsigned wid,
NetPartSelect::dir_t dir__) NetPartSelect::dir_t dir__)
: NetNode(sig->scope(), sig->scope()->local_symbol(), 2), : NetNode(sig->scope(), sig->scope()->local_symbol(), 2),
off_(off), wid_(wid), dir_(dir__) off_(off), wid_(wid), dir_(dir__), signed_flag_(false)
{ {
connect(pin(1), sig->pin(0));
set_line(*sig); set_line(*sig);
switch (dir_) { switch (dir_) {
@ -823,27 +899,28 @@ NetPartSelect::NetPartSelect(NetNet*sig, unsigned off, unsigned wid,
pin(1).set_dir(Link::OUTPUT); pin(1).set_dir(Link::OUTPUT);
break; break;
} }
connect(pin(1), sig->pin(0));
} }
NetPartSelect::NetPartSelect(NetNet*sig, NetNet*sel, NetPartSelect::NetPartSelect(NetNet*sig, NetNet*sel,
unsigned wid) unsigned wid, bool signed_flag)
: NetNode(sig->scope(), sig->scope()->local_symbol(), 3), : NetNode(sig->scope(), sig->scope()->local_symbol(), 3),
off_(0), wid_(wid), dir_(VP) off_(0), wid_(wid), dir_(VP), signed_flag_(signed_flag)
{ {
connect(pin(1), sig->pin(0));
connect(pin(2), sel->pin(0));
switch (dir_) { switch (dir_) {
case NetPartSelect::VP: case NetPartSelect::VP:
pin(0).set_dir(Link::OUTPUT); pin(0).set_dir(Link::OUTPUT);
pin(1).set_dir(Link::INPUT); pin(1).set_dir(Link::INPUT);
break; break;
case NetPartSelect::PV: case NetPartSelect::PV:
pin(0).set_dir(Link::INPUT); /* Only a vector to part can be a variable select. */
pin(1).set_dir(Link::OUTPUT); assert(0);
break;
} }
pin(2).set_dir(Link::INPUT); pin(2).set_dir(Link::INPUT);
connect(pin(1), sig->pin(0));
connect(pin(2), sel->pin(0));
} }
NetPartSelect::~NetPartSelect() NetPartSelect::~NetPartSelect()
@ -2271,12 +2348,12 @@ NetNet* NetESignal::sig()
return net_; return net_;
} }
unsigned NetESignal::lsi() const long NetESignal::lsi() const
{ {
return net_->lsb(); return net_->lsb();
} }
unsigned NetESignal::msi() const long NetESignal::msi() const
{ {
return net_->msb(); return net_->msb();
} }
@ -2591,6 +2668,7 @@ static DelayType get_loop_delay_type(const NetExpr*expr, const NetProc*proc)
/* This should never happen since delay_type_from_expr() only /* This should never happen since delay_type_from_expr() only
* returns three different values. */ * returns three different values. */
default: default:
result = NO_DELAY;
assert(0); assert(0);
} }

View File

@ -193,11 +193,17 @@ class NetPins : public LineInfo {
const Link&pin(unsigned idx) const; const Link&pin(unsigned idx) const;
void dump_node_pins(ostream&, unsigned, const char**pin_names =0) const; void dump_node_pins(ostream&, unsigned, const char**pin_names =0) const;
void set_default_dir(Link::DIR d);
void set_default_init(verinum::V val);
bool is_linked(); bool is_linked();
bool pins_are_virtual(void) const;
void devirtualize_pins(void);
private: private:
Link*pins_; Link*pins_;
const unsigned npins_; const unsigned npins_;
Link::DIR default_dir_;
verinum::V default_init_;
}; };
/* ========= /* =========
@ -341,6 +347,11 @@ class Nexus {
NetNet* pick_any_net(); NetNet* pick_any_net();
/* This method returns true if there are any assignments that
use this nexus as an l-value. This can be true if the nexus
is a variable, but also if this is a net with a force. */
bool assign_lval() const;
/* This method returns true if there are any drivers /* This method returns true if there are any drivers
(including variables) attached to this nexus. */ (including variables) attached to this nexus. */
bool drivers_present() const; bool drivers_present() const;
@ -536,7 +547,7 @@ class NetNet : public NetObj {
public: public:
enum Type { NONE, IMPLICIT, IMPLICIT_REG, INTEGER, WIRE, TRI, TRI1, enum Type { NONE, IMPLICIT, IMPLICIT_REG, INTEGER, WIRE, TRI, TRI1,
SUPPLY0, SUPPLY1, WAND, TRIAND, TRI0, WOR, TRIOR, REG, SUPPLY0, SUPPLY1, WAND, TRIAND, TRI0, WOR, TRIOR, REG,
WONE }; UWIRE };
enum PortType { NOT_A_PORT, PIMPLICIT, PINPUT, POUTPUT, PINOUT }; enum PortType { NOT_A_PORT, PIMPLICIT, PINPUT, POUTPUT, PINOUT };
@ -575,6 +586,9 @@ class NetNet : public NetObj {
bool get_isint() const; bool get_isint() const;
void set_isint(bool); void set_isint(bool);
bool get_scalar() const;
void set_scalar(bool);
/* Attach a discipline to the net. */ /* Attach a discipline to the net. */
ivl_discipline_t get_discipline() const; ivl_discipline_t get_discipline() const;
void set_discipline(ivl_discipline_t dis); void set_discipline(ivl_discipline_t dis);
@ -644,6 +658,7 @@ class NetNet : public NetObj {
ivl_variable_type_t data_type_; ivl_variable_type_t data_type_;
bool signed_; bool signed_;
bool isint_; // original type of integer bool isint_; // original type of integer
bool is_scalar_;
ivl_discipline_t discipline_; ivl_discipline_t discipline_;
long msb_, lsb_; long msb_, lsb_;
@ -710,6 +725,9 @@ class NetScope : public Attrib {
void rem_event(NetEvent*); void rem_event(NetEvent*);
NetEvent*find_event(perm_string name); NetEvent*find_event(perm_string name);
/* These methods add or find a genvar that lives in this scope. */
void add_genvar(perm_string name, LineInfo *li);
LineInfo* find_genvar(perm_string name);
/* These methods manage signals. The add_ and rem_signal /* These methods manage signals. The add_ and rem_signal
methods are used by the NetNet objects to make themselves methods are used by the NetNet objects to make themselves
@ -728,6 +746,7 @@ class NetScope : public Attrib {
const NetScope* child(const hname_t&name) const; const NetScope* child(const hname_t&name) const;
TYPE type() const; TYPE type() const;
void print_type(ostream&) const;
void set_task_def(NetTaskDef*); void set_task_def(NetTaskDef*);
void set_func_def(NetFuncDef*); void set_func_def(NetFuncDef*);
@ -750,6 +769,10 @@ class NetScope : public Attrib {
void is_auto(bool is_auto__) { is_auto_ = is_auto__; }; void is_auto(bool is_auto__) { is_auto_ = is_auto__; };
bool is_auto() const { return is_auto_; }; bool is_auto() const { return is_auto_; };
/* Is the module a cell (is in a `celldefine) */
void is_cell(bool is_cell__) { is_cell_ = is_cell__; };
bool is_cell() const { return is_cell_; };
const NetTaskDef* task_def() const; const NetTaskDef* task_def() const;
const NetFuncDef* func_def() const; const NetFuncDef* func_def() const;
@ -767,9 +790,11 @@ class NetScope : public Attrib {
void time_unit(int); void time_unit(int);
void time_precision(int); void time_precision(int);
void time_from_timescale(bool);
int time_unit() const; int time_unit() const;
int time_precision() const; int time_precision() const;
bool time_from_timescale() const;
void default_nettype(NetNet::Type); void default_nettype(NetNet::Type);
NetNet::Type default_nettype() const; NetNet::Type default_nettype() const;
@ -877,10 +902,13 @@ class NetScope : public Attrib {
unsigned def_lineno_; unsigned def_lineno_;
signed char time_unit_, time_prec_; signed char time_unit_, time_prec_;
bool time_from_timescale_;
NetNet::Type default_nettype_; NetNet::Type default_nettype_;
NetEvent *events_; NetEvent *events_;
map<perm_string,LineInfo*> genvars_;
typedef std::map<perm_string,NetNet*>::const_iterator signals_map_iter_t; typedef std::map<perm_string,NetNet*>::const_iterator signals_map_iter_t;
std::map <perm_string,NetNet*> signals_map_; std::map <perm_string,NetNet*> signals_map_;
perm_string module_name_; perm_string module_name_;
@ -894,7 +922,7 @@ class NetScope : public Attrib {
NetScope*sub_; NetScope*sub_;
unsigned lcounter_; unsigned lcounter_;
bool is_auto_; bool is_auto_, is_cell_;
}; };
/* /*
@ -1772,12 +1800,14 @@ class NetPartSelect : public NetNode {
explicit NetPartSelect(NetNet*sig, explicit NetPartSelect(NetNet*sig,
unsigned off, unsigned wid, dir_t dir); unsigned off, unsigned wid, dir_t dir);
explicit NetPartSelect(NetNet*sig, NetNet*sel, explicit NetPartSelect(NetNet*sig, NetNet*sel,
unsigned wid); unsigned wid, bool signed_flag = false);
~NetPartSelect(); ~NetPartSelect();
unsigned base() const; unsigned base() const;
unsigned width() const; unsigned width() const;
dir_t dir() const; dir_t dir() const;
/* Is the select signal signed? */
bool signed_flag() const { return signed_flag_; }
virtual void dump_node(ostream&, unsigned ind) const; virtual void dump_node(ostream&, unsigned ind) const;
bool emit_node(struct target_t*tgt) const; bool emit_node(struct target_t*tgt) const;
@ -1786,6 +1816,7 @@ class NetPartSelect : public NetNode {
unsigned off_; unsigned off_;
unsigned wid_; unsigned wid_;
dir_t dir_; dir_t dir_;
bool signed_flag_;
}; };
/* /*
@ -3256,6 +3287,7 @@ class NetEBAdd : public NetEBinary {
virtual ivl_variable_type_t expr_type() const; virtual ivl_variable_type_t expr_type() const;
virtual bool set_width(unsigned w, bool last_chance); virtual bool set_width(unsigned w, bool last_chance);
virtual void cast_signed(bool sign_flag);
virtual NetEBAdd* dup_expr() const; virtual NetEBAdd* dup_expr() const;
virtual NetExpr* eval_tree(int prune_to_width = -1); virtual NetExpr* eval_tree(int prune_to_width = -1);
virtual NetNet* synthesize(Design*, NetScope*scope, NetExpr*root); virtual NetNet* synthesize(Design*, NetScope*scope, NetExpr*root);
@ -3278,6 +3310,7 @@ class NetEBDiv : public NetEBinary {
virtual ivl_variable_type_t expr_type() const; virtual ivl_variable_type_t expr_type() const;
virtual bool set_width(unsigned w, bool last_chance); virtual bool set_width(unsigned w, bool last_chance);
virtual void cast_signed(bool sign_flag);
virtual NetEBDiv* dup_expr() const; virtual NetEBDiv* dup_expr() const;
virtual NetExpr* eval_tree(int prune_to_width = -1); virtual NetExpr* eval_tree(int prune_to_width = -1);
virtual NetNet* synthesize(Design*, NetScope*scope, NetExpr*root); virtual NetNet* synthesize(Design*, NetScope*scope, NetExpr*root);
@ -3408,6 +3441,7 @@ class NetEBMult : public NetEBinary {
virtual ivl_variable_type_t expr_type() const; virtual ivl_variable_type_t expr_type() const;
virtual bool set_width(unsigned w, bool last_chance); virtual bool set_width(unsigned w, bool last_chance);
virtual void cast_signed(bool sign_flag);
virtual NetEBMult* dup_expr() const; virtual NetEBMult* dup_expr() const;
virtual NetExpr* eval_tree(int prune_to_width = -1); virtual NetExpr* eval_tree(int prune_to_width = -1);
virtual NetNet* synthesize(Design*, NetScope*scope, NetExpr*root); virtual NetNet* synthesize(Design*, NetScope*scope, NetExpr*root);
@ -3803,8 +3837,8 @@ class NetESignal : public NetExpr {
const NetNet* sig() const; const NetNet* sig() const;
NetNet* sig(); NetNet* sig();
// Declared vector dimensions for the signal. // Declared vector dimensions for the signal.
unsigned msi() const; long msi() const;
unsigned lsi() const; long lsi() const;
virtual ivl_variable_type_t expr_type() const; virtual ivl_variable_type_t expr_type() const;

View File

@ -16,7 +16,6 @@
* along with this program; if not, write to the Free Software * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#ident "$Id: netlist.txt,v 1.10 2000/07/23 18:06:15 steve Exp $"
Note that the netlist.h header contains detailed descriptions of how Note that the netlist.h header contains detailed descriptions of how
@ -291,49 +290,3 @@ values. These are filled in during scope elaboration and are used in
subsequent elaboration phases to arrange for scaling of delays. This subsequent elaboration phases to arrange for scaling of delays. This
information can also be used by the code generator to scale times back information can also be used by the code generator to scale times back
to the units of the scope, if that is desired. to the units of the scope, if that is desired.
$Log: netlist.txt,v $
Revision 1.10 2000/07/23 18:06:15 steve
Document time scale in netlists.
Revision 1.9 2000/07/14 06:12:57 steve
Move inital value handling from NetNet to Nexus
objects. This allows better propogation of inital
values.
Clean up constant propagation a bit to account
for regs that are not really values.
Revision 1.8 2000/03/08 04:36:54 steve
Redesign the implementation of scopes and parameters.
I now generate the scopes and notice the parameters
in a separate pass over the pform. Once the scopes
are generated, I can process overrides and evalutate
paremeters before elaboration begins.
Revision 1.7 1999/11/28 23:42:02 steve
NetESignal object no longer need to be NetNode
objects. Let them keep a pointer to NetNet objects.
Revision 1.6 1999/11/21 00:13:09 steve
Support memories in continuous assignments.
Revision 1.5 1999/11/02 04:55:34 steve
Add the synthesize method to NetExpr to handle
synthesis of expressions, and use that method
to improve r-value handling of LPM_FF synthesis.
Modify the XNF target to handle LPM_FF objects.
Revision 1.4 1999/09/29 00:03:27 steve
Spelling fixes from Larry.
Revision 1.3 1999/07/24 02:11:20 steve
Elaborate task input ports.
Revision 1.2 1999/07/21 01:15:29 steve
Document netlist semantics.
Revision 1.1 1999/05/27 04:13:08 steve
Handle expression bit widths with non-fatal errors.

View File

@ -416,6 +416,7 @@ const char *human_readable_op(const char op, bool unary)
case '-': type = "-"; break; case '-': type = "-"; break;
case '*': type = "*"; break; case '*': type = "*"; break;
case '/': type = "/"; break; case '/': type = "/"; break;
case '%': type = "%"; break;
case '<': type = "<"; break; case '<': type = "<"; break;
case '>': type = ">"; break; case '>': type = ">"; break;
@ -447,6 +448,7 @@ const char *human_readable_op(const char op, bool unary)
case 'p': type = "**"; break; // Power case 'p': type = "**"; break; // Power
default: default:
type = "???";
assert(0); assert(0);
} }
return type; return type;

View File

@ -231,4 +231,8 @@ const char *human_readable_op(const char op, bool unary = false);
enum const_bool { C_NON, C_0, C_1, C_X }; enum const_bool { C_NON, C_0, C_1, C_X };
const_bool const_logical(const NetExpr*expr); const_bool const_logical(const NetExpr*expr);
extern bool dly_used_no_timescale;
extern bool dly_used_timescale;
extern bool display_ts_dly_warning;
#endif #endif

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 * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -134,7 +134,7 @@ NetNet*crop_to_width(Design*des, NetNet*net, unsigned wid)
NetNet::WIRE, wid); NetNet::WIRE, wid);
tmp->data_type(net->data_type()); tmp->data_type(net->data_type());
tmp->local_flag(true); tmp->local_flag(true);
tmp->set_line(*tmp); tmp->set_line(*net);
connect(ps->pin(0), tmp->pin(0)); connect(ps->pin(0), tmp->pin(0));
return tmp; return tmp;

314
parse.y
View File

@ -55,6 +55,13 @@ static PTask* current_task = 0;
static PFunction* current_function = 0; static PFunction* current_function = 0;
static stack<PBlock*> current_block_stack; static stack<PBlock*> current_block_stack;
/* This is used to keep track of the extra arguments after the notifier
* in the $setuphold and $recrem timing checks. This allows us to print
* a warning message that the delayed signals will not be created. We
* need to do this since not driving these signals creates real
* simulation issues. */
static unsigned args_after_notifier;
/* Later version of bison (including 1.35) will not compile in stack /* Later version of bison (including 1.35) will not compile in stack
extension if the output is compiled with C++ and either the YYSTYPE extension if the output is compiled with C++ and either the YYSTYPE
or YYLTYPE are provided by the source code. However, I can get the or YYLTYPE are provided by the source code. However, I can get the
@ -80,6 +87,22 @@ static stack<PBlock*> current_block_stack;
const static struct str_pair_t pull_strength = { PGate::PULL, PGate::PULL }; const static struct str_pair_t pull_strength = { PGate::PULL, PGate::PULL };
const static struct str_pair_t str_strength = { PGate::STRONG, PGate::STRONG }; const static struct str_pair_t str_strength = { PGate::STRONG, PGate::STRONG };
static list<pair<perm_string,PExpr*> >* make_port_list(char*id, PExpr*expr)
{
list<pair<perm_string,PExpr*> >*tmp = new list<pair<perm_string,PExpr*> >;
tmp->push_back(make_pair(lex_strings.make(id), expr));
delete[]id;
return tmp;
}
static list<pair<perm_string,PExpr*> >* make_port_list(list<pair<perm_string,
PExpr*> >*tmp,
char*id, PExpr*expr)
{
tmp->push_back(make_pair(lex_strings.make(id), expr));
delete[]id;
return tmp;
}
static list<perm_string>* list_from_identifier(char*id) static list<perm_string>* list_from_identifier(char*id)
{ {
list<perm_string>*tmp = new list<perm_string>; list<perm_string>*tmp = new list<perm_string>;
@ -146,6 +169,9 @@ static PECallFunction*make_call_function(perm_string tn, PExpr*arg1, PExpr*arg2)
strdup. They can be put into lists with the texts type. */ strdup. They can be put into lists with the texts type. */
char*text; char*text;
list<perm_string>*perm_strings; list<perm_string>*perm_strings;
list<pair<perm_string,PExpr*> >*port_list;
pform_name_t*pform_name; pform_name_t*pform_name;
ivl_discipline_t discipline; ivl_discipline_t discipline;
@ -210,40 +236,56 @@ static PECallFunction*make_call_function(perm_string tn, PExpr*arg1, PExpr*arg2)
%token K_PO_POS K_PO_NEG K_POW %token K_PO_POS K_PO_NEG K_POW
%token K_PSTAR K_STARP %token K_PSTAR K_STARP
%token K_LOR K_LAND K_NAND K_NOR K_NXOR K_TRIGGER %token K_LOR K_LAND K_NAND K_NOR K_NXOR K_TRIGGER
%token K_abs K_abstol K_access K_acos K_acosh K_asin K_analog K_asinh %token K_edge_descriptor
%token K_atan K_atanh K_atan2 K_automatic
%token K_always K_and K_assign K_begin K_bool K_buf K_bufif0 K_bufif1 K_case
%token K_casex K_casez K_ceil K_cmos K_continuous K_cos K_cosh
%token K_ddt_nature K_deassign K_default K_defparam K_disable K_discrete
%token K_domain K_edge K_edge_descriptor K_discipline
%token K_else K_end K_endcase K_enddiscipline K_endfunction K_endgenerate
%token K_endmodule K_endnature
%token K_endprimitive K_endspecify K_endtable K_endtask K_event
%token K_exclude K_exp K_floor K_flow K_from
%token K_for K_force K_forever K_fork K_function K_generate K_genvar
%token K_ground K_highz0 K_highz1 K_hypot K_idt_nature K_if K_ifnone K_inf
%token K_initial K_inout K_input K_integer K_join K_large K_ln K_localparam
%token K_log K_logic K_macromodule K_max
%token K_medium K_min K_module K_nand K_nature K_negedge
%token K_nmos K_nor K_not K_notif0
%token K_notif1 K_or K_output K_parameter K_pmos K_posedge K_potential
%token K_pow K_primitive
%token K_pull0 K_pull1 K_pulldown K_pullup K_rcmos K_real K_realtime
%token K_reg K_release K_repeat
%token K_rnmos K_rpmos K_rtran K_rtranif0 K_rtranif1 K_scalared
%token K_signed K_sin K_sinh K_small K_specify
%token K_specparam K_sqrt K_string K_strong0 K_strong1 K_supply0 K_supply1
%token K_table
%token K_tan K_tanh K_task
%token K_time K_tran K_tranif0 K_tranif1 K_tri K_tri0 K_tri1 K_triand
%token K_trior K_trireg K_units K_vectored K_wait K_wand K_weak0 K_weak1
%token K_while K_wire
%token K_wone K_wor K_xnor K_xor
%token K_Shold K_Speriod K_Srecovery K_Srecrem K_Ssetup K_Swidth K_Ssetuphold
/* The base tokens from 1364-1995. */
%token K_always K_and K_assign K_begin K_buf K_bufif0 K_bufif1 K_case
%token K_casex K_casez K_cmos K_deassign K_default K_defparam K_disable
%token K_edge K_else K_end K_endcase K_endfunction K_endmodule
%token K_endprimitive K_endspecify K_endtable K_endtask K_event K_for
%token K_force K_forever K_fork K_function K_highz0 K_highz1 K_if
%token K_ifnone K_initial K_inout K_input K_integer K_join K_large
%token K_macromodule K_medium K_module K_nand K_negedge K_nmos K_nor
%token K_not K_notif0 K_notif1 K_or K_output K_parameter K_pmos K_posedge
%token K_primitive K_pull0 K_pull1 K_pulldown K_pullup K_rcmos K_real
%token K_realtime K_reg K_release K_repeat K_rnmos K_rpmos K_rtran
%token K_rtranif0 K_rtranif1 K_scalared K_small K_specify K_specparam
%token K_strong0 K_strong1 K_supply0 K_supply1 K_table K_task K_time
%token K_tran K_tranif0 K_tranif1 K_tri K_tri0 K_tri1 K_triand K_trior
%token K_trireg K_vectored K_wait K_wand K_weak0 K_weak1 K_while K_wire
%token K_wor K_xnor K_xor
%token K_Shold K_Snochange K_Speriod K_Srecovery K_Ssetup K_Ssetuphold
%token K_Sskew K_Swidth
/* Icarus specific tokens. */
%token KK_attribute K_bool K_logic
/* The new tokens from 1364-2001. */
%token K_automatic K_endgenerate K_generate K_genvar K_localparam
%token K_noshowcancelled K_pulsestyle_onevent K_pulsestyle_ondetect
%token K_showcancelled K_signed K_unsigned
%token K_Sfullskew K_Srecrem K_Sremoval K_Stimeskew
/* The 1364-2001 configuration tokens. */
%token K_cell K_config K_design K_endconfig K_incdir K_include K_instance
%token K_liblist K_library K_use
/* The new tokens from 1364-2005. */
%token K_wone K_uwire
/* The new tokens from 1800-2005. */
%token K_always_comb K_always_ff K_always_latch K_assert %token K_always_comb K_always_ff K_always_latch K_assert
%token KK_attribute /* The new tokens for Verilog-AMS 2.3. */
%token K_abs K_abstol K_access K_acos K_acosh K_analog K_asin K_asinh
%token K_atan K_atan2 K_atanh K_ceil K_continuous K_cos K_cosh
%token K_ddt_nature K_discipline K_discrete K_domain K_enddiscipline
%token K_endnature K_exclude K_exp K_floor K_flow K_from K_ground
%token K_hypot K_idt_nature K_inf K_ln K_log K_max K_min K_nature
%token K_potential K_pow K_sin K_sinh K_sqrt K_string K_tan K_tanh
%token K_units
%type <flag> from_exclude %type <flag> from_exclude
%type <number> number %type <number> number
@ -260,7 +302,9 @@ static PECallFunction*make_call_function(perm_string tn, PExpr*arg1, PExpr*arg2)
%type <expr> udp_initial_expr_opt %type <expr> udp_initial_expr_opt
%type <text> register_variable net_variable real_variable %type <text> register_variable net_variable real_variable
%type <perm_strings> register_variable_list net_variable_list real_variable_list list_of_identifiers %type <perm_strings> register_variable_list net_variable_list
%type <perm_strings> real_variable_list list_of_identifiers
%type <port_list> list_of_port_identifiers
%type <net_decl_assign> net_decl_assign net_decl_assigns %type <net_decl_assign> net_decl_assign net_decl_assigns
@ -682,6 +726,7 @@ delay_value_simple
description description
: module : module
| udp_primitive | udp_primitive
| config_declaration
| nature_declaration | nature_declaration
| discipline_declaration | discipline_declaration
| KK_attribute '(' IDENTIFIER ',' STRING ',' STRING ')' | KK_attribute '(' IDENTIFIER ',' STRING ',' STRING ')'
@ -746,6 +791,54 @@ nature_item
{ delete[] $3; } { delete[] $3; }
; ;
config_declaration
: K_config IDENTIFIER ';'
K_design lib_cell_identifiers ';'
list_of_config_rule_statements
K_endconfig
{ cerr << @1 << ": sorry: config declarations are not supported and "
"will be skipped." << endl;
delete[] $2;
}
;
lib_cell_identifiers
: /* The BNF implies this can be blank, but I'm not sure exactly what
* this means. */
| lib_cell_identifiers lib_cell_id
;
list_of_config_rule_statements
: /* config rules are optional. */
| list_of_config_rule_statements config_rule_statement
;
config_rule_statement
: K_default K_liblist list_of_libraries ';'
| K_instance hierarchy_identifier K_liblist list_of_libraries ';'
{ delete $2; }
| K_instance hierarchy_identifier K_use lib_cell_id opt_config ';'
{ delete $2; }
| K_cell lib_cell_id K_liblist list_of_libraries ';'
| K_cell lib_cell_id K_use lib_cell_id opt_config ';'
;
opt_config
: /* The use clause takse an optional :config. */
| ':' K_config
lib_cell_id
: IDENTIFIER
{ delete[] $1; }
| IDENTIFIER '.' IDENTIFIER
{ delete[] $1; delete[] $3; }
;
list_of_libraries
: /* A NULL library means use the parents cell library. */
| list_of_libraries IDENTIFIER
{ delete[] $2; }
drive_strength drive_strength
: '(' dr_strength0 ',' dr_strength1 ')' : '(' dr_strength0 ',' dr_strength1 ')'
{ $$.str0 = $2.str0; { $$.str0 = $2.str0;
@ -900,6 +993,21 @@ expression
FILE_NAME(tmp, @2); FILE_NAME(tmp, @2);
$$ = tmp; $$ = tmp;
} }
| '~' '&' expr_primary %prec UNARY_PREC
{ yyerror(@1, "error: '~' '&' is not a valid expression. "
"Please use operator '~&' instead.");
$$ = 0;
}
| '~' '|' expr_primary %prec UNARY_PREC
{ yyerror(@1, "error: '~' '|' is not a valid expression. "
"Please use operator '~|' instead.");
$$ = 0;
}
| '~' '^' expr_primary %prec UNARY_PREC
{ yyerror(@1, "error: '~' '^' is not a valid expression. "
"Please use operator '~^' instead.");
$$ = 0;
}
| K_NAND expr_primary %prec UNARY_PREC | K_NAND expr_primary %prec UNARY_PREC
{ PEUnary*tmp = new PEUnary('A', $2); { PEUnary*tmp = new PEUnary('A', $2);
FILE_NAME(tmp, @2); FILE_NAME(tmp, @2);
@ -1647,6 +1755,17 @@ list_of_identifiers
{ $$ = list_from_identifier($1, $3); } { $$ = list_from_identifier($1, $3); }
; ;
list_of_port_identifiers
: IDENTIFIER
{ $$ = make_port_list($1, 0); }
| IDENTIFIER '=' expression
{ $$ = make_port_list($1, $3); }
| list_of_port_identifiers ',' IDENTIFIER
{ $$ = make_port_list($1, $3, 0); }
| list_of_port_identifiers ',' IDENTIFIER '=' expression
{ $$ = make_port_list($1, $3, $5); }
;
/* The list_of_ports and list_of_port_declarations rules are the /* The list_of_ports and list_of_port_declarations rules are the
port list formats for module ports. The list_of_ports_opt rule is port list formats for module ports. The list_of_ports_opt rule is
@ -1876,7 +1995,20 @@ module : attribute_list_opt module_start IDENTIFIER
{ pform_module_set_ports($6); } { pform_module_set_ports($6); }
module_item_list_opt module_item_list_opt
K_endmodule K_endmodule
{ pform_endmodule($3); { Module::UCDriveType ucd;
switch (uc_drive) {
case UCD_NONE:
default:
ucd = Module::UCD_NONE;
break;
case UCD_PULL0:
ucd = Module::UCD_PULL0;
break;
case UCD_PULL1:
ucd = Module::UCD_PULL1;
break;
}
pform_endmodule($3, in_celldefine, ucd);
delete[]$3; delete[]$3;
} }
@ -1991,9 +2123,20 @@ module_item
SR_BOTH); SR_BOTH);
} }
| K_output var_type signed_opt range_opt list_of_identifiers ';' | K_output var_type signed_opt range_opt list_of_port_identifiers ';'
{ pform_makewire(@1, $4, $3, $5, $2, NetNet::POUTPUT, { list<pair<perm_string,PExpr*> >::const_iterator pp;
IVL_VT_NO_TYPE, 0, SR_BOTH); list<perm_string>*tmp = new list<perm_string>;
for (pp = $5->begin(); pp != $5->end(); pp++) {
tmp->push_back((*pp).first);
}
pform_makewire(@1, $4, $3, tmp, $2, NetNet::POUTPUT,
IVL_VT_NO_TYPE, 0, SR_BOTH);
for (pp = $5->begin(); pp != $5->end(); pp++) {
if ((*pp).second) {
pform_make_reginit(@1, (*pp).first, (*pp).second);
}
}
delete $5;
} }
/* var_type declaration (reg variables) cannot be input or output, /* var_type declaration (reg variables) cannot be input or output,
@ -2124,8 +2267,7 @@ module_item
| K_task automatic_opt IDENTIFIER ';' | K_task automatic_opt IDENTIFIER ';'
{ assert(current_task == 0); { assert(current_task == 0);
current_task = pform_push_task_scope($3, $2); current_task = pform_push_task_scope(@1, $3, $2);
FILE_NAME(current_task, @1);
} }
task_item_list_opt task_item_list_opt
statement_or_null statement_or_null
@ -2137,12 +2279,11 @@ module_item
delete[]$3; delete[]$3;
} }
| K_task automatic_opt IDENTIFIER | K_task automatic_opt IDENTIFIER '('
{ assert(current_task == 0); { assert(current_task == 0);
current_task = pform_push_task_scope($3, $2); current_task = pform_push_task_scope(@1, $3, $2);
FILE_NAME(current_task, @1);
} }
'(' task_port_decl_list ')' ';' task_port_decl_list ')' ';'
block_item_decls_opt block_item_decls_opt
statement_or_null statement_or_null
K_endtask K_endtask
@ -2152,6 +2293,23 @@ module_item
current_task = 0; current_task = 0;
delete[]$3; delete[]$3;
} }
| K_task automatic_opt IDENTIFIER '(' ')' ';'
{ assert(current_task == 0);
current_task = pform_push_task_scope(@1, $3, $2);
}
block_item_decls_opt
statement_or_null
K_endtask
{ current_task->set_ports(0);
current_task->set_statement($9);
pform_pop_scope();
current_task = 0;
cerr << @3 << ": warning: task definition for \"" << $3
<< "\" has an empty port declaration list!" << endl;
delete[]$3;
}
| K_task automatic_opt IDENTIFIER error K_endtask | K_task automatic_opt IDENTIFIER error K_endtask
{ {
pform_pop_scope(); pform_pop_scope();
@ -2166,8 +2324,7 @@ module_item
| K_function automatic_opt function_range_or_type_opt IDENTIFIER ';' | K_function automatic_opt function_range_or_type_opt IDENTIFIER ';'
{ assert(current_function == 0); { assert(current_function == 0);
current_function = pform_push_function_scope($4, $2); current_function = pform_push_function_scope(@1, $4, $2);
FILE_NAME(current_function, @1);
} }
function_item_list statement function_item_list statement
K_endfunction K_endfunction
@ -2181,8 +2338,7 @@ module_item
| K_function automatic_opt function_range_or_type_opt IDENTIFIER | K_function automatic_opt function_range_or_type_opt IDENTIFIER
{ assert(current_function == 0); { assert(current_function == 0);
current_function = pform_push_function_scope($4, $2); current_function = pform_push_function_scope(@1, $4, $2);
FILE_NAME(current_function, @1);
} }
'(' task_port_decl_list ')' ';' '(' task_port_decl_list ')' ';'
block_item_decls_opt block_item_decls_opt
@ -2244,7 +2400,7 @@ module_item
} }
} }
| K_generate K_begin ':' IDENTIFIER { | K_generate K_begin ':' IDENTIFIER {
pform_start_generate_nblock(@1, $4); pform_start_generate_nblock(@2, $4);
} module_item_list_opt K_end K_endgenerate } module_item_list_opt K_end K_endgenerate
{ /* Detect and warn about anachronistic named begin/end use */ { /* Detect and warn about anachronistic named begin/end use */
if (generation_flag > GN_VER2001) { if (generation_flag > GN_VER2001) {
@ -2410,7 +2566,12 @@ net_type
| K_supply1 { $$ = NetNet::SUPPLY1; } | K_supply1 { $$ = NetNet::SUPPLY1; }
| K_wor { $$ = NetNet::WOR; } | K_wor { $$ = NetNet::WOR; }
| K_trior { $$ = NetNet::TRIOR; } | K_trior { $$ = NetNet::TRIOR; }
| K_wone { $$ = NetNet::WONE; } | K_wone { $$ = NetNet::UWIRE;
cerr << @1.text << ":" << @1.first_line << ": warning: "
"'wone' is deprecated, please use 'uwire' "
"instead." << endl;
}
| K_uwire { $$ = NetNet::UWIRE; }
; ;
var_type var_type
@ -3095,10 +3256,20 @@ specify_item
} }
pform_module_specify_path(tmp); pform_module_specify_path(tmp);
} }
| K_Sfullskew '(' spec_reference_event ',' spec_reference_event
',' delay_value ',' delay_value spec_notifier_opt ')' ';'
{ delete $7;
delete $9;
}
| K_Shold '(' spec_reference_event ',' spec_reference_event | K_Shold '(' spec_reference_event ',' spec_reference_event
',' delay_value spec_notifier_opt ')' ';' ',' delay_value spec_notifier_opt ')' ';'
{ delete $7; { delete $7;
} }
| K_Snochange '(' spec_reference_event ',' spec_reference_event
',' delay_value ',' delay_value spec_notifier_opt ')' ';'
{ delete $7;
delete $9;
}
| K_Speriod '(' spec_reference_event ',' delay_value | K_Speriod '(' spec_reference_event ',' delay_value
spec_notifier_opt ')' ';' spec_notifier_opt ')' ';'
{ delete $5; { delete $5;
@ -3107,6 +3278,15 @@ specify_item
',' delay_value spec_notifier_opt ')' ';' ',' delay_value spec_notifier_opt ')' ';'
{ delete $7; { delete $7;
} }
| K_Srecrem '(' spec_reference_event ',' spec_reference_event
',' delay_value ',' delay_value spec_notifier_opt ')' ';'
{ delete $7;
delete $9;
}
| K_Sremoval '(' spec_reference_event ',' spec_reference_event
',' delay_value spec_notifier_opt ')' ';'
{ delete $7;
}
| K_Ssetup '(' spec_reference_event ',' spec_reference_event | K_Ssetup '(' spec_reference_event ',' spec_reference_event
',' delay_value spec_notifier_opt ')' ';' ',' delay_value spec_notifier_opt ')' ';'
{ delete $7; { delete $7;
@ -3116,10 +3296,13 @@ specify_item
{ delete $7; { delete $7;
delete $9; delete $9;
} }
| K_Srecrem '(' spec_reference_event ',' spec_reference_event | K_Sskew '(' spec_reference_event ',' spec_reference_event
',' delay_value ',' delay_value spec_notifier_opt ')' ';' ',' delay_value spec_notifier_opt ')' ';'
{ delete $7;
}
| K_Stimeskew '(' spec_reference_event ',' spec_reference_event
',' delay_value spec_notifier_opt ')' ';'
{ delete $7; { delete $7;
delete $9;
} }
| K_Swidth '(' spec_reference_event ',' delay_value ',' expression | K_Swidth '(' spec_reference_event ',' delay_value ',' expression
spec_notifier_opt ')' ';' spec_notifier_opt ')' ';'
@ -3129,6 +3312,18 @@ specify_item
| K_Swidth '(' spec_reference_event ',' delay_value ')' ';' | K_Swidth '(' spec_reference_event ',' delay_value ')' ';'
{ delete $5; { delete $5;
} }
| K_pulsestyle_onevent specify_path_identifiers ';'
{ delete $2;
}
| K_pulsestyle_ondetect specify_path_identifiers ';'
{ delete $2;
}
| K_showcancelled specify_path_identifiers ';'
{ delete $2;
}
| K_noshowcancelled specify_path_identifiers ';'
{ delete $2;
}
; ;
specify_item_list specify_item_list
@ -3338,15 +3533,22 @@ spec_notifier_opt
; ;
spec_notifier spec_notifier
: ',' : ','
{ } { args_after_notifier = 0; }
| ',' hierarchy_identifier | ',' hierarchy_identifier
{ delete $2; } { args_after_notifier = 0; delete $2; }
| spec_notifier ',' | spec_notifier ','
{ } { args_after_notifier += 1; }
| spec_notifier ',' hierarchy_identifier | spec_notifier ',' hierarchy_identifier
{ delete $3; } { args_after_notifier += 1;
if (args_after_notifier >= 3) {
cerr << @3 << ": warning: timing checks are not supported "
"and delayed signal \"" << *$3
<< "\" will not be driven." << endl;
}
delete $3; }
/* How do we match this path? */
| IDENTIFIER | IDENTIFIER
{ delete[]$1; } { args_after_notifier = 0; delete[]$1; }
; ;

View File

@ -1,7 +1,7 @@
#ifndef __parse_api_H #ifndef __parse_api_H
#define __parse_api_H #define __parse_api_H
/* /*
* 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 * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -46,4 +46,9 @@ extern int pform_parse(const char*path, FILE*file =0);
extern string vl_file; extern string vl_file;
extern void pform_set_timescale(int units, int prec, const char*file,
unsigned lineno);
extern int def_ts_units;
extern int def_ts_prec;
#endif #endif

View File

@ -1,7 +1,7 @@
#ifndef __parse_misc_H #ifndef __parse_misc_H
#define __parse_misc_H #define __parse_misc_H
/* /*
* Copyright (c) 1998-2000 Stephen Williams (steve@icarus.com) * Copyright (c) 1998-2009 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -60,9 +60,15 @@ extern void VLerror(const YYLTYPE&loc, const char*msg);
#define yywarn VLwarn #define yywarn VLwarn
extern void VLwarn(const YYLTYPE&loc, const char*msg); extern void VLwarn(const YYLTYPE&loc, const char*msg);
extern void destroy_lexor();
extern ostream& operator << (ostream&, const YYLTYPE&loc); extern ostream& operator << (ostream&, const YYLTYPE&loc);
extern unsigned error_count, warn_count; extern unsigned error_count, warn_count;
extern unsigned long based_size; extern unsigned long based_size;
extern bool in_celldefine;
enum UCDriveType { UCD_NONE, UCD_PULL0, UCD_PULL1 };
extern UCDriveType uc_drive;
#endif #endif

195
pform.cc
View File

@ -70,11 +70,11 @@ static NetNet::Type pform_default_nettype = NetNet::WIRE;
* These variables track the current time scale, as well as where the * These variables track the current time scale, as well as where the
* timescale was set. This supports warnings about tangled timescales. * timescale was set. This supports warnings about tangled timescales.
*/ */
static int pform_time_unit = 0; static int pform_time_unit;
static int pform_time_prec = 0; static int pform_time_prec;
static char*pform_timescale_file = 0; static char*pform_timescale_file = 0;
static unsigned pform_timescale_line = 0; static unsigned pform_timescale_line;
static inline void FILE_NAME(LineInfo*obj, const char*file, unsigned lineno) static inline void FILE_NAME(LineInfo*obj, const char*file, unsigned lineno)
{ {
@ -103,7 +103,7 @@ void pform_pop_scope()
} }
} }
PTask* pform_push_task_scope(char*name, bool is_auto) PTask* pform_push_task_scope(const struct vlltype&loc, char*name, bool is_auto)
{ {
perm_string task_name = lex_strings.make(name); perm_string task_name = lex_strings.make(name);
@ -111,11 +111,30 @@ PTask* pform_push_task_scope(char*name, bool is_auto)
if (pform_cur_generate) { if (pform_cur_generate) {
task = new PTask(task_name, pform_cur_generate->lexical_scope, task = new PTask(task_name, pform_cur_generate->lexical_scope,
is_auto); is_auto);
FILE_NAME(task, loc);
// Check if the task is already in the dictionary.
if (pform_cur_generate->tasks.find(task->pscope_name()) !=
pform_cur_generate->tasks.end()) {
cerr << task->get_fileline() << ": error: duplicate "
"definition for task '" << name << "' in '"
<< pform_cur_module->mod_name() << "' (generate)."
<< endl;
error_count += 1;
}
pform_cur_generate->tasks[task->pscope_name()] = task; pform_cur_generate->tasks[task->pscope_name()] = task;
pform_cur_generate->lexical_scope = task; pform_cur_generate->lexical_scope = task;
} else { } else {
task = new PTask(task_name, lexical_scope, task = new PTask(task_name, lexical_scope,
is_auto); is_auto);
FILE_NAME(task, loc);
// Check if the task is already in the dictionary.
if (pform_cur_module->tasks.find(task->pscope_name()) !=
pform_cur_module->tasks.end()) {
cerr << task->get_fileline() << ": error: duplicate "
"definition for task '" << name << "' in '"
<< pform_cur_module->mod_name() << "'." << endl;
error_count += 1;
}
pform_cur_module->tasks[task->pscope_name()] = task; pform_cur_module->tasks[task->pscope_name()] = task;
lexical_scope = task; lexical_scope = task;
} }
@ -123,7 +142,8 @@ PTask* pform_push_task_scope(char*name, bool is_auto)
return task; return task;
} }
PFunction* pform_push_function_scope(char*name, bool is_auto) PFunction* pform_push_function_scope(const struct vlltype&loc, char*name,
bool is_auto)
{ {
perm_string func_name = lex_strings.make(name); perm_string func_name = lex_strings.make(name);
@ -131,11 +151,30 @@ PFunction* pform_push_function_scope(char*name, bool is_auto)
if (pform_cur_generate) { if (pform_cur_generate) {
func = new PFunction(func_name, pform_cur_generate->lexical_scope, func = new PFunction(func_name, pform_cur_generate->lexical_scope,
is_auto); is_auto);
FILE_NAME(func, loc);
// Check if the function is already in the dictionary.
if (pform_cur_generate->funcs.find(func->pscope_name()) !=
pform_cur_generate->funcs.end()) {
cerr << func->get_fileline() << ": error: duplicate "
"definition for function '" << name << "' in '"
<< pform_cur_module->mod_name() << "' (generate)."
<< endl;
error_count += 1;
}
pform_cur_generate->funcs[func->pscope_name()] = func; pform_cur_generate->funcs[func->pscope_name()] = func;
pform_cur_generate->lexical_scope = func; pform_cur_generate->lexical_scope = func;
} else { } else {
func = new PFunction(func_name, lexical_scope, func = new PFunction(func_name, lexical_scope,
is_auto); is_auto);
FILE_NAME(func, loc);
// Check if the function is already in the dictionary.
if (pform_cur_module->funcs.find(func->pscope_name()) !=
pform_cur_module->funcs.end()) {
cerr << func->get_fileline() << ": error: duplicate "
"definition for function '" << name << "' in '"
<< pform_cur_module->mod_name() << "'." << endl;
error_count += 1;
}
pform_cur_module->funcs[func->pscope_name()] = func; pform_cur_module->funcs[func->pscope_name()] = func;
lexical_scope = func; lexical_scope = func;
} }
@ -259,10 +298,25 @@ void pform_set_timescale(int unit, int prec,
first_flag = false; first_flag = false;
} }
pform_timescale_file = strdup(file); if (file) pform_timescale_file = strdup(file);
else pform_timescale_file = 0;
pform_timescale_line = lineno; pform_timescale_line = lineno;
if (warn_timescale && first_flag && (pform_modules.size() > 0)) { if (!warn_timescale || !first_flag || !file) return;
/* Look to see if we have any modules without a timescale. */
bool have_no_ts = false;
map<perm_string,Module*>::iterator mod;
for (mod = pform_modules.begin(); mod != pform_modules.end(); mod++) {
const Module*mp = (*mod).second;
if (mp->time_from_timescale ||
mp->timescale_warn_done) continue;
have_no_ts = true;
break;
}
/* If we do then print a message for the new ones. */
if (have_no_ts) {
cerr << file << ":" << lineno << ": warning: " cerr << file << ":" << lineno << ": warning: "
<< "Some modules have no timescale. This may cause" << "Some modules have no timescale. This may cause"
<< endl; << endl;
@ -273,7 +327,10 @@ void pform_set_timescale(int unit, int prec,
map<perm_string,Module*>::iterator mod; map<perm_string,Module*>::iterator mod;
for (mod = pform_modules.begin() for (mod = pform_modules.begin()
; mod != pform_modules.end() ; mod++) { ; mod != pform_modules.end() ; mod++) {
const Module*mp = (*mod).second; Module*mp = (*mod).second;
if (mp->time_from_timescale ||
mp->timescale_warn_done) continue;
mp->timescale_warn_done = true;
cerr << file << ":" << lineno << ": : " cerr << file << ":" << lineno << ": : "
<< " -- module " << (*mod).first << " -- module " << (*mod).first
@ -342,6 +399,9 @@ void pform_startmodule(const char*name, const char*file, unsigned lineno,
pform_cur_module = new Module(lex_name); pform_cur_module = new Module(lex_name);
pform_cur_module->time_unit = pform_time_unit; pform_cur_module->time_unit = pform_time_unit;
pform_cur_module->time_precision = pform_time_prec; pform_cur_module->time_precision = pform_time_prec;
/* If we have a timescale file then the time information is from
* a timescale directive. */
pform_cur_module->time_from_timescale = pform_timescale_file != 0;
pform_cur_module->default_nettype = pform_default_nettype; pform_cur_module->default_nettype = pform_default_nettype;
FILE_NAME(pform_cur_module, file, lineno); FILE_NAME(pform_cur_module, file, lineno);
@ -407,11 +467,14 @@ void pform_module_set_ports(vector<Module::port_t*>*ports)
} }
} }
void pform_endmodule(const char*name) void pform_endmodule(const char*name, bool in_celldefine,
Module::UCDriveType uc_drive)
{ {
assert(pform_cur_module); assert(pform_cur_module);
perm_string mod_name = pform_cur_module->mod_name(); perm_string mod_name = pform_cur_module->mod_name();
assert(strcmp(name, mod_name) == 0); assert(strcmp(name, mod_name) == 0);
pform_cur_module->is_cell = in_celldefine;
pform_cur_module->uc_drive = uc_drive;
map<perm_string,Module*>::const_iterator test = map<perm_string,Module*>::const_iterator test =
pform_modules.find(mod_name); pform_modules.find(mod_name);
@ -434,13 +497,31 @@ void pform_endmodule(const char*name)
pform_cur_module = 0; pform_cur_module = 0;
} }
static void pform_add_genvar(const struct vlltype&li, const perm_string&name,
map<perm_string,LineInfo*>&genvars)
{
LineInfo*lni = new LineInfo();
FILE_NAME(lni, li);
if (genvars.find(name) != genvars.end()) {
cerr << lni->get_fileline() << ": error: genvar '"
<< name << "' has already been declared." << endl;
cerr << genvars[name]->get_fileline()
<< ": the previous declaration is here." << endl;
error_count += 1;
delete lni;
} else {
genvars[name] = lni;
}
}
void pform_genvars(const struct vlltype&li, list<perm_string>*names) void pform_genvars(const struct vlltype&li, list<perm_string>*names)
{ {
list<perm_string>::const_iterator cur; list<perm_string>::const_iterator cur;
for (cur = names->begin(); cur != names->end() ; *cur++) { for (cur = names->begin(); cur != names->end() ; *cur++) {
LineInfo*lni = new LineInfo(); if (pform_cur_generate)
FILE_NAME(lni, li); pform_add_genvar(li, *cur, pform_cur_generate->genvars);
pform_cur_module->genvars[*cur] = lni; else
pform_add_genvar(li, *cur, pform_cur_module->genvars);
} }
delete names; delete names;
@ -455,7 +536,6 @@ void pform_start_generate_for(const struct vlltype&li,
FILE_NAME(gen, li); FILE_NAME(gen, li);
// For now, assume that generates do not nest.
gen->parent = pform_cur_generate; gen->parent = pform_cur_generate;
pform_cur_generate = gen; pform_cur_generate = gen;
@ -476,7 +556,6 @@ void pform_start_generate_if(const struct vlltype&li, PExpr*test)
FILE_NAME(gen, li); FILE_NAME(gen, li);
// For now, assume that generates do not nest.
gen->parent = pform_cur_generate; gen->parent = pform_cur_generate;
pform_cur_generate = gen; pform_cur_generate = gen;
@ -499,7 +578,6 @@ void pform_start_generate_else(const struct vlltype&li)
FILE_NAME(gen, li); FILE_NAME(gen, li);
// For now, assume that generates do not nest.
gen->parent = pform_cur_generate; gen->parent = pform_cur_generate;
pform_cur_generate = gen; pform_cur_generate = gen;
@ -1028,13 +1106,13 @@ static void pform_set_net_range(perm_string name,
if (range == 0) { if (range == 0) {
/* This is the special case that we really mean a /* This is the special case that we really mean a
scalar. Set a fake range. */ scalar. Set a fake range. */
cur->set_range(0, 0, rt); cur->set_range(0, 0, rt, true);
} else { } else {
assert(range->count() == 2); assert(range->count() == 2);
assert((*range)[0]); assert((*range)[0]);
assert((*range)[1]); assert((*range)[1]);
cur->set_range((*range)[0], (*range)[1], rt); cur->set_range((*range)[0], (*range)[1], rt, false);
} }
cur->set_signed(signed_flag); cur->set_signed(signed_flag);
@ -1068,9 +1146,21 @@ void pform_set_net_range(list<perm_string>*names,
*/ */
static void pform_make_event(perm_string name, const char*fn, unsigned ln) static void pform_make_event(perm_string name, const char*fn, unsigned ln)
{ {
LexicalScope*scope = pform_get_cur_scope();
// Check if the named event is already in the dictionary.
if (scope->events.find(name) != scope->events.end()) {
LineInfo tloc;
FILE_NAME(&tloc, fn, ln);
cerr << tloc.get_fileline() << ": error: duplicate definition "
"for named event '" << name << "' in '"
<< pform_cur_module->mod_name() << "'." << endl;
error_count += 1;
}
PEvent*event = new PEvent(name); PEvent*event = new PEvent(name);
FILE_NAME(event, fn, ln); FILE_NAME(event, fn, ln);
pform_get_cur_scope()->events[name] = event; scope->events[name] = event;
} }
void pform_make_events(list<perm_string>*names, const char*fn, unsigned ln) void pform_make_events(list<perm_string>*names, const char*fn, unsigned ln)
@ -1396,14 +1486,16 @@ void pform_module_define_port(const struct vlltype&li,
if (range == 0) { if (range == 0) {
cur->set_range(0, 0, (type == NetNet::IMPLICIT) ? SR_PORT : cur->set_range(0, 0, (type == NetNet::IMPLICIT) ? SR_PORT :
SR_BOTH); SR_BOTH,
true);
} else { } else {
assert(range->count() == 2); assert(range->count() == 2);
assert((*range)[0]); assert((*range)[0]);
assert((*range)[1]); assert((*range)[1]);
cur->set_range((*range)[0], (*range)[1], cur->set_range((*range)[0], (*range)[1],
(type == NetNet::IMPLICIT) ? SR_PORT : SR_BOTH); (type == NetNet::IMPLICIT) ? SR_PORT : SR_BOTH,
false);
} }
if (attr) { if (attr) {
@ -1483,7 +1575,7 @@ void pform_makewire(const vlltype&li, perm_string name,
<< " to " << dt << "." << endl; << " to " << dt << "." << endl;
} }
ivl_assert(*cur, flag); ivl_assert(*cur, flag);
cur->set_range(0, 0, SR_NET); cur->set_range(0, 0, SR_NET, true);
cur->set_signed(true); cur->set_signed(true);
break; break;
default: default:
@ -1673,7 +1765,7 @@ svector<PWire*>*pform_make_task_ports(NetNet::PortType pt,
/* If there is a range involved, it needs to be set. */ /* If there is a range involved, it needs to be set. */
if (range) if (range)
curw->set_range((*range)[0], (*range)[1], SR_PORT); curw->set_range((*range)[0], (*range)[1], SR_PORT, false);
svector<PWire*>*tmp = new svector<PWire*>(*res, curw); svector<PWire*>*tmp = new svector<PWire*>(*res, curw);
@ -1763,13 +1855,32 @@ void pform_set_parameter(const struct vlltype&loc,
bool signed_flag, svector<PExpr*>*range, PExpr*expr, bool signed_flag, svector<PExpr*>*range, PExpr*expr,
LexicalScope::range_t*value_range) LexicalScope::range_t*value_range)
{ {
if (pform_get_cur_scope() == pform_cur_generate) { LexicalScope*scope = pform_get_cur_scope();
if (scope == pform_cur_generate) {
VLerror("parameter declarations are not permitted in generate blocks"); VLerror("parameter declarations are not permitted in generate blocks");
return; return;
} }
// Check if the parameter name is already in the dictionary.
if (scope->parameters.find(name) != scope->parameters.end()) {
LineInfo tloc;
FILE_NAME(&tloc, loc);
cerr << tloc.get_fileline() << ": error: duplicate definition "
"for parameter '" << name << "' in '"
<< pform_cur_module->mod_name() << "'." << endl;
error_count += 1;
}
if (scope->localparams.find(name) != scope->localparams.end()) {
LineInfo tloc;
FILE_NAME(&tloc, loc);
cerr << tloc.get_fileline() << ": error: localparam and "
"parameter in '" << pform_cur_module->mod_name()
<< "' have the same name '" << name << "'." << endl;
error_count += 1;
}
assert(expr); assert(expr);
Module::param_expr_t&parm = pform_get_cur_scope()->parameters[name]; Module::param_expr_t&parm = scope->parameters[name];
FILE_NAME(&parm, loc); FILE_NAME(&parm, loc);
parm.expr = expr; parm.expr = expr;
@ -1788,7 +1899,7 @@ void pform_set_parameter(const struct vlltype&loc,
parm.signed_flag = signed_flag; parm.signed_flag = signed_flag;
parm.range = value_range; parm.range = value_range;
if (pform_get_cur_scope() == pform_cur_module) if (scope == pform_cur_module)
pform_cur_module->param_names.push_back(name); pform_cur_module->param_names.push_back(name);
} }
@ -1796,6 +1907,26 @@ void pform_set_localparam(const struct vlltype&loc,
perm_string name, ivl_variable_type_t type, perm_string name, ivl_variable_type_t type,
bool signed_flag, svector<PExpr*>*range, PExpr*expr) bool signed_flag, svector<PExpr*>*range, PExpr*expr)
{ {
LexicalScope*scope = pform_get_cur_scope();
// Check if the localparam name is already in the dictionary.
if (scope->localparams.find(name) != scope->localparams.end()) {
LineInfo tloc;
FILE_NAME(&tloc, loc);
cerr << tloc.get_fileline() << ": error: duplicate definition "
"for localparam '" << name << "' in '"
<< pform_cur_module->mod_name() << "'." << endl;
error_count += 1;
}
if (scope->parameters.find(name) != scope->parameters.end()) {
LineInfo tloc;
FILE_NAME(&tloc, loc);
cerr << tloc.get_fileline() << ": error: parameter and "
"localparam in '" << pform_cur_module->mod_name()
<< "' have the same name '" << name << "'." << endl;
error_count += 1;
}
assert(expr); assert(expr);
Module::param_expr_t&parm = pform_get_cur_scope()->localparams[name]; Module::param_expr_t&parm = pform_get_cur_scope()->localparams[name];
FILE_NAME(&parm, loc); FILE_NAME(&parm, loc);
@ -1819,6 +1950,15 @@ void pform_set_localparam(const struct vlltype&loc,
void pform_set_specparam(perm_string name, PExpr*expr) void pform_set_specparam(perm_string name, PExpr*expr)
{ {
// Check if the specparam name is already in the dictionary.
if (pform_cur_module->specparams.find(name) !=
pform_cur_module->specparams.end()) {
cerr << expr->get_fileline() << ": error: duplicate definition "
"for specparam '" << name << "' in '"
<< pform_cur_module->mod_name() << "'." << endl;
error_count += 1;
}
assert(expr); assert(expr);
pform_cur_module->specparams[name] = expr; pform_cur_module->specparams[name] = expr;
} }
@ -1933,7 +2073,7 @@ static void pform_set_reg_integer(perm_string name)
cur->set_range(new PENumber(new verinum(integer_width-1, integer_width)), cur->set_range(new PENumber(new verinum(integer_width-1, integer_width)),
new PENumber(new verinum((uint64_t)0, integer_width)), new PENumber(new verinum((uint64_t)0, integer_width)),
SR_NET); SR_NET, false);
cur->set_signed(true); cur->set_signed(true);
} }
@ -1964,7 +2104,7 @@ static void pform_set_reg_time(perm_string name)
cur->set_range(new PENumber(new verinum(TIME_WIDTH-1, integer_width)), cur->set_range(new PENumber(new verinum(TIME_WIDTH-1, integer_width)),
new PENumber(new verinum((uint64_t)0, integer_width)), new PENumber(new verinum((uint64_t)0, integer_width)),
SR_NET); SR_NET, false);
} }
void pform_set_reg_time(list<perm_string>*names) void pform_set_reg_time(list<perm_string>*names)
@ -2045,6 +2185,7 @@ int pform_parse(const char*path, FILE*file)
error_count += 1; error_count += 1;
} }
destroy_lexor();
return error_count; return error_count;
} }

13
pform.h
View File

@ -1,7 +1,7 @@
#ifndef __pform_H #ifndef __pform_H
#define __pform_H #define __pform_H
/* /*
* Copyright (c) 1998-2008 Stephen Williams (steve@icarus.com) * Copyright (c) 1998-2009 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -159,7 +159,8 @@ extern void pform_module_define_port(const struct vlltype&li,
extern Module::port_t* pform_module_port_reference(perm_string name, extern Module::port_t* pform_module_port_reference(perm_string name,
const char*file, const char*file,
unsigned lineno); unsigned lineno);
extern void pform_endmodule(const char*); extern void pform_endmodule(const char*, bool in_celldefine,
Module::UCDriveType uc_drive);
extern void pform_make_udp(perm_string name, list<perm_string>*parms, extern void pform_make_udp(perm_string name, list<perm_string>*parms,
svector<PWire*>*decl, list<string>*table, svector<PWire*>*decl, list<string>*table,
@ -180,8 +181,10 @@ extern void pform_make_udp(perm_string name,
*/ */
extern void pform_pop_scope(); extern void pform_pop_scope();
extern PTask*pform_push_task_scope(char*name, bool is_auto); extern PTask*pform_push_task_scope(const struct vlltype&loc, char*name,
extern PFunction*pform_push_function_scope(char*name, bool is_auto); bool is_auto);
extern PFunction*pform_push_function_scope(const struct vlltype&loc, char*name,
bool is_auto);
extern PBlock*pform_push_block_scope(char*name, PBlock::BL_TYPE tt); extern PBlock*pform_push_block_scope(char*name, PBlock::BL_TYPE tt);
extern void pform_put_behavior_in_scope(AProcess*proc); extern void pform_put_behavior_in_scope(AProcess*proc);
@ -191,7 +194,7 @@ extern verinum* pform_verinum_with_size(verinum*s, verinum*val,
/* /*
* This function takes the list of names as new genvars to declare in * This function takes the list of names as new genvars to declare in
* the current module scope. * the current module or generate scope.
*/ */
extern void pform_genvars(const struct vlltype&li, list<perm_string>*names); extern void pform_genvars(const struct vlltype&li, list<perm_string>*names);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1998-2008 Stephen Williams (steve@icarus.com) * Copyright (c) 1998-2009 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -410,6 +410,8 @@ void PDelays::dump_delays(ostream&out) const
if (delay_[0] && delay_[1] && delay_[2]) if (delay_[0] && delay_[1] && delay_[2])
out << "#(" << *delay_[0] << "," << *delay_[1] << "," << out << "#(" << *delay_[0] << "," << *delay_[1] << "," <<
*delay_[2] << ")"; *delay_[2] << ")";
else if (delay_[0] && delay_[1])
out << "#(" << *delay_[0] << "," << *delay_[1] << ")";
else if (delay_[0]) else if (delay_[0])
out << "#" << *delay_[0]; out << "#" << *delay_[0];
else else
@ -1032,6 +1034,12 @@ void PGenerate::dump(ostream&out, unsigned indent) const
(*idx)->dump(out, indent+2); (*idx)->dump(out, indent+2);
} }
typedef map<perm_string,LineInfo*>::const_iterator genvar_iter_t;
for (genvar_iter_t cur = genvars.begin()
; cur != genvars.end() ; cur++) {
out << setw(indent+2) << "" << "genvar " << ((*cur).first) << ";" << endl;
}
for (list<PGenerate*>::const_iterator idx = generate_schemes.begin() for (list<PGenerate*>::const_iterator idx = generate_schemes.begin()
; idx != generate_schemes.end() ; idx++) { ; idx != generate_schemes.end() ; idx++) {
(*idx)->dump(out, indent+2); (*idx)->dump(out, indent+2);
@ -1147,7 +1155,9 @@ void Module::dump(ostream&out) const
out << " *) "; out << " *) ";
} }
out << "module " << mod_name() << ";" << endl; out << "module " << mod_name() << ";";
if (is_cell) out << " // Is in `celldefine.";
out << endl;
for (unsigned idx = 0 ; idx < ports.size() ; idx += 1) { for (unsigned idx = 0 ; idx < ports.size() ; idx += 1) {
port_t*cur = ports[idx]; port_t*cur = ports[idx];

View File

@ -10,4 +10,6 @@
echo "Building version_tag.h with git describe" echo "Building version_tag.h with git describe"
tmp=`git describe | sed -e 's;\(.*\);#define VERSION_TAG "\1";'` tmp=`git describe | sed -e 's;\(.*\);#define VERSION_TAG "\1";'`
echo "$tmp" > version_tag.h echo "#ifndef VERSION_TAG" > version_tag.h
echo "$tmp" >> version_tag.h
echo "#endif" >> version_tag.h

67
scripts/MAKE_RELEASE.sh Normal file
View File

@ -0,0 +1,67 @@
#!/bin/sh
# This script makes a release from a git repository. The input is
# the number for a snapshot and the path to a temporary directory.
# for example:
#
# sh scripts/MAKE_RELEASE.sh 0.9.1 ~/tmp
#
# The above assumes that there is a tag "v0_9_1" at the point
# to be released. (The tag has the "v", but the argument to this
# script does not have the "v"). This script extracts based on the
# tag, uses the temporary directory to stage intermediate results,
# and finally creates a file called verilog-0.9.1.tar.gz that
# contains the release ready to go.
#
# The complete steps to make a release x.y.z generally are:
#
# (Edit version_base.h and verilog.spec to reflect the version)
#
# git tag -a v0_9_1
# (Make the tag in the local git repository.)
#
# sh scripts/MAKE_RELEASE.sh 0.9.1 ~/tmp
# (Make the snapshot bundle verilog-0.9.1.tar.gz)
#
# git push --tags
# (Publish the tag to the repository.)
#
id=$1
destdir=$2
# The git tag to use.
tag="v"`echo $id | tr '.' '_'`
# The prefix is the directory that contains the extracted files
# of the bundle. This is also the name of the bundle file itself.
prefix="verilog-$id"
if [ ! -d $destdir ]; then
echo "ERROR: Directory $destdir does not exist."
exit 1
fi
if [ -e $destdir/$prefix ]; then
echo "ERROR: $destdir/$prefix already exists."
exit 1
fi
echo "Exporting $tag to $destdir/$prefix..."
git archive --prefix="$prefix/" $tag | ( cd "$destdir" && tar xf - )
versionh="$destdir/$prefix/version_tag.h"
echo "Create $versionh ..."
echo "#ifndef VERSION_TAG" > $versionh
echo "#define VERSION_TAG \"$tag\"" >> $versionh
echo "#endif" >> $versionh
echo "Running autoconf.sh..."
( cd $destdir/$prefix && sh autoconf.sh )
echo "Making bundle $prefix.tar.gz..."
tar czf $prefix.tar.gz --exclude=autom4te.cache -C "$destdir" $prefix
echo "Removing temporary $destdir/$prefix..."
rm -rf "$destdir/$prefix"
echo done

View File

@ -47,9 +47,11 @@ fi
echo "Exporting $tag to $destdir/$prefix..." echo "Exporting $tag to $destdir/$prefix..."
git archive --prefix="$prefix/" $tag | ( cd "$destdir" && tar xf - ) git archive --prefix="$prefix/" $tag | ( cd "$destdir" && tar xf - )
versionh="$destdir/$prefix/version.h" versionh="$destdir/$prefix/version_tag.h"
echo "Create $versionh ..." echo "Create $versionh ..."
echo "#define VERSION_TAG \"$tag\"" > $versionh echo "#ifndef VERSION_TAG" > $versionh
echo "#define VERSION_TAG \"$tag\"" >> $versionh
echo "#endif" >> $versionh
echo "Running autoconf.sh..." echo "Running autoconf.sh..."
( cd $destdir/$prefix && sh autoconf.sh ) ( cd $destdir/$prefix && sh autoconf.sh )

View File

@ -106,6 +106,18 @@ bool NetEBAdd::set_width(unsigned w, bool)
return wid == w; return wid == w;
} }
void NetEBAdd::cast_signed(bool sign_flag)
{
if (has_sign() == sign_flag)
return;
if (sign_flag == false) {
left_->cast_signed(sign_flag);
right_->cast_signed(sign_flag);
}
cast_signed_base_(sign_flag);
}
/* /*
* The bitwise logical operators have operands the same size as the * The bitwise logical operators have operands the same size as the
* result. Anything else is a mess. I first try to get the operands to * result. Anything else is a mess. I first try to get the operands to
@ -168,6 +180,19 @@ bool NetEBDiv::set_width(unsigned w, bool)
return w == expr_width(); return w == expr_width();
} }
void NetEBDiv::cast_signed(bool sign_flag)
{
if (has_sign() == sign_flag)
return;
if (sign_flag == false) {
left_->cast_signed(sign_flag);
right_->cast_signed(sign_flag);
}
cast_signed_base_(sign_flag);
}
bool NetEBLogic::set_width(unsigned w, bool) bool NetEBLogic::set_width(unsigned w, bool)
{ {
bool flag; bool flag;
@ -192,6 +217,19 @@ bool NetEBMult::set_width(unsigned w, bool)
return true; return true;
} }
void NetEBMult::cast_signed(bool sign_flag)
{
if (has_sign() == sign_flag)
return;
if (sign_flag == false) {
left_->cast_signed(sign_flag);
right_->cast_signed(sign_flag);
}
cast_signed_base_(sign_flag);
}
bool NetEBPow::set_width(unsigned w, bool last_chance) bool NetEBPow::set_width(unsigned w, bool last_chance)
{ {
return w == expr_width(); return w == expr_width();

View File

@ -1,5 +1,3 @@
# $Id: README-solaris_pkg.txt,v 1.3 2007/02/26 19:49:49 steve Exp $
Notes about the solaris package. Notes about the solaris package.
I. Installing a prebuilt solaris package I. Installing a prebuilt solaris package

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2004-2008 Stephen Williams (steve@icarus.com) * Copyright (c) 2004-2009 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -46,6 +46,16 @@ struct sfunc_return_type_cell : sfunc_return_type {
static struct sfunc_return_type_cell*sfunc_stack = 0; static struct sfunc_return_type_cell*sfunc_stack = 0;
void cleanup_sys_func_table()
{
struct sfunc_return_type_cell *next, *cur = sfunc_stack;
while (cur) {
next = cur->next;
delete cur;
cur = next;
}
}
const struct sfunc_return_type* lookup_sys_func(const char*name) const struct sfunc_return_type* lookup_sys_func(const char*name)
{ {
/* First, try to find then name in the function stack. */ /* First, try to find then name in the function stack. */
@ -186,7 +196,7 @@ int load_sys_func_table(const char*path)
fprintf(stderr, "%s:%s: Unknown type: %s\n", fprintf(stderr, "%s:%s: Unknown type: %s\n",
path, name, stype); path, name, stype);
} }
fclose(fd);
return 0; return 0;
} }

View File

@ -545,6 +545,8 @@ extern "C" unsigned long ivl_expr_uvalue(ivl_expr_t net)
assert(0); assert(0);
} }
assert(0);
return 0;
} }
extern "C" ivl_variable_type_t ivl_expr_value(ivl_expr_t net) extern "C" ivl_variable_type_t ivl_expr_value(ivl_expr_t net)
@ -1268,6 +1270,8 @@ extern "C" unsigned ivl_lpm_size(ivl_lpm_t net)
return net->u_.ufunc.ports - 1; return net->u_.ufunc.ports - 1;
case IVL_LPM_REPEAT: case IVL_LPM_REPEAT:
return net->u_.repeat.count; return net->u_.repeat.count;
case IVL_LPM_CONCAT:
return net->u_.concat.inputs;
default: default:
assert(0); assert(0);
return 0; return 0;
@ -1655,6 +1659,12 @@ extern "C" unsigned ivl_scope_is_auto(ivl_scope_t net)
return net->is_auto; return net->is_auto;
} }
extern "C" unsigned ivl_scope_is_cell(ivl_scope_t net)
{
assert(net);
return net->is_cell;
}
extern "C" unsigned ivl_scope_lineno(ivl_scope_t net) extern "C" unsigned ivl_scope_lineno(ivl_scope_t net)
{ {
assert(net); assert(net);
@ -1893,10 +1903,17 @@ extern "C" const char* ivl_signal_name(ivl_signal_t net)
extern "C" ivl_nexus_t ivl_signal_nex(ivl_signal_t net, unsigned word) extern "C" ivl_nexus_t ivl_signal_nex(ivl_signal_t net, unsigned word)
{ {
assert(word < net->array_words); assert(word < net->array_words);
if (net->array_words > 1) if (net->array_words > 1) {
return net->pins[word]; if (net->pins) {
else return net->pins[word];
} else {
// net->pins can be NULL for a virtualized reg array.
assert(net->type_ == IVL_SIT_REG);
return NULL;
}
} else {
return net->pin; return net->pin;
}
} }
extern "C" int ivl_signal_msb(ivl_signal_t net) extern "C" int ivl_signal_msb(ivl_signal_t net)

View File

@ -199,7 +199,7 @@ void dll_target::expr_concat(const NetEConcat*net)
cur->type_ = IVL_EX_CONCAT; cur->type_ = IVL_EX_CONCAT;
cur->value_ = IVL_VT_VECTOR; cur->value_ = IVL_VT_VECTOR;
cur->width_ = net->expr_width(); cur->width_ = net->expr_width();
cur->signed_ = 0; cur->signed_ = net->has_sign() ? 1 : 0;
cur->u_.concat_.rept = net->repeat(); cur->u_.concat_.rept = net->repeat();
cur->u_.concat_.parms = net->nparms(); cur->u_.concat_.parms = net->nparms();
@ -308,6 +308,7 @@ void dll_target::expr_event(const NetEEvent*net)
assert(expr_); assert(expr_);
expr_->type_ = IVL_EX_EVENT; expr_->type_ = IVL_EX_EVENT;
FILE_NAME(expr_, net);
expr_->value_= IVL_VT_VOID; expr_->value_= IVL_VT_VOID;
/* Locate the event by name. Save the ivl_event_t in the /* Locate the event by name. Save the ivl_event_t in the
@ -351,6 +352,7 @@ void dll_target::expr_select(const NetESelect*net)
expr_ = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s)); expr_ = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s));
assert(expr_); assert(expr_);
FILE_NAME(expr_, net);
expr_->type_ = IVL_EX_SELECT; expr_->type_ = IVL_EX_SELECT;
expr_->value_= IVL_VT_VECTOR; expr_->value_= IVL_VT_VECTOR;
@ -450,10 +452,10 @@ void dll_target::expr_signal(const NetESignal*net)
/* Make account for the special case that this is a reference /* Make account for the special case that this is a reference
to an array as a whole. We detect this case by noting that to an array as a whole. We detect this case by noting that
this is an array (more than 1 word) and there is no word this is an array (more than 0 array dimensions) and that
select expression. In that case, this is an IVL_EX_ARRAY there is no word select expression. For this case, we have
expression instead of a SIGNAL expression. */ an IVL_EX_ARRAY expression instead of a SIGNAL expression. */
if (sig->array_words > 1 && word_expr == 0) { if (sig->array_dimensions_ > 0 && word_expr == 0) {
expr_->type_ = IVL_EX_ARRAY; expr_->type_ = IVL_EX_ARRAY;
expr_->width_ = 0; // Doesn't make much sense for arrays. expr_->width_ = 0; // Doesn't make much sense for arrays.
} }

View File

@ -46,7 +46,6 @@ inline ivl_dll_t ivl_dlopen(const char *name)
inline void * ivl_dlsym(ivl_dll_t dll, const char *nm) inline void * ivl_dlsym(ivl_dll_t dll, const char *nm)
{ {
FARPROC sym;
return (void*)GetProcAddress((HMODULE)dll, nm); return (void*)GetProcAddress((HMODULE)dll, nm);
} }
@ -2147,13 +2146,18 @@ bool dll_target::part_select(const NetPartSelect*net)
obj->type = IVL_LPM_PART_PV; obj->type = IVL_LPM_PART_PV;
break; break;
} }
FILE_NAME(obj, net);
obj->name = net->name(); // NetPartSelect names are permallocated. obj->name = net->name(); // NetPartSelect names are permallocated.
assert(net->scope()); assert(net->scope());
obj->scope = find_scope(des_, net->scope()); obj->scope = find_scope(des_, net->scope());
assert(obj->scope); assert(obj->scope);
/* Part selects are always unsigned. */ /* Part selects are always unsigned, so we use this to indicate
obj->u_.part.signed_flag = 0; * if the part select base signal is signed or not. */
if (net->signed_flag())
obj->u_.part.signed_flag = 1;
else
obj->u_.part.signed_flag = 0;
/* Choose the width of the part select. */ /* Choose the width of the part select. */
obj->width = net->width(); obj->width = net->width();
@ -2389,6 +2393,7 @@ void dll_target::scope(const NetScope*net)
scop->nattr = net->attr_cnt(); scop->nattr = net->attr_cnt();
scop->attr = fill_in_attributes(net); scop->attr = fill_in_attributes(net);
scop->is_auto = net->is_auto(); scop->is_auto = net->is_auto();
scop->is_cell = net->is_cell();
switch (net->type()) { switch (net->type()) {
case NetScope::MODULE: case NetScope::MODULE:
@ -2510,6 +2515,10 @@ void dll_target::signal(const NetNet*net)
assert(0); assert(0);
break; break;
case NetNet::UWIRE:
cerr << net->get_fileline()
<< ": warning: uwire is not currently supported, converting "
"it to a wire!" << endl;
case NetNet::TRI: case NetNet::TRI:
case NetNet::WIRE: case NetNet::WIRE:
case NetNet::IMPLICIT: case NetNet::IMPLICIT:
@ -2560,12 +2569,22 @@ void dll_target::signal(const NetNet*net)
obj->array_base = net->array_first(); obj->array_base = net->array_first();
obj->array_words = net->array_count(); obj->array_words = net->array_count();
obj->array_addr_swapped = net->array_addr_swapped() ? 1 : 0; obj->array_addr_swapped = net->array_addr_swapped() ? 1 : 0;
assert(obj->array_words == net->pin_count());
if (debug_optimizer && obj->array_words > 1000) cerr << "debug: "
"t-dll creating nexus array " << obj->array_words << " long" << endl;
if (obj->array_words > 1 && net->pins_are_virtual()) {
obj->pins = NULL;
if (debug_optimizer && obj->array_words > 1000) cerr << "debug: "
"t-dll used NULL for big nexus array" << endl;
return;
}
if (obj->array_words > 1) if (obj->array_words > 1)
obj->pins = new ivl_nexus_t[obj->array_words]; obj->pins = new ivl_nexus_t[obj->array_words];
for (unsigned idx = 0 ; idx < obj->array_words ; idx += 1) { for (unsigned idx = 0 ; idx < obj->array_words ; idx += 1) {
const Nexus*nex = net->pin(idx).nexus(); const Nexus*nex = net->pins_are_virtual() ? 0 : net->pin(idx).nexus();
if (nex == 0) { if (nex == 0) {
// Special case: This pin is connected to // Special case: This pin is connected to
// nothing. This can happen, for example, if the // nothing. This can happen, for example, if the
@ -2597,6 +2616,7 @@ void dll_target::signal(const NetNet*net)
obj->pin = tmp; obj->pin = tmp;
} }
} }
if (debug_optimizer && obj->array_words > 1000) cerr << "debug: t-dll done with big nexus array" << endl;
} }
bool dll_target::signal_paths(const NetNet*net) bool dll_target::signal_paths(const NetNet*net)

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