Compare commits

..
272 Commits
Author SHA1 Message Date
Cary R 0e4dfa6732 Fix some compile warnings when using more modern compilers 2015-08-19 11:20:57 -07:00
Cary R 66b4843987 V0.8: Fix autoconf warning.
This just copies the same change that was done for development over to V0.8.
2011-11-23 10:48:42 -08:00
Cary R 4dee700ca5 V0.8: Add #! support for MinGW since newer shells support this. 2011-03-15 18:59:29 -07:00
Cary R 32e30f2d5b V0.8: Fix cleanup and cygwin out of source building
This patch adds a few missing files to clean/distclean and also
fixes the out of source directory building for cygwin/MinGW.
2011-03-14 16:56:03 -07:00
Cary R ac8fddfa01 V0.8: Update Makefile.in files to support cygwin compile.
Update the various Makefile.in files to support compiling in the source
directory with cygwin using a suffix (default).
2011-03-14 16:55:56 -07:00
Cary R 9aa80965bd V0.8: Remove more space issues. 2011-03-08 19:13:14 -08:00
Larry Doolittle ec0c4343e8 Drop trailing spaces
There weren't that many
2011-03-04 17:47:59 -08:00
Larry Doolittle 76103f2167 Spelling fixes
Mostly comments, but a few format strings
2011-03-04 17:46:57 -08:00
Larry Doolittle 09664bc52e Propagate default CFLAGS into vvp Makefile 2011-03-04 10:39:35 -08:00
Cary R 3f0e1bacc1 V0.8: Reduce synthesized DFF pessimism.
This patch updates the DFF UDP to have less pessimism.
2011-01-12 16:28:58 -08:00
Cary R 11fa67ebbe V0.8: rework latch synthesis and warn that async. set/clear are missing.
This patch reworks the latch synthesis that Alan submitted to be
more in line with the rest of the code and simplified it in a
few places. It also adds a warning that we do not currently
support synthesizing asynchronous set/clear signals for a latch.
2011-01-12 16:26:39 -08:00
Cary R 14926e7ce0 V0.8: Fail if both an LPM/wire and a reg drive a nexus.
In synthesis we transform registers into wires, but if there is bad
Verilog code where the register is written from non-synthesized code
then we can't do this! This patch adds a check in the code generator
for this and prints a error message instead of generating a .resolv
to combine the two, which is certainly not correct.
2011-01-12 16:24:50 -08:00
Cary R 34661e9af5 V0.8: Rework the NetLatch and back end code.
This patch reworks the NetLatch class to better match the NetFF class
(e.g. it adds a place for the async controls and value, adds a dump
routine, etc.) and moves it into the normal netlist.{h,cc} files. It
removes the unused Aload and Sload routines, etc. from the NetFF class.
It switches the latch to use the existing ff object to pass information
to the target and uses the existing FF routines as applicable.

ivl_lpm_async_clr()
ivl_lpm_async_set()
ivl_lpm_aset_value()
ivl_lpm_clk() for the gate
ivl_lpm_data()
ivl_lpm_q()

It adds support for generating a latch UDP just like is done for the
D flip-flop in the tgt-vvp code generator and fixes a bug in the
generation of the clear signal when both the Aclr and Aset signals
clear the register.
2011-01-12 16:19:32 -08:00
Cary R 678dd7bdaa V0.8: Add support for negedge FF and Aclr/Aset both clear.
This patch fixes the bugs reported in pr1757438. These are fpga/edif
code generation bugs. For a DFF we need to add an inverter for a
negedge device and if both the Aclr and Aset signals clear the FF
we need to create the OR of these signals to drive the Aclr pin.
2011-01-12 16:17:13 -08:00
Cary R 3a162ea69f V0.8: Fix dffsynth code generation bug.
If both the async. clr and set pins clear a flip-flop then we need to
create an OR gate to combine the two signals to connect to the single
DFF clr pin. This patch fixes the tgt-vvp code generator to implement
this functionality.
2011-01-12 16:14:52 -08:00
Cary R 5f3e5f6b35 V0.8: add a warning that a latch primitive is not supported.
At the moment a latch primitive is not supported by vvp.
2011-01-12 15:55:09 -08:00
Cary R 3cc12e8446 V0.8: Update PLI_BYTE definition.
The standard defines this as char not signed char. Using signed char was
causing some compiler warnings in the vpi tests with modern compilers.
2011-01-12 15:52:49 -08:00
Cary R 9bab275716 V0.8: Remove some more compile warnings.
This patch removes some more compile warnings when compiling using
the default gcc compiler for Ubuntu-10.10.
2011-01-12 15:52:32 -08:00
Cary R ae14a58bff V0.8: Remove deprecated #ident and fix some other compile warnings
This patch removes #ident since it is deprecated in recent gcc
versions. It also removes all the CVS comments and fixes a few
other compilation warnings. There are still a few compilation
warnings, but this takes care of most of them. Fixing the rest
will require a bit more thought.
2011-01-12 15:49:03 -08:00
Alan M. Feldstein 5b9a72dbbf Add -h option to usage output. 2010-11-25 09:24:18 -08:00
Alan M. Feldstein bd9923dbbd latch synthesis fix: Connect gate pin in netlist. 2010-11-25 09:21:46 -08:00
Cary R 35c68d8c58 V0.8: Ignore system tasks/functions NULL arguments in @* calculation.
System tasks and functions can be defined to have NULL arguments.
This patch makes the @* sensitivity list calculation skip these
NULL (constant) arguments.
2010-11-25 09:15:11 -08:00
Alan M. Feldstein 867c864132 Use appropriate makefile dependencies option for Sun Studio 12 C++ compiler. 2010-01-25 15:53:56 -08:00
Alan M. Feldstein b6e6225d81 Not all C++ compilers recognize (or need) -Wall. 2010-01-25 15:51:53 -08:00
Alan M. Feldstein 80ef9522dd Not all C compilers recognize (or need) -Wall. 2010-01-25 15:48:28 -08:00
Cary R 90d65ae48f Format the --enable-suffix help correctly.
(Cherry-picked from 537ba93fe4)
2009-10-08 16:49:33 -07:00
Stephen Williams 95a0face2b Minor portability fixes from Alan Feldstein. 2009-08-21 15:35:44 -07:00
Cary R c88583264c V0.8 add .gitignore file
Add a .gitignore file like V0.9 and development have. This is
a slightly modified version to match V0.8.
2009-08-02 11:13:58 -07:00
Cary R 89bcbc75d3 V0.8: Remove check for ivl in driver/main.c
This check could be useful, but it was making make check fail
since it was before base was redefined by -B. This check is
not in V0.9, so it was easier to just remove it from V0.8. This
would only happen if <path>/lib/ivl-0.8/ivl did not already
exist (on a pristine system).
2009-07-06 15:22:53 -07:00
Stephen Williams cfd0162176 Remove CVS .cvsignore files.
We are in git now. We don't want these files, they
are just clutter, especially in packages.
2009-01-02 15:59:34 -08:00
Werner Hoch e4df6f7966 Add missing DESTDIR to the Makefiles 2009-01-02 15:28:53 -08:00
Jared Casper 3e39109b0e Compatibility with gcc-4.3
Using auto_ptr in elab_net.cc (added in commit 15702f1, "Fix bad
memory reference." on 2008-11-28) requires #include <memory> when
compiling with gcc-4.3.
2008-12-12 07:41:16 -08:00
Cary R 27be6e88bc V0.8: backport of check primitive port count code.
This patch backports from multiple places checks that verify
that the various primitives are given the correct number of
port expressions.
2008-12-09 19:21:48 -08:00
Cary R 918b0a410f V0.8: backport $random fix.
Back port a $random fix from development.
2008-12-09 15:43:28 -08:00
Stephen Williams ec85377d13 Prepare for 0.8.7 release. 2008-12-09 09:47:42 -08:00
Cary R a22124a198 V0.8: Mostly back port the version checking code from development.
This is a back port from development of the code to put and check
that the vvp input file is the right version. It also adds the -V
flag to vvp. It does not add the VERSION_TAG information so will
only produce the single string ivl_version tag. The runtime will
read both forms since if it is feed a V0.9 file we want it to
complain nicely (no syntax error). To change the displayed version
for the various programs and checks change version.h.
2008-12-05 22:01:13 -08:00
Cary R e8bc5aefb4 V0.8: Get arrayed instance ports correct.
This is a back port from development of the code to get the
arrayed instance port order correct (MSB to LSB).
2008-12-05 21:57:57 -08:00
Cary R ca5d265350 V0.8: left shift of integer value needs to use integer size
This is a back port from development of the code to resize an
unsized constant value to 32 bits. Development used integer_width,
but that is not supported in V0.8. Development also supports using
the expression width which V0.8 does not.
2008-12-05 21:54:59 -08:00
Cary R 113312a0c1 V0.8: do not schedule function calls.
This patch mirrors what was done in development to force a function
call to be run immediately.
2008-11-28 10:16:23 -08:00
Cary R 12d5aa08e2 V0.8: A $signed can make a concat signed.
This patch mirrors what was done in development to fix the
signed concat problem.
2008-11-28 10:12:11 -08:00
Stephen Williams 15702f1b87 Fix bad memory reference.
The expression for the repeat expression was deleted before the
tests for expression sanity.
2008-11-28 10:00:57 -08:00
Stephen Williams 9b5ef0bbb9 Checkin some developer convenience scripts. 2008-11-28 09:32:22 -08:00
Cary R b8d9f19eb0 Use MOS instead of bufif devices for mux optimization.
This patch mirrors what was done in development to fix the mux
with one input as Z optimization. It should use a MOS device
instead of a bufif device.
2008-11-28 09:16:21 -08:00
Cary R 8d9f7e2e26 Include directory should be 0.8 not 0.0.
The include directory had the wrong version.
2008-11-28 09:11:58 -08:00
Stephen Williams 65326fd6a9 Put header files in include/iverilog dir.
The include/verilog directory is a bit too
generic. Use the include/iverilog dir instead.
2008-11-25 16:29:30 -08:00
Cary R bb92974839 V0.8: Fail on a zero width repeat
This patch mirrors what was done in development to fail for zero
width repeats. Actually development supports them in some contexts,
this is allowed in 1364-2005, but V0.8 doesn't support them at all.
2008-11-24 21:07:51 -08:00
Cary R 7dc473db8d V0.8: fix signed parameter multiply
This patch mirrors what was done in development to fix the
multiplication of signed values.
2008-11-24 21:03:11 -08:00
Cary R abc2aa17d2 V0.8: complain about a negative repeat value.
This patch mirrors what was done in development to complain
about a negative repeat value.
2008-11-24 21:00:58 -08:00
Cary R c8bffe728a V0.8: fix verinum XOR with z input
This patch mirrors what was done in development to fix the XOR
of a z bit in verinum.
2008-11-24 20:56:48 -08:00
Cary R d134f6f074 V0.8: fix $ungetc argument order.
This patch mirrors what was done in development to fix $ungetc.
2008-11-24 20:52:38 -08:00
Cary R 8deb2c0b60 V0.8: only return a real time value for $realtime.
This patch mirrors what was done in development to only return a
real value when realtime is called.
2008-11-24 20:49:53 -08:00
Cary R 451783056d V0.8: Can not have and undefined repeat.
This patch mirrors what was done in development to fail when the
repeat has an undefined value.
2008-11-24 20:44:28 -08:00
Cary R 322bbed7c7 V0.8: Don't crash on invalid input.
This patch mirrors what was done in development to prevent a crash
when given invalid input.
2008-11-24 20:42:48 -08:00
Cary R e8bb9b1f76 V0.8: `timescale can not be inside module definition.
This patch mirrors what was done in development to complain
about a `timescale inside of a module definition.
2008-11-24 20:39:49 -08:00
Cary R f112b77d3b V0.8: Fix single bit reductions with 1'bz input.
This patch mirrors what was done in development to support single
bit reductions correctly.
2008-11-20 20:25:39 -08:00
Cary R ddf68ca14c Don't let -I block -ivl!
When -I was added it was blocking -ivl since the string comparison
is case insensitive.
(cherry picked from commit a412149e2c)
2008-11-20 20:23:52 -08:00
Cary R d8fdcd5a38 Add verilog<suffix> to MinGW iverilog-vpi tool
When changing where the include files were located the MinGW
iverilog-vpi tool was missed.
(cherry picked from commit 45f2d68d33)
2008-11-20 20:12:45 -08:00
Stephen Williams 408e25f6bc Make the 0.8 series use --enable-suffix by default
This we are working on closing out this release series,
install with the 0.8 suffix enabled by default from
now on.
2008-11-20 09:53:52 -08:00
Cary R 3dd2c74ebe V0.8: For scheduled put values save the string and free it after the put.
Users expect that vpi_put_value() will keep a copy of the string
that is passed to it. This patch implements this buy copying the
string and then freeing it after the actual put_value call.
2008-11-20 09:31:52 -08:00
Cary R d260052940 Fix MinGW suffix configuration.
In the driver-vpi file we need to use g for the suffix replacement
so that both libraries get changed.

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

Also, move installed C/C++ header files into a subdirectory of
their own under the target include directory, to make clearer
the purpose and source of those files.

(cherry picked from commit 4bc90f7cfd)
2008-11-19 22:39:10 -08:00
Cary R 74e2343e52 V0.8: fix shifting of 0 or signed constant.
This patch matches the one from development. If just returns the
L-value if the shift is a NOP.
2008-11-16 11:07:58 -08:00
Cary R b4b9667def Fix signed divide for words that match the machine word.
There was an error when calculating the negative of a value that
was the same width as the native machine word. This patch is similar
to what was done in 0.9 to fix the problem there.
2008-11-16 11:05:04 -08:00
Cary R 5e401055e8 V0.8: do signed comparisons and fix verinum < and <=
This patch fixes the verinum < and <= operators to directly
compare the long result not the difference. Because of overflow
the difference can give an incorrect value. Using a long value
is technically wrong, but that will need to be a different
patch. It also fixes the eval_leeq_() routine to correctly build
the largest value in a signed comparison.
2008-08-23 09:30:37 -07:00
Cary R e89bce48ed Error message for missing system tasks/functions.
This patch adds an error message for the standard system
tasks and functions that are not currently implemented.
2008-08-23 09:23:49 -07:00
Cary R cf01d1a75f V0.8: Remork previous patch to use the correct method 2008-06-25 15:38:20 -07:00
Cary R 6df10a082b V0.8: fix memory leak in recent patch. 2008-06-25 12:52:04 -07:00
Cary R 22ad8c42bc V0.8: Copy file and line info during a macro expansion.
The file and line number information needs to be copied when
doing a macro expansion. This prevents a macro that expands to
an `ifdef of other construct that needs to push the stack
from core dumping because the file is NULL.
2008-06-25 11:26:02 -07:00
Cary R f418bea775 MinGW fixes (system return and vsnprintf)
The MinGW system() implementation appears to return the straight
return value instead of the waitpid() like result that more
normal systems return. Because of this just return the system()
result without processing for MinGW compilations.

Older version of the MinGW runtime (pre 3.14) just used the
underlying vsnprintf(). Which has some problems. The 3.14 version
has some nice improvements, but it has a sever bug when processing
"%*.*f", -1, -1, <some_real_value>.  Because of this we need to use
the underlying version without the enhancements for now.
2008-05-22 20:20:29 -07:00
Stephen Williams 568e601212 Do not use "synthesize" to elaborate nets if not necessary.
The synthesize was causing memories to be exploded, whis was then causing
memory word addresses to turn into bit index statements, causing bugs.
So don't synthesize if we are not actually synthesizing.
2008-05-22 09:37:19 -07:00
Cary R b7e7d3cb04 User tasks have empty nex_output().
This patch matches what is done in the development branch and
fixes the reported bug.
2008-05-13 11:09:12 -07:00
Cary R 8a1543aaaf V0.8: pad user function port in synthesize().
This patch removes the assert in synthesize() for user functions and
replaces it with a pad to width.
2008-02-25 16:07:29 -08:00
Cary R c6ba9269bc Fix some problems in driver-vpi/main.c
Fixed a few problems in driver-vpi/main.c that were preventing
the Verilog-A math library from compiling.
2008-02-25 16:02:40 -08:00
Michael Witten 3af373667a [PATCH] Removed #include asm/page.h on GNU/Linux
vvp/main.cc was including asm/page.h on GNU/Linux
systems, though that file does not often exist and
is not necessary.

Signed-off-by: Michael Witten <[email protected]>
2008-02-04 13:20:57 -08:00
Stephen Williams d49e44594b Fix reported build errors with gcc 4.3
Add missing includes to cstring et al.
2008-01-21 18:04:30 -08:00
Cary R 4d3f592b5f V0.8 add check target to {tgt-*,vpi}/Makefile.in
Add missing Makefile check targets to the tgt-* and vpi directories.
2008-01-16 11:07:47 -08:00
Cary R d1e82d3d12 V0.8: ignore edge-control specifiers
Update the specify code in V0.8 to ignore edge-control specifiers.
2008-01-15 15:57:40 -08:00
Cary R d70ccb6895 V0.8: update driver-vpi/* to match iverilog-vpi.sh
This patch updates the MinGW C version of iverilog-vpi to match the
shell version. This allows the vpi tests in the test suite to be run.
2008-01-09 08:10:39 -08:00
Cary R e34647f79c V0.8: Add vvp flag that allows $stop to act like $finish.
This patch adds a new flag to vvp "-n" that can be used to make
$stop and hence <Control-C> act like $finish. This may be desired
when using vvp in a non-interactive environment.
2008-01-09 08:08:19 -08:00
Cary R 24b097ce89 V0.8 fix for shift/reduce warning
This patch fixes the oversight in the previous patch and eliminated
the shift/reduce warning. Apply it after the previous one.
2007-12-31 17:52:27 -08:00
Cary R 83ee7e7988 V0.8: allow NULL ports in task calls.
This is a direct back port from development that allows tasks to
be called with no ports. This fixes one failure in the test suite.
2007-12-31 17:52:09 -08:00
Cary R f33d477166 V0.8: allow vthr_vector to be converted to real.
This is a direct back port from development that allows vthread
vectors to be converted to real values. This is the first step
in fixing two more failures in the test suite.
2007-12-29 15:02:11 -08:00
Cary R 3f16d3402a V0.8: add `elsif add some conditional directive syntax checks.
This is a direct back port from the development branch. It adds
the `elsif directive and adds check that the conditional
directives are used correctly.
2007-12-29 14:54:29 -08:00
Cary R 304a63d8e3 Fix protect/endprotect
This patch makes stable match the development branch. `protect/`endprotect
are not required to be on their own line.
2007-12-29 14:49:13 -08:00
Cary R 23d56d8198 V0.8: fix a few more specify block problems.
This patch fixes a few more specify block problems in the stable
branch.
2007-12-29 14:44:13 -08:00
Cary R a8f68fe416 V0.8: ignore ifnone in specify block
In specify blocks ignore the ifnone command.
2007-12-29 14:37:48 -08:00
Cary R 5dc4202929 V0.8: Back port development patch for pr1716276
This is a straight back port of the development patch for the
problem reported in pr1716276. This was causing the test case
to core dump under stable.
2007-12-29 14:29:27 -08:00
Cary R 281b4edbab v0.8: Do not run the first time step if the compilation failed.
This patch fixes another minor problem introduced by the process
end of simulation events. Specifically if the compilation has
indicated we should not run do not even start the main event loop.
2007-12-10 16:26:06 -08:00
Cary R 3eb86a2376 Process end of simulation events.
This is copied from the development branch. It allows the processing
of events that happen at the simulation finish time.
2007-12-06 18:54:15 -08:00
Cary R 1fb93c0565 Fix call back free problem.
This is copied from the development branch. The issue is that calling
vpi_free_object should not really free a call back handle since it is
the real call back object and doing so will invalidate it. This will
likely end with a core dump.
2007-12-06 18:50:31 -08:00
Holger Waechtler bdb900b25f Fix compile error on some gcc versions 2007-12-03 14:27:53 -08:00
Cary R 28da79dcc3 V0.8: Add the enhancements in iverilog-vpi from devel
Back port all the enhancements to iverilog-vpi made in the
development branch to the stable branch.
2007-11-29 18:05:06 -08:00
Cary R bbd61823b9 Update vpi/etc. files to correctly use PLI_INT32
This patch fixes the various PLI code that was incorrectly
using int for PLI_INT32 for functions that are used with the
vpi_systf_data and cd_data data structures.
2007-11-29 18:01:51 -08:00
Stephen Williams 0f716d6dca Prepare for 0.8.6 release. 2007-11-26 10:55:13 -08:00
Cary R a44236f8cb v0_8: A leading underscore is valid for macro substitutions.
For text macro substitutions the lexor did not allow leading underscores.
This patch fixes that omission. All other places that text macros may be
used appear to be correct.
2007-11-16 15:48:25 -08:00
Cary R 4be2ccb3fa Add error message for pr1489570.
This patch does not add the functionality needed to fix pr1489570, but
it does give an error message that is a bit more descriptive of the
current limitation (cannot do division or modulus with wide value).
2007-11-14 13:52:19 -08:00
Cary R 9f4dc5411f v0_8: make patch for pr1792108 synth aware.
This patch makes the behavior selection for pr1792108 depend on the
synth* functors.
2007-11-14 13:38:43 -08:00
Stephen Williams 545d20eba5 Error message for inconnected primitive ports.
Error message (instead of a seg fault) when a primitive port
is left unconnected.

Signed-off-by: Stephen Williams <[email protected]>
2007-10-31 11:41:04 -07:00
Stephen Williams b2159d1e64 Unary minus size assertion
Fix errors with unary subtraction producing logic gates with
inconsistent widths.

Signed-off-by: Stephen Williams <[email protected]>
2007-10-31 11:40:45 -07:00
Stephen Williams 4c8df2a370 No system functions in continuous assignments.
Do not support (in 0.8) system functions in continuous assignments.
Make a better error message.

Signed-off-by: Stephen Williams <[email protected]>
2007-10-31 11:40:35 -07:00
Stephen Williams eed0885dd0 Fix comparison of two negative numbers
Pairs of negative numbers that are equal do not set
the LT flag correctly at runtime.
2007-10-31 11:39:45 -07:00
Cary R 0fc10d0262 v0_8: fix @* to correctly handle non-input nets.
This is a slightly modified version of the patch from the development
branch. Specifically it only allows outputs in the sensitivity list for
non-synthesis back ends. The text from the development patch follows.

@* was only expanding to input nets. nex_input() for blocks was removing
any output net that was also an input. There was also a bug in how output
nets were removed. Only outputs currently defined were removed from the
input list.

always @(*) begin
  y = a;
  z = y;
end

would report "a" as an input. While

always @(*) begin
  z = y;
  y = a;
end

would report both "a" and "y" as inputs.

To fix this all nex_inputs now take a flag that when true (the default)
correctly removes any output from the input list. Both the above cases
will now return "a". If the flag is false outputs which are also inputs
will be included in the input list. This is what the @* elaboration code
uses to get the correct sensitivity list.
2007-10-30 17:49:35 -07:00
Cary R 1775c78aa9 v0_8: clear expression look aside for transient thread.
This is a back port of code from the development branch. The problem is
that for named blocks (which create a transient thread) the look aside
was not being cleared for the new thread. This resulted in an invalid
variable reference optimization.
2007-10-30 17:33:06 -07:00
Cary R 85652e24e0 v0_8: explicitly state the V0.8 cannot evaluate constant real expressions.
V0.8 does not have the code to evaluate constant real expressions. This
patch adds a line to the normal error message that says this explicitly.
2007-10-29 16:28:36 -07:00
Cary R eb4fc8fb7b Warn that bit based signals cannot be converted to real.
V0.8 does not have the code to covert bit based signals to a real value,
so print a more descriptive error message before quiting.
2007-10-29 16:24:55 -07:00
Cary R 043b7ae684 v0_8: warn about unused variable in for loop.
This patch back ports from the development branch a warning when
an undefined variable is used in a for loop.
2007-10-29 16:20:58 -07:00
Cary R 2946f30ffc v0_8: fix comparison in previous patch for pr1745132
If I had remembered to test the passing case I would have noticed
the comparison was wrong.
2007-10-29 16:15:07 -07:00
Cary R 5530aea6a3 v0_8: print an error message for an invalid bit selection.
This code may be used for more than just a bit select so the error message
is fairly generic. Though it should help in tracking down the real problem
(invalid Verilog code).
2007-10-29 16:14:49 -07:00
Cary R 40e09cd719 v0_8-add min_typ_max to expressions.
This patch adds min_typ_max to expressions. Remember when using a
min_typ_max triplet in an expression they must be enclosed with
parenthesis (1364-2001 section 4.3 page 58).
2007-10-29 16:08:34 -07:00
Cary R c67f3b0081 v0_8: implement $printtimescale.
This patch implements the $printtimescale system task. It is a back port
from the development branch. One thing to note is that the precision is
the global precision not the local precision. The patch to fix that could
also be back ported if needed, but it is significantly more work.
2007-10-29 16:02:08 -07:00
Cary R 95254aa27e v0_8: disable lxt support if libbzip2 is not found.
Configure was checking for libbzip2, but it was not doing anything with
the result. This patch disables lxt support if libbzip2 is not found.
2007-10-29 15:58:35 -07:00
Cary R 468e3bb702 v0_8 make C style comments work in false/suppressed ifdef/etc. blocks.
C style comments were not recognized as comments in false or
suppressed sections of ifdef/etc. blocks. This prohibited an
unneeded endif/else/etc. from being commented out with this
style of comment.
2007-10-29 15:50:29 -07:00
Alan M. Feldstein be8c8a8eb7 Removed UML not for publication.
Removed UML not for publication.
2007-10-24 16:18:02 -07:00
Alan M. Feldstein 5cae6b64af Fixed dangling latch gate inputs.
With -tfnf, observed
(latch  43020 1 43022 43021)
in the output file. That 3rd number is the ID of the gate nexus. However, it was only found as
(dangle 43022)
The purpose of this patch is to fix that in the common code.
2007-10-24 16:16:23 -07:00
steve f600e774d5 Add support for NAND gates. (Chris H) 2007-06-06 15:46:22 +00:00
steve d16dd26660 Support Latch synthesis (Alan Feldstein) 2007-05-30 17:48:53 +00:00
steve 8c04d669f9 DEBUG aids. (Alan Feldstein) 2007-05-30 17:48:26 +00:00
steve 5d2dcfd7f7 Fix uninitilized line number. 2007-05-25 18:35:45 +00:00
steve 0b3f1e4119 Better configuration messages (Alan Feldstein) 2007-05-16 23:51:42 +00:00
steve 8bd9fc7128 Supress error about types for default rule. 2007-04-26 00:50:54 +00:00
steve 1b551aaf94 Update to v0.8.4 release. 2007-03-23 23:26:51 +00:00
steve a3dda80fb2 Properly support signed task/function arguments. 2007-03-23 23:22:57 +00:00
steve 9e9d5ccfdd Fix compile time eval of <= comparison. 2007-03-23 23:02:31 +00:00
steve 07daee9438 Fix compile time evaluation of < operator. 2007-03-23 20:59:25 +00:00
steve 82808d8b5d Parse attribute attached to block items. 2007-03-23 19:31:22 +00:00
steve c045f51a7f Spelling fixes (larry doolittle) 2007-02-26 19:51:38 +00:00
steve d72eadb885 Get page size from sysconf. 2007-02-16 23:29:17 +00:00
steve e99f0a8f51 Comment about 10.3. 2007-02-09 05:30:22 +00:00
steve ed2cb380cd fix lexical handling of slashes in strings. 2007-02-09 05:29:24 +00:00
steve dc8e941260 Fix parse of bit select in notifier expression, 2006-12-03 04:58:20 +00:00
steve d486b81f23 Fix crash handling constant true conditional. 2006-11-27 01:47:14 +00:00
steve 59c2f16a5f Fix evaluate of constant condition expressions. 2006-11-27 01:32:24 +00:00
steve 1470a061fd Add synthesis of user defined functions. 2006-11-26 01:54:05 +00:00
steve c1333a21ef Prevent constant mux outputs from confusing itself. 2006-11-12 01:20:45 +00:00
steve 04ef0b7d80 Fix async blocks to take accumulated input. 2006-11-11 23:10:20 +00:00
steve 2fc9413d1f More detailed BuildRequires settings. 2006-11-11 21:21:50 +00:00
steve c94bdbcdb0 Make signal lookup use extended names. 2006-11-11 21:21:21 +00:00
steve 1820cd0244 Fix compile on Mac OS X 2006-11-02 17:47:52 +00:00
steve aa3cbbdf99 Error message for condit expression not synthesized. 2006-11-02 02:13:15 +00:00
steve 0a9b6f34ae Detect and synthesize enables using condit false. 2006-10-30 02:03:30 +00:00
steve 5c2c5453ac Fix code generation for signed numbers in real expressions. 2006-10-11 00:19:04 +00:00
steve 0c6bb476ea Get rounding of conversion correct. 2006-10-11 00:17:35 +00:00
steve 568924dcb5 Version stamp update 2006-10-04 17:08:59 +00:00
steve 33b3f7bdda Detect delay precision overflow. 2006-10-04 00:37:03 +00:00
steve 3a04e0a051 Fix a dangling reference to NetEParam objects in defparams. 2006-10-04 00:34:45 +00:00
steve 66ae377801 Snapshot v0.8.3 2006-10-03 21:34:40 +00:00
steve 898db57405 Describe the preconfigure steps. 2006-09-28 23:42:14 +00:00
steve 0fe45b5046 Fix host type detection in some configure scripts. 2006-09-22 03:29:02 +00:00
steve 20cfe99457 Fix left shift of small unsized constants. 2006-09-20 20:27:02 +00:00
steve 4ec8b38a5c Special handling of exploded memory arguments. 2006-09-15 23:56:05 +00:00
steve 79add47002 Build instruction typos and minor corrections. 2006-09-15 23:53:24 +00:00
steve c429f4c9a7 missing sig diagnostics. 2006-08-23 04:09:14 +00:00
steve 7f6a0b652a Do not count self as signifincant in nodangle. 2006-08-23 04:08:55 +00:00
steve 9f3f9154eb Fix missing sig on certain mux outputs.
Ignore condit statements (for synthesis) with no outputs.
2006-08-23 04:08:19 +00:00
steve 498fd06412 Add synthesis for casez statements. 2006-08-22 04:22:45 +00:00
steve 6d3b780791 Improve performance of unlink of heavily connected nexa. 2006-08-15 03:41:24 +00:00
steve a0ec981c50 Improved nexus management performance. 2006-08-08 02:17:48 +00:00
steve 930cd598a0 Typo clearing an event cell. 2006-08-06 18:09:42 +00:00
steve 77adab0f33 Remove excess PEString:: prefix for stubborn compilers. 2006-07-28 16:26:17 +00:00
steve 0e3768f829 Handle statement output override better in blocks. 2006-07-23 19:42:33 +00:00
steve 22884f2e64 Add support for full_case attribute. 2006-07-10 00:21:49 +00:00
steve 62da6aca28 Root dir variable does not include lib/ivl components. 2006-07-07 21:31:50 +00:00
steve 525ebddb0c Properly synthesize casex statements. 2006-07-02 00:50:15 +00:00
steve 521750c007 Fix ambiguity warnings. 2006-06-27 01:47:25 +00:00
steve 85d2833a62 Fix const/non-const warnings. 2006-06-27 01:37:14 +00:00
steve e2cc258283 Cure exit from main warning. 2006-06-27 01:33:17 +00:00
steve f09cf85c76 Fix unused var warning for mingw32 build. 2006-06-27 01:30:20 +00:00
steve c32de1dba0 Handle case where case output appears to be internal. 2006-06-26 00:05:46 +00:00
steve 628b866c36 Change Copyright tag to License. 2006-06-24 05:22:55 +00:00
steve 08dbe801c1 synthesis of NetCondit handles partial resets. 2006-06-23 03:49:46 +00:00
steve 101810df21 Handle simple memory addressing in expression synthesis. 2006-06-15 01:57:26 +00:00
steve 3877b636df synthesis for NetEBitSel. 2006-06-14 03:02:54 +00:00
steve 9d028a63f2 Remove redundant call to get_root_dir. 2006-06-14 03:01:49 +00:00
steve 35e5cea9df Add support for -Wunused warnings. 2006-06-12 00:16:50 +00:00
steve ec510071f1 Fix partial use of NetMux in sync condit statements. 2006-06-07 03:17:39 +00:00
steve 7413c533f6 Compilation warnings. 2006-06-02 23:42:48 +00:00
steve dde69cebb6 Handle condit clauses with unassigned outputs. 2006-06-01 03:01:48 +00:00
steve f942657ad5 NetESignal input is only selected bits. 2006-05-21 21:58:46 +00:00
steve fad1620828 Replace assertions with error messages. 2006-05-20 16:06:48 +00:00
steve a9931e7a58 Fix synthesis of l-value bit select in block. 2006-05-18 01:47:12 +00:00
steve 6cd4adb135 Fix synthesis of expressions with land of vectors. 2006-05-15 03:55:22 +00:00
steve 9643b86ab3 Update to use only Mingw for build. 2006-05-08 04:33:35 +00:00
steve 452eaeaea8 Handle memory assignments out of range during synthesis 2006-05-05 01:56:36 +00:00
steve 3a6e2df958 Fix uninitialized mem_lref_ member. 2006-05-02 02:00:15 +00:00
steve e73b7e2656 parse.cc and parse.h are made by the same steps. 2006-05-01 20:11:56 +00:00
steve 469ec11190 Merge fixes from devel tree. 2006-04-25 05:11:14 +00:00
steve e0bbfa512c Constant propagate addresses through NetRamDq read ports. 2006-04-23 04:26:13 +00:00
steve 94c9af2a5d Add cprop debugging. 2006-04-23 04:25:45 +00:00
steve 9f2e7df0ff vpp.conf is generated, so add it to cvsignore. 2006-04-23 02:44:29 +00:00
steve f02b2c9d7a Fix handling of exploded memories with partial or missing resets. 2006-04-16 19:26:37 +00:00
steve 058dac4290 Exploded memories accessed by constant indices. 2006-04-10 03:43:39 +00:00
steve ce4e21a962 Punt on set/reset if some sources are unconnected. 2006-04-01 01:37:58 +00:00
steve 065d6bc1e3 Add synth debug flag 2006-04-01 01:37:24 +00:00
steve 312d09dc1d Handle asynchronous demux/bit replacements. 2006-03-26 23:09:21 +00:00
steve faf7f30283 Add the .demux device. 2006-03-26 23:09:00 +00:00
steve 5d41e98c1f More installation directory flexibility. 2006-03-26 21:47:26 +00:00
steve 5e8330a4ff Better error messages when synthesis fails. 2006-03-18 18:43:21 +00:00
steve ef8964c65a Fix crash when memory exploding doesnot work 2006-03-16 05:40:18 +00:00
steve aa42ec381c Fix a spelling error in an error message. 2006-03-16 05:39:43 +00:00
steve c9d4aab9cb Right shifts really are allowed. 2006-03-16 05:39:20 +00:00
steve b8bc531f05 Fix the memsynth1 case. 2006-03-12 07:34:16 +00:00
steve 79cb8c883a Add support for negedge FFs by using attributes. 2006-02-25 05:03:28 +00:00
steve 27e633410c Add change callback to vpiMemory objects. 2006-02-19 16:57:31 +00:00
steve 7527c466ed Handle synthesis of FF vectors with l-value decoder. 2006-02-19 00:11:31 +00:00
steve 3ea1214160 More robust test for concat constant-ness. 2006-02-07 22:46:23 +00:00
steve 782542922d Detect nul arguments to concat expressions. 2006-02-07 22:45:54 +00:00
steve 1f8102c4dc Speed up processing of connect when one side is empty. 2006-01-27 02:05:46 +00:00
steve c4b34e8720 Document how the default statement handling works. 2006-01-27 01:58:53 +00:00
steve e494be7cbf Fix pin_Sel overrun. 2006-01-22 00:13:59 +00:00
steve eb0a78e9ce When mux has wide select but sparse choices, use 1hot translation. 2006-01-21 21:42:31 +00:00
steve e80138ec8c Restrict DFF to only one of Sset and Sclr. 2006-01-18 06:16:11 +00:00
steve 943316c6f6 Support DFF with synchronous inputs. 2006-01-18 06:15:45 +00:00
steve 52b8ed9077 Rework l-value handling to allow for more l-value type flexibility. 2006-01-18 01:23:23 +00:00
steve fc227aa3e1 Remember to set DLL= flag. 2006-01-14 20:13:38 +00:00
steve 41993815e9 Show synchronous set/clr of FF. 2006-01-14 20:13:22 +00:00
steve c5063f5d2f Case statement handles partial outputs. 2006-01-01 02:25:07 +00:00
steve f28aa11936 Allow for implicit case default in synchronous processes. 2006-01-01 01:30:39 +00:00
steve 3131fa68b7 Fix crashes caused bu synthesis of sqrt32.v. 2005-12-31 04:28:14 +00:00
steve def3809b3f Handle DFF definitions spread out within a block. 2005-12-19 01:13:47 +00:00
steve 3429c24a6a Properly fail when concat is not actually constant. 2005-12-18 21:06:01 +00:00
steve f47627d752 Fix missing outputs from synchronous conditionals to get out from in. 2005-12-15 02:38:51 +00:00
steve 9468f3d06f Handle both asynchronous set and reset. 2005-12-14 01:53:39 +00:00
steve b997de63a5 Account for sync vs async muxes. 2005-12-14 00:54:29 +00:00
steve f50f06ab4e Handle concatenations in l-values. 2005-12-10 04:26:32 +00:00
steve d5d03812cd Fix crash on block with assignments that assign lval to self. 2005-12-10 03:30:50 +00:00
steve b6d5a0675e Support constant concatenation of constants. 2005-12-07 03:28:44 +00:00
steve e63e830d62 Error messages for missing else clauses. 2005-12-07 02:14:37 +00:00
steve 74ca34bd82 Handle partial sets of conditional clauses. 2005-11-16 00:38:26 +00:00
steve c9d480028e Allow for block output to be set throughout the statements. 2005-11-13 22:28:48 +00:00
steve cc89ba66af Do not panic if case statement is nul. 2005-11-13 22:28:14 +00:00
steve 05e6d51004 Snapshot 0.8.2 2005-09-30 15:13:37 +00:00
steve ae583204e3 Snapshot 0.8.2 2005-09-30 15:01:44 +00:00
steve 018476f7cd More predictable ordering of items in NexusSet. 2005-09-25 23:30:31 +00:00
steve bfabeab6b9 Add Xilinx virtex as a reference EDIF device. 2005-09-25 16:35:36 +00:00
steve 4a3f1a3641 Attach line numbers to NetMux devices. 2005-09-11 02:56:37 +00:00
steve d97560caa7 Fix overly agressive constant propagation through MUX causing lost Z bits. 2005-09-11 02:50:51 +00:00
steve 393102d43a Evaluate magnitude compare with real operands. 2005-09-09 02:17:08 +00:00
steve 8e97a0e4d4 Support b1 edge in primitive tables. 2005-09-09 02:13:15 +00:00
steve 4ea789a2d7 More explicit internal error message. 2005-09-04 15:41:54 +00:00
steve 354f7ad920 More explicit internal error message. 2005-09-04 15:39:19 +00:00
steve f4a6206790 Handle b0 edges in primitives. 2005-09-04 15:33:19 +00:00
steve fd29ba3398 Reduce mux slices that are constant throughout range. 2005-08-28 22:00:39 +00:00
steve 44fbf60885 More thorough constant propagation through MUX devices. 2005-08-28 19:51:02 +00:00
steve a0d69113c3 More thorough constant propagation through MUX devices. 2005-08-28 19:50:03 +00:00
steve 86942ac592 Dump CMP_GE devices. 2005-08-28 17:37:28 +00:00
steve 075f9cbc4b Back-port edif_nexus_to_joint from tgt-edif. 2005-08-27 22:29:30 +00:00
steve 9dab368880 fix configure and build instructions for mingw build. 2005-08-27 22:19:37 +00:00
steve 5f6027fb66 Join cell0 and cell1 instances in LPM target. 2005-08-25 18:52:32 +00:00
steve 53156793fe Add support for implicit defaults in case and conditions. 2005-08-22 01:00:41 +00:00
steve 4644c220e8 Handle statements in blocks overriding previous statement outputs. 2005-08-21 22:49:54 +00:00
steve c30cd9afea Display NOR gates. 2005-08-21 22:27:57 +00:00
steve a8f45a18f0 Fix the comment in the EDIT header. 2005-08-21 22:25:51 +00:00
steve 6828e3e2ea Generate LPM for the CMP_EQ device. 2005-08-21 14:39:33 +00:00
steve 75eb372adf configure tgt-edif subdir. 2005-08-21 02:20:16 +00:00
steve 3b753fe52b Add the tgt-edif target. 2005-08-17 01:17:28 +00:00
steve 8c73fa7840 Fix compilation warnings/errors with newer compilers. 2005-08-13 00:45:53 +00:00
steve d310e656c7 Fix parse errors related to pr766. 2005-07-27 14:48:34 +00:00
steve 0510367b70 Fix compile errors with g++-4. 2005-07-06 22:41:34 +00:00
steve 3e11207a56 Fix gcc4 build issues. 2005-06-14 15:33:54 +00:00
steve 665f31271f popen must be matched by pclose. 2005-03-22 15:53:12 +00:00
steve 9a2b56675c Fix set_width to allow binary logical operands to be self determined. 2005-03-05 01:36:16 +00:00
steve c9f38f5ffa Improve distclean targets. 2005-02-23 18:40:23 +00:00
steve 5ea4152162 Spelling fixes from Larry. 2005-02-23 18:37:52 +00:00
steve 327c897d7e Spellig fixes. 2005-02-19 16:39:30 +00:00
steve 29ebe486b7 Fix multiple delete of an expression. 2005-02-19 16:38:14 +00:00
steve 4af0acb3be Fix (from Tony) for clock compression detection 2005-02-11 17:04:22 +00:00
steve 8435774c26 Fix evaluate of constants in netlist concatenation repeats. 2005-01-29 00:18:23 +00:00
steve 6172748c65 Add stub config files to CVS. 2005-01-28 18:30:11 +00:00
steve ca0ae9040a Add ability to compile real values into index registers. 2005-01-28 18:29:29 +00:00
steve d9cdbde3f6 More robust handling of file name argument to $fopen. 2005-01-01 20:07:41 +00:00
steve 307a97116f Fix leak of word registers in code generator. 2004-12-12 04:25:10 +00:00
steve 83d2c6dfd1 Update for 0.8 files. 2004-10-14 01:12:41 +00:00
481 changed files with 36173 additions and 63751 deletions
-27
View File
@@ -1,27 +0,0 @@
lexor_keyword.cc
parse.h
parse.cc
parse.cc.output
parse.output
syn-rules.cc
syn-rules.cc.output
syn-rules.output
lexor.cc
iverilog-vpi
iverilog-vpi.pdf
iverilog-vpi.ps
ivl
ivl.exp
dep
configure
Makefile
check
check.cc
check.vvp
config.status
config.log
config.cache
autom4te.cache
config.h
_pli_types.h
dosify
+82
View File
@@ -0,0 +1,82 @@
# Lines that start with '#' are comments.
#
# This file is for the development branch of Icarus Verilog.
#
# The following files will be ignored by git.
# Object files and libraries
*.[oa]
# From autoconf
configure
config.log
config.status
Makefile
/_pli_types.h
config.h
/tgt-vvp/vvp_config.h
/vpi/vpi_config.h
# Directories
autom4te.cache
dep
# Compiler back end and library files
/tgt-vvp/*.conf
*.tgt
*.vpi
/cadpli/cadpli.vpl
# lex, yacc and gperf output
/driver/cflexor.c
/driver/cfparse.c
/driver/cfparse.h
/driver/cfparse.output
/ivlpp/lexor.c
/ivlpp/parse.c
/ivlpp/parse.h
/ivlpp/parse.output
/lexor.cc
/lexor_keyword.cc
/parse.cc
/parse.h
/parse.output
/syn-rules.cc
/syn-rules.output
/vpi/sys_readmem_lex.c
/vvp/lexor.cc
/vvp/parse.cc
/vvp/parse.h
/vvp/parse.output
# Program created files
/vvp/tables.cc
# The executables.
*.exe
/driver/iverilog
/iverilog-vpi
/ivl
/ivlpp/ivlpp
/vvp/vvp
/ivl.exp
/vvp/vvp.exp
# Check output
/check.vvp
# The PostScript and PDF generated manual files.
/driver/iverilog.ps
/driver/iverilog.pdf
/iverilog-vpi.ps
/iverilog-vpi.pdf
/tgt-fpga/iverilog-fpga.ps
/tgt-fpga/iverilog-fpga.pdf
/vvp/vvp.ps
/vvp/vvp.pdf
+1 -38
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2000 Stephen Williams ([email protected])
* Copyright (c) 2000-2010 Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -16,9 +16,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: Attrib.cc,v 1.6 2004/02/20 18:53:33 steve Exp $"
#endif
# include "config.h"
@@ -102,37 +99,3 @@ const verinum& Attrib::attr_value(unsigned idx) const
assert(idx < nlist_);
return list_[idx].val;
}
/*
* $Log: Attrib.cc,v $
* Revision 1.6 2004/02/20 18:53:33 steve
* Addtrbute keys are perm_strings.
*
* Revision 1.5 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.4 2002/05/26 01:39:02 steve
* Carry Verilog 2001 attributes with processes,
* all the way through to the ivl_target API.
*
* Divide signal reference counts between rval
* and lval references.
*
* Revision 1.3 2002/05/23 03:08:50 steve
* Add language support for Verilog-2001 attribute
* syntax. Hook this support into existing $attribute
* handling, and add number and void value types.
*
* Add to the ivl_target API new functions for access
* of complex attributes attached to gates.
*
* Revision 1.2 2001/07/25 03:10:48 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
*
* Revision 1.1 2000/12/04 17:37:03 steve
* Add Attrib class for holding NetObj attributes.
*
*/
+1 -31
View File
@@ -1,7 +1,7 @@
#ifndef __Attrib_H
#define __Attrib_H
/*
* Copyright (c) 2000 Stephen Williams ([email protected])
* Copyright (c) 2000-2010 Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -18,9 +18,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: Attrib.h,v 1.5 2004/02/20 18:53:33 steve Exp $"
#endif
# include "StringHeap.h"
# include "verinum.h"
@@ -60,31 +57,4 @@ class Attrib {
Attrib& operator= (const Attrib&);
};
/*
* $Log: Attrib.h,v $
* Revision 1.5 2004/02/20 18:53:33 steve
* Addtrbute keys are perm_strings.
*
* Revision 1.4 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.3 2002/05/26 01:39:02 steve
* Carry Verilog 2001 attributes with processes,
* all the way through to the ivl_target API.
*
* Divide signal reference counts between rval
* and lval references.
*
* Revision 1.2 2002/05/23 03:08:50 steve
* Add language support for Verilog-2001 attribute
* syntax. Hook this support into existing $attribute
* handling, and add number and void value types.
*
* Add to the ivl_target API new functions for access
* of complex attributes attached to gates.
*
* Revision 1.1 2000/12/04 17:37:03 steve
* Add Attrib class for holding NetObj attributes.
*
*/
#endif
+5 -8
View File
@@ -53,7 +53,7 @@ So, if your program doesn't compile, tell me so, tell me where the
error occurs, and include a complete Perfectly Valid Test Program(tm).
You tell me that it fails to compile for you, and I find that it
compiles for me, then hooray I fixed it. It can happen, you
know. What's on my disk is more recent then the latest snapshot.
know. What's on my disk is more recent than the latest snapshot.
If your program does compile, but generates incorrect output, I need
to know what it says and what you think it should say. From this I can
@@ -72,7 +72,7 @@ reporting problems with. However, if you clearly explain what is right
and wrong about the generated netlist, I will probably be able to fix
the problem. It may take a few iterations.
In this case, if possible include not only the sample Verilog program,
In this case, if possible include not only the sample verilog program,
but the generated netlist file(s) and a clear indication of what went
wrong. If it is not clear to me, I will ask for clarification.
@@ -80,9 +80,9 @@ wrong. If it is not clear to me, I will ask for clarification.
If the output is strictly correct, but just not good enough for
practical use, I would like to know. These sorts of problems are
likely to be more subjective then a core dump, but are worthy of
likely to be more subjective than a core dump, but are worthy of
consideration. However, realize that outright errors will get more
attention then missed optimizations.
attention than missed optimizations.
THE MAKING OF A GOOD TEST PROGRAM
@@ -160,11 +160,8 @@ I must insist that any copyright material submitted for inclusion
include the GPL license notice as shown in the rest of the source.
$Id: BUGS.txt,v 1.5 2007/03/22 16:08:14 steve Exp $
$Id: BUGS.txt,v 1.4 2003/02/19 04:36:31 steve Exp $
$Log: BUGS.txt,v $
Revision 1.5 2007/03/22 16:08:14 steve
Spelling fixes from Larry
Revision 1.4 2003/02/19 04:36:31 steve
Notes on hte bug database.
+188 -86
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001 Stephen Williams ([email protected])
* Copyright (c) 2001-2010 Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -16,137 +16,239 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: HName.cc,v 1.8 2007/06/02 03:42:12 steve Exp $"
#endif
# include "config.h"
# include "HName.h"
# include <iostream>
# include <cstring>
# include <cstdlib>
# include <climits>
# include <string.h>
# include <stdlib.h>
#ifdef HAVE_MALLOC_H
# include <malloc.h>
#endif
hname_t::hname_t()
{
number_ = INT_MIN;
item_ = 0;
count_ = 0;
}
hname_t::hname_t(perm_string text)
hname_t::hname_t(const char*text)
{
name_ = text;
number_ = INT_MIN;
}
hname_t::hname_t(perm_string text, int num)
{
name_ = text;
number_ = num;
item_ = strdup(text);
count_ = 1;
}
hname_t::hname_t(const hname_t&that)
{
name_ = that.name_;
number_ = that.number_;
}
hname_t& hname_t::operator = (const hname_t&that)
{
name_ = that.name_;
number_ = that.number_;
return *this;
count_ = that.count_;
switch (count_) {
case 0:
item_ = 0;
break;
case 1:
item_ = strdup(that.item_);
break;
default:
array_ = new char*[count_];
for (unsigned idx = 0 ; idx < count_ ; idx += 1)
array_[idx] = strdup(that.array_[idx]);
break;
}
}
hname_t::~hname_t()
{
switch (count_) {
case 0:
break;
case 1:
free(item_);
break;
default:
for (unsigned idx = 0 ; idx < count_ ; idx += 1)
free(array_[idx]);
delete[]array_;
break;
}
}
perm_string hname_t::peek_name(void) const
unsigned hname_t::component_count() const
{
return name_;
return count_;
}
bool hname_t::has_number() const
void hname_t::append(const char*text)
{
return number_ != INT_MIN;
char**tmp;
switch (count_) {
case 0:
count_ = 1;
item_ = strdup(text);
break;
case 1:
count_ = 2;
tmp = new char*[2];
tmp[0] = item_;
tmp[1] = strdup(text);
array_ = tmp;
break;
default:
tmp = new char*[count_+1];
for (unsigned idx = 0 ; idx < count_ ; idx += 1)
tmp[idx] = array_[idx];
delete[]array_;
array_ = tmp;
array_[count_] = strdup(text);
count_ += 1;
}
}
int hname_t::peek_number() const
void hname_t::prepend(const char*text)
{
return number_;
char**tmp;
switch (count_) {
case 0:
count_ = 1;
item_ = strdup(text);
break;
case 1:
count_ = 2;
tmp = new char*[2];
tmp[0] = strdup(text);
tmp[1] = item_;
array_ = tmp;
break;
default:
tmp = new char*[count_+1];
tmp[0] = strdup(text);
for (unsigned idx = 0 ; idx < count_ ; idx += 1)
tmp[idx+1] = array_[idx];
delete[]array_;
array_ = tmp;
count_ += 1;
}
}
char* hname_t::remove_tail_name()
{
if (count_ == 0)
return 0;
if (count_ == 1) {
char*tmp = item_;
count_ = 0;
item_ = 0;
return tmp;
}
if (count_ == 2) {
char*tmp1 = array_[0];
char*tmp2 = array_[1];
delete[]array_;
count_ = 1;
item_ = tmp1;
return tmp2;
}
char*tmpo = array_[count_-1];
char**tmpa = new char*[count_-1];
for (unsigned idx = 0 ; idx < count_-1 ; idx += 1)
tmpa[idx] = array_[idx];
delete[]array_;
array_ = tmpa;
count_ -= 1;
return tmpo;
}
const char* hname_t::peek_name(unsigned idx) const
{
if (idx >= count_)
return 0;
if (count_ == 1)
return item_;
return array_[idx];
}
const char* hname_t::peek_tail_name() const
{
switch (count_) {
case 0:
return 0;
case 1:
return item_;
default:
return array_[count_-1];
}
}
bool operator < (const hname_t&l, const hname_t&r)
{
int cmp = strcmp(l.peek_name(), r.peek_name());
if (cmp < 0) return true;
if (cmp > 0) return false;
if (l.has_number() && r.has_number())
return l.peek_number() < r.peek_number();
else
unsigned idx = 0;
const char*lc = l.peek_name(idx);
const char*rc = r.peek_name(idx);
while (lc && rc) {
int cmp = strcmp(lc, rc);
if (cmp < 0)
return true;
if (cmp > 0)
return false;
idx += 1;
lc = l.peek_name(idx);
rc = r.peek_name(idx);
}
if (lc && !rc)
return false;
if (rc && !lc)
return true;
// Must be ==
return false;
}
bool operator == (const hname_t&l, const hname_t&r)
{
if (l.peek_name() == r.peek_name()) {
if (l.has_number() && r.has_number())
return l.peek_number() == r.peek_number();
else
return true;
unsigned idx = 0;
const char*lc = l.peek_name(idx);
const char*rc = r.peek_name(idx);
while (lc && rc) {
int cmp = strcmp(lc, rc);
if (cmp != 0)
return false;
idx += 1;
lc = l.peek_name(idx);
rc = r.peek_name(idx);
}
return false;
}
if (lc || rc)
return false;
bool operator != (const hname_t&l, const hname_t&r)
{ return ! (l==r); }
// Must be ==
return true;
}
ostream& operator<< (ostream&out, const hname_t&that)
{
if (that.peek_name() == 0) {
switch (that.count_) {
case 0:
out << "";
return out;
case 1:
out << that.item_;
return out;
default:
out << that.array_[0];
for (unsigned idx = 1 ; idx < that.count_ ; idx += 1)
out << "." << that.array_[idx];
return out;
}
out << that.peek_name();
if (that.has_number())
out << "[" << that.peek_number() << "]";
return out;
}
/*
* $Log: HName.cc,v $
* Revision 1.8 2007/06/02 03:42:12 steve
* Properly evaluate scope path expressions.
*
* Revision 1.7 2007/05/16 19:12:33 steve
* Fix hname_t use of space for 1 perm_string.
*
* Revision 1.6 2007/04/26 03:06:21 steve
* Rework hname_t to use perm_strings.
*
* Revision 1.5 2002/11/02 03:27:52 steve
* Allow named events to be referenced by
* hierarchical names.
*
* Revision 1.4 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.3 2002/01/05 04:36:06 steve
* include malloc.h only when available.
*
* Revision 1.2 2001/12/18 04:52:45 steve
* Include config.h for namespace declaration.
*
* Revision 1.1 2001/12/03 04:47:14 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
*
*/
+32 -50
View File
@@ -1,7 +1,7 @@
#ifndef __HName_H
#define __HName_H
/*
* Copyright (c) 2001-2007 Stephen Williams ([email protected])
* Copyright (c) 2001-2010 Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -18,12 +18,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: HName.h,v 1.7 2007/06/02 03:42:12 steve Exp $"
#endif
# include <iostream>
# include "StringHeap.h"
#ifdef __GNUC__
#if __GNUC__ > 2
using namespace std;
@@ -31,69 +27,55 @@ using namespace std;
#endif
/*
* This class represents a component of a Verilog hierarchical name. A
* hierarchical component contains a name string (represented here
* with a perm_string) and an optional signed number. This signed
* number is used if the scope is part of an array, for example an
* array of module instances or a loop generated scope.
* This class represents a Verilog hierarchical name. A hierarchical
* name is an ordered list of simple names.
*/
class hname_t {
public:
hname_t ();
explicit hname_t (perm_string text);
explicit hname_t (perm_string text, int num);
explicit hname_t (const char*text);
hname_t (const hname_t&that);
~hname_t();
hname_t& operator= (const hname_t&);
// This method adds a name to the end of the hierarchical
// path. This becomes a new base name.
void append(const char*text);
// Return the string part of the hname_t.
perm_string peek_name(void) const;
// This method adds a name to the *front* of the hierarchical
// path. The base name remains the same, unless this is the
// only component.
void prepend(const char*text);
bool has_number() const;
int peek_number() const;
// This method removes the tail name from the hierarchy, and
// returns a pointer to that tail name. That tail name now
// must be removed by the caller.
char* remove_tail_name();
// Return the given component in the hierarchical name. If the
// idx is too large, return 0.
const char*peek_name(unsigned idx) const;
const char*peek_tail_name() const;
// Return the number of components in the hierarchical
// name. If this is a simple name, this will return 1.
unsigned component_count() const;
friend ostream& operator<< (ostream&, const hname_t&);
private:
perm_string name_;
// If the number is anything other then INT_MIN, then this is
// the numeric part of the name. Otherwise, it is not part of
// the name at all.
int number_;
union {
char**array_;
char* item_;
};
unsigned count_;
private: // not implemented
hname_t& operator= (const hname_t&);
};
extern bool operator < (const hname_t&, const hname_t&);
extern bool operator == (const hname_t&, const hname_t&);
extern bool operator != (const hname_t&, const hname_t&);
extern ostream& operator<< (ostream&, const hname_t&);
/*
* $Log: HName.h,v $
* Revision 1.7 2007/06/02 03:42:12 steve
* Properly evaluate scope path expressions.
*
* Revision 1.6 2007/05/16 19:12:33 steve
* Fix hname_t use of space for 1 perm_string.
*
* Revision 1.5 2007/04/26 03:06:21 steve
* Rework hname_t to use perm_strings.
*
* Revision 1.4 2002/11/02 03:27:51 steve
* Allow named events to be referenced by
* hierarchical names.
*
* Revision 1.3 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.2 2002/06/14 03:25:51 steve
* Compiler portability.
*
* Revision 1.1 2001/12/03 04:47:14 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
*
*/
#endif
+7 -7
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2000 Stephen Williams ([email protected])
* Copyright (c) 2000-2010 Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -23,7 +23,7 @@
# include <sstream>
LineInfo::LineInfo()
: lineno_(0)
: file_(0), lineno_(0)
{
}
@@ -31,12 +31,12 @@ LineInfo::~LineInfo()
{
}
string LineInfo::get_fileline() const
std::string LineInfo::get_line() const
{
ostringstream buf;
buf << (file_.str()? file_.str() : "") << ":" << lineno_;
std::ostringstream buf;
buf << (file_? file_ : "") << ":" << lineno_;
string res = buf.str();
std::string res = buf.str();
return res;
}
@@ -46,7 +46,7 @@ void LineInfo::set_line(const LineInfo&that)
lineno_ = that.lineno_;
}
void LineInfo::set_file(perm_string f)
void LineInfo::set_file(const char*f)
{
file_ = f;
}
+5 -10
View File
@@ -1,7 +1,7 @@
#ifndef __LineInfo_H
#define __LineInfo_H
/*
* Copyright (c) 1999 Stephen Williams ([email protected])
* Copyright (c) 1999-2010 Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -19,7 +19,6 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
# include "StringHeap.h"
# include <string>
using namespace std;
@@ -38,19 +37,15 @@ class LineInfo {
LineInfo();
~LineInfo();
// Get a fully formatted file/lineno
string get_fileline() const;
// Set the file/line fro another LineInfo object.
std::string get_line() const;
void set_line(const LineInfo&that);
// Access parts of LineInfo data
void set_file(perm_string f);
void set_file(const char*f);
void set_lineno(unsigned n);
perm_string get_file() const { return file_; }
unsigned get_lineno() const { return lineno_; }
private:
perm_string file_;
const char* file_;
unsigned lineno_;
};
+107 -115
View File
@@ -15,14 +15,14 @@
# Software Foundation, Inc.,
# 59 Temple Place - Suite 330
# Boston, MA 02111-1307, USA
#
SHELL = /bin/sh
# This version string is only used in the version message printed
# by the compiler. It reflects the assigned version number for the
# product as a whole. Most components also print the CVS Name: token
# in order to get a more automatic version stamp as well.
VERSION = 0.9.devel
# This string is used as an installation suffix. It modifies certain
# key install paths/files such that a build and install of Icarus Verilog
# with the same $(prefix) but a different $(suffix) will not interfere.
# The normal configuration leaves suffix empty
suffix = @install_suffix@
prefix = @prefix@
exec_prefix = @exec_prefix@
@@ -35,10 +35,15 @@ VPATH = $(srcdir)
bindir = @bindir@
libdir = @libdir@
includedir = @includedir@
# This is actually the directory where we install our own header files.
# It is a little different from the generic includedir.
includedir = @includedir@/iverilog$(suffix)
mandir = @mandir@
libdir64 = @libdir64@
dllib=@DLLIB@
strip_dynamic=@strip_dynamic@
CC = @CC@
CXX = @CXX@
@@ -46,29 +51,35 @@ INSTALL = @INSTALL@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
STRIP = @STRIP@
LEX = @LEX@
YACC = @YACC@
MAN = @MAN@
PS2PDF = @PS2PDF@
GIT = @GIT@
CPPFLAGS = @ident_support@ @DEFS@ -I. -I$(srcdir) @CPPFLAGS@
CXXFLAGS = -Wall @CXXFLAGS@
CPPFLAGS = @DEFS@ -I. -I$(srcdir) @CPPFLAGS@
CXXFLAGS = @WARNING_CXXFLAGS@ @CXXFLAGS@
PICFLAGS = @PICFLAG@
LDFLAGS = @rdynamic@ @LDFLAGS@
all: dep version.h ivl@EXEEXT@
# The TARGETS variable lists the target modules that can be build and
# installed. Some of them depend on external things, so are only
# compiled if the prerequisites are installed.
TARGETS = tgt-null
all: dep ivl@EXEEXT@
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) $@); done
for dir in ivlpp ; \
for tgt in $(TARGETS); do (cd $$tgt ; $(MAKE) $@); done
for dir in ivlpp tgt-verilog tgt-stub; \
do (cd $$dir ; $(MAKE) $@); done
cd driver ; $(MAKE) VERSION=$(VERSION) $@
cd driver ; $(MAKE) $@
# In the windows world, the installer will need a dosify program to
# dosify text files.
ifeq (@MINGW32@,yes)
ifeq (@WIN32@,yes)
all: dep dosify.exe
dosify.exe: dosify.c
$(CC) -o dosify.exe dosify.c
dosify.exe: $(srcdir)/dosify.c
$(CC) -o dosify.exe $(srcdir)/dosify.c
endif
# This rule rules the compiler in the trivial hello.vl program to make
@@ -77,41 +88,61 @@ check: all
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) check); done
test -r check.conf || cp $(srcdir)/check.conf .
driver/iverilog -B. -BPivlpp -tcheck -ocheck.vvp $(srcdir)/examples/hello.vl
ifeq (@WIN32@,yes)
ifeq (@install_suffix@,)
vvp/vvp -M- -M./vpi ./check.vvp | grep 'Hello, World'
else
# On Windows if we have a suffix we must run the vvp part of
# the test with a suffix since it was built/linked that way.
ln vvp/vvp.exe vvp/vvp$(suffix).exe
vvp/vvp$(suffix) -M- -M./vpi ./check.vvp | grep 'Hello, World'
rm vvp/vvp$(suffix).exe
endif
else
vvp/vvp -M- -M./vpi ./check.vvp | grep 'Hello, World'
endif
clean:
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) $@); done
for dir in vpi ivlpp tgt-verilog tgt-pal driver driver-vpi; \
for tgt in $(TARGETS); do (cd $$tgt ; $(MAKE) $@); done
for dir in vpi ivlpp tgt-verilog tgt-stub driver; \
do (cd $$dir ; $(MAKE) $@); done
rm -f *.o parse.cc parse.cc.output parse.h lexor.cc
rm -f *.o parse.cc parse.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 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
distclean: clean
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) $@); done
for dir in vpi ivlpp tgt-verilog tgt-pal driver driver-vpi; \
for tgt in $(TARGETS); do (cd $$tgt ; $(MAKE) $@); done
for dir in vpi ivlpp tgt-verilog tgt-stub driver; \
do (cd $$dir ; $(MAKE) $@); done
rm -f Makefile config.status config.log config.cache config.h
rm -f Makefile config.status config.log config.cache
rm -f config.h
rm -f _pli_types.h
ifneq (@srcdir@,.)
rm -f check.conf
rmdir $(SUBDIRS)
endif
rm -rf autom4te.cache
TT = t-dll.o t-dll-api.o t-dll-expr.o t-dll-proc.o
FF = cprop.o nodangle.o synth.o synth2.o syn-rules.o
TT = t-dll.o t-dll-api.o t-dll-expr.o t-dll-proc.o t-xnf.o
FF = cprop.o nodangle.o synth.o synth2.o syn-rules.o xnfio.o
O = main.o async.o design_dump.o discipline.o dup_expr.o elaborate.o elab_expr.o \
elab_lval.o elab_net.o elab_pexpr.o elab_scope.o \
O = main.o async.o design_dump.o dup_expr.o elaborate.o elab_expr.o \
elab_lval.o elab_net.o elab_anet.o elab_pexpr.o elab_scope.o \
elab_sig.o emit.o eval.o eval_attrib.o \
eval_tree.o expr_synth.o functor.o lexor.o lexor_keyword.o link_const.o \
load_module.o netlist.o netmisc.o net_assign.o \
net_design.o net_event.o net_expr.o net_force.o net_func.o \
net_link.o net_modulo.o net_nex_input.o net_nex_output.o \
net_proc.o net_scope.o net_tran.o net_udp.o pad_to_width.o \
parse.o parse_misc.o pform.o pform_disciplines.o pform_dump.o pform_types.o \
net_proc.o net_scope.o net_udp.o net_variable.o pad_to_width.o \
parse.o parse_misc.o pform.o pform_dump.o \
set_width.o symbol_search.o sync.o sys_funcs.o \
verinum.o verireal.o target.o targets.o \
Attrib.o HName.o LineInfo.o Module.o PDelays.o PEvent.o \
PExpr.o PGate.o PGenerate.o PScope.o PSpec.o \
Attrib.o HName.o LineInfo.o Module.o PData.o PDelays.o PEvent.o \
PExpr.o PGate.o \
PTask.o PUdp.o PFunction.o PWire.o Statement.o StringHeap.o \
$(FF) $(TT)
@@ -132,6 +163,7 @@ ivl@EXEEXT@: $O $(srcdir)/ivl.def
else
ivl@EXEEXT@: $O
$(CXX) $(LDFLAGS) -o ivl@EXEEXT@ $O $(dllib)
endif
ifeq (@MINGW32@,yes)
@@ -141,10 +173,13 @@ all: dep iverilog-vpi
iverilog-vpi: iverilog-vpi.sh
sed -e 's;@SHARED@;@shared@;' -e 's;@PIC@;@PICFLAG@;' \
-e 's;@SUFFIX@;$(suffix);' \
-e 's;@IVCC@;$(CC);' \
-e 's;@IVCXX@;$(CXX);' \
-e 's;@IVCFLAGS@;$(CXXFLAGS);' \
-e 's;@INCLUDEDIR@;@includedir@;' \
-e 's;@LIBDIR64@;@libdir64@;' \
-e 's;@VPIDIR1@;@vpidir1@;' -e 's;@VPIDIR2@;@vpidir2@;' \
-e 's;@INCLUDEDIR@;$(includedir);' \
-e 's;@LIBDIR@;@libdir@;' $< > $@
chmod +x $@
endif
@@ -153,7 +188,7 @@ dep:
mkdir dep
%.o: %.cc
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -MD -c $< -o $*.o
$(CXX) $(CPPFLAGS) $(CXXFLAGS) @DEPENDENCY_CPPFLAGS@ -c $< -o $*.o $(DEBUGFLAGS)
mv $*.d dep/$*.d
@@ -174,7 +209,7 @@ lexor.cc: $(srcdir)/lexor.lex
lexor_keyword.o: lexor_keyword.cc parse.h
lexor_keyword.cc: lexor_keyword.gperf
gperf -o -i 7 -C -k 1-4,$$ -L ANSI-C -H keyword_hash -N check_identifier -t $(srcdir)/lexor_keyword.gperf > lexor_keyword.cc || (rm -f lexor_keyword.cc ; false)
gperf -o -i 7 -C -k 1-3,$$ -L ANSI-C -H keyword_hash -N check_identifier -t $(srcdir)/lexor_keyword.gperf > lexor_keyword.cc || (rm -f lexor_keyword.cc ; false)
iverilog-vpi.ps: $(srcdir)/iverilog-vpi.man
$(MAN) -t $(srcdir)/iverilog-vpi.man > iverilog-vpi.ps
@@ -182,136 +217,93 @@ iverilog-vpi.ps: $(srcdir)/iverilog-vpi.man
iverilog-vpi.pdf: iverilog-vpi.ps
$(PS2PDF) iverilog-vpi.ps iverilog-vpi.pdf
# For VERSION_TAG in driver/main.c, first try git-describe, then look for a
# version.h file in the source tree (included in snapshots and releases), and
# finally use nothing.
.PHONY: version.h
# "true" and "false" in the next few lines are Unix shell command names
ifeq ($(GIT),none)
GIT_PRESENT = false
else
GIT_PRESENT = true
endif
version.h:
@if $(GIT_PRESENT) && test -d $(srcdir)/.git; then \
echo "Using git-describe for VERSION_TAG"; \
tmp=`$(GIT) --git-dir $(srcdir)/.git describe \
| sed -e 's;\(.*\);#define VERSION_TAG "\1";'`; \
echo "$$tmp" | diff - $@ > /dev/null 2>&1 || echo "$$tmp" > $@ || exit 1; \
elif test -r $(srcdir)/$@; then \
echo "Using $(srcdir)/$@ for VERSION_TAG"; \
diff $(srcdir)/$@ $@ > /dev/null 2>&1 || cp $(srcdir)/$@ $@; \
else \
echo "Using empty VERSION_TAG"; \
echo '#define VERSION_TAG ""' > $@; \
fi
ifeq (@MINGW32@,yes)
# Build and install the iverilog-vpi.pdf only if there is a man
# program *and* a ps2pdf program.
ifeq (@WIN32@,yes)
ifeq ($(MAN),none)
INSTALL_DOC = $(mandir)/man1/iverilog-vpi.1
INSTALL_DOC = $(mandir)/man1/iverilog-vpi$(suffix).1
else
ifeq ($(PS2PDF),none)
INSTALL_DOC = $(mandir)/man1/iverilog-vpi.1
INSTALL_DOC = $(mandir)/man1/iverilog-vpi$(suffix).1
else
INSTALL_DOC = $(prefix)/iverilog-vpi.pdf $(mandir)/man1/iverilog-vpi.1
INSTALL_DOC = $(prefix)/iverilog-vpi$(suffix).pdf $(mandir)/man1/iverilog-vpi$(suffix).1
all: dep iverilog-vpi.pdf
endif
endif
INSTALL_DOCDIR = $(mandir)/man1
else
INSTALL_DOC = $(mandir)/man1/iverilog-vpi.1
INSTALL_DOC = $(mandir)/man1/iverilog-vpi$(suffix).1
INSTALL_DOCDIR = $(mandir)/man1
endif
ifeq (@MINGW32@,yes)
WIN32_INSTALL = $(prefix)/hello.vl $(prefix)/sqrt.vl $(prefix)/sqrt-virtex.v $(prefix)/QUICK_START.txt
WIN32_INSTALL =
else
WIN32_INSTALL = $(bindir)/iverilog-vpi
WIN32_INSTALL = $(bindir)/iverilog-vpi$(suffix)
endif
XNF_INSTALL = $(libdir)/ivl/xnf.conf $(libdir)/ivl/xnf-s.conf
XNF_INSTALL = $(libdir)/ivl$(suffix)/xnf.conf $(libdir)/ivl$(suffix)/xnf-s.conf
install: all installdirs $(libdir)/ivl/ivl@EXEEXT@ $(libdir)/ivl/include/constants.vams $(libdir)/ivl/include/disciplines.vams $(includedir)/ivl_target.h $(includedir)/_pli_types.h $(includedir)/vpi_user.h $(includedir)/acc_user.h $(includedir)/veriuser.h $(WIN32_INSTALL) $(INSTALL_DOC)
install: all installdirs $(libdir)/ivl$(suffix)/ivl@EXEEXT@ $(includedir)/ivl_target.h $(includedir)/_pli_types.h $(includedir)/vpi_user.h $(includedir)/acc_user.h $(includedir)/veriuser.h $(WIN32_INSTALL) $(INSTALL_DOC) $(XNF_INSTALL)
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) $@); done
for tgt in $(TARGETS); do (cd $$tgt ; $(MAKE) $@); done
for dir in vpi ivlpp driver; \
do (cd $$dir ; $(MAKE) $@); done
$(bindir)/iverilog-vpi: ./iverilog-vpi
$(INSTALL_SCRIPT) ./iverilog-vpi $(DESTDIR)$(bindir)/iverilog-vpi
$(DESTDIR)$(bindir)/iverilog-vpi$(suffix): ./iverilog-vpi
$(INSTALL_SCRIPT) ./iverilog-vpi $(DESTDIR)$(bindir)/iverilog-vpi$(suffix)
$(libdir)/ivl/ivl@EXEEXT@: ./ivl@EXEEXT@
$(INSTALL_PROGRAM) ./ivl@EXEEXT@ $(DESTDIR)$(libdir)/ivl/ivl@EXEEXT@
$(libdir)/ivl$(suffix)/ivl@EXEEXT@: ./ivl@EXEEXT@
$(INSTALL_PROGRAM) ./ivl@EXEEXT@ $(DESTDIR)$(libdir)/ivl$(suffix)/ivl@EXEEXT@
$(libdir)/ivl/include/constants.vams: $(srcdir)/constants.vams
$(INSTALL_DATA) $(srcdir)/constants.vams $@
$(DESTDIR)$(libdir)/ivl$(suffix)/xnf-s.conf: $(srcdir)/xnf-s.conf
$(INSTALL_DATA) $(srcdir)/xnf-s.conf $(DESTDIR)$(libdir)/ivl$(suffix)/xnf-s.conf
$(libdir)/ivl/include/disciplines.vams: $(srcdir)/disciplines.vams
$(INSTALL_DATA) $(srcdir)/disciplines.vams $@
$(DESTDIR)$(libdir)/ivl$(suffix)/xnf.conf: $(srcdir)/xnf.conf
$(INSTALL_DATA) $(srcdir)/xnf.conf $(DESTDIR)$(libdir)/ivl$(suffix)/xnf.conf
$(libdir)/ivl/xnf-s.conf: $(srcdir)/xnf-s.conf
$(INSTALL_DATA) $(srcdir)/xnf-s.conf $(DESTDIR)$(libdir)/ivl/xnf-s.conf
$(libdir)/ivl/xnf.conf: $(srcdir)/xnf.conf
$(INSTALL_DATA) $(srcdir)/xnf.conf $(DESTDIR)$(libdir)/ivl/xnf.conf
$(includedir)/ivl_target.h: $(srcdir)/ivl_target.h
$(DESTDIR)$(includedir)/ivl_target.h: $(srcdir)/ivl_target.h
$(INSTALL_DATA) $(srcdir)/ivl_target.h $(DESTDIR)$(includedir)/ivl_target.h
$(includedir)/_pli_types.h: _pli_types.h
$(DESTDIR)$(includedir)/_pli_types.h: _pli_types.h
$(INSTALL_DATA) $< $(DESTDIR)$(includedir)/_pli_types.h
$(includedir)/vpi_user.h: $(srcdir)/vpi_user.h
$(DESTDIR)$(includedir)/vpi_user.h: $(srcdir)/vpi_user.h
$(INSTALL_DATA) $(srcdir)/vpi_user.h $(DESTDIR)$(includedir)/vpi_user.h
$(includedir)/acc_user.h: $(srcdir)/acc_user.h
$(DESTDIR)$(includedir)/acc_user.h: $(srcdir)/acc_user.h
$(INSTALL_DATA) $(srcdir)/acc_user.h $(DESTDIR)$(includedir)/acc_user.h
$(includedir)/veriuser.h: $(srcdir)/veriuser.h
$(DESTDIR)$(includedir)/veriuser.h: $(srcdir)/veriuser.h
$(INSTALL_DATA) $(srcdir)/veriuser.h $(DESTDIR)$(includedir)/veriuser.h
$(mandir)/man1/iverilog-vpi.1: $(srcdir)/iverilog-vpi.man
$(INSTALL_DATA) $(srcdir)/iverilog-vpi.man $(DESTDIR)$(mandir)/man1/iverilog-vpi.1
$(DESTDIR)$(mandir)/man1/iverilog-vpi$(suffix).1: $(srcdir)/iverilog-vpi.man
$(INSTALL_DATA) $(srcdir)/iverilog-vpi.man $(DESTDIR)$(mandir)/man1/iverilog-vpi$(suffix).1
$(prefix)/iverilog-vpi.pdf: iverilog-vpi.pdf
$(INSTALL_DATA) iverilog-vpi.pdf $(DESTDIR)$(prefix)/iverilog-vpi.pdf
$(DESTDIR)$(prefix)/iverilog-vpi$(suffix).pdf: iverilog-vpi.pdf
$(INSTALL_DATA) iverilog-vpi.pdf $(DESTDIR)$(prefix)/iverilog-vpi$(suffix).pdf
# In windows installations, put a few examples and the quick_start
# into the destination directory.
ifeq (@MINGW32@,yes)
$(prefix)/hello.vl: $(srcdir)/examples/hello.vl
./dosify.exe $(srcdir)/examples/hello.vl tmp.vl
mv tmp.vl $(prefix)/hello.vl
$(prefix)/sqrt.vl: $(srcdir)/examples/sqrt.vl
./dosify.exe $(srcdir)/examples/sqrt.vl tmp.vl
mv tmp.vl $(prefix)/sqrt.vl
$(prefix)/sqrt-virtex.v: $(srcdir)/examples/sqrt-virtex.v
./dosify.exe $(srcdir)/examples/sqrt-virtex.v tmp.vl
mv tmp.vl $(prefix)/sqrt-virtex.v
$(prefix)/QUICK_START.txt: $(srcdir)/QUICK_START.txt
./dosify.exe $(srcdir)/QUICK_START.txt tmp.txt
mv tmp.txt $(prefix)/QUICK_START.txt
endif
installdirs: mkinstalldirs
$(srcdir)/mkinstalldirs $(DESTDIR)$(bindir) $(DESTDIR)$(includedir) $(DESTDIR)$(libdir)/ivl \
$(DESTDIR)$(libdir)/ivl/include $(DESTDIR)$(mandir) $(DESTDIR)$(mandir)/man1
$(srcdir)/mkinstalldirs $(DESTDIR)$(bindir) $(DESTDIR)$(includedir) $(DESTDIR)$(libdir)/ivl$(suffix) \
$(DESTDIR)$(libdir)/ivl$(suffix)/include $(DESTDIR)$(mandir) $(DESTDIR)$(mandir)/man1
uninstall:
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) $@); done
for tgt in $(TARGETS); do (cd $$tgt ; $(MAKE) $@); done
for dir in vpi ivlpp driver; \
do (cd $$dir ; $(MAKE) $@); done
for f in xnf.conf xnf-s.conf ivl@EXEEXT@ include/constants.vams include/disciplines.vams; \
do rm -f $(DESTDIR)$(libdir)/ivl/$$f; done
-rmdir $(DESTDIR)$(libdir)/ivl/include
-rmdir $(DESTDIR)$(libdir)/ivl
for f in verilog iverilog-vpi gverilog@EXEEXT@; \
for f in xnf.conf xnf-s.conf ivl@EXEEXT@; \
do rm -f $(DESTDIR)$(libdir)/ivl$(suffix)/$$f; done
-rmdir $(DESTDIR)$(libdir)/ivl$(suffix)/include
-rmdir $(DESTDIR)$(libdir)/ivl$(suffix)
for f in verilog$(suffix) iverilog-vpi$(suffix); \
do rm -f $(DESTDIR)$(bindir)/$$f; done
for f in ivl_target.h vpi_user.h _pli_types.h acc_user.h veriuser.h; \
do rm -f $(DESTDIR)$(includedir)/$$f; done
rm -f $(DESTDIR)$(mandir)/man1/iverilog-vpi.1 $(DESTDIR)$(prefix)/iverilog-vpi.pdf
-test X$(suffix) = X || rmdir $(DESTDIR)$(includedir)
rm -f $(DESTDIR)$(mandir)/man1/iverilog-vpi$(suffix).1
rm -f $(DESTDIR)$(prefix)/iverilog-vpi$(suffix).pdf
-include $(patsubst %.o, dep/%.d, $O)
+35 -3
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998-2008 Stephen Williams ([email protected])
* Copyright (c) 1998-2010 Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -26,9 +26,8 @@
/* n is a permallocated string. */
Module::Module(perm_string n)
: PScope(n, 0)
: name_(n)
{
library_flag = false;
default_nettype = NetNet::NONE;
}
@@ -51,6 +50,21 @@ void Module::add_function(perm_string name, PFunction *func)
funcs_[name] = func;
}
PWire* Module::add_wire(PWire*wire)
{
PWire*&ep = wires_[wire->path()];
if (ep) return ep;
assert(ep == 0);
ep = wire;
return wire;
}
void Module::add_behavior(PProcess*b)
{
behaviors_.push_back(b);
}
unsigned Module::port_count() const
{
return ports.count();
@@ -93,6 +107,15 @@ unsigned Module::find_port(const char*name) const
}
PWire* Module::get_wire(const hname_t&name) const
{
map<hname_t,PWire*>::const_iterator obj = wires_.find(name);
if (obj == wires_.end())
return 0;
else
return (*obj).second;
}
PGate* Module::get_gate(perm_string name)
{
for (list<PGate*>::iterator cur = gates_.begin()
@@ -106,8 +129,17 @@ PGate* Module::get_gate(perm_string name)
return 0;
}
const map<hname_t,PWire*>& Module::get_wires() const
{
return wires_;
}
const list<PGate*>& Module::get_gates() const
{
return gates_;
}
const list<PProcess*>& Module::get_behaviors() const
{
return behaviors_;
}
+31 -54
View File
@@ -1,7 +1,7 @@
#ifndef __Module_H
#define __Module_H
/*
* Copyright (c) 1998-2008 Stephen Williams ([email protected])
* Copyright (c) 1998-2010 Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -19,22 +19,19 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
# include <list>
# include <map>
# include "svector.h"
# include "StringHeap.h"
# include "HName.h"
# include "named.h"
# include "PScope.h"
# include "LineInfo.h"
# include "netlist.h"
# include "pform_types.h"
class PData;
class PEvent;
class PExpr;
class PEIdent;
class PGate;
class PGenerate;
class PSpecPath;
class PTask;
class PFunction;
class PWire;
@@ -48,7 +45,7 @@ class NetScope;
* therefore the handle for grasping the described circuit.
*/
class Module : public PScope, public LineInfo {
class Module : public LineInfo {
/* The module ports are in general a vector of port_t
objects. Each port has a name and an ordered list of
@@ -67,43 +64,16 @@ class Module : public PScope, public LineInfo {
explicit Module(perm_string name);
~Module();
/* Initially false. This is set to true if the module has been
declared as a library module. This makes the module
ineligible for being chosen as an implicit root. It has no
other effect. */
bool library_flag;
NetNet::Type default_nettype;
struct range_t {
// True if this is an exclude
bool exclude_flag;
// lower bound
// If low_open_flag is false and low_expr=0, then use -inf
bool low_open_flag;
PExpr*low_expr;
// upper bound
// If high_open_flag is false and high_expr=0, then use +inf
bool high_open_flag;
PExpr*high_expr;
// Next range description in list
struct range_t*next;
};
/* The module has parameters that are evaluated when the
module is elaborated. During parsing, I put the parameters
into this map. */
struct param_expr_t : public LineInfo {
param_expr_t() : type(IVL_VT_NO_TYPE), msb(0), lsb(0), signed_flag(false), expr(0), range(0) { }
// Type information
ivl_variable_type_t type;
struct param_expr_t {
PExpr*expr;
PExpr*msb;
PExpr*lsb;
bool signed_flag;
// Value expression
PExpr*expr;
// If there are range constrants, list them here
range_t*range;
};
map<perm_string,param_expr_t>parameters;
map<perm_string,param_expr_t>localparams;
@@ -118,7 +88,7 @@ class Module : public PScope, public LineInfo {
new parameters within the module, but may be used to set
values within this module (when instantiated) or in other
instantiated modules. */
map<pform_name_t,PExpr*>defparms;
map<hname_t,PExpr*>defparms;
/* Parameters may be overridden at instantiation time;
the overrides do not contain explicit parameter names,
@@ -132,26 +102,28 @@ class Module : public PScope, public LineInfo {
named array of PEident pointers. */
svector<port_t*> ports;
/* Keep a table of named events declared in the module. */
map<perm_string,PEvent*>events;
/* Keep a table of datum variables declared in the module. */
map<hname_t,PData*>datum;
map<perm_string,PExpr*> attributes;
/* These are the timescale for this module. The default is
set by the `timescale directive. */
int time_unit, time_precision;
/* The module has a list of genvars that may be used in
various generate schemes. */
map<perm_string,LineInfo*> genvars;
/* the module has a list of generate schemes that appear in
the module definition. These are used at elaboration time. */
list<PGenerate*> generate_schemes;
list<PSpecPath*> specify_paths;
// The mod_name() is the name of the module type.
perm_string mod_name() const { return pscope_name(); }
perm_string mod_name() const { return name_; }
void add_gate(PGate*gate);
// The add_wire method adds a wire by name, but only if the
// wire name doesn't already exist. Either way, the result is
// the existing wire or the pointer passed in.
PWire* add_wire(PWire*wire);
void add_behavior(PProcess*behave);
void add_task(perm_string name, PTask*def);
void add_function(perm_string name, PFunction*def);
@@ -159,26 +131,31 @@ class Module : public PScope, public LineInfo {
const svector<PEIdent*>& get_port(unsigned idx) const;
unsigned find_port(const char*name) const;
// Find a wire by name. This is used for connecting gates to
// existing wires, etc.
PWire* get_wire(const hname_t&name) const;
PGate* get_gate(perm_string name);
const map<hname_t,PWire*>& get_wires() const;
const list<PGate*>& get_gates() const;
const list<PProcess*>& get_behaviors() const;
void dump(ostream&out) const;
bool elaborate(Design*, NetScope*scope) const;
typedef map<perm_string,NetExpr*> replace_t;
bool elaborate_scope(Design*, NetScope*scope, const replace_t&rep) const;
bool elaborate_scope(Design*, NetScope*scope) const;
bool elaborate_sig(Design*, NetScope*scope) const;
private:
perm_string name_;
map<hname_t,PWire*> wires_;
list<PGate*> gates_;
list<PProcess*> behaviors_;
map<perm_string,PTask*> tasks_;
map<perm_string,PFunction*> funcs_;
static void elaborate_parm_item_(perm_string name, const param_expr_t&cur,
Design*des, NetScope*scope);
private: // Not implemented
Module(const Module&);
Module& operator= (const Module&);
+14 -6
View File
@@ -1,7 +1,5 @@
#ifndef __vvp_island_H
#define __vvp_island_H
/*
* Copyright (c) 2008 Stephen Williams (steve@icarus.com)
* Copyright (c) 2003-2010 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -20,8 +18,18 @@
*/
# include "config.h"
# include "vvp_net.h"
# include <assert.h>
# include "PData.h"
PData::PData(const hname_t&h)
: hname_(h)
{
}
#endif
PData::~PData()
{
}
const hname_t&PData::name() const
{
return hname_;
}
+25 -15
View File
@@ -1,7 +1,7 @@
#ifndef __sfunc_H
#define __sfunc_H
#ifndef __PData_H
#define __PData_H
/*
* Copyright (c) 2006-2008 Stephen Williams (steve@icarus.com)
* Copyright (c) 2003-2010 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -19,25 +19,35 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
# include "pointers.h"
# include "HName.h"
# include "netlist.h"
# include "LineInfo.h"
class sfunc_core : public vvp_wide_fun_core, protected vvp_gen_event_s {
/*
* The PData object represents declaration of atomic datum such as
* real and realtime variables. These are variables that cannot be bit
* or part selected, but can be used in expressions.
*/
class PData : public LineInfo {
public:
sfunc_core(vvp_net_t*ptr, vpiHandle sys, unsigned argc, vpiHandle*argv);
~sfunc_core();
PData(const hname_t&hname);
~PData();
// Return a hierarchical name.
const hname_t&name() const;
void elaborate_scope(Design*des, NetScope*scope) const;
map<string,PExpr*> attributes;
private:
void recv_vec4_from_inputs(unsigned port);
void recv_real_from_inputs(unsigned port);
void run_run();
hname_t hname_;
private:
vpiHandle sys_;
unsigned argc_;
vpiHandle*argv_;
PData(const PData&);
PData& operator= (const PData&);
};
#endif
+33 -41
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1999-2008 Stephen Williams ([email protected])
* Copyright (c) 1999-2010 Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -24,7 +24,6 @@
# include "PDelays.h"
# include "PExpr.h"
# include "verinum.h"
# include "netmisc.h"
PDelays::PDelays()
{
@@ -60,11 +59,29 @@ void PDelays::set_delays(const svector<PExpr*>*del, bool df)
delete_flag_ = df;
}
static NetExpr*calculate_val(Design*des, NetScope*scope, const PExpr*expr)
static unsigned long calculate_val(Design*des, NetScope*scope,
const PExpr*expr)
{
NetExpr*dex = expr->elaborate_expr(des, scope, -1, false);
eval_expr(dex);
NetExpr*dex = expr->elaborate_expr(des, scope);
if (NetExpr*tmp = dex->eval_tree()) {
delete dex;
dex = tmp;
}
int shift = scope->time_unit() - des->get_precision();
if (sizeof(unsigned) <= 4 && shift > 9) {
cerr << expr->get_line() << ": error: Precision overflow"
<< " in scope " << scope->name() << "." << endl;
cerr << expr->get_line() << ": :"
<< " Units are 10e" << scope->time_unit()
<< " minus precision 10e" << des->get_precision()
<< " is 10e" << shift << "." << endl;
cerr << expr->get_line() << ": : Perhaps a timescale "
<< "is missing or incorrect?" << endl;
des->errors += 1;
return 0;
}
/* If the delay expression is a real constant or vector
constant, then evaluate it, scale it to the local time
@@ -73,15 +90,12 @@ static NetExpr*calculate_val(Design*des, NetScope*scope, const PExpr*expr)
if (NetECReal*tmp = dynamic_cast<NetECReal*>(dex)) {
verireal fn = tmp->value();
int shift = scope->time_unit() - des->get_precision();
long delay = fn.as_long(shift);
if (delay < 0)
delay = 0;
delete tmp;
NetEConst*tmp2 = new NetEConst(verinum(delay));
tmp2->set_line(*expr);
return tmp2;
return delay;
}
@@ -92,57 +106,35 @@ static NetExpr*calculate_val(Design*des, NetScope*scope, const PExpr*expr)
des->scale_to_precision(fn.as_ulong(), scope);
delete tmp;
NetEConst*tmp2 = new NetEConst(verinum(delay));
tmp2->set_line(*expr);
return tmp2;
return delay;
}
/* Oops, cannot evaluate down to a constant. */
return dex;
}
/* Oops, cannot evaluate down to a constant. Error message. */
delete dex;
static NetExpr* make_delay_nets(Design*des, NetExpr*expr)
{
if (dynamic_cast<NetESignal*> (expr))
return expr;
cerr << expr->get_line() << ": sorry: non-constant "
<< "delays not supported here: " << *expr << endl;
des->errors += 1;
return 0;
if (dynamic_cast<NetEConst*> (expr))
return expr;
NetNet*sig = expr->synthesize(des);
if (sig == 0) {
cerr << expr->get_fileline() << ": error: Expression " << *expr
<< " is not suitable for delay expression." << endl;
return 0;
}
expr = new NetESignal(sig);
return expr;
}
void PDelays::eval_delays(Design*des, NetScope*scope,
NetExpr*&rise_time,
NetExpr*&fall_time,
NetExpr*&decay_time,
bool as_nets_flag) const
unsigned long&rise_time,
unsigned long&fall_time,
unsigned long&decay_time) const
{
assert(scope);
if (delay_[0]) {
rise_time = calculate_val(des, scope, delay_[0]);
if (as_nets_flag)
rise_time = make_delay_nets(des, rise_time);
if (delay_[1]) {
fall_time = calculate_val(des, scope, delay_[1]);
if (as_nets_flag)
fall_time = make_delay_nets(des, fall_time);
if (delay_[2]) {
decay_time = calculate_val(des, scope, delay_[2]);
if (as_nets_flag)
decay_time = make_delay_nets(des, decay_time);
} else {
if (rise_time < fall_time)
+4 -39
View File
@@ -1,7 +1,7 @@
#ifndef __PDelays_H
#define __PDelays_H
/*
* Copyright (c) 1999-2002 Stephen Williams ([email protected])
* Copyright (c) 1999-2010 Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -18,9 +18,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: PDelays.h,v 1.9 2006/01/03 05:22:14 steve Exp $"
#endif
# include "svector.h"
# include <string>
@@ -34,7 +31,6 @@ using namespace std;
class Design;
class NetScope;
class NetExpr;
class PExpr;
/*
@@ -54,10 +50,9 @@ class PDelays {
void set_delays(const svector<PExpr*>*del, bool delete_flag=true);
void eval_delays(Design*des, NetScope*scope,
NetExpr*&rise_time,
NetExpr*&fall_time,
NetExpr*&decay_time,
bool as_nets_flag =false) const;
unsigned long&rise_time,
unsigned long&fall_time,
unsigned long&decay_time) const;
void dump_delays(ostream&out) const;
@@ -72,34 +67,4 @@ class PDelays {
ostream& operator << (ostream&o, const PDelays&);
/*
* $Log: PDelays.h,v $
* Revision 1.9 2006/01/03 05:22:14 steve
* Handle complex net node delays.
*
* Revision 1.8 2006/01/02 05:33:19 steve
* Node delays can be more general expressions in structural contexts.
*
* Revision 1.7 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.6 2002/06/14 03:25:51 steve
* Compiler portability.
*
* Revision 1.5 2001/12/29 20:19:31 steve
* Do not delete delay expressions of UDP instances.
*
* Revision 1.4 2001/11/22 06:20:59 steve
* Use NetScope instead of string for scope path.
*
* Revision 1.3 2001/01/16 02:44:17 steve
* Use the iosfwd header if available.
*
* Revision 1.2 2000/02/23 02:56:53 steve
* Macintosh compilers do not support ident.
*
* Revision 1.1 1999/09/04 19:11:46 steve
* Add support for delayed non-blocking assignments.
*
*/
#endif
+1 -28
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2004 Stephen Williams ([email protected])
* Copyright (c) 2004-2010 Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -16,9 +16,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: PEvent.cc,v 1.5 2004/02/19 06:57:10 steve Exp $"
#endif
# include "config.h"
@@ -37,27 +34,3 @@ perm_string PEvent::name() const
{
return name_;
}
/*
* $Log: PEvent.cc,v $
* Revision 1.5 2004/02/19 06:57:10 steve
* Memory and Event names use perm_string.
*
* Revision 1.4 2003/03/01 06:25:30 steve
* Add the lex_strings string handler, and put
* scope names and system task/function names
* into this table. Also, permallocate event
* names from the beginning.
*
* Revision 1.3 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.2 2001/07/25 03:10:48 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
*
* Revision 1.1 2000/04/01 19:31:57 steve
* Named events as far as the pform.
*
*/
+1 -38
View File
@@ -1,7 +1,7 @@
#ifndef __PEvent_H
#define __PEvent_H
/*
* Copyright (c) 2000-2004 Stephen Williams ([email protected])
* Copyright (c) 2000-2010 Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -18,9 +18,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: PEvent.h,v 1.9 2004/02/19 06:57:10 steve Exp $"
#endif
# include "LineInfo.h"
# include "StringHeap.h"
@@ -54,38 +51,4 @@ class PEvent : public LineInfo {
PEvent& operator= (const PEvent&);
};
/*
* $Log: PEvent.h,v $
* Revision 1.9 2004/02/19 06:57:10 steve
* Memory and Event names use perm_string.
*
* Revision 1.8 2003/03/01 06:25:30 steve
* Add the lex_strings string handler, and put
* scope names and system task/function names
* into this table. Also, permallocate event
* names from the beginning.
*
* Revision 1.7 2003/01/30 16:23:07 steve
* Spelling fixes.
*
* Revision 1.6 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.5 2001/12/03 04:47:14 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
*
* Revision 1.4 2001/01/16 02:44:18 steve
* Use the iosfwd header if available.
*
* Revision 1.3 2000/04/09 17:44:30 steve
* Catch event declarations during scope elaborate.
*
* Revision 1.2 2000/04/04 03:20:15 steve
* Simulate named event trigger and waits.
*
* Revision 1.1 2000/04/01 19:31:57 steve
* Named events as far as the pform.
*
*/
#endif
+21 -63
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998-2007 Stephen Williams <[email protected]>
* Copyright (c) 1998-2010 Stephen Williams <[email protected]>
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -43,17 +43,9 @@ bool PExpr::is_constant(Module*) const
return false;
}
NetNet* PExpr::elaborate_lnet(Design*des, NetScope*) const
NetNet* PExpr::elaborate_lnet(Design*des, NetScope*, bool) const
{
cerr << get_fileline() << ": error: expression not valid in assign l-value: "
<< *this << endl;
return 0;
}
NetNet* PExpr::elaborate_bi_net(Design*des, NetScope*) const
{
cerr << get_fileline() << ": error: "
<< "expression not valid as argument to inout port: "
cerr << get_line() << ": error: expression not valid in assign l-value: "
<< *this << endl;
return 0;
}
@@ -72,44 +64,13 @@ bool PEBinary::is_constant(Module*mod) const
return left_->is_constant(mod) && right_->is_constant(mod);
}
PEBComp::PEBComp(char op, PExpr*l, PExpr*r)
: PEBinary(op, l, r)
{
}
PEBComp::~PEBComp()
{
}
PEBShift::PEBShift(char op, PExpr*l, PExpr*r)
: PEBinary(op, l, r)
{
}
PEBShift::~PEBShift()
{
}
PECallFunction::PECallFunction(const pform_name_t&n, const svector<PExpr *> &parms)
PECallFunction::PECallFunction(const hname_t&n, const svector<PExpr *> &parms)
: path_(n), parms_(parms)
{
}
static pform_name_t pn_from_ps(perm_string n)
{
name_component_t tmp_name (n);
pform_name_t tmp;
tmp.push_back(tmp_name);
return tmp;
}
PECallFunction::PECallFunction(perm_string n, const svector<PExpr*>&parms)
: path_(pn_from_ps(n)), parms_(parms)
{
}
PECallFunction::PECallFunction(perm_string n)
: path_(pn_from_ps(n))
PECallFunction::PECallFunction(const hname_t&n)
: path_(n)
{
}
@@ -126,6 +87,8 @@ bool PEConcat::is_constant(Module *mod) const
{
bool constant = repeat_? repeat_->is_constant(mod) : true;
for (unsigned i = 0; constant && i < parms_.count(); ++i) {
if (parms_[i] == 0)
continue;
constant = constant && parms_[i]->is_constant(mod);
}
return constant;
@@ -175,32 +138,33 @@ bool PEFNumber::is_constant(Module*) const
return true;
}
PEIdent::PEIdent(const pform_name_t&that)
: path_(that)
PEIdent::PEIdent(const hname_t&s)
: path_(s), msb_(0), lsb_(0), idx_(0)
{
}
PEIdent::PEIdent(perm_string s)
{
path_.push_back(name_component_t(s));
}
PEIdent::~PEIdent()
{
}
const hname_t& PEIdent::path() const
{
return path_;
}
/*
* An identifier can be in a constant expression if (and only if) it is
* a parameter or genvar.
*
* NOTE: This test does not work if the name is hierarchical!
* a parameter.
*/
bool PEIdent::is_constant(Module*mod) const
{
if (mod == 0) return false;
/* */
perm_string tmp = path_.back().name;
/* This is a work-around for map not matching < even when
there is a perm_string operator that can do the comprare.
The real fix is to make the path_ carry perm_strings. */
perm_string tmp = perm_string::literal(path_.peek_name(0));
{ map<perm_string,Module::param_expr_t>::const_iterator cur;
cur = mod->parameters.find(tmp);
@@ -212,11 +176,6 @@ bool PEIdent::is_constant(Module*mod) const
if (cur != mod->localparams.end()) return true;
}
{ map<perm_string,LineInfo*>::const_iterator cur;
cur = mod->genvars.find(tmp);
if (cur != mod->genvars.end()) return true;
}
return false;
}
@@ -299,4 +258,3 @@ bool PEUnary::is_constant(Module*m) const
{
return expr_->is_constant(m);
}
+122 -370
View File
@@ -1,7 +1,7 @@
#ifndef __PExpr_H
#define __PExpr_H
/*
* Copyright (c) 1998-2008 Stephen Williams <[email protected]>
* Copyright (c) 1998-2010 Stephen Williams <[email protected]>
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -20,11 +20,9 @@
*/
# include <string>
# include <vector>
# include "netlist.h"
# include "verinum.h"
# include "LineInfo.h"
# include "pform_types.h"
class Design;
class Module;
@@ -49,48 +47,11 @@ class PExpr : public LineInfo {
virtual void dump(ostream&) const;
// This method tests the width that the expression wants to
// be. It is used by elaboration of assignments to figure out
// the width of the expression.
//
// The "min" is the width of the local context, so it the
// minimum width that this function should return. Initially
// this is the same as the lval width.
//
// The "lval" is the width of the destination where this
// result is going to go. This can be used to constrain the
// amount that an expression can reasonably expand. For
// example, there is no point expanding an addition to beyond
// the lval. This extra bit of information allows the
// expression to optimize itself a bit. If the lval==0, then
// the subexpression should not make l-value related
// optimizations.
//
// The unsigned_flag is set to true if the expression is
// unsized and therefore expandable. This happens if a
// sub-expression is an unsized literal. Some expressions make
// special use of that.
virtual unsigned test_width(Design*des, NetScope*scope,
unsigned min, unsigned lval,
bool&unsized_flag) const;
// During the elaborate_sig phase, we may need to scan
// expressions to find implicit net declarations.
virtual bool elaborate_sig(Design*des, NetScope*scope) const;
// Procedural elaboration of the expression. The expr_width is
// the width of the context of the expression (i.e. the
// l-value width of an assignment),
//
// ... or -1 if the expression is self-determined. or
// ... or -2 if the expression is losslessly
// self-determined. This can happen in situations where the
// result is going to a pseudo-infinitely wide context.
//
// The sys_task_arg flag is true if expressions are allowed to
// be incomplete.
// Procedural elaboration of the expression. Set the
// bare_memory_ok flag if the result is allowed to be a
// NetEMemory without an index.
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
int expr_width, bool sys_task_arg) const;
bool sys_task_arg =false) const;
// Elaborate expressions that are the r-value of parameter
// assignments. This elaboration follows the restrictions of
@@ -102,36 +63,30 @@ class PExpr : public LineInfo {
// continuous assign or other wholly structural context.
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
unsigned lwidth,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay,
unsigned long rise,
unsigned long fall,
unsigned long decay,
Link::strength_t drive0 =Link::STRONG,
Link::strength_t drive1 =Link::STRONG)
const;
// This method elaborates the expression as NetNet objects. It
// only allows regs suitable for procedural continuous assignments.
virtual NetNet* elaborate_anet(Design*des, NetScope*scope) const;
// This method elaborates the expression as gates, but
// restricted for use as l-values of continuous assignments.
virtual NetNet* elaborate_lnet(Design*des, NetScope*scope) const;
// This is similar to elaborate_lnet, except that the
// expression is evaluated to be bi-directional. This is
// useful for arguments to inout ports of module instances and
// ports of tran primitives.
virtual NetNet* elaborate_bi_net(Design*des, NetScope*scope) const;
virtual NetNet* elaborate_lnet(Design*des, NetScope*scope,
bool implicit_net_ok =false) const;
// Expressions that can be in the l-value of procedural
// assignments can be elaborated with this method. If the
// is_force flag is true, then the set of valid l-value types
// is slightly modified to accommodate the Verilog force
// statement
virtual NetAssign_* elaborate_lval(Design*des,
NetScope*scope,
bool is_force) const;
// assignments can be elaborated with this method.
virtual NetAssign_* elaborate_lval(Design*des, NetScope*scope) const;
// This attempts to evaluate a constant expression, and return
// a verinum as a result. If the expression cannot be
// evaluated, return 0.
virtual verinum* eval_const(Design*des, NetScope*sc) const;
virtual verinum* eval_const(const Design*des, const NetScope*sc) const;
// This method returns true if that expression is the same as
// this expression. This method is used for comparing
@@ -157,30 +112,29 @@ class PEConcat : public PExpr {
PEConcat(const svector<PExpr*>&p, PExpr*r =0);
~PEConcat();
virtual verinum* eval_const(Design*des, NetScope*sc) const;
virtual verinum* eval_const(const Design*des, const NetScope*sc) const;
virtual void dump(ostream&) const;
virtual bool elaborate_sig(Design*des, NetScope*scope) const;
virtual NetNet* elaborate_lnet(Design*des, NetScope*scope) const;
virtual NetNet* elaborate_bi_net(Design*des, NetScope*scope) const;
// Concatenated Regs can be on the left of procedural
// continuous assignments.
virtual NetNet* elaborate_anet(Design*des, NetScope*scope) const;
virtual NetNet* elaborate_lnet(Design*des, NetScope*scope,
bool implicit_net_ok =false) const;
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
unsigned width,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay,
unsigned long rise,
unsigned long fall,
unsigned long decay,
Link::strength_t drive0,
Link::strength_t drive1) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
int expr_width, bool sys_task_arg) const;
bool sys_task_arg =false) const;
virtual NetEConcat*elaborate_pexpr(Design*des, NetScope*) const;
virtual NetAssign_* elaborate_lval(Design*des,
NetScope*scope,
bool is_force) const;
virtual NetAssign_* elaborate_lval(Design*des, NetScope*scope) const;
virtual bool is_constant(Module*) const;
private:
NetNet* elaborate_lnet_common_(Design*des, NetScope*scope,
bool bidirectional_flag) const;
private:
svector<PExpr*>parms_;
PExpr*repeat_;
@@ -227,23 +181,15 @@ class PEFNumber : public PExpr {
/* The eval_const method as applied to a floating point number
gets the *integer* value of the number. This accounts for
any rounding that is needed to get the value. */
virtual verinum* eval_const(Design*des, NetScope*sc) const;
virtual verinum* eval_const(const Design*des, const NetScope*sc) const;
/* A PEFNumber is a constant, so this returns true. */
virtual bool is_constant(Module*) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
int expr_width, bool sys_task_arg) const;
bool sys_task_arg =false) const;
virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
unsigned lwidth,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay,
Link::strength_t drive0,
Link::strength_t drive1) const;
virtual void dump(ostream&) const;
private:
@@ -253,42 +199,32 @@ class PEFNumber : public PExpr {
class PEIdent : public PExpr {
public:
explicit PEIdent(perm_string);
explicit PEIdent(const pform_name_t&);
explicit PEIdent(const hname_t&s);
~PEIdent();
// Add another name to the string of hierarchy that is the
// current identifier.
void append_name(perm_string);
virtual void dump(ostream&) const;
virtual unsigned test_width(Design*des, NetScope*scope,
unsigned min, unsigned lval,
bool&unsized_flag) const;
virtual bool elaborate_sig(Design*des, NetScope*scope) const;
// Regs can be on the left of procedural continuous assignments
virtual NetNet* elaborate_anet(Design*des, NetScope*scope) const;
// Identifiers are allowed (with restrictions) is assign l-values.
virtual NetNet* elaborate_lnet(Design*des, NetScope*scope) const;
virtual NetNet* elaborate_bi_net(Design*des, NetScope*scope) const;
virtual NetNet* elaborate_lnet(Design*des, NetScope*scope,
bool implicit_net_ok =false) const;
// Identifiers are also allowed as procedural assignment l-values.
virtual NetAssign_* elaborate_lval(Design*des,
NetScope*scope,
bool is_force) const;
virtual NetAssign_* elaborate_lval(Design*des, NetScope*scope) const;
// Structural r-values are OK.
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
unsigned lwidth,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay,
unsigned long rise,
unsigned long fall,
unsigned long decay,
Link::strength_t drive0,
Link::strength_t drive1) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
int expr_width, bool sys_task_arg) const;
bool sys_task_arg =false) const;
virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
// Elaborate the PEIdent as a port to a module. This method
@@ -296,116 +232,39 @@ class PEIdent : public PExpr {
NetNet* elaborate_port(Design*des, NetScope*sc) const;
virtual bool is_constant(Module*) const;
verinum* eval_const(Design*des, NetScope*sc) const;
verinum* eval_const(const Design*des, const NetScope*sc) const;
const pform_name_t& path() const { return path_; }
const hname_t& path() const;
private:
pform_name_t path_;
private:
// Common functions to calculate parts of part/bit selects.
bool calculate_parts_(Design*, NetScope*, long&msb, long&lsb) const;
NetExpr* calculate_up_do_base_(Design*, NetScope*) const;
bool calculate_param_range_(Design*, NetScope*,
const NetExpr*msb_ex, long&msb,
const NetExpr*lsb_ex, long&lsb) const;
bool calculate_up_do_width_(Design*, NetScope*, unsigned long&wid) const;
private:
NetAssign_*elaborate_lval_net_word_(Design*, NetScope*, NetNet*) const;
bool elaborate_lval_net_part_(Design*, NetScope*, NetAssign_*) const;
bool elaborate_lval_net_idx_(Design*, NetScope*, NetAssign_*,
index_component_t::ctype_t) const;
private:
NetExpr*elaborate_expr_param(Design*des,
NetScope*scope,
const NetExpr*par,
NetScope*found,
const NetExpr*par_msb,
const NetExpr*par_lsb) const;
NetExpr*elaborate_expr_param_part_(Design*des,
NetScope*scope,
const NetExpr*par,
NetScope*found,
const NetExpr*par_msb,
const NetExpr*par_lsb) const;
NetExpr*elaborate_expr_param_idx_up_(Design*des,
NetScope*scope,
const NetExpr*par,
NetScope*found,
const NetExpr*par_msb,
const NetExpr*par_lsb) const;
NetExpr*elaborate_expr_net(Design*des,
NetScope*scope,
NetNet*net,
NetScope*found,
bool sys_task_arg) const;
NetExpr*elaborate_expr_net_word_(Design*des,
NetScope*scope,
NetNet*net,
NetScope*found,
bool sys_task_arg) const;
NetExpr*elaborate_expr_net_part_(Design*des,
NetScope*scope,
NetESignal*net,
NetScope*found) const;
NetExpr*elaborate_expr_net_idx_up_(Design*des,
NetScope*scope,
NetESignal*net,
NetScope*found) const;
NetExpr*elaborate_expr_net_idx_do_(Design*des,
NetScope*scope,
NetESignal*net,
NetScope*found) const;
NetExpr*elaborate_expr_net_bit_(Design*des,
NetScope*scope,
NetESignal*net,
NetScope*found) const;
hname_t path_;
public:
// Use these to support bit- and part-select operators.
PExpr*msb_;
PExpr*lsb_;
NetNet* elaborate_net_array_(Design*des, NetScope*scope,
NetNet*sig, unsigned lwidth,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay,
Link::strength_t drive0,
Link::strength_t drive1) const;
// If this is a reference to a memory, this is the index
// expression.
PExpr*idx_;
NetNet* elaborate_net_ram_(Design*des, NetScope*scope,
NetMemory*mem, unsigned lwidth,
unsigned long rise,
unsigned long fall,
unsigned long decay) const;
NetNet* elaborate_net_net_(Design*des, NetScope*scope,
NetNet*sig, unsigned lwidth,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay,
Link::strength_t drive0,
Link::strength_t drive1) const;
NetNet* elaborate_net_net_idx_up_(Design*des, NetScope*scope,
NetNet*sig, unsigned lwidth,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay,
Link::strength_t drive0,
Link::strength_t drive1) const;
NetNet* elaborate_net_bitmux_(Design*des, NetScope*scope,
NetNet*sig,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay,
unsigned long rise,
unsigned long fall,
unsigned long decay,
Link::strength_t drive0,
Link::strength_t drive1) const;
private:
NetNet* elaborate_lnet_common_(Design*des, NetScope*scope,
bool bidirectional_flag) const;
NetNet*make_implicit_net_(Design*des, NetScope*scope) const;
bool eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
long&midx, long&lidx) const;
NetNet*process_select_(Design*des, NetScope*scope, NetNet*sig) const;
NetAssign_* elaborate_mem_lval_(Design*des, NetScope*scope,
NetMemory*mem) const;
};
@@ -418,25 +277,19 @@ class PENumber : public PExpr {
const verinum& value() const;
virtual void dump(ostream&) const;
virtual unsigned test_width(Design*des, NetScope*scope,
unsigned min, unsigned lval,
bool&unsized_flag) const;
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
unsigned lwidth,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay,
unsigned long rise,
unsigned long fall,
unsigned long decay,
Link::strength_t drive0,
Link::strength_t drive1) const;
virtual NetEConst*elaborate_expr(Design*des, NetScope*,
int expr_width, bool) const;
bool sys_task_arg =false) const;
virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
virtual NetAssign_* elaborate_lval(Design*des,
NetScope*scope,
bool is_force) const;
virtual NetAssign_* elaborate_lval(Design*des, NetScope*scope) const;
virtual verinum* eval_const(Design*des, NetScope*sc) const;
virtual verinum* eval_const(const Design*des, const NetScope*sc) const;
virtual bool is_the_same(const PExpr*that) const;
virtual bool is_constant(Module*) const;
@@ -460,22 +313,17 @@ class PEString : public PExpr {
string value() const;
virtual void dump(ostream&) const;
virtual unsigned test_width(Design*des, NetScope*scope,
unsigned min, unsigned lval,
bool&unsized_flag) const;
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
unsigned width,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay,
unsigned long rise,
unsigned long fall,
unsigned long decay,
Link::strength_t drive0,
Link::strength_t drive1) const;
virtual NetEConst*elaborate_expr(Design*des, NetScope*,
int expr_width, bool) const;
bool sys_task_arg =false) const;
virtual NetEConst*elaborate_pexpr(Design*des, NetScope*sc) const;
verinum* eval_const(Design*, NetScope*) const;
verinum* eval_const(const Design*, const NetScope*) const;
virtual bool is_constant(Module*) const;
@@ -490,49 +338,20 @@ class PEUnary : public PExpr {
~PEUnary();
virtual void dump(ostream&out) const;
virtual bool elaborate_sig(Design*des, NetScope*scope) const;
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
unsigned width,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay,
unsigned long rise,
unsigned long fall,
unsigned long decay,
Link::strength_t drive0,
Link::strength_t drive1) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
int expr_width, bool sys_task_arg) const;
bool sys_task_arg =false) const;
virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
virtual verinum* eval_const(Design*des, NetScope*sc) const;
virtual verinum* eval_const(const Design*des, const NetScope*sc) const;
virtual bool is_constant(Module*) const;
private:
NetNet* elab_net_uminus_const_logic_(Design*des, NetScope*scope,
NetEConst*expr,
unsigned width,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay,
Link::strength_t drive0,
Link::strength_t drive1) const;
NetNet* elab_net_uminus_const_real_(Design*des, NetScope*scope,
NetECReal*expr,
unsigned width,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay,
Link::strength_t drive0,
Link::strength_t drive1) const;
NetNet* elab_net_unary_real_(Design*des, NetScope*scope,
NetExpr*expr,
unsigned width,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay,
Link::strength_t drive0,
Link::strength_t drive1) const;
private:
char op_;
PExpr*expr_;
@@ -547,109 +366,65 @@ class PEBinary : public PExpr {
virtual bool is_constant(Module*) const;
virtual void dump(ostream&out) const;
virtual unsigned test_width(Design*des, NetScope*scope,
unsigned min, unsigned lval,
bool&unsized_flag) const;
virtual bool elaborate_sig(Design*des, NetScope*scope) const;
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
unsigned width,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay,
unsigned long rise,
unsigned long fall,
unsigned long decay,
Link::strength_t drive0,
Link::strength_t drive1) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
int expr_width, bool sys_task_arg) const;
bool sys_task_arg =false) const;
virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
virtual verinum* eval_const(Design*des, NetScope*sc) const;
virtual verinum* eval_const(const Design*des, const NetScope*sc) const;
protected:
private:
char op_;
PExpr*left_;
PExpr*right_;
NetExpr*elaborate_expr_base_(Design*, NetExpr*lp, NetExpr*rp, int use_wid) const;
NetExpr*elaborate_eval_expr_base_(Design*, NetExpr*lp, NetExpr*rp, int use_wid) const;
NetExpr*elaborate_expr_base_(Design*, NetExpr*lp, NetExpr*rp) const;
static void suppress_operand_sign_if_needed_(NetExpr*lp, NetExpr*rp);
private:
NetNet* elaborate_net_add_(Design*des, NetScope*scope,
unsigned lwidth,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay) const;
unsigned long rise,
unsigned long fall,
unsigned long decay) const;
NetNet* elaborate_net_bit_(Design*des, NetScope*scope,
unsigned lwidth,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay) const;
unsigned long rise,
unsigned long fall,
unsigned long decay) const;
NetNet* elaborate_net_cmp_(Design*des, NetScope*scope,
unsigned lwidth,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay) const;
unsigned long rise,
unsigned long fall,
unsigned long decay) const;
NetNet* elaborate_net_div_(Design*des, NetScope*scope,
unsigned lwidth,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay) const;
unsigned long rise,
unsigned long fall,
unsigned long decay) const;
NetNet* elaborate_net_mod_(Design*des, NetScope*scope,
unsigned lwidth,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay) const;
unsigned long rise,
unsigned long fall,
unsigned long decay) const;
NetNet* elaborate_net_log_(Design*des, NetScope*scope,
unsigned lwidth,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay) const;
unsigned long rise,
unsigned long fall,
unsigned long decay) const;
NetNet* elaborate_net_mul_(Design*des, NetScope*scope,
unsigned lwidth,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay) const;
NetNet* elaborate_net_pow_(Design*des, NetScope*scope,
unsigned lwidth,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay) const;
unsigned long rise,
unsigned long fall,
unsigned long decay) const;
NetNet* elaborate_net_shift_(Design*des, NetScope*scope,
unsigned lwidth,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay) const;
};
/*
* Here are a few specialized classes for handling specific binary
* operators.
*/
class PEBComp : public PEBinary {
public:
explicit PEBComp(char op, PExpr*l, PExpr*r);
~PEBComp();
virtual unsigned test_width(Design*des, NetScope*scope,
unsigned min, unsigned lval,
bool&flag) const;
NetExpr* elaborate_expr(Design*des, NetScope*scope,
int expr_width, bool sys_task_arg) const;
};
class PEBShift : public PEBinary {
public:
explicit PEBShift(char op, PExpr*l, PExpr*r);
~PEBShift();
virtual unsigned test_width(Design*des, NetScope*scope,
unsigned min, unsigned lval, bool&flag) const;
unsigned long rise,
unsigned long fall,
unsigned long decay) const;
};
/*
@@ -665,23 +440,17 @@ class PETernary : public PExpr {
virtual bool is_constant(Module*) const;
virtual void dump(ostream&out) const;
virtual unsigned test_width(Design*des, NetScope*scope,
unsigned min, unsigned lval,
bool&unsized_flag) const;
virtual bool elaborate_sig(Design*des, NetScope*scope) const;
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
unsigned width,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay,
unsigned long rise,
unsigned long fall,
unsigned long decay,
Link::strength_t drive0,
Link::strength_t drive1) const;
virtual NetETernary*elaborate_expr(Design*des, NetScope*,
int expr_width, bool sys_task_arg) const;
bool sys_task_arg =false) const;
virtual NetETernary*elaborate_pexpr(Design*des, NetScope*sc) const;
virtual verinum* eval_const(Design*des, NetScope*sc) const;
virtual verinum* eval_const(const Design*des, const NetScope*sc) const;
private:
PExpr*expr_;
@@ -696,45 +465,28 @@ class PETernary : public PExpr {
*/
class PECallFunction : public PExpr {
public:
explicit PECallFunction(const pform_name_t&n, const svector<PExpr *> &parms);
// Call of system function (name is not hierarchical)
explicit PECallFunction(perm_string n, const svector<PExpr *> &parms);
explicit PECallFunction(perm_string n);
explicit PECallFunction(const hname_t&n, const svector<PExpr *> &parms);
explicit PECallFunction(const hname_t&n);
~PECallFunction();
virtual void dump(ostream &) const;
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
unsigned width,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay,
unsigned long rise,
unsigned long fall,
unsigned long decay,
Link::strength_t drive0,
Link::strength_t drive1) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
int expr_wid, bool sys_task_arg) const;
virtual unsigned test_width(Design*des, NetScope*scope,
unsigned min, unsigned lval,
bool&unsized_flag) const;
bool sys_task_arg =false) const;
private:
pform_name_t path_;
hname_t path_;
svector<PExpr *> parms_;
bool check_call_matches_definition_(Design*des, NetScope*dscope) const;
NetExpr* elaborate_sfunc_(Design*des, NetScope*scope, int expr_wid) const;
NetNet* elaborate_net_sfunc_(Design*des, NetScope*scope,
unsigned width,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay,
Link::strength_t drive0,
Link::strength_t drive1) const;
unsigned test_width_sfunc_(Design*des, NetScope*scope,
unsigned min, unsigned lval,
bool&unsized_flag) const;
NetExpr* elaborate_sfunc_(Design*des, NetScope*scope) const;
};
#endif
+3 -3
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1999-2008 Stephen Williams ([email protected])
* Copyright (c) 1999-2010 Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -21,8 +21,8 @@
#include "PTask.h"
PFunction::PFunction(perm_string name, PScope*parent)
: PScope(name, parent), ports_(0), statement_(0)
PFunction::PFunction(perm_string name)
: name_(name), ports_(0), statement_(0)
{
return_type_.type = PTF_NONE;
}
+2 -60
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1999-2007 Stephen Williams ([email protected])
* Copyright (c) 1999-2010 Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -87,69 +87,12 @@ void PGate::elaborate_scope(Design*, NetScope*) const
* parameters. This method understands how to handle the different
* numbers of expressions.
*/
void PGate::eval_delays(Design*des, NetScope*scope,
NetExpr*&rise_expr,
NetExpr*&fall_expr,
NetExpr*&decay_expr,
bool as_net_flag) const
{
delay_.eval_delays(des, scope,
rise_expr, fall_expr, decay_expr,
as_net_flag);
}
void PGate::eval_delays(Design*des, NetScope*scope,
unsigned long&rise_time,
unsigned long&fall_time,
unsigned long&decay_time) const
{
NetExpr*rise_expr, *fall_expr, *decay_expr;
delay_.eval_delays(des, scope, rise_expr, fall_expr, decay_expr);
if (rise_expr == 0) {
rise_time = 0;
fall_time = 0;
decay_time = 0;
}
if (NetEConst*tmp = dynamic_cast<NetEConst*> (rise_expr)) {
rise_time = tmp->value().as_ulong();
} else {
cerr << get_fileline() << ": error: Delay expressions must be "
<< "constant here." << endl;
cerr << get_fileline() << ": : Cannot calculate "
<< *rise_expr << endl;
des->errors += 1;
rise_time = 0;
}
if (NetEConst*tmp = dynamic_cast<NetEConst*> (fall_expr)) {
fall_time = tmp->value().as_ulong();
} else {
if (fall_expr != rise_expr) {
cerr << get_fileline() << ": error: Delay expressions must be "
<< "constant here." << endl;
cerr << get_fileline() << ": : Cannot calculate "
<< *rise_expr << endl;
}
des->errors += 1;
fall_time = 0;
}
if (NetEConst*tmp = dynamic_cast<NetEConst*> (decay_expr)) {
decay_time = tmp->value().as_ulong();
} else {
cerr << get_fileline() << ": error: Delay expressions must be "
<< "constant here." << endl;
cerr << get_fileline() << ": : Cannot calculate "
<< *rise_expr << endl;
des->errors += 1;
decay_time = 0;
}
delay_.eval_delays(des, scope, rise_time, fall_time, decay_time);
}
PGAssign::PGAssign(svector<PExpr*>*pins)
@@ -242,4 +185,3 @@ perm_string PGModule::get_type()
{
return type_;
}
+7 -28
View File
@@ -1,7 +1,7 @@
#ifndef __PGate_H
#define __PGate_H
/*
* Copyright (c) 1998-2004 Stephen Williams ([email protected])
* Copyright (c) 1998-2010 Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -18,20 +18,18 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: PGate.h,v 1.32 2006/04/10 00:37:42 steve Exp $"
#endif
# include "svector.h"
# include "StringHeap.h"
# include "named.h"
# include "LineInfo.h"
# include "PDelays.h"
# include "netlist.h"
# include <map>
# include <string>
class PExpr;
class PUdp;
class Design;
class NetScope;
class Module;
/*
@@ -65,23 +63,11 @@ class PGate : public LineInfo {
perm_string get_name() const { return name_; }
// This method evaluates the delays all the way to an
// integer. If the delay is non-constant, then set the times
// to 0, print an error message and mark an error to the
// design.
void eval_delays(Design*des, NetScope*scope,
unsigned long&rise_time,
unsigned long&fall_time,
unsigned long&decay_time) const;
// This evaluates the delays as far as possible, but returns
// an expression, and do not signal errors.
void eval_delays(Design*des, NetScope*scope,
NetExpr*&rise_time,
NetExpr*&fall_time,
NetExpr*&decay_time,
bool as_net_flag =false) const;
unsigned pin_count() const { return pins_? pins_->count() : 0; }
const PExpr*pin(unsigned idx) const { return (*pins_)[idx]; }
@@ -93,7 +79,7 @@ class PGate : public LineInfo {
map<perm_string,PExpr*> attributes;
virtual void dump(ostream&out, unsigned ind =4) const;
virtual void dump(ostream&out) const;
virtual void elaborate(Design*des, NetScope*scope) const;
virtual void elaborate_scope(Design*des, NetScope*sc) const;
virtual bool elaborate_sig(Design*des, NetScope*scope) const;
@@ -127,9 +113,8 @@ class PGAssign : public PGate {
explicit PGAssign(svector<PExpr*>*pins, svector<PExpr*>*dels);
~PGAssign();
void dump(ostream&out, unsigned ind =4) const;
void dump(ostream&out) const;
virtual void elaborate(Design*des, NetScope*scope) const;
virtual bool elaborate_sig(Design*des, NetScope*scope) const;
private:
};
@@ -165,9 +150,8 @@ class PGBuiltin : public PGate {
Type type() const { return type_; }
void set_range(PExpr*msb, PExpr*lsb);
virtual void dump(ostream&out, unsigned ind =4) const;
virtual void dump(ostream&out) const;
virtual void elaborate(Design*, NetScope*scope) const;
virtual bool elaborate_sig(Design*des, NetScope*scope) const;
private:
Type type_;
@@ -209,7 +193,7 @@ class PGModule : public PGate {
// method to pass the range to the pform.
void set_range(PExpr*msb, PExpr*lsb);
virtual void dump(ostream&out, unsigned ind =4) const;
virtual void dump(ostream&out) const;
virtual void elaborate(Design*, NetScope*scope) const;
virtual void elaborate_scope(Design*des, NetScope*sc) const;
virtual bool elaborate_sig(Design*des, NetScope*scope) const;
@@ -236,11 +220,6 @@ class PGModule : public PGate {
void elaborate_udp_(Design*, PUdp *udp, NetScope*scope) const;
void elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const;
bool elaborate_sig_mod_(Design*des, NetScope*scope, Module*mod) const;
bool elaborate_sig_udp_(Design*des, NetScope*scope, PUdp*udp) const;
NetNet*resize_net_to_port_(Design*des, NetScope*scope,
NetNet*sig, unsigned port_wid,
NetNet::PortType dir) const;
};
#endif
-117
View File
@@ -1,117 +0,0 @@
#ifndef __PGenerate_H
#define __PGenerate_H
/*
* Copyright (c) 2006 Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: PGenerate.h,v 1.4 2007/06/02 03:42:12 steve Exp $"
#endif
# include "LineInfo.h"
# include "StringHeap.h"
# include "HName.h"
# include <list>
# include <map>
# include "pform_types.h"
class Design;
class NetScope;
class PExpr;
class PProcess;
class PGate;
class PWire;
/*
* This represents a generate scheme. The interpretation of the
* members depends on the scheme_type.
*
* GS_LOOP
*
* GS_CASE
* loop_test is the expression to be compared.
* generates contains only GS_CASE_ITEM schemes.
* GS_CASE_ITEM
* The parent points to the GS_CASE that contains this item.
* the loop_test is compared with the parent->loop_test expression.
*/
class PGenerate : public LineInfo {
public:
PGenerate(unsigned id_number);
~PGenerate();
// Generate schemes have an ID number, for when the scope is
// implicit.
const unsigned id_number;
perm_string scope_name;
enum scheme_t {GS_NONE, GS_LOOP, GS_CONDIT, GS_ELSE,
GS_CASE, GS_CASE_ITEM};
scheme_t scheme_type;
// generate loops have an index variable and three
// expressions: for (index = <init>; <test>; index=<step>)
perm_string loop_index;
PExpr*loop_init;
PExpr*loop_test;
PExpr*loop_step;
map<perm_string,PWire*>wires;
PWire* get_wire(perm_string name) const;
list<PGate*> gates;
void add_gate(PGate*);
list<PProcess*> behaviors;
void add_behavior(PProcess*behave);
list<PGenerate*> generates;
PGenerate*parent;
// This method is called by the elaboration of a module to
// generate scopes. the container is the scope that is to
// contain the generated scope.
bool generate_scope(Design*des, NetScope*container);
// Elaborate signals within any of the generated scopes that
// were made by this generate block within the given container scope.
bool elaborate_sig(Design*des, NetScope*container) const;
bool elaborate(Design*des, NetScope*container) const;
void dump(ostream&out, unsigned indent) const;
private:
bool generate_scope_loop_(Design*des, NetScope*container);
bool generate_scope_condit_(Design*des, NetScope*container, bool else_flag);
bool generate_scope_case_(Design*des, NetScope*container);
// Elaborate_scope within a generated scope.
void elaborate_subscope_(Design*des, NetScope*scope);
// These are the scopes created by generate_scope.
list<NetScope*>scope_list_;
// internal function called on each scope generated by this scheme.
bool elaborate_sig_(Design*des, NetScope*scope) const;
bool elaborate_(Design*des, NetScope*scope) const;
private: // not implemented
PGenerate(const PGenerate&);
PGenerate& operator= (const PGenerate&);
};
#endif
-38
View File
@@ -1,38 +0,0 @@
/*
* Copyright (c) 2008 Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
# include "PScope.h"
PScope::PScope(perm_string n, PScope*p)
: name_(n), parent_(p)
{
}
PScope::~PScope()
{
}
PWire* PScope::wires_find(perm_string name)
{
map<perm_string,PWire*>::const_iterator cur = wires.find(name);
if (cur == wires.end())
return 0;
else
return (*cur).second;
}
-80
View File
@@ -1,80 +0,0 @@
#ifndef __PScope_H
#define __PScope_H
/*
* Copyright (c) 2008 Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
# include "StringHeap.h"
# include "pform_types.h"
# include <map>
class PEvent;
class PProcess;
class PWire;
class Design;
class NetScope;
/*
* The PScope class is a base representation of an object that
* represents lexical scope. For example, a module, a function/task, a
* named block is derived from a PScope.
*
* NOTE: This is note the same concept as the "scope" of an elaborated
* hierarchy. That is represented by NetScope objects after elaboration.
*/
class PScope {
public:
// When created, a scope has a name and a parent. The name is
// the name of the definition. For example, if this is a
// module declaration, the name is the name after the "module"
// keyword, and if this is a task scope, the name is the task
// name. The parent is the lexical parent of this scope. Since
// modules do not nest in Verilog, the parent must be nil for
// modules. Scopes for tasks and functions point to their
// containing module.
PScope(perm_string name, PScope*parent);
virtual ~PScope();
perm_string pscope_name() const { return name_; }
PScope* pscope_parent() { return parent_; }
// Nets an variables (wires) in the scope
map<perm_string,PWire*>wires;
PWire* wires_find(perm_string name);
// Named events in the scope.
map<perm_string,PEvent*>events;
// Behaviors (processes) in this scope
list<PProcess*> behaviors;
protected:
void dump_wires_(ostream&out, unsigned indent) const;
bool elaborate_sig_wires_(Design*des, NetScope*scope) const;
bool elaborate_behaviors_(Design*des, NetScope*scope) const;
private:
perm_string name_;
PScope*parent_;
};
#endif
-79
View File
@@ -1,79 +0,0 @@
#ifndef __PSpec_H
#define __PSpec_H
/*
* Copyright (c) 2006 Stephen Williams <[email protected]>
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: PSpec.h,v 1.3 2007/04/13 02:34:35 steve Exp $"
#endif
# include "LineInfo.h"
# include "StringHeap.h"
# include <vector>
class PExpr;
/*
* The PSpecPath is the parse of a specify path, which is in its most
* general form <path> = <delays>. The <delays> are collected into the
* "delays" vector in all cases, and the variety is in the other
* members.
*
* All paths also have a list of source names in the src vector, and a
* list of destination names in the dst vector. These pairs are the
* actual paths.
*
* If the path is a simple path, then:
* condition == nil
* edge == 0
* data_source_expression == nil
*
* If the path is conditional, then conditional == true and condition
* is the condition expression. If the condition expression is nil,
* then this is an ifnone conditional path.
*
* If data_source_expression != nil, then the path is edge sensitive
* and the edge might not be 0.
*/
class PSpecPath : public LineInfo {
public:
PSpecPath(unsigned src_cnt, unsigned dst_cnt);
~PSpecPath();
void elaborate(class Design*des, class NetScope*scope) const;
void dump(std::ostream&out, unsigned ind) const;
public:
// Condition expression, if present.
bool conditional;
class PExpr* condition;
// Edge specification (-1==negedge, 0 = no edge, 1==posedge)
int edge;
// Ordered set of source nodes of a path
std::vector<perm_string> src;
// Ordered set of destination nodes of a path
std::vector<perm_string> dst;
// Data source expression
class PExpr* data_source_expression;
std::vector<class PExpr*>delays;
};
#endif
+3 -31
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1999-2008 Stephen Williams ([email protected])
* Copyright (c) 1999-2010 Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -21,8 +21,8 @@
# include "PTask.h"
PTask::PTask(perm_string name, PScope*parent)
: PScope(name, parent), ports_(0), statement_(0)
PTask::PTask()
: ports_(0), statement_(0)
{
}
@@ -41,31 +41,3 @@ void PTask::set_statement(Statement*s)
assert(statement_ == 0);
statement_ = s;
}
/*
* $Log: PTask.cc,v $
* Revision 1.7 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.6 2001/07/25 03:10:48 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
*
* Revision 1.5 2001/04/19 03:04:47 steve
* Spurious assert of empty statemnt.
*
* Revision 1.4 2001/01/13 22:20:08 steve
* Parse parameters within nested scopes.
*
* Revision 1.3 2000/02/23 02:56:53 steve
* Macintosh compilers do not support ident.
*
* Revision 1.2 1999/07/24 02:11:19 steve
* Elaborate task input ports.
*
* Revision 1.1 1999/07/03 02:12:51 steve
* Elaborate user defined tasks.
*
*/
+8 -9
View File
@@ -1,7 +1,7 @@
#ifndef __PTask_H
#define __PTask_H
/*
* Copyright (c) 1999-2008 Stephen Williams ([email protected])
* Copyright (c) 1999-2010 Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -20,7 +20,6 @@
*/
# include "LineInfo.h"
# include "PScope.h"
# include "svector.h"
# include "StringHeap.h"
# include <string>
@@ -33,7 +32,6 @@ class PExpr;
enum PTaskFuncEnum {
PTF_NONE,
PTF_REG,
PTF_REG_S,
PTF_INTEGER,
PTF_REAL,
PTF_REALTIME,
@@ -48,10 +46,10 @@ struct PTaskFuncArg {
/*
* The PTask holds the parsed definitions of a task.
*/
class PTask : public PScope, public LineInfo {
class PTask : public LineInfo {
public:
explicit PTask(perm_string name, PScope*parent);
explicit PTask();
~PTask();
void set_ports(svector<PWire *>*p);
@@ -69,7 +67,7 @@ class PTask : public PScope, public LineInfo {
// Elaborate the statement to finish off the task definition.
void elaborate(Design*des, NetScope*scope) const;
void dump(ostream&, unsigned) const;
void dump(std::ostream&, unsigned) const;
private:
svector<PWire*>*ports_;
@@ -87,10 +85,10 @@ class PTask : public PScope, public LineInfo {
*
* The output value is not elaborated until elaborate_sig.
*/
class PFunction : public PScope, public LineInfo {
class PFunction : public LineInfo {
public:
explicit PFunction(perm_string name, PScope*parent);
explicit PFunction(perm_string name);
~PFunction();
void set_ports(svector<PWire *>*p);
@@ -105,9 +103,10 @@ class PFunction : public PScope, public LineInfo {
/* Elaborate the behavioral statement. */
void elaborate(Design *des, NetScope*) const;
void dump(ostream&, unsigned) const;
void dump(std::ostream&, unsigned) const;
private:
perm_string name_;
PTaskFuncArg return_type_;
svector<PWire *> *ports_;
Statement *statement_;
+1 -18
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2003-2004 Stephen Williams ([email protected])
* Copyright (c) 2003-2010 Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -16,9 +16,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: PUdp.cc,v 1.3 2004/03/08 00:47:44 steve Exp $"
#endif
# include "PUdp.h"
@@ -37,17 +34,3 @@ unsigned PUdp::find_port(const char*name)
return ports.count();
}
/*
* $Log: PUdp.cc,v $
* Revision 1.3 2004/03/08 00:47:44 steve
* primitive ports can bind bi name.
*
* Revision 1.2 2004/02/18 17:11:54 steve
* Use perm_strings for named langiage items.
*
* Revision 1.1 2003/07/15 05:07:13 steve
* Move PUdp constructor into compiled file.
*
*/
+5 -57
View File
@@ -1,7 +1,7 @@
#ifndef __PUdp_H
#define __PUdp_H
/*
* Copyright (c) 1998-2004 Stephen Williams ([email protected])
* Copyright (c) 1998-2010 Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -18,9 +18,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: PUdp.h,v 1.12 2004/03/08 00:47:44 steve Exp $"
#endif
# include <map>
# include "StringHeap.h"
@@ -55,20 +52,20 @@ class PUdp {
public:
explicit PUdp(perm_string n, unsigned nports);
svector<string>ports;
svector<std::string>ports;
unsigned find_port(const char*name);
bool sequential;
svector<string>tinput;
svector<std::string>tinput;
svector<char> tcurrent;
svector<char> toutput;
verinum::V initial;
map<string,PExpr*> attributes;
std::map<std::string,PExpr*> attributes;
void dump(ostream&out) const;
void dump(std::ostream&out) const;
perm_string name_;
private:
@@ -78,53 +75,4 @@ class PUdp {
PUdp& operator= (const PUdp&);
};
/*
* $Log: PUdp.h,v $
* Revision 1.12 2004/03/08 00:47:44 steve
* primitive ports can bind bi name.
*
* Revision 1.11 2004/02/18 17:11:54 steve
* Use perm_strings for named langiage items.
*
* Revision 1.10 2003/07/15 05:07:13 steve
* Move PUdp constructor into compiled file.
*
* Revision 1.9 2003/07/15 03:49:22 steve
* Spelling fixes.
*
* Revision 1.8 2003/01/30 16:23:07 steve
* Spelling fixes.
*
* Revision 1.7 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.6 2002/05/23 03:08:51 steve
* Add language support for Verilog-2001 attribute
* syntax. Hook this support into existing $attribute
* handling, and add number and void value types.
*
* Add to the ivl_target API new functions for access
* of complex attributes attached to gates.
*
* Revision 1.5 2001/04/22 23:09:45 steve
* More UDP consolidation from Stephan Boettcher.
*
* Revision 1.4 2000/02/23 02:56:53 steve
* Macintosh compilers do not support ident.
*
* Revision 1.3 1999/06/15 03:44:53 steve
* Get rid of the STL vector template.
*
* Revision 1.2 1998/12/01 00:42:13 steve
* Elaborate UDP devices,
* Support UDP type attributes, and
* pass those attributes to nodes that
* are instantiated by elaboration,
* Put modules into a map instead of
* a simple list.
*
* Revision 1.1 1998/11/25 02:35:53 steve
* Parse UDP primitives all the way to pform.
*
*/
#endif
+25 -99
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1999-2007 Stephen Williams ([email protected])
* Copyright (c) 1999-2010 Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -19,18 +19,22 @@
# include "config.h"
# include "PWire.h"
# include "PExpr.h"
# include <assert.h>
PWire::PWire(perm_string n,
NetNet::Type t,
NetNet::PortType pt,
ivl_variable_type_t dt)
: name_(n), type_(t), port_type_(pt), data_type_(dt),
signed_(false), isint_(false),
port_msb_(0), port_lsb_(0), port_set_(false),
net_msb_(0), net_lsb_(0), net_set_(false), error_cnt_(0),
lidx_(0), ridx_(0), discipline_(0)
PWire::PWire(const hname_t&n, NetNet::Type t, NetNet::PortType pt)
: hname_(n), type_(t), port_type_(pt), signed_(false), isint_(false),
lidx_(0), ridx_(0)
{
if (t == NetNet::INTEGER) {
type_ = NetNet::REG;
signed_ = true;
isint_ = true;
}
}
PWire::PWire(char*n, NetNet::Type t, NetNet::PortType pt)
: hname_(n), type_(t), port_type_(pt), signed_(false), isint_(false),
lidx_(0), ridx_(0)
{
if (t == NetNet::INTEGER) {
type_ = NetNet::REG;
@@ -44,9 +48,9 @@ NetNet::Type PWire::get_wire_type() const
return type_;
}
perm_string PWire::basename() const
const hname_t& PWire::path() const
{
return name_;
return hname_;
}
bool PWire::set_wire_type(NetNet::Type t)
@@ -101,25 +105,6 @@ bool PWire::set_port_type(NetNet::PortType pt)
}
}
bool PWire::set_data_type(ivl_variable_type_t dt)
{
if (data_type_ != IVL_VT_NO_TYPE) {
if (data_type_ != dt)
return false;
else
return true;
}
assert(data_type_ == IVL_VT_NO_TYPE);
data_type_ = dt;
return true;
}
ivl_variable_type_t PWire::get_data_type() const
{
return data_type_;
}
void PWire::set_signed(bool flag)
{
signed_ = flag;
@@ -135,76 +120,17 @@ bool PWire::get_isint() const
return isint_;
}
void PWire::set_range(PExpr*m, PExpr*l, PWSRType type)
void PWire::set_range(PExpr*m, PExpr*l)
{
switch (type) {
case SR_PORT:
if (port_set_) {
cerr << get_fileline() << ": error: Port ``" << name_
<< "'' has already been declared a port." << endl;
error_cnt_ += 1;
} else {
port_msb_ = m;
port_lsb_ = l;
port_set_ = true;
}
return;
case SR_NET:
if (net_set_) {
cerr << get_fileline() << ": error: Net ``" << name_
<< "'' has already been declared." << endl;
error_cnt_ += 1;
} else {
net_msb_ = m;
net_lsb_ = l;
net_set_ = true;
}
return;
case SR_BOTH:
if (port_set_ || net_set_) {
if (port_set_) {
cerr << get_fileline() << ": error: Port ``" << name_
<< "'' has already been declared a port." << endl;
error_cnt_ += 1;
}
if (net_set_) {
cerr << get_fileline() << ": error: Net ``" << name_
<< "'' has already been declared." << endl;
error_cnt_ += 1;
}
} else {
port_msb_ = m;
port_lsb_ = l;
port_set_ = true;
net_msb_ = m;
net_lsb_ = l;
net_set_ = true;
}
return;
}
msb_ = svector<PExpr*>(msb_,m);
lsb_ = svector<PExpr*>(lsb_,l);
}
void PWire::set_memory_idx(PExpr*ldx, PExpr*rdx)
{
if (lidx_ != 0 || ridx_ != 0) {
cerr << get_fileline() << ": error: Array ``" << name_
<< "'' has already been declared." << endl;
error_cnt_ += 1;
} else {
lidx_ = ldx;
ridx_ = rdx;
}
}
void PWire::set_discipline(discipline_t*d)
{
assert(discipline_ == 0);
discipline_ = d;
}
discipline_t* PWire::get_discipline(void) const
{
return discipline_;
assert(lidx_ == 0);
assert(ridx_ == 0);
assert(type_ == NetNet::REG);
lidx_ = ldx;
ridx_ = rdx;
}
+13 -40
View File
@@ -1,7 +1,7 @@
#ifndef __PWire_H
#define __PWire_H
/*
* Copyright (c) 1998-2007 Stephen Williams ([email protected])
* Copyright (c) 1998-2010 Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -18,15 +18,11 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: PWire.h,v 1.21 2007/05/24 04:07:11 steve Exp $"
#endif
# include "netlist.h"
# include "LineInfo.h"
# include <map>
# include "svector.h"
# include "StringHeap.h"
#ifdef HAVE_IOSFWD
# include <iosfwd>
@@ -36,12 +32,6 @@ class ostream;
class PExpr;
class Design;
class discipline_t;
/*
* The different type of PWire::set_range() calls.
*/
enum PWSRType {SR_PORT, SR_NET, SR_BOTH};
/*
* Wires include nets, registers and ports. A net or register becomes
@@ -49,21 +39,18 @@ enum PWSRType {SR_PORT, SR_NET, SR_BOTH};
* identifies a port by keeping it in its port list.
*
* The hname parameter to the constructor is a hierarchical name. It
* is the name of the wire within a module, so does not include the
* current scope or any instances. Modules contain all the wires, so
* from that perspective, sub-scopes within the module are a part of
* the wire name.
* is an array of strings starting with the root, running towards
* the base name, and terminated by a null pointer. The environment
* allocates the memory for me.
*/
class PWire : public LineInfo {
public:
PWire(perm_string name,
NetNet::Type t,
NetNet::PortType pt,
ivl_variable_type_t dt);
PWire(const hname_t&hname, NetNet::Type t, NetNet::PortType pt);
PWire(char*name, NetNet::Type t, NetNet::PortType pt);
// Return a hierarchical name.
perm_string basename() const;
const hname_t&path() const;
NetNet::Type get_wire_type() const;
bool set_wire_type(NetNet::Type);
@@ -75,48 +62,34 @@ class PWire : public LineInfo {
bool get_signed() const;
bool get_isint() const;
bool set_data_type(ivl_variable_type_t dt);
ivl_variable_type_t get_data_type() const;
void set_range(PExpr*msb, PExpr*lsb, PWSRType type);
void set_range(PExpr*msb, PExpr*lsb);
void set_memory_idx(PExpr*ldx, PExpr*rdx);
void set_discipline(discipline_t*);
discipline_t* get_discipline(void) const;
map<perm_string,PExpr*> attributes;
// Write myself to the specified stream.
void dump(ostream&out, unsigned ind=4) const;
void dump(ostream&out) const;
NetNet* elaborate_sig(Design*, NetScope*scope) const;
void elaborate_sig(Design*, NetScope*scope) const;
private:
perm_string name_;
hname_t hname_;
NetNet::Type type_;
NetNet::PortType port_type_;
ivl_variable_type_t data_type_;
bool signed_;
bool isint_; // original type of integer
// These members hold expressions for the bit width of the
// wire. If they do not exist, the wire is 1 bit wide.
PExpr*port_msb_;
PExpr*port_lsb_;
bool port_set_;
PExpr*net_msb_;
PExpr*net_lsb_;
bool net_set_;
unsigned error_cnt_;
svector<PExpr*>msb_;
svector<PExpr*>lsb_;
// If this wire is actually a memory, these indices will give
// me the size and address range of the memory.
PExpr*lidx_;
PExpr*ridx_;
discipline_t*discipline_;
private: // not implemented
PWire(const PWire&);
PWire& operator= (const PWire&);
+62 -21
View File
@@ -88,10 +88,6 @@ Normally, this command automatically figures out everything it needs
to know. It generally works pretty well. There are a few flags to the
configure script that modify its behavior:
--without-ipal
This turns off support for Icarus PAL, whether ipal
libraries are installed or not.
--prefix=<root>
The default is /usr/local, which causes the tool suite to
be compiled for install in /usr/local/bin,
@@ -107,6 +103,17 @@ configure script that modify its behavior:
compilation of 32bit compatible vvp (vvp32) and the vpi
modules that match.
--enable-suffix
--enable-suffix=<your-suffix>
--disable-suffix
Enable/disable changing the names of install files to use
a suffix string so that this version or install can co-
exist with other versions. This renames the installed
commands (iverilog, iverilog-vpi, vvp) and the installed
library files and include directory so that installations
with the same prefix but different suffix are guaranteed
to not interfere with each other.
2.2.1 Special AMD64 Instructions
(The Icarus Verilog RPM for x86_64 is build using these instructions.)
@@ -114,7 +121,7 @@ configure script that modify its behavior:
If you are building for Linux/AMD64 (a.k.a x86_64) then to get the
most out of your install, first make sure you have both 64bit and
32bit development libraries installed. Then configure with this
somewhat more complicated command:
somewhat more complex command:
./configure libdir64='$(prefix)/lib64' vpidir1=vpi64 vpidir2=. --enable-vvp32
@@ -359,8 +366,7 @@ constructs.
Icarus Verilog includes some features that are not part of the
IEEE1364 standard, but have well defined meaning, and also sometimes
gives nonstandard (but extended) meanings to some features of the
language that are defined. See the "extensions.txt" documentation for
more details.
language that are defined.
$is_signed(<expr>)
This system function returns 1 if the expression contained is
@@ -471,20 +477,6 @@ more details.
combinational always blocks to be triggered when the values in
the sensitivity list are initialized by initial threads.
Nets with Types
Icarus Verilog support an extension syntax that allows nets
and regs to be explicitly typed. The currently supported types
are logic, bool and real. This implies that "logic" and "bool"
are new keywords. Typical syntax is:
wire real foo = 1.0;
reg logic bar, bat;
... and so forth. The syntax can be turned off by using the
-g2 flag to iverilog, and turned on explicitly with the -g2x
flag to iverilog.
6.0 CREDITS
Except where otherwise noted, Icarus Verilog, ivl and ivlpp are
@@ -494,3 +486,52 @@ Verilog guidance, and especially testing from many people. Testers in
particular include a larger community of people interested in a GPL
Verilog for Linux.
6.1 PORT MAINTAINERS
This is a list of people who have created ports and precompiled
packages for various operating systems. These folks have graciously
taken on the task of building Icarus Verilog on their systems and
bundled it into neat packages.(+) If you want to be added to the list (or
removed from the list) send e-mail to me.
FreeBSD/{Intel,alpha}
Ying-Chieh Liao <[email protected]>
Linux/{alpha,AMD64,Intel} (RPMS)
Stephen Williams <[email protected]>
Linux/* (.debs)
Hamish Moffatt <[email protected]>
Macintosh -- MacO/S
Yasuhisa Kato <[email protected]>
Mac O/S X
Timothy J. Wood <[email protected]>
NetBSD/*
Dan McMahill <[email protected]>
Solaris/SPARC packages (.pkg)
Dan McMahill <[email protected]>
Cygwin32/*
Venkat Iyer <[email protected]>
Mingw32
Venkat Iyer <[email protected]>
(+) These are not the only systems where Icarus Verilog has been run,
just the systems where precompiled binaries are publicly available.
6.2 TEST SUITE MANAGER
Steve Wilson <[email protected]> has taken on the large task of managing
the test suite. He has maintained the regression test scripts, the
driver list, received submissions from myself and others, and has
written a great many tests on his own. Any compiler writer, for any
language, will tell you that the test suite is at least as important
as the compiler code itself.
+13 -57
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998-1999 Stephen Williams ([email protected])
* Copyright (c) 1998-2010 Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -16,9 +16,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: Statement.cc,v 1.30 2007/05/24 04:07:11 steve Exp $"
#endif
# include "config.h"
@@ -86,13 +83,18 @@ PAssignNB::~PAssignNB()
{
}
PBlock::PBlock(perm_string n, PScope*parent, BL_TYPE t)
: PScope(n, parent), bl_type_(t)
PBlock::PBlock(perm_string n, BL_TYPE t, const svector<Statement*>&st)
: name_(n), bl_type_(t), list_(st)
{
}
PBlock::PBlock(BL_TYPE t, const svector<Statement*>&st)
: bl_type_(t), list_(st)
{
}
PBlock::PBlock(BL_TYPE t)
: PScope(perm_string(),0), bl_type_(t)
: bl_type_(t)
{
}
@@ -102,27 +104,16 @@ PBlock::~PBlock()
delete list_[idx];
}
void PBlock::set_statement(const svector<Statement*>&st)
{
list_ = st;
}
PCallTask::PCallTask(const pform_name_t&n, const svector<PExpr*>&p)
PCallTask::PCallTask(const hname_t&n, const svector<PExpr*>&p)
: path_(n), parms_(p)
{
}
PCallTask::PCallTask(perm_string n, const svector<PExpr*>&p)
: parms_(p)
{
path_.push_back(name_component_t(n));
}
PCallTask::~PCallTask()
{
}
const pform_name_t& PCallTask::path() const
const hname_t& PCallTask::path() const
{
return path_;
}
@@ -184,7 +175,7 @@ PDelayStatement::~PDelayStatement()
{
}
PDisable::PDisable(const pform_name_t&sc)
PDisable::PDisable(const hname_t&sc)
: scope_(sc)
{
}
@@ -279,7 +270,7 @@ PRepeat::~PRepeat()
delete statement_;
}
PTrigger::PTrigger(const pform_name_t&e)
PTrigger::PTrigger(const hname_t&e)
: event_(e)
{
}
@@ -298,38 +289,3 @@ PWhile::~PWhile()
delete cond_;
delete statement_;
}
/*
* $Log: Statement.cc,v $
* Revision 1.30 2007/05/24 04:07:11 steve
* Rework the heirarchical identifier parse syntax and pform
* to handle more general combinations of heirarch and bit selects.
*
* Revision 1.29 2004/02/18 17:11:54 steve
* Use perm_strings for named langiage items.
*
* Revision 1.28 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.27 2002/04/21 22:31:02 steve
* Redo handling of assignment internal delays.
* Leave it possible for them to be calculated
* at run time.
*
* Revision 1.26 2002/04/21 04:59:07 steve
* Add support for conbinational events by finding
* the inputs to expressions and some statements.
* Get case and assignment statements working.
*
* Revision 1.25 2001/12/03 04:47:14 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
*
* Revision 1.24 2001/11/22 06:20:59 steve
* Use NetScope instead of string for scope path.
*
* Revision 1.23 2001/07/25 03:10:48 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
*/
+17 -31
View File
@@ -1,7 +1,7 @@
#ifndef __Statement_H
#define __Statement_H
/*
* Copyright (c) 1998-2008 Stephen Williams ([email protected])
* Copyright (c) 1998-2010 Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -24,7 +24,6 @@
# include "StringHeap.h"
# include "PDelays.h"
# include "PExpr.h"
# include "PScope.h"
# include "HName.h"
# include "LineInfo.h"
class PExpr;
@@ -34,7 +33,6 @@ class Design;
class NetAssign_;
class NetCAssign;
class NetDeassign;
class NetForce;
class NetScope;
/*
@@ -53,8 +51,6 @@ class PProcess : public LineInfo {
virtual ~PProcess();
bool elaborate(Design*des, NetScope*scope) const;
Type type() const { return type_; }
Statement*statement() { return statement_; }
@@ -72,16 +68,18 @@ class PProcess : public LineInfo {
* fact, the Statement class is abstract and represents all the
* possible kinds of statements that exist in Verilog.
*/
class Statement : public LineInfo {
class Statement : public LineInfo, public Attrib {
public:
Statement() { }
virtual ~Statement() =0;
map<perm_string,PExpr*> attributes;
void dump_attributes(ostream&out, unsigned ind) const;
virtual void dump(ostream&out, unsigned ind) const;
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
virtual void elaborate_scope(Design*des, NetScope*scope) const;
virtual void elaborate_sig(Design*des, NetScope*scope) const;
};
/*
@@ -146,27 +144,25 @@ class PAssignNB : public PAssign_ {
* statements before constructing this object, so it knows a priori
* what is contained.
*/
class PBlock : public PScope, public Statement {
class PBlock : public Statement {
public:
enum BL_TYPE { BL_SEQ, BL_PAR };
// If the block has a name, it is a scope and also has a parent.
explicit PBlock(perm_string n, PScope*parent, BL_TYPE t);
// If it doesn't have a name, it's not a scope
explicit PBlock(perm_string n, BL_TYPE t, const svector<Statement*>&st);
explicit PBlock(BL_TYPE t, const svector<Statement*>&st);
explicit PBlock(BL_TYPE t);
~PBlock();
BL_TYPE bl_type() const { return bl_type_; }
void set_statement(const svector<Statement*>&st);
virtual void dump(ostream&out, unsigned ind) const;
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
virtual void elaborate_scope(Design*des, NetScope*scope) const;
virtual void elaborate_sig(Design*des, NetScope*scope) const;
private:
perm_string name_;
const BL_TYPE bl_type_;
svector<Statement*>list_;
};
@@ -174,11 +170,10 @@ class PBlock : public PScope, public Statement {
class PCallTask : public Statement {
public:
explicit PCallTask(const pform_name_t&n, const svector<PExpr*>&parms);
explicit PCallTask(perm_string n, const svector<PExpr*>&parms);
explicit PCallTask(const hname_t&n, const svector<PExpr*>&parms);
~PCallTask();
const pform_name_t& path() const;
const hname_t& path() const;
unsigned nparms() const { return parms_.count(); }
@@ -199,7 +194,7 @@ class PCallTask : public Statement {
NetProc* elaborate_sys(Design*des, NetScope*scope) const;
NetProc* elaborate_usr(Design*des, NetScope*scope) const;
pform_name_t path_;
hname_t path_;
svector<PExpr*> parms_;
};
@@ -216,7 +211,6 @@ class PCase : public Statement {
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
virtual void elaborate_scope(Design*des, NetScope*scope) const;
virtual void elaborate_sig(Design*des, NetScope*scope) const;
virtual void dump(ostream&out, unsigned ind) const;
private:
@@ -252,7 +246,6 @@ class PCondit : public Statement {
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
virtual void elaborate_scope(Design*des, NetScope*scope) const;
virtual void elaborate_sig(Design*des, NetScope*scope) const;
virtual void dump(ostream&out, unsigned ind) const;
private:
@@ -287,7 +280,6 @@ class PDelayStatement : public Statement {
virtual void dump(ostream&out, unsigned ind) const;
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
virtual void elaborate_scope(Design*des, NetScope*scope) const;
virtual void elaborate_sig(Design*des, NetScope*scope) const;
private:
PExpr*delay_;
@@ -301,14 +293,14 @@ class PDelayStatement : public Statement {
class PDisable : public Statement {
public:
explicit PDisable(const pform_name_t&sc);
explicit PDisable(const hname_t&sc);
~PDisable();
virtual void dump(ostream&out, unsigned ind) const;
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
private:
pform_name_t scope_;
hname_t scope_;
};
/*
@@ -335,7 +327,6 @@ class PEventStatement : public Statement {
virtual void dump(ostream&out, unsigned ind) const;
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
virtual void elaborate_scope(Design*des, NetScope*scope) const;
virtual void elaborate_sig(Design*des, NetScope*scope) const;
// This method is used to elaborate, but attach a previously
// elaborated statement to the event.
@@ -354,7 +345,7 @@ class PForce : public Statement {
explicit PForce(PExpr*l, PExpr*r);
~PForce();
virtual NetForce* elaborate(Design*des, NetScope*scope) const;
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
virtual void dump(ostream&out, unsigned ind) const;
private:
@@ -369,7 +360,6 @@ class PForever : public Statement {
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
virtual void elaborate_scope(Design*des, NetScope*scope) const;
virtual void elaborate_sig(Design*des, NetScope*scope) const;
virtual void dump(ostream&out, unsigned ind) const;
private:
@@ -385,7 +375,6 @@ class PForStatement : public Statement {
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
virtual void elaborate_scope(Design*des, NetScope*scope) const;
virtual void elaborate_sig(Design*des, NetScope*scope) const;
virtual void dump(ostream&out, unsigned ind) const;
private:
@@ -404,7 +393,6 @@ class PNoop : public Statement {
public:
PNoop() { }
~PNoop() { }
};
class PRepeat : public Statement {
@@ -414,7 +402,6 @@ class PRepeat : public Statement {
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
virtual void elaborate_scope(Design*des, NetScope*scope) const;
virtual void elaborate_sig(Design*des, NetScope*scope) const;
virtual void dump(ostream&out, unsigned ind) const;
private:
@@ -442,14 +429,14 @@ class PRelease : public Statement {
class PTrigger : public Statement {
public:
explicit PTrigger(const pform_name_t&ev);
explicit PTrigger(const hname_t&ev);
~PTrigger();
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
virtual void dump(ostream&out, unsigned ind) const;
private:
pform_name_t event_;
hname_t event_;
};
class PWhile : public Statement {
@@ -460,7 +447,6 @@ class PWhile : public Statement {
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
virtual void elaborate_scope(Design*des, NetScope*scope) const;
virtual void elaborate_sig(Design*des, NetScope*scope) const;
virtual void dump(ostream&out, unsigned ind) const;
private:
+2 -31
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2004 Stephen Williams ([email protected])
* Copyright (c) 2002-2010 Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -16,9 +16,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: StringHeap.cc,v 1.6 2004/02/18 17:11:54 steve Exp $"
#endif
# include "StringHeap.h"
#ifdef HAVE_MALLOC_H
@@ -131,7 +128,7 @@ perm_string StringHeapLex::make(const char*text)
return perm_string(add(text));
}
perm_string StringHeapLex::make(const string&text)
perm_string StringHeapLex::make(const std::string&text)
{
return perm_string(add(text.c_str()));
}
@@ -178,29 +175,3 @@ bool operator < (perm_string a, perm_string b)
return false;
}
/*
* $Log: StringHeap.cc,v $
* Revision 1.6 2004/02/18 17:11:54 steve
* Use perm_strings for named langiage items.
*
* Revision 1.5 2003/03/01 06:25:30 steve
* Add the lex_strings string handler, and put
* scope names and system task/function names
* into this table. Also, permallocate event
* names from the beginning.
*
* Revision 1.4 2003/01/27 05:09:17 steve
* Spelling fixes.
*
* Revision 1.3 2003/01/16 21:44:46 steve
* Keep some debugging status.
*
* Revision 1.2 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.1 2002/08/04 19:13:16 steve
* dll uses StringHeap for named items.
*
*/
+2 -29
View File
@@ -1,7 +1,7 @@
#ifndef __StringHeap_H
#define __StringHeap_H
/*
* Copyright (c) 2002-2004 Stephen Williams ([email protected])
* Copyright (c) 2002-2010 Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -18,9 +18,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: StringHeap.h,v 1.6 2005/06/14 19:13:43 steve Exp $"
#endif
# include "config.h"
# include <string>
@@ -103,7 +100,7 @@ class StringHeapLex : private StringHeap {
const char*add(const char*);
perm_string make(const char*);
perm_string make(const string&);
perm_string make(const std::string&);
unsigned add_count() const;
unsigned add_hit_count() const;
@@ -120,28 +117,4 @@ class StringHeapLex : private StringHeap {
StringHeapLex& operator= (const StringHeapLex&);
};
/*
* $Log: StringHeap.h,v $
* Revision 1.6 2005/06/14 19:13:43 steve
* gcc3/4 compile errors.
*
* Revision 1.5 2004/02/18 17:11:54 steve
* Use perm_strings for named langiage items.
*
* Revision 1.4 2003/03/01 06:25:30 steve
* Add the lex_strings string handler, and put
* scope names and system task/function names
* into this table. Also, permallocate event
* names from the beginning.
*
* Revision 1.3 2003/01/16 21:44:46 steve
* Keep some debugging status.
*
* Revision 1.2 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.1 2002/08/04 19:13:16 steve
* dll uses StringHeap for named items.
*
*/
#endif
+2 -43
View File
@@ -1,7 +1,7 @@
#ifndef PLI_TYPES
#define PLI_TYPES
/*
* Copyright (c) 2003 Stephen Williams ([email protected])
* Copyright (c) 2003-2010 Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -18,9 +18,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: _pli_types.h.in,v 1.8 2007/06/05 21:32:30 steve Exp $"
#endif
# undef HAVE_INTTYPES_H
@@ -84,46 +81,8 @@ typedef signed int PLI_INT32;
typedef unsigned int PLI_UINT32;
typedef signed short PLI_INT16;
typedef unsigned short PLI_UINT16;
typedef char PLI_BYTE8;
typedef signed char PLI_BYTE8;
typedef unsigned char PLI_UBYTE8;
#endif
/*
* $Log: _pli_types.h.in,v $
* Revision 1.8 2007/06/05 21:32:30 steve
* More standard PLI_BYTE8.
*
* Revision 1.7 2003/11/12 02:38:44 steve
* Clean up manual definitions of PLI_UINT64_FMT.
*
* Revision 1.6 2003/11/08 20:06:21 steve
* Spelling fixes in comments.
*
* Revision 1.5 2003/10/29 03:28:27 steve
* Add the PLU_UINT64_FMT string for formatting output.
*
* Revision 1.4 2003/10/29 03:23:12 steve
* Portably handle time format of VCD prints.
*
* Revision 1.3 2003/10/02 21:30:06 steve
* Use configured TIME_FMT in vcd dump printf.
*
* Revision 1.2 2003/10/02 19:33:44 steve
* Put libraries in libdir64.
*
* Revision 1.1 2003/09/30 01:33:13 steve
* Add PLI_UINT64 to _pli_types.h.
*
* Revision 1.2 2003/05/26 04:39:16 steve
* Typo type name.
*
* Revision 1.1 2003/02/17 06:39:47 steve
* Add at least minimal implementations for several
* acc_ functions. Add support for standard ACC
* string handling.
*
* Add the _pli_types.h header file to carry the
* IEEE1364-2001 standard PLI type declarations.
*
*/
#endif
+1 -82
View File
@@ -1,7 +1,7 @@
#ifndef __acc_user_H
#define __acc_user_H
/*
* Copyright (c) 2002 Stephen Williams (steve@icarus.com)
* Copyright (c) 2002-2010 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -18,9 +18,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: acc_user.h,v 1.20 2003/12/17 15:45:07 steve Exp $"
#endif
/*
* This header file contains the definitions and declarations needed
@@ -273,82 +270,4 @@ extern char* acc_version(void);
EXTERN_C_END
/*
* $Log: acc_user.h,v $
* Revision 1.20 2003/12/17 15:45:07 steve
* Add acc_set_scope function.
*
* Revision 1.19 2003/10/10 02:57:45 steve
* Some PLI1 stubs.
*
* Revision 1.18 2003/06/13 19:23:41 steve
* Add a bunch more PLI1 routines.
*
* Revision 1.17 2003/06/04 01:56:20 steve
* 1) Adds configure logic to clean up compiler warnings
* 2) adds acc_compare_handle, acc_fetch_range, acc_next_scope and
* tf_isetrealdelay, acc_handle_scope
* 3) makes acc_next reentrant
* 4) adds basic vpiWire type support
* 5) fills in some acc_object_of_type() and acc_fetch_{full}type()
* 6) add vpiLeftRange/RigthRange to signals
*
* Revision 1.16 2003/05/30 04:18:31 steve
* Add acc_next function.
*
* Revision 1.15 2003/05/29 02:35:41 steve
* acc_fetch_type supports module.
*
* Revision 1.14 2003/05/29 02:21:45 steve
* Implement acc_fetch_defname and its infrastructure in vvp.
*
* Revision 1.13 2003/05/24 03:02:04 steve
* Add implementation of acc_handle_by_name.
*
* Revision 1.12 2003/05/18 00:16:35 steve
* Add PLI_TRACE tracing of PLI1 modules.
*
* Add tf_isetdelay and friends, and add
* callback return values for acc_vcl support.
*
* Revision 1.11 2003/04/24 18:57:05 steve
* Add acc_fetch_fulltype function.
*
* Revision 1.10 2003/04/20 02:48:39 steve
* Support value change callbacks.
*
* Revision 1.9 2003/04/12 18:57:13 steve
* More acc_ function stubs.
*
* Revision 1.8 2003/03/13 04:35:09 steve
* Add a bunch of new acc_ and tf_ functions.
*
* Revision 1.7 2003/02/17 06:39:47 steve
* Add at least minimal implementations for several
* acc_ functions. Add support for standard ACC
* string handling.
*
* Add the _pli_types.h header file to carry the
* IEEE1364-2001 standard PLI type declarations.
*
* Revision 1.6 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.5 2002/06/11 15:19:12 steve
* Add acc_fetch_argc/argv/version (mruff)
*
* Revision 1.4 2002/06/07 02:58:58 steve
* Add a bunch of acc/tf functions. (mruff)
*
* Revision 1.3 2002/06/02 19:03:29 steve
* Add acc_handle_tfarg and acc_next_topmode
*
* Revision 1.2 2002/05/30 02:06:05 steve
* Implement acc_product_version.
*
* Revision 1.1 2002/05/23 03:46:42 steve
* Add the acc_user.h header file.
*
*/
#endif
Vendored
+25 -36
View File
@@ -1,29 +1,22 @@
# AX_CPP_IDENT
# ------------
# Check if the C compiler supports #ident
# Define and substitute ident_support if so.
#
# It would be simpler and more consistent with the rest of the autoconf
# structure to AC_DEFINE(HAVE_CPP_IDENT) instead of
# ident_support='-DHAVE_CVS_IDENT=1' and AC_SUBST(ident_support), but that
# change would require all C files in the icarus top level directory to
# put #include <config.h> before the #ifdef HAVE_CVS_IDENT (and change
# HAVE_CVS_IDENT to HAVE_CPP_IDENT). That would also remove all special
# ident_support handling from the Makefile. Manyana.
#
AC_DEFUN([AX_CPP_IDENT],
[AC_CACHE_CHECK([for ident support in C compiler], ax_cv_cpp_ident,
[AC_TRY_COMPILE([
#ident "$Id: aclocal.m4,v 1.7 2007/05/16 23:59:12 steve Exp $"
],[while (0) {}],
[AS_VAR_SET(ax_cv_cpp_ident, yes)],
[AS_VAR_SET(ax_cv_cpp_ident, no)])])
if test $ax_cv_cpp_ident = yes; then
ident_support='-DHAVE_CVS_IDENT=1'
# AX_ENABLE_SUFFIX
# ----------------
# Create the configure option --enable-suffix[=suffix] to generate suffix
# strings for the installed commands. This allows for shared installs of
# different builds. Remember to change the default suffix string to some
# value appropriate for the current version.
AC_DEFUN([AX_ENABLE_SUFFIX],
[AC_ARG_ENABLE([suffix],[AC_HELP_STRING([--enable-suffix],
[Use/set the installation command suffix])],
[true],[enable_suffix=yes])
if test X$enable_suffix = Xyes; then
install_suffix='-0.8'
elif test X$enable_suffix = Xno; then
install_suffix=''
else
install_suffix="$enable_suffix"
fi
AC_SUBST(ident_support)
])# AC_CPP_IDENT
AC_SUBST(install_suffix)
])# AX_ENABLE_SUFFIX
# _AX_C_UNDERSCORES_MATCH_IFELSE(PATTERN, ACTION-IF-MATCH, ACTION-IF-NOMATCH)
# ------------------------------
@@ -32,7 +25,7 @@ AC_SUBST(ident_support)
# - the object file produced by AC_COMPILE_IFELSE is called "conftest.$ac_objext"
# - the nm(1) utility is available, and its name is "nm".
AC_DEFUN([_AX_C_UNDERSCORES_MATCH_IF],
[AC_COMPILE_IFELSE([void underscore(void){}],
[AC_COMPILE_IFELSE([AC_LANG_SOURCE([void underscore(void){}])],
[AS_IF([nm conftest.$ac_objext|grep $1 >/dev/null 2>/dev/null],[$2],[$3])],
[AC_MSG_ERROR([underscore test crashed])]
)])
@@ -91,13 +84,9 @@ AC_MSG_RESULT($WIN32)
AC_DEFUN([AX_LD_EXTRALIBS],
[AC_MSG_CHECKING([for extra libs needed])
EXTRALIBS=
case "${host}" in
*-*-cygwin* )
if test "$MINGW32" = "yes"; then
EXTRALIBS="-liberty"
fi
;;
esac
if test "$MINGW32" = "yes"; then
EXTRALIBS="-liberty"
fi
AC_SUBST(EXTRALIBS)
AC_MSG_RESULT($EXTRALIBS)
])# AX_LD_EXTRALIBS
@@ -109,7 +98,7 @@ AC_DEFUN([AX_LD_SHAREDLIB_OPTS],
[AC_MSG_CHECKING([for shared library link flag])
shared=-shared
case "${host}" in
*-*-cygwin*)
*-*-cygwin* | *-*-mingw32*)
shared="-shared -Wl,--enable-auto-image-base"
;;
@@ -138,7 +127,7 @@ AC_DEFUN([AX_C_PICFLAG],
PICFLAG=-fPIC
case "${host}" in
*-*-cygwin*)
*-*-cygwin* | *-*-mingw32*)
PICFLAG=
;;
@@ -173,7 +162,7 @@ case "${host}" in
rdynamic=""
;;
*-*-cygwin*)
*-*-cygwin* | *-*-mingw32*)
rdynamic=""
;;
+6 -31
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2002 Stephen Williams (steve@icarus.com)
* Copyright (c) 2002-2010 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -16,9 +16,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: async.cc,v 1.7 2004/01/18 23:26:54 steve Exp $"
#endif
# include "config.h"
@@ -66,6 +63,10 @@ bool NetEvWait::is_asynchronous()
NexusSet*inputs = statement_->nex_input();
/* All the inputs of the statement must be accounted for in
the sensitivity list. Otherwise, there are inputs that can
change without the event being triggered, and that implies
a latch, not a combinational circuit. */
if (! sense->contains(*inputs)) {
delete sense;
delete inputs;
@@ -85,36 +86,10 @@ bool NetProc::is_asynchronous()
return false;
}
bool NetProcTop::is_asynchronous()
bool NetProcTop::is_asynchronous() const
{
if (type_ == NetProcTop::KINITIAL)
return false;
return statement_->is_asynchronous();
}
/*
* $Log: async.cc,v $
* Revision 1.7 2004/01/18 23:26:54 steve
* The is_combinational function really need not recurse.
*
* Revision 1.6 2003/12/20 00:33:39 steve
* More thorough check that NetEvWait is asynchronous.
*
* Revision 1.5 2003/09/04 20:28:05 steve
* Support time0 resolution of combinational threads.
*
* Revision 1.4 2002/08/18 22:07:16 steve
* Detect temporaries in sequential block synthesis.
*
* Revision 1.3 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.2 2002/07/04 00:24:16 steve
* initial statements are not asynchronous.
*
* Revision 1.1 2002/06/30 02:21:31 steve
* Add structure for asynchronous logic synthesis.
*
*/
+8
View File
@@ -70,6 +70,14 @@ warning.)
* Other Attributes
(* ivl_full_case *)
This attribute only has meaning when attached to case statements,
and only when doing synthesis. The statement means to ignore the
possibility that some cases are not defined. Presume that the
device really is fully specified and do not emit any warnings
about missing guards.
[ none defined yet ]
+3 -3
View File
@@ -7,13 +7,13 @@
# to just run this script to autoconf wherever needed.
#
echo "Autoconf in root..."
autoconf -f
autoconf
for dir in vpip vpi vvp tgt-vvp tgt-fpga tgt-stub libveriuser cadpli
for dir in vpip vpi vvp tgt-vvp tgt-edif tgt-fpga libveriuser cadpli
do
echo "Autoconf in $dir..."
( cd ./$dir ; autoconf -f --include=.. )
done
echo "Precompiling lexor_keyword.gperf"
gperf -o -i 7 -C -k 1-4,\$ -L ANSI-C -H keyword_hash -N check_identifier -t ./lexor_keyword.gperf > lexor_keyword.cc
gperf -o -i 7 -C -k 1-3,\$ -L ANSI-C -H keyword_hash -N check_identifier -t ./lexor_keyword.gperf > lexor_keyword.cc
-7
View File
@@ -1,7 +0,0 @@
Makefile
cadpli.vpl
dep
configure
config.log
config.status
autom4te.cache
+24 -10
View File
@@ -15,10 +15,10 @@
# Software Foundation, Inc.,
# 59 Temple Place - Suite 330
# Boston, MA 02111-1307, USA
#
SHELL = /bin/sh
VERSION = 0.9.devel
suffix = @install_suffix@
prefix = @prefix@
exec_prefix = @exec_prefix@
@@ -30,21 +30,32 @@ bindir = @bindir@
libdir = @libdir@
includedir = $(prefix)/include
vpidir = @libdir@/ivl
vpidir = @libdir@/ivl$(suffix)/@vpidir1@
strip_dynamic=@strip_dynamic@
CC = @CC@
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
CPPFLAGS = @ident_support@ -I$(srcdir) -I$(srcdir)/.. -I.. @CPPFLAGS@ @DEFS@ @PICFLAG@
CPPFLAGS = -I$(srcdir) -I$(srcdir)/.. -I.. @CPPFLAGS@ @DEFS@ @PICFLAG@
CFLAGS = -Wall @CFLAGS@
LDFLAGS = @LDFLAGS@
STRIP = @STRIP@
SHARED = @shared@
all:
ifeq (@enable_vvp32@,yes)
vpidir32 = $(libdir)/ivl$(suffix)/@vpidir2@
ALL32 = all32
INSTALL32 = install32
UNINSTALL32 = uninistall32
include $(srcdir)/enable_vvp32.mk
endif
all: dep cadpli.vpl $(ALL32)
# No specific check operations.
@@ -60,7 +71,7 @@ dep:
O = cadpli.o
SYSTEM_VPI_LDFLAGS = -L../vvp -lvpi
ifeq (@MINGW32@,yes)
ifeq (@WIN32@,yes)
SYSTEM_VPI_LDFLAGS += @EXTRALIBS@
endif
@@ -72,18 +83,21 @@ clean:
distclean: clean
rm -f Makefile config.status config.log config.cache
rm -rf autom4te.cache
install: all installdirs $(vpidir)/cadpli.vpl $(INSTALL32)
$(vpidir)/cadpli.vpl: ./cadpli.vpl
$(INSTALL_PROGRAM) ./cadpli.vpl $(vpidir)/cadpli.vpl
$(DESTDIR)$(vpidir)/cadpli.vpl: ./cadpli.vpl
$(INSTALL_PROGRAM) ./cadpli.vpl $(DESTDIR)$(vpidir)/cadpli.vpl
installdirs: ../mkinstalldirs
$(srcdir)/../mkinstalldirs $(vpidir)
$(srcdir)/../mkinstalldirs $(DESTDIR)$(vpidir)
uninstall: $(UNINSTALL32)
rm -f $(vpidir)/cadpli.vpl
rm -f $(DESTDIR)$(vpidir)/cadpli.vpl
uninstall32:
ifeq (@enable_vvp32@,yes)
include $(srcdir)/enable_vvp32.mk
endif
-include $(patsubst %.o, dep/%.d, $O)
+1 -35
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2003 Stephen Williams (steve@icarus.com)
* Copyright (c) 2003-2010 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -16,9 +16,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: cadpli.c,v 1.7 2004/09/10 00:15:45 steve Exp $"
#endif
# include <vpi_user.h>
# include <veriuser.h>
@@ -87,34 +84,3 @@ void (*vlog_startup_routines[])() = {
thunker_register,
0
};
/*
* $Log: cadpli.c,v $
* Revision 1.7 2004/09/10 00:15:45 steve
* Remove bad casts.
*
* Revision 1.6 2004/09/05 21:19:51 steve
* Better type safety.
*
* Revision 1.5 2003/08/26 16:26:02 steve
* ifdef idents correctly.
*
* Revision 1.4 2003/04/30 01:28:06 steve
* Remove veriusertfs stuf.
*
* Revision 1.3 2003/02/22 04:04:38 steve
* Only include malloc.h if it is present.
*
* Revision 1.2 2003/02/17 00:01:25 steve
* Use a variant of ivl_dlfcn to do dynamic loading
* from within the cadpli module.
*
* Change the +cadpli flag to -cadpli, to keep the
* plusargs namespace clear.
*
* Revision 1.1 2003/02/16 02:23:54 steve
* Add the cadpli interface module.
*
*/
+16 -1
View File
@@ -10,8 +10,14 @@ AC_SUBST(EXEEXT)
# Combined check for Microsoft-related bogosities; sets WIN32 if found
AX_WIN32
AX_ENABLE_SUFFIX
AC_PROG_INSTALL
# vvp32 is by default disabled
#enable_vvp32=no
AC_SUBST(enable_vvp32)
AC_CHECK_HEADERS(malloc.h)
AC_CHECK_SIZEOF(unsigned long long)
@@ -56,6 +62,15 @@ AX_C_UNDERSCORES_TRAILING
## end of test for underscores
#######################
AX_CPP_IDENT
# where to put vpi subdirectories
AC_MSG_CHECKING(for VPI subdirectories)
if test x${vpidir1} = x
then
vpidir1="."
fi
AC_SUBST(vpidir1)
AC_SUBST(vpidir2)
AC_MSG_RESULT(${vpidir1} ${vpidir2})
AC_OUTPUT(Makefile)
+39
View File
@@ -0,0 +1,39 @@
#
# This source code is free software; you can redistribute it
# and/or modify it in source code form under the terms of the GNU
# Library General Public License as published by the Free Software
# Foundation; either version 2 of the License, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Library General Public License for more details.
#
# You should have received a copy of the GNU Library General Public
# License along with this program; if not, write to the Free
# Software Foundation, Inc.,
# 59 Temple Place - Suite 330
# Boston, MA 02111-1307, USA
#
#ident "$Id: enable_vvp32.mk,v 1.1 2003/10/09 01:07:20 steve Exp $"
#
all32: bin32 bin32/cadpli.vpl
bin32:
mkdir bin32
bin32/%.o: %.c
$(CC) -m32 -Wall -I$(srcdir) -I$(srcdir)/.. $(CPPFLAGS) $(CFLAGS) -MD -c $< -o $@
bin32/cadpli.vpl: $(addprefix bin32/,$O) ../vvp/bin32/libvpi.a ../libveriuser/bin32/libveriuser.o
$(CC) $(SHARED) -m32 -o $@ $(addprefix bin32/,$O) ../libveriuser/bin32/libveriuser.o ../vvp/bin32/libvpi.a
install32: all32 $(vpidir32)/cadpli.vpl
$(vpidir32)/cadpli.vpl: bin32/cadpli.vpl
$(INSTALL_PROGRAM) bin32/cadpli.vpl $(vpidir32)/cadpli.vpl
uninstall32:
rm -f $(vpidir32)/cadpli.vpl
+12 -31
View File
@@ -1,7 +1,7 @@
#ifndef __ivl_dlfcn_H
#define __ivl_dlfcn_H
/*
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
* Copyright (c) 2001-2010 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -18,9 +18,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: ivl_dlfcn.h,v 1.3 2004/10/04 01:10:56 steve Exp $"
#endif
#if defined(__MINGW32__)
# include <windows.h>
@@ -35,16 +32,16 @@ typedef shl_t ivl_dll_t;
#endif
#if defined(__MINGW32__)
static inline ivl_dll_t ivl_dlopen(const char *name)
inline ivl_dll_t ivl_dlopen(const char *name)
{ return (void *)LoadLibrary(name); }
static inline void *ivl_dlsym(ivl_dll_t dll, const char *nm)
inline void *ivl_dlsym(ivl_dll_t dll, const char *nm)
{ return (void *)GetProcAddress((HINSTANCE)dll,nm);}
static inline void ivl_dlclose(ivl_dll_t dll)
inline void ivl_dlclose(ivl_dll_t dll)
{ (void)FreeLibrary((HINSTANCE)dll);}
static inline const char *dlerror(void)
inline const char *dlerror(void)
{
static char msg[256];
unsigned long err = GetLastError();
@@ -61,10 +58,10 @@ static inline const char *dlerror(void)
}
#elif defined(HAVE_DLFCN_H)
static inline ivl_dll_t ivl_dlopen(const char*name)
inline ivl_dll_t ivl_dlopen(const char*name)
{ return dlopen(name,RTLD_LAZY); }
static inline void* ivl_dlsym(ivl_dll_t dll, const char*nm)
inline void* ivl_dlsym(ivl_dll_t dll, const char*nm)
{
void*sym = dlsym(dll, nm);
/* Not found? try without the leading _ */
@@ -73,41 +70,25 @@ static inline void* ivl_dlsym(ivl_dll_t dll, const char*nm)
return sym;
}
static inline void ivl_dlclose(ivl_dll_t dll)
inline void ivl_dlclose(ivl_dll_t dll)
{ dlclose(dll); }
#elif defined(HAVE_DL_H)
static inline ivl_dll_t ivl_dlopen(const char*name)
inline ivl_dll_t ivl_dlopen(const char*name)
{ return shl_load(name, BIND_IMMEDIATE, 0); }
static inline void* ivl_dlsym(ivl_dll_t dll, const char*nm)
inline void* ivl_dlsym(ivl_dll_t dll, const char*nm)
{
void*sym;
int rc = shl_findsym(&dll, nm, TYPE_PROCEDURE, &sym);
return (rc == 0) ? sym : 0;
}
static inline void ivl_dlclose(ivl_dll_t dll)
inline void ivl_dlclose(ivl_dll_t dll)
{ shl_unload(dll); }
static inline const char*dlerror(void)
inline const char*dlerror(void)
{ return strerror( errno ); }
#endif
/*
* $Log: ivl_dlfcn.h,v $
* Revision 1.3 2004/10/04 01:10:56 steve
* Clean up spurious trailing white space.
*
* Revision 1.2 2003/12/12 05:43:08 steve
* Some systems dlsym requires leading _ or not on whim.
*
* Revision 1.1 2003/02/17 00:01:25 steve
* Use a variant of ivl_dlfcn to do dynamic loading
* from within the cadpli module.
*
* Change the +cadpli flag to -cadpli, to keep the
* plusargs namespace clear.
*
*/
#endif
+13 -60
View File
@@ -1,7 +1,7 @@
#ifndef __compiler_H
#define __compiler_H
/*
* Copyright (c) 1999-2008 Stephen Williams (steve@icarus.com)
* Copyright (c) 1999-2010 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -29,12 +29,11 @@
*/
/*
* The integer_width is the width of integer variables. This is also
* the minimum width of unsized integers when they are found in
* self-determined contexts.
*/
extern unsigned integer_width;
/* The INTEGER_WIDTH is the default width of integer variables, and
the presumed width of unsigned literal numbers. */
#ifndef INTEGER_WIDTH
# define INTEGER_WIDTH 32
#endif
/* The TIME_WIDTH is the width of time variables. */
#ifndef TIME_WIDTH
@@ -76,8 +75,8 @@ extern bool warn_timescale;
/* Warn about legal but questionable module port bindings. */
extern bool warn_portbinding;
/* Warn about structures that may have infinite loops. */
extern bool warn_inf_loop;
/* Warn about unused or unassigned variables. */
extern bool warn_unused;
/* This is true if verbose output is requested. */
extern bool verbose_flag;
@@ -85,8 +84,8 @@ extern bool verbose_flag;
extern bool debug_scopes;
extern bool debug_eval_tree;
extern bool debug_elaborate;
extern bool debug_synth2;
extern bool debug_optimizer;
extern bool debug_synth;
extern bool debug_cprop;
/* Path to a directory useful for finding subcomponents. */
extern const char*basedir;
@@ -96,73 +95,27 @@ extern list<const char*>library_suff;
extern int build_library_index(const char*path, bool key_case_sensitive);
/* This is the generation of Verilog that the compiler is asked to
support. Then there are also more detailed controls for more
specific language features. */
support. */
enum generation_t {
GN_VER1995 = 1,
GN_VER2001 = 2,
GN_VER2005 = 3,
GN_SYSVER30 = 3,
GN_DEFAULT = 3
};
extern generation_t generation_flag;
/* If this flag is true, enable extended types support. */
extern bool gn_cadence_types_flag;
/* If this flag is true, enable miscellaneous extensions. */
extern bool gn_icarus_misc_flag;
/* If this flag is true, then elaborate specify blocks. If this flag
is false, then skip elaboration of specify behavior. */
extern bool gn_specify_blocks_flag;
/* If this flag is true, then support/elaborate Verilog-AMS. */
extern bool gn_verilog_ams_flag;
/* If this flag is false a warning is printed when the port declaration
is scalar and the net/register definition is vectored. */
extern bool gn_io_range_error_flag;
/* The bits of these GN_KEYWORDS_* constants define non-intersecting
sets of keywords. The compiler enables groups of keywords by setting
lexor_keyword_mask with the OR of the bits for the keywords to be
enabled. */
enum { GN_KEYWORDS_1364_1995 = 0x0001,
GN_KEYWORDS_1364_2001 = 0x0002,
GN_KEYWORDS_1364_2001_CONFIG = 0x0004,
GN_KEYWORDS_1364_2005 = 0x0008,
GN_KEYWORDS_VAMS_2_3 = 0x0010,
GN_KEYWORDS_ICARUS = 0x8000
};
extern int lexor_keyword_mask;
/* This is the string to use to invoke the preprocessor. */
extern char*ivlpp_string;
extern map<perm_string,unsigned> missing_modules;
/* Files that are library files are in this map. The lexor compares
file names as it processes `line directives, and if the file name
matches an entry in this table, it will turn on the
library_active_flag so that modules know that they are in a
library. */
extern map<perm_string,bool> library_file_map;
/*
* the lex_strings are perm_strings made up of tokens from the source
* file. Identifiers are so likely to be used many times that it makes
* much sense to use a StringHeapLex to hold them.
*/
extern StringHeapLex lex_strings;
extern StringHeap misc_strings;
/*
* The filename_strings are perm_strings for file names. They are put
* into their own StringHeapLex because these paths are used a *lot*
* and this makes them more sure to hash together.
*/
extern StringHeapLex filename_strings;
/*
@@ -175,7 +128,7 @@ extern StringHeapLex filename_strings;
*/
struct sfunc_return_type {
const char* name;
ivl_variable_type_t type;
NetExpr::TYPE type;
unsigned wid;
int signed_flag;
};
+1 -49
View File
@@ -1,7 +1,7 @@
#ifndef __config_H /* -*- c++ -*- */
#define __config_H
/*
* Copyright (c) 2001 Stephen Williams ([email protected])
* Copyright (c) 2001-2010 Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -18,9 +18,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: config.h.in,v 1.12 2007/02/02 04:33:00 steve Exp $"
#endif
#if defined(__cplusplus)
# if !defined(__GNUC__)
@@ -37,7 +34,6 @@
# undef HAVE_TIMES
# undef HAVE_IOSFWD
# undef HAVE_GETOPT_H
# undef HAVE_INTTYPES_H
# undef HAVE_LIBIBERTY_H
# undef HAVE_MALLOC_H
# undef HAVE_DLFCN_H
@@ -49,48 +45,4 @@
# undef HAVE_SYS_WAIT_H
# undef WORDS_BIGENDIAN
#ifdef HAVE_INTTYPES_H
# include <inttypes.h>
#endif
/*
* $Log: config.h.in,v $
* Revision 1.12 2007/02/02 04:33:00 steve
* Use inttypes.h instead of stdint.h for portability.
*
* Revision 1.11 2004/10/04 01:10:52 steve
* Clean up spurious trailing white space.
*
* Revision 1.10 2003/08/26 16:26:01 steve
* ifdef idents correctly.
*
* Revision 1.9 2003/07/03 16:29:55 steve
* spemm WORDS_BIGENDIAN correctly.
*
* Revision 1.8 2003/03/07 02:44:33 steve
* Implement $realtobits.
*
* Revision 1.7 2003/02/20 00:49:24 steve
* detect -lz and -lbz2 libraries.
*
* Revision 1.6 2003/01/10 19:01:04 steve
* Only use libiberty.h if available.
*
* Revision 1.5 2002/08/11 23:39:33 steve
* Remove VVM option.
*
* Revision 1.4 2002/02/16 03:18:53 steve
* Make vvm optional, normally off.
*
* Revision 1.3 2001/10/18 16:16:23 steve
* Include HAVE_SYS_WAIT in config.h (PR#306)
*
* Revision 1.2 2001/09/15 18:27:04 steve
* Make configure detect malloc.h
*
* Revision 1.1 2001/07/25 03:10:48 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
*
*/
#endif // __config_H
+36 -7
View File
@@ -11,7 +11,7 @@ AC_CHECK_TOOL(STRIP, strip, true)
AC_CHECK_PROGS(XGPERF,gperf,none)
AC_CHECK_PROGS(MAN,man,none)
AC_CHECK_PROGS(PS2PDF,ps2pdf,none)
AC_CHECK_PROGS(GIT,git,none)
if test "$XGPERF" = "none"
then
echo ""
@@ -45,7 +45,16 @@ AC_SUBST(EXEEXT)
# Combined check for Microsoft-related bogosities; sets WIN32 if found
AX_WIN32
AC_LANG_CPLUSPLUS
# vvp32 is by default disabled
#enable_vvp32=no
AC_SUBST(enable_vvp32)
AC_CHECK_DECL(__SUNPRO_C,AC_SUBST(WARNING_CFLAGS,),AC_SUBST(WARNING_CFLAGS,-Wall))
AC_LANG(C++)
AC_CHECK_DECL(__SUNPRO_CC,AC_SUBST(WARNING_CXXFLAGS,),AC_SUBST(WARNING_CXXFLAGS,-Wall))
AC_CHECK_DECL(__SUNPRO_CC,AC_SUBST(DEPENDENCY_CPPFLAGS,-xMD),AC_SUBST(DEPENDENCY_CPPFLAGS,-MD))
AC_CHECK_HEADERS(getopt.h malloc.h inttypes.h libiberty.h iosfwd sys/wait.h)
@@ -87,11 +96,13 @@ AC_SUBST(DLLIB)
AC_PROG_INSTALL
AC_LANG_C
AC_LANG(C)
AC_C_BIGENDIAN
# $host
AX_ENABLE_SUFFIX
AX_LD_EXTRALIBS
# Compiler option for position independent code, needed when making shared objects.
@@ -119,9 +130,27 @@ AX_C_UNDERSCORES_TRAILING
## end of test for underscores
#######################
AX_CPP_IDENT
# If not otherwise specified, set the libdir64 variable
# to the same as libdir.
AC_MSG_CHECKING(for libdir64 path)
if test x${libdir64} = x
then
libdir64="${libdir}"
fi
AC_SUBST(libdir64)
AC_MSG_RESULT(${libdir64})
# XXX disable tgt-fpga for the moment
AC_CONFIG_SUBDIRS(vvp vpi tgt-stub tgt-null tgt-vvp libveriuser cadpli)
# where to put vpi subdirectories
AC_MSG_CHECKING(for VPI subdirectories)
if test x${vpidir1} = x
then
vpidir1="."
fi
AC_OUTPUT(Makefile ivlpp/Makefile driver/Makefile driver-vpi/Makefile tgt-null/Makefile tgt-verilog/Makefile tgt-pal/Makefile)
AC_SUBST(vpidir1)
AC_SUBST(vpidir2)
AC_MSG_RESULT(${vpidir1} ${vpidir2})
AC_CONFIG_SUBDIRS(vvp vpi tgt-vvp tgt-edif tgt-fpga libveriuser cadpli)
AC_OUTPUT(Makefile ivlpp/Makefile driver/Makefile driver-vpi/Makefile tgt-null/Makefile tgt-stub/Makefile tgt-verilog/Makefile tgt-pal/Makefile)
-43
View File
@@ -1,43 +0,0 @@
// Mathematical and physical constants
`ifdef CONSTANTS_VAMS
`else
`define CONSTANTS_VAMS 1
// M_ is a mathematical constant
`define M_E 2.7182818284590452354
`define M_LOG2E 1.4426950408889634074
`define M_LOG10E 0.43429448190325182765
`define M_LN2 0.69314718055994530942
`define M_LN10 2.30258509299404568402
`define M_PI 3.14159265358979323846
`define M_TWO_PI 6.28318530717958647693
`define M_PI_2 1.57079632679489661923
`define M_PI_4 0.78539816339744830962
`define M_1_PI 0.31830988618379067154
`define M_2_PI 0.63661977236758134308
`define M_2_SQRTPI 1.12837916709551257390
`define M_SQRT2 1.41421356237309504880
`define M_SQRT1_2 0.70710678118654752440
/*
* Do we need these? For now they are not available.
*
// The following constants have been taken from http://physics.nist.gov
// P_ is a physical constant
// charge of electron in coulombs
`define P_Q 1.602176462e-19
// speed of light in vacuum in meters/sec
`define P_C 2.99792458e8
// Boltzmann's constant in joules/kelvin
`define P_K 1.3806503e-23
// Planck's constant in joules*sec
`define P_H 6.62606876e-34
// permittivity of vacuum in farads/meter
`define P_EPS0 8.854187817e-12
// permeability of vacuum in henrys/meter
`define P_U0 (4.0e-7 * `M_PI)
// zero celsius in kelvin
`define P_CELSIUS0 273.15
*/
`endif
+499 -146
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998-2005 Stephen Williams (steve@icarus.com)
* Copyright (c) 1998-2010 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -19,12 +19,11 @@
# include "config.h"
# include <cstdlib>
# include "netlist.h"
# include "netmisc.h"
# include "functor.h"
# include "compiler.h"
# include "ivl_assert.h"
# include <assert.h>
@@ -46,6 +45,9 @@ struct cprop_functor : public functor_t {
virtual void lpm_ff(Design*des, NetFF*obj);
virtual void lpm_logic(Design*des, NetLogic*obj);
virtual void lpm_mux(Design*des, NetMux*obj);
virtual void lpm_mux_large(Design*des, NetMux*obj);
virtual void lpm_ram_dq(Design*des, NetRamDq*obj);
bool lpm_ram_dq_const_address_(Design*des, NetRamDq*obj);
};
void cprop_functor::signal(Design*des, NetNet*obj)
@@ -54,6 +56,86 @@ void cprop_functor::signal(Design*des, NetNet*obj)
void cprop_functor::lpm_add_sub(Design*des, NetAddSub*obj)
{
// For now, only additions are handled.
if (obj->attribute(perm_string::literal("LPM_Direction")) != verinum("ADD"))
return;
// If the low bit on the A side is 0, then eliminate it from
// the adder, and pass the B side directly to the
// result. Don't reduce the adder smaller then a 1-bit
// adder. These will be eliminated later.
while ((obj->width() > 1)
&& obj->pin_DataA(0).nexus()->drivers_constant()
&& (obj->pin_DataA(0).nexus()->driven_value() == verinum::V0)) {
NetAddSub*tmp = 0;
tmp = new NetAddSub(obj->scope(), obj->name(), obj->width()-1);
//connect(tmp->pin_Aclr(), obj->pin_Aclr());
//connect(tmp->pin_Add_Sub(), obj->pin_Add_Sub());
//connect(tmp->pin_Clock(), obj->pin_Clock());
//connect(tmp->pin_Cin(), obj->pin_Cin());
connect(tmp->pin_Cout(), obj->pin_Cout());
//connect(tmp->pin_Overflow(), obj->pin_Overflow());
for (unsigned idx = 0 ; idx < tmp->width() ; idx += 1) {
connect(tmp->pin_DataA(idx), obj->pin_DataA(idx+1));
connect(tmp->pin_DataB(idx), obj->pin_DataB(idx+1));
connect(tmp->pin_Result(idx), obj->pin_Result(idx+1));
}
connect(obj->pin_Result(0), obj->pin_DataB(0));
delete obj;
des->add_node(tmp);
obj = tmp;
count += 1;
}
// Now do the same thing on the B side.
while ((obj->width() > 1)
&& obj->pin_DataB(0).nexus()->drivers_constant()
&& (obj->pin_DataB(0).nexus()->driven_value() == verinum::V0)) {
NetAddSub*tmp = 0;
tmp = new NetAddSub(obj->scope(), obj->name(), obj->width()-1);
//connect(tmp->pin_Aclr(), obj->pin_Aclr());
//connect(tmp->pin_Add_Sub(), obj->pin_Add_Sub());
//connect(tmp->pin_Clock(), obj->pin_Clock());
//connect(tmp->pin_Cin(), obj->pin_Cin());
connect(tmp->pin_Cout(), obj->pin_Cout());
//connect(tmp->pin_Overflow(), obj->pin_Overflow());
for (unsigned idx = 0 ; idx < tmp->width() ; idx += 1) {
connect(tmp->pin_DataA(idx), obj->pin_DataA(idx+1));
connect(tmp->pin_DataB(idx), obj->pin_DataB(idx+1));
connect(tmp->pin_Result(idx), obj->pin_Result(idx+1));
}
connect(obj->pin_Result(0), obj->pin_DataA(0));
delete obj;
des->add_node(tmp);
obj = tmp;
count += 1;
}
// If the adder is only 1 bit wide, then replace it with the
// simple logic gate.
if (obj->width() == 1) {
NetLogic*tmp;
if (obj->pin_Cout().is_linked()) {
tmp = new NetLogic(obj->scope(),
obj->scope()->local_symbol(),
3, NetLogic::AND);
connect(tmp->pin(0), obj->pin_Cout());
connect(tmp->pin(1), obj->pin_DataA(0));
connect(tmp->pin(2), obj->pin_DataB(0));
des->add_node(tmp);
}
tmp = new NetLogic(obj->scope(), obj->name(), 3, NetLogic::XOR);
connect(tmp->pin(0), obj->pin_Result(0));
connect(tmp->pin(1), obj->pin_DataA(0));
connect(tmp->pin(2), obj->pin_DataB(0));
delete obj;
des->add_node(tmp);
count += 1;
return;
}
}
void cprop_functor::lpm_compare(Design*des, NetCompare*obj)
@@ -72,8 +154,6 @@ void cprop_functor::lpm_compare(Design*des, NetCompare*obj)
void cprop_functor::lpm_compare_eq_(Design*des, NetCompare*obj)
{
#if 0
/* XXXX Need to reimplement this code to account for vectors. */
NetScope*scope = obj->scope();
unsigned const_count = 0;
@@ -169,7 +249,7 @@ void cprop_functor::lpm_compare_eq_(Design*des, NetCompare*obj)
with a simple XOR gate. */
if (top == 1) {
NetLogic*tmp = new NetLogic(scope, obj->name(), 3,
NetLogic::XNOR, 1);
NetLogic::XNOR);
connect(tmp->pin(0), obj->pin_AEB());
connect(tmp->pin(1), obj->pin_DataA(0));
connect(tmp->pin(2), obj->pin_DataB(0));
@@ -192,7 +272,6 @@ void cprop_functor::lpm_compare_eq_(Design*des, NetCompare*obj)
delete obj;
des->add_node(tmp);
count += 1;
#endif
}
void cprop_functor::lpm_ff(Design*des, NetFF*obj)
@@ -200,30 +279,61 @@ void cprop_functor::lpm_ff(Design*des, NetFF*obj)
// Look for and count unlinked FF outputs. Note that if the
// Data and Q pins are connected together, they can be removed
// from the circuit, since it doesn't do anything.
unsigned unlinked_count = 0;
for (unsigned idx = 0 ; idx < obj->width() ; idx += 1) {
if (connected(obj->pin_Data(idx), obj->pin_Q(idx))
&& (! obj->pin_Sclr().is_linked())
&& (! obj->pin_Sset().is_linked())
&& (! obj->pin_Aclr().is_linked())
&& (! obj->pin_Aset().is_linked())) {
obj->pin_Data(idx).unlink();
obj->pin_Q(idx).unlink();
}
if (! obj->pin_Q(idx).is_linked())
unlinked_count += 1;
}
if (connected(obj->pin_Data(), obj->pin_Q())
&& (! obj->pin_Sclr().is_linked())
&& (! obj->pin_Sset().is_linked())
&& (! obj->pin_Aclr().is_linked())
&& (! obj->pin_Aset().is_linked())) {
obj->pin_Data().unlink();
obj->pin_Q().unlink();
// If the entire FF is unlinked, remove the whole thing.
if (unlinked_count == obj->width()) {
delete obj;
count += 1;
return;
}
// If some of the FFs are unconnected, make a new FF array
// that does not include the useless FF devices.
if (unlinked_count > 0) {
NetFF*tmp = new NetFF(obj->scope(), obj->name(),
obj->width()-unlinked_count);
connect(tmp->pin_Clock(), obj->pin_Clock());
connect(tmp->pin_Enable(), obj->pin_Enable());
connect(tmp->pin_Aset(), obj->pin_Aset());
connect(tmp->pin_Aclr(), obj->pin_Aclr());
connect(tmp->pin_Sset(), obj->pin_Sset());
connect(tmp->pin_Sclr(), obj->pin_Sclr());
unsigned tidx = 0;
for (unsigned idx = 0 ; idx < obj->width() ; idx += 1)
if (obj->pin_Q(idx).is_linked()) {
connect(tmp->pin_Data(tidx), obj->pin_Data(idx));
connect(tmp->pin_Q(tidx), obj->pin_Q(idx));
tidx += 1;
}
assert(tidx == obj->width() - unlinked_count);
delete obj;
des->add_node(tmp);
count += 1;
return;
}
}
void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
{
#if 0
NetScope*scope = obj->scope();
#endif
switch (obj->type()) {
#if 0
/* XXXX This old code assumed that the individual bit
slices could be replaced with different gates. They
cannot when the device takes atomic vectors, so this
needs to be rewritten. XXXX */
case NetLogic::NAND:
case NetLogic::AND: {
unsigned top = obj->pin_count();
@@ -338,12 +448,12 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
case NetLogic::AND:
tmp = new NetLogic(scope,
obj->name(), 2,
NetLogic::BUF, 1);
NetLogic::BUF);
break;
case NetLogic::NAND:
tmp = new NetLogic(scope,
obj->name(), 2,
NetLogic::NOT, 1);
NetLogic::NOT);
break;
default:
assert(0);
@@ -369,7 +479,7 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
if (top < obj->pin_count()) {
NetLogic*tmp = new NetLogic(scope,
obj->name(), top,
obj->type(), 1);
obj->type());
tmp->rise_time(obj->rise_time());
tmp->fall_time(obj->fall_time());
tmp->decay_time(obj->decay_time());
@@ -386,12 +496,7 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
}
break;
}
#endif
#if 0
/* XXXX This old code assumed that the individual bit
slices could be replaced with different gates. They
cannot when the device takes atomic vectors, so this
needs to be rewritten. XXXX */
case NetLogic::NOR:
case NetLogic::OR: {
@@ -491,12 +596,12 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
case NetLogic::OR:
tmp = new NetLogic(scope,
obj->name(), 2,
NetLogic::BUF, 1);
NetLogic::BUF);
break;
case NetLogic::NOR:
tmp = new NetLogic(scope,
obj->name(), 2,
NetLogic::NOT, 1);
NetLogic::NOT);
break;
default:
assert(0);
@@ -513,7 +618,7 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
delete obj;
count += 1;
return;
v }
}
/* Finally, this cleans up the gate by creating a
new [N]OR gate that has the right number of
@@ -521,7 +626,7 @@ v }
if (top < obj->pin_count()) {
NetLogic*tmp = new NetLogic(scope,
obj->name(), top,
obj->type(), 1);
obj->type());
tmp->rise_time(obj->rise_time());
tmp->fall_time(obj->fall_time());
tmp->decay_time(obj->decay_time());
@@ -538,12 +643,7 @@ v }
}
break;
}
#endif
#if 0
/* XXXX This old code assumed that the individual bit
slices could be replaced with different gates. They
cannot when the device takes atomic vectors, so this
needs to be rewritten. XXXX */
case NetLogic::XNOR:
case NetLogic::XOR: {
unsigned top = obj->pin_count();
@@ -665,11 +765,11 @@ v }
if (obj->type() == NetLogic::XOR)
tmp = new NetLogic(scope,
obj->name(), 2,
NetLogic::NOT, 1);
NetLogic::NOT);
else
tmp = new NetLogic(scope,
obj->name(), 2,
NetLogic::BUF, 1);
NetLogic::BUF);
tmp->rise_time(obj->rise_time());
tmp->fall_time(obj->fall_time());
@@ -694,11 +794,11 @@ v }
if (obj->type() == NetLogic::XOR)
tmp = new NetLogic(scope,
obj->name(), 2,
NetLogic::BUF, 1);
NetLogic::BUF);
else
tmp = new NetLogic(scope,
obj->name(), 2,
NetLogic::NOT, 1);
NetLogic::NOT);
tmp->rise_time(obj->rise_time());
tmp->fall_time(obj->fall_time());
@@ -720,7 +820,7 @@ v }
if (top < obj->pin_count()) {
NetLogic*tmp = new NetLogic(scope,
obj->name(), top,
obj->type(), 1);
obj->type());
des->add_node(tmp);
tmp->pin(0).drive0(obj->pin(0).drive0());
tmp->pin(0).drive1(obj->pin(0).drive1());
@@ -733,130 +833,386 @@ v }
}
break;
}
#endif
default:
break;
}
}
static void replace_with_bufif(Design*des, NetMux*obj, NetLogic::TYPE type)
{
NetScope*scope = obj->scope();
NetLogic*tmp = new NetLogic(obj->scope(),
scope->local_symbol(),
3, type, obj->width());
des->add_node(tmp);
connect(obj->pin_Result(), tmp->pin(0));
connect(obj->pin_Data(type==NetLogic::BUFIF0? 0 : 1), tmp->pin(1));
if (obj->width() == 1) {
/* Special case that the expression is 1 bit
wide. Connect the select directly to the enable. */
connect(obj->pin_Sel(), tmp->pin(2));
} else {
/* General case that the expression is arbitrarily
wide. Replicate the enable signal (which we
assume is 1 bit wide) to match the expression,
and connect the enable vector to the enable
input of the gate. */
NetReplicate*rtmp = new NetReplicate(scope,
scope->local_symbol(),
obj->width(),
obj->width());
des->add_node(rtmp);
connect(obj->pin_Sel(), rtmp->pin(1));
connect(tmp->pin(2), rtmp->pin(0));
NetNet*rsig = new NetNet(scope, scope->local_symbol(),
NetNet::WIRE, obj->width());
rsig->local_flag(true);
rsig->data_type(IVL_VT_LOGIC);
connect(tmp->pin(2), rsig->pin(0));
}
delete obj;
}
/*
* This detects the case where the mux selects between a value and
* Vz. In this case, replace the device with a bufif with the sel
* Vz. In this case, replace the device with a MOS with the sel
* input used to enable the output.
*/
void cprop_functor::lpm_mux(Design*des, NetMux*obj)
{
if (obj->size() > 2) {
lpm_mux_large(des, obj);
return;
}
if (obj->size() != 2)
return;
if (obj->sel_width() != 1)
return;
/* If the first input is all constant Vz, then replace the
NetMux with an array of BUFIF1 devices, with the enable
connected to the select input. */
NetScope*scope = obj->scope();
bool flag = true;
for (unsigned idx = 0 ; idx < obj->width() ; idx += 1) {
bool cflag_a = obj->pin_Data(idx, 0).nexus()->drivers_constant();
bool cflag_b = obj->pin_Data(idx, 1).nexus()->drivers_constant();
if (! obj->pin_Data(0).nexus()->drivers_constant()) {
/* If both data inputs are constant, we'll be able to do
a substitution. */
if (cflag_a && cflag_b)
continue;
verinum::V va = cflag_a
? obj->pin_Data(idx, 0).nexus()->driven_value()
: verinum::Vx;
verinum::V vb = cflag_b
? obj->pin_Data(idx, 1).nexus()->driven_value()
: verinum::Vx;
/* If only one Data input is constant, but a constant
HiZ, then we will be able to do a MOS
substitution. */
if (cflag_a && va==verinum::Vz)
continue;
if (cflag_b && vb==verinum::Vz)
continue;
/* Otherwise, we cannot accurately do a substitution. If
one input is non-constant, then that input may have a
HiZ value, and there is no Verilog logic other than a
MUX that can pass a HiZ value. */
flag = false;
}
if (flag && obj->pin_Data(0).nexus()->driven_value() != verinum::Vz) {
flag = false;
}
if (flag) {
replace_with_bufif(des, obj, NetLogic::BUFIF1);
count += 1;
if (! flag) {
return;
}
/* Create a temporary net to hold the result value that we
build up. When we are done, we will connect this to the
Result pins of the mux, then delete the mux *and* this
net. That will cause all the proper connectivity to
happen. */
NetNet result_tmp(scope, scope->local_symbol(),
NetNet::WIRE, obj->width());
/* We know that every slice has at least one constant. Run
through the slices again, creating boolean devices to
replace the MUX slice. */
for (unsigned idx = 0 ; idx < obj->width() ; idx += 1) {
/* If the Sel==0 input is constant Z, make a NMOS. */
if (obj->pin_Data(idx, 0).nexus()->drivers_constant()
&& obj->pin_Data(idx, 0).nexus()->driven_value()==verinum::Vz) {
NetLogic*tmp = new NetLogic(scope,
scope->local_symbol(),
3, NetLogic::NMOS);
connect(result_tmp.pin(idx), tmp->pin(0));
connect(obj->pin_Data(idx,1), tmp->pin(1));
connect(obj->pin_Sel(0), tmp->pin(2));
des->add_node(tmp);
continue;
}
/* If the Sel==1 input is constant Z, make a PMOS. */
if (obj->pin_Data(idx, 1).nexus()->drivers_constant()
&& obj->pin_Data(idx, 1).nexus()->driven_value()==verinum::Vz) {
NetLogic*tmp = new NetLogic(scope,
scope->local_symbol(),
3, NetLogic::PMOS);
connect(result_tmp.pin(idx), tmp->pin(0));
connect(obj->pin_Data(idx,0), tmp->pin(1));
connect(obj->pin_Sel(0), tmp->pin(2));
des->add_node(tmp);
continue;
}
/* At this point, the only cases that are left are where
the data inputs are both constant, and neither are
HiZ. From this we know how to generate the output
from only the S input. */
if (! (obj->pin_Data(idx, 0).nexus()->drivers_constant()
&& obj->pin_Data(idx, 1).nexus()->drivers_constant())) {
cerr << obj->get_line() << ": internal error: "
<< "Drivers not constant where expected?"
<< " obj->width()=" << obj->width()
<< " idx=" << idx
<< endl;
obj->dump_node(cerr, 4);
}
assert(obj->pin_Data(idx, 0).nexus()->drivers_constant()
&& obj->pin_Data(idx, 1).nexus()->drivers_constant());
verinum::V a = obj->pin_Data(idx, 0).nexus()->driven_value();
verinum::V b = obj->pin_Data(idx, 1).nexus()->driven_value();
if (a == b) {
connect(result_tmp.pin(idx), obj->pin_Data(idx,0));
continue;
}
if (a == verinum::V0 && b == verinum::V1) {
connect(result_tmp.pin(idx), obj->pin_Sel(0));
continue;
}
if (a == verinum::V1 && b == verinum::V0) {
NetLogic*tmp = new NetLogic(scope,
scope->local_symbol(),
2, NetLogic::NOT);
connect(result_tmp.pin(idx), tmp->pin(0));
connect(obj->pin_Sel(0), tmp->pin(1));
des->add_node(tmp);
continue;
}
/* A==0: Q = B & S */
if (a == verinum::V0) {
NetLogic*tmp = new NetLogic(scope,
scope->local_symbol(),
3, NetLogic::AND);
connect(result_tmp.pin(idx), tmp->pin(0));
connect(obj->pin_Data(idx,1), tmp->pin(1));
connect(obj->pin_Sel(0), tmp->pin(2));
des->add_node(tmp);
continue;
}
/* B==1: Q = A | S */
if (b == verinum::V1) {
NetLogic*tmp = new NetLogic(scope,
scope->local_symbol(),
3, NetLogic::OR);
connect(result_tmp.pin(idx), tmp->pin(0));
connect(obj->pin_Data(idx,0), tmp->pin(1));
connect(obj->pin_Sel(0), tmp->pin(2));
des->add_node(tmp);
continue;
}
/* A==1: Q = B | ~S */
if (a == verinum::V1) {
NetLogic*inv = new NetLogic(scope,
scope->local_symbol(),
2, NetLogic::NOT);
NetNet*invs = new NetNet(scope,
scope->local_symbol(),
NetNet::TRI, 1);
invs->local_flag(true);
connect(inv->pin(0), invs->pin(0));
connect(inv->pin(1), obj->pin_Sel(0));
des->add_node(inv);
NetLogic*tmp = new NetLogic(scope,
scope->local_symbol(),
3, NetLogic::OR);
connect(result_tmp.pin(idx), tmp->pin(0));
connect(obj->pin_Data(idx,1), tmp->pin(1));
connect(inv->pin(0), tmp->pin(2));
des->add_node(tmp);
continue;
}
/* B==0: Q = A & ~S */
if (b == verinum::V0) {
NetLogic*inv = new NetLogic(scope,
scope->local_symbol(),
2, NetLogic::NOT);
NetNet*invs = new NetNet(scope,
scope->local_symbol(),
NetNet::TRI, 1);
invs->local_flag(true);
connect(inv->pin(0), invs->pin(0));
connect(inv->pin(1), obj->pin_Sel(0));
des->add_node(inv);
NetLogic*tmp = new NetLogic(scope,
scope->local_symbol(),
3, NetLogic::AND);
connect(result_tmp.pin(idx), tmp->pin(0));
connect(obj->pin_Data(idx,0), tmp->pin(1));
connect(inv->pin(0), tmp->pin(2));
des->add_node(tmp);
continue;
}
assert(0);
/* If instead the second input is all constant Vz, replace the
NetMux with an array of BUFIF0 devices. */
flag = true;
if (! obj->pin_Data(1).nexus()->drivers_constant()) {
flag = false;
}
if (flag && obj->pin_Data(1).nexus()->driven_value() != verinum::Vz) {
flag = false;
}
for (unsigned idx = 0 ; idx < obj->width() ; idx += 1)
connect(result_tmp.pin(idx), obj->pin_Result(idx));
if (flag) {
replace_with_bufif(des, obj, NetLogic::BUFIF0);
count += 1;
return;
}
/* If the select input is constant, then replace with a BUFZ */
flag = obj->pin_Sel().nexus()->drivers_constant();
verinum::V sel_val = flag? obj->pin_Sel().nexus()->driven_value() : verinum::Vx;
if ((sel_val != verinum::Vz) && (sel_val != verinum::Vx)) {
NetBUFZ*tmp = new NetBUFZ(obj->scope(), obj->name(), obj->width());
tmp->set_line(*obj);
if (debug_optimizer)
cerr << obj->get_fileline() << ": debug: "
<< "Replace binary MUX with constant select=" << sel_val
<< " with a BUFZ to the selected input." << endl;
tmp->rise_time(obj->rise_time());
tmp->fall_time(obj->fall_time());
tmp->decay_time(obj->decay_time());
connect(tmp->pin(0), obj->pin_Result());
if (sel_val == verinum::V1)
connect(tmp->pin(1), obj->pin_Data(1));
else
connect(tmp->pin(1), obj->pin_Data(0));
delete obj;
des->add_node(tmp);
count += 1;
}
delete obj;
count += 1;
}
void cprop_functor::lpm_mux_large(Design*des, NetMux*obj)
{
NetScope*scope = obj->scope();
unsigned width = obj->width();
unsigned size = obj->size();
/* This test looks for bit slices that are constant
throughout. If we find any, we can reduce the width of the
MUX to eliminate the fixed value. */
/* After the following for loop, this array of bools will
contain "true" for each bit slice that is constant and
identical, and "false" otherwise. The reduce_width will
count the number of true entries in the flags array. */
bool*flags = new bool[width];
unsigned reduce_width = 0;
for (unsigned bit = 0 ; bit < width ; bit += 1) {
flags[bit] = true;
/* If not even the first selection is constant, then the
slice cannot be reduced. */
if (! obj->pin_Data(bit, 0).nexus()->drivers_constant()) {
flags[bit] = false;
continue;
}
/* If any of the remaining selections in non-consant, or
constant with a different value, then this slice
cannot be reduced. */
verinum::V val = obj->pin_Data(bit, 0).nexus()->driven_value();
for (unsigned idx = 1; flags[bit] && idx < size ; idx += 1) {
if (!obj->pin_Data(bit,idx).nexus()->drivers_constant()) {
flags[bit] = false;
break;
}
if (val != obj->pin_Data(bit,idx).nexus()->driven_value()) {
flags[bit] = false;
break;
}
}
if (! flags[bit]) {
/* This bit slice is too complex. Go on. */
continue;
}
reduce_width += 1;
}
/* If no slices can be reduced, then we are finished. */
if (reduce_width == 0) {
delete[]flags;
return;
}
/* Handle the very special case that all the slices can be
reduced. We don't need a MUX at all! */
if (reduce_width == width) {
for (unsigned idx = 0 ; idx < width ; idx += 1)
connect(obj->pin_Result(idx), obj->pin_Data(idx,0));
delete obj;
count += 1;
delete[]flags;
return;
}
/* Create a reduced mux with the same name and size, but fewer
slices. Connect all the slices that we are keeping. */
NetMux*tmp = new NetMux(scope, obj->name(),
width-reduce_width, size, obj->sel_width());
tmp->set_line(*obj);
for (unsigned idx = 0 ; idx < obj->sel_width() ; idx += 1)
connect(obj->pin_Sel(idx), tmp->pin_Sel(idx));
unsigned dst_bit = 0;
for (unsigned bit = 0 ; bit < width ; bit += 1) {
if (flags[bit]) {
connect(obj->pin_Result(bit), obj->pin_Data(bit,0));
continue;
}
connect(obj->pin_Result(bit), tmp->pin_Result(dst_bit));
for (unsigned idx = 0 ; idx < size ; idx += 1)
connect(obj->pin_Data(bit,idx), tmp->pin_Data(dst_bit,idx));
dst_bit += 1;
}
/* Add the new node. Delete the old node. Signal that we
change the design and may use a rescan. */
des->add_node(tmp);
delete obj;
delete[]flags;
count += 1;
}
void cprop_functor::lpm_ram_dq(Design*des, NetRamDq*obj)
{
if (lpm_ram_dq_const_address_(des,obj))
return;
}
/*
* Try to evaluate a constant address input. If we find it, then
* replace the NetRamDq with a direct link to the addressed word.
*/
bool cprop_functor::lpm_ram_dq_const_address_(Design*des, NetRamDq*obj)
{
NetMemory*mem = obj->mem();
NetNet* reg = mem->reg_from_explode();
/* I only know how to do this on exploded memories. */
if (reg == 0)
return false;
verinum sel (0UL, obj->awidth());
for (unsigned idx = 0 ; idx < obj->awidth() ; idx += 1) {
if (! obj->pin_Address(idx).nexus()->drivers_constant())
return false;
sel.set(idx, obj->pin_Address(idx).nexus()->driven_value());
}
unsigned long address = sel.as_ulong();
/* If the address is outside the ram, then leave this to the
code generator to figure out. */
if (address >= obj->size())
return false;
unsigned base = address * obj->width();
assert(base+obj->width() <= reg->pin_count());
for (unsigned idx = 0 ; idx < obj->width() ; idx += 1)
connect(reg->pin(base+idx), obj->pin_Q(idx));
if (debug_cprop) {
cerr << obj->get_line() << ": debug: Replace read port with"
<< " fixed link to word " << address << "." << endl;
}
delete obj;
count += 1;
return true;
}
/*
* This functor looks to see if the constant is connected to nothing
* but signals. If that is the case, delete the dangling constant and
@@ -871,17 +1227,15 @@ struct cprop_dc_functor : public functor_t {
void cprop_dc_functor::lpm_const(Design*des, NetConst*obj)
{
// 'bz constant values drive high impedance to whatever is
// connected to it. In other words, it is a noop. But that is
// only true if *all* the bits of the vectors.
// connected to it. In other words, it is a noop.
{ unsigned tmp = 0;
ivl_assert(*obj, obj->pin_count()==1);
for (unsigned idx = 0 ; idx < obj->width() ; idx += 1) {
for (unsigned idx = 0 ; idx < obj->pin_count() ; idx += 1)
if (obj->value(idx) == verinum::Vz) {
obj->pin(idx).unlink();
tmp += 1;
}
}
if (tmp == obj->width()) {
if (tmp == obj->pin_count()) {
delete obj;
return;
}
@@ -974,4 +1328,3 @@ void cprop(Design*des)
cprop_dc_functor dc;
des->functor(&dc);
}
+194 -453
View File
File diff suppressed because it is too large Load Diff
-39
View File
@@ -1,39 +0,0 @@
/*
* Copyright (c) 2008 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
# include "discipline.h"
nature_t::nature_t(perm_string name, perm_string access)
: name_(name), access_(access)
{
}
nature_t::~nature_t()
{
}
discipline_t::discipline_t(perm_string name, ddomain_t domain,
nature_t*pot, nature_t*flow)
: name_(name), domain_(domain), potential_(pot), flow_(flow)
{
}
discipline_t::~discipline_t()
{
}
-75
View File
@@ -1,75 +0,0 @@
#ifndef __discipline_H
#define __discipline_H
/*
* Copyright (c) 2008 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
/*
* The discipline types include the discipline, nature and other
* related types for managing declared and used disciplines in a
* Verilog-AMS program.
*/
# include "StringHeap.h"
# include <iostream>
# include <map>
# include "LineInfo.h"
typedef enum { DD_NONE, DD_DISCRETE, DD_CONTINUOUS } ddomain_t;
extern std::ostream& operator << (std::ostream&, ddomain_t);
class nature_t : public LineInfo {
public:
explicit nature_t(perm_string name, perm_string access);
~nature_t();
perm_string name() const { return name_; }
// Identifier for the access function for this nature
perm_string access() const { return access_; }
private:
perm_string name_;
perm_string access_;
};
class discipline_t : public LineInfo {
public:
explicit discipline_t (perm_string name, ddomain_t dom,
nature_t*pot, nature_t*flow);
~discipline_t();
perm_string name() const { return name_; }
ddomain_t domain() const { return domain_; }
const nature_t*potential() const { return potential_; }
const nature_t*flow() const { return flow_; }
private:
perm_string name_;
ddomain_t domain_;
nature_t*potential_;
nature_t*flow_;
private: // not implemented
discipline_t(const discipline_t&);
discipline_t& operator = (const discipline_t&);
};
extern map<perm_string,nature_t*> natures;
extern map<perm_string,discipline_t*> disciplines;
#endif
-72
View File
@@ -1,72 +0,0 @@
// Standard definitions for Verilog-AMS
`ifdef DISCIPLINES_VAMS
`else
`define DISCIPLINES_VAMS 1
discipline \logic ;
domain discrete;
enddiscipline
discipline ddiscrete;
domain discrete;
enddiscipline
nature Current;
units = "A";
access = I;
idt_nature = Charge;
`ifdef CURRENT_ABSTOL
abstol = `CURRENT_ABSTOL
`else
abstol = 1e-12;
`endif
endnature
nature Charge;
units = "coul";
access = Q;
ddt_nature = Current;
`ifdef CHARGE_ABSTOL
abstol = `CHARGE_ABSTOL;
`else
abstol = 1e-14;
`endif
endnature
nature Voltage;
units = "V";
access = V;
idt_nature = Flux;
`ifdef VOLTAGE_ABSTOL
abstol = `VOLTAGE_ABSTOL;
`else
abstol = 1e-6;
`endif
endnature
nature Flux;
units = "Wb";
access = Phi;
ddt_nature = Voltage;
`ifdef FLUX_ABSTOL
abstol = `flux_ABSTOL;
`else
abstol = 1e-9;
`endif
endnature
discipline electrical;
potential Voltage;
flow Current;
enddiscipline
discipline voltage;
potential Voltage;
enddiscipline
discipline current;
flow Current;
enddiscipline
`endif // !`ifdef DISCIPLINES_VAMS
-2
View File
@@ -1,2 +0,0 @@
Makefile
iverilog-vpi.exe
+10 -9
View File
@@ -15,10 +15,10 @@
# Software Foundation, Inc.,
# 59 Temple Place - Suite 330
# Boston, MA 02111-1307, USA
#
SHELL = /bin/sh
VERSION = 0.9.devel
suffix = @install_suffix@
prefix = @prefix@
exec_prefix = @exec_prefix@
@@ -27,6 +27,8 @@ datarootdir = @datarootdir@
VPATH = $(srcdir)
suffix = @install_suffix@
bindir = $(exec_prefix)/bin
libdir = $(exec_prefix)/lib
includedir = $(prefix)/include
@@ -39,14 +41,12 @@ INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
CPPFLAGS = @ident_support@ -I. -I$(srcdir)/.. -DVERSION='"$(VERSION)"' @CPPFLAGS@ @DEFS@
CPPFLAGS = -I. -I$(srcdir)/.. @CPPFLAGS@ @DEFS@
CFLAGS = -Wall @CFLAGS@
LDFLAGS = @LDFLAGS@
all: iverilog-vpi@EXEEXT@
check: all
clean:
rm -f *.o config.h
rm -f iverilog-vpi@EXEEXT@
@@ -65,6 +65,7 @@ main.o: main.c config.h
config.h: config.h.in
sed -e 's;@IVLCC@;@CC@;' -e 's;@IVLCXX@;@CXX@;' \
-e 's;@SUFFIX@;$(suffix);g' \
-e 's;@IVLCFLAGS@;@CXXFLAGS@;' \
-e 's;@SHARED@;@shared@;' $< > $@
@@ -73,13 +74,13 @@ res.o: res.rc
windres -i res.rc -o res.o
#
install: all installdirs $(bindir)/iverilog-vpi@EXEEXT@
install: all installdirs $(bindir)/iverilog-vpi$(suffix)@EXEEXT@
$(bindir)/iverilog-vpi@EXEEXT@: ./iverilog-vpi@EXEEXT@
$(INSTALL_PROGRAM) ./iverilog-vpi@EXEEXT@ $(bindir)/iverilog-vpi@EXEEXT@
$(bindir)/iverilog-vpi$(suffix)@EXEEXT@: ./iverilog-vpi@EXEEXT@
$(INSTALL_PROGRAM) ./iverilog-vpi@EXEEXT@ $(bindir)/iverilog-vpi$(suffix)@EXEEXT@
installdirs: ../mkinstalldirs
$(srcdir)/../mkinstalldirs $(bindir)
uninstall:
rm -f $(bindir)/iverilog-vpi@EXEEXT@
rm -f $(bindir)/iverilog-vpi$(suffix)@EXEEXT@
+2 -1
View File
@@ -5,4 +5,5 @@
#define IVERILOG_VPI_CXX "@IVLCXX@"
#define IVERILOG_VPI_CFLAGS " @IVLCFLAGS@"
#define IVERILOG_VPI_LDFLAGS "@SHARED@"
#define IVERILOG_VPI_LDLIBS "-lveriuser -lvpi"
#define IVERILOG_VPI_LDLIBS "-lveriuser@SUFFIX@ -lvpi@SUFFIX@"
#define IVERILOG_SUFFIX "@SUFFIX@"
+10 -14
View File
@@ -87,9 +87,9 @@ static void myExit(int exitVal)
static void usage()
{
fprintf(stderr,"usage: iverilog-vpi [src and obj files]...\n");
fprintf(stderr," or iverilog-vpi -mingw=dir\n");
fprintf(stderr," or iverilog-vpi -ivl=dir\n");
fprintf(stderr,"usage: iverilog-vpi" IVERILOG_SUFFIX " [src and obj files]...\n");
fprintf(stderr," or iverilog-vpi" IVERILOG_SUFFIX " -mingw=dir\n");
fprintf(stderr," or iverilog-vpi" IVERILOG_SUFFIX " -ivl=dir\n");
myExit(1);
}
@@ -384,7 +384,7 @@ static int parse(int argc, char *argv[])
/* Check for the --install-dir option */
else if (stricmp("--install-dir", argv[idx]) == 0) {
setup_ivl_environment();
printf("%s\\\\lib\\\\ivl\\\\.\n", gstr.pIVL);
printf("%s\\\\lib\\\\ivl" IVERILOG_SUFFIX "\\\\.\n", gstr.pIVL);
myExit(0);
}
/* This is different than iverilog-vpi.sh, we don't
@@ -444,14 +444,14 @@ static void checkIvlDir(char *root)
initDynString(&path);
assign(&path,gstr.pIVL);
appendBackSlash(&path);
append(&path,"bin\\vvp.exe");
append(&path,"bin\\vvp" IVERILOG_SUFFIX ".exe");
irv = _stat(path,&stat_buf);
deInitDynString(path);
if (irv) {
fprintf(stderr,"error: %s does not appear to be the valid root directory of\n",root);
fprintf(stderr," Icarus Verilog. Use the -ivl option of iverilog-vpi.exe to\n");
fprintf(stderr," Icarus Verilog. Use the -ivl option of iverilog-vpi" IVERILOG_SUFFIX " to\n");
fprintf(stderr," point to the Icarus Verilog root directory. For a Windows\n");
fprintf(stderr," command shell the option would be something like -ivl=c:\\iverilog\n");
fprintf(stderr," For a Cygwin shell the option would be something like\n");
@@ -503,7 +503,7 @@ static void setup_ivl_environment()
SetRegistryKey(IVL_REGKEY_IVL,gstr.pIVL);
} else if (!GetRegistryKey(IVL_REGKEY_IVL,&gstr.pIVL)) {
fprintf(stderr,"error: can not locate the Icarus Verilog root directory, use the -ivl option\n");
fprintf(stderr," of iverilog-vpi.exe to point to the Icarus Verilog root directory.\n");
fprintf(stderr," of iverilog-vpi" IVERILOG_SUFFIX " to point to the Icarus Verilog root directory.\n");
fprintf(stderr," For a Windows command shell the option would be something like\n");
fprintf(stderr," -ivl=c:\\iverilog For a Cygwin shell the option would be something\n");
fprintf(stderr," like -ivl=c:\\\\iverilog\n");
@@ -511,20 +511,16 @@ static void setup_ivl_environment()
}
/* Build up the CFLAGS option string */
assign(&gstr.pCFLAGS,IVERILOG_VPI_CFLAGS);
append(&gstr.pCFLAGS," -I");
assign(&gstr.pCFLAGS,IVERILOG_VPI_CFLAGS " -I");
append(&gstr.pCFLAGS,gstr.pIVL);
appendBackSlash(&gstr.pCFLAGS);
append(&gstr.pCFLAGS, "\\");
append(&gstr.pCFLAGS,"include");
append(&gstr.pCFLAGS,"\\include\\\\iverilog" IVERILOG_SUFFIX);
/* Build up the LDFLAGS option string */
assign(&gstr.pLDLIBS,"-L");
append(&gstr.pLDLIBS,gstr.pIVL);
appendBackSlash(&gstr.pLDLIBS);
append(&gstr.pLDLIBS, "\\");
append(&gstr.pLDLIBS,"lib ");
append(&gstr.pLDLIBS,IVERILOG_VPI_LDLIBS);
append(&gstr.pLDLIBS,"\\lib " IVERILOG_VPI_LDLIBS);
}
/* compile source modules */
-15
View File
@@ -1,15 +0,0 @@
a.out
Makefile
parse.c
parse.h
parse.output
lexor.c
cfparse.c
cfparse.h
cfparse.output
cflexor.c
foo.*
iverilog
iverilog.ps
iverilog.pdf
tmp.pdf
+25 -22
View File
@@ -15,10 +15,10 @@
# Software Foundation, Inc.,
# 59 Temple Place - Suite 330
# Boston, MA 02111-1307, USA
#
SHELL = /bin/sh
VERSION = 0.9.devel
suffix = @install_suffix@
prefix = @prefix@
exec_prefix = @exec_prefix@
@@ -41,8 +41,8 @@ INSTALL_DATA = @INSTALL_DATA@
MAN = @MAN@
PS2PDF = @PS2PDF@
CPPFLAGS = @ident_support@ -I. -I.. -I$(srcdir)/.. -I$(srcdir) -DVERSION='"$(VERSION)"' @CPPFLAGS@ @DEFS@
CFLAGS = -Wall @CFLAGS@
CPPFLAGS = -I. -I.. -I$(srcdir)/.. -I$(srcdir) @CPPFLAGS@ @DEFS@
CFLAGS = @WARNING_CFLAGS@ @CFLAGS@
LDFLAGS = @LDFLAGS@
all: iverilog@EXEEXT@
@@ -50,10 +50,12 @@ all: iverilog@EXEEXT@
clean:
rm -f *.o lexor.c parse.c parse.h parse.output
rm -f cflexor.c cfparse.c cfparse.h cfparse.output
rm -f iverilog@EXEEXT@ iverilog.pdf iverilog.ps
rm -f iverilog.ps iverilog.pdf
rm -f iverilog@EXEEXT@
distclean: clean
rm -f Makefile
rm -rf autom4te.cache
O = main.o substit.o cflexor.o cfparse.o
@@ -67,8 +69,8 @@ cfparse.h cfparse.c: cfparse.y
bison --verbose -t -d -o cfparse.c --name-prefix=cf $(srcdir)/cfparse.y
main.o: main.c globals.h ../version.h
$(CC) $(CPPFLAGS) $(CFLAGS) -c -DIVL_ROOT='"@libdir@/ivl"' -DIVL_INC='"@includedir@"' -DIVL_LIB='"@libdir@"' -DDLLIB='"@DLLIB@"' $(srcdir)/main.c
main.o: main.c globals.h
$(CC) $(CPPFLAGS) $(CFLAGS) -c -DIVL_ROOT='"@libdir@/ivl$(suffix)"' -DIVL_INC='"@includedir@"' -DIVL_LIB='"@libdir@"' -DDLLIB='"@DLLIB@"' $(DEBUGFLAGS) $(srcdir)/main.c
build_string.o: build_string.c globals.h
cflexor.o: cflexor.c cfparse.h cfparse_misc.h globals.h
@@ -80,37 +82,38 @@ iverilog.ps: $(srcdir)/iverilog.man
iverilog.pdf: iverilog.ps
$(PS2PDF) iverilog.ps iverilog.pdf
ifeq (@MINGW32@,yes)
ifeq (@WIN32@,yes)
ifeq ($(MAN),none)
INSTALL_DOC = $(mandir)/man1/iverilog.1
INSTALL_DOC = $(mandir)/man1/iverilog$(suffix).1
else
ifeq ($(PS2PDF),none)
INSTALL_DOC = $(mandir)/man1/iverilog.1
INSTALL_DOC = $(mandir)/man1/iverilog$(suffix).1
else
INSTALL_DOC = $(prefix)/iverilog.pdf $(mandir)/man1/iverilog.1
INSTALL_DOC = $(prefix)/iverilog$(suffix).pdf $(mandir)/man1/iverilog$(suffix).1
all: iverilog.pdf
endif
endif
INSTALL_DOCDIR = $(mandir)/man1
else
INSTALL_DOC = $(mandir)/man1/iverilog.1
INSTALL_DOC = $(mandir)/man1/iverilog$(suffix).1
INSTALL_DOCDIR = $(mandir)/man1
endif
install: all installdirs $(bindir)/iverilog@EXEEXT@ $(INSTALL_DOC)
install: all installdirs $(bindir)/iverilog$(suffix)@EXEEXT@ $(INSTALL_DOC)
$(bindir)/iverilog@EXEEXT@: ./iverilog@EXEEXT@
$(INSTALL_PROGRAM) ./iverilog@EXEEXT@ $(bindir)/iverilog@EXEEXT@
$(DESTDIR)$(bindir)/iverilog$(suffix)@EXEEXT@: ./iverilog@EXEEXT@
$(INSTALL_PROGRAM) ./iverilog@EXEEXT@ $(DESTDIR)$(bindir)/iverilog$(suffix)@EXEEXT@
$(mandir)/man1/iverilog.1: $(srcdir)/iverilog.man
$(INSTALL_DATA) $(srcdir)/iverilog.man $(mandir)/man1/iverilog.1
$(DESTDIR)$(mandir)/man1/iverilog$(suffix).1: $(srcdir)/iverilog.man
$(INSTALL_DATA) $(srcdir)/iverilog.man $(DESTDIR)$(mandir)/man1/iverilog$(suffix).1
$(prefix)/iverilog.pdf: iverilog.pdf
$(INSTALL_DATA) iverilog.pdf $(prefix)/iverilog.pdf
$(DESTDIR)$(prefix)/iverilog$(suffix).pdf: iverilog.pdf
$(INSTALL_DATA) iverilog.pdf $(DESTDIR)$(prefix)/iverilog$(suffix).pdf
installdirs: ../mkinstalldirs
$(srcdir)/../mkinstalldirs $(bindir) $(INSTALL_DOCDIR)
$(srcdir)/../mkinstalldirs $(DESTDIR)$(bindir) $(DESTDIR)$(INSTALL_DOCDIR)
uninstall:
rm -f $(bindir)/iverilog@EXEEXT@
rm -f $(mandir)/man1/iverilog.1 $(prefix)/iverilog.pdf
rm -f $(DESTDIR)$(bindir)/iverilog$(suffix)@EXEEXT@
rm -f $(DESTDIR)$(mandir)/man1/iverilog$(suffix).1
rm -f $(DESTDIR)$(prefix)/iverilog$(suffix).pdf
+19 -120
View File
@@ -4,7 +4,7 @@
%{
/*
* Copyright (c) 2001 Stephen Williams ([email protected])
* Copyright (c) 2001-2010 Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -21,49 +21,40 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: cflexor.lex,v 1.11 2007/03/22 16:08:18 steve Exp $"
#endif
# include "cfparse.h"
# include "cfparse_misc.h"
# include "globals.h"
# include <string.h>
static int comment_enter;
static char* trim_trailing_white(char*txt, int trim);
/*
* Mostly copied from the flex manual. Do not make this arbitrary
* depth without checking for looping files.
* Lexical location information is passed in the yylloc variable to th
* parser. The file names, strings, are kept in a list so that I can
* re-use them. The set_file_name function will return a pointer to
* the name as it exists in the list (and delete the passed string.)
* If the name is new, it will be added to the list.
*/
#define MAX_CMDFILE_DEPTH 15
YYLTYPE yylloc;
typedef struct t_cmdfile {
char *cmdfile;
YY_BUFFER_STATE buffer;
} s_cmdfile;
s_cmdfile cmdfile_stack[MAX_CMDFILE_DEPTH];
int cmdfile_stack_ptr = 0;
static int comment_enter;
%}
%x CCOMMENT
%x LCOMMENT
%x PLUS_ARGS
%x FILE_NAME
%%
/* Accept C++ style comments. */
"//".* { comment_enter = YY_START; BEGIN(LCOMMENT); }
<LCOMMENT>. { yymore(); }
<LCOMMENT>\n { cflloc.first_line += 1; BEGIN(comment_enter); }
<LCOMMENT>\n { yylloc.first_line += 1; BEGIN(comment_enter); }
/* Accept C style comments. */
"/*" { comment_enter = YY_START; BEGIN(CCOMMENT); }
<CCOMMENT>. { yymore(); }
<CCOMMENT>\n { cflloc.first_line += 1; yymore(); }
<CCOMMENT>\n { yylloc.first_line += 1; yymore(); }
<CCOMMENT>"*/" { BEGIN(comment_enter); }
/* Accept shell type comments. */
@@ -72,7 +63,7 @@ int cmdfile_stack_ptr = 0;
/* Skip white space. */
[ \t\f\r] { ; }
/* Skip line ends, but also count the line. */
\n { cflloc.first_line += 1; }
\n { yylloc.first_line += 1; }
"+define+" { BEGIN(PLUS_ARGS); return TOK_DEFINE; }
@@ -85,7 +76,6 @@ int cmdfile_stack_ptr = 0;
"+libext+" { BEGIN(PLUS_ARGS); return TOK_LIBEXT; }
"+integer-width+" { BEGIN(PLUS_ARGS); return TOK_INTEGER_WIDTH; }
/* If it is not any known plus-flag, return the generic form. */
"+"[^\n \t\b\f\r+]* {
@@ -107,16 +97,12 @@ int cmdfile_stack_ptr = 0;
<PLUS_ARGS>[ \t\b\f\r] { BEGIN(0); }
<PLUS_ARGS>\n {
cflloc.first_line += 1;
yylloc.first_line += 1;
BEGIN(0); }
/* Notice the -a flag. */
"-a" { return TOK_Da; }
/* Notice the -c or -f flag. */
"-c" { return TOK_Dc; }
"-f" { return TOK_Dc; }
/* Notice the -v flag. */
"-v" { return TOK_Dv; }
@@ -126,113 +112,26 @@ int cmdfile_stack_ptr = 0;
/* This rule matches paths and strings that may be file names. This
is a little bit tricky, as we don't want to mistake a comment for
a string word. */
"/"[\r\n] { /* Special case of file name "/" */
cflval.text = trim_trailing_white(yytext, 0);
return TOK_STRING; }
"/"[^\*\/] { /* A file name that starts with "/". */
yymore();
BEGIN(FILE_NAME); }
[^/\n \t\b\r+-][^/\n\r]* { /* A file name that starts with other than "/" */
yymore();
BEGIN(FILE_NAME); }
"/"[^\*\/].* { cflval.text = strdup(yytext);
return TOK_STRING; }
[^/\n \t\b\r+-].* { cflval.text = strdup(yytext);
return TOK_STRING; }
<FILE_NAME>"//" {
/* Found a trailing comment. Returning the terminated name. */
cflval.text = trim_trailing_white(yytext, 2);
BEGIN(LCOMMENT);
return TOK_STRING; }
<FILE_NAME>"/"?[^/\n\r]* {
yymore();
/* not a comment... continuing */; }
<FILE_NAME>[\n\r] {
/* No trailing comment. Return the file name. */
cflval.text = trim_trailing_white(yytext, 0);
BEGIN(0);
return TOK_STRING; }
/* Fallback match. */
. { return yytext[0]; }
/* At the end of file switch back to the previous buffer. */
<<EOF>> {
if (--cmdfile_stack_ptr < 0) {
free(current_file);
yyterminate();
} else {
yy_delete_buffer(YY_CURRENT_BUFFER);
yy_switch_to_buffer(cmdfile_stack[cmdfile_stack_ptr].buffer);
free(current_file);
current_file = cmdfile_stack[cmdfile_stack_ptr].cmdfile;
} }
%%
static char* trim_trailing_white(char*text, int trim)
{
char*cp = text + strlen(text);
while (cp > text && trim > 0) {
trim -= 1;
cp -= 1;
*cp = 0;
}
while (cp > text && strchr("\n\r\t\b", cp[-1]))
cp -= 1;
cp[0] = 0;
return strdup(text);
}
int yywrap()
{
return 1;
}
void switch_to_command_file(const char *file)
{
char path[4096];
char *cp;
if (cmdfile_stack_ptr >= MAX_CMDFILE_DEPTH) {
fprintf(stderr, "Error: command files nested too deeply (%d) "
"at %s:%d.\n", MAX_CMDFILE_DEPTH, current_file,
cflloc.first_line);
exit(1);
}
cmdfile_stack[cmdfile_stack_ptr].buffer = YY_CURRENT_BUFFER;
cmdfile_stack[cmdfile_stack_ptr].cmdfile = current_file;
cmdfile_stack_ptr += 1;
/*
* If this is a relative file then add the current path to the
* file name.
*/
if (file[0] != '/') {
strcpy(path, current_file);
cp = strrchr(path, '/');
if (cp == 0) strcpy(path, file); /* A base file. */
else {
*(cp+1) = '\0';
strcat(path, file);
}
} else strcpy(path, file); /* An absolute path. */
yyin = fopen(path, "r");
if (yyin == NULL) {
fprintf(stderr, "Error: unable to read nested command file (%s) "
"at %s:%d.\n", path, current_file, cflloc.first_line);
exit(1);
}
current_file = strdup(path);
yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
cflloc.first_line = 1;
}
void cfreset(FILE*fd, const char*path)
{
yyin = fd;
yyrestart(fd);
current_file = strdup(path);
cflloc.first_line = 1;
yylloc.first_line = 1;
yylloc.text = (char*)path;
}
+6 -34
View File
@@ -1,6 +1,6 @@
%{
/*
* Copyright (c) 20001 Stephen Williams ([email protected])
* Copyright (c) 2001-2010 Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -17,10 +17,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: cfparse.y,v 1.12 2007/04/19 02:52:53 steve Exp $"
#endif
# include "globals.h"
# include "cfparse_misc.h"
@@ -60,9 +56,8 @@ static void translate_file_name(char*text)
char*text;
};
%token TOK_Da TOK_Dc TOK_Dv TOK_Dy
%token TOK_Da TOK_Dv TOK_Dy
%token TOK_DEFINE TOK_INCDIR TOK_LIBDIR TOK_LIBDIR_NOCASE TOK_LIBEXT
%token TOK_INTEGER_WIDTH
%token <text> TOK_PLUSARG TOK_PLUSWORD TOK_STRING
%%
@@ -84,7 +79,7 @@ item
: TOK_STRING
{ char*tmp = substitutions($1);
translate_file_name(tmp);
process_file_name(tmp, 0);
process_file_name(tmp);
free($1);
free(tmp);
}
@@ -93,23 +88,15 @@ item
| TOK_Da { }
/* Match a -c <cmdfile> or -f <cmdfile> */
| TOK_Dc TOK_STRING
{ char*tmp = substitutions($2);
translate_file_name(tmp);
switch_to_command_file(tmp);
free($2);
free(tmp);
}
/* The -v <libfile> flag is ignored, and the <libfile> is processed
as an ordinary source file. */
| TOK_Dv TOK_STRING
{ char*tmp = substitutions($2);
translate_file_name(tmp);
process_file_name(tmp, 1);
process_file_name(tmp);
fprintf(stderr, "%s:%u: Ignoring -v in front of %s\n",
@1.text, @1.first_line, $2);
free($2);
free(tmp);
}
@@ -154,15 +141,6 @@ item
| TOK_LIBEXT libext_args
/* These are various misc flags that are supported. */
| TOK_INTEGER_WIDTH TOK_PLUSARG
{ char*tmp = substitutions($2);
free($2);
integer_width = strtoul(tmp,0,10);
free(tmp);
}
/* The +<word> tokens that are not otherwise matched, are
ignored. The skip_args rule arranges for all the argument words
to be consumed. */
@@ -183,12 +161,6 @@ item
}
free($1);
}
| error
{ fprintf(stderr, "Error: unable to parse line %d in "
"%s.\n", cflloc.first_line, current_file);
return 1;
}
;
/* inc_args are +incdir+ arguments in order. */
+2 -3
View File
@@ -1,7 +1,7 @@
#ifndef __cfparse_misc_H
#define __cfparse_misc_H
/*
* Copyright (c) 2001 Picture Elements, Inc.
* Copyright (c) 2001-2010 Picture Elements, Inc.
* Stephen Williams (steve@picturel.com)
*
* This source code is free software; you can redistribute it
@@ -33,11 +33,10 @@ struct cfltype {
const char*text;
};
# define YYLTYPE struct cfltype
extern YYLTYPE yylloc;
int cflex(void);
int cferror(const char *);
int cfparse(void);
void switch_to_command_file(const char *);
char *current_file;
#endif
+2 -40
View File
@@ -1,7 +1,7 @@
#ifndef __globals_H
#define __globals_H
/*
* Copyright (c) 2000 Stephen Williams (steve@icarus.com)
* Copyright (c) 2000-2010 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -18,9 +18,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: globals.h,v 1.21 2007/04/19 02:52:53 steve Exp $"
#endif
# include <stddef.h>
@@ -49,14 +46,11 @@ extern int synth_flag;
/* This is the name of the selected target. */
extern const char*targ;
/* This is the integer-width argument that will be passed to ivl. */
extern unsigned integer_width;
/* Perform variable substitutions on the string. */
extern char* substitutions(const char*str);
/* Add the name to the list of source files. */
extern void process_file_name(const char*name, int lib_flag);
extern void process_file_name(const char*name);
/* Add the name to the list of library directories. */
extern void process_library_switch(const char*name);
@@ -78,36 +72,4 @@ extern char warning_flags[];
extern char* library_flags;
extern char* library_flags2;
/*
* $Log: globals.h,v $
* Revision 1.21 2007/04/19 02:52:53 steve
* Add support for -v flag in command file.
*
* Revision 1.20 2007/03/07 04:24:59 steve
* Make integer width controllable.
*
* Revision 1.19 2003/11/18 06:31:46 steve
* Remove the iverilog.conf file.
*
* Revision 1.18 2003/11/13 04:09:49 steve
* Pass flags through the temporary config file.
*
* Revision 1.17 2003/11/01 04:21:57 steve
* Add support for a target static config file.
*
* Revision 1.16 2002/08/12 01:35:01 steve
* conditional ident string using autoconfig.
*
* Revision 1.15 2002/06/23 20:10:51 steve
* Variable substitution in command files.
*
* Revision 1.14 2002/05/28 20:40:37 steve
* ivl indexes the search path for libraries, and
* supports case insensitive module-to-file lookup.
*
* Revision 1.13 2002/05/28 00:50:40 steve
* Add the ivl -C flag for bulk configuration
* from the driver, and use that to run library
* modules through the preprocessor.
*/
#endif
+17 -94
View File
@@ -1,11 +1,10 @@
.TH iverilog 1 "April 22nd, 2008" Version "0.9.devel"
.TH iverilog 1 "$Date: 2006/06/12 00:16:53 $" Version "$Date: 2006/06/12 00:16:53 $"
.SH NAME
iverilog - Icarus Verilog compiler
.SH SYNOPSIS
.B iverilog
[-ESVv] [-Bpath] [-ccmdfile|-fcmdfile] [-Dmacro[=defn]] [-pflag=value]
[-dname] [-g1995|-g2001|-g2005|-g<feature>]
[-ESVv] [-Bpath] [-ccmdfile] [-g1|-g2|-g3.0] [-Dmacro[=defn]] [-pflag=value]
[-Iincludedir] [-mmodule] [-Mfile] [-Nfile] [-ooutputfilename]
[-stopmodule] [-ttype] [-Tmin/typ/max] [-Wclass] [-ypath] sourcefile
@@ -29,8 +28,8 @@ program. However, the \fB-B\fP switch allows the user to select a
different set of programs. The path given is used to locate
\fIivlpp\fP, \fIivl\fP, code generators and the VPI modules.
.TP 8
.B -c\fIfile\fP -f\fIfile\fP
These flags specifies an input file that contains a list of Verilog
.B -c\fIfile\fP
This flag specifies an input file that contains a list of Verilog
source files. This is similar to the \fIcommand file\fP of other
Verilog simulators, in that it is a file that contains the file names
instead of taking them on the command line. See \fBCommand Files\fP below.
@@ -43,60 +42,21 @@ Verilog source.
.B -D\fImacro=defn\fP
Defines macro \fImacro\fP as \fIdefn\fP.
.TP 8
.B -d\fIname\fP
Activate a class of compiler debugging messages. The \fB-d\fP switch may
be used as often as necessary to activate all the desired messages.
Supported names are scopes, eval_tree, elaborate, and synth2;
any other names are ignored.
.TP 8
.B -E
Preprocess the Verilog source, but do not compile it. The output file
is the Verilog input, but with file inclusions and macro references
expanded and removed. This is useful, for example, to preprocess
Verilog source for use by other compilers.
.TP 8
.B -g1995\fI|\fP-g2001\fI|\fP-g2005
.B -g1\fI|\fP-g2\fI|\fP-g3.0
Select the Verilog language \fIgeneration\fP to support in the
compiler. This selects between \fIIEEE1364-1995\fP,
\fIIEEE1364-2001\fP(2), or \fIIEEE1364-2005\fP. Normally,
compiler. This selects between \fIIEEE1364-1995\fP(1),
\fIIEEE1364-2001\fP(2), or \fISystemVerilog 3.0\fP(3.0). Normally,
Icarus Verilog defaults to the latest known generation of the
language. This flag is most useful to restrict the language to a set
supported by tools of specific generations, for compatibility with
other tools.
.TP 8
.B -gverilog-ams\fI|-fP-gno-verilog-ams
Enable or disable (default) support for Verilog-AMS.
.TP 8
.B -gspecify\fI|\fP-gno-specify
Enable (default) or disable specify block support. When enabled,
specify block code is elaborated. When disabled, specify blocks are
parsed but ignored. Specify blocks are commonly not needed for RTL
simulation, and in fact can hurt performance of the
simulation. However, disabling specify blocks reduces accuracy of
full-timing simulations.
.TP 8
.B -gstd-include\fI|\fP-gno-std-include
Enable (default) or disable the search of a standard installation
include directory after all other explicit include directories. This
standard include directory is a convenient place to install standard
header files that a Verilog program may include.
.TP 8
.B -gxtypes\fI|\fP-gno-xtypes
Enable (default) or disable support for extended types. Enabling
extended types allows for new types that are supported by Icarus
Verilog as extensions beyond the baseline Verilog. It may be necessary
to disable extended types if compiling code that clashes with the few
new keywords used to implement the type system.
.TP 8
.B -gio-range-error\fI|\fP-gno-io-range-error
The standards requires that a vectored port have matching ranges for its
port declaration as well as any net/register declaration. It was common
practice in the past to only specify the range for the net/register
declaration and some tools still allow this. By default any mismatch is
reported as a error. Using \fI-gno-io-range-error\fP will produce a
warning instead of a fatal error for the case of a vectored net/register
and a scalar port declaration.
.TP 8
.B -I\fIincludedir\fP
Append directory \fIincludedir\fP to list of directories searched
for Verilog include files. The \fB-I\fP switch may be used many times
@@ -114,8 +74,6 @@ leading or trailing space.
Add this module to the list of VPI modules to be loaded by the
simulation. Many modules can be specified, and all will be loaded, in
the order specified. The system module is implicit and always included.
If a System Function Table file (<module>.sft) exists for the module it
will be loaded automatically.
.TP 8
.B -N\fIpath\fP
This is used for debugging the compiler proper. Dump the final netlist
@@ -150,9 +108,9 @@ they will be used as root modules instead.
.B -T\fImin|typ|max\fP
Use this switch to select min, typ or max times from min:typ:max
expressions. Normally, the compiler will simply use the typ value from
these expressions (printing a warning for the first ten it finds) but
this switch will tell the compiler explicitly which value to use. This
will suppress the warning that the compiler is making a choice.
these expressions (with a warning) but this switch will tell the
compiler explicitly which value to use. This will suppress the
warning that the compiler is making a choice.
.TP 8
.B -t\fItarget\fP
Use this switch to specify the target output format. See the
@@ -255,19 +213,10 @@ timescales are inconsistent, and simulation timing can be confusing
and dependent on compilation order.
.TP 8
.B infloop
This enables warnings for \fRalways\fP statements that may have runtime
infinite loops (has paths with no or zero delay). This class of warnings
is not included in \fB-Wall\fP and hence does not have a \fBno-\fP variant.
A fatal error message will always be printed when the compiler can
determine that there will definitely be an infinite loop (all paths have
no or zero delay).
When you suspect an always statement is producing a runtime infinite loop
use this flag to find the always statements that need to have their logic
verified. It is expected that many of the warnings will be false
positives, since the code treats the value of all variables and signals
as indeterminate.
.B unused
This enables warnings for unused variables. This may detect variables
that are not assigned, or variables and nets that are not used, or
similar possible misuses of variables and nets.
.SH "SYSTEM FUNCTION TABLE FILES"
If the source file name as a \fB.sft\fP suffix, then it is taken to be
@@ -306,13 +255,7 @@ well as # comments, if the # starts the line.
.I "file name"
A simple file name or file path is taken to be the name of a Verilog
source file. The path starts with the first non-white-space
character. Variables are substituted in file names.
.TP 8
.B -c\ \fIcmdfile\fP -f\ \fIcmdfile\fP
A \fB-c\fP or \fB-f\fP token prefixes a command file, exactly like it
does on the command line. The cmdfile may be on the same line or the
next non-comment line.
character. Variables are substitued in file names.
.TP 8
.B -y\ \fIlibdir\fP
@@ -367,35 +310,18 @@ become munged.
.B +tolower-filename\fP
This is similar to the \fB+toupper-filename\fP hack described above.
.TP 8
.B +integer-width+\fIvalue\fP
This allows the programmer to select the width for integer variables
in the Verilog source. The default is 32, the value can be any desired
integer value.
.SH "VARIABLES IN COMMAND FILES"
In certain cases, iverilog supports variables in command files. These
are strings of the form "$(\fIvarname\fP)", where \fIvarname\fP is the
name of the environment variable to read. The entire string is
replaced with the contents of that variable. Variables are only
substituted in contexts that explicitly support them, including file
substitued in contexts that explicitly support them, including file
and directory strings.
Variable values come from the operating system environment, and not
from preprocessor defines elsewhere in the file or the command line.
.SH PREDEFINED MACROS
The following macros are predefined by the compiler:
.TP 8
.B __ICARUS__ = 1\fP
This is defined always when compiling with Icarus Verilog.
.TP 8
.B __VAMS_ENABLE__ = 1\fp
This is defined if Verilog-AMS is enabled.
.SH EXAMPLES
These examples assume that you have a Verilog source file called hello.v in
the current directory
@@ -425,12 +351,9 @@ Steve Williams ([email protected])
vvp(1),
.BR "<http://www.icarus.com/eda/verilog/>"
Tips on using, debugging, and developing the compiler can be found at
.BR "<http://iverilog.wikia.com/>"
.SH COPYRIGHT
.nf
Copyright \(co 2002-2008 Stephen Williams
Copyright \(co 2002 Stephen Williams
This document can be freely redistributed according to the terms of the
GNU General Public License version 2.0
+202 -270
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2000-2008 Stephen Williams (steve@icarus.com)
* Copyright (c) 2000-2010 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -37,13 +37,12 @@ const char NOTICE[] =
;
const char HELP[] =
"Usage: iverilog [-ESvV] [-B base] [-c cmdfile|-f cmdfile] [-g1|-g2|-g2x]\n"
"Usage: iverilog [-EhSvV] [-B base] [-c cmdfile] [-g1|-g2|-g3.0]\n"
" [-D macro[=defn]] [-I includedir] [-M depfile] [-m module]\n"
" [-N file] [-o filename] [-p flag=value]\n"
" [-s topmodule] [-t target] [-T min|typ|max]\n"
" [-W class] [-y dir] [-Y suf] source_file(s)\n"
"\n"
"See the man page for details.";
"See man page for details.";
#define MAXSIZE 4096
@@ -87,6 +86,10 @@ extern const char*optarg;
# define IVL_ROOT "."
#endif
#ifndef IVL_ROOT_VARIABLE
# define IVL_ROOT_VARIABLE "IVERILOG_ROOT"
#endif
# include "globals.h"
#include "cfparse_misc.h" /* cfparse() */
@@ -106,20 +109,12 @@ const char*npath = 0;
const char*targ = "vvp";
const char*depfile = 0;
const char*generation = "2x";
const char*gen_specify = "specify";
const char*gen_xtypes = "xtypes";
const char*gen_icarus = "icarus-misc";
const char*gen_io_range_error = "io-range-error";
const char*gen_verilog_ams = "no-verilog-ams";
/* Boolean: true means use a default include dir, false means don't */
int gen_std_include = 1;
const char*generation = "3.0";
char warning_flags[16] = "";
unsigned integer_width = 32;
char*inc_list = 0;
char*def_list = 0;
char*mod_list = 0;
char*command_filename = 0;
@@ -130,19 +125,15 @@ char*source_path = 0;
FILE*source_file = 0;
unsigned source_count = 0;
char*defines_path = 0;
FILE*defines_file = 0;
char*iconfig_path = 0;
FILE*iconfig_file = 0;
char*compiled_defines_path = 0;
static char iconfig_common_path_buf[4096] = "";
char*iconfig_common_path = iconfig_common_path_buf;
int synth_flag = 0;
int verbose_flag = 0;
int command_file = 0;
FILE *fp;
@@ -151,48 +142,6 @@ char tmp[MAXSIZE];
static char ivl_root[MAXSIZE];
/* Structure to keep a FIFO list of the command files */
typedef struct t_command_file {
char *filename;
struct t_command_file *next;
} s_command_file, *p_command_file;
p_command_file cmd_file_head = NULL; /* The FIFO head */
p_command_file cmd_file_tail = NULL; /* The FIFO tail */
/* Function to add a command file name to the FIFO. */
void add_cmd_file(const char* filename)
{
p_command_file new;
new = (p_command_file) malloc(sizeof(s_command_file));
new->filename = strdup(filename);
new->next = NULL;
if (cmd_file_head == NULL) {
cmd_file_head = new;
cmd_file_tail = new;
} else {
cmd_file_tail->next = new;
cmd_file_tail = new;
}
}
/* Function to return the top command file name from the FIFO. */
char *get_cmd_file()
{
char *filename;
if (cmd_file_head == NULL) filename = NULL;
else {
p_command_file head;
filename = cmd_file_head->filename;
head = cmd_file_head;
cmd_file_head = cmd_file_head->next;
free(head);
}
return filename;
}
#ifdef __MINGW32__
# include <io.h>
# include <fcntl.h>
@@ -205,7 +154,7 @@ static FILE*fopen_safe(const char*path)
if (fd != -1)
file = _fdopen(fd, "w");
return file;
return file;
}
#else
# include <fcntl.h>
@@ -218,7 +167,7 @@ static FILE*fopen_safe(const char*path)
if (fd != -1)
file = fdopen(fd, "w");
return file;
return file;
}
#endif
@@ -315,22 +264,77 @@ static int t_default(char*cmd, unsigned ncmd)
}
#endif
#ifdef DEBUG
char *original_cmd = malloc( strlen( cmd ) + (size_t)1 );
strcpy( original_cmd, cmd );
if (verbose_flag)
cmd = realloc( cmd, strlen( original_cmd ) + (size_t)19 ); /* more than enough memory for the ivlpp command and ">/tmp/ivlpp_stdout" */
if( cmd == NULL ){
exit( EXIT_FAILURE );
}
char *debug_ivl = malloc( strlen( original_cmd ) + (size_t)5 ); /* more than enough memory for "gdb " and ivl program_name */
strcpy( debug_ivl, "gdb " );
static char whitespace[] = " \t\f\r\v\n";
char *token;
int found_pipe = 0;
unsigned long token_counter = 0UL;
strcpy( cmd, "" );
for( token = strtok( original_cmd, whitespace ); token != NULL; token = strtok( NULL, whitespace ) ){
if( strcmp( token, "|" ) == 0 ){
found_pipe = 1;
}
if( found_pipe ){
token_counter++;
}
if( token_counter == 0UL ){
strcat( cmd, token );
strcat( cmd, " " ); /* harmless space after last token, and it was already there anyway */
}
if( token_counter == 2UL ){
strcat( debug_ivl, token );
}
if( token_counter > 2UL ){
printf( "%s\n", token );
}
}
free( original_cmd );
#ifdef __MINGW32__
strcat( cmd, ">%TMP%\\ivlpp_stdout" );
#else
strcat( cmd, ">/tmp/ivlpp_stdout" );
#endif
#endif
if (verbose_flag) {
printf("translate: %s\n", cmd);
fflush(stdout);
}
rc = system(cmd);
if ( ! getenv("IVERILOG_ICONFIG")) {
remove(source_path);
remove(iconfig_path);
remove(defines_path);
remove(compiled_defines_path);
#ifdef DEBUG
if( verbose_flag ){
printf( "%s\n", debug_ivl );
}
system( debug_ivl ); /* For simplicity, ignore any return value, which is implementation dependent anyway. */
free( debug_ivl );
#endif
remove(source_path);
if ( ! getenv("IVERILOG_ICONFIG"))
remove(iconfig_path);
#ifdef __MINGW32__ /* MinGW just returns the exit status, so return it! */
return rc;
#else
if (rc != 0) {
if (rc == 127) {
fprintf(stderr, "Failed to execute: %s\n", cmd);
@@ -352,37 +356,40 @@ static int t_default(char*cmd, unsigned ncmd)
static void process_warning_switch(const char*name)
{
if (strcmp(name,"all") == 0) {
process_warning_switch("implicit");
process_warning_switch("portbind");
process_warning_switch("timescale");
strcat(warning_flags, "iptu");
} else if (strcmp(name,"implicit") == 0) {
if (! strchr(warning_flags, 'i'))
if (! strchr(warning_flags+2, 'i'))
strcat(warning_flags, "i");
} else if (strcmp(name,"portbind") == 0) {
if (! strchr(warning_flags, 'p'))
if (! strchr(warning_flags+2, 'p'))
strcat(warning_flags, "p");
} else if (strcmp(name,"timescale") == 0) {
if (! strchr(warning_flags, 't'))
if (! strchr(warning_flags+2, 't'))
strcat(warning_flags, "t");
/* Since the infinite loop check is not part of 'all' it
* does not have a no- version. */
} else if (strcmp(name,"infloop") == 0) {
if (! strchr(warning_flags, 'l'))
strcat(warning_flags, "l");
} else if (strcmp(name,"unused") == 0) {
if (! strchr(warning_flags+2, 'u'))
strcat(warning_flags, "u");
} else if (strcmp(name,"no-implicit") == 0) {
char*cp = strchr(warning_flags, 'i');
char*cp = strchr(warning_flags+2, 'i');
if (cp) while (*cp) {
cp[0] = cp[1];
cp += 1;
}
} else if (strcmp(name,"no-portbind") == 0) {
char*cp = strchr(warning_flags, 'p');
char*cp = strchr(warning_flags+2, 'p');
if (cp) while (*cp) {
cp[0] = cp[1];
cp += 1;
}
} else if (strcmp(name,"no-timescale") == 0) {
char*cp = strchr(warning_flags, 't');
char*cp = strchr(warning_flags+2, 't');
if (cp) while (*cp) {
cp[0] = cp[1];
cp += 1;
}
} else if (strcmp(name,"no-unused") == 0) {
char*cp = strchr(warning_flags+2, 'u');
if (cp) while (*cp) {
cp[0] = cp[1];
cp += 1;
@@ -407,12 +414,32 @@ void process_library2_switch(const char *name)
void process_include_dir(const char *name)
{
fprintf(defines_file, "I:%s\n", name);
if (inc_list == 0) {
inc_list = malloc(strlen(" -I")+strlen(name)+1);
strcpy(inc_list, " -I");
strcat(inc_list, name);
} else {
inc_list = realloc(inc_list, strlen(inc_list)
+ strlen(" -I")
+ strlen(name) + 1);
strcat(inc_list, " -I");
strcat(inc_list, name);
}
}
void process_define(const char*name)
{
fprintf(defines_file,"D:%s\n", name);
if (def_list == 0) {
def_list = malloc(strlen(" -D")+strlen(name)+1);
strcpy(def_list, " -D");
strcat(def_list, name);
} else {
def_list = realloc(def_list, strlen(def_list)
+ strlen(" -D")
+ strlen(name) + 1);
strcat(def_list, " -D");
strcat(def_list, name);
}
}
/*
@@ -421,7 +448,7 @@ void process_define(const char*name)
* .sft suffix, and if so pass that as a sys_func file. Otherwise, it
* is a Verilog source file to be written into the file list.
*/
void process_file_name(const char*name, int lib_flag)
void process_file_name(const char*name)
{
if (strlen(name) > 4 && strcasecmp(".sft", name+strlen(name)-4) == 0) {
fprintf(iconfig_file,"sys_func:%s\n", name);
@@ -429,87 +456,27 @@ void process_file_name(const char*name, int lib_flag)
} else {
fprintf(source_file, "%s\n", name);
source_count += 1;
if (lib_flag)
fprintf(iconfig_file,"library_file:%s\n", name);
}
}
int process_generation(const char*name)
{
if (strcmp(name,"1995") == 0)
generation = "1995";
if (strcmp(name,"1") == 0)
generation = "1";
else if (strcmp(name,"2001") == 0)
generation = "2001";
else if (strcmp(name,"2") == 0)
generation = "2";
else if (strcmp(name,"2005") == 0)
generation = "2005";
else if (strcmp(name,"1") == 0) { /* Deprecated: use 1995 */
generation = "1995";
gen_xtypes = "no-xtypes";
gen_icarus = "no-icarus-misc";
} else if (strcmp(name,"2") == 0) { /* Deprecated: use 2001 */
generation = "2001";
gen_xtypes = "no-xtypes";
gen_icarus = "no-icarus-misc";
} else if (strcmp(name,"2x") == 0) { /* Deprecated: use 2005/xtypes */
generation = "2005";
gen_xtypes = "xtypes";
gen_icarus = "icarus-misc";
} else if (strcmp(name,"xtypes") == 0)
gen_xtypes = "xtypes";
else if (strcmp(name,"no-xtypes") == 0)
gen_xtypes = "no-xtypes";
else if (strcmp(name,"icarus-misc") == 0)
gen_icarus = "icarus-misc";
else if (strcmp(name,"no-icarus-misc") == 0)
gen_icarus = "no-icarus-misc";
else if (strcmp(name,"specify") == 0)
gen_specify = "specify";
else if (strcmp(name,"no-specify") == 0)
gen_specify = "no-specify";
else if (strcmp(name,"std-include") == 0)
gen_std_include = 1;
else if (strcmp(name,"no-std-include") == 0)
gen_std_include = 0;
else if (strcmp(name,"io-range-error") == 0)
gen_io_range_error = "io-range-error";
else if (strcmp(name,"no-io-range-error") == 0)
gen_io_range_error = "no-io-range-error";
else if (strcmp(name,"verilog-ams") == 0)
gen_verilog_ams = "verilog-ams";
else if (strcmp(name,"no-verilog-ams") == 0)
gen_verilog_ams = "no-verilog-ams";
else if (strcmp(name,"3.0") == 0)
generation = "3.0";
else {
fprintf(stderr, "Unknown/Unsupported Language generation "
"%s\n\n", name);
"%s\n", name);
fprintf(stderr, "Supported generations are:\n");
fprintf(stderr, " 1995 -- IEEE1364-1995\n"
" 2001 -- IEEE1364-2001\n"
" 2005 -- IEEE1364-2005\n"
"Other generation flags:\n"
" specify | no-specify\n"
" verilog-ams | no-verinlog-ams\n"
" std-include | no-std-include\n"
" xtypes | no-xtypes\n"
" icarus-misc | no-icarus-misc\n"
" io-range-error | no-io-range-error\n");
fprintf(stderr, " 1 -- IEEE1364-1995 (Verilog 1)\n"
" 2 -- IEEE1364-2001 (Verilog 2001)\n"
" 3.0 -- SystemVerilog 3.0\n");
return 1;
}
@@ -517,27 +484,12 @@ int process_generation(const char*name)
}
/*
* If it exists add the SFT file for the given module.
* This function fills in th ivl_root directory with the appropriate
* path, based on operating system, build time configuration, and
* environment.
*/
void add_sft_file(const char *module)
static char* get_root_dir()
{
char *file;
file = (char *) malloc(strlen(base)+1+strlen(module)+4+1);
sprintf(file, "%s%c%s.sft", base, sep, module);
if (access(file, R_OK) == 0)
fprintf(iconfig_file, "sys_func:%s\n", file);
free(file);
}
int main(int argc, char **argv)
{
char*cmd;
unsigned ncmd;
int e_flag = 0;
int version_flag = 0;
int opt, idx, rc;
#ifdef __MINGW32__
{ char * s;
char basepath[1024];
@@ -564,18 +516,37 @@ int main(int argc, char **argv)
s = strrchr(ivl_root, sep);
if (s) *s = 0;
strcat(ivl_root, "\\lib\\ivl");
base = ivl_root;
}
#else
/* In a UNIX environment, the IVL_ROOT from the Makefile is
dependable. It points to the $prefix/lib/ivl directory,
where the sub-parts are installed. */
strcpy(ivl_root, IVL_ROOT);
base = ivl_root;
{ char*var = 0;
/* In other systems, use the configured root. */
strcpy(ivl_root, IVL_ROOT);
/* In any case, the IVL_ROOT variable can be used to override
the install location at run time. If it is set, use that
value instead. */
if ( (var = getenv(IVL_ROOT_VARIABLE)) ) {
strncpy(ivl_root, var, MAXSIZE);
strcat(ivl_root, "/lib/ivl");
}
}
#endif
return ivl_root;
}
int main(int argc, char **argv)
{
char*cmd;
unsigned ncmd;
int e_flag = 0;
int version_flag = 0;
int opt, idx, rc;
base = get_root_dir();
/* Create a temporary file for communicating input parameters
to the preprocessor. */
source_path = strdup(my_tempfile("ivrlg", &source_file));
@@ -586,21 +557,6 @@ int main(int argc, char **argv)
return 1;
}
defines_path = strdup(my_tempfile("ivrlg2", &defines_file));
if (NULL == defines_file) {
fprintf(stderr, "%s: Error opening temporary file %s\n",
argv[0], defines_path);
fprintf(stderr, "%s: Please check TMP or TMPDIR.\n", argv[0]);
fclose(source_file);
remove(source_path);
return 1;
}
fprintf(defines_file, "D:__ICARUS__=1\n");
if (strcmp(gen_verilog_ams,"verilog-ams") == 0)
fprintf(defines_file, "D:__VAMS_ENABLE__=1\n");
/* Create another temporary file for passing configuration
information to ivl. */
@@ -621,22 +577,10 @@ int main(int argc, char **argv)
fprintf(stderr, "%s: Please check TMP or TMPDIR.\n", argv[0]);
fclose(source_file);
remove(source_path);
fclose(defines_file);
remove(defines_path);
return 1;
}
/* Create a temporary file (I only really need the path) that
can carry preprocessor precompiled defines to the library. */
{ FILE*tmp_file = 0;
compiled_defines_path = strdup(my_tempfile("ivrli", &tmp_file));
if (tmp_file) {
fclose(tmp_file);
}
}
while ((opt = getopt(argc, argv, "B:c:D:d:Ef:g:hI:M:m:N::o:p:Ss:T:t:vVW:y:Y:")) != EOF) {
while ((opt = getopt(argc, argv, "B:c:D:Ef:g:hI:M:m:N::o:p:Ss:T:t:vVW:y:Y:")) != EOF) {
switch (opt) {
case 'B':
@@ -651,30 +595,29 @@ int main(int argc, char **argv)
}
break;
case 'c':
case 'f':
add_cmd_file(optarg);
break;
command_filename = malloc(strlen(optarg)+1);
strcpy(command_filename, optarg);
break;
case 'D':
process_define(optarg);
break;
case 'E':
e_flag = 1;
break;
case 'f':
fprintf(stderr, "warning: The -f flag is moved to -p\n");
case 'p':
fprintf(iconfig_file, "flag:%s\n", optarg);
break;
case 'd':
fprintf(iconfig_file, "debug:%s\n", optarg);
break;
case 'g':
rc = process_generation(optarg);
if (rc != 0)
return -1;
break;
case 'h':
fprintf(stderr, "%s\n", HELP);
return 1;
case 'h':
fprintf(stderr, "%s\n", HELP);
return 1;
case 'I':
process_include_dir(optarg);
@@ -686,7 +629,6 @@ int main(int argc, char **argv)
case 'm':
fprintf(iconfig_file, "module:%s\n", optarg);
add_sft_file(optarg);
break;
case 'N':
@@ -744,8 +686,8 @@ int main(int argc, char **argv)
pbase = base;
if (version_flag || verbose_flag) {
printf("Icarus Verilog version " VERSION " (" VERSION_TAG ")\n\n");
printf("Copyright 1998-2008 Stephen Williams\n");
printf("Icarus Verilog version " VERSION "\n\n");
printf("Copyright 1998-2010 Stephen Williams\n");
puts(NOTICE);
if (version_flag)
@@ -764,82 +706,75 @@ int main(int argc, char **argv)
how to handle them. */
fprintf(iconfig_file, "sys_func:%s%csystem.sft\n", base, sep);
/* If verilog-ams is enabled, then include the va_math module
as well. */
if (strcmp(gen_verilog_ams,"verilog-ams") == 0) {
fprintf(iconfig_file, "sys_func:%s%cva_math.sft\n", base, sep);
fprintf(iconfig_file, "module:va_math\n");
}
if (mtm != 0) fprintf(iconfig_file, "-T:%s\n", mtm);
fprintf(iconfig_file, "generation:%s\n", generation);
fprintf(iconfig_file, "generation:%s\n", gen_specify);
fprintf(iconfig_file, "generation:%s\n", gen_xtypes);
fprintf(iconfig_file, "generation:%s\n", gen_io_range_error);
fprintf(iconfig_file, "generation:%s\n", gen_verilog_ams);
fprintf(iconfig_file, "generation:%s\n", gen_icarus);
fprintf(iconfig_file, "warnings:%s\n", warning_flags);
fprintf(iconfig_file, "out:%s\n", opath);
if (depfile) fprintf(iconfig_file, "depfile:%s\n", depfile);
while ( (command_filename = get_cmd_file()) ) {
if (command_filename) {
int rc;
if (( fp = fopen(command_filename, "r")) == NULL ) {
fprintf(stderr, "%s: cannot open command file %s "
"for reading.\n", argv[0], command_filename);
fprintf(stderr, "%s: Can't open %s\n",
argv[0], command_filename);
return 1;
}
cfreset(fp, command_filename);
rc = cfparse();
if (rc != 0) {
fprintf(stderr, "%s: parsing failed in base command "
"file %s.\n", argv[0], command_filename);
fprintf(stderr, "%s: error reading command file\n",
command_filename);
return 1;
}
free(command_filename);
}
if (depfile) {
fprintf(defines_file, "M:%s\n", depfile);
}
/* Finally, process all the remaining words on the command
line as file names. */
for (idx = optind ; idx < argc ; idx += 1)
process_file_name(argv[idx], 0);
process_file_name(argv[idx]);
/* If the use of a default include directory is not
specifically disabled, then write that directory as the
very last include directory to use... always. */
if (gen_std_include) {
fprintf(defines_file, "I:%s%cinclude", base, sep);
}
fclose(source_file);
source_file = 0;
fclose(defines_file);
defines_file = 0;
if (source_count == 0) {
fprintf(stderr, "%s: no source files.\n\n%s\n", argv[0], HELP);
fprintf(stderr, "%s: No input files.\n", argv[0]);
fprintf(stderr, "%s\n", HELP);
return 1;
}
/* Start building the preprocess command line. */
sprintf(tmp, "%s%civlpp %s%s -F%s -f%s -p%s ", pbase,sep,
sprintf(tmp, "%s%civlpp %s%s -D__ICARUS__=1 -f%s ", pbase,sep,
verbose_flag?" -v":"",
e_flag?"":" -L", defines_path, source_path,
compiled_defines_path);
e_flag?"":" -L", source_path);
ncmd = strlen(tmp);
cmd = malloc(ncmd + 1);
strcpy(cmd, tmp);
if (inc_list) {
cmd = realloc(cmd, ncmd + strlen(inc_list) + 1);
strcat(cmd, inc_list);
ncmd += strlen(inc_list);
}
if (def_list) {
cmd = realloc(cmd, ncmd + strlen(def_list) + 1);
strcat(cmd, def_list);
ncmd += strlen(def_list);
}
if (depfile) {
cmd = realloc(cmd, ncmd + strlen(depfile) + 5);
strcat(cmd, " -M ");
strcat(cmd, depfile);
ncmd += strlen(depfile) + 4;
}
/* If the -E flag was given on the command line, then all we
do is run the preprocessor and put the output where the
user wants it. */
@@ -858,11 +793,8 @@ int main(int argc, char **argv)
rc = system(cmd);
remove(source_path);
fclose(iconfig_file);
if ( ! getenv("IVERILOG_ICONFIG")) {
if ( ! getenv("IVERILOG_ICONFIG"))
remove(iconfig_path);
remove(defines_path);
remove(compiled_defines_path);
}
if (rc != 0) {
if (WIFEXITED(rc)) {
@@ -877,13 +809,13 @@ int main(int argc, char **argv)
return 0;
}
fprintf(iconfig_file, "iwidth:%u\n", integer_width);
/* Write the preprocessor command needed to preprocess a
single file. This may be used to preprocess library
files. */
fprintf(iconfig_file, "ivlpp:%s%civlpp -L -F%s -P%s\n",
pbase, sep, defines_path, compiled_defines_path);
fprintf(iconfig_file, "ivlpp:%s%civlpp -D__ICARUS__ -L %s %s\n",
pbase, sep,
inc_list? inc_list : "",
def_list? def_list : "");
/* Done writing to the iconfig file. Close it now. */
fclose(iconfig_file);
+1 -25
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2002 Stephen Williams (steve@icarus.com)
* Copyright (c) 2002-2010 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -16,9 +16,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: substit.c,v 1.5 2003/12/19 01:27:10 steve Exp $"
#endif
# include <string.h>
# include <stdlib.h>
@@ -92,24 +89,3 @@ char* substitutions(const char*str)
return buf;
}
/*
* $Log: substit.c,v $
* Revision 1.5 2003/12/19 01:27:10 steve
* Fix various unsigned compare warnings.
*
* Revision 1.4 2002/08/12 01:35:01 steve
* conditional ident string using autoconfig.
*
* Revision 1.3 2002/08/11 23:47:04 steve
* Add missing Log and Ident strings.
*
* Revision 1.2 2002/06/25 01:33:01 steve
* include malloc.h only when available.
*
* Revision 1.1 2002/06/23 20:10:51 steve
* Variable substitution in command files.
*
*/
+19 -22
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1999-2008 Stephen Williams (steve@icarus.com)
* Copyright (c) 1999-2010 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -24,17 +24,15 @@
NetEBComp* NetEBComp::dup_expr() const
{
NetEBComp*tmp = new NetEBComp(op_, left_->dup_expr(),
right_->dup_expr());
assert(tmp);
tmp->set_line(*this);
return tmp;
NetEBComp*result = new NetEBComp(op_, left_->dup_expr(),
right_->dup_expr());
result->set_line(*this);
return result;
}
NetEConst* NetEConst::dup_expr() const
{
NetEConst*tmp = new NetEConst(value_);
assert(tmp);
tmp->set_line(*this);
return tmp;
}
@@ -42,7 +40,6 @@ NetEConst* NetEConst::dup_expr() const
NetEConstParam* NetEConstParam::dup_expr() const
{
NetEConstParam*tmp = new NetEConstParam(scope_, name_, value());
assert(tmp);
tmp->set_line(*this);
return tmp;
}
@@ -50,7 +47,6 @@ NetEConstParam* NetEConstParam::dup_expr() const
NetECRealParam* NetECRealParam::dup_expr() const
{
NetECRealParam*tmp = new NetECRealParam(scope_, name_, value());
assert(tmp);
tmp->set_line(*this);
return tmp;
}
@@ -69,12 +65,8 @@ NetEScope* NetEScope::dup_expr() const
NetESelect* NetESelect::dup_expr() const
{
NetESelect*tmp = new NetESelect(expr_->dup_expr(),
base_? base_->dup_expr() : 0,
expr_width());
assert(tmp);
tmp->set_line(*this);
return tmp;
return new NetESelect(expr_->dup_expr(), base_->dup_expr(),
expr_width());
}
NetESFunc* NetESFunc::dup_expr() const
@@ -88,13 +80,12 @@ NetESFunc* NetESFunc::dup_expr() const
tmp->parm(idx, tmp->parm(idx)->dup_expr());
}
tmp->set_line(*this);
return tmp;
}
NetESignal* NetESignal::dup_expr() const
{
NetESignal*tmp = new NetESignal(net_, word_);
NetESignal*tmp = new NetESignal(net_, msi_, lsi_);
assert(tmp);
tmp->expr_width(expr_width());
tmp->set_line(*this);
@@ -106,8 +97,6 @@ NetETernary* NetETernary::dup_expr() const
NetETernary*tmp = new NetETernary(cond_->dup_expr(),
true_val_->dup_expr(),
false_val_->dup_expr());
assert(tmp);
tmp->set_line(*this);
return tmp;
}
@@ -121,7 +110,11 @@ NetEUFunc* NetEUFunc::dup_expr() const
tmp_parms[idx] = parms_[idx]->dup_expr();
}
tmp = new NetEUFunc(scope_, func_, result_sig_->dup_expr(), tmp_parms);
tmp = 0;
if (result_sig_)
tmp = new NetEUFunc(func_, result_sig_->dup_expr(), tmp_parms);
if (result_var_)
tmp = new NetEUFunc(func_, result_var_->dup_expr(), tmp_parms);
assert(tmp);
tmp->set_line(*this);
@@ -132,7 +125,6 @@ NetEUnary* NetEUnary::dup_expr() const
{
NetEUnary*tmp = new NetEUnary(op_, expr_->dup_expr());
assert(tmp);
tmp->set_line(*this);
return tmp;
}
@@ -140,6 +132,11 @@ NetEUReduce* NetEUReduce::dup_expr() const
{
NetEUReduce*tmp = new NetEUReduce(op_, expr_->dup_expr());
assert(tmp);
tmp->set_line(*this);
return tmp;
}
NetEVariable* NetEVariable::dup_expr() const
{
NetEVariable*tmp = new NetEVariable(var_);
return tmp;
}
+3 -54
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2000-2003 Stephen Williams (steve@icarus.com)
* Copyright (c) 2000-2010 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -16,9 +16,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: elab_anet.cc,v 1.13 2007/03/22 16:08:14 steve Exp $"
#endif
# include "config.h"
@@ -89,13 +86,10 @@ NetNet* PEConcat::elaborate_anet(Design*des, NetScope*scope) const
NetNet*osig = new NetNet(scope, scope->local_symbol(),
NetNet::IMPLICIT_REG, pins);
/* Assume that all the data types are the same. */
osig->data_type(nets[0]->data_type());
pins = 0;
for (unsigned idx = nets.count() ; idx > 0 ; idx -= 1) {
NetNet*cur = nets[idx-1];
assert(cur->data_type() == osig->data_type());
for (unsigned pin = 0; pin < cur->pin_count(); pin += 1) {
connect(osig->pin(pins), cur->pin(pin));
pins += 1;
@@ -112,10 +106,11 @@ NetNet* PEIdent::elaborate_anet(Design*des, NetScope*scope) const
NetNet* sig = 0;
NetMemory* mem = 0;
NetVariable* var = 0;
const NetExpr*par = 0;
NetEvent* eve = 0;
symbol_search(des, scope, path_, sig, mem, par, eve);
symbol_search(des, scope, path_, sig, mem, var, par, eve);
if (mem != 0) {
@@ -166,49 +161,3 @@ NetNet* PEIdent::elaborate_anet(Design*des, NetScope*scope) const
return sig;
}
/*
* $Log: elab_anet.cc,v $
* Revision 1.13 2007/03/22 16:08:14 steve
* Spelling fixes from Larry
*
* Revision 1.12 2006/05/01 20:47:58 steve
* More explicit datatype setup.
*
* Revision 1.11 2005/07/11 16:56:50 steve
* Remove NetVariable and ivl_variable_t structures.
*
* Revision 1.10 2004/10/04 01:10:52 steve
* Clean up spurious trailing white space.
*
* Revision 1.9 2003/09/19 03:50:12 steve
* Remove find_memory method from Design class.
*
* Revision 1.8 2003/06/21 01:21:43 steve
* Harmless fixup of warnings.
*
* Revision 1.7 2003/03/06 00:28:41 steve
* All NetObj objects have lex_string base names.
*
* Revision 1.6 2003/01/27 05:09:17 steve
* Spelling fixes.
*
* Revision 1.5 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.4 2001/12/03 04:47:14 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
*
* Revision 1.3 2001/07/25 03:10:48 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
*
* Revision 1.2 2001/01/06 02:29:36 steve
* Support arrays of integers.
*
* Revision 1.1 2000/12/06 06:31:09 steve
* Check lvalue of procedural continuous assign (PR#29)
*
*/
+448 -1479
View File
File diff suppressed because it is too large Load Diff
+110 -247
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2000-2008 Stephen Williams (steve@icarus.com)
* Copyright (c) 2000-2010 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -22,18 +22,15 @@
# include "PExpr.h"
# include "netlist.h"
# include "netmisc.h"
# include "compiler.h"
# include <cstdlib>
# include <iostream>
# include <climits>
# include "ivl_assert.h"
/*
* These methods generate a NetAssign_ object for the l-value of the
* assignment. This is common code for the = and <= statements.
*
* What gets generated depends on the structure of the l-value. If the
* l-value is a simple name (i.e., foo <= <value>) then the NetAssign_
* l-value is a simple name (i.e., foo <= <value>) the the NetAssign_
* is created the width of the foo reg and connected to all the
* bits.
*
@@ -66,13 +63,11 @@
* is to try to make a net elaboration, and see if the result is
* suitable for assignment.
*/
NetAssign_* PExpr::elaborate_lval(Design*des,
NetScope*scope,
bool is_force) const
NetAssign_* PExpr::elaborate_lval(Design*des, NetScope*scope) const
{
NetNet*ll = 0;
if (ll == 0) {
cerr << get_fileline() << ": Assignment l-value too complex."
cerr << get_line() << ": Assignment l-value too complex."
<< endl;
return 0;
}
@@ -94,12 +89,10 @@ NetAssign_* PExpr::elaborate_lval(Design*des,
* a is the MSB and b the LSB. Connect the LSB to the low pins of the
* NetAssign_ object.
*/
NetAssign_* PEConcat::elaborate_lval(Design*des,
NetScope*scope,
bool is_force) const
NetAssign_* PEConcat::elaborate_lval(Design*des, NetScope*scope) const
{
if (repeat_) {
cerr << get_fileline() << ": error: Repeat concatenations make "
cerr << get_line() << ": error: Repeat concatenations make "
"no sense in l-value expressions. I refuse." << endl;
des->errors += 1;
return 0;
@@ -110,13 +103,13 @@ NetAssign_* PEConcat::elaborate_lval(Design*des,
for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) {
if (parms_[idx] == 0) {
cerr << get_fileline() << ": error: Empty expressions "
cerr << get_line() << ": error: Empty expressions "
<< "not allowed in concatenations." << endl;
des->errors += 1;
continue;
}
NetAssign_*tmp = parms_[idx]->elaborate_lval(des, scope, is_force);
NetAssign_*tmp = parms_[idx]->elaborate_lval(des, scope);
/* If the l-value doesn't elaborate, the error was
already detected and printed. We just skip it and let
@@ -144,65 +137,43 @@ NetAssign_* PEConcat::elaborate_lval(Design*des,
* Handle the ident as an l-value. This includes bit and part selects
* of that ident.
*/
NetAssign_* PEIdent::elaborate_lval(Design*des,
NetScope*scope,
bool is_force) const
NetAssign_* PEIdent::elaborate_lval(Design*des, NetScope*scope) const
{
NetNet* reg = 0;
NetMemory* mem = 0;
NetVariable* var = 0;
const NetExpr*par = 0;
NetEvent* eve = 0;
symbol_search(des, scope, path_, reg, par, eve);
symbol_search(des, scope, path_, reg, mem, var, par, eve);
if (mem) {
return elaborate_mem_lval_(des, scope, mem);
}
if (var) {
NetAssign_*cur = new NetAssign_(var);
return cur;
}
if (reg == 0) {
cerr << get_fileline() << ": error: Could not find variable ``"
<< path_ << "'' in ``" << scope_path(scope) <<
cerr << get_line() << ": error: Could not find variable ``"
<< path_ << "'' in ``" << scope->name() <<
"''" << endl;
des->errors += 1;
return 0;
}
ivl_assert(*this, reg);
const name_component_t&name_tail = path_.back();
index_component_t::ctype_t use_sel = index_component_t::SEL_NONE;
if (!name_tail.index.empty())
use_sel = name_tail.index.back().sel;
// This is the special case that the l-value is an entire
// memory. This is, in fact, an error.
if (reg->array_dimensions() > 0 && name_tail.index.empty()) {
cerr << get_fileline() << ": error: Cannot assign to array "
<< path_ << ". Did you forget a word index?" << endl;
des->errors += 1;
return 0;
}
if (reg->array_dimensions() > 0)
return elaborate_lval_net_word_(des, scope, reg);
if (use_sel == index_component_t::SEL_PART) {
NetAssign_*lv = new NetAssign_(reg);
elaborate_lval_net_part_(des, scope, lv);
return lv;
}
if (use_sel == index_component_t::SEL_IDX_UP ||
use_sel == index_component_t::SEL_IDX_DO) {
NetAssign_*lv = new NetAssign_(reg);
elaborate_lval_net_idx_(des, scope, lv, use_sel);
return lv;
}
assert(reg);
/* Get the signal referenced by the identifier, and make sure
it is a register. Wires are not allows in this context,
unless this is the l-value of a force. */
if ((reg->type() != NetNet::REG) && !is_force) {
cerr << get_fileline() << ": error: " << path_ <<
" is not a valid l-value in " << scope_path(scope) <<
it is a register. (Wires are not allows in this context. */
if (reg->type() != NetNet::REG) {
cerr << get_line() << ": error: " << path_ <<
" is not a reg/integer/time in " << scope->name() <<
"." << endl;
cerr << reg->get_fileline() << ": : " << path_ <<
cerr << reg->get_line() << ": : " << path_ <<
" is declared here as " << reg->type() << "." << endl;
des->errors += 1;
return 0;
@@ -211,29 +182,57 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
long msb, lsb;
NetExpr*mux;
if (use_sel == index_component_t::SEL_BIT) {
if (msb_ && lsb_) {
/* This handles part selects. In this case, there are
two bit select expressions, and both must be
constant. Evaluate them and pass the results back to
the caller. */
verinum*vl = lsb_->eval_const(des, scope);
if (vl == 0) {
cerr << lsb_->get_line() << ": error: "
"Part select expressions must be constant."
<< endl;
cerr << lsb_->get_line() << ": : This lsb expression "
"violates the rule: " << *lsb_ << endl;
des->errors += 1;
return 0;
}
verinum*vm = msb_->eval_const(des, scope);
if (vm == 0) {
cerr << msb_->get_line() << ": error: "
"Part select expressions must be constant."
<< endl;
cerr << msb_->get_line() << ": : This msb expression "
"violates the rule: " << *msb_ << endl;
des->errors += 1;
return 0;
}
const index_component_t&index_tail = name_tail.index.back();
ivl_assert(*this, index_tail.msb != 0);
ivl_assert(*this, index_tail.lsb == 0);
msb = vm->as_long();
lsb = vl->as_long();
mux = 0;
} else if (msb_) {
/* If there is only a single select expression, it is a
bit select. Evaluate the constant value and treat it
as a part select with a bit width of 1. If the
expression it not constant, then return the
expression as a mux. */
NetExpr*index_expr = elab_and_eval(des, scope, index_tail.msb, -1);
if (NetEConst*index_con = dynamic_cast<NetEConst*> (index_expr)) {
msb = index_con->value().as_long();
lsb = index_con->value().as_long();
mux = 0;
} else {
assert(lsb_ == 0);
verinum*v = msb_->eval_const(des, scope);
if (v == 0) {
NetExpr*m = msb_->elaborate_expr(des, scope);
assert(m);
msb = 0;
lsb = 0;
mux = index_expr;
mux = m;
} else {
msb = v->as_long();
lsb = v->as_long();
mux = 0;
}
} else {
@@ -241,6 +240,8 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
/* No select expressions, so presume a part select the
width of the register. */
assert(msb_ == 0);
assert(lsb_ == 0);
msb = reg->msb();
lsb = reg->lsb();
mux = 0;
@@ -255,19 +256,7 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
bmux to select the target bit. */
lv = new NetAssign_(reg);
/* Correct the mux for the range of the vector. */
if (reg->msb() < reg->lsb())
mux = make_sub_expr(reg->lsb(), mux);
else if (reg->lsb() != 0)
mux = make_add_expr(mux, - reg->lsb());
lv->set_part(mux, 1);
} else if (msb == reg->msb() && lsb == reg->lsb()) {
/* No bit select, and part select covers the entire
vector. Simplest case. */
lv = new NetAssign_(reg);
lv->set_bmux(mux);
} else {
@@ -279,7 +268,7 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
unsigned wid = moff - loff + 1;
if (moff < loff) {
cerr << get_fileline() << ": error: part select "
cerr << get_line() << ": error: part select "
<< reg->name() << "[" << msb<<":"<<lsb<<"]"
<< " is reversed." << endl;
des->errors += 1;
@@ -291,8 +280,8 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
converted to normalized form so is relative the
variable pins. */
if ((wid + loff) > reg->vector_width()) {
cerr << get_fileline() << ": error: bit/part select "
if ((wid + loff) > reg->pin_count()) {
cerr << get_line() << ": error: bit/part select "
<< reg->name() << "[" << msb<<":"<<lsb<<"]"
<< " is out of range." << endl;
des->errors += 1;
@@ -300,185 +289,59 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
}
lv = new NetAssign_(reg);
lv->set_part(new NetEConst(verinum(loff)), wid);
lv->set_part(loff, wid);
assert(moff < reg->pin_count());
}
return lv;
}
NetAssign_* PEIdent::elaborate_lval_net_word_(Design*des,
NetScope*scope,
NetNet*reg) const
NetAssign_* PEIdent::elaborate_mem_lval_(Design*des, NetScope*scope,
NetMemory*mem) const
{
const name_component_t&name_tail = path_.back();
ivl_assert(*this, !name_tail.index.empty());
const index_component_t&index_head = name_tail.index.front();
if (index_head.sel == index_component_t::SEL_PART) {
cerr << get_fileline() << ": error: cannot perform a part "
<< "select on array " << reg->name() << "." << endl;
if (msb_ == 0) {
cerr << get_line() << ": error: Assign to memory \""
<< mem->name() << "\" requires a word select index."
<< endl;
des->errors += 1;
return 0;
}
ivl_assert(*this, index_head.sel == index_component_t::SEL_BIT);
ivl_assert(*this, index_head.msb != 0);
ivl_assert(*this, index_head.lsb == 0);
NetExpr*word = elab_and_eval(des, scope, index_head.msb, -1);
// If there is a non-zero base to the memory, then build an
// expression to calculate the canonical address.
if (long base = reg->array_first()) {
word = make_add_expr(word, 0-base);
eval_expr(word);
if (msb_ && lsb_) {
cerr << get_line() << ": error: Cannot use part select on "
<< "memory \"" << mem->name() << ".\"" << endl;
des->errors += 1;
return 0;
}
NetAssign_*lv = new NetAssign_(reg);
lv->set_word(word);
assert(msb_ && !lsb_);
if (debug_elaborate)
cerr << get_fileline() << ": debug: Set array word=" << *word << endl;
NetExpr*ix = msb_->elaborate_expr(des, scope);
if (ix == 0)
return 0;
// Test for the case that the index is a constant, and is out
// of bounds. The "word" expression is the word index already
// converted to canonical address, so this just needs to check
// that the address is not too big.
if (NetEConst*word_const = dynamic_cast<NetEConst*>(word)) {
verinum word_val = word_const->value();
long index = word_val.as_long();
assert (reg->array_count() <= LONG_MAX);
if (index < 0 || index >= (long) reg->array_count()) {
cerr << get_fileline() << ": warning: Constant array index "
<< (index + reg->array_first())
<< " is out of range for array "
<< reg->name() << "." << endl;
/* Evaluate the memory index expression down as must as
possible. Ideally, we can get it down to a constant. */
if (! dynamic_cast<NetEConst*>(ix)) {
NetExpr*tmp = ix->eval_tree();
if (tmp) {
tmp->set_line(*ix);
delete ix;
ix = tmp;
}
}
/* An array word may also have part selects applied to them. */
index_component_t::ctype_t use_sel = index_component_t::SEL_NONE;
if (name_tail.index.size() > 1)
use_sel = name_tail.index.back().sel;
if (use_sel == index_component_t::SEL_PART)
elaborate_lval_net_part_(des, scope, lv);
if (use_sel == index_component_t::SEL_IDX_UP ||
use_sel == index_component_t::SEL_IDX_DO)
elaborate_lval_net_idx_(des, scope, lv, use_sel);
NetAssign_*lv = new NetAssign_(mem);
lv->set_bmux(ix);
lv->set_part(0, mem->width());
return lv;
}
bool PEIdent::elaborate_lval_net_part_(Design*des,
NetScope*scope,
NetAssign_*lv) const
NetAssign_* PENumber::elaborate_lval(Design*des, NetScope*) const
{
long msb, lsb;
bool flag = calculate_parts_(des, scope, msb, lsb);
if (!flag)
return false;
NetNet*reg = lv->sig();
assert(reg);
if (msb == reg->msb() && lsb == reg->lsb()) {
/* No bit select, and part select covers the entire
vector. Simplest case. */
} else {
/* If the bit/part select is constant, then make the
NetAssign_ only as wide as it needs to be and connect
only to the selected bits of the reg. */
unsigned loff = reg->sb_to_idx(lsb);
unsigned moff = reg->sb_to_idx(msb);
unsigned wid = moff - loff + 1;
if (moff < loff) {
cerr << get_fileline() << ": error: part select "
<< reg->name() << "[" << msb<<":"<<lsb<<"]"
<< " is reversed." << endl;
des->errors += 1;
return false;
}
/* If the part select extends beyond the extreme of the
variable, then report an error. Note that loff is
converted to normalized form so is relative the
variable pins. */
if ((wid + loff) > reg->vector_width()) {
cerr << get_fileline() << ": error: bit/part select "
<< reg->name() << "[" << msb<<":"<<lsb<<"]"
<< " is out of range." << endl;
des->errors += 1;
return false;
}
lv->set_part(new NetEConst(verinum(loff)), wid);
}
return true;
}
bool PEIdent::elaborate_lval_net_idx_(Design*des,
NetScope*scope,
NetAssign_*lv,
index_component_t::ctype_t use_sel) const
{
const name_component_t&name_tail = path_.back();;
ivl_assert(*this, !name_tail.index.empty());
const index_component_t&index_tail = name_tail.index.back();
ivl_assert(*this, index_tail.msb != 0);
ivl_assert(*this, index_tail.lsb != 0);
NetNet*reg = lv->sig();
assert(reg);
if (reg->type() != NetNet::REG) {
cerr << get_fileline() << ": error: " << path_ <<
" is not a reg/integer/time in " << scope_path(scope) <<
"." << endl;
cerr << reg->get_fileline() << ": : " << path_ <<
" is declared here as " << reg->type() << "." << endl;
des->errors += 1;
return false;
}
unsigned long wid;
calculate_up_do_width_(des, scope, wid);
NetExpr*base = elab_and_eval(des, scope, index_tail.msb, -1);
/* Correct the mux for the range of the vector. */
if (reg->msb() < reg->lsb())
base = make_sub_expr(reg->lsb(), base);
else if (reg->lsb() != 0)
base = make_add_expr(base, - reg->lsb());
if (use_sel == index_component_t::SEL_IDX_DO && wid > 1 ) {
base = make_add_expr(base, 1-(long)wid);
}
if (debug_elaborate)
cerr << get_fileline() << ": debug: Set part select width="
<< wid << ", base=" << *base << endl;
lv->set_part(base, wid);
return true;
}
NetAssign_* PENumber::elaborate_lval(Design*des, NetScope*, bool) const
{
cerr << get_fileline() << ": error: Constant values not allowed "
cerr << get_line() << ": error: Constant values not allowed "
<< "in l-value expressions." << endl;
des->errors += 1;
return 0;
+1211 -2341
View File
File diff suppressed because it is too large Load Diff
+32 -74
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2000-2008 Stephen Williams (steve@icarus.com)
* Copyright (c) 2000-2010 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -22,15 +22,12 @@
# include "PExpr.h"
# include "compiler.h"
# include "util.h"
# include "netmisc.h"
# include <cstdlib>
# include <iostream>
# include "ivl_assert.h"
NetExpr*PExpr::elaborate_pexpr(Design*des, NetScope*sc) const
{
cerr << get_fileline() << ": error: invalid parameter expression: "
cerr << get_line() << ": error: invalid parameter expression: "
<< *this << endl;
des->errors += 1;
@@ -53,7 +50,7 @@ NetExpr*PEBinary::elaborate_pexpr (Design*des, NetScope*scope) const
return 0;
}
NetExpr*tmp = elaborate_expr_base_(des, lp, rp, -2);
NetExpr*tmp = elaborate_expr_base_(des, lp, rp);
return tmp;
}
@@ -74,11 +71,10 @@ NetEConcat* PEConcat::elaborate_pexpr(Design*des, NetScope*scope) const
if (repeat_) {
repeat = repeat_->elaborate_pexpr(des, scope);
if (repeat == 0) {
cerr << get_fileline() << ": error: "
cerr << get_line() << ": error: "
"concatenation repeat expression cannot be evaluated."
<< endl;
des->errors += 1;
return 0;
}
/* continue on even if the repeat expression doesn't
@@ -105,12 +101,11 @@ NetEConcat* PEConcat::elaborate_pexpr(Design*des, NetScope*scope) const
the width check for later. */
} else if (! ex->has_width()) {
cerr << ex->get_fileline() << ": error: operand of "
cerr << ex->get_line() << ": error: operand of "
<< "concatenation has indefinite width: "
<< *ex << endl;
des->errors += 1;
delete tmp;
return 0;
}
tmp->set(idx, ex);
@@ -121,7 +116,7 @@ NetEConcat* PEConcat::elaborate_pexpr(Design*des, NetScope*scope) const
NetExpr*PEFNumber::elaborate_pexpr(Design*des, NetScope*scope) const
{
return elaborate_expr(des, scope, -1, false);
return elaborate_expr(des, scope);
}
/*
@@ -132,75 +127,42 @@ NetExpr*PEFNumber::elaborate_pexpr(Design*des, NetScope*scope) const
*/
NetExpr*PEIdent::elaborate_pexpr(Design*des, NetScope*scope) const
{
pform_name_t path = path_;
name_component_t name_tail = path_.back();
path.pop_back();
hname_t path = path_;
char*name = path.remove_tail_name();
NetScope*pscope = scope;
if (path_.size() > 0) {
list<hname_t> tmp = eval_scope_path(des, scope, path);
pscope = des->find_scope(scope, tmp);
}
if (path.peek_name(0))
pscope = des->find_scope(scope, path);
const NetExpr*ex_msb;
const NetExpr*ex_lsb;
const NetExpr*ex = 0;
// Look up the parameter name in the current scope. If the
// name is not found in the pscope, look in containing scopes,
// but do not go outside the containing module instance.
for (;;) {
ex = pscope->get_parameter(name_tail.name, ex_msb, ex_lsb);
if (ex != 0)
break;
if (pscope->type() == NetScope::MODULE)
break;
pscope = pscope->parent();
ivl_assert(*this, pscope);
}
perm_string perm_name = lex_strings.make(name);
delete name;
const NetExpr*ex = pscope->get_parameter(perm_name);
if (ex == 0) {
cerr << get_fileline() << ": error: identifier ``" << name_tail.name <<
"'' is not a parameter in "<< scope_path(scope)<< "." << endl;
cerr << get_line() << ": error: identifier ``" << path_ <<
"'' is not a parameter in " << scope->name() << "." << endl;
des->errors += 1;
return 0;
}
NetExpr*res = new NetEParam(des, pscope, name_tail.name);
NetExpr*res = new NetEParam(des, pscope, perm_name);
res->set_line(*this);
assert(res);
index_component_t::ctype_t use_sel = index_component_t::SEL_NONE;
if (!name_tail.index.empty())
use_sel = name_tail.index.back().sel;
switch (use_sel) {
case index_component_t::SEL_NONE:
break;
default:
case index_component_t::SEL_PART:
cerr << get_fileline() << ": sorry: Cannot part select "
"bits of parameters." << endl;
assert(idx_ == 0);
if (msb_ && lsb_) {
cerr << get_line() << ": sorry: Cannot part select "
"bits of parameters." << endl;
des->errors += 1;
delete res;
return 0;
case index_component_t::SEL_BIT:
} else if (msb_) {
/* We have here a bit select. Insert a NetESelect node
to handle it. */
NetExpr*tmp = name_tail.index.back().msb->elaborate_pexpr(des, scope);
if (tmp == 0) {
delete res;
return 0;
NetExpr*tmp = msb_->elaborate_pexpr(des, scope);
if (tmp != 0) {
res = new NetESelect(res, tmp, 1);
}
if (debug_elaborate)
cerr << get_fileline() << ": debug: "
<< "Bit select [" << *tmp << "]"
<< " in parameter expression." << endl;
res = new NetESelect(res, tmp, 1);
res->set_line(*this);
break;
}
return res;
@@ -211,13 +173,13 @@ NetExpr*PEIdent::elaborate_pexpr(Design*des, NetScope*scope) const
*/
NetExpr*PENumber::elaborate_pexpr(Design*des, NetScope*sc) const
{
return elaborate_expr(des, sc, -1, false);
return elaborate_expr(des, sc);
}
NetEConst* PEString::elaborate_pexpr(Design*des, NetScope*scope) const
{
return elaborate_expr(des, scope, -1, false);
return elaborate_expr(des, scope);
}
NetETernary* PETernary::elaborate_pexpr(Design*des, NetScope*scope) const
@@ -225,11 +187,10 @@ NetETernary* PETernary::elaborate_pexpr(Design*des, NetScope*scope) const
NetExpr*c = expr_->elaborate_pexpr(des, scope);
NetExpr*t = tru_->elaborate_pexpr(des, scope);
NetExpr*f = fal_->elaborate_pexpr(des, scope);
if (c == 0 || t == 0 || f == 0) return 0;
NetETernary*tmp = new NetETernary(c, t, f);
tmp->set_line(*this);
return tmp;
if (c == 0) return 0;
if (t == 0) return 0;
if (f == 0) return 0;
return new NetETernary(c, t, f);
}
NetExpr*PEUnary::elaborate_pexpr (Design*des, NetScope*scope) const
@@ -247,12 +208,10 @@ NetExpr*PEUnary::elaborate_pexpr (Design*des, NetScope*scope) const
tmp = new NetEUnary(op_, ip);
tmp->set_line(*this);
break;
case '~':
tmp = new NetEUBits(op_, ip);
tmp->set_line(*this);
break;
case '!': // Logical NOT
case '&': // Reduction AND
case '|': // Reduction OR
@@ -264,6 +223,5 @@ NetExpr*PEUnary::elaborate_pexpr (Design*des, NetScope*scope) const
tmp->set_line(*this);
break;
}
return tmp;
}
+131 -475
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2000-2008 Stephen Williams (steve@icarus.com)
* Copyright (c) 2000-2010 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -19,11 +19,9 @@
# include "config.h"
# include "compiler.h"
# include "netmisc.h"
# include <cstring>
# include <iostream>
# include <cstdlib>
# include <stdio.h>
# include <cstring>
/*
* Elaboration happens in two passes, generally. The first scans the
@@ -33,10 +31,10 @@
*/
# include "Module.h"
# include "PData.h"
# include "PEvent.h"
# include "PExpr.h"
# include "PGate.h"
# include "PGenerate.h"
# include "PTask.h"
# include "PWire.h"
# include "Statement.h"
@@ -44,91 +42,12 @@
# include "util.h"
# include <typeinfo>
# include <assert.h>
# include "ivl_assert.h"
void Module::elaborate_parm_item_(perm_string name, const param_expr_t&cur,
Design*des, NetScope*scope)
{
PExpr*ex = cur.expr;
assert(ex);
NetExpr*val = ex->elaborate_pexpr(des, scope);
if (val == 0) return;
NetExpr*msb = 0;
NetExpr*lsb = 0;
bool signed_flag = cur.signed_flag;
/* If the parameter declaration includes msb and lsb,
then use them to calculate a width for the
result. Then make sure the constant expression of the
parameter value is coerced to have the correct
and defined width. */
if (cur.msb) {
assert(cur.lsb);
msb = cur.msb ->elaborate_pexpr(des, scope);
assert(msb);
lsb = cur.lsb ->elaborate_pexpr(des, scope);
assert(lsb);
}
if (signed_flag) {
/* If explicitly signed, then say so. */
val->cast_signed(true);
} else if (cur.msb) {
/* If there is a range, then the signedness comes
from the type and not the expression. */
val->cast_signed(signed_flag);
} else {
/* otherwise, let the expression describe
itself. */
signed_flag = val->has_sign();
}
NetScope::range_t*range_list = 0;
for (Module::range_t*range = cur.range ; range ; range = range->next) {
NetScope::range_t*tmp = new NetScope::range_t;
tmp->exclude_flag = range->exclude_flag;
tmp->low_open_flag = range->low_open_flag;
tmp->high_open_flag = range->high_open_flag;
if (range->low_expr) {
tmp->low_expr = elab_and_eval(des, scope, range->low_expr, -1);
ivl_assert(*range->low_expr, tmp->low_expr);
} else {
tmp->low_expr = 0;
}
if (range->high_expr && range->high_expr==range->low_expr) {
// Detect the special case of a "point"
// range. These are called out by setting the high
// and low expression ranges to the same
// expression. The exclude_flags should be false
// in this case
ivl_assert(*range->high_expr, tmp->low_open_flag==false && tmp->high_open_flag==false);
tmp->high_expr = tmp->low_expr;
} else if (range->high_expr) {
tmp->high_expr = elab_and_eval(des, scope, range->high_expr, -1);
ivl_assert(*range->high_expr, tmp->high_expr);
} else {
tmp->high_expr = 0;
}
tmp->next = range_list;
range_list = tmp;
}
val = scope->set_parameter(name, val, cur.type, msb, lsb, signed_flag, range_list, cur);
assert(val);
delete val;
}
bool Module::elaborate_scope(Design*des, NetScope*scope,
const replace_t&replacements) const
bool Module::elaborate_scope(Design*des, NetScope*scope) const
{
if (debug_scopes) {
cerr << get_fileline() << ": debug: Elaborate scope "
<< scope_path(scope) << "." << endl;
cerr << get_line() << ": debug: Elaborate scope "
<< scope->name() << "." << endl;
}
// Generate all the parameters that this instance of this
@@ -143,7 +62,7 @@ bool Module::elaborate_scope(Design*des, NetScope*scope,
// place of the elaborated expression.
typedef map<perm_string,param_expr_t>::const_iterator mparm_it_t;
typedef map<pform_name_t,PExpr*>::const_iterator pform_parm_it_t;
typedef map<hname_t,PExpr*>::const_iterator hparm_it_t;
// This loop scans the parameters in the module, and creates
@@ -154,10 +73,10 @@ bool Module::elaborate_scope(Design*des, NetScope*scope,
NetEParam*tmp = new NetEParam;
tmp->set_line(*((*cur).second.expr));
tmp->cast_signed( (*cur).second.signed_flag );
if ((*cur).second.msb)
tmp->cast_signed( (*cur).second.signed_flag );
scope->set_parameter((*cur).first, tmp, (*cur).second.type,
0, 0, false, 0, (*cur).second);
scope->set_parameter((*cur).first, tmp, 0, 0, false);
}
for (mparm_it_t cur = localparams.begin()
@@ -168,8 +87,7 @@ bool Module::elaborate_scope(Design*des, NetScope*scope,
if ((*cur).second.msb)
tmp->cast_signed( (*cur).second.signed_flag );
scope->set_parameter((*cur).first, tmp, (*cur).second.type,
0, 0, false, 0, (*cur).second);
scope->set_parameter((*cur).first, tmp, 0, 0, false);
}
@@ -181,41 +99,61 @@ bool Module::elaborate_scope(Design*des, NetScope*scope,
for (mparm_it_t cur = parameters.begin()
; cur != parameters.end() ; cur ++) {
elaborate_parm_item_((*cur).first, (*cur).second, des, scope);
}
PExpr*ex = (*cur).second.expr;
assert(ex);
/* run parameter replacements that were collected from the
containing scope and meant for me. */
for (replace_t::const_iterator cur = replacements.begin()
; cur != replacements.end() ; cur ++) {
NetExpr*val = ex->elaborate_pexpr(des, scope);
NetExpr*msb = 0;
NetExpr*lsb = 0;
bool signed_flag = false;
NetExpr*val = (*cur).second;
if (val == 0) {
cerr << get_fileline() << ": internal error: "
<< "Missing expression in parameter replacement for "
<< (*cur).first;
/* If the parameter declaration includes msb and lsb,
then use them to calculate a width for the
result. Then make sure the constant expression of the
parameter value is coerced to have the correct
and defined width. */
if ((*cur).second.msb) {
msb = (*cur).second.msb ->elaborate_pexpr(des, scope);
assert(msb);
lsb = (*cur).second.lsb ->elaborate_pexpr(des, scope);
signed_flag = (*cur).second.signed_flag;
}
val->cast_signed(signed_flag);
val = scope->set_parameter((*cur).first, val,
msb, lsb, signed_flag);
assert(val);
if (debug_scopes) {
cerr << get_fileline() << ": debug: "
<< "Replace " << (*cur).first
<< " with expression " << *val
<< " from " << val->get_fileline() << "." << endl;
cerr << get_fileline() << ": : "
<< "Type=" << val->expr_type() << endl;
}
bool flag = scope->replace_parameter((*cur).first, val);
if (! flag) {
cerr << val->get_fileline() << ": warning: parameter "
<< (*cur).first << " not found in "
<< scope_path(scope) << "." << endl;
}
delete val;
}
for (mparm_it_t cur = localparams.begin()
; cur != localparams.end() ; cur ++) {
elaborate_parm_item_((*cur).first, (*cur).second, des, scope);
PExpr*ex = (*cur).second.expr;
assert(ex);
NetExpr*val = ex->elaborate_pexpr(des, scope);
NetExpr*msb = 0;
NetExpr*lsb = 0;
bool signed_flag = false;
/* If the parameter declaration includes msb and lsb,
then use them to calculate a width for the
result. Then make sure the constant expression of the
parameter value is coerced to have the correct
and defined width. */
if ((*cur).second.msb) {
msb = (*cur).second.msb ->elaborate_pexpr(des, scope);
assert(msb);
lsb = (*cur).second.lsb ->elaborate_pexpr(des, scope);
signed_flag = (*cur).second.signed_flag;
}
val->cast_signed(signed_flag);
val = scope->set_parameter((*cur).first, val,
msb, lsb, signed_flag);
assert(val);
delete val;
}
// Run through the defparams for this module, elaborate the
@@ -228,7 +166,7 @@ bool Module::elaborate_scope(Design*des, NetScope*scope,
// here because the parameter receiving the assignment may be
// in a scope not discovered by this pass.
for (pform_parm_it_t cur = defparms.begin()
for (hparm_it_t cur = defparms.begin()
; cur != defparms.end() ; cur ++ ) {
PExpr*ex = (*cur).second;
@@ -249,17 +187,6 @@ bool Module::elaborate_scope(Design*des, NetScope*scope,
delete[]attr;
// Generate schemes can create new scopes in the form of
// generated code. Scan the generate schemes, and *generate*
// new scopes, which is slightly different from simple
// elaboration.
typedef list<PGenerate*>::const_iterator generate_it_t;
for (generate_it_t cur = generate_schemes.begin()
; cur != generate_schemes.end() ; cur ++ ) {
(*cur) -> generate_scope(des, scope);
}
// Tasks introduce new scopes, so scan the tasks in this
// module. Create a scope for the task and pass that to the
@@ -271,17 +198,8 @@ bool Module::elaborate_scope(Design*des, NetScope*scope,
for (tasks_it_t cur = tasks_.begin()
; cur != tasks_.end() ; cur ++ ) {
hname_t use_name( (*cur).first );
if (scope->child(use_name)) {
cerr << get_fileline() << ": error: task/scope name "
<< use_name << " already used in this context."
<< endl;
des->errors += 1;
continue;
}
NetScope*task_scope = new NetScope(scope, use_name,
NetScope*task_scope = new NetScope(scope, (*cur).first,
NetScope::TASK);
task_scope->set_line((*cur).second);
(*cur).second->elaborate_scope(des, task_scope);
}
@@ -295,17 +213,8 @@ bool Module::elaborate_scope(Design*des, NetScope*scope,
for (funcs_it_t cur = funcs_.begin()
; cur != funcs_.end() ; cur ++ ) {
hname_t use_name( (*cur).first );
if (scope->child(use_name)) {
cerr << get_fileline() << ": error: function/scope name "
<< use_name << " already used in this context."
<< endl;
des->errors += 1;
continue;
}
NetScope*func_scope = new NetScope(scope, use_name,
NetScope*func_scope = new NetScope(scope, (*cur).first,
NetScope::FUNC);
func_scope->set_line((*cur).second);
(*cur).second->elaborate_scope(des, func_scope);
}
@@ -327,8 +236,8 @@ bool Module::elaborate_scope(Design*des, NetScope*scope,
typedef list<PProcess*>::const_iterator proc_it_t;
for (proc_it_t cur = behaviors.begin()
; cur != behaviors.end() ; cur ++ ) {
for (proc_it_t cur = behaviors_.begin()
; cur != behaviors_.end() ; cur ++ ) {
(*cur) -> statement() -> elaborate_scope(des, scope);
}
@@ -344,288 +253,19 @@ bool Module::elaborate_scope(Design*des, NetScope*scope,
(*et).second->elaborate_scope(des, scope);
}
for (map<hname_t,PData*>::const_iterator cur = datum.begin()
; cur != datum.end() ; cur ++ ) {
(*cur).second->elaborate_scope(des, scope);
}
return des->errors == 0;
}
bool PGenerate::generate_scope(Design*des, NetScope*container)
{
switch (scheme_type) {
case GS_LOOP:
return generate_scope_loop_(des, container);
case GS_CONDIT:
return generate_scope_condit_(des, container, false);
case GS_ELSE:
return generate_scope_condit_(des, container, true);
case GS_CASE:
return generate_scope_case_(des, container);
return true;
case GS_CASE_ITEM:
cerr << get_fileline() << ": internal error: "
<< "Case item outside of a case generate scheme?" << endl;
return false;
default:
cerr << get_fileline() << ": sorry: Generate of this sort"
<< " is not supported yet!" << endl;
return false;
}
}
/*
* This is the elaborate scope method for a generate loop.
*/
bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
{
// Check that the loop_index variable was declared in a
// genvar statement.
// MISSING CODE!
// We're going to need a genvar...
int genvar;
// The initial value for the genvar does not need (nor can it
// use) the genvar itself, so we can evaluate this expression
// the same way any other parameter value is evaluated.
NetExpr*init_ex = elab_and_eval(des, container, loop_init, -1);
NetEConst*init = dynamic_cast<NetEConst*> (init_ex);
if (init == 0) {
cerr << get_fileline() << ": error: Cannot evaluate genvar"
<< " init expression: " << *loop_init << endl;
des->errors += 1;
return false;
}
// Since we will be adding the genvar value as a local parameter
// to each instances scope. We need to make sure a parameter does
// not already exist.
const NetExpr*tmsb;
const NetExpr*tlsb;
const NetExpr*texpr = container->get_parameter(loop_index, tmsb, tlsb);
if (texpr != 0) {
cerr << get_fileline() << ": error: Cannot have a genvar "
<< "and parameter with the same name: " << loop_index << endl;
des->errors += 1;
return false;
}
genvar = init->value().as_long();
delete init_ex;
if (debug_scopes)
cerr << get_fileline() << ": debug: genvar init = " << genvar << endl;
container->genvar_tmp = loop_index;
container->genvar_tmp_val = genvar;
NetExpr*test_ex = elab_and_eval(des, container, loop_test, -1);
NetEConst*test = dynamic_cast<NetEConst*>(test_ex);
assert(test);
while (test->value().as_long()) {
// The actual name of the scope includes the genvar so
// that each instance has a unique name in the
// container. The format of using [] is part of the
// Verilog standard.
hname_t use_name (scope_name, genvar);
if (container->child(use_name)) {
cerr << get_fileline() << ": error: block/scope name "
<< use_name << " already used in this context."
<< endl;
des->errors += 1;
return false;
}
if (debug_scopes)
cerr << get_fileline() << ": debug: "
<< "Create generated scope " << use_name << endl;
NetScope*scope = new NetScope(container, use_name,
NetScope::GENBLOCK);
scope->set_line(get_file(), get_lineno());
// Set in the scope a localparam for the value of the
// genvar within this instance of the generate
// block. Code within this scope thus has access to the
// genvar as a constant.
{
verinum genvar_verinum(genvar);
genvar_verinum.has_sign(true);
NetEConstParam*gp = new NetEConstParam(scope,
loop_index,
genvar_verinum);
// The file and line information should really come
// from the genvar statement, not the for loop.
scope->set_localparam(loop_index, gp, *this);
if (debug_scopes)
cerr << get_fileline() << ": debug: "
<< "Create implicit localparam "
<< loop_index << " = " << genvar_verinum << endl;
}
elaborate_subscope_(des, scope);
// Calculate the step for the loop variable.
NetExpr*step_ex = elab_and_eval(des, container, loop_step, -1);
NetEConst*step = dynamic_cast<NetEConst*>(step_ex);
assert(step);
if (debug_scopes)
cerr << get_fileline() << ": debug: genvar step from "
<< genvar << " to " << step->value().as_long() << endl;
genvar = step->value().as_long();
container->genvar_tmp_val = genvar;
delete step;
delete test_ex;
test_ex = elab_and_eval(des, container, loop_test, -1);
test = dynamic_cast<NetEConst*>(test_ex);
assert(test);
}
// Clear the genvar_tmp field in the scope to reflect that the
// genvar is no longer value for evaluating expressions.
container->genvar_tmp = perm_string();
return true;
}
bool PGenerate::generate_scope_condit_(Design*des, NetScope*container, bool else_flag)
{
NetExpr*test_ex = elab_and_eval(des, container, loop_test, -1);
NetEConst*test = dynamic_cast<NetEConst*> (test_ex);
assert(test);
// If the condition evaluates as false, then do not create the
// scope.
if ( (test->value().as_long() == 0 && !else_flag)
|| (test->value().as_long() != 0 && else_flag) ) {
if (debug_scopes)
cerr << get_fileline() << ": debug: Generate condition "
<< (else_flag? "(else)" : "(if)")
<< " value=" << test->value() << ": skip generation"
<< endl;
delete test_ex;
return true;
}
hname_t use_name (scope_name);
if (container->child(use_name)) {
cerr << get_fileline() << ": error: block/scope name "
<< scope_name << " already used in this context."
<< endl;
des->errors += 1;
return false;
}
if (debug_scopes)
cerr << get_fileline() << ": debug: Generate condition "
<< (else_flag? "(else)" : "(if)")
<< " value=" << test->value() << ": Generate scope="
<< use_name << endl;
NetScope*scope = new NetScope(container, use_name,
NetScope::GENBLOCK);
scope->set_line(get_file(), get_lineno());
elaborate_subscope_(des, scope);
return true;
}
bool PGenerate::generate_scope_case_(Design*des, NetScope*container)
{
NetExpr*case_value_ex = elab_and_eval(des, container, loop_test, -1);
NetEConst*case_value_co = dynamic_cast<NetEConst*>(case_value_ex);
assert(case_value_co);
// The name of the scope to generate, whatever that item is.
hname_t use_name (scope_name);
if (debug_scopes)
cerr << get_fileline() << ": debug: Generate case "
<< "switch value=" << case_value_co->value() << endl;
PGenerate*default_item = 0;
typedef list<PGenerate*>::const_iterator generator_it_t;
generator_it_t cur = generates.begin();
while (cur != generates.end()) {
PGenerate*item = *cur;
assert( item->scheme_type == PGenerate::GS_CASE_ITEM );
// Detect that the item is a default.
if (item->loop_test == 0) {
default_item = item;
cur ++;
continue;
}
NetExpr*item_value_ex = elab_and_eval(des, container, item->loop_test, -1);
NetEConst*item_value_co = dynamic_cast<NetEConst*>(item_value_ex);
assert(item_value_co);
// If we stumble on the item that matches, then break
// out now.
if (case_value_co->value() == item_value_co->value()) {
delete item_value_co;
break;
}
delete item_value_co;
cur ++;
}
delete case_value_co;
case_value_co = 0;
PGenerate*item = (cur == generates.end())? default_item : *cur;
if (item == 0) {
cerr << get_fileline() << ": debug: "
<< "No generate items found" << endl;
return true;
}
if (debug_scopes)
cerr << get_fileline() << ": debug: "
<< "Generate case matches item at "
<< item->get_fileline() << endl;
NetScope*scope = new NetScope(container, use_name,
NetScope::GENBLOCK);
scope->set_line(get_file(), get_lineno());
item->elaborate_subscope_(des, scope);
return true;
}
void PGenerate::elaborate_subscope_(Design*des, NetScope*scope)
{
// Scan the generated scope for nested generate schemes,
// and *generate* new scopes, which is slightly different
// from simple elaboration.
typedef list<PGenerate*>::const_iterator generate_it_t;
for (generate_it_t cur = generates.begin()
; cur != generates.end() ; cur ++ ) {
(*cur) -> generate_scope(des, scope);
}
// Scan the generated scope for gates that may create
// their own scopes.
typedef list<PGate*>::const_iterator pgate_list_it_t;
for (pgate_list_it_t cur = gates.begin()
; cur != gates.end() ; cur ++) {
(*cur) ->elaborate_scope(des, scope);
}
// Save the scope that we created, for future use.
scope_list_.push_back(scope);
}
void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const
{
if (get_name() == "") {
cerr << get_fileline() << ": error: Instantiation of module "
cerr << get_line() << ": error: Instantiation of module "
<< mod->mod_name() << " requires an instance name." << endl;
des->errors += 1;
return;
@@ -638,8 +278,8 @@ void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const
// about to create, and if I find it then somebody beat me to
// it.
if (sc->child(hname_t(get_name()))) {
cerr << get_fileline() << ": error: Instance/Scope name " <<
if (sc->child(get_name())) {
cerr << get_line() << ": error: Instance/Scope name " <<
get_name() << " already used in this context." <<
endl;
des->errors += 1;
@@ -657,21 +297,19 @@ void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const
if (strcmp(mod->mod_name(), scn->module_name()) != 0)
continue;
cerr << get_fileline() << ": error: You cannot instantiate "
cerr << get_line() << ": error: You cannot instantiate "
<< "module " << mod->mod_name() << " within itself." << endl;
cerr << get_fileline() << ": : The offending instance is "
<< scope_path(sc) << "." << get_name() << " within "
<< scope_path(scn) << "." << endl;
cerr << get_line() << ": : The offending instance is "
<< sc->name() << "." << get_name() << " within "
<< scn->name() << "." << endl;
des->errors += 1;
return;
}
NetExpr*mse = msb_ ? elab_and_eval(des, sc, msb_, -1) : 0;
NetExpr*lse = lsb_ ? elab_and_eval(des, sc, lsb_, -1) : 0;
NetEConst*msb = dynamic_cast<NetEConst*> (mse);
NetEConst*lsb = dynamic_cast<NetEConst*> (lse);
verinum*msb = msb_ ? msb_->eval_const(des, sc) : 0;
verinum*lsb = lsb_ ? lsb_->eval_const(des, sc) : 0;
assert( (msb == 0) || (lsb != 0) );
@@ -682,20 +320,17 @@ void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const
if (msb) {
instance_array = true;
instance_high = msb->value().as_long();
instance_low = lsb->value().as_long();
instance_high = msb->as_long();
instance_low = lsb->as_long();
if (instance_high > instance_low)
instance_count = instance_high - instance_low + 1;
else
instance_count = instance_low - instance_high + 1;
delete mse;
delete lse;
}
NetScope::scope_vec_t instances (instance_count);
if (debug_scopes) {
cerr << get_fileline() << ": debug: Create " << instance_count
cerr << get_line() << ": debug: Create " << instance_count
<< " instances of " << get_name()
<< "." << endl;
}
@@ -705,28 +340,29 @@ void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const
// instantiation line.
for (int idx = 0 ; idx < instance_count ; idx += 1) {
hname_t use_name (get_name());
perm_string use_name = get_name();
if (instance_array) {
char name_buf[128];
int instance_idx = idx;
if (instance_low < instance_high)
instance_idx = instance_low + idx;
else
instance_idx = instance_low - idx;
use_name = hname_t(get_name(), instance_idx);
snprintf(name_buf, sizeof name_buf,
"%s[%d]", get_name().str(), instance_idx);
use_name = lex_strings.make(name_buf);
}
if (debug_scopes) {
cerr << get_fileline() << ": debug: Module instance " << use_name
<< " becomes child of " << scope_path(sc)
cerr << get_line() << ": debug: Module instance " << use_name
<< " becomes child of " << sc->name()
<< "." << endl;
}
// Create the new scope as a MODULE with my name.
NetScope*my_scope = new NetScope(sc, use_name, NetScope::MODULE);
my_scope->set_line(get_file(), mod->get_file(),
get_lineno(), mod->get_lineno());
my_scope->set_module_name(mod->mod_name());
my_scope->default_nettype(mod->default_nettype);
@@ -737,6 +373,13 @@ void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const
my_scope->time_precision(mod->time_precision);
des->set_precision(mod->time_precision);
// This call actually arranges for the description of the
// module type to process this instance and handle parameters
// and sub-scopes that might occur. Parameters are also
// created in that scope, as they exist. (I'll override them
// later.)
mod->elaborate_scope(des, my_scope);
// Look for module parameter replacements. The "replace" map
// maps parameter name to replacement expression that is
// passed. It is built up by the ordered overrides or named
@@ -779,8 +422,6 @@ void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const
}
Module::replace_t replace_net;
// And here we scan the replacements we collected. Elaborate
// the expression in my context, then replace the sub-scope
// parameter value with the new expression.
@@ -791,19 +432,15 @@ void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const
PExpr*tmp = (*cur).second;
// No expression means that the parameter is not
// replaced at all.
if (tmp == 0)
continue;
if (tmp == 0) continue;
NetExpr*val = tmp->elaborate_pexpr(des, sc);
replace_net[(*cur).first] = val;
bool flag = my_scope->replace_parameter((*cur).first, val);
if (! flag) {
cerr << val->get_line() << ": warning: parameter "
<< (*cur).first << " not found in "
<< sc->name() << "." << endl;
}
}
// This call actually arranges for the description of the
// module type to process this instance and handle parameters
// and sub-scopes that might occur. Parameters are also
// created in that scope, as they exist. (I'll override them
// later.)
mod->elaborate_scope(des, my_scope, replace_net);
}
/* Stash the instance array of scopes into the parent
@@ -816,6 +453,34 @@ void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const
sc->instance_arrays[get_name()] = instances;
}
/*
* Elaborate the datum within the module. This variable may be
* within a subscope (i.e., a function or task) so use the components
* of the name to find the precise scope where this item goes.
*/
void PData::elaborate_scope(Design*des, NetScope*scope) const
{
NetScope*sub_scope = scope;
for (unsigned idx = 0 ; idx < (hname_.component_count()-1); idx += 1) {
sub_scope = sub_scope->child(hname_.peek_name(idx));
if (sub_scope == 0) {
cerr << get_line() << ": internal error: "
<< "Could not find sub-scope "
<< hname_.peek_name(idx) << " of "
<< hname_ << " in module " << scope->name()
<< endl;
des->errors += 1;
return;
}
}
const char*basename = hname_.peek_tail_name();
NetVariable*tmp = new NetVariable(lex_strings.make(basename));
tmp->set_line(*this);
sub_scope->add_variable(tmp);
}
/*
* The isn't really able to create new scopes, but it does create the
* event name in the current scope, so can be done during the
@@ -865,19 +530,10 @@ void PBlock::elaborate_scope(Design*des, NetScope*scope) const
{
NetScope*my_scope = scope;
if (pscope_name() != 0) {
hname_t use_name(pscope_name());
if (scope->child(use_name)) {
cerr << get_fileline() << ": error: block/scope name "
<< use_name << " already used in this context."
<< endl;
des->errors += 1;
return;
}
my_scope = new NetScope(scope, use_name, bl_type_==BL_PAR
if (name_ != 0) {
my_scope = new NetScope(scope, name_, bl_type_==BL_PAR
? NetScope::FORK_JOIN
: NetScope::BEGIN_END);
my_scope->set_line(get_file(), get_lineno());
}
for (unsigned idx = 0 ; idx < list_.count() ; idx += 1)
+276 -682
View File
File diff suppressed because it is too large Load Diff
+617 -1519
View File
File diff suppressed because it is too large Load Diff
+67 -86
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998-2008 Stephen Williams (steve@icarus.com)
* Copyright (c) 1998-2010 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -49,29 +49,24 @@ bool NetUDP::emit_node(struct target_t*tgt) const
return true;
}
bool NetAbs::emit_node(struct target_t*tgt) const
{
tgt->lpm_abs(this);
return true;
}
bool NetAddSub::emit_node(struct target_t*tgt) const
{
tgt->lpm_add_sub(this);
return true;
}
bool NetArrayDq::emit_node(struct target_t*tgt) const
{
return tgt->lpm_array_dq(this);
}
bool NetCaseCmp::emit_node(struct target_t*tgt) const
{
tgt->net_case_cmp(this);
return true;
}
bool NetCAssign::emit_node(struct target_t*tgt) const
{
tgt->net_cassign(this);
return true;
}
bool NetCLShift::emit_node(struct target_t*tgt) const
{
tgt->lpm_clshift(this);
@@ -84,16 +79,21 @@ bool NetCompare::emit_node(struct target_t*tgt) const
return true;
}
bool NetConcat::emit_node(struct target_t*tgt) const
{
return tgt->concat(this);
}
bool NetConst::emit_node(struct target_t*tgt) const
{
return tgt->net_const(this);
}
bool NetDecode::emit_node(struct target_t*tgt) const
{
return tgt->lpm_decode(this);
}
bool NetDemux::emit_node(struct target_t*tgt) const
{
return tgt->lpm_demux(this);
}
bool NetDivide::emit_node(struct target_t*tgt) const
{
tgt->lpm_divide(this);
@@ -106,9 +106,16 @@ bool NetFF::emit_node(struct target_t*tgt) const
return true;
}
bool NetLiteral::emit_node(struct target_t*tgt) const
bool NetForce::emit_node(struct target_t*tgt) const
{
return tgt->net_literal(this);
tgt->net_force(this);
return true;
}
bool NetLatch::emit_node(struct target_t*tgt) const
{
tgt->lpm_latch(this);
return true;
}
bool NetModulo::emit_node(struct target_t*tgt) const
@@ -129,47 +136,17 @@ bool NetMux::emit_node(struct target_t*tgt) const
return true;
}
bool NetPartSelect::emit_node(struct target_t*tgt) const
bool NetRamDq::emit_node(struct target_t*tgt) const
{
return tgt->part_select(this);
}
bool NetPow::emit_node(struct target_t*tgt) const
{
tgt->lpm_pow(this);
tgt->lpm_ram_dq(this);
return true;
}
bool NetReplicate::emit_node(struct target_t*tgt) const
{
return tgt->replicate(this);
}
bool NetSignExtend::emit_node(struct target_t*tgt) const
{
return tgt->sign_extend(this);
}
bool NetUReduce::emit_node(struct target_t*tgt) const
{
return tgt->ureduce(this);
}
bool NetSysFunc::emit_node(struct target_t*tgt) const
{
return tgt->net_sysfunction(this);
}
bool NetUserFunc::emit_node(struct target_t*tgt) const
{
return tgt->net_function(this);
}
bool NetTran::emit_node(struct target_t*tgt) const
{
return tgt->tran(this);
}
bool NetBUFZ::emit_node(struct target_t*tgt) const
{
return tgt->bufz(this);
@@ -349,6 +326,9 @@ void NetScope::emit_scope(struct target_t*tgt) const
for (NetEvent*cur = events_ ; cur ; cur = cur->snext_)
tgt->event(cur);
for (NetVariable*cur = vars_ ; cur ; cur = cur->snext_)
tgt->variable(cur);
for (NetScope*cur = sub_ ; cur ; cur = cur->sib_)
cur->emit_scope(tgt);
@@ -358,19 +338,15 @@ void NetScope::emit_scope(struct target_t*tgt) const
tgt->signal(cur);
cur = cur->sig_next_;
} while (cur != signals_->sig_next_);
/* Run the signals again, but this time to connect the
delay paths. This is done as a second pass because
the paths reference other signals that may be later
in the list. We can do it here becase delay paths are
always connected within the scope. */
cur = signals_->sig_next_;
do {
tgt->signal_paths(cur);
cur = cur->sig_next_;
} while (cur != signals_->sig_next_);
}
if (memories_) {
NetMemory*cur = memories_->snext_;
do {
tgt->memory(cur);
cur = cur->snext_;
} while (cur != memories_->snext_);
}
}
bool NetScope::emit_defs(struct target_t*tgt) const
@@ -389,9 +365,7 @@ bool NetScope::emit_defs(struct target_t*tgt) const
case TASK:
tgt->task_def(this);
break;
default: /* BEGIN_END and FORK_JOIN, GENERATE... */
for (NetScope*cur = sub_ ; cur ; cur = cur->sib_)
flag &= cur->emit_defs(tgt);
default: /* BEGIN_END and FORK_JOIN, do nothing */
break;
}
@@ -403,12 +377,13 @@ void NetWhile::emit_proc_recurse(struct target_t*tgt) const
proc_->emit_proc(tgt);
}
int Design::emit(struct target_t*tgt) const
bool Design::emit(struct target_t*tgt) const
{
int rc = 0;
bool rc = true;
if (tgt->start_design(this) == false)
return -2;
rc = rc && tgt->start_design(this);
if (rc == false)
return false;
// enumerate the scopes
for (list<NetScope*>::const_iterator scope = root_scopes_.begin();
@@ -417,36 +392,27 @@ int Design::emit(struct target_t*tgt) const
// emit nodes
bool nodes_rc = true;
if (nodes_) {
NetNode*cur = nodes_->node_next_;
do {
nodes_rc = nodes_rc && cur->emit_node(tgt);
rc = rc && cur->emit_node(tgt);
cur = cur->node_next_;
} while (cur != nodes_->node_next_);
}
// emit task and function definitions
bool tasks_rc = true;
for (list<NetScope*>::const_iterator scope = root_scopes_.begin();
scope != root_scopes_.end(); scope++)
tasks_rc &= (*scope)->emit_defs(tgt);
rc &= (*scope)->emit_defs(tgt);
// emit the processes
bool proc_rc = true;
for (const NetProcTop*idx = procs_ ; idx ; idx = idx->next_)
proc_rc &= idx->emit(tgt);
rc = rc && idx->emit(tgt);
rc = tgt->end_design(this);
if (nodes_rc == false)
return -1;
if (tasks_rc == false)
return -2;
if (proc_rc == false)
return -3;
if (tgt->end_design(this) != 0)
rc = false;
return rc;
}
@@ -481,9 +447,14 @@ void NetECRealParam::expr_scan(struct expr_scan_t*tgt) const
tgt->expr_rparam(this);
}
void NetEMemory::expr_scan(struct expr_scan_t*tgt) const
{
tgt->expr_memory(this);
}
void NetEParam::expr_scan(struct expr_scan_t*tgt) const
{
cerr << get_fileline() << ":internal error: unexpected NetEParam."
cerr << get_line() << ":internal error: unexpected NetEParam."
<< endl;
}
@@ -517,6 +488,11 @@ void NetESignal::expr_scan(struct expr_scan_t*tgt) const
tgt->expr_signal(this);
}
void NetEBitSel::expr_scan(struct expr_scan_t*tgt) const
{
tgt->expr_subsignal(this);
}
void NetETernary::expr_scan(struct expr_scan_t*tgt) const
{
tgt->expr_ternary(this);
@@ -527,7 +503,12 @@ void NetEUnary::expr_scan(struct expr_scan_t*tgt) const
tgt->expr_unary(this);
}
int emit(const Design*des, const char*type)
void NetEVariable::expr_scan(struct expr_scan_t*tgt) const
{
tgt->expr_variable(this);
}
bool emit(const Design*des, const char*type)
{
for (unsigned idx = 0 ; target_table[idx] ; idx += 1) {
const struct target*tgt = target_table[idx];
@@ -538,5 +519,5 @@ int emit(const Design*des, const char*type)
cerr << "error: Code generator type " << type
<< " not found." << endl;
return -1;
return false;
}
+20 -33
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998-1999 Stephen Williams (steve@icarus.com)
* Copyright (c) 1998-2010 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -19,20 +19,18 @@
# include "config.h"
# include <cstring>
# include <iostream>
# include "PExpr.h"
# include "netlist.h"
# include "netmisc.h"
# include "compiler.h"
verinum* PExpr::eval_const(Design*, NetScope*) const
verinum* PExpr::eval_const(const Design*, const NetScope*) const
{
return 0;
}
verinum* PEBinary::eval_const(Design*des, NetScope*scope) const
verinum* PEBinary::eval_const(const Design*des, const NetScope*scope) const
{
verinum*l = left_->eval_const(des, scope);
if (l == 0) return 0;
@@ -111,7 +109,10 @@ verinum* PEBinary::eval_const(Design*des, NetScope*scope) const
case 'l': { // left shift (<<)
assert(r->is_defined());
unsigned long rv = r->as_ulong();
res = new verinum(verinum::V0, l->len());
unsigned use_wid = l->len();
if (! l->has_len())
use_wid += rv;
res = new verinum(verinum::V0, use_wid);
if (rv < res->len()) {
unsigned cnt = res->len() - rv;
for (unsigned idx = 0 ; idx < cnt ; idx += 1)
@@ -141,15 +142,16 @@ verinum* PEBinary::eval_const(Design*des, NetScope*scope) const
delete r;
return res;
}
verinum* PEConcat::eval_const(Design*des, NetScope*scope) const
verinum* PEConcat::eval_const(const Design*des, const NetScope*scope) const
{
verinum*accum = parms_[0]->eval_const(des, scope);
if (accum == 0)
return 0;
for (unsigned idx = 1 ; idx < parms_.count() ; idx += 1) {
verinum*tmp = parms_[idx]->eval_const(des, scope);
/* Oops, found an argument that is not constant. Give up. */
if (tmp == 0) {
delete accum;
return 0;
@@ -163,36 +165,21 @@ verinum* PEConcat::eval_const(Design*des, NetScope*scope) const
return accum;
}
/*
* Evaluate an identifier as a constant expression. This is only
* possible if the identifier is that of a parameter.
*/
verinum* PEIdent::eval_const(Design*des, NetScope*scope) const
verinum* PEIdent::eval_const(const Design*des, const NetScope*scope) const
{
assert(scope);
NetNet*net;
NetEvent*eve;
const NetExpr*expr;
const name_component_t&name_tail = path_.back();
// Handle the special case that this ident is a genvar
// variable name. In that case, the genvar meaning preempts
// everything and we just return that value immediately.
if (scope->genvar_tmp
&& strcmp(name_tail.name,scope->genvar_tmp) == 0) {
return new verinum(scope->genvar_tmp_val);
}
symbol_search(des, scope, path_, net, expr, eve);
const NetExpr*expr = des->find_parameter(scope, path_);
if (expr == 0)
return 0;
const NetEConst*eval = dynamic_cast<const NetEConst*>(expr);
if (eval == 0) {
cerr << get_fileline() << ": internal error: Unable to evaluate "
cerr << get_line() << ": internal error: Unable to evaluate "
<< "constant expression (parameter=" << path_
<< "): " << *expr << endl;
return 0;
@@ -200,30 +187,30 @@ verinum* PEIdent::eval_const(Design*des, NetScope*scope) const
assert(eval);
if (!name_tail.index.empty())
if (msb_ || lsb_)
return 0;
return new verinum(eval->value());
}
verinum* PEFNumber::eval_const(Design*, NetScope*) const
verinum* PEFNumber::eval_const(const Design*, const NetScope*) const
{
long val = value_->as_long();
return new verinum(val);
}
verinum* PENumber::eval_const(Design*, NetScope*) const
verinum* PENumber::eval_const(const Design*, const NetScope*) const
{
return new verinum(value());
}
verinum* PEString::eval_const(Design*, NetScope*) const
verinum* PEString::eval_const(const Design*, const NetScope*) const
{
return new verinum(string(text_));
}
verinum* PETernary::eval_const(Design*des, NetScope*scope) const
verinum* PETernary::eval_const(const Design*des, const NetScope*scope) const
{
verinum*test = expr_->eval_const(des, scope);
if (test == 0)
@@ -243,7 +230,7 @@ verinum* PETernary::eval_const(Design*des, NetScope*scope) const
}
}
verinum* PEUnary::eval_const(Design*des, NetScope*scope) const
verinum* PEUnary::eval_const(const Design*des, const NetScope*scope) const
{
verinum*val = expr_->eval_const(des, scope);
if (val == 0)
@@ -257,7 +244,7 @@ verinum* PEUnary::eval_const(Design*des, NetScope*scope) const
/* We need to expand the value a bit if we are
taking the 2's complement so that we are
guaranteed to not overflow. */
verinum tmp ((uint64_t)0, val->len()+1);
verinum tmp (0UL, val->len()+1);
for (unsigned idx = 0 ; idx < val->len() ; idx += 1)
tmp.set(idx, val->get(idx));
+3 -42
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2004 Stephen Williams (steve@icarus.com)
* Copyright (c) 2002-2010 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -16,9 +16,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: eval_attrib.cc,v 1.9 2007/06/04 19:14:06 steve Exp $"
#endif
# include "config.h"
# include "util.h"
@@ -35,7 +32,8 @@
attrib_list_t* evaluate_attributes(const map<perm_string,PExpr*>&att,
unsigned&natt,
Design*des, NetScope*scope)
const Design*des,
const NetScope*scope)
{
natt = att.size();
if (natt == 0)
@@ -70,40 +68,3 @@ attrib_list_t* evaluate_attributes(const map<perm_string,PExpr*>&att,
assert(idx == natt);
return table;
}
/*
* $Log: eval_attrib.cc,v $
* Revision 1.9 2007/06/04 19:14:06 steve
* Build errors in picky GCC compilers.
*
* Revision 1.8 2005/11/27 17:01:57 steve
* Fix for stubborn compiler.
*
* Revision 1.7 2004/02/20 18:53:35 steve
* Addtrbute keys are perm_strings.
*
* Revision 1.6 2003/01/27 05:09:17 steve
* Spelling fixes.
*
* Revision 1.5 2002/08/12 01:34:59 steve
* conditional ident string using autoconfig.
*
* Revision 1.4 2002/08/10 21:59:39 steve
* The default attribute value is 1.
*
* Revision 1.3 2002/06/06 18:57:18 steve
* Use standard name for iostream.
*
* Revision 1.2 2002/06/03 03:55:14 steve
* compile warnings.
*
* Revision 1.1 2002/05/23 03:08:51 steve
* Add language support for Verilog-2001 attribute
* syntax. Hook this support into existing $attribute
* handling, and add number and void value types.
*
* Add to the ivl_target API new functions for access
* of complex attributes attached to gates.
*
*/
+578 -622
View File
File diff suppressed because it is too large Load Diff
-3
View File
@@ -1,3 +0,0 @@
,*
hello_vpi.vpi
show_vcd.vcd
+63 -63
View File
@@ -162,11 +162,11 @@ end
endmodule
module des(pt, key, ct, clk);
input [1:64] pt;
input [1:64] key;
output [1:64] ct;
input clk;
wire [1:48] k1x,k2x,k3x,k4x,k5x,k6x,k7x,k8x,k9x,k10x,k11x,k12x,k13x,k14x,k15x,k16x;
input [1:64] pt;
input [1:64] key;
output [1:64] ct;
input clk;
wire [1:48] k1x,k2x,k3x,k4x,k5x,k6x,k7x,k8x,k9x,k10x,k11x,k12x,k13x,k14x,k15x,k16x;
wire [1:32] l0x,l1x,l2x,l3x,l4x,l5x,l6x,l7x,l8x,l9x,l10x,l11x,l12x,l13x,l14x,l15x,l16x;
wire [1:32] r0x,r1x,r2x,r3x,r4x,r5x,r6x,r7x,r8x,r9x,r10x,r11x,r12x,r13x,r14x,r15x,r16x;
@@ -194,9 +194,9 @@ endmodule
module pc1(key, c0x, d0x);
input [1:64] key;
output [1:28] c0x, d0x;
wire [1:56] XX;
input [1:64] key;
output [1:28] c0x, d0x;
wire [1:56] XX;
assign XX[1]=key[57]; assign XX[2]=key[49]; assign XX[3]=key[41]; assign XX[4]=key[33]; assign XX[5]=key[25]; assign XX[6]=key[17]; assign XX[7]=key[9];
assign XX[8]=key[1]; assign XX[9]=key[58]; assign XX[10]=key[50]; assign XX[11]=key[42]; assign XX[12]=key[34]; assign XX[13]=key[26]; assign XX[14]=key[18];
@@ -213,9 +213,9 @@ endmodule
module pc2(c,d,k);
input [1:28] c,d;
output [1:48] k;
wire [1:56] YY;
input [1:28] c,d;
output [1:48] k;
wire [1:56] YY;
assign YY[1:28]=c; assign YY[29:56]=d;
@@ -231,7 +231,7 @@ endmodule
module rol1(o, i);
output [1:28] o;
output [1:28] o;
input [1:28] i;
assign o={i[2:28],i[1]};
@@ -240,7 +240,7 @@ endmodule
module rol2(o, i);
output [1:28] o;
output [1:28] o;
input [1:28] i;
assign o={i[3:28],i[1:2]};
@@ -248,10 +248,10 @@ endmodule
module keysched(key,k1x,k2x,k3x,k4x,k5x,k6x,k7x,k8x,k9x,k10x,k11x,k12x,k13x,k14x,k15x,k16x);
input [1:64] key;
output [1:48] k1x,k2x,k3x,k4x,k5x,k6x,k7x,k8x,k9x,k10x,k11x,k12x,k13x,k14x,k15x,k16x;
wire [1:28] c0x,c1x,c2x,c3x,c4x,c5x,c6x,c7x,c8x,c9x,c10x,c11x,c12x,c13x,c14x,c15x,c16x;
wire [1:28] d0x,d1x,d2x,d3x,d4x,d5x,d6x,d7x,d8x,d9x,d10x,d11x,d12x,d13x,d14x,d15x,d16x;
input [1:64] key;
output [1:48] k1x,k2x,k3x,k4x,k5x,k6x,k7x,k8x,k9x,k10x,k11x,k12x,k13x,k14x,k15x,k16x;
wire [1:28] c0x,c1x,c2x,c3x,c4x,c5x,c6x,c7x,c8x,c9x,c10x,c11x,c12x,c13x,c14x,c15x,c16x;
wire [1:28] d0x,d1x,d2x,d3x,d4x,d5x,d6x,d7x,d8x,d9x,d10x,d11x,d12x,d13x,d14x,d15x,d16x;
pc1 pc1(key, c0x, d0x);
@@ -294,10 +294,10 @@ endmodule
module s1(clk, b, so);
input clk;
input [1:6] b;
output [1:4] so;
reg [1:4] so;
input clk;
input [1:6] b;
output [1:4] so;
reg [1:4] so;
always @(posedge clk)
casex(b)
@@ -370,10 +370,10 @@ endmodule
module s2(clk, b, so);
input clk;
input [1:6] b;
output [1:4] so;
reg [1:4] so;
input clk;
input [1:6] b;
output [1:4] so;
reg [1:4] so;
always @(posedge clk)
casex(b)
@@ -446,10 +446,10 @@ endmodule
module s3(clk, b, so);
input clk;
input [1:6] b;
output [1:4] so;
reg [1:4] so;
input clk;
input [1:6] b;
output [1:4] so;
reg [1:4] so;
always @(posedge clk)
casex(b)
@@ -522,10 +522,10 @@ endmodule
module s4(clk, b, so);
input clk;
input [1:6] b;
output [1:4] so;
reg [1:4] so;
input clk;
input [1:6] b;
output [1:4] so;
reg [1:4] so;
always @(posedge clk)
casex(b)
@@ -598,10 +598,10 @@ endmodule
module s5(clk, b, so);
input clk;
input [1:6] b;
output [1:4] so;
reg [1:4] so;
input clk;
input [1:6] b;
output [1:4] so;
reg [1:4] so;
always @(posedge clk)
casex(b)
@@ -674,10 +674,10 @@ endmodule
module s6(clk, b, so);
input clk;
input [1:6] b;
output [1:4] so;
reg [1:4] so;
input clk;
input [1:6] b;
output [1:4] so;
reg [1:4] so;
always @(posedge clk)
casex(b)
@@ -750,10 +750,10 @@ endmodule
module s7(clk, b, so);
input clk;
input [1:6] b;
output [1:4] so;
reg [1:4] so;
input clk;
input [1:6] b;
output [1:4] so;
reg [1:4] so;
always @(posedge clk)
casex(b)
@@ -826,10 +826,10 @@ endmodule
module s8(clk, b, so);
input clk;
input [1:6] b;
output [1:4] so;
reg [1:4] so;
input clk;
input [1:6] b;
output [1:4] so;
reg [1:4] so;
always @(posedge clk)
casex(b)
@@ -902,8 +902,8 @@ endmodule
module ip(pt, l0x, r0x);
input [1:64] pt;
output [1:32] l0x, r0x;
input [1:64] pt;
output [1:32] l0x, r0x;
assign l0x[1]=pt[58]; assign l0x[2]=pt[50]; assign l0x[3]=pt[42]; assign l0x[4]=pt[34];
assign l0x[5]=pt[26]; assign l0x[6]=pt[18]; assign l0x[7]=pt[10]; assign l0x[8]=pt[2];
@@ -941,10 +941,10 @@ endmodule
module desxor1(e,b1x,b2x,b3x,b4x,b5x,b6x,b7x,b8x,k);
input [1:48] e;
output [1:6] b1x,b2x,b3x,b4x,b5x,b6x,b7x,b8x;
input [1:48] k;
wire [1:48] XX;
input [1:48] e;
output [1:6] b1x,b2x,b3x,b4x,b5x,b6x,b7x,b8x;
input [1:48] k;
wire [1:48] XX;
assign XX = k ^ e;
assign b1x = XX[1:6];
@@ -960,9 +960,9 @@ endmodule
module pp(so1x,so2x,so3x,so4x,so5x,so6x,so7x,so8x,ppo);
input [1:4] so1x,so2x,so3x,so4x,so5x,so6x,so7x,so8x;
output [1:32] ppo;
wire [1:32] XX;
input [1:4] so1x,so2x,so3x,so4x,so5x,so6x,so7x,so8x;
output [1:32] ppo;
wire [1:32] XX;
assign XX[1:4]=so1x; assign XX[5:8]=so2x; assign XX[9:12]=so3x; assign XX[13:16]=so4x;
assign XX[17:20]=so5x; assign XX[21:24]=so6x; assign XX[25:28]=so7x; assign XX[29:32]=so8x;
@@ -980,8 +980,8 @@ endmodule
module desxor2(d,l,q);
input [1:32] d,l;
output [1:32] q;
input [1:32] d,l;
output [1:32] q;
assign q = d ^ l;
@@ -994,10 +994,10 @@ input [1:32] li, ri;
input [1:48] k;
output [1:32] lo, ro;
wire [1:48] e;
wire [1:48] e;
wire [1:6] b1x,b2x,b3x,b4x,b5x,b6x,b7x,b8x;
wire [1:4] so1x,so2x,so3x,so4x,so5x,so6x,so7x,so8x;
wire [1:32] ppo;
wire [1:32] ppo;
xp xp(ri, e);
desxor1 desxor1(e, b1x, b2x, b3x, b4x, b5x, b6x, b7x, b8x, k);
@@ -1018,7 +1018,7 @@ endmodule
module fp(l,r,ct);
input [1:32] l,r;
input [1:32] l,r;
output [1:64] ct;
assign ct[1]=r[8]; assign ct[2]=l[8]; assign ct[3]=r[16]; assign ct[4]=l[16]; assign ct[5]=r[24]; assign ct[6]=l[24]; assign ct[7]=r[32]; assign ct[8]=l[32];
+2 -8
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: hello_vpi.c,v 1.5 2007/01/17 05:35:48 steve Exp $"
#ident "$Id: hello_vpi.c,v 1.3 2002/08/12 01:35:01 steve Exp $"
#endif
/*
@@ -33,7 +33,7 @@
# include <vpi_user.h>
static PLI_INT32 my_hello_calltf(char *xx)
static int my_hello_calltf(char *xx)
{
vpi_printf("Hello World, from VPI.\n");
return 0;
@@ -62,12 +62,6 @@ void (*vlog_startup_routines[])() = {
};
/*
* $Log: hello_vpi.c,v $
* Revision 1.5 2007/01/17 05:35:48 steve
* Fix typo is hello_vpi.c example.
*
* Revision 1.4 2006/10/30 22:46:25 steve
* Updates for Cygwin portability (pr1585922)
*
* Revision 1.3 2002/08/12 01:35:01 steve
* conditional ident string using autoconfig.
*
+4 -4
View File
@@ -55,12 +55,12 @@
module register (out, val, clk, oe);
output [7:0] out;
input [7:0] val;
input clk, oe;
input [7:0] val;
input clk, oe;
reg [7:0] Q;
reg [7:0] Q;
wire [7:0] out;
wire [7:0] out;
bufif0 drv[7:0](out, Q, oe);
+6 -6
View File
@@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
* $Id: sqrt-virtex.v,v 1.5 2007/03/22 16:08:18 steve Exp $"
* $Id: sqrt-virtex.v,v 1.4.2.2 2005/02/23 18:37:52 steve Exp $"
*/
/*
@@ -130,7 +130,7 @@
* contains Verilog code that simulates the mapped design. This output
* Verilog has the single root module "chip_root", which came from the
* name of the root module when we were making the EDIF file in the
* first place. The module has ports named just line the ports of the
* first place. The module has ports named just like the ports of the
* chip_root module below.
*
* The generated Verilog uses the library in the directory
@@ -154,7 +154,7 @@
*
* The POST_MAP compiler directive causes the GSR manipulations
* included in the test bench to be compiled in, to simulate the chip
* startup. Other then that, the test bench runs the post-map design
* startup. Other than that, the test bench runs the post-map design
* the same way the pre-synthesis design works.
*
* Run this design with the command:
@@ -183,7 +183,7 @@
* where sqrt(y) is the exact square root of y and floor(N) is the
* largest integer <= N.
*
* For 32 bit numbers, this will never run more than 16 iterations,
* For 32bit numbers, this will never run more than 16 iterations,
* which amounts to 16 clocks.
*/
@@ -252,7 +252,7 @@ endmodule // sqrt32
module main;
reg [31:0] x;
reg clk, reset;
reg clk, reset;
wire [15:0] y;
wire rdy;
@@ -354,7 +354,7 @@ module chip_root(clk, rdy, reset, x, y);
input [31:0] x;
output [15:0] y;
wire clk_int;
wire clk_int;
(* cellref="BUFG:O,I" *)
buf gbuf (clk_int, clk);
+2 -2
View File
@@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
* $Id: sqrt.vl,v 1.5 2007/03/22 16:08:18 steve Exp $"
* $Id: sqrt.vl,v 1.4 2004/10/04 01:10:56 steve Exp $"
*/
/*
@@ -50,7 +50,7 @@
* where sqrt(y) is the exact square root of y and floor(N) is the
* largest integer <= N.
*
* For 32 bit numbers, this will never run more than 16 iterations,
* For 32bit numbers, this will never run more than 16 iterations,
* which amounts to 16 clocks.
*/
+589 -607
View File
File diff suppressed because it is too large Load Diff
-84
View File
@@ -1,84 +0,0 @@
Icarus Verilog Extensions
Icarus Verilog supports certain extensions to the baseline IEEE1364
standard. Some of these are picked from extended variants of the
language, such as SystemVerilog, and some are expressions of internal
behavior of Icarus Verilog, made available as a tool debugging aid.
* Builtin System Functions
** Extended Verilog Data Types
This feature is turned off if the generation flag "-g" is set to other
then the default "2x". For example, "iverilog -g2x" enables extended
data types, and "iverilog -g2" disables them.
Icarus Verilog adds support for extended data types. This extended
type syntax is based on a proposal by Cadence Design Systems,
originally as an update to the IEEE1364. That original proposal has
apparently been absorbed by the IEEE1800 SystemVerilog
standard. Icarus Verilog currently only takes the new primitive types
from the proposal.
Extended data types separates the concept of net/variable from the
data type. Both nets and variables can declared with any data
type. The primitive types available are:
logic - The familiar 0, 1, x and z, optionally with strength.
bool - Limited to only 0 and 1
real - 64bit real values
Nets with logic type may have multiple drivers with strength, and the
value is resolved the usual way. Only logic values may be driven to
logic nets, so bool values driven onto logic nets are implicitly
converted to logic.
Nets with any other type may not have multiple drivers. The compiler
should detect the multiple drivers and report an error.
- Declarations
The declaration of a net is extended to include the type of the wire,
with the syntax:
wire <type> <wire-assignment-list>... ;
The <type>, if omitted, is taken to be logic. The "wire" can be any of
the net keywords. Wires can be logic, bool, real, or vectors of logic
or bool. Some valid examples:
wire real foo = 1.0;
tri logic bus[31:0];
wire bool addr[23:0];
... and so on.
The declarations of variables is similar. The "reg" keyword is used to
specify that this is a variable. Variables can have the same data
types as nets.
- Ports
Module and task ports in standard Verilog are restricted to logic
types. This extension removes that restriction, allowing any type to
pass through the port consistent with the continuous assignment
connectivity that is implied by the type.
- Expressions
Expressions in the face of real values is covered by the baseline
Verilog standard.
The bool type supports the same operators as the logic type, with the
obvious differences imposed by the limited domain.
Comparison operators (not case compare) return logic if either of
their operands is logic. If both are bool or real (including mix of
bool and real) then the result is bool. This is because comparison of
bools and reals always return exactly true or false.
Case comparison returns bool. This differs from baseline Verilog,
which strictly speaking returns a logic, but only 0 or 1 values.
All the arithmetic operators return bool if both of their operands are
bool or real. Otherwise, they return logic.
+10 -38
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1999-2008 Stephen Williams (steve@icarus.com)
* Copyright (c) 1999-2010 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -40,10 +40,6 @@ void functor_t::process(class Design*, class NetProcTop*)
{
}
void functor_t::lpm_abs(class Design*, class NetAbs*)
{
}
void functor_t::lpm_add_sub(class Design*, class NetAddSub*)
{
}
@@ -60,10 +56,6 @@ void functor_t::lpm_divide(class Design*, class NetDivide*)
{
}
void functor_t::lpm_literal(class Design*, class NetLiteral*)
{
}
void functor_t::lpm_modulo(class Design*, class NetModulo*)
{
}
@@ -72,6 +64,10 @@ void functor_t::lpm_ff(class Design*, class NetFF*)
{
}
void functor_t::lpm_latch(class Design*, class NetLatch*)
{
}
void functor_t::lpm_logic(class Design*, class NetLogic*)
{
}
@@ -84,19 +80,10 @@ void functor_t::lpm_mux(class Design*, class NetMux*)
{
}
void functor_t::lpm_pow(class Design*, class NetPow*)
void functor_t::lpm_ram_dq(class Design*, class NetRamDq*)
{
}
void functor_t::sign_extend(class Design*, class NetSignExtend*)
{
}
void functor_t::lpm_ureduce(class Design*, class NetUReduce*)
{
}
void NetScope::run_functor(Design*des, functor_t*fun)
{
for (NetScope*cur = sub_ ; cur ; cur = cur->sib_) {
@@ -178,11 +165,6 @@ void NetNode::functor_node(Design*, functor_t*)
{
}
void NetAbs::functor_node(Design*des, functor_t*fun)
{
fun->lpm_abs(des, this);
}
void NetAddSub::functor_node(Design*des, functor_t*fun)
{
fun->lpm_add_sub(des, this);
@@ -208,9 +190,9 @@ void NetFF::functor_node(Design*des, functor_t*fun)
fun->lpm_ff(des, this);
}
void NetLiteral::functor_node(Design*des, functor_t*fun)
void NetLatch::functor_node(Design*des, functor_t*fun)
{
fun->lpm_literal(des, this);
fun->lpm_latch(des, this);
}
void NetLogic::functor_node(Design*des, functor_t*fun)
@@ -233,19 +215,9 @@ void NetMux::functor_node(Design*des, functor_t*fun)
fun->lpm_mux(des, this);
}
void NetPow::functor_node(Design*des, functor_t*fun)
void NetRamDq::functor_node(Design*des, functor_t*fun)
{
fun->lpm_pow(des, this);
}
void NetSignExtend::functor_node(Design*des, functor_t*fun)
{
fun->sign_extend(des, this);
}
void NetUReduce::functor_node(Design*des, functor_t*fun)
{
fun->lpm_ureduce(des, this);
fun->lpm_ram_dq(des, this);
}
proc_match_t::~proc_match_t()
+6 -14
View File
@@ -1,7 +1,7 @@
#ifndef __functor_H
#define __functor_H
/*
* Copyright (c) 1999-2008 Stephen Williams (steve@icarus.com)
* Copyright (c) 1999-2010 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -48,9 +48,6 @@ struct functor_t {
/* This method is called for each process in the design. */
virtual void process(class Design*des, class NetProcTop*);
/* This method is called for each structural abs(). */
virtual void lpm_abs(class Design*des, class NetAbs*);
/* This method is called for each structural adder. */
virtual void lpm_add_sub(class Design*des, class NetAddSub*);
@@ -63,15 +60,15 @@ struct functor_t {
/* This method is called for each structural constant. */
virtual void lpm_divide(class Design*des, class NetDivide*);
/* Constant literals. */
virtual void lpm_literal(class Design*des, class NetLiteral*);
/* This method is called for each structural constant. */
virtual void lpm_modulo(class Design*des, class NetModulo*);
/* This method is called for each FF in the design. */
virtual void lpm_ff(class Design*des, class NetFF*);
/* This method is called for each latch in the design. */
virtual void lpm_latch(class Design*des, class NetLatch*);
/* Handle LPM combinational logic devices. */
virtual void lpm_logic(class Design*des, class NetLogic*);
@@ -81,13 +78,8 @@ struct functor_t {
/* This method is called for each MUX. */
virtual void lpm_mux(class Design*des, class NetMux*);
/* This method is called for each power. */
virtual void lpm_pow(class Design*des, class NetPow*);
/* This method is called for each unary reduction gate. */
virtual void lpm_ureduce(class Design*des, class NetUReduce*);
virtual void sign_extend(class Design*des, class NetSignExtend*);
/* This is called for eacm RamDq device. */
virtual void lpm_ram_dq(class Design*des, class NetRamDq*);
};
struct proc_match_t {
+3 -12
View File
@@ -1,7 +1,4 @@
NOTE: THE CONTENTS OF THIS FILE ARE BEING MOVED TO THE DOCUMENTATION
WIKI AT http://iverilog.wikia.com. PLEASE ADD NEW ENTRIES THERE.
Icarus Verilog vs. IEEE1364
Copyright 2000 Stephen Williams
@@ -285,12 +282,12 @@ One might note that the quote from section 4.1.14 says "Unsized
expressions...", so arguably accepting (15+1) or even (16+0) as an
operand to a concatenation is not a violation of the letter of the
law. However, the very next sentence of the quote expresses the
intent, and accepting (15+1) as having a more defined size then (16)
intent, and accepting (15+1) as having a more defined size than (16)
seems to be a violation of that intent.
Whatever a compiler decides the size is, the user has no way to
predict it, and the compiler should not have the right to treat (15+1)
any differently then (16). Therefore, Icarus Verilog takes the
any differently than (16). Therefore, Icarus Verilog takes the
position that such expressions are *unsized* and are not allowed as
operands to concatenations. Icarus Verilog will in general assume that
operations on unsized numbers produce unsized results. There are
@@ -501,14 +498,8 @@ of 4-value behavior in the dead zone, and appears more user friendly
when viewed by reasonable viewers.
$Id: ieee1364-notes.txt,v 1.19 2007/04/18 02:36:13 steve Exp $
$Id: ieee1364-notes.txt,v 1.17 2003/07/15 03:49:22 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.
+21 -4
View File
@@ -17,17 +17,29 @@
# 59 Temple Place - Suite 330
# Boston, MA 02111-1307, USA
#
#ident "$Id: iverilog-vpi.sh,v 1.17 2007/02/06 05:07:31 steve Exp $"
# These are the variables used for compiling files
CC=@IVCC@
CXX=@IVCXX@
CFLAGS="@PIC@ @IVCFLAGS@ -I@INCLUDEDIR@"
SUFFIX=@SUFFIX@
# These are used for linking...
LD=$CC
LDFLAGS="@SHARED@ -L@LIBDIR@"
LDLIBS="-lveriuser -lvpi"
LDFLAGS32="@SHARED@ -L@LIBDIR@"
LDFLAGS64="@SHARED@ -L@LIBDIR64@"
LDFLAGS="$LDFLAGS64"
LDLIBS="-lveriuser$SUFFIX -lvpi$SUFFIX"
INSTDIR64="@VPIDIR1@"
INSTDIR32="@VPIDIR2@"
if test x$INSTDIR32 = x
then
INSTDIR32=$INSTDIR64
fi
INSTDIR="$INSTDIR64"
CCSRC=
CXSRC=
@@ -85,6 +97,11 @@ do
-D*) DEFS="$DEFS $parm"
;;
-m32) LDFLAGS="-m32 $LDFLAGS32"
CFLAGS="-m32 $CFLAGS"
INSTDIR="$INSTDIR32"
;;
--cflags)
echo "$CFLAGS"
exit;
@@ -101,7 +118,7 @@ do
;;
--install-dir)
echo "@LIBDIR@/ivl"
echo "@LIBDIR@/ivl$SUFFIX/$INSTDIR"
exit
;;
esac
+37 -75
View File
@@ -9,11 +9,9 @@ ivl_design_roots
ivl_design_time_precision
ivl_const_bits
ivl_const_delay
ivl_const_real
ivl_const_pin
ivl_const_pins
ivl_const_signed
ivl_const_type
ivl_const_width
ivl_event_any
ivl_event_basename
@@ -23,15 +21,14 @@ ivl_event_neg
ivl_event_nneg
ivl_event_npos
ivl_event_pos
ivl_event_scope
ivl_expr_type
ivl_expr_bits
ivl_expr_def
ivl_expr_dvalue
ivl_expr_event
ivl_expr_file
ivl_expr_lineno
ivl_expr_lsi
ivl_expr_memory
ivl_expr_name
ivl_expr_opcode
ivl_expr_oper1
@@ -47,44 +44,36 @@ ivl_expr_signed
ivl_expr_string
ivl_expr_uvalue
ivl_expr_value
ivl_expr_variable
ivl_expr_width
ivl_file_table_index
ivl_file_table_item
ivl_file_table_size
ivl_island_flag_set
ivl_island_flag_test
ivl_logic_attr
ivl_logic_attr_cnt
ivl_logic_attr_val
ivl_logic_basename
ivl_logic_delay
ivl_logic_drive0
ivl_logic_drive1
ivl_logic_name
ivl_logic_pin
ivl_logic_pins
ivl_logic_basename
ivl_logic_scope
ivl_logic_type
ivl_logic_pin
ivl_logic_pins
ivl_logic_udp
ivl_logic_width
ivl_lpm_array
ivl_lpm_aset_value
ivl_lpm_async_clr
ivl_lpm_async_set
ivl_lpm_base
ivl_lpm_attr_cnt
ivl_lpm_attr_val
ivl_lpm_basename
ivl_lpm_clk
ivl_lpm_data
ivl_lpm_datab
ivl_lpm_data2
ivl_lpm_data2_width
ivl_lpm_decode
ivl_lpm_define
ivl_lpm_delay
ivl_lpm_enable
ivl_lpm_file
ivl_lpm_lineno
ivl_lpm_memory
ivl_lpm_name
ivl_lpm_q
ivl_lpm_scope
@@ -93,17 +82,25 @@ ivl_lpm_selects
ivl_lpm_signed
ivl_lpm_size
ivl_lpm_sset_value
ivl_lpm_string
ivl_lpm_sync_clr
ivl_lpm_sync_set
ivl_lpm_type
ivl_lpm_width
ivl_lval_idx
ivl_lval_mem
ivl_lval_mux
ivl_lval_part_off
ivl_lval_pin
ivl_lval_pins
ivl_lval_sig
ivl_lval_width
ivl_lval_var
ivl_memory_basename
ivl_memory_root
ivl_memory_scope
ivl_memory_size
ivl_memory_width
ivl_nexus_get_private
ivl_nexus_name
@@ -118,36 +115,23 @@ ivl_nexus_ptr_pin
ivl_nexus_ptr_lpm
ivl_nexus_ptr_log
ivl_nexus_ptr_sig
ivl_nexus_ptr_switch
ivl_parameter_basename
ivl_parameter_expr
ivl_parameter_file
ivl_parameter_lineno
ivl_path_condit
ivl_path_delay
ivl_path_is_condit
ivl_path_scope
ivl_path_source
ivl_path_source_negedge
ivl_path_source_posedge
ivl_scope_attr_cnt
ivl_scope_attr_val
ivl_scope_basename
ivl_scope_children
ivl_scope_def
ivl_scope_def_file
ivl_scope_def_lineno
ivl_scope_event
ivl_scope_events
ivl_scope_file
ivl_scope_lineno
ivl_scope_logs
ivl_scope_log
ivl_scope_lpms
ivl_scope_lpm
ivl_scope_mem
ivl_scope_mems
ivl_scope_name
ivl_scope_param
ivl_scope_params
@@ -156,38 +140,26 @@ ivl_scope_port
ivl_scope_ports
ivl_scope_sigs
ivl_scope_sig
ivl_scope_switch
ivl_scope_switches
ivl_scope_time_precision
ivl_scope_time_units
ivl_scope_type
ivl_scope_tname
ivl_scope_var
ivl_scope_vars
ivl_signal_array_base
ivl_signal_array_count
ivl_signal_attr
ivl_signal_attr_cnt
ivl_signal_attr_val
ivl_signal_basename
ivl_signal_data_type
ivl_signal_dimensions
ivl_signal_file
ivl_signal_integer
ivl_signal_lineno
ivl_signal_local
ivl_signal_lsb
ivl_signal_msb
ivl_signal_name
ivl_signal_nex
ivl_signal_npath
ivl_signal_path
ivl_signal_pin
ivl_signal_pins
ivl_signal_port
ivl_signal_signed
ivl_signal_type
ivl_signal_width
ivl_path_delay
ivl_path_source
ivl_signal_name
ivl_signal_basename
ivl_process_attr_cnt
ivl_process_attr_val
@@ -210,34 +182,24 @@ ivl_stmt_cond_true
ivl_stmt_delay_expr
ivl_stmt_delay_val
ivl_stmt_events
ivl_stmt_file
ivl_stmt_lineno
ivl_stmt_lval
ivl_stmt_lvals
ivl_stmt_lwidth
ivl_stmt_name
ivl_stmt_nevent
ivl_stmt_nexus
ivl_stmt_nexus_count
ivl_stmt_parm
ivl_stmt_parm_count
ivl_stmt_rval
ivl_stmt_sub_stmt
ivl_switch_a
ivl_switch_b
ivl_switch_basename
ivl_switch_enable
ivl_switch_file
ivl_switch_island
ivl_switch_lineno
ivl_switch_offset
ivl_switch_part
ivl_switch_scope
ivl_switch_type
ivl_switch_width
ivl_udp_init
ivl_udp_name
ivl_udp_nin
ivl_udp_row
ivl_udp_rows
ivl_udp_sequ
ivl_variable_name
ivl_variable_type
-43
View File
@@ -1,43 +0,0 @@
/*
* Copyright (c) 2007 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: ivl_assert.h,v 1.1 2007/01/31 04:21:10 steve Exp $"
#endif
#ifndef __ivl_assert_h
#define __ivl_assert_h
# include <assert.h>
#define ivl_assert(tok, expression) \
do { \
if (! (expression)) \
__ivl_assert(#expression, tok, __FILE__, __LINE__); \
} while(0)
#define __ivl_assert(expression, tok, file, line) \
do { \
cerr << (tok).get_fileline() << ": assert: " \
<< file << ":" << line \
<< ": failed assertion " << (expression) << endl; \
abort(); \
} while(0)
#endif
+212 -842
View File
File diff suppressed because it is too large Load Diff

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