Compare commits

...

483 Commits

Author SHA1 Message Date
Stephen Williams 8288f7305d Prepare for Icarus Verilog version 0.9.7 release 2013-08-19 12:10:31 -07:00
Cary R 8b6ccc65d6 Update to latest FST API files from GTKWave 2013-08-09 11:35:07 -07:00
Cary R 452c1650f4 Update FST files to latest from GTkWave 2013-07-16 11:27:52 -07:00
Cary R 00337d2418 Fix space issue in vvp/vvp_net.cc 2013-07-15 16:19:23 -07:00
Cary R bf2b086669 Back port vector8 changes from development to eliminate compile warnings 2013-07-15 16:16:04 -07:00
Cary R 4289ae23f9 Update fstap files to the latest from GTKWave 2013-06-14 16:35:44 -07:00
Martin Whitaker 4efb601fee V0.9: Fix for br930 - support attributes on old-style port declarations. 2013-05-19 11:05:01 +01:00
Cary R c8c0a298e4 V0.9 Update fstapi.c to latest from SVN 2013-04-16 15:14:01 -07:00
Martin Whitaker f99ca8672c Fix VHDL code generator crash when a terneray operator has a real operand. 2013-04-12 23:50:16 +01:00
Martin Whitaker 19e266159e Fix for br924.
Prevent compiler crashes after a function argument fails to be
elaborated (back-ported from development).
2013-03-31 19:57:37 +01:00
Cary R 2777a8b00b V0.9: A concatenation may also need a BUFZ to hold the drive strength
Just like a select a concatenation needs a BUFZ to hold the drive strength.
2013-02-12 18:37:09 -08:00
Cary R c84eec1d60 V0.9: minor fixes to br916 patch 2013-02-04 11:45:42 -08:00
Martin Whitaker 0f4658135e V0.9: Stopgap fix for br916.
Currently, when a variable expression is passed to a system task,
the expression value is stored in thread memory. Values stored
in thread memory cannot safely be passed to $strobe or $monitor,
because the thread memory may get reused or deallocated before
the $strobe or $monitor task actually executes. As a temporary
measure, we just trap this case and terminate with a "sorry"
message. A proper fix would require the expression value to be
calculated at the time the $strobe or $monitor executes, not at
the time it is called.
2013-02-04 11:45:35 -08:00
Martin Whitaker 200951275c Fix logic value returned for unambiguous HiZ1 strength.
If a strength aware net has an unambiguous HiZ1 strength, VVP treats
it as a logic '1'. It should be treated as a logic 'z'. An ambiguous
HiZ1/HiZ0 strength should also be treated as a logic 'z'.
2013-01-28 19:07:08 -08:00
Cary R 9b1c1a5d48 Fix space issue 2013-01-25 10:34:34 -08:00
Cary R edf741106d V0.9: Handle undefined L-value selects
L-value bit selects were incorrectly converting an undefined index to 0.

L-value part selects were asserting if an undefined index was given.

This patch unifies how all these are handle (including indexed part selects).

The base is set to an undefined value and an appropriate width is used.
A warning message is always printed since this is not a simple out of
range issue. It is the responsibility of the code generator to skip the
assignment, but we always want to execute the R-value since it could have
a side effect.
2013-01-25 10:32:52 -08:00
Cary R 4b805a2b89 Remove space issues 2013-01-21 19:29:34 -08:00
Martin Whitaker 8ae15b93cf Fix for bug 915 (was 3592746).
probe_expr_width() must be called before calling elab_and_eval(), to
determine the expression type.
2013-01-21 19:12:07 -08:00
Martin Whitaker 66338431f5 Fix for bug 913 (was 3587570).
probe_expr_width() must be called before calling elab_and_eval(), to
determine the expression type.
2013-01-21 19:02:08 -08:00
Martin Whitaker 0a06cf5d28 V0.9: Fix display of net array words when data type is signed.
When VVP compiles a .array statement for a net array, it does not
know the data type, so initialises the array signed_flag to false.
We need to set the signed_flag to the correct value once we know
the data type, to allow the VPI routines to correctly format the
data.
2013-01-21 18:46:59 -08:00
Martin Whitaker 15fee99abb Fix for pr3571573.
This patchs adds an implementation of recv_vec4_pv() to the vvp_fun_concat
class. This was already present in devel, so just needed to be backported
to v0.9.
2013-01-21 18:24:39 -08:00
Cary R 0ab44eca13 Update fstapi.c from GTKWave to fix MinGW compile. 2012-11-27 09:19:29 -08:00
Cary R 760ab91a36 Update fstapi.c and lxt2_write.c to latest from GTKWave
This just fixes warnings in cppcheck
2012-11-15 15:33:05 -08:00
Stephen Williams fc41668cf1 Make use of LDFLAGS when linking *.tgt files
Submitted by Ahmed El-Mahmoudy
2012-11-03 10:27:59 -07:00
Stephen Williams b8bcb016aa Fix licensing issues.
Remove des.v, which has incompatible restrictions.
Repair some copyright names (Remove Picture Elements)
Update FSF address.
2012-10-01 09:06:51 -07:00
Stephen Williams a233e21cd8 Prepare for 0.9.6 release. 2012-09-05 18:20:12 -07:00
Stephen Williams 87c691654e Spelling fixes. 2012-09-05 17:55:20 -07:00
Cary R 1f6aec6e26 Add %u support to the scanf routines. 2012-09-05 14:24:09 -07:00
Cary R 61cfb9e1fd Add support for %z to the scanf() routines 2012-09-04 18:46:37 -07:00
Cary R 01c4cd3dad Windows (mingw) _vsnprintf() returns -1 not the required size on overflow.
Windows and hence mingw does not follow the standard regarding the return
value of vsnprintf(). The mingw code needs to iteratively search for a
buffer large enough to print the output.
2012-08-31 10:57:31 -07:00
Cary R 62f1aa135b Cleanup after the va_copy()
I missed that va_end() needs to be called on the new ap created by va_copy().
2012-08-31 09:22:36 -07:00
Cary R 5794098aa4 Save the va_list so it can be reused if needed.
The second call to vsnprintf() needs to have a copy of the argument list
so it can run correctly. On some system vsnprintf() destorys the original
argument list.
2012-08-30 20:04:25 -07:00
Cary R 9d5f438872 Allocate a string buffer as needed in the code generator and vvp display code
When sending a string to a system task/function allocate the space needed
to avoid truncating the string vs using a large fixed buffer.

In vvp allocate and use an exactly sized buffer for the MCD print routine if
the fixed buffer is not large enough. Using a fixed buffer keeps normal
printing fast.
2012-08-30 19:12:23 -07:00
Martin Whitaker 267ba427a3 Fix for pr3561350.
When a new NetEBMult object is created, the compiler guesses the
expression width based on the sum of the operand widths. When we
duplicate an expression, we need to override this with the width
from the original expression.
2012-08-29 10:29:56 -07:00
Martin Whitaker a3987a112b V0.9: Fix for pr3557493.
defparam assignments found inside a generate block were being stored
in the enclosing module scope. They should be stored in the generate
block scope.
2012-08-21 17:46:50 -07:00
Cary R e8b40e14b9 Update lxt, lxt2 and fst files to latest from GTKWave 2012-08-16 14:56:32 -07:00
Cary R 34bb00144f V0.9: back port some cross compile changes 2012-08-13 18:09:00 -07:00
Cary R 0a518c1786 V0.9: update uninstall include directory rule 2012-08-13 17:12:00 -07:00
Martin Whitaker cd029fe35d Fix time scaling in PLI TF routines for MinGW.
When built with MinGW, pow() may not always generate an exact integer
result when supplied with integer operands. Converting the result to an
integer before we use it seems to be enough to work round this issue.
2012-08-06 13:39:40 -07:00
Martin Whitaker 693574107b V0.9: Add missing semi-colons in parser rules.
Also add null actions to prevent older versions of bison failing due
to type clashes, plus a few minor spelling/formatting fixes.
2012-08-01 15:39:56 -07:00
Martin Whitaker db3b1d9bf0 Handle error case of zero width in indexed part select.
The compiler doesn't currently check that the width of an indexed
part select is non-zero. If code contains this erroneous case, the
compiler can crash (with an assertion failure). This patch causes
the compiler to output a suitable error message and recover. It
also fixes a potential crash if an illegal expresson is encountered.
(cherry picked from commit c4ff8300d3)
2012-07-27 18:49:48 -07:00
Martin Whitaker d3563bc210 V0.9: Allow a UDP instance to have a simple real delay.
The parser does not distinguish between module and UDP instances, so
a UDP delay is handled by the rules used for parsing module parameter
overrides. Although these rules had been relaxed to accept the case of
a simple decimal value (e.g. #10), they did not allow a simple real
value (e.g. #0.1).
2012-07-27 18:35:08 -07:00
Martin Whitaker 52f15498b9 V0.9: Fix elaboration order in generate blocks.
Currently, localparam declarations inside generate blocks are
elaborated after any nested generate constructs are elaborated.
This prevents the localparams being used by the nested constructs.
Reversing the elaboration order fixes this bug.
2012-07-01 12:15:02 -07:00
Martin Whitaker 27cb31db4b V0.9: Fix for pr3527022.
This patch adds support for an explicit range or type in a parameter
declaration that is part of a module parameter port list.
2012-05-18 13:57:18 -07:00
Cary R a6ca1a7ce8 V0.9: For a delayed vpi_put_value() copy any pointer data members.
When vpi_put_value() is asked to delay the assignment any pointer data
needs to be duplicated so that the caller can clean up the locally
allocated memory without causing memory access problems.
2012-04-02 15:31:32 -07:00
Martin Whitaker ca2319153f V0.9 - Fix for pr3499807.
Output a "sorry" message to inform the user that tranif delays are
not supported.
2012-03-12 09:06:16 -07:00
Cary R 0210d49cf8 V0.9: Fix the formatting of time values that are less than 1
This patch is a modification of a user contributed patch that fixes the
time formatting when the time is less than 1 and $timeformat() is used.
2012-01-23 18:52:49 -08:00
Cary R c292f77f28 V0.9: Remove crash for function def with zero args and warn on calls
Normal Verilog does not allow a function to be defined without at
least an input argument. This patch fixes a crash that was happening
when a function with no arguments was defined. It also adds checks
and prints a descriptive error message when calling a function without
an argument.

The development branch allows this in SV.
2012-01-09 19:12:55 -08:00
Cary R 5f47d660a1 V0.9: remove unneeded -s flags for flex
I added these in a previous patch, but they are not needed and
generate a warning.
2012-01-07 11:35:43 -08:00
Cary R b47fad7d19 V0.9: Update lex/yacc builds to be consistent and to support parallel builds
Not all the lex/yacc (flex/bison) targets were using a consistent syntax.
This patch fixes that and explicitly serializes the *.c/*.cc and *.h build.
Not doing this was causing problem when using make -j. The issue appears to
be that if two targets are specified for a rule (e.g. file.cc file.h: file.y)
make does not realize they are both built by the same call so the rule is
executed twice. Once for the .cc target and once for the .h target. This is
not a problem for a serial build. To work around this only use the .c/.cc
file in the main target and then make the .h file depend on the .c/.cc file
as a sub-target.
2012-01-04 18:40:37 -08:00
Cary R e1789e7fb9 V0.9: To reduce error divide by an integer vs multiple by a fraction.
This same change was done in the vpi directory. This patch fixes the
issues in the libveriuser directory. This fixed a fail in the vpi
timescale test under MinGW.
2011-12-16 19:09:48 -08:00
Martin Whitaker 2b67a6d465 Add support for param declarations with signed type but no range
The standard allows a parameter (or localparam) declaration of the
form "parameter signed my_param = ...". The parser currently rejects
this. A small adjustment is also required in the parameter evaluation
code to correctly apply the type.
2011-12-16 13:52:18 -08:00
Martin Whitaker c96619527a Fix for pr3452808.
The tran island rework included an optimisation that meant that an
island port would only be resolved once the initial value for the net
attached to that port had propagated to the port. However, v0.9 does
not propagate initial values in some cases, so this optimisation
cannot be used.
2011-12-10 12:09:26 -08:00
Cary R 0fa7764eac V0.9:Don't pad a real argument to a user task.
The compiler was incorrectly padding real arguments to tasks if they were
assigned to vectored arguments greater than 1 bit wide. This was asserting
for some cases and generating incorrect code for others.
2011-12-05 19:07:10 -08:00
Cary R c60877999c V0.9: Define turn_sig_to_wire_on_release_ to false in constructor.
Not giving this a default value was leaving the value undefined under
some circumstances. This was producing incorrect results on Cygwin.
2011-11-25 17:06:02 -08:00
Cary R fff46da881 v0.9: Treat an empty @* as something that will never trigger.
An @* with no sensitivities should be treated as something that will
never trigger vs something that will run continuously. This patch makes
this change and adds a warning when an @* has no sensitivities since
this is almost certainly a coding bug.
2011-11-23 17:34:00 -08:00
Cary R 34d8eb27c7 V0.9: Add support for a named block to only have variable definitions.
It is legal for a named block to contain variable definitions and
no statements. This patch fixes this for both style of blocks. It
also organizes the block parsing code to be a bit more clear, adds
an error case for fork/join and changes on check for size() > 0 for
the more efficient ! empty().
2011-11-22 20:48:43 -08:00
Stephen Williams e97ca19a25 Add --always and --dirty to git describe. 2011-11-19 09:05:36 -08:00
Cary R 68c6e578ae V0.9: For wire and/or nets we need all the net resolution to be and/or.
If a wired and/or net has more than four connections all the other
resolution branches must also be wired and/or. All other nets can
just be tri since tri0/tri1 only needs the final resolution to be
an active pull up/down.
2011-11-19 08:48:31 -08:00
Cary R 8e1c507984 V0.9: Assert that sync/async set/clear are not supported for a DFF primitive.
Since synthesis is not currently supported we do not support/generate
sync/async set or clear control inputs. This is further complicated by
the fact that the VVP DFF primitive is not fully implemented.
2011-11-17 14:42:07 -08:00
Cary R da49a4a798 V0.9: Report that a vectored full connection only supports a single src/dst
In a specify block a full connection is defined to only support a single
source and destination path. This patch adds an error message when this
is found, except we skip the error if all the paths are a single bit
wide. This exemption was added to match the functionality found in
NC-Verilog and presumably Verilog-XL.

A message was also added in place of an assert if the source signals was
not found in the current scope.
2011-11-10 17:57:59 -08:00
Cary R aab491a762 V0.9: Add check that a parallel connection uses the same width input/output.
This patch uses the full_flag to verify that the input and output have the
same width for a parallel connection. Icarus always uses a full connection
so this is just a portability issue with other simulators.

The pform dump code was also modified to correctly display the polarity
and full/parallel connection type.
2011-11-10 17:46:34 -08:00
Cary R 3dca540a29 V0.9: Fix space issues.
This patch removes space before EOL, etc.
2011-11-03 19:20:06 -07:00
Ole Henrik Jahren 36f72a8521 Add missing hyphen to --ldlibs option in iverilog-vpi man page
(cherry picked from commit d2dc0e535f)
2011-11-03 19:09:20 -07:00
Stephen Williams 1a3ce11a79 Prepare for version 0.9.5 2011-11-01 09:57:50 -07:00
Cary R 2fbe7434f2 Use UINT_MAX instead of -1 to set unsigned to maximum value.
The Sun C compiler warns when -1 is used to initialize an unsigned.
(cherry picked from commit 7d588d699b)
2011-10-31 17:23:15 -07:00
Cary R 85faab8a08 V0.9: Reduce the error when scaling a real time value.
When scaling a time value we would often use the power operator to
create constants 10**-N that were then multiplied with the original
value. The problem with this is that there is some errors in the
representation of the fractional number. It is better to create a
integer value 10**N and then divide the original value by this
exact constant. You still have the calculation error, but the scale
value is now an exactly real value.
2011-10-31 10:44:43 -07:00
Cary R e160f5c562 Remove old comment. 2011-10-31 10:40:33 -07:00
Cary R 9481262c06 V0.9: Major rework of the $sscanf()/$fscanf() code.
Add support for %m, suppression '*' and a maximum field width along with
a number of other fixes/enhancements. There is still no support for
%u, %v or %z.
2011-10-31 10:40:27 -07:00
Cary R 3d99bb13c4 Make some messages consistent.
This patch makes some of the VPI messages consistent with the rest.
2011-10-31 10:36:46 -07:00
Martin Whitaker af07b87419 Restore ability to supply LDFLAGS to MinGW configure.
The fix to get a C99 compliant strtod() in MinGW mistakenly set the
LDFLAGS value rather than appending to it. This meant that a LDFLAGS
supplied by the user on the configure command line would be ignored.
(cherry picked from commit c4433e47c1)
2011-10-31 10:30:57 -07:00
Martin Whitaker f4dec1710d Fix for tf_getlongsimtime link error on MinGW/Cygwin.
MinGW and Cygwin don't currently support weak function definitions.
For these platforms, make tf_getlongsimtime a strong symbol.
(cherry picked from commit 7f62579524)
2011-10-26 18:50:02 -07:00
Martin Whitaker fa88ac03dd Workaround for MinGW non-standard strtod.
MinGW has reverted to using the Microsoft msvcrt0 implementation
of the strtod() function. This implementation doesn't accept "INF"
"NaN". MinGW does provide a C99 compliant implementation of this
function called __strtod(). We need to force the linker to replace
all references to strtod() with references to __strtod().
(cherry picked from commit b6cb065404)
2011-10-26 18:49:05 -07:00
Cary R c6bc46b9a4 Update fstapi.c to latest from GTkWave
There was a change in how the FST data was flushed.
(cherry picked from commit 0b978dac48)
2011-10-26 18:48:13 -07:00
Cary R eb5a385433 v0.9: Report that forcing a word to/from a variable array in not supported.
This patch adds error messages that forcing a word to/from a variable
array is not currently supported. This is because variable arrays no
longer are fully populated and don't have an access functor for each
word. Forcing a word from/to a net array does work as expected since
each word in a net array is created.

Technically forcing a variable array word is not supported in 1364-2005.
Reading from an array word, which is supported,  will be fixed in
development once the expression rework is finished.

The error message printed when forcing a bit/part select l-value was
also improved.
2011-10-25 19:43:01 -07:00
Cary R 0ad589eaca V0.9: Improve the out of range check in tgt-vhdl/stmt.cc
Promote the unsigned values to long to get a good comparison and on a
machine where an unsigned is the same size as a long (32 bit) assert
that the unsigned values are constrained to fit into a long. It's unlikely
the values needed to create invalid results would ever happen, but this
patch makes sure it doesn't go undetected.
2011-10-25 19:05:21 -07:00
Cary R 17344563a8 V0.9: Remove some scan-build warnings.
One of these is a real bug, the others are just minor optimizations.
2011-10-20 16:54:50 -07:00
Cary R 617243f298 Update various dumper files from GTKWave SVN
Update some of the files we get from GTKWave to match the latest from SVN.
(cherry picked from commit b9af189229)
2011-10-20 16:51:15 -07:00
Cary R aa1bfafbc2 V0.9: Fix autoconf warning.
This just copies the same change that was done for development over to V0.9.
2011-10-19 18:17:19 -07:00
Cary R 4dae0471de V0.9: Remove some gcc/g++ (4.6.1) warnings.
This patch remove some unused variable warnings found with gcc/g++ 4.6.1
on Ubuntu 11.10.
2011-10-19 18:16:06 -07:00
Martin Whitaker f8bc2b6198 V0.9 Fix for pr3420994.
The VPI object data model diagrams show a one to many relationship
between the "mod path" and "path term" objects. This means that the
correct way to obtain handles to "path term" objects is to use the
vpi_iterate and vpi_scan functions.

Support for the old method of obtaining handles to "path term" objects
using the vpi_handle function is retained for backwards compatibility.
2011-10-19 14:41:42 -07:00
Martin Whitaker 88d845a612 Corrected tf_getlongsimtime() to match behaviour of other simulators.
The PLI tf_getlongsimtime() function is a non-standard function provided
for compatibility with some commercial simulators. To match the behaviour
of those simulators, it should return the raw simulation time, not a
scaled time.
(cherry picked from commit a3813c006d)
2011-10-16 16:36:44 -07:00
Cary R e47f18f79f When printing a Dec numeric value use the string size and the minimum size.
The vpiDecStrVal case for the get_numeric() function needs to use the
existing string width as the minimum result size. -1 can be represented as
a signed value with a width of 1. This gives a display width of -1 which
is too small for the -1 string value. This was creating valgrind issues.
In general the string value should be the minimum so this is a safe change.
(cherry picked from commit 5a9e4aaec7)
2011-10-16 16:34:52 -07:00
Cary R b7b2d710b1 V0.9: Free the iterator if there are extra arguments.
To avoid extra memory usage on error free the iterator if there are
extra arguments.
2011-10-16 16:33:09 -07:00
Cary R f874e81606 Remove two unused argument warnings
(cherry picked from commit dc2c67e25f)
2011-10-16 16:25:38 -07:00
Cary R 78d5b3f278 Update lxt_write and lxt2_write files from GTKWave
Update the lxt_write.[ch] and lxt2_write.[ch] files to the latest from
GTKWave. This is just comment changes.
(cherry picked from commit cff0deeacc)
2011-10-01 09:49:54 -07:00
Martin Whitaker fc8195fd61 V0.9 Remove more clang warnings.
clang warns that the yyinput function generated by flex is never used.
2011-09-25 10:23:41 -07:00
Cary R 4f2a41f186 V0.9: Remove clang/clang++ warnings.
This patch makes the code consistently use struct/class in the C++ files,
it removes a couple shadow warnings and where a class pointer is passed to
the C routines it defines the pointer as a class for C++ and as struct for C.
2011-09-25 10:23:34 -07:00
Alexander Klimov 5c6c8deba3 Fix long division.
On a 64-bit machine the following module shows incorrect division
results:

`define X {4'b 1000, `N'b 0}
`define Y {1'b  1, `N'b 0}
module b;
   reg [`N:0] y = `Y;
   reg [3:0] z1, z2;
   initial begin
      z1 = `X / `Y;
      z2 = `X /  y;
      $display("%3d %b %b", `N, z1, z2);
   end
endmodule // b

$ for N in {60..65}; do /usr/bin/iverilog -DN=$N -oa b.v && /usr/bin/vvp a; done
 60 1000 1000
 61 1000 1000
 62 1000 0111
 63 1000 0101
 64 1000 1000
 65 1000 1000

The first chunk of the patch (result -> tmp_result) fixes this:

$ for N in {60..65}; do iverilog -DN=$N -oa b.v && vvp a; done
 60 1000 1000
 61 1000 1000
 62 1000 1000
 63 1000 1000
 64 1000 1000
 65 1000 1000

The second chunk fixes

`define X 264'h 800000000000000000000000000000000000000000000000000000000000000000
`define Y 192'h c6df998d06b97b0db1f056638484d609c0895e8112153524
module c;
   reg [191:0] y = `Y;
   reg [72:0] z1, z2;
   initial begin
      z1 = `X / `Y;
      z2 = `X /  y;
      $display("%x %x %b", z1, z2, z1 == z2);
   end
endmodule // c

$ /usr/bin/iverilog -oa c.v && /usr/bin/vvp a
0a4c4a2c1dacd76220c 0809033397ca3427927 0

$ iverilog -oa c.v && vvp a
0a4c4a2c1dacd76220c 0a4c4a2c1dacd76220c 1
(cherry picked from commit 766bf45dcf)
2011-09-17 18:57:00 -07:00
Cary R 354abcc9bd V0.9: For MinGW driver report an error if the two \\ are not found in the exe path
We need to print a message and fail if the two \\ characters are not found
in the executable path.
2011-09-11 11:30:21 -07:00
Cary R 662e765dc5 V0.9: For MinGW report an error if the two \\ are not found in the exe path
We need to print a message and fail if the two \\ characters are not found
in the executable path.
2011-09-06 19:31:15 -07:00
Cary R 0af5b0b16e V0.9: Fix verinum negative comparisons.
For mixed sized negative operands the verinum comparisons were sometimes
returning the wrong value.
2011-07-19 20:22:50 -07:00
Cary R bfb1678dee V0.9: Fix incorrect function in tgt-stub/expression.c.
This fixes a bug where the unary expression code was using the incorrect
function to check to see if the data type was real.
2011-06-26 11:28:11 -07:00
Cary R a7645b2191 V0.9: Fix spacing issues. 2011-06-26 11:26:27 -07:00
Martin Whitaker ebfe869067 v0.9 fix for pr3296466.
The compiler was handling bi-directional pass switches using the default
case for primitive gates, where the first port is treated as an output
and the remaining ports are treated as inputs. This patch adds a special
case for pass switches, so that the first two ports are treated as
bi-directional.

This patch also reworks the tran island code to allow it to handle cases
where tran primitives cross-connect different bits of the same vector.
2011-06-12 17:50:15 -07:00
Cary R a59b778d75 V0.9: Always process specparams since they can be used outside a specify block.
The -gno-specify flag should only control the delay and timing checks.
It should not also remove the specparams since they can be used outside
of a specify block.
2011-06-04 10:58:34 -07:00
Martin Whitaker 9ac9f36e3c (V0.9) Modified rules for primitive gate port expression widths.
The IEEE standard states that the port expressions used for arrays
of primitive gates must be the exact width required, but is silent
about the requirements for single instances. The consensus among
other simulators is that for input ports of single instances, the
expression is silently truncated to a single bit.

This patch also fixes a compiler crash if an error is found when
elaborating a primitive gate port expression.
2011-06-04 10:54:23 -07:00
Cary R 409898eb3b Update fstapi.c to match the latest from GTKWave
(cherry picked from commit feba73119a)
2011-05-29 09:14:38 -07:00
Cary R 134bd22e0b V0.9: Report the correct gate port number.
The error message was reporting the error message as zero based
instead of one based.
2011-05-29 09:13:00 -07:00
Cary R 9e853b4c04 Fix bug in queue average with a very large number of entries.
Icarus is not actually fast enough to run into this issue in a
reasonable amount of time. I discovered this by thinking about
the algorithm and verified the fix with custom code.
(cherry picked from commit 35488ac254)
2011-05-29 09:11:28 -07:00
Cary R 95eec63579 V0.9: Fix spelling problem reported in pr3301924 2011-05-29 09:08:06 -07:00
Martin Whitaker 16db50bed6 Fix for pr3301924.
If a relative path name is passed to the Windows LoadModule function,
it is applied in turn to each path in the DLL search path. For the
ivl_dlopen function, we actually want to mimic the Unix behaviour,
where a relative path is relative to the current working directory.
On systems where the KB2264107 security fix has been applied, the
CWD is excluded from the DLL search path, so we no longer get the
required behaviour. This patch reworks the ivl_dlopen function to
give the correct behaviour under Windows.

This patch also adds a flush of the stderr stream after reporting
VPI call errors. This fixes a race between the stdout and stderr
streams when running the regression tests in a MinGW shell.
(cherry picked from commit 767bb87ee2)
2011-05-29 09:07:20 -07:00
Cary R 88bf49d692 V0.9: Properly terminate a snprintf() call.
snprintf() copies at most N characters, but the string may not be
terminated correctly. This patch uses sizeof() so that the snprintf()
call matches the size of the buffer and adds code to insert a NULL as
the last character of the string.
2011-05-07 11:49:51 -07:00
Stephen Williams 735a789f20 cfparse.y needs stdio.h
Based on patch subbmitted to sourceforge tracker by
Greg Steuck (gnezdo)
(cherry picked from commit c02d6953ef)
2011-04-27 11:18:55 -07:00
Stephen Williams dbbe27ebce fix bad declarations from previous patch. 2011-04-27 11:16:47 -07:00
Cary R d3f7e4f1e6 V0.9: Back port the down payment on const-correctness patch from Larry
This patch is a back port of the applicable changes made in the patch
originally submitted by Larry for development on (9/27/2010).
2011-04-27 11:11:08 -07:00
Cary R dfedd3dda1 Remove some OpenBSD time variable warnings.
Since time is a function OpenBSD does not like us using a variable
named time. This patch fixes that in the sys_queue.c file.
2011-04-27 11:09:37 -07:00
Cary R 8e4008ae19 $q_full should return x for an invalid id.
After some more thought I believe it is better for $q_full to return
'bx instead of 2 when $q_full is given an invalid id. This will make
the typical full/not full checks both return false. We still return
an error code in the status variable.
(cherry picked from commit 10b2310c52)
2011-04-20 18:21:23 -07:00
Cary R 323f12ebfd V0.9: Convert a single % at the end of a format string to %%.
If there is a single % at the end of a format string then automatically
convert this to %% so that we get a single % in the output.
2011-04-20 18:16:54 -07:00
Cary R a51ea8f3b2 V0.9: Add (back-port) the stochastic (queue) tasks/function.
This patch back-ports the stochastic tasks/function from
development. See the development branch patches for more
information.
2011-04-20 17:43:46 -07:00
Cary R 6f2fd4e169 V0.9: Fix a few problems with the power operator.
The power operator defines 2**-1 and -2**-1 to be zero. This patch fixes
both the procedural and continuous assignments to work correctly. It also
fixes a problem in the compiler power code so that the one constant value
always has at least two bits.
2011-04-20 17:40:09 -07:00
Stephen Williams 4c9853551c flex and bison handled in makefiles with variables
Greg Steuck submitted this patch.
2011-03-29 08:54:58 -07:00
Cary R 524544da2d Update the FST dumper to include the vpiDefName if it's unique.
This patch adds the vpiDefName for a module if it is different than
the vpiName. This will be used in a future version of GTKWave.
(cherry picked from commit 085a5c8d02)
2011-03-23 12:01:54 -07:00
Stephen Williams 90bad1a36c Prepare for 0.9.4 release. 2011-03-17 12:26:38 -07:00
Cary R 28ca2a42de v0.9: Remove the last version.h references 2011-03-17 11:53:38 -07:00
Cary R 7011019f2d V0.9: Add #! support for MinGW since newer shells support this. 2011-03-15 18:57:36 -07:00
Cary R ea78ae51c7 For an input report the expression is pruned vs padded.
There was a single message when the expression width was larger
than the port width. This patch makes it a bit more clear by
saying that the expression was pruned.
(cherry picked from commit 1fbe777c81)
2011-03-14 17:05:46 -07:00
Cary R 6b4de9aa82 A '$' is also allowed in identifier names (dumpers)
Update the dumper escaped identifier check to allow a '$'
character after the first character in a normal identifier.
(cherry picked from commit 2e0accf812)
2011-03-14 17:04:47 -07:00
Martin Whitaker b1b54ff531 Fix for pr3194155 (v0.9).
Currently the compiler coerces input ports to inout ports whenever
there is an internal driver connected to the internal port net.
This generates an error if the port is externally connected to
something other than a structural net. This patch modifies the
compiler to ensure port coercion only occurs in valid cases.
2011-03-14 17:00:56 -07:00
Martin Whitaker 9084c4aab1 Miscellaneous improvements and fixes to shift elaboration (v0.9).
This patch ensures that the result of a shift is an undefined value
if the right operand is an undefined value. It also improves the
code generated for right shifts where the right operand is constant
(which fixes the compiler crash on pr3098439b in the test suite).
2011-03-14 16:57:36 -07:00
Cary R 337eb3f8e7 V0.9: Fix spacing issues
Fix space before tab and space/tab before EOL.
2011-03-08 19:21:56 -08:00
Cary R b6223f39c9 V0.9: Don't normalize the port base (lidx) twice.
eval_part_select_() has already normalized the base number so don't
do it again.
2011-03-02 19:39:02 -08:00
Cary R 9d0e85afe1 V0.9: Don't delete L-value concat signals and give a better error message.
This patch removes the code that was deleting the signals in an L-value
concat if the concatenation failed to elaborate. This is incorrect since
the signal could be used in another context that is processed later. The
error message when an output/inout port fails to elaborate was also
improved to give the expression that is connected to the port.
2011-02-28 19:43:54 -08:00
Cary R 8de917347e V0.9: Allows multiple attribute instances.
This patch adds the ability to have multiple attribute instances
(e.g. (* foo = 1 *) (* bar = 2 *)).
2011-02-28 19:40:56 -08:00
Cary R cedee1137e Update fstapi files to latest from GTKWave 3.3.19
Update the fstapi.{c,h} file to match the latest from GTKWave.
(cherry picked from commit ed0469bac5)
2011-02-28 18:22:21 -08:00
Cary R 8ad73b013e The select not the original parameter get the file/line info.
When taking a variable part select of a parameter we need to
give file and line information to the select not the parameter.
(cherry picked from commit 0106578fb6)
2011-02-28 18:19:00 -08:00
Cary R 9d519ffa78 Don't include local signals in @* sensitivity list.
A locally created signal should not be included in the sensitivity
list created by @*.
2011-01-31 14:57:18 -08:00
Cary R 8841f81f51 V0.9: Add support for giving both strengths to a pull device.
In the standard a pull device can be given both a 1 and 0 strength.
Only the appropriate one is actually used. This patch adds support
for giving both pull strength to a pull device.
2011-01-31 14:53:19 -08:00
Cary R 3b89043f68 v0.9: Fix some bugs in task integer/real arguments.
This patch fixes the following problem in the compiler:

  An integer task argument should be marked as an integer port.

  An implicit register can be converted to either a reg or an integer.

  An old style task port should default to <no type> unless reg or some
  other type is provided. ANSI style is always defined. For example:
    input ri;
    output ro;
    inout rio;
    real ri, ro, rio;
  should define all three task ports to be of type real.
2011-01-31 14:43:38 -08:00
Cary R d08d7d8858 Keep nulls in a verinum and keep as string when padding is mod 8.
For diagnostics and to know what is really going on in the compiler
we need to keep any NULL that is in a verinum string or when
displayed as/converted to a string.

When padding a verinum string if the padding is in multiples of eight
then keep the string property.
(cherry picked from commit dc17190f4d)
2011-01-18 17:15:39 -08:00
Cary R 6336432461 is_cell needs to be defined for root scopes.
This patch fixes a small bug found with the vlog95 back end. A root scope
should define is_cell instead of leaving it undefined. Normally I would
expect a root scope to not be a cell, but I don't think the standard
prohibits this from happening, so copy the value from the definition.
(cherry picked from commit 1a1b0d7551)
2011-01-18 17:14:21 -08:00
Cary R b67ee0f1e8 Add a vpath for the local lexor_keyword.cc
This patch doesn't completely fix the problem, but with it the problem
is at least manageable. The issues was that when the lexor_keyword.gperf
file is updated and you are building outside the source directory the
Makefile would create a local lexor_keyword.cc as expected. The problem
is that it always looked in the source directory for the file. This
patch adds a special vpath rule that says to look in the build directory
first and then in the source directory for lexor_keyword.cc.

This works as expected except for the first time the lexor_keyword.cc
file is generated locally. During the make invocation it compares the
source lexor_keyword.cc file to the gperf file and notices it is out of
date. It then generates a new file in the build directory, but the make
rule is still using the source file which didn't change so it doesn't
rebuild as needed. To get the new file to compile you need to run make
a second time to get the rule to execute using the local version of the
file. This extra make invocation is only needed when the local file is
first created since after that the rule always uses the local file.

I plan to look at resolving the remaining issue, but there is much
subtlety in this since you effectively need to break/rebuild the make
dependency tree to get this to build correctly in a single run.
(cherry picked from commit e67dcf5216)
2011-01-18 17:12:29 -08:00
Cary R 1c8f00e90d V0.9: Fix the display of characters with the MSB set (cast to unsigned char).
When a verinum is displayed as a string we need to make sure that any
character that will be displayed as an octal constant must be converted
correctly. Also change to isprint() instead of isgraph() since it is the
same as isgraph() plus a space.
2011-01-12 16:32:08 -08:00
Cary R 5a536b88c9 V0.9: Add a warning that ifnone with an edge-sensitive path is not supported.
Cadence allows an ifnone with an edge-sensitive path. Until we understand
exactly what this is and how to implement it this patch adds a warning
that an ifnone with an edge-sensitive path is not supported.
2011-01-12 16:08:13 -08:00
Cary R f1cfd624cb V0.9: Update some warning messages
Update some of the tgt-vvp warning messages.
2011-01-12 16:03:14 -08:00
Cary R e5e2acfd24 Update fstapi.{c,h} files to match GTKWave 3.3.17.
The files generated after this patch is applied are not backwardly
compatible with older versions of the API.
(cherry picked from commit 25c1795fb7)
2010-12-02 16:17:12 -08:00
Cary R 3f7d635afd V0.9: Fail if the user defines a real variable as a vector.
Using reg real [1:0] var you can define a real variable with a
range. This was crashing the run time. This patch catches this
in the compiler and prints an appropriate message.
2010-11-25 09:34:25 -08:00
Larry Doolittle 8c1b5be360 fix boring C lint in header
With warnings turned sufficiently high in gcc, I get:
  .../vpi_user.h:568: warning: function declaration isn't a prototype
when building VPI modules.  Patch is trivial.
(cherry picked from commit 186779c29b)
2010-11-25 09:10:40 -08:00
Cary R 2e4810ac8a V0.9: Assert if the vcdid overflows.
It should never happen, but if it does assert vs generating an
invalid VCD identifier.
2010-11-25 09:08:25 -08:00
Cary R f7e0f622fa V0.9: Update fstapi.c to match GTKWave 3.3.15 release 2010-11-25 09:07:01 -08:00
Cary R 15bff3a23b 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.
(cherry picked from commit 9477154e5b)
2010-11-25 09:03:59 -08:00
Cary R 8dea333521 V0.9: Ignore COND in SDF timing check back annotations
When back annotating from a SDF file we already ignore timing checks so
we may as well ignore the COND statement that can be used with them.

Also update a few other changes from development.
2010-11-25 09:00:33 -08:00
Cary R 709a076ecf V0.9: Handle escaped characters in a SDF identifier.
This patch adds the ability to parse a SDF identifier that contains
escaped characters.
2010-11-25 08:57:18 -08:00
Cary R 9a826152a6 V0.9: Add support for passing -0.0 to vvp. 2010-11-18 17:00:17 -08:00
Cary R 3612e53f7c V0.9: Add support for taking ! of a constant real value. 2010-11-18 16:51:51 -08:00
Cary R c88caa764d Another GTKWave file update,
(cherry picked from commit 1ce595da2b)
2010-11-09 17:08:17 -08:00
Cary R 1c8e191918 V0.9: back port fixes from development.
This patch back ports some fixes from development. It adds the ability
to do signed === and !== correctly, adds support for && and || of real
values in eval_tree and fixes an obscure bug in t-dll.cc.
2010-11-09 16:40:50 -08:00
Cary R 29a69bacd0 Update GTKWave files to the latest from GTKWave CVS.
This update fixes a rare bug in the FST file creation process along
with a general sync of the files.
(cherry picked from commit a359cc301c)
2010-11-02 11:30:53 -07:00
Cary R 09b80051bd V0.9: Add probe_expr_width() for specparam value.
This patch adds a call to probe_expr_width() before a specparam
value is evaluated. This calculates the expression type/width.
2010-10-06 15:21:40 -07:00
Cary R 87cd9a89e0 V0.9: Resize an unsized signed constant if it is less than integer_width.
An unsized signed constant that is smaller than integer_width needs
to be resized up to either the integer_width or the expression width
whichever is smaller.
2010-10-06 15:18:13 -07:00
Stephen Williams 213b687563 Edit missed version_base.h version stamp 2010-09-27 10:42:32 -07:00
Stephen Williams 248924f64b Clean up for v0.9.3 2010-09-27 09:10:42 -07:00
Stephen Williams c7d1bf5d6a Updated Mingw build instructions from Martin. 2010-09-27 09:07:34 -07:00
Cary R 85ebc1162b Remove MinGW shadow warning.
Remove a shadow warning in a MinGW specific code block.
2010-09-24 15:37:46 -07:00
Larry Doolittle 20f78515c8 Spelling fixes
All fixes are in comments, except for one error message (was "iternal error")
2010-09-22 13:42:55 -07:00
Cary R 01ad32e375 Update fstapi.c to the latest from GTKWave-3.3.12
(cherry picked from commit 0dad9e3adb)
2010-09-22 09:16:20 -07:00
Cary R 04b9cf5715 v0.9: Fix signed/unsigned compare warnings.
Fix all the Icarus files that can be so that we do not have any
signed/unsigned compare warnings. It also removes const as a
return qualifier for two routines in discipline.h.
2010-09-22 09:14:39 -07:00
Cary R 633006bc6e V0.9: Pad and sign convert array index expressions as needed.
This patch mimics what was done for vectors, but is simpler since
arrays don't use the endian information. It also needs to address
the fact that .array/port assumes the expression is unsigned so
any signed expression must be padded to make it larger than the
maximum array word when it is converted to unsigned.
2010-09-19 13:52:28 -07:00
Cary R e6b04cc5d0 V0.9: Normalize variable bit/indexed part selects using a fixed routine.
This patch modifies all the variable bit and indexed part selects
to use a common routine. This routine determines the minimum
width needed to calculate the result correctly, pads the expression
if needed and then converts the expression to signed if required to
make the calculation correct.
2010-09-19 13:52:20 -07:00
Cary R 3333a5e520 Fix generation of PS files and hence PDF files on cygwin.
The Cygwin man command requires that you have a / in the path
if you want to avoid looking at the normal search path. This
patch addes ./ before the manual page file name. Which should
work on any system. It also makes the vvp generation create a
PS file like is done in the other Makefiles.

By default we generate normal manual pages. You can then
create PostScript version and from these you can generate a
PDF version.
(cherry picked from commit 5ae3e48cdb)
2010-09-19 13:50:52 -07:00
Cary R f4bec3b713 Resize constants in eval_expr when needed.
If we are given an unsized constant that is smaller then the requested
width then resize the constant to fit.
(cherry picked from commit acb55916da)
2010-09-13 16:19:09 -07:00
Cary R cc024fde2b V0.9: An if statement is optional and results in no delay.
While checking for an infinite loop in an always block I missed
the case where an if statement does not have a statement. This
was resulting in a segmentation fault.
2010-09-13 14:07:56 -07:00
Martin Whitaker 0a94253261 Fix for pr3064375.
The search for similar events, used to elide duplicates, was ignoring
the event edge sensitivity. This allowed events that should have been
triggered on different edges of the same signal to be merged.
2010-09-12 09:17:10 -07:00
Stephen Williams d46b6cdcbb git ignore emacs backup files. 2010-09-12 08:59:46 -07:00
Stephen Williams 008082c8cb Clear up compile warning on gcc44 compilers. 2010-09-12 08:59:19 -07:00
Cary R 64d713dd6d Don't elide unconnected module ports.
When performing a translation we do not want to elide any module
ports. Dropping ports can result in port mismatch issues.
(cherry picked from commit b252dc0192)
2010-09-10 17:56:49 -07:00
Cary R 97a3bf5aeb V0.9: Report and fail gracefully for recursive parameter definitions.
If someone accidentally makes a parameter depend on itself
we need to report this not crash. This patch fixes the crash
and prints an appropriate string of messages to figure out
the loop. Icarus currently supports forward references of
parameters so more complicated loops can be created. These
are also caught.
2010-09-08 17:12:04 -07:00
Cary R 7c4d07bda6 V0.9: Warn the user that synthesis is no longer maintained.
Add code to print a warning if the user tries to use the -S flag.
We need this warning since synthesis is not currently being actively
maintained or supported in any branch after V0.8.
2010-09-04 16:40:23 -07:00
Patrick Doyle a45aa9f37a Keep expression width when evaluating expressions ahead of time.
Added 'expr_wid' parameter to calls to 'eval_expr()' within
PEBinary::elaborate_eval_expr_base_()'.  This makes a specific problem
go away and may even be the correct thing to do.
(cherry picked from commit 2ffc2d36f2)
2010-08-19 17:33:47 -07:00
Stephen Williams 46b45daea8 Fix broken search for similar events.
The search for similar events, used to elide duplicates, was easily
confounded by duplicate pins connected to a probe. This caused the
similarity count to get messed up, and bad things happened. Change
the method to use set comparisons instead.
2010-08-18 20:52:43 -07:00
Stephen Williams 2ab2ff6b72 Add $info, $warning and $error as aliases to $display
Submitted by voiz@sourceforge.net
2010-08-06 21:38:20 -07:00
Cary R 3c2e4a3a7b Update fstapi.c to latest from gtkwave 3.3.10
(cherry picked from commit 44b08a4630)
2010-08-06 21:34:42 -07:00
Cary R 39b91f604a V0.9: Cleanup some compiler warnings under CentOS 5.5
This patch cleans up a couple of warnings when compiling on CentOS 5.5
using gcc 4.1.2.
2010-08-06 21:31:19 -07:00
Cary R c09b4035da The switch gates do not support a strength specification.
This patch splits the switch types out of the gates to allow
them to be defined to not take a strength specification.
(cherry picked from commit df4722b92c)
2010-08-06 21:26:35 -07:00
Cary R 6c996c1056 V0.9: We have already verified that we have a 64 bit immediate value.
These checks are not needed since we have already verified that
we have a 64 bit immediate value. This is likely old code that
should have been removed when the original functionality was
changed.
2010-08-06 21:18:23 -07:00
Cary R 9d6d9fd9d6 V0.9: Add unlimited tail recursion for the real ternary operator.
This patch modifies the real ternary operator code to support
unlimited tail recursion without overflowing the thread
registers. Head recursion is still limited by the available
registers.

It fixes the thread word checks to use a new define that has
the correct number of thread words (16). It adds a message
instead of just an assert if the thread words are exhausted.

And it also changes some of the error messages to use vvp.tgt
in the message to be consistent with the other messages.
2010-08-06 21:10:57 -07:00
Cary R 86f4e9560e V0.9: Only set the multiply width if it is greater than zero and vectorable
We only need to set the width of a multiple if the width is greater
than zero and if the expression is vectorable. This matches what is
done for addition.
2010-07-06 20:20:10 -07:00
Cary R 1e06094d1d Update fstapi files to match the GTKWave 3.3.8 release.
This patch updates fstapi.{c,h} to match the ones in the GTKWave
3.3.8 release.
(cherry picked from commit ed29161614)
2010-07-06 20:19:05 -07:00
Cary R 8e9c282ed4 V0.9: Fix some on error memory leaks in vvp.
This patch modifies the vvp main code to cleanup if there was an
error compiling the input file. There are still a few issues, but
this takes care of most of them.
2010-06-18 16:04:17 -07:00
Cary R 4a7bab0813 V0.9: On error there is no need to pop the scope.
The error routines for task and function definitions were incorrectly
popping the scope. This should not be done since no scope was pushed.
Also assert that the current_task/function is 0 to catch that kind of
error like the other definition rules.
2010-06-18 16:02:37 -07:00
Cary R b2fd383d05 V0.9: Fix shadow warnings found on OpenBSD.
gcc on OpenBSD reported shadow warnings for variables, arguments named
log, time and exp. This patch renanes those variables to logic, timerec
and expr.
2010-06-18 16:01:10 -07:00
Cary R 34c34e33cf V0.9: back port of SunPro compiler support.
This patch combines all the changes needed to back port support for
the SunPro compilers to the stable branch.
2010-06-18 15:57:52 -07:00
Cary R 22faa019d1 Update fstapi.c to match latest from GTKWave.
(cherry picked from commit 263dff6fbe)
2010-06-11 17:40:23 -07:00
Cary R 1f35d57854 V0.9: Fix int/long warning. 2010-06-11 17:38:46 -07:00
Cary R a916f8e34e V0.9: Cache vpi_call error messages so we can include file and line info.
This patch caches the vpi_call error messages (task/function does
not exist, task being called as a function and function being
called as a task). This allows us to display the file name and line
number information for the invalid usage.
2010-06-11 17:38:39 -07:00
Cary R 6d56e356b4 Don't crash when using `define value for an `include argument.
When pushing the current file path we need to get past any `define
expansions that have been pushed onto the stack to find the real
file path.

This patch is partially based on a patch submitted by Steve Tell.
(cherry picked from commit b2d479eaf6)
2010-06-11 17:36:57 -07:00
Cary R e11f4cf69e Don't crash if parameter/localparam defined from constant user function.
This patch avoids a crash when trying to use a parameter/localparam that
has been assigned a value from a constant user function. Icarus does not
currently support constant user functions so it creates a parameter with
a NULL value. This patch fixes a few places where this could crash the
compiler.
(cherry picked from commit 3f203c4363)
2010-06-11 17:35:41 -07:00
Cary R 597c3da220 V0.9: Fix shadow warnings add -Wshadow and update Makefile.in for SunPro
This patch combines a couple of things from the development patch.
It adds the -Wshadow flag and updates all the Makefile.in files to
support the gcc or SunPro compiler. It also fixes all the shadow
warnings. For the most part this is a copy of few patches from
development.
2010-06-11 15:56:48 -07:00
Cary R d165f32113 Add escaped identifier support to the FST dumper and some clean up.
This patch adds escaped identifier support to the FST dumper and
cleans up the VCD and FST code a bit. Also a simple spelling fix.
(cherry picked from commit 3fe68c4c04)
2010-06-11 15:55:04 -07:00
Cary R 5d320760eb Fix memory leak on error in driver/main.c.
(cherry picked from commit 09d59d744d)
2010-06-11 15:52:21 -07:00
Stephen Williams 1a725e063b Remove malloc.h support and for C++ files use <c...> include files.
The functions (malloc, free, etc.) that used to be provided in
malloc.h are now provided in cstdlib for C++ files and stdlib.h for
C files. Since we require a C99 compliant compiler it makes sense
that malloc.h is no longer needed.

This patch also modifies all the C++ files to use the <c...>
version of the standard C header files (e.g. <cstdlib> vs
<stdlib.h>). Some of the files used the C++ version and others did
not. There are still a few other header changes that could be done,
but this takes care of much of it.

(Cherry-picked from 1993bf6f69)
2010-06-01 11:27:16 -07:00
Cary R 21aec4d995 Remove OpenBSD compilation warning.
This is a trivial change to remove a warning when compiling using
the latest version of OpenBSD.
(cherry picked from commit 8122432e47)
2010-06-01 11:00:18 -07:00
Cary R fbaecdff87 V0.9 back port of dumpers only sort scope list when needed.
We need a slightly different patch for V0.9 than development. The fst
patch already has this change and the lxt2 file in V0.9 also needs
this change. See the development patch for more information.
2010-06-01 10:57:58 -07:00
Cary R a346507e93 V0.9: add fst dumper support.
This patch adds fst dumper support just like was done for development.
These changes match the latest code for development except V0.9 does
not currently support returning a value from vpi_register_systf() and
it does not support vpip_make_systf_system_defined(). If these are
added sys_fst.c will need to be updated.
2010-06-01 10:57:49 -07:00
Cary R 7af35ed08f Fix config.h.in HAVE_ALLOCA_H and HAVE_FSEEKO defines
This patch fixes the config.h.in file to correctly undefine
these two defines so that configure can define them when
available.
(cherry picked from commit 5a6683197a)
2010-06-01 10:52:42 -07:00
Cary R 632a1b8024 Fix some large/negative immediate value compiler bugs.
Fix how immediate values are checked and allow a large negative
value to be returned from get_number_immediate().
(cherry picked from commit 7969a58eeb)
2010-06-01 10:13:30 -07:00
Cary R 743d16ce60 Fix lxt2 space/speed flags.
The lxt2 routine was referencing the lxt not the lxt2 versions
of the space/speed flags. This also adds the lx2 version of the
flags. These were already supported in the sys_table.c file.
(cherry picked from commit f268af3580)
2010-05-21 17:30:05 -07:00
Cary R 644610828e lxt_write.c and lxt2_write.c reference <config.h> not "vpi_config.h"
Since the base lxt_write.c and lxt2_write.c files reference <config.h>
instead of "vpi_config.h" all their definitions need to be moved to
the main config.h include file.
(cherry picked from commit 3f433b325f)
2010-05-17 20:57:47 -07:00
Cary R afd18466cc Update lxt_write.c to fix OpenSolaris compile warning.
(cherry picked from commit ffa1f1139b)
2010-05-13 19:08:34 -07:00
Cary R bda4a30847 Update lxt_write.c and lxt2_write.c to latest files from GTKWave.
These files were updated based on a patch I sent Tony.
(cherry picked from commit c8d160a007)
2010-05-13 18:50:04 -07:00
Cary R d3f60a2a98 $dist_erlang needs to use rtl_dist_erlang.
The erlang distribution calltf routine was incorrectly using the
normal distribution.
(cherry picked from commit 26b95b94f7)
2010-05-03 15:34:57 -07:00
Cary R c781db5779 Remove bitchar_to_idx() function in tgt-vvp/vvp_process.c
This function is no longer used and was likely replaced with a
different scheme, so serves no useful purpose.
(cherry picked from commit 8dfe9961c8)
2010-05-03 15:33:02 -07:00
Cary R c36e1f0703 tgt-stub/memory.c is no longer needed/valid
The tgt-stub/memory.c file is not used and uses an obsolete ivl
interface so it serves no useful purpose.
(cherry picked from commit 6451523f73)
2010-05-03 15:28:44 -07:00
Cary R eed962c787 Update lxt_write.h and lxt2_write.h from GTKWave
This patch updates the lxt_write.h and lxt2_write.h header files
to the latest ones from GTKWave CVS. It also adds HAVE_INTTYPES_H
to the vpi_config.h.in header.
(cherry picked from commit bf54c838a6)
2010-05-03 15:24:55 -07:00
Cary R 385b211851 V0.9 - Don't free a NULL iterator in $dumpvars.
This patch fixes two places where Icarus under certain conditions
would try to free a NULL iterator value in $dumpvars(). $dumpvars()
can have a NULL argument to indicate that all variables should be
dumped. Under two error conditions the code was trying to free
this NULL argument reference.

The standard does not define if vpi_free_object() can support a
NULL reference. Icarus does not currently allow it (it asserts).
2010-05-03 15:22:00 -07:00
Cary R 7a363625d4 Add support for bit <-> real conversion for output ports.
This patch adds support for converting bit based ports to real signals.
You can only do this for single instances. Arrayed instance would
create multiple instances driving the same real signal.

Any real port can be connected to a bit based signal. The only limitation
is that the signal width must be an integer multiple of the instance
count since all the real conversions must have the same width.

Also add an error message for an arrayed instance with real to real
output connections. Again multiple drivers.

This patch also adds errors for inout real and bit based inout ports
driving a real signal. There is no logical way to deal with the full
capabilities of inout and real ports/signals. So for now they are not
allowed.
(cherry picked from commit e0001de3ba)
2010-05-03 15:18:02 -07:00
Cary R d614a81b2b Remove obsolete VAMS $log function.
This patch remove the old VAMS $log function. It could create confusion
with the Verilog $log task. Recent versions of VAMS and 1364-2005 use
$log10 for the base 10 logarithm.
(cherry picked from commit 2eb01605b1)
2010-05-03 15:09:16 -07:00
Stephen Williams 8ac5412a35 Account for unsized arguments to comparisons.
Comparison expressions have sorta-self-determined arguments.
Handle the special cause that some of the arguments may be
themselves unsized, and so expecting to be even wider then
otherwise.
(cherry picked from commit c4098cffdf)
2010-04-27 12:02:15 -07:00
Cary R c56b31c632 V0.9 Remove some gcc-4.3.4 warnings (Cygwin)
The latest gcc with the latest Cygwin complains when passing a char to
the toupper, tolower, isspace, isalnum, isprint, isdigit or isalpha
functions/macros. These functions are defined to take an integer. This
patch adds cast to int as needed to remove the warnings. After this
there are still two warnings related to a signed/unsigned comparison
in yy_get_next_buffer() (part of flex).
2010-04-14 13:12:31 -07:00
Cary R 2b63da8920 Fix thread modulus code to sign extend correctly.
When the width of a long long match the vector width we do not need
to sign extend and using the << operator for this case is undefined.
(cherry picked from commit 23a1ec9f53)
2010-04-14 13:09:22 -07:00
Cary R dbcbaab847 Fix a comment typo
(cherry picked from commit 6f9e364dab)
2010-04-14 13:08:13 -07:00
Cary R b7cba671ba Do not search up for a symbol if a hierarchical path was given.
When searching for a symbol we do not want to search up the
hierarchical stack if the symbol we are searching for was
prefixed with a hierarchical path.
(cherry picked from commit 3aaacd4c79)
2010-04-14 13:01:17 -07:00
Cary R 65ba9c3bf5 Set negative absolute SDF delays to zero.
The SDF standard allows negative absolute delays, but simulation
tools cannot handle this so set negative delays to zero.
(cherry picked from commit 301bbe94a0)
2010-04-02 17:15:01 -07:00
Cary R a0681e580f The SDF timing spec list can have zero or more elements.
The SDF file format supports zero or more timing specs. Previously
the parser was one or more. Things like tie high/low cells do not
have any delay information so zero or more is needed and matches
the standard.
(cherry picked from commit 68b1273d2d)
2010-03-30 11:33:59 -07:00
Cary R 855daae00f Fix line number error with to end of line comments.
The single line comment "//" was getting double counted.
(cherry picked from commit cbce1ddc04)
2010-03-30 11:33:41 -07:00
Cary R 4ee4d735c3 Use WIN32 instead of CYGWIN in tgt-null
(cherry picked from commit 99eac44ad1)
2010-03-25 12:49:21 -07:00
Cary R 6da47b1eba Perform bit <-> real conversions for module inputs.
This patch makes the compiler perform either bit to real or
real to bit conversion when needed on module input signals.
(cherry picked from commit 8e69764834)
2010-03-25 12:46:14 -07:00
Cary R baa3352ef1 vpi_get_value should return an appropriate value during compiletf.
The vpi_get_value() function should not crash when called during
the compiletf phase. This patch fixes this by returning 'bx for
any vectors in thread space. It also fixes some other minor things
that my test code uncovered. Most of the other objects work as
expected.
(cherry picked from commit bc7a5a9725)
2010-03-25 12:42:39 -07:00
Cary R 059068f070 Ignore zero replication constants.
This patch enhances elaboration to drop/ignore zero replication
count constants. Not doing this was causing problems later in
the compiler. We still pass non-constant expressions since
both user and system functions must be run for their possible
side effects. Constants can never have a side effect so just
dropping them is acceptable.
(cherry picked from commit 9a94d55738)
2010-03-22 18:11:58 -07:00
Cary R 53c206f2c5 Fix space issues.
(cherry picked from commit 2a463f00b3)
2010-03-22 18:10:50 -07:00
Cary R 19858807fe Add scope information for named blocks (begin/fork).
This patch adds the appropriate scope changes to get the scope
information correct for named blocks.
(cherry picked from commit 440cbba1d6)
2010-03-22 18:07:54 -07:00
Cary R 1c03cdafaf Fix trailing garbage in previous patch .
(cherry picked from commit 9cbb9251b4)
2010-03-16 15:51:52 -07:00
Cary R e3b16d72a3 NB-assign needs to convert reals at the l-value width.
This patch mimics what was done for normal assignments to get the
width correct for nonblocking assignments when converting a real
r-value to a l-value vector.
(cherry picked from commit d5c10af4f4)
2010-03-16 15:51:38 -07:00
Cary R 86fad34813 Make taking an edge of a named event an error.
A named event does not have an edge so taking a posedge or negedge
is illegal. This patch adds an error message for this. Before the
edge was being ignored for named events, but this is incompatible
with other tools.
(cherry picked from commit 4af24b6b9e)
2010-03-16 15:48:34 -07:00
Stephen Williams 73a9880417 Fix broken $() substitution in command files.
(cherry picked from commit 8d65d0735a)
2010-03-16 15:24:26 -07:00
Cary R 5680dec04c Add missing strtoul argument
The previous patch missed this some how. I don't know how it compiled
correctly before!
(cherry picked from commit 08d0337e50)
2010-03-08 14:58:30 -08:00
Cary R d14c3449e4 Ignore bit selects in SDF INTERCONNECT lines.
Icarus does not support interconnect delays so INTERCONNECT is
currently ignored. The SDF parser does not currently support a
bit select as a port_instance. Since we are already ignoring
the INTERCONNECT I added support for bit selects there. This
is probably the most common place to find them.
2010-03-08 14:57:07 -08:00
Stephen Williams 526b114d18 Minor fixes to README.txt file.
(cherry picked from commit b48b833dab)
2010-03-05 16:03:23 -08:00
Martin Whitaker 1e09352f11 Fix for pr2943394 (v0.9 branch).
This patch fixes the behaviour when a variable or net is released
when it is not currently forced.
2010-02-10 17:23:42 -08:00
Martin Whitaker 7363e4326d Fix for LXT/LXT2 output using MinGW.
When using MinGW, routines registered via atexit() inside a
DLL are only called when the DLL is detached. If not detached
manually, DLLs are automatically detached *after* all remaining
open files are closed. This meant that by the time the LXT or
LXT2 close_dumpfile routine was called, the dump file handle
was no longer valid, so any remaining output was lost. This
patch fixes the problem by manually detaching the VPI modules.
(cherry picked from commit 4818db887e)
2010-02-10 17:21:14 -08:00
Stephen Williams 90144cfb3c Merge branch 'v0_9-branch' of ssh://steve-icarus@icarus.com/~steve-icarus/git/verilog into v0_9-branch 2010-02-03 09:00:13 -08:00
Cary R 971576589e Fix some MinGW compile warnings.
This patch fixes some compile warnings found using the latest
MinGW compiler.
2010-02-02 21:00:56 -08:00
Alan M. Feldstein 65744da19c Use appropriate makefile dependencies option for Sun Studio 12 C++ compiler. 2010-02-02 20:56:03 -08:00
Alan M. Feldstein dec724b8f3 Not all C++ compilers recognize (or need) -Wall. 2010-02-02 20:50:21 -08:00
Alan M. Feldstein 24355dae67 Not all C compilers recognize (or need) -Wall. 2010-02-02 20:49:50 -08:00
Cary R c337b0ef0c Fix an obscure memory leak and fix formatting.
This patch fixes an obscure memory leak and make the formatting
of these two routines match the rest of the code in the file.
(cherry picked from commit 7866e92761)
2010-01-25 14:56:25 -08:00
Martin Whitaker 8fc049eefd Fix for pr2922063.
When handling the $signed/$unsigned system functions, the compiler
was applying the new signed/unsigned property to the NetExpr object
representing the input argument. This caused the input argument to
be evaluated incorrectly. This patch fixes this by applying the new
property to the NetExpr object created to pad the result to the
required size.

In testing this fix, it was also discovered that the width of the
input argument expression was not being calculated correctly. This
patch also fixes this issue.
(cherry picked from commit 14b2037ce4)
2010-01-25 14:49:11 -08:00
Nick Gasson 2be20d49ed Fix build with gcc-4.5
New version of GCC does not like the X::X() construct.
(cherry picked from commit b855b0368d)
2010-01-25 14:47:04 -08:00
Cary R 03411aba85 realloc() to the correct string.
Someone had mistyped the destination of the realloc. It should
have been the original string not the input buffer.
(cherry picked from commit 6eb5f593f0)
2010-01-25 14:44:38 -08:00
Martin Whitaker 70d2f7e353 Fix for pr2929913 (v0.9 backport).
After changing an array word, vvp propagates the change to every port
attached to the array. The code did not properly handle the case of
an array port declared in an automatic scope with an associated array
declared in a static scope.
2010-01-25 14:41:54 -08:00
Cary R c03aed2b17 Fix some constant bit/part select bugs and add warnings.
This patch fixes a few bugs in constant bit/part selects and
adds optional warnings for out of bound or undefined selects.
(cherry picked from commit 5a0363ebd3)
2010-01-25 14:37:10 -08:00
Cary R 2d1b8e4c81 Add +timescale to the command file.
This patch adds a +timescale command to the command file
syntax that can be used to set the default time scale of
the simulation.
2010-01-25 14:32:59 -08:00
Cary R 9afa95dff7 A signal select is signed if the select not the signal is signed.
The padding for a signal select was using the signal to determine
if the padding should be singed or not. In reality this should be
unsigned padding unless the select was enclosed in a $signed().
(cherry picked from commit 458258d554)
2010-01-09 11:43:43 -08:00
Cary R 2718f85222 vpi_get_vlog_info should return the version information.
This patch fixes vpi_get_vlog_info to return the VERSION.
(cherry picked from commit ea4bae7c33)
2010-01-09 11:40:15 -08:00
Stephen Williams a08de693d4 Step to the 0.9.2 release.
Advance version stamps.
2009-12-30 08:45:06 -08:00
Stephen Williams 37837f3904 Fix references to version_base.h in Makefiles.
(cherry picked from commit d2dd0daa3c)
2009-12-28 09:50:34 -08:00
Cary R daa01a05d8 A constant real number is not unsized.
We can have unsized bit values, but reals always have a size.
(cherry picked from commit ebac088511)
2009-12-28 09:34:57 -08:00
Cary R 9cd7a22dbe Having lround() does not mean llround() is available.
We need to check for both lround() and llround() for at
least Cygwin.
(cherry picked from commit a1e2bfc93c)
2009-12-25 18:16:52 -05:00
Martin Whitaker f733030b41 Add warning about casting large integer values to reals.
The compiler and vvp runtime don't correctly handle casts to reals
when the source value is more than 63 bits in magnitude. This is
fixed in devel, but can't be backported to v0.9 because it adds new
vvp instructions. This patch causes the compiler to output a warning
about potentiall incorrect results.
2009-12-25 17:53:08 -05:00
Martin Whitaker 99f7d1197c Make vvp thread word storage consistently 64 bits (backport to v0.9).
The vvp thread word storage had previously been changed to always store
64-bit values, but some instructions still only operate on native long
values. This patch ensures all instructions that modify thread words
support 64-bit values.
2009-12-25 17:51:56 -05:00
Cary R 7817e479a4 V0.9 - Add suffix support for windows (both MinGW and Cygwin).
dlltool which is used by both MinGW and Cygwin to create dynamic
libraries must have the name of the executable it creates the
library/information from exactly match the installed executable
name. If we have a suffix then it must be used. This patch adds
that to the build process for vvp since it can be installed with
a suffix. It also modifies the check routines since you must run
vvp with a suffix if the library it links to was built for a
suffixed executable.
2009-12-25 11:53:36 -05:00
Cary R 0c97cabe18 Use the correct line information in crop_to_width()
This was using its own information instead of the input nets information.
2009-12-25 11:37:50 -05:00
Cary R e56c142dff Reuse the number of input information.
This was already assigned to a variable so lets use that instead of
geting it again.
2009-12-25 11:37:35 -05:00
Cary R 7e06a87b8e Properly extend/crop a user function argument in a continuous assignment.
When passing an argument to a user function in a continuous assignment
we need to sign extend the value if it is signed and too short. We need
to crop an argument if it is too long.
2009-12-25 11:37:16 -05:00
Cary R 0c3eef4c41 Function arg. expressions need to use the expr. width and arg. width.
When evaluating a function argument expression we need to use either
the expression width or the argument width which ever is larger. This
matches the way normal assignments work. We then only take the bits
needed at the end.
2009-12-25 11:33:12 -05:00
Cary R 3b22be5507 A ternary can be signed.
If the two branches of a ternary are signed then the result will
also be signed.
2009-12-25 11:28:03 -05:00
Nick Gasson 287b19f22d VHDL: fix spurious resize seen in pr2911213
Another case when ivl_scope_sig list was used instead of
ivl_scope_param.
2009-12-25 11:26:46 -05:00
Cary R 8de7fc6161 Add suffix support to MinGW.
This patch adds suffix support to the relative path that MinGW
calculates in both the iverilog and vvp executables.
2009-12-25 11:22:25 -05:00
Cary R 663ab34ae7 V0.9 Add casts/etc. in vvp directory to remove Cygwin compile warnings. 2009-12-15 07:29:06 -08:00
Cary R b5c819051b Fix out of bounds select warning text in man page.
(cherry picked from commit 8144283b0d)
2009-12-15 07:26:12 -08:00
Cary R fdbc212349 Fixe .cast documentation.
(cherry picked from commit a228d53cc2)
2009-12-15 07:24:42 -08:00
Nick Gasson d35d542b9e VHDL: ensure with-select statement choices completely cover input space
Newer versions of GHDL seem to be stricter when checking this than
older versions. ModelSim still accepts an incomplete with-select,
however.

This patch makes the output 'U' if none of the conditions match.
(cherry picked from commit 9c568d8f47)
2009-12-15 07:22:26 -08:00
Cary R 8139551908 Add CFLAGS to vvp/Makefile.in
We do have one C program in the vvp directory so add CFLAGS to
the Makefile. This patch also modifies the two local programs
tables and version to use -Wall.
(cherry picked from commit 1a25b3deda)
2009-12-12 08:36:02 -08:00
Nick Gasson 021ae6c08f VHDL: emit function parameters in correct order
The function draw_scope was extracting the input/output parameters
just by looking at the (unordered) list of signals in the function
scope rather than using the ivl_scope_ports list.
(cherry picked from commit a9c85cf5b6)
2009-12-12 08:34:47 -08:00
Cary R b8b1bc4a36 Add some casts in libveriuser to remove warnings.
The Cygwin compiler is a bit picky. This patch adds some casts
to remove compilation warnings. In the past I have had warnings
off because of problems with the STL, but for C directories
like this it makes sense to enable the warnings. It also does
not recognize that an assert(0) or assert(false) ends a routine
so it complains about no return at end of function or variables
not being defined.
(cherry picked from commit 6ae1f64c3c)
2009-12-12 08:31:31 -08:00
Cary R 327cdc77a3 Add some casts in tgt-vhdl to remove warnings.
The Cygwin compiler is a bit picky. This patch adds some casts
to remove compilation warnings. In the past I have had warnings
off because of problems with the STL, but we may as well get
rid of the warnings we can. It also does not recognize that an
assert(0) or assert(false) ends a routine so it complains about
no return at end of function or variables not being defined.
(cherry picked from commit 3f12a401eb)
2009-12-12 08:31:15 -08:00
Cary R a8e1643ae9 Add some casts in vpi to remove warnings.
The Cygwin compiler is a bit picky. This patch adds some casts
to remove compilation warnings. In the past I have had warnings
off because of problems with the STL, but for C directories
like this it makes sense to enable the warnings. It also does
not recognize that an assert(0) or assert(false) ends a routine
so it complains about no return at end of function or variables
not being defined.
(cherry picked from commit f31a4e6d20)
2009-12-12 08:30:40 -08:00
Cary R 02a986b35d Add some casts in main directory to remove warnings.
The Cygwin compiler is a bit picky. This patch adds some casts
to remove compilation warnings. In the past I have had warnings
off because of problems with the STL, but for this directory we
mas as well remove the warnings we can. It also does not
recognize that an assert(0) or assert(false) ends a routine so
it complains about no return at end of function or variables
not being defined.
(cherry picked from commit 81d4cbc4bd)
2009-12-12 08:26:55 -08:00
Cary R 8759eaf720 Remove extra MinGW only varaible in t-dll.cc.
(cherry picked from commit 1f375ef16a)
2009-12-12 08:26:34 -08:00
Cary R daff9ed30d Remove version.exe with a -f to avoid a warning.
If version.exe does not exist and we don't have a -f then we
will get a warning.
(cherry picked from commit 05a3929b1a)
2009-12-12 08:26:09 -08:00
Martin Whitaker e4a319cfe2 Fix for pr2909414.
Currently the compiler only applies defparam statements that are
found in the initial root module hierarchy. This patch ensures that
defparam statements within scopes created by generate constructs or
instance arrays are also applied.
(cherry picked from commit e2be397aa8)
2009-12-12 08:22:09 -08:00
Cary R 3d5c6c6f30 Remove unused MinGW variable.
There was an unused variable in driver/main.c under MinGW.
(cherry picked from commit 392ac1200c)
2009-12-11 09:25:07 -08:00
Cary R c44ce66a87 Add debug_eval_tree code for the pow operator.
The power operator was missing eval_tree debug information.
This patch fixes that deficiency.
(cherry picked from commit a85880a8bb)
2009-12-09 19:10:12 -08:00
Cary R ce8a84db3c For MinGW make driver/main.c always create a path with a back slash
The MinGW executable should be able to support a path with mixed
separators, but to make things consistent all the path in the main
driver program (driver/main.c) now always use a '\' or convert a
path to use '\' (e.g. getenv() returns a path with a '/').
(cherry picked from commit e9c653dfa3)
2009-12-09 19:08:59 -08:00
Martin Whitaker 33c852d2b4 Reduce memory use for simulations that run in zero time.
The fix for pr1830834 causes vvp to only delete a completed thread
when the simulation time next advances. If a procedural model is
being simulated which makes many task or function calls within a
single time step, this can lead to excessive memory use. This patch
modifies the behaviour so that thread deletion is only delayed if
that thread has caused a sync event to be placed in the event queue.
This should catch all cases where the thread private data can be
accessed after a thread has terminated.
(cherry picked from commit c7b0aef414)
2009-12-09 19:05:26 -08:00
Cary R 1eb593e8ad Make the verinum pow operator work correctly.
The functionality of the integer power operator is specified in
1364-2005 on page 45-46 and specifically Table 5-6. This patch
fixes the verinum pow operator to work as specified in this
table. It also fixes an error in the == operator when both
operators are signed and only the left argument is negative.
(cherry picked from commit eea816e423)
2009-12-09 19:02:28 -08:00
Cary R 8ef7344ea5 Update wavealloca.h to fix MinGW compilation warning
This patch fixes a warning when compiling vpi/sys_lxt2.c under
MinGW regarding the definition of alloca().
(cherry picked from commit 59ebd47ba6)
2009-12-09 19:00:53 -08:00
Stephen Williams 5479aaf721 Add explicit dependencies on generated header files.
These explicit dependencies are not normally needed (because they
are covered by automatic dependency generation) but when the "-jN"
flag is passed to gmake, they help gmake schedule parallel builds.
2009-12-04 15:20:03 -08:00
Stephen Williams b85b2d8a26 More portable use of tail.
Apparently, tail +2 is not portable, but tail -n +2 should work.
2009-12-04 14:57:36 -08:00
Cary R 8b7ffa1a17 Update lxt/lxt2 files to latest from GTKWave.
This patch updated the four file lxt_write.{c,h} and
lxt2_write.{c,h} to the latest ones from GTKWave. This
required adding the wavealloc.h include file and an
update to configure.in and vpi/vpi_config.h.in to add
checks/definitions for ALLOCA and FSEEKO.
(cherry picked from commit b6f7354cee)
2009-12-03 08:21:12 -08:00
Cary R 9b6e9f5832 Add support for spaces in many paths/files names
This patch adds support for spaces in the path to the temporary files.
Adds support for spaces in output files and in library paths.

A space in the installation path is only supported under MinGW
(windows) at this time.
(cherry picked from commit dba2a6e434)
2009-12-03 08:19:32 -08:00
Cary R ab926ccee4 Convert a few sprintfs to snprintf
This patch converts a few sprintf statements to snprintf
to protect against buffer overflow.

It also converts a few sizeof calls from sizeof(x) to
sizeof x like other places in the code.
(cherry picked from commit f44c1cadde)
2009-12-03 08:18:20 -08:00
Cary R 3351004945 Remove unneeded definitions in drivers/globals.h
There were a bunch of unneeded definitions in drivers/globals.h.
All of these were only used in main.c so do not need to be in a
header file.
2009-12-03 08:15:24 -08:00
Cary R 7684814593 Minor rework of how driver-vpi is supported.
Add driver-vpi to either SUBDIRS or NOTUSED depending on if we
are building for MinGW or not. This is more logical and allows
the clean and distclean targets to be simplified.
(cherry picked from commit 145133bdb0)
2009-12-03 08:08:41 -08:00
Stephen Williams 3f29f96695 Fix delays in continuous assignment to support 64bit delays.
Remove the 32bit restriction on a few cases of delays in continuous
assignment expressions.
(cherry picked from commit de1f17d429)
2009-12-01 10:21:57 -08:00
Stephen Williams 7210061f2c Make all should build the iverilog-vpi.man file.
The "make install" target may not in general be able to build
the iverilog-vpi.man file, so make sure it it build by make all.
(cherry picked from commit 2e60a181c0)
2009-12-01 07:40:48 -08:00
Cary R 2396faac39 Add basic support for spaces in the install path for MinGW.
This patch adds support for spaces in the install path on MinGW.
It does this by converting the Long version of the iverilog path
into a Short version that does not have spaces in it. If we don't
do this then we can not add support for other arguments with
spaces in the path or filename. It also modifies the driver-vpi
program to support spaces in the saved ivl path. This is done by
just enclosing the include and library path argument in double
quotes.

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

The distclean target was also enhance so that when
building from a remote directory (srcdir != .) we
remove all the extra files and directories.
(cherry picked from commit 6909737bf2)
2009-12-01 07:38:11 -08:00
Cary R 14bc857c54 Make MinGW compile using a remote build directory.
This patch fixes a few MinGW specific issues that prevented it
from building in a remote directory.
(cherry picked from commit 8abe0d7d71)
2009-12-01 07:37:58 -08:00
Stephen Williams f49f3f56cf Make version.exe so that subdirs can get access to it.
(cherry picked from commit 342ec152bc)
2009-12-01 07:37:33 -08:00
Cary R c89ae29bf2 Fix some extra/invalid font switches in iverilog.man.
Cleanup some unneeded \fP statements and remove the invalid and
unneeded \fp statement. Slightly reword the __ICARUS__ definition.
(cherry picked from commit 74634864cf)
2009-12-01 07:34:19 -08:00
Stephen Williams d570437a17 Unify the version stamp in the version_*.h header files.
Try to put all the version stamps into common version_base.h
and version_stamp.h header files. All the source programs then
get their version from these header files.

Also handle the version stamps in the man pages by using the
version_*.h header file contents to edit the version strings
in the man page title bar markers.
(cherry picked from commit 966e29db3b)

Conflicts:

	driver/iverilog.man.in
	iverilog-vpi.man.in
	version_base.in
	vpi/vams_simparam.c
	vvp/vvp.man.in
2009-11-27 12:37:11 -08:00
Stephen Williams 0cc8285a01 Handle case that delay output is pending when new event arrives
If the delay has an event pending for the current time, then use
that as a reference for calculating the next delay. If that is not
done, then the delay calculated against the wrong reference might
result in zero, and bad results.
(cherry picked from commit f07577db11)
2009-11-25 07:50:35 -08:00
Stephen Williams d090fd7a17 Fix vpi_control operation codes to be standard
Apparently, the vpi_user.h definitions for vpiStop et al were added
before they were standardized by 1364-2000, and never corrected.
Change the values to be standard. (Submitted by Matt Trostel.)

I also added some binary compatibility for existing .vpi modules
that were compiled with the older constant values.
(cherry picked from commit 711365521d)
2009-11-05 06:41:51 -08:00
Cary R 09cdf5268e Add more non-breaking hyphens in the manual pages.
This has been started, but this patch adds a bunch more (all?) of
the non-breaking hyphens needed in the manual pages.
2009-11-03 14:47:12 -08:00
Martin Whitaker c1f750ff98 Fix vvp code generator bug for CA function calls with array word arguments.
If a function in a continuous assignment is passed an array word as
an argument, syntactically incorrect vvp code is generated. This is
because the code calls draw_net_input to generate the input labels
part way through writing out the .ufunc statement. If an input is
an array word, draw_net_input causes a .array/port statement to be
emitted, which gets written out in the middle of the .ufunc statement.
This patch fixes the problem by collecting the necessary input labels
prior to starting writing the .ufunc statement.
(cherry picked from commit 9950704735)
2009-11-01 11:09:07 -08:00
Cary R c7414f79b0 Add a waring that timing check delayed signals will not be driven.
The $setuphold and $recrem timing checks can create delayed signals
that are needed to get a model to work correctly when negative timing
check values are used. Since we do not support timing checks and just
ignore them this can create simulation problems when a user tries to
use these delayed signals since they are not driven.

This patch adds a waring when the circuit is being compiled that these
delayed signals will not be driven. This will be needed until we get
time to add the real timing checks are mimic the delayed properties of
the timing check.
(cherry picked from commit a5060b8adc)
2009-11-01 11:02:15 -08:00
Cary R 95eec69102 Cleanup a few more issues found with cppcheck.
Minor fixes and code reorganization to remove a few more issues
that cppcheck is complaining about. It has a few false warnings
and some issues that need more investigation.
(cherry picked from commit ae49197a14)
2009-11-01 11:00:53 -08:00
Stephen Williams 23ea74a126 Implement cbAtStartOfSimTime callback.
(cherry picked from commit 1b7a42ffcd)
2009-11-01 10:53:13 -08:00
Stephen Williams 70f15b472f Fix the vpiObjTypeVal for signals to be scalar or vector.
Scalar signals have a preferred type of vpiScalarVal, but vectors
have a preferred type of vpiVectorVal. Use the signal width to
distinguish.
(cherry picked from commit 5fb89262df)
2009-11-01 10:52:43 -08:00
Cary R 73d9a37020 Cleanup Makefile clean targets.
This patch removes bin32 from the clean targets since it is no
longer user/created. It adds autom4te.cache to the distclean
target in the main directory. It removes the files in driver
that are not created (lexor.c parse.c, etc.). The *.cc.output
files are no longer created so removing them is not needed.
(cherry picked from commit cf2f99ec3d)
2009-10-29 10:55:20 -07:00
Cary R 13921f0c0c Add a warning message if an environment variable is not found.
Instead of silently skipping the substitution we now print a warning
message if an environment variable substitution is not found.
(cherry picked from commit 83aa1363ea)
2009-10-29 10:54:12 -07:00
Cary R 29f5c882eb Add support for ${var} substitutions in the command file.
We still support $(var).

(cherry picked from commit 4cb39f584d)

Conflicts:

	driver/iverilog.man
2009-10-29 10:52:25 -07:00
Stephen Williams 98c3391acb Fix index out of bounds error message.
When displaying an index out-of-bounds message, use the index
given in the source code, not the canonical (translated) value.
(cherry picked from commit 37b11e0355)
2009-10-28 19:20:00 -07:00
Stephen Williams f5728c4a39 Add appropriate hysteresis to tranif input pins.
The tranif input pins are normally nothing special, but sometimes
they are fed back from the switch body. In this case, the control
needs to see the current *output* from the fed back port, in order
to get the results that people expect.
(cherry picked from commit 33158355ba)

Conflicts:

	tgt-vvp/draw_net_input.c
	vvp/island_tran.cc
2009-10-28 16:32:40 -07:00
Cary R cca3b0ed5a V0.9: Fix memory.h include issues.
The local "memory.h" file is no longer used in V0.9 or development,
so it does not need to be included in vvp/codes.h. The VHDL target
does not use the system <memory.h> header file so there is no need
to have a define for it in the vhld_config.h.in file.
2009-10-26 11:16:50 -07:00
Cary R 391ef78d42 Add error message that only 32 bit immediate CA delays are supported.
The .delay (x,y,z) functor and the get_number_immediate() function
only supports 32 bit delay values. This patch adds an error message
if the user passes a larger, but valid value.
(cherry picked from commit 1f0857606a)
2009-10-26 11:14:19 -07:00
Jared Casper ab5b9271f3 Still more build system cleanup.
- Add missing dependency of configure on aclocal.m4.

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

- Add stamp files to .gitignore
(cherry picked from commit c167b3a01f)
2009-10-26 11:12:04 -07:00
Jared Casper 7eb4825435 More build system tweaks, fixing pr2881797.
Use the time stamp file technique recommended by the autoconf manual
to prevent unneccesary rebuilds because of an unchanged config.h.
Uses the automake trick of generating the stamp files in the
_AC_AM_CONFIG_HEADER_HOOK macro instead of littering the source
directory with stamp-h.in files.

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

An orthogonal fix of how config.status is called in subdirectories.
When in a subdirectory and config.status is called with
../config.status and $(srcdir) is a relative path, config.status gets
confused.  Fixed by replacing '../config.status --file=Makefile.in'
with 'cd ..; ./config.status --file=<dir>/Makefile.in'
(cherry picked from commit 7ead2aa88b)
2009-10-20 10:04:01 -07:00
Cary R 58511ab212 More valgrind cleanup.
This patch adds code to cleanup system functions driving a
continuous assignment. It also modifies the user function
cleanup to not interfere with this. It also adds a count
of the nets and signals that were not cleaned up that is
pnly printed when running valgrind. They are not flagged
y valgrind since they are pool managed objects. There are
a few signals that need to be cleaned up and local nets
are missed so there are a lot of nets.

(Cherry picked from dec524a151)
2009-10-20 10:00:05 -07:00
Cary R b3ca7e1774 Update the simulator subversion. 2009-10-20 09:51:14 -07:00
Jared Casper 5e8e59484b Base Makefile improvements.
Instead of calling make in subdirectories using a sh for loop, use GNU
make's $(foreach ) to create a string of commands connected with &&.
This way an error in a subdirectory will stop the build, instead of
continuing on to the next subdirectory, which the old version does.

Also added rules to regenerate configure when configure.in changes,
and to run config.status --recheck when that happens.
(cherry picked from commit d098db0a06)
2009-10-19 07:57:55 -07:00
Stephen Williams 517b4e3248 Get drive of pull-ups right.
The drive for a pullup comes from ivl_nexus_pt_drive1. Get this
wrong and a pullup turns into a HiZ.
(cherry picked from commit 6b17dcc587)
2009-10-14 10:14:37 -07:00
Cary R a6fdb4b6e6 Clean up user function calls from thread space.
This patch adds cleanup code that cleans up the memory that is
allocated by the of_EXEC_UFUNC command. This knocks a few more
files off the valgrind list.
(cherry picked from commit 02ca7fe7fc)
2009-10-14 10:11:06 -07:00
Cary R ad786a2aa3 Don't replace parameter overrides that did not evaluate.
Trying to replace a parameter override that did not evaluate
correctly can lead to a crash, so just skip the substitution.
(cherry picked from commit 8abf303753)
2009-10-14 10:05:20 -07:00
Cary R e92c4638ed $clog2() should return an integer value.
The constant $clog2() was returning a value that had an integer
width, but it did not have the sign bit set. This could result
in incorrect math expressions. This patch sets the sign bit for
the constant $clog2() result.
(cherry picked from commit bc60536eb9)
2009-10-14 10:02:20 -07:00
Cary R fd4b849091 In driver-vpi only look at the first CC word when checking compiler path.
In the MinGW version of iverilog-vpi (C version located in driver-vpi)
we must only look at the first word of the IVERILOG_VPI_CC definition.
A recent change to the configuration process made this equal to
"gcc -std=gnu99" which will not be found when looking for the
gcc executable. We nee to look for "<path>\\bin\\gcc.exe". This
patch modifies the driver to only use the first word when looking for
the compiler, but uses the full value when compiling.
(cherry picked from commit d9d8d4b093)
2009-10-14 09:59:39 -07:00
Cary R 98e5e36f03 We must have autoconf version 2.60 or later.
When AC_PROG_CC_C99 was added recently we created an implicit
requirement for autoconf version 2.60. This patch makes that
implicit requirement and explicit requirement.
(cherry picked from commit ff39575dc0)
2009-10-14 09:57:44 -07:00
Cary R 1a0d475907 Fix obscure valgrind memory leak.
(cherry picked from commit 3303cc144f)
2009-10-14 09:55:57 -07:00
Cary R 807a66f0a2 Add a configure check to see if uint64_t and unsigned long are identical.
This is needed to get vvp to compile under MacOS 10.6 and possibly other
64 bit systems that define uint64_t as unsigned long long vs unsigned
long (both are 64 bits).
(cherry picked from commit 39f243b18e)
2009-10-08 16:43:02 -07:00
Cary R 92e7587320 Format the --enable-suffix help correctly.
(cherry picked from commit 537ba93fe4)
2009-10-08 11:42:31 -07:00
Stephen Williams 04be3a6323 Do not cprop through ternaries if the selector is an l-value.
It turns out that it is possible for an otherwise constant net
mux to be non-constant if there is a force that can drive the
net. This can be detected as an l-value reference to an otherwise
constant selector.
(cherry picked from commit abc4eb9d52)
2009-10-06 07:20:44 -07:00
Cary R d2a900d187 Fix bug in vector8 operator=
operator= would try to overwrite it self under some circumstances.
This was found with valgrind and using -O0. It works with -O2.
(cherry picked from commit 9ea6604439)
2009-10-03 09:01:44 -07:00
Cary R eb9d79ec61 Check if the compiler supports C99 and better check for some math functions.
Add a configuration check that says we would like to use C99 if the
compiler supports it. Also change the lround(), nan(), fmin() and
fmax() checks to look in the default libraries as well as the math
library.

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

Add a missing int for main in draw_tt.c.
(cherry picked from commit ed7e9f8be5)
2009-10-01 12:01:11 -07:00
Cary R e8dada7337 The concat object can get out of sequence so don't optimize a repeat.
Under some situation the optimized repeat expression can get out
of sync while it is being processed this causes the code to
reference freed memory. This happens when the repeat expression
is converted to an unsigned integer, but the repeat expression
is used in a different path. It was easier to just remove the
optimization then track down the convoluted call sequence that
was causing this and then figure out what needed to be fixed.
The repeat expression must be constant, so is likely not too
complicated so this optimization is very minor and should not
be missed.
(cherry picked from commit 3259354d29)
2009-10-01 12:00:39 -07:00
Cary R 3dfc1d5097 Fix &A<> to support an undefined word index.
This patch adds support to &A<> for an undefined word index.
It mostly matches what was done for &PV<>.
(cherry picked from commit 4b50473939)
2009-09-24 16:06:21 -07:00
Cary R 6bbf97a05d Warn that a signed part select may not work for signals < 32 bits.
If a signed signal is driving a part select in a CA and the width
is less than 32 bits. the value will be zero extended and will
not work for negative values. This patch adds a warning that this
could happen. This will be fixed in development.
(cherry picked from commit e1af002a32)
2009-09-24 13:44:22 -07:00
Cary R e7815c3984 Optimize a full L-value indexed part select, etc.
This patch adds an optimization when a constant indexed part
select covers the entire L-value. It also fixes a few issues
in the code generator related to part selects.
(cherry picked from commit 09fa57742a)
2009-09-24 13:32:57 -07:00
Cary R fb01245501 Only process the first 32 bits of the part select base.
When reading from thread space only read the first 32 bits
(sizeof int) for the part select base. This matches the other
parts of the PV_get_base() code.
(cherry picked from commit c82baa2793)
2009-09-24 13:29:50 -07:00
Cary R d0a45ffe9d Warn that &A<> may have problems with a signed select from thread space.
Like the &PV<> code we should warn the user that a signed select
from thread space may not work correctly for &A<>. This will be fixed
in development.
(cherry picked from commit 1851cba955)
2009-09-24 12:16:54 -07:00
Stephen Williams 9c624a2403 Better portability for rpm install section.
(cherry picked from commit d3d84dde6a)
2009-09-23 15:56:16 -07:00
Stephen Williams 4d4a693248 Improve some assert messages
Replace some assert functions with ivl_assert.
2009-09-16 14:45:55 -07:00
Cary R 1872652019 Don't check the scope for array words.
We do not want to check an array word scope to see if the scope
was already included since a scope does not include array words.
They must be explicitly specified.
(cherry picked from commit 0b6bd343e8)
2009-09-15 20:51:11 -07:00
Cary R d68fea3f58 Warn that events can not be user task or function arguments.
This patch makes events passed as arguments to user tasks or functions
a compile time error with an appropriate error message.
(cherry picked from commit 4d57ede0e5)
2009-09-15 20:45:49 -07:00
Cary R b0e2185ade Fix 64 bit problem in vvp/vpi_signal.c
This is based on a suggested fix from Martin. It fixes the crash
for two tests in the test suite. As a bonus it is more efficient.
(cherry picked from commit 43f41572cb)
2009-09-15 20:40:14 -07:00
Cary R 6aaf2f84a8 Squash some gcc 4.3.3 warnings.
This patch clears all the gcc 4.3.3 warning that can be fixed.
The remaining warning is dictated by older versions of the
1364 standard.
(cherry picked from commit 6d5d06cae4)
2009-09-15 20:38:57 -07:00
Cary R 7ad50f4454 Revert one change from previous patch.
I was mistaken in changing the cast in the comparison.
(cherry picked from commit 5a11a8a9c2)
2009-09-15 20:35:48 -07:00
Cary R 19b0d5b7c9 Fix another 64 bit problem in a part select.
This patch fixes a problem in the .part/v select when the index is
undefined. The default value needs to be INT_MIN, so when the long
is cast to an int the value is in range.
(cherry picked from commit 1b300cb2f6)
2009-09-15 20:35:35 -07:00
Cary R ae87aff745 Fix .part/v to only use a 32 bit value.
To get better functionality in V0.9 and development until we
add a select that is sign aware to .part/v this patch uses
a 32 bit integer (int) for the select value. This allows a
normal Verilog integer to produce the correct results. A
warning for smaller signed index vectors is planned, but it
needs more input.
(cherry picked from commit 27f032760e)
2009-09-15 20:35:24 -07:00
Cary R 9c09394785 Add support for 'bx from a signal to &PV<>
&PV<> was just using vpi_get_value() when a signal was driving
the select. This incorrectly returned 0 for 'bx or 'bz. This
patch adds a check for an undefined value and returns INT_MIN
for this case.
(cherry picked from commit 1b0dd8c8e5)
2009-09-13 08:38:08 -07:00
Cary R 3f8f81568a Add file/line information to named events and better expr. error.
This patch adds file and line number information to named events.
It also modifies the draw_eval_expr_wid() routine to fail with
an appropriate message for named events. This checking needs to
be pushed into the elaboration stage, but this will give a better
message than we had before.
(cherry picked from commit dff6a1ebff)
2009-09-13 08:34:59 -07:00
Martin Whitaker bb5d30ead5 Add user control over implicit sensitivity list warnings.
This patch adds two new warning classes that can be enabled or
disabled via the -W command line option. The first controls
whether a warning is generated if a part select within an
always @* statement causes the entire vector to be added to
the implicit sensitivity list. The second controls whether a
warning is generated if a word select within an always @*
statement causes the entire array to be added to the implicit
sensitivity list. The first class is not automatically enabled
by -Wall, the second class is.
(cherry picked from commit fc49420cb5)
2009-09-13 08:27:54 -07:00
Nick Gasson 4e77abca44 Allow labelled begin blocks to contain processes in VHDL target
This is a simple fix for a crash that occured when a process
was inside a labelled begin inside a generate statement.
(cherry picked from commit face1a1d15)
2009-09-03 18:16:47 -07:00
Nick Gasson 902ae19bbf Handle generate scopes with signals in VHDL target
This uniques the name of each copy of a signal and adds
it to the containing VHDL entity.
(cherry picked from commit 388c9c6747)
2009-09-03 18:16:35 -07:00
Nick Gasson 5587e42e2e Translate simple generate loops to VHDL
This handles generate loops and genvars with no local variables
(cherry picked from commit bc7ec04cab)
2009-09-03 18:16:18 -07:00
Cary R f8f363a0b6 Remove old configure files in vvp directory.
(cherry picked from commit 5f08f40cad)
2009-09-03 18:15:23 -07:00
Cary R f34485d415 Support negative index for %assign/av opcodes.
If the array index is negative these opcodes need to just return.
(cherry picked from commit 9d765820bf)
2009-09-03 18:12:40 -07:00
Cary R df177e9e14 Major rewrite of indexed part selects.
This patch is a major rewrite of the indexed part selects (+: and -:).

It made the following enhancements:

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

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

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

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

5. Added more assert(! number_is_unknown) statements.

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

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

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

9. Major fix of draw_select_expr() in the code generator.
(cherry picked from commit 2b17366ad5)
2009-09-03 18:07:51 -07:00
Cary R 5d4c8d616a Propagate sign in synthesize for math operators.
The sign of the expression needs to be propagated for the
math operators when they are synthesized.
(cherry picked from commit a49463e728)
2009-09-03 18:02:40 -07:00
Cary R 72c02a8285 Pass file/line information for part selects.
Propagate the file and line information for a part select
expression and LPM (continuous assign).
(cherry picked from commit 06997c63ed)
2009-09-03 18:02:24 -07:00
Cary R 043c86ba02 Enhance %shiftr/i0 and $shiftl/i0 to work with negative shifts.
The %shiftr/i0 and %shiftl/i0 opcodes are used for some part
selects and if we have a negative shift we want the value to be
padded with 'bx. This patch enhances the two %shift/i0 opcodes
to work with negative shifts and for negative shifts pad with
'bx instead of 'b0.

It also fixes %ix/get/s to use a uint64_t instead of a unsigned
long to avoid problems with sign extension on 32 bit machines.
(cherry picked from commit ecb00017cb)
2009-09-03 18:02:02 -07:00
Cary R b9d0783ad9 Assert number is not unknown for many cases in tgt-vvp.
This patch adds a number of asserts that a number is not unknown
in places where this should never happen.
(cherry picked from commit d108221fef)
2009-09-03 18:01:43 -07:00
Cary R 047ee137ed Add vvp support for out of bound variable part selects.
This patch adds support for variable part selects with out of bound
and 'bx index values.
(cherry picked from commit 1306a6db81)
2009-09-03 18:01:27 -07:00
Cary R ef814a9ef4 Add a -Wselect-range warning class.
This patch adds support for a -Wselect-range warning class to the
driver and ivl programs. This is part of -Wall. The actual checks
will be added in a later patch.

Cherry-picked from e576e1eb2c
2009-09-03 18:00:31 -07:00
Cary R fa0ecb3761 Convert IVL_LPM_CONCAT to use ivl_lpm_size() instead of ivl_lpm_selects()
It was documented that a IVL_LPM_CONCAT would use _size() instead
of _selects(). This patch adds the functionality to _size() and
converts all the Icarus provided code generators to use _size().
_select() will be kept for compatibility in V0.9.
(cherry picked from commit 4cd790a2d2)
2009-09-03 17:52:35 -07:00
Cary R f2a81cf660 Fix subtle bug in scope checking.
This check looks to be defined to check the child scope not the
top level scope.
(cherry picked from commit 872962ef18)
2009-09-03 17:49:18 -07:00
Cary R e1b4d531a1 Update config.guess and config.sub to latest version.
This patch updates the config.guess and config.sub files to the
latest ones from automake 1.11.
(cherry picked from commit 9669ccd011)
2009-09-03 17:48:17 -07:00
Cary R a418995988 Update MinGW requirements, etc.
The old readline library was causing problem. I updated the mingw.txt
file to use the gnuwin32 version of readline (5.0-1) which works. I
also mentioned that I plan to rewrite the directions using a newer
version of MinGW.
(cherry picked from commit a51f2dca50)
2009-09-03 17:46:53 -07:00
Cary R 8c36e20fd4 Add support for an undefined index for the %load/a* opcodes.
These opcodes need to return 'bx or 0.0 for the real opcode when
the array index is undefined.

The patch also documents the auto incrementing of the bit
index register done by the %load/avx.p opcode.
(cherry picked from commit 8623f804f2)
2009-09-03 17:40:01 -07:00
Cary R 2c982a6edb Add missing limits.h include in vpi_signal.cc
(cherry picked from commit 83c7a24cff)
2009-09-03 17:37:52 -07:00
Cary R a298bfb22a For a part select driving another part select the extra bits must be 'bz.
When a part select is driving another part select any bits outside the
original select must be 'bz instead of 'bx. If we initialize the temporary
buffer to 'bz this should work as required. It there are multiple drivers
then a resolver comes into play and this should not matter.
(cherry picked from commit e31b6bd20c)
2009-09-03 17:35:16 -07:00
Cary R cce61d7134 Ignore a zero MCD for $fflush, $fdisplay*, $fwrite* and $fstrobe*.
(cherry picked from commit ed4e2eb046)
2009-09-03 17:30:12 -07:00
Martin Whitaker aad5443a36 Fix for pr2842185 and for genvar scopes.
When checking for name collisions, the compiler looks for genvar
declarations in the enclosing module rather than in the current
scope, which leads to false positives. The compiler also places
all genvar declarations in the enclosing module scope, even when
the declarations are inside a generate block which has its own
scope. This patch fixes both these faults. It also fixes some
typos and outdated information in comments.
(cherry picked from commit da010db739)
2009-09-03 17:24:45 -07:00
Martin Whitaker f5f104f8a6 Fix for pr2837451.
pr2827132 changed the val_ field in vvp_fun_part_sa to only store
the bit values for the selected part, not the entire source vector,
but omitted to modify the recv_vec4_pv method to handle this change.
This patch rectifies that omission.
(cherry picked from commit 7c6176357f)
2009-08-18 17:33:30 -07:00
Cary R b7ff68c3f4 Fix a few more minor memory leaks.
This patch fixes a few more memory leaks that can happen under
error conditions.
(cherry picked from commit 35f3d7f60e)
2009-08-18 15:00:12 -07:00
Cary R 69986a5bc7 Do not schedule a new event if the previous event has the same value.
If the previous event has exactly the same value as this event then
we do not add this event to the event queue.
(cherry picked from commit 2e820ca6f0)
2009-08-18 14:56:14 -07:00
Cary R c0f4b0374a Warn that we do not support non-blocking assignment to real array words.
A while ago we changed how variable arrays were accessed. This change
did not get propagated to the non-blocking assignment for real array
words. This patch adds a warning that this is not currently supported.
We can add this to development, but not V0.9 (interface change).
(cherry picked from commit 88b18d4212)
2009-08-18 14:52:35 -07:00
Cary R 817b1ef3d4 UDPs need to evaluate their arguments before generation
When generating a .udp call the arguments need to be evaluated
before the .udp is. This allows things like .resolv to be built
correctly.
(cherry picked from commit cb5c4299fb)
2009-08-18 14:48:30 -07:00
Cary R f9774758a3 UDPs can only take two delay values.
Check in the compiler that a UDP is only given two delay values.
(cherry picked from commit 7916e148f8)
2009-08-18 14:45:31 -07:00
Cary R eb2fed7015 Fix some memory leaks/issues found with cppcheck.
I ran cppcheck on the code and it found a few obscure memory leaks and
a few other issues. This patch fixes most of them.
(cherry picked from commit 2e166b7279)
2009-08-18 14:36:32 -07:00
Stephen Williams 5af47cda12 Fix man page formatting for portability. 2009-08-10 06:34:18 -07:00
Cary R 0aad444bbf Add full $ferror() support, bug fixes, etc.
This patch adds $ferror() support. This is enhanced over what the standard
says needs to be supported. All file I/O routines set/clear the errno flag,
This allows $ferror() to check when an invalid fd/MCD is passed to a
system task. The $ferror() fd is only checked if errno is not set since
all the other routines will set EBADF when they are called. This allows us
to test the output from $fopen() which sets the fd to zero (an invalid fd)
when it has a problem.

The following bugs (changes) are also fixed:

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

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

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

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

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

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

Free the argument handle when $fscanf() is called with an invalid fd
(memory leak).
(cherry picked from commit ce89a68735)
2009-08-02 11:07:23 -07:00
Cary R e63c75d1a3 Add a warning when we reach 1024 files.
It's not too likely we will ever reach this, but we should be nice
and print a message instead of just failing. We could set errno,
but for now the warning will have to be enough.
(cherry picked from commit b0ac550791)
2009-08-02 11:04:24 -07:00
Cary R a5b0872016 Fix memory leak, unneeded argument.
Very minor issues dosify was not closing files so memory leaks could
show up and vpi/sys_readmem.c was passing the file after it was
closed to the lexor cleanup code. The lexor cleanup code does not
need an argument.
(cherry picked from commit 52fbb3f734)
2009-08-02 11:01:31 -07:00
Cary R f6b9db1c78 Add full genvar support and name space checking.
This patch adds genvars to the elaboration process. It adds checks
that a genvar is defined for a generate loop and that a genvar does
not conflict with any other items in its name space.
(cherry picked from commit 72a98e85cb)
2009-07-29 08:56:01 -07:00
Martin Whitaker 597097eaef Fix for pr2821633.
Currently, edge event functors declared in automatically allocated
scopes that are used to detect edges on signals declared in static
scopes are unable to correctly determine edge information for the
first signal delta they receive because they do not know the old
state of the signal. This patch causes the state of static signals
received by these event functors to be recorded as static state in
the functors, so the old state of the signals can be initialised
to the correct value when a new automatic context is created.
(cherry picked from commit d7fe9c613c)
2009-07-29 08:52:50 -07:00
Martin Whitaker 47512e351f Suppress unnecessary update of part select functor output.
Currently a part select functor will send updates to nodes connected
to its output whenever any part of its input vector changes. This
patch ensures updates are only sent when the selected part of the
input vector changes.
(cherry picked from commit 1453c5b0bb)
2009-07-29 08:50:28 -07:00
Cary R 506c09f5f8 Fix power operator width in self-determined context.
In a self determined context the width of the power operator
is defined to be the left argument width.
(cherry picked from commit e98000426e)
2009-07-29 08:47:25 -07:00
Cary R 693fb93962 Fix CA replication of zero issues.
This patch fixes a CA to evaluate and ignore a replication of zero.
It also fixes a minor glitch in the data type calculation code. This
was causing a problem if a zero width replication was the first
element in a concatenation/replication since the data type was hard
coded to the first element of the concatenation/replication. It now
uses the first defined element in the concatenation/replication to
determine the data type.
(cherry picked from commit b629d913d2)
2009-07-29 08:44:15 -07:00
Cary R 8ca5926db9 Fix procedural concatenation/repetition problems
This patch evaluates the whole concatenation expression and
makes the concatenation padding sign aware. This is needed
when $signed({...}) is passed as an argument.

A repetition is just N copies of the base expression not N
evaluations of the base expression. This is only a problem
when functions have side effects. It's also faster to copy.
The evaluation must also be done when the replication count
is zero (see 1364-2005).
(cherry picked from commit e362a86b16)
2009-07-29 08:44:05 -07:00
Cary R 7acafd128f The scanf functions must return EOF if source starts at the end of input.
The $fscanf() and $sscanf() functions are defined to return EOF when
the end of input is reached before any matches or match failures have
occurred.
(cherry picked from commit c5ee1fdbf5)
2009-07-29 08:40:47 -07:00
Cary R d0a12f5b14 When skipping C-style comments in a skipped `ifdef include the '\n'
When a C-style comment /* */ is being skipped because it is in a
skipped `ifdef, `ifndef, etc. directive then we need to output a
'\n' at any comment end of line.
(cherry picked from commit e932c41587)
2009-07-29 08:37:59 -07:00
Cary R 8964a175f8 Find the width of net arrays correctly.
Add code to the generic get_array_word_size() function to correctly
find the width of net arrays and use this routine in the _vthr_
code as needed.
(cherry picked from commit 212bd4134a)
2009-07-29 08:34:49 -07:00
Cary R 97d70f9069 base if for ivl pbase is for ivlpp 2009-07-29 08:31:43 -07:00
Cary R 0dc0fbf78d Add check for prec > unit in `timescale directive. 2009-07-29 08:28:14 -07:00
Cary R 786b3a0ca9 Real constants are always signed.
Set the signed_flag_ for real constants.
2009-07-29 08:21:36 -07:00
Cary R 24a60ce6af Add compiler warnings for more constant out of bounds array accesses.
This patch adds compiler warning messages for all/most constant out
of bounds array access.
2009-07-06 15:08:56 -07:00
Cary R 4c640f67cb More VCD enhancements.
Make the code smarter so it can keep fewer items in the lists.
Scopes and explicitly given variables are all that is kept.
Includes a few other refinements.
2009-07-06 15:06:15 -07:00
Cary R cfe68fe6b4 Add basic support for events and cleanup VCD dumper.
This patch adds support for dumping named events to the VCD
dumper only. The LXT and LXT2 will be added once this has
been tested more. It also reworks the $dumpvars routine
to be more consistent concerning warning messages for duplicate
signal dump requests and fixes some bugs.

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

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

For example:

  $dumpvars(0, var, scope_that_includes_var);

Will work without a warning message.

  $dumpvars(0, scope_that_includes_var, var);

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

Other enhancements include the start of including type
information in the output. For now integer is added, the
other type information will require changes to the code
generator and hence will only be done in development.
2009-07-06 15:06:02 -07:00
Cary R 78149e9d15 Use correct sign for signal and constant addition.
This was incorrectly using the expression sign not checking if
the two sub-expressions are both signed. This likely used to
work, but in the context of $signed which sets the expression
to signed so we can have a signed expression without both
sub-expressions being signed.
2009-07-06 15:01:23 -07:00
Cary R bbe037bf9f Print a warning for an implicit sensitivity list that has selects.
An implicit sensitivity list that has selects (bit, part, indexed
part or array) will include more than the user expects so print a
warning to let them know what will happen. Other simulators have
the same behavior, but I believe this is incorrect and needs to
be fixed to only include the appropriate parts. The warnings can
go when we fix this functionality, but we need them now to warn
the user that they may not be getting what they expect. One other
simulator warns for array selects.

This patch also adds the array index to the sensitivity list.
2009-06-23 09:53:31 -07:00
Cary R d3bf6be7b2 Fix real variable array and net array bugs.
This patch fixes a number of bugs related to real variable and net
arrays. Specifically the following:

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

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

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

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

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

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

7. Initialize all real array words to 0.0 when the array is created.
2009-06-23 09:50:13 -07:00
Cary R 6146a98278 Make the dumpers match better (VCD, LXT, LXT2).
This patch removes some of the unneeded differences in the
various dumper routines. This is the start of a complete
refactoring, but the first task is to make them as common
as possible and this is the start of that.
2009-06-23 09:43:22 -07:00
Cary R 63c7285113 For real expressions evaluate non-real sub-exprs as bits and convert.
When processing procedural real expressions we need to evaluate
non-real sub-expressions as bit based expressions and then
convert the result to a real value. This is particularly import
for integer division.
2009-06-23 09:37:41 -07:00
Cary R 79e0203280 Use a default buffer size of 512 vs 256 for displaying.
This patch changes the initial buffer size when displaying results
to 512 from 256. This initial buffer is used as the default for the
floating point results and failed when %f is given a large, but
valid value. To make this even more safe we add the precision to
the size to make sure we do not overflow the buffer.
2009-06-23 09:31:18 -07:00
Cary R ad419dfbe4 Parse the config declarations and report they will be ignored.
This patch adds code to parse config declarations and reports
that they are not currently supported and will be ignored.
2009-06-23 09:25:21 -07:00
Cary R 75d71fe312 Some compiler cleanup and minor memory leak fixes.
This patch cleans up some unneeded code. Releases some allocated
memory before the compiler quits and fixes a couple minor memory
leaks in the compiler and vvp code generator.
2009-06-23 09:14:03 -07:00
Cary R 5a30355faf Ignore specify pulsestyle_* and *showcancelled directives.
This patch adds code to silently ignore the specify directives:
  pulsestyle_onevent
  pulsestyle_ondetect
  showcancelled
  noshowcancelled.
2009-06-08 11:12:04 -07:00
Cary R 623e897e55 Some delay expressions need to probe their width (ternary)
The ternary operator requires that the expression width be defined.
This requires that the delay expression has test_width() run on it.
2009-06-08 11:09:10 -07:00
Cary R 0bb6360ac7 Allocate the fd table dynamically in 32 entry chunks.
The fd table used to be statically allocated with only 32 entries.
Three of these were preallocated for stdin, stdout and stderr
leaving only 29 for the user.  This patch makes the allocation of
this table dynamic with a hard limit at 1024 total fds. The table
is increased in 32 bit chunks.
2009-06-08 11:06:43 -07:00
Cary R 4b850e1e74 Fix bugs in &= and |= for vvp_vector4_t
Someone got a bit too creative in reducing the original equations
I wrote to handle this. This patch reverts the previous code and
uses my original equations. This passes for both wide and narrow
vectors. The equations are slightly more complicated, but the old
z2x conversion had some overhead. I would expect the time to be
about the same, but you now get the correct results.
2009-06-08 09:45:25 -07:00
Cary R 8ce807a263 Parse all the 1364-1995 and 1364-2001 timing checks.
This patch adds code to parse and ignore the following timing checks:

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

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

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

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

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

`BAR(x)

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

I don't see the advantage in keeping all the expanding macro's text
together, so my solution is to simply allocate a new buffer and pass it
as (struct include_stack_t *)->str to the flex parsing function and free
it at the end.
2009-06-08 08:51:31 -07:00
Cary R bbf11b830b Add support for unconnected_drive.
Icarus has recognized this directive, but it did not do anything
with the information. This patch adds the functionality for most
common cases. It adds this by changing the input net type from
wire/tri to tri1 or tri0 depending on the pull. The issue is that
if the input net is not a wire or tri this is not safe and should
really be done as an external pull gate connected to the input.
We will need to handle this is it ever comes up. For now a sorry
message is printed.
2009-06-08 08:42:12 -07:00
Cary R d345fb7654 Add more default net types
Previously Icarus only supported a default net type of wire or none.
This patch adds the rest of the supported net types (all except
uwire and trireg) to the `default_nettype directive. It also fixes
make_implicit_net_() to use the default_nettype instead of always
using implicit (the same as wire).
2009-06-08 08:25:21 -07:00
Cary R 3186e3dc54 Rework the `timescale directive and cleanup `line a bit.
This patch reworks the `timescale directive to do a better
job of parsing the line, it refactors some of the code and
should produce better error messages. It also tightens up
parsing the numeric constant, etc. to better match the
Verilog standard.

The parsing of `line has been enhanced to only allow 0, 1 or
2 for the level and a single line comment at the end of the
line is ignored.
2009-06-07 21:45:31 -07:00
Cary R d4d50fd97d Use strchr() instead of index().
strchr() is more portable and index() is not available under
MinGW so replace index() with strchr().
2009-06-07 21:30:42 -07:00
Cary R 3337c9d51a Make ivl warn that it does not support `ifndef or `elsif
We added support for these two directives some time ago,
but ivl was never updated to warn that it did not support
them and you needed to use ivlpp.
2009-05-24 10:36:33 -07:00
Cary R dfda202f14 Add better error checking to the two line directives.
Icarus supports both a #line and `line directive. This patch
reworks the parsing of these to provide better error detection
and full checking.
2009-05-24 10:34:06 -07:00
Cary R 5ca440dc1c Add support for `resetall and other directive changes.
This patch adds support for the `resetall directive.

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

The `timescale processing was reworked to handle being
reset and hooks were added to easily change the default
time units and precision when we add that feature request.
2009-05-24 10:28:42 -07:00
Cary R 96908e2fc5 Add compiler support for `celldefine, vpiCellInstance
This patch adds support to the compiler and stub backend for
`celldefine. This matches the compiler portion of the full
support that was added to 0.10.devel. This does not change
vvp or the vvp interface since changing the interface is not
allowed in a stable branch.
2009-05-24 10:21:37 -07:00
Cary R 9f07e3c16e Print a better error message for a '~' token in front of ('&' | '|' | '^')
Some users may expect this to work so this patch catches these
specific cases and tells the user to use the singe unary operators
'~&', etc. instead.
2009-05-24 10:18:51 -07:00
Cary R 3ae3e34732 Cleanup if an invalid option is given.
Cleanup the temporary files and memory if iverilog is given
an invalid option.
2009-05-24 10:16:13 -07:00
Cary R 372efd8c30 Fix memory leak when parsing command files.
These are not leaks in the true sense of the word, but it is
memory that is not being freed before the program finishes
so valgrind will complain about this.
2009-05-24 10:15:45 -07:00
Larry Doolittle ac7f55f22a Remove fresh const lint
It looks pretty stupid and non-c++-y, but it does remove two compiler warnings
vvp/stop.cc: In function 'void stop_handler(int)':
vvp/stop.cc:492: warning: deprecated conversion from string constant to 'char*'
vvp/stop.cc:493: warning: deprecated conversion from string constant to 'char*'
2009-05-24 10:14:01 -07:00
Cary R b74736c784 Display and error for hierarchical references in a parameter r-value expr.
Display and error message when the user uses a hierarchical reference
in a parameter r-value expression.
2009-05-19 08:38:46 -07:00
Cary R 7988ef04d8 Add support for displaying a real parameter using %d.
This patch modifies the real parameter get_value routine to use
the standard vpip_real_get_value() routine. This routine has
support for an integer and a decimal string value.
2009-05-19 08:33:02 -07:00
Cary R 61214108fe Add support for initializing outputs declared as output reg.
The standard allows an output declared as "output reg" to be
given an initialization assignment in the output declaration.
this patch adds that functionality. Specifically:

  output reg out = 1'b0;

works as expected.
2009-05-19 08:28:39 -07:00
Cary R 356a19c918 Add escaping to the stringification of macros.
Icarus support returning a string version of a macro ``<MACRO>.
The problem was that it did not escape '\' or '"' so if the
macro to be escaped had either of these it would create an
invalid string. This patch fixes this by translating these two
codes to their octal equivalent when the macro is converted.
2009-05-19 08:25:41 -07:00
Cary R f1c5b58845 Fix the %assign/v0/x1 operators for width equal negative offset case.
This patch fixes the three %assign/v0/x1 operators to correctly
notice that the select has fallen off the start of the vector
for the case that the negative offset equaled the width.
2009-05-19 08:22:12 -07:00
Cary R fad37da1dc Fix %t to work with real system functions.
Fix %t to get the real value when the argument comes from a real
valued system function.
2009-05-06 14:25:03 -07:00
Cary R 80f74d0d24 Add a warning message for some array words when dumping.
When dumping an array word the name is implicitly converted to
an escaped identifier. If this implicit name conflicts with an
explicitly created escaped identifier this patch will print a
warning message warning that the array word will conflict with
an escaped identifier.
2009-05-06 14:22:26 -07:00
Cary R d25f689f55 Vec8 delays should schedule like vec4 delays.
This patch adds code to calculate the vec8 delays using the
same method that is used to calculate the vec4 delays.
2009-05-06 14:19:37 -07:00
Cary R 42618741d9 Calculate the width of an array word correctly.
When finding the width of an array word we need to skip any word
selects for the array dimensions.
2009-05-06 14:16:21 -07:00
Cary R 9bcfc8ab6d Check for name space collisions.
This patch adds code to check for most of the name space
collisions. genvars are not checked correctly since they
are not completely implemented.
2009-04-27 18:07:03 -07:00
Cary R de75e71152 Dump the streams when entering interactive mode.
This patch adds code to automatically dump the output stream
including any dump file when entering interactive mode. When
the user typed ^C or $stop was executed.
2009-04-21 15:11:25 -07:00
Cary R 5f8f7bc6fc Add support for dumping non-constant array selects as a constant select.
Dumping array words is an enhancement that we have added to Icarus.
The problem was that if you wanted to dump the whole array you would
like to use a for loop as follows:

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

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

Adding this functionality necessitated adding support for vpiIndex
to the &A<> routines.
2009-04-21 15:09:01 -07:00
Cary R f7fb754ee8 It is an error to select part of a scalar value.
In 1364-2005 it is an explicit error to take the select of a scalar
or real value. We added the checks for real a while ago. This patch
adds the functionality for scalar values. In the future we may want
to push the scalar property to the run time.
2009-04-21 15:02:14 -07:00
Cary R e59a6b8df7 Warn the user if they use both a default and `timescale based delay.
This patch add code to print a warning message if it finds both a
default and `timescale based delays. The -Wall or more specifically
the -Wtimescale flag can be used to find the module with the missing
`timescale directive.
2009-04-21 14:56:25 -07:00
Cary R f149a30045 Handle $stop and $finish at the interactive prompt.
This patch adds interactive support for $stop and $finish.
$stop displays a message that the simulator is already stopped.
$finish acts exactly like (calls) the interactive "finish"
command. Having $stop do nothing and $finish not finish until
you exit interactive mode is not very intuitive.
2009-04-21 14:54:44 -07:00
Cary R ddaba5b017 Print a better error message for the optional system tasks/funcs
This patch adds better error messages (compiletf) for the optional
system tasks and functions (Annex C 1364-2005). Doing this also
makes calling them fail more gracefully (it is no longer a RE).
2009-04-21 14:42:12 -07:00
Cary R dff535923f Generate better error messages for concat. with indefinite width.
This patch generates a more user friendly error message for a
concatenation with an indefinite width operand.
2009-04-21 14:38:52 -07:00
Cary R d66471c449 Add $readmempath to set a search path for $readmem{b,h}.
This patch add a new system function $readmempath. It accepts
a ":" separated list of directories that $readmem{b,h} will
use when trying to open a given file. If the file given to
$readmem{b,h} starts with a '/' (an absolute path) the search
list will not be used. A new call to $readmempath will replace
the previous search list with the given list. The search list
elements are check to see if they exist and are directories.
If not a warning will be displayed and they will not be added
to the list.
2009-04-21 14:35:29 -07:00
Cary R b16e3ab59e Allow macro expansions to take arguments with multiple arguments.
This patch allows a macro expansion to have an argument which
itself has multiple arguments (handle nested ",").
(cherry picked from commit 047828ded0)
2009-04-08 19:16:26 -07:00
Cary R d7b76e9390 Add support for recursive modules inside generate blocks
This patch adds support for recursive module loops if the
loop contains a generate block. The assumption is that the
user is doing the right thing in the generate block to make
the loop terminate. For this case there is also a check
that limits the number of loops (default 10). This prevents
the system from crashing when the user did not correctly
terminate the looping structure. The limit can be changed
by the user if needed.
(cherry picked from commit 5e723bfd61)
2009-04-08 19:12:39 -07:00
Cary R 6f692e7984 Use the port that has already been fetched.
This patch reuses the port that has already been fetched vs
fetching it again.
(cherry picked from commit a7741d2bd5)
2009-04-08 19:11:22 -07:00
Cary R dfe7279488 Check for both the library and include file when adding history.
When adding history (add_history) use both the existence of the
library and the header file to determine if history can be
supported. Add a new USE_HISTORY that is the and of these two.
(cherry picked from commit 4b2e5e5914)
2009-04-08 19:09:52 -07:00
Cary R b9ea0036de For div/mod only sign extend if both arguments are signed.
Only sign extend the operands for division or modulus if
both of them are signed. Previously only the individual
operand signedness was being considered.
(cherry picked from commit d074a37a2d)
2009-04-08 19:07:24 -07:00
Cary R fc24624fa2 Add support for empty task port lists with a warning.
The standard does not allow this, but it appears that other
simulators do. This patch adds the functionality, but prints
a warning message for the invalid task definition.
(cherry picked from commit 46350da5f0)
2009-04-08 19:05:03 -07:00
Cary R cca3d5907c Skip leading space for some codes in scanf routines.
Most conversion codes in the scanf routines are supposed to
skip leading space. This patch adds that functionality.
(cherry picked from commit e987162cb9)
2009-04-05 14:01:53 -07:00
Cary R ec809c9137 Fix constant CA delays to support two/three values.
This patch fixes the code generator to correctly create three value
constant delays. It also fixes a bug in the compiler related to the
precalculation of the high-Z delay when only two delays are given.
Previously if was using a pointer not a value comparison to find
the minimum value.

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

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

The r-arg is always unsigned.

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

Removed some obsoleted/outdated code.
(cherry picked from commit d7f272d14c)
2009-03-31 07:40:28 -07:00
Larry Doolittle 710ad582ed Make VHDL code generator skip over virtual pins
Fixes pr2701438
(cherry picked from commit a05ac4b5f4)
2009-03-31 07:34:19 -07:00
Stephen Williams 183137b60c BUFZ devices are strength-aware
When vvp_vector8_t objects come in, pass them out as vec8. The
BUFZ device is used in situations where this acts much like a
simple wire.
2009-03-28 10:08:39 -07:00
Cary R 9c7c719cac Use AC_HELP_STRING instead of AS_HELP_STRING.
The later causes a warning under MinGW. The former appears
to work everywhere.
2009-03-27 06:37:21 -07:00
Cary R 2f3061c158 We are deprecating the $log function in favor of $log10.
When the VAMS math functions were originally built we did a
straight copy of the log() function to $log(). This can
conflict with other Verilog-D definitions of $log. We
need to deprecate this function and remove it before the
next major release.
2009-03-27 06:32:46 -07:00
Cary R af08ff64c7 Add message the the $dumpports* task are not available
These are in the standard and we did not have error messages
for them. This patch make calling these tasks a compiletf
fatal error.
2009-03-27 06:29:44 -07:00
Cary R 036c176e8b Add the $fread() system function.
This patch adds the $fread() system function. Icarus does not
currently allow missing arguments in functions so the following
standard specified functionality is not supported:

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

It also fixes a memory leak in fopen related to the get_filename
refactoring I recently did.
2009-03-26 11:51:22 -07:00
Cary R 327e8d0ec0 Use a single = in configure.in test
The ability to use == is an extension so use the more common =.
2009-03-26 11:45:11 -07:00
Larry Doolittle cfb45e56e2 Address pr2710081, version_tag.h guards
Tested with both bash and dash on Debian, has the desired effect.
No promises for cygwin.
2009-03-26 11:42:42 -07:00
Cary R 809044cbf8 Add guards in CREATE_VERSION script.
This patch adds the same guards that the other two scripts
create for the version_tag.h file.
2009-03-26 11:38:32 -07:00
Larry Doolittle 2a53255445 Add support for virtual reg arrays to tgt-stub
This patch adds support for virtualized register arrays to the
tgt-stub back end.

Based Cary's patch, but with a slightly different style.
Both work fine.
2009-03-26 11:03:42 -07:00
Stephen Williams 4205752bb0 Clean up release builder scripts.
The version.h file is generated by the Makefile, we should
prefill the version_tag.h file.
2009-03-20 14:29:18 -07:00
Cary R d237e35076 Make vvp use inttypes for the 64 bit printing info.
To get the correct print format for a 64 bit value it is much
better to use <inttypes.h> (when available) than building our
own value. This allows MinGW to use the non-standard I64.
2009-03-20 13:58:32 -07:00
Stephen Williams 90f37fe3cb Slightly more portable version of configure test. 2009-03-19 18:31:21 -07:00
Stephen Williams 4be2f61b53 Get ready for the 0.9 first release. 2009-03-19 10:17:12 -07:00
Purdea Andrei f8aa9073ac fixing: %0b format prints nothing for a 0 input
the following example returns ||. This patch fixes it to return |0|.
module t();
wire [3:0] b;
initial
    $monitor("|%0b|", b);
assign b = 0;
endmodule
(cherry picked from commit c9d2400dd0)
2009-03-19 09:11:49 -07:00
Cary R 9ea20d6677 Cleanup lxt and lxt2 EOS data.
This patch cleans up the memory allocated in the lxt and lxt2
$dumpvars routines.
(cherry picked from commit be158dd45f)
2009-03-19 09:05:05 -07:00
Cary R 9fec1f7e45 Handle zero repetition in a synthesized concatenation.
It is valid to have a repetition of zero inside a concatenation
that has other elements with a defined width. This patch adds
this functionality to the synthesize method. It also prints
an error if you try to synthesize a zero width constant.
(cherry picked from commit fa8a3d6c2e)
2009-03-17 16:04:49 -07:00
Stephen Williams c47ea0721c fix the arithmetic of multi-word division.
The Multiword division was not handling some degenerate high
guesses for the intermediate division result guess. The end result
was an assertion. Recover from this case.

(Does the addinb back of bp need to be optimized better?)
(cherry picked from commit 6715426833)
2009-03-17 16:04:28 -07:00
Stephen Williams ef12137931 Pass unsigned-ness of arithmetic operators through operands.
The arithmetic operands are signed only if both operands are signed.
If the expression is unsigned, then the expression as a whole needs
to be processed as unsigned in order to get padding right.
(cherry picked from commit c4a62dee0d)
2009-03-17 16:04:09 -07:00
Larry Doolittle 0e8a12eebf Don't make useless arrays of nexa
When a pin array is virtual, dll_target::signal() doesn't need
to make a corresponding set of stub nexa.

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

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

Closes: pr2023076
(cherry picked from commit 3a18bda8ee)
2009-03-15 13:54:08 -07:00
Cary R 9473e823ed You must assert a logical not NULL.
This fixes a small problem where an assert was being called
with NULL instead of 0.
(cherry picked from commit ac4cb1bbe9)
2009-03-15 13:53:55 -07:00
Larry Doolittle c75f9db315 Add user interface to pin virtualization
Flag is DISABLE_VIRTUAL_PINS.  Try to give a helpful hint for
how to work around any problems our regression testing might
have missed.
(cherry picked from commit 67381431ed)
2009-03-15 13:53:41 -07:00
Larry Doolittle 1d31a91b4f Remove valgrind errors triggered by virtual pins
NetBus wasn't initializing pin direction.
I hope Link::PASSIVE is correct for busses!
No test suite regressions.
(cherry picked from commit f344515e38)
2009-03-15 13:53:28 -07:00
Larry Doolittle b795d8c1d8 Virtualize Pins until needed
Reduces resource usage when compiling large memories.
Normal usage patterns still create large nexus arrays
in t-dll.cc:dll_target::signal().

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

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

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

See extensive discussion on iverilog-devel, March 4-5 2009,
title "pr2023076: large memories".
(cherry picked from commit 5bc41e1a17)
2009-03-15 13:52:57 -07:00
Larry Doolittle 5ec7731e04 Detect overflows converting to long
The code is ugly, but the results are good.
No regressions in existing testsuite, needs a new entry.
2009-03-13 15:17:51 -07:00
Larry Doolittle bb29e1d588 Drop useless CVS stuff in .txt files
Remove useless, redundant, misleading, and misspelled $Id$ and $Log$
cruft from all .txt files.
(cherry picked from commit 86bf6c447b)
2009-03-13 09:42:17 -07:00
Larry Doolittle 74fd1865cb Minor tweaks ahead of memory virtualization
Limit memory sizes to whatever fits in unsigned; crash if
the conversion from unsigned long to unsigned overflows,
instead of just wrapping.  I don't know what happens on
a 32-bit machine if you ask for an 8 Gig memory, but with
a 64-bit machine and this patch, it crashes with an assert.

Set direction on PartSelect Links before connecting them.

May or may not be considered orthogonal to upcoming
memory virtualization patches.
2009-03-09 14:46:13 -07:00
Larry Doolittle b40b6fb50d Spelling fixes
Mostly comments, but includes user-visible debug messages.
(cherry picked from commit b0c4a87133)
2009-03-09 14:44:07 -07:00
Stephen Williams 19b68f6332 Fix broken definition of is_linked().
(cherry picked from commit fff2598709)
2009-03-09 14:43:18 -07:00
Cary R c96e4da9e4 More constant function not supported warnings.
This patch adds more places that need to warn about constant
functions not being available.
2009-03-05 17:09:43 -08:00
321 changed files with 23034 additions and 11728 deletions

7
.gitignore vendored
View File

@ -6,6 +6,7 @@
# Object files and libraries # Object files and libraries
*.[oa] *.[oa]
*~
# From autoconf # From autoconf
configure configure
@ -18,6 +19,7 @@ config.h
/tgt-vvp/vvp_config.h /tgt-vvp/vvp_config.h
/tgt-vhdl/vhdl_config.h /tgt-vhdl/vhdl_config.h
/vpi/vpi_config.h /vpi/vpi_config.h
stamp-*-h
/version.h /version.h
/version_tag.h /version_tag.h
@ -61,6 +63,11 @@ dep
# Program created files # Program created files
/vvp/tables.cc /vvp/tables.cc
/iverilog-vpi.man
/driver-vpi/res.rc
/driver/iverilog.man
/vvp/vvp.man
# The executables. # The executables.
*.exe *.exe
/driver/iverilog /driver/iverilog

View File

@ -1,5 +1,5 @@
/* /*
* 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 * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -20,7 +20,7 @@
# include "config.h" # include "config.h"
# include "Attrib.h" # include "Attrib.h"
# include <assert.h> # include <cassert>
Attrib::Attrib() Attrib::Attrib()
{ {

View File

@ -1,7 +1,7 @@
#ifndef __Attrib_H #ifndef __Attrib_H
#define __Attrib_H #define __Attrib_H
/* /*
* Copyright (c) 2000 Stephen Williams (steve@icarus.com) * Copyright (c) 2000-2009 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -30,7 +30,7 @@ class Attrib {
public: public:
Attrib(); Attrib();
~Attrib(); virtual ~Attrib();
const verinum&attribute(perm_string key) const; const verinum&attribute(perm_string key) const;
void attribute(perm_string key, const verinum&value); void attribute(perm_string key, const verinum&value);

View File

@ -54,7 +54,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). 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 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 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 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 to know what it says and what you think it should say. From this I can

View File

@ -1,5 +1,5 @@
/* /*
* 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 * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -23,9 +23,6 @@
# include <cstring> # include <cstring>
# include <cstdlib> # include <cstdlib>
# include <climits> # include <climits>
#ifdef HAVE_MALLOC_H
# include <malloc.h>
#endif
hname_t::hname_t() hname_t::hname_t()
@ -116,4 +113,3 @@ ostream& operator<< (ostream&out, const hname_t&that)
return out; return out;
} }

View File

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

View File

@ -30,7 +30,7 @@ SHELL = /bin/sh
# The "suffix" is used as an installation suffix. It modifies certain # The "suffix" is used as an installation suffix. It modifies certain
# key install paths/files such that a build and install of Icarus Verilog # key install paths/files such that a build and install of Icarus Verilog
# with the same $(prefix) but a different $(suffix) will not interfere. # with the same $(prefix) but a different $(suffix) will not interfere.
# The normal configuratin leaves suffix empty # The normal configuration leaves suffix empty
suffix = @install_suffix@ suffix = @install_suffix@
prefix = @prefix@ prefix = @prefix@
@ -40,10 +40,22 @@ datarootdir = @datarootdir@
SUBDIRS = ivlpp vvp vpi libveriuser cadpli tgt-null tgt-stub tgt-vvp \ SUBDIRS = ivlpp vvp vpi libveriuser cadpli tgt-null tgt-stub tgt-vvp \
tgt-vhdl driver tgt-vhdl driver
# Only run distclean for these driectories. # Only run distclean for these directories.
NOTUSED = tgt-fpga tgt-pal tgt-verilog NOTUSED = tgt-fpga tgt-pal tgt-verilog
VPATH = $(srcdir) ifeq (@MINGW32@,yes)
SUBDIRS += driver-vpi
else
NOTUSED += driver-vpi
endif
# To get the version headers to build correctly we only want to look
# for C++ files in the source directory. All other files will require
# an explicit $(srcdir). The one exception to this is if we need to
# rebuild the lexor_keyword.cc file. If we do, then we want to use the
# local version instead of the one is $(srcdir).
vpath lexor_keyword.cc .
vpath %.cc $(srcdir)
bindir = @bindir@ bindir = @bindir@
libdir = @libdir@ libdir = @libdir@
@ -55,7 +67,9 @@ mandir = @mandir@
dllib=@DLLIB@ dllib=@DLLIB@
CC = @CC@ CC = @CC@
HOSTCC = @CC@
CXX = @CXX@ CXX = @CXX@
DLLTOOL = @DLLTOOL@
INSTALL = @INSTALL@ INSTALL = @INSTALL@
INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_PROGRAM = @INSTALL_PROGRAM@
@ -67,48 +81,61 @@ PS2PDF = @PS2PDF@
GIT = @GIT@ GIT = @GIT@
CPPFLAGS = @DEFS@ -I. -I$(srcdir) @CPPFLAGS@ CPPFLAGS = @DEFS@ -I. -I$(srcdir) @CPPFLAGS@
CXXFLAGS = -Wall @CXXFLAGS@ CXXFLAGS = @WARNING_FLAGS@ @CXXFLAGS@
PICFLAGS = @PICFLAG@ PICFLAGS = @PICFLAG@
LDFLAGS = @rdynamic@ @LDFLAGS@ LDFLAGS = @rdynamic@ @LDFLAGS@
all: dep config.h _pli_types.h version.h ivl@EXEEXT@ all: dep config.h _pli_types.h version_tag.h ivl@EXEEXT@ version.exe iverilog-vpi.man
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) $@); done $(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true
# In the windows world, the installer will need a dosify program to # In the windows world, the installer will need a dosify program to
# dosify text files. # dosify text files.
ifeq (@MINGW32@,yes) ifeq (@MINGW32@,yes)
all: dep dosify.exe all: dep dosify.exe
dosify.exe: dosify.c dosify.exe: $(srcdir)/dosify.c
$(CC) -o dosify.exe dosify.c $(HOSTCC) -o dosify.exe $(srcdir)/dosify.c
endif endif
# This rule rules the compiler in the trivial hello.vl program to make # This rule rules the compiler in the trivial hello.vl program to make
# sure the basics were compiled properly. # sure the basics were compiled properly.
check: all check: all
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) check); done $(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true
test -r check.conf || cp $(srcdir)/check.conf . test -r check.conf || cp $(srcdir)/check.conf .
driver/iverilog -B. -BPivlpp -tcheck -ocheck.vvp $(srcdir)/examples/hello.vl driver/iverilog -B. -BPivlpp -tcheck -ocheck.vvp $(srcdir)/examples/hello.vl
ifeq (@WIN32@,yes)
ifeq (@install_suffix@,)
vvp/vvp -M- -M./vpi ./check.vvp | grep 'Hello, World' vvp/vvp -M- -M./vpi ./check.vvp | grep 'Hello, World'
else
# On Windows if we have a suffix we must run the vvp part of
# the test with a suffix since it was built/linked that way.
ln vvp/vvp.exe vvp/vvp$(suffix).exe
vvp/vvp$(suffix) -M- -M./vpi ./check.vvp | grep 'Hello, World'
rm vvp/vvp$(suffix).exe
endif
else
vvp/vvp -M- -M./vpi ./check.vvp | grep 'Hello, World'
endif
clean: clean:
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) $@); done $(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true
ifeq (@MINGW32@,no) rm -f *.o parse.cc parse.h lexor.cc
(cd driver-vpi ; $(MAKE) $@) rm -f ivl.exp iverilog-vpi.man iverilog-vpi.pdf iverilog-vpi.ps
endif rm -f parse.output syn-rules.output dosify.exe ivl@EXEEXT@ check.vvp
rm -f *.o parse.cc parse.cc.output parse.h lexor.cc rm -f lexor_keyword.cc libivl.a libvpi.a iverilog-vpi syn-rules.cc
rm -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 -rf dep rm -rf dep
rm -f version.exe
distclean: clean distclean: clean
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) $@); done $(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true
ifeq (@MINGW32@,no) $(foreach dir,$(NOTUSED),$(MAKE) -C $(dir) $@ && ) true
(cd driver-vpi ; $(MAKE) $@) rm -f Makefile config.status config.log config.cache
rm -f stamp-config-h config.h
rm -f stamp-_pli_types-h _pli_types.h
ifneq (@srcdir@,.)
rm -f version_tag.h check.conf
rmdir $(SUBDIRS) $(NOTUSED)
endif endif
for dir in $(NOTUSED); do (cd $$dir ; $(MAKE) $@); done rm -rf autom4te.cache
rm -f Makefile config.status config.log config.cache config.h
rm -f _pli_types.h
TT = t-dll.o t-dll-api.o t-dll-expr.o t-dll-proc.o t-dll-analog.o TT = t-dll.o t-dll-api.o t-dll-expr.o t-dll-proc.o t-dll-analog.o
FF = cprop.o nodangle.o synth.o synth2.o syn-rules.o FF = cprop.o nodangle.o synth.o synth2.o syn-rules.o
@ -134,12 +161,22 @@ $(FF) $(TT)
Makefile: $(srcdir)/Makefile.in config.status Makefile: $(srcdir)/Makefile.in config.status
./config.status --file=$@ ./config.status --file=$@
config.h: $(srcdir)/config.h.in stamp-config-h: $(srcdir)/config.h.in config.status
./config.status --header=$@ @rm -f $@
./config.status config.h
config.h: stamp-config-h
_pli_types.h: $(srcdir)/_pli_types.h.in stamp-_pli_types-h: $(srcdir)/_pli_types.h.in config.status
./config.status --header=$@ @rm -f $@
./config.status _pli_types.h
_pli_types.h: stamp-_pli_types-h
$(srcdir)/configure: $(srcdir)/configure.in $(srcdir)/aclocal.m4
cd $(srcdir) && autoconf
config.status: $(srcdir)/configure
./config.status --recheck
./config.status
ifeq (@WIN32@,yes) ifeq (@WIN32@,yes)
# Under Windows (mingw) I need to make the ivl.exe in two steps. # Under Windows (mingw) I need to make the ivl.exe in two steps.
@ -148,7 +185,7 @@ ifeq (@WIN32@,yes)
# that really exports the things that the import library imports. # that really exports the things that the import library imports.
ivl@EXEEXT@: $O $(srcdir)/ivl.def ivl@EXEEXT@: $O $(srcdir)/ivl.def
$(CXX) -o ivl@EXEEXT@ $O $(dllib) @EXTRALIBS@ $(CXX) -o ivl@EXEEXT@ $O $(dllib) @EXTRALIBS@
dlltool --dllname ivl@EXEEXT@ --def $(srcdir)/ivl.def \ $(DLLTOOL) --dllname ivl@EXEEXT@ --def $(srcdir)/ivl.def \
--output-lib libivl.a --output-exp ivl.exp --output-lib libivl.a --output-exp ivl.exp
$(CXX) $(LDFLAGS) -o ivl@EXEEXT@ ivl.exp $O $(dllib) @EXTRALIBS@ $(CXX) $(LDFLAGS) -o ivl@EXEEXT@ ivl.exp $O $(dllib) @EXTRALIBS@
else else
@ -156,12 +193,10 @@ ivl@EXEEXT@: $O
$(CXX) $(LDFLAGS) -o ivl@EXEEXT@ $O $(dllib) $(CXX) $(LDFLAGS) -o ivl@EXEEXT@ $O $(dllib)
endif endif
ifeq (@MINGW32@,yes) ifeq (@MINGW32@,no)
SUBDIRS += driver-vpi
else
all: dep iverilog-vpi all: dep iverilog-vpi
iverilog-vpi: iverilog-vpi.sh Makefile iverilog-vpi: $(srcdir)/iverilog-vpi.sh Makefile
sed -e 's;@SHARED@;@shared@;' -e 's;@PIC@;@PICFLAG@;' \ sed -e 's;@SHARED@;@shared@;' -e 's;@PIC@;@PICFLAG@;' \
-e 's;@SUFFIX@;$(suffix);' \ -e 's;@SUFFIX@;$(suffix);' \
-e 's;@IVCC@;$(CC);' \ -e 's;@IVCC@;$(CC);' \
@ -172,47 +207,53 @@ iverilog-vpi: iverilog-vpi.sh Makefile
chmod +x $@ chmod +x $@
endif endif
version.exe: $(srcdir)/version.c $(srcdir)/version_base.h version_tag.h
$(HOSTCC) @WARNING_FLAGS@ -o version.exe -I. -I$(srcdir) $(srcdir)/version.c
dep: dep:
mkdir dep mkdir dep
%.o: %.cc %.o: %.cc config.h
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -MD -c $< -o $*.o $(CXX) $(CPPFLAGS) $(CXXFLAGS) @DEPENDENCY_FLAG@ -c $< -o $*.o
mv $*.d dep/$*.d mv $*.d dep/$*.d
# Here are some explicit dependencies needed to get things going.
main.o: main.cc version_tag.h
lexor.o: lexor.cc parse.h lexor.o: lexor.cc parse.h
parse.o: parse.cc parse.o: parse.cc
parse.cc parse.h: $(srcdir)/parse.y # Build this in two steps to avoid parallel build issues (see pr3462585)
$(YACC) --verbose -t -p VL -d -o parse.cc $(srcdir)/parse.y parse.cc: $(srcdir)/parse.y
$(YACC) --verbose -t -p VL -d -o $@ $<
parse.h: parse.cc
mv parse.cc.h parse.h 2>/dev/null || mv parse.hh parse.h mv parse.cc.h parse.h 2>/dev/null || mv parse.hh parse.h
syn-rules.cc: $(srcdir)/syn-rules.y syn-rules.cc: $(srcdir)/syn-rules.y
$(YACC) --verbose -p syn_ -o syn-rules.cc $(srcdir)/syn-rules.y $(YACC) --verbose -t -p syn_ -o $@ $<
lexor.cc: $(srcdir)/lexor.lex lexor.cc: $(srcdir)/lexor.lex
$(LEX) -PVL -s -olexor.cc $(srcdir)/lexor.lex $(LEX) -PVL -s -t $< > $@
lexor_keyword.o: lexor_keyword.cc parse.h lexor_keyword.o: lexor_keyword.cc parse.h
lexor_keyword.cc: lexor_keyword.gperf lexor_keyword.cc: $(srcdir)/lexor_keyword.gperf
gperf -o -i 7 -C -k 1-4,$$ -L ANSI-C -H keyword_hash -N check_identifier -t $(srcdir)/lexor_keyword.gperf > lexor_keyword.cc || (rm -f lexor_keyword.cc ; false) gperf -o -i 7 -C -k 1-4,$$ -L ANSI-C -H keyword_hash -N check_identifier -t $(srcdir)/lexor_keyword.gperf > lexor_keyword.cc || (rm -f lexor_keyword.cc ; false)
iverilog-vpi.ps: $(srcdir)/iverilog-vpi.man iverilog-vpi.man: $(srcdir)/iverilog-vpi.man.in version.exe
$(MAN) -t $(srcdir)/iverilog-vpi.man > iverilog-vpi.ps ./version.exe `head -1 $(srcdir)/iverilog-vpi.man.in`'\n' > $@
tail -n +2 $(srcdir)/iverilog-vpi.man.in >> $@
iverilog-vpi.ps: iverilog-vpi.man
$(MAN) -t ./iverilog-vpi.man > iverilog-vpi.ps
iverilog-vpi.pdf: iverilog-vpi.ps iverilog-vpi.pdf: iverilog-vpi.ps
$(PS2PDF) iverilog-vpi.ps iverilog-vpi.pdf $(PS2PDF) iverilog-vpi.ps iverilog-vpi.pdf
# The version.h header file is the concatenation of a relatively static
# base version and the detailed version tag.
version.h: $(srcdir)/version_base.in version_tag.h
cat $(srcdir)/version_base.in version_tag.h > version.h
# For VERSION_TAG in driver/main.c, first try git-describe, then look for a # For VERSION_TAG in driver/main.c, first try git-describe, then look for a
# version.h file in the source tree (included in snapshots and releases), and # version_tag.h file in the source tree (included in snapshots and releases),
# finally use nothing. # and finally use nothing.
# "true" and "false" in the next few lines are Unix shell command names # "true" and "false" in the next few lines are Unix shell command names
ifeq ($(GIT),none) ifeq ($(GIT),none)
@ -223,15 +264,16 @@ endif
version_tag.h version: version_tag.h version:
@if $(GIT_PRESENT) && test -d $(srcdir)/.git; then \ @if $(GIT_PRESENT) && test -d $(srcdir)/.git; then \
echo "Using git-describe for VERSION_TAG"; \ echo "Using git-describe for VERSION_TAG"; \
tmp=`$(GIT) --git-dir $(srcdir)/.git describe \ tag=`$(GIT) --git-dir $(srcdir)/.git describe --always --dirty`; \
| sed -e 's;\(.*\);#define VERSION_TAG "\1";'`; \ tmp=`printf "#ifndef VERSION_TAG\n#define VERSION_TAG \"$$tag\"\n#endif\n"`; \
echo "$$tmp" | diff - version_tag.h > /dev/null 2>&1 || echo "$$tmp" > version_tag.h || exit 1; \ echo "$$tmp" | diff - version_tag.h > /dev/null 2>&1 || echo "$$tmp" > version_tag.h || exit 1; \
elif test -r $(srcdir)/version_tag.h; then \ elif test -r $(srcdir)/version_tag.h; then \
echo "Using $(srcdir)/version_tag.h for VERSION_TAG"; \ echo "Using $(srcdir)/version_tag.h for VERSION_TAG"; \
diff $(srcdir)/version_tag.h version_tag.h > /dev/null 2>&1 || cp $(srcdir)/version_tag.h version_tag.h; \ diff $(srcdir)/version_tag.h version_tag.h > /dev/null 2>&1 || cp $(srcdir)/version_tag.h version_tag.h; \
else \ else \
echo "Using empty VERSION_TAG"; \ echo "Using empty VERSION_TAG"; \
echo '#define VERSION_TAG ""' > version_tag.h; \ tmp=`printf "#ifndef VERSION_TAG\n#define VERSION_TAG \"\"\n#endif\n"`; \
echo "$$tmp" | diff - version_tag.h > /dev/null 2>&1 || echo "$$tmp" > version_tag.h || exit 1; \
fi fi
ifeq (@MINGW32@,yes) ifeq (@MINGW32@,yes)
@ -258,7 +300,7 @@ WIN32_INSTALL = $(bindir)/iverilog-vpi$(suffix)
endif endif
install: all installdirs $(libdir)/ivl$(suffix)/ivl@EXEEXT@ $(libdir)/ivl$(suffix)/include/constants.vams $(libdir)/ivl$(suffix)/include/disciplines.vams $(includedir)/ivl_target.h $(includedir)/_pli_types.h $(includedir)/vpi_user.h $(includedir)/acc_user.h $(includedir)/veriuser.h $(WIN32_INSTALL) $(INSTALL_DOC) install: all installdirs $(libdir)/ivl$(suffix)/ivl@EXEEXT@ $(libdir)/ivl$(suffix)/include/constants.vams $(libdir)/ivl$(suffix)/include/disciplines.vams $(includedir)/ivl_target.h $(includedir)/_pli_types.h $(includedir)/vpi_user.h $(includedir)/acc_user.h $(includedir)/veriuser.h $(WIN32_INSTALL) $(INSTALL_DOC)
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) $@); done $(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true
$(bindir)/iverilog-vpi$(suffix): ./iverilog-vpi $(bindir)/iverilog-vpi$(suffix): ./iverilog-vpi
$(INSTALL_SCRIPT) ./iverilog-vpi "$(DESTDIR)$(bindir)/iverilog-vpi$(suffix)" $(INSTALL_SCRIPT) ./iverilog-vpi "$(DESTDIR)$(bindir)/iverilog-vpi$(suffix)"
@ -287,8 +329,8 @@ $(includedir)/acc_user.h: $(srcdir)/acc_user.h
$(includedir)/veriuser.h: $(srcdir)/veriuser.h $(includedir)/veriuser.h: $(srcdir)/veriuser.h
$(INSTALL_DATA) $(srcdir)/veriuser.h "$(DESTDIR)$(includedir)/veriuser.h" $(INSTALL_DATA) $(srcdir)/veriuser.h "$(DESTDIR)$(includedir)/veriuser.h"
$(mandir)/man1/iverilog-vpi$(suffix).1: $(srcdir)/iverilog-vpi.man $(mandir)/man1/iverilog-vpi$(suffix).1: iverilog-vpi.man
$(INSTALL_DATA) $(srcdir)/iverilog-vpi.man "$(DESTDIR)$(mandir)/man1/iverilog-vpi$(suffix).1" $(INSTALL_DATA) iverilog-vpi.man "$(DESTDIR)$(mandir)/man1/iverilog-vpi$(suffix).1"
$(prefix)/iverilog-vpi$(suffix).pdf: iverilog-vpi.pdf $(prefix)/iverilog-vpi$(suffix).pdf: iverilog-vpi.pdf
$(INSTALL_DATA) iverilog-vpi.pdf "$(DESTDIR)$(prefix)/iverilog-vpi$(suffix).pdf" $(INSTALL_DATA) iverilog-vpi.pdf "$(DESTDIR)$(prefix)/iverilog-vpi$(suffix).pdf"
@ -303,7 +345,7 @@ installdirs: $(srcdir)/mkinstalldirs
"$(DESTDIR)$(mandir)/man1" "$(DESTDIR)$(mandir)/man1"
uninstall: uninstall:
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) $@); done $(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true
for f in ivl@EXEEXT@ include/constants.vams include/disciplines.vams; \ for f in ivl@EXEEXT@ include/constants.vams include/disciplines.vams; \
do rm -f "$(DESTDIR)$(libdir)/ivl$(suffix)/$$f"; done do rm -f "$(DESTDIR)$(libdir)/ivl$(suffix)/$$f"; done
-rmdir "$(DESTDIR)$(libdir)/ivl$(suffix)/include" -rmdir "$(DESTDIR)$(libdir)/ivl$(suffix)/include"
@ -312,7 +354,7 @@ uninstall:
do rm -f "$(DESTDIR)$(bindir)/$$f"; done do rm -f "$(DESTDIR)$(bindir)/$$f"; done
for f in ivl_target.h vpi_user.h _pli_types.h acc_user.h veriuser.h; \ for f in ivl_target.h vpi_user.h _pli_types.h acc_user.h veriuser.h; \
do rm -f "$(DESTDIR)$(includedir)/$$f"; done do rm -f "$(DESTDIR)$(includedir)/$$f"; done
-test X$(suffix) = X || rmdir "$(DESTDIR)/$(includedir)" -test X$(suffix) = X || rmdir "$(DESTDIR)$(includedir)"
rm -f "$(DESTDIR)$(mandir)/man1/iverilog-vpi$(suffix).1" "$(DESTDIR)$(prefix)/iverilog-vpi$(suffix).pdf" rm -f "$(DESTDIR)$(mandir)/man1/iverilog-vpi$(suffix).1" "$(DESTDIR)$(prefix)/iverilog-vpi$(suffix).pdf"

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1998-2008 Stephen Williams (steve@icarus.com) * Copyright (c) 1998-2009 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -22,14 +22,17 @@
# include "Module.h" # include "Module.h"
# include "PGate.h" # include "PGate.h"
# include "PWire.h" # include "PWire.h"
# include <assert.h> # include <cassert>
/* n is a permallocated string. */ /* n is a permallocated string. */
Module::Module(perm_string n) Module::Module(perm_string n)
: PScope(n) : PScope(n)
{ {
library_flag = false; library_flag = false;
is_cell = false;
uc_drive = UCD_NONE;
default_nettype = NetNet::NONE; default_nettype = NetNet::NONE;
timescale_warn_done = false;
} }
Module::~Module() Module::~Module()

View File

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

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1999-2008 Stephen Williams (steve@icarus.com) * Copyright (c) 1999-2009 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -26,6 +26,11 @@
# include "verinum.h" # include "verinum.h"
# include "netmisc.h" # include "netmisc.h"
bool dly_used_no_timescale = false;
bool dly_used_timescale = false;
bool display_ts_dly_warning = true;
PDelays::PDelays() PDelays::PDelays()
{ {
delete_flag_ = true; delete_flag_ = true;
@ -60,12 +65,28 @@ void PDelays::set_delays(const svector<PExpr*>*del, bool df)
delete_flag_ = df; delete_flag_ = df;
} }
static NetExpr*calculate_val(Design*des, NetScope*scope, const PExpr*expr) static NetExpr*calculate_val(Design*des, NetScope*scope, PExpr*expr)
{ {
ivl_variable_type_t tmp_type = IVL_VT_NO_TYPE;
bool tmp_flag = false;
expr->test_width(des, scope, 0, 0, tmp_type, tmp_flag);
NetExpr*dex = expr->elaborate_expr(des, scope, -1, false); NetExpr*dex = expr->elaborate_expr(des, scope, -1, false);
eval_expr(dex); eval_expr(dex);
/* Print a warning if we find default and `timescale based
* delays in the design, since this is likely an error. */
if (scope->time_from_timescale()) dly_used_timescale = true;
else dly_used_no_timescale = true;
if (display_ts_dly_warning &&
dly_used_no_timescale && dly_used_timescale) {
cerr << "warning: Found both default and "
"`timescale based delays. Use" << endl;
cerr << " -Wtimescale to find the "
"module(s) with no `timescale." << endl;
display_ts_dly_warning = false;
}
/* If the delay expression is a real constant or vector /* If the delay expression is a real constant or vector
constant, then evaluate it, scale it to the local time constant, then evaluate it, scale it to the local time
units, and return an adjusted value. */ units, and return an adjusted value. */
@ -119,6 +140,20 @@ static NetExpr* make_delay_nets(Design*des, NetScope*scope, NetExpr*expr)
return expr; return expr;
} }
static NetExpr* calc_decay_time(NetExpr *rise, NetExpr *fall)
{
NetEConst *c_rise = dynamic_cast<NetEConst*>(rise);
NetEConst *c_fall = dynamic_cast<NetEConst*>(fall);
if (c_rise && c_fall) {
if (c_rise->value() < c_fall->value()) return rise;
else return fall;
}
cerr << fall->get_fileline() << ": sorry: can not calculate the "
<< "decay time from " << *rise << " and " << *fall << endl;
return 0;
}
void PDelays::eval_delays(Design*des, NetScope*scope, void PDelays::eval_delays(Design*des, NetScope*scope,
NetExpr*&rise_time, NetExpr*&rise_time,
NetExpr*&fall_time, NetExpr*&fall_time,
@ -140,14 +175,14 @@ void PDelays::eval_delays(Design*des, NetScope*scope,
if (delay_[2]) { if (delay_[2]) {
decay_time = calculate_val(des, scope, delay_[2]); decay_time = calculate_val(des, scope, delay_[2]);
if (as_nets_flag) if (as_nets_flag)
decay_time = make_delay_nets(des, scope, decay_time); decay_time = make_delay_nets(des, scope,
decay_time);
} else { } else {
if (rise_time < fall_time) // If this is zero then we need to do the min()
decay_time = rise_time; // at run time.
else decay_time = calc_decay_time(rise_time, fall_time);
decay_time = fall_time;
} }
} else { } else {
assert(delay_[2] == 0); assert(delay_[2] == 0);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1998-2008 Stephen Williams <steve@icarus.com> * Copyright (c) 1998-2008,2011 Stephen Williams <steve@icarus.com>
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -61,6 +61,11 @@ NetNet* PExpr::elaborate_bi_net(Design*des, NetScope*) const
return 0; return 0;
} }
bool PExpr::is_collapsible_net(Design*, NetScope*) const
{
return false;
}
PEBinary::PEBinary(char op, PExpr*l, PExpr*r) PEBinary::PEBinary(char op, PExpr*l, PExpr*r)
: op_(op), left_(l), right_(r) : op_(op), left_(l), right_(r)
{ {
@ -79,6 +84,8 @@ bool PEBinary::has_aa_term(Design*des, NetScope*scope) const
PEBComp::PEBComp(char op, PExpr*l, PExpr*r) PEBComp::PEBComp(char op, PExpr*l, PExpr*r)
: PEBinary(op, l, r) : PEBinary(op, l, r)
{ {
left_width_ = 0;
right_width_ = 0;
} }
PEBComp::~PEBComp() PEBComp::~PEBComp()

27
PExpr.h
View File

@ -1,7 +1,7 @@
#ifndef __PExpr_H #ifndef __PExpr_H
#define __PExpr_H #define __PExpr_H
/* /*
* Copyright (c) 1998-2009 Stephen Williams <steve@icarus.com> * Copyright (c) 1998-2011 Stephen Williams <steve@icarus.com>
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -133,6 +133,12 @@ class PExpr : public LineInfo {
// evaluated, return 0. // evaluated, return 0.
virtual verinum* eval_const(Design*des, NetScope*sc) const; virtual verinum* eval_const(Design*des, NetScope*sc) const;
// This method returns true if the expression represents a
// structural net that can have multiple drivers. This is
// used to test whether an input port connection can be
// collapsed to a single wire.
virtual bool is_collapsible_net(Design*des, NetScope*scope) const;
// This method returns true if that expression is the same as // This method returns true if that expression is the same as
// this expression. This method is used for comparing // this expression. This method is used for comparing
// expressions that must be structurally "identical". // expressions that must be structurally "identical".
@ -175,6 +181,7 @@ class PEConcat : public PExpr {
virtual NetAssign_* elaborate_lval(Design*des, virtual NetAssign_* elaborate_lval(Design*des,
NetScope*scope, NetScope*scope,
bool is_force) const; bool is_force) const;
virtual bool is_collapsible_net(Design*des, NetScope*scope) const;
private: private:
NetNet* elaborate_lnet_common_(Design*des, NetScope*scope, NetNet* elaborate_lnet_common_(Design*des, NetScope*scope,
bool bidirectional_flag) const; bool bidirectional_flag) const;
@ -183,7 +190,6 @@ class PEConcat : public PExpr {
std::valarray<unsigned>tested_widths_; std::valarray<unsigned>tested_widths_;
PExpr*repeat_; PExpr*repeat_;
NetExpr*repeat_expr_;
}; };
/* /*
@ -287,6 +293,8 @@ class PEIdent : public PExpr {
verinum* eval_const(Design*des, NetScope*sc) const; verinum* eval_const(Design*des, NetScope*sc) const;
virtual bool is_collapsible_net(Design*des, NetScope*scope) const;
const pform_name_t& path() const { return path_; } const pform_name_t& path() const { return path_; }
private: private:
@ -308,7 +316,8 @@ class PEIdent : public PExpr {
NetExpr* calculate_up_do_base_(Design*, NetScope*) const; NetExpr* calculate_up_do_base_(Design*, NetScope*) const;
bool calculate_param_range_(Design*, NetScope*, bool calculate_param_range_(Design*, NetScope*,
const NetExpr*msb_ex, long&msb, const NetExpr*msb_ex, long&msb,
const NetExpr*lsb_ex, long&lsb) const; const NetExpr*lsb_ex, long&lsb,
long length) const;
bool calculate_up_do_width_(Design*, NetScope*, unsigned long&wid) const; bool calculate_up_do_width_(Design*, NetScope*, unsigned long&wid) const;
@ -339,6 +348,12 @@ class PEIdent : public PExpr {
NetScope*found, NetScope*found,
const NetExpr*par_msb, const NetExpr*par_msb,
const NetExpr*par_lsb) const; const NetExpr*par_lsb) const;
NetExpr*elaborate_expr_param_idx_do_(Design*des,
NetScope*scope,
const NetExpr*par,
NetScope*found,
const NetExpr*par_msb,
const NetExpr*par_lsb) const;
NetExpr*elaborate_expr_net(Design*des, NetExpr*elaborate_expr_net(Design*des,
NetScope*scope, NetScope*scope,
NetNet*net, NetNet*net,
@ -527,6 +542,10 @@ class PEBComp : public PEBinary {
NetExpr* elaborate_expr(Design*des, NetScope*scope, NetExpr* elaborate_expr(Design*des, NetScope*scope,
int expr_width, bool sys_task_arg) const; int expr_width, bool sys_task_arg) const;
NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const; NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
private:
int left_width_;
int right_width_;
}; };
/* /*
@ -668,6 +687,8 @@ class PECallFunction : public PExpr {
bool check_call_matches_definition_(Design*des, NetScope*dscope) const; bool check_call_matches_definition_(Design*des, NetScope*dscope) const;
NetExpr* cast_to_width_(NetExpr*expr, int wid, bool signed_flag) const;
NetExpr* elaborate_sfunc_(Design*des, NetScope*scope, int expr_wid) const; NetExpr* elaborate_sfunc_(Design*des, NetScope*scope, int expr_wid) const;
NetExpr* elaborate_access_func_(Design*des, NetScope*scope, ivl_nature_t) const; NetExpr* elaborate_access_func_(Design*des, NetScope*scope, ivl_nature_t) const;
unsigned test_width_sfunc_(Design*des, NetScope*scope, unsigned test_width_sfunc_(Design*des, NetScope*scope,

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1999-2007 Stephen Williams (steve@icarus.com) * Copyright (c) 1999-2010 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -22,7 +22,7 @@
# include "PGate.h" # include "PGate.h"
# include "PExpr.h" # include "PExpr.h"
# include "verinum.h" # include "verinum.h"
# include <assert.h> # include <cassert>
PGate::PGate(perm_string name, PGate::PGate(perm_string name,
svector<PExpr*>*pins, svector<PExpr*>*pins,
@ -189,4 +189,3 @@ perm_string PGModule::get_type()
{ {
return type_; return type_;
} }

View File

@ -161,7 +161,8 @@ class PGBuiltin : public PGate {
unsigned calculate_array_count_(Design*, NetScope*, unsigned calculate_array_count_(Design*, NetScope*,
long&high, long&low) const; long&high, long&low) const;
unsigned calculate_output_count_(void) const; void calculate_gate_and_lval_count_(unsigned&gate_count,
unsigned&lval_count) const;
NetNode* create_gate_for_output_(Design*, NetScope*, NetNode* create_gate_for_output_(Design*, NetScope*,
perm_string gate_name, perm_string gate_name,

View File

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

View File

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

12
PSpec.h
View File

@ -1,7 +1,7 @@
#ifndef __PSpec_H #ifndef __PSpec_H
#define __PSpec_H #define __PSpec_H
/* /*
* Copyright (c) 2006 Stephen Williams <steve@icarus.com> * Copyright (c) 2006-2011 Stephen Williams <steve@icarus.com>
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -46,6 +46,12 @@ class PExpr;
* *
* If data_source_expression != nil, then the path is edge sensitive * If data_source_expression != nil, then the path is edge sensitive
* and the edge might not be 0. * and the edge might not be 0.
*
* The full flag is used to verify that only vectors of the same size
* are used in a parallel connection. Icarus always creates a full
* connection between the source and destination. The polarity is for
* informational (display) purposes only. The polarity is either '+',
* '-' or 0.
*/ */
class PSpecPath : public LineInfo { class PSpecPath : public LineInfo {
@ -63,6 +69,10 @@ class PSpecPath : public LineInfo {
class PExpr* condition; class PExpr* condition;
// Edge specification (-1==negedge, 0 = no edge, 1==posedge) // Edge specification (-1==negedge, 0 = no edge, 1==posedge)
int edge; int edge;
// Is this a full connection.
bool full_flag;
// What is the polarity of the connection.
char polarity;
// Ordered set of source nodes of a path // Ordered set of source nodes of a path
std::vector<perm_string> src; std::vector<perm_string> src;
// Ordered set of destination nodes of a path // Ordered set of destination nodes of a path

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1999-2007 Stephen Williams (steve@icarus.com) * Copyright (c) 1999-2011 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -20,7 +20,7 @@
# include "config.h" # include "config.h"
# include "PWire.h" # include "PWire.h"
# include "PExpr.h" # include "PExpr.h"
# include <assert.h> # include <cassert>
PWire::PWire(perm_string n, PWire::PWire(perm_string n,
NetNet::Type t, NetNet::Type t,
@ -29,8 +29,8 @@ PWire::PWire(perm_string n,
: name_(n), type_(t), port_type_(pt), data_type_(dt), : name_(n), type_(t), port_type_(pt), data_type_(dt),
signed_(false), isint_(false), signed_(false), isint_(false),
port_msb_(0), port_lsb_(0), port_set_(false), port_msb_(0), port_lsb_(0), port_set_(false),
net_msb_(0), net_lsb_(0), net_set_(false), error_cnt_(0), net_msb_(0), net_lsb_(0), net_set_(false), is_scalar_(false),
lidx_(0), ridx_(0), discipline_(0) error_cnt_(0), lidx_(0), ridx_(0), discipline_(0)
{ {
if (t == NetNet::INTEGER) { if (t == NetNet::INTEGER) {
type_ = NetNet::REG; type_ = NetNet::REG;
@ -58,7 +58,15 @@ bool PWire::set_wire_type(NetNet::Type t)
type_ = t; type_ = t;
return true; return true;
case NetNet::IMPLICIT_REG: case NetNet::IMPLICIT_REG:
if (t == NetNet::REG) { type_ = t; return true; } if (t == NetNet::REG) {
type_ = t;
return true;
}
if (t == NetNet::INTEGER) {
type_ = NetNet::REG;
isint_ = true;
return true;
}
return false; return false;
case NetNet::REG: case NetNet::REG:
if (t == NetNet::INTEGER) { if (t == NetNet::INTEGER) {
@ -135,7 +143,12 @@ bool PWire::get_isint() const
return isint_; return isint_;
} }
void PWire::set_range(PExpr*m, PExpr*l, PWSRType type) bool PWire::get_scalar() const
{
return is_scalar_;
}
void PWire::set_range(PExpr*m, PExpr*l, PWSRType type, bool is_scalar)
{ {
switch (type) { switch (type) {
case SR_PORT: case SR_PORT:
@ -147,6 +160,7 @@ void PWire::set_range(PExpr*m, PExpr*l, PWSRType type)
port_msb_ = m; port_msb_ = m;
port_lsb_ = l; port_lsb_ = l;
port_set_ = true; port_set_ = true;
is_scalar_ = is_scalar;
} }
return; return;
@ -159,6 +173,7 @@ void PWire::set_range(PExpr*m, PExpr*l, PWSRType type)
net_msb_ = m; net_msb_ = m;
net_lsb_ = l; net_lsb_ = l;
net_set_ = true; net_set_ = true;
is_scalar_ = is_scalar;
} }
return; return;
@ -181,6 +196,7 @@ void PWire::set_range(PExpr*m, PExpr*l, PWSRType type)
net_msb_ = m; net_msb_ = m;
net_lsb_ = l; net_lsb_ = l;
net_set_ = true; net_set_ = true;
is_scalar_ = is_scalar;
} }
return; return;
} }

View File

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

View File

@ -156,8 +156,9 @@ step. There may be dangling references, and it is not yet clear which
module is the root. module is the root.
One can see a human readable version of the final pform by using the One can see a human readable version of the final pform by using the
``-P <path>'' flag to the compiler. This will cause iverilog to dump ``-P <path>'' flag to the ``ivl'' subcommand. This will cause ivl
the pform into the file named <path>. to dump the pform into the file named <path>. (Note that this is not
normally done, unless debugging the ``ivl'' subcommand.)
3.3 Elaboration 3.3 Elaboration

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 * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -18,12 +18,14 @@
*/ */
# include "StringHeap.h" # include "StringHeap.h"
#ifdef HAVE_MALLOC_H # include <cstdlib>
# include <malloc.h> # include <cstring>
# include <cassert>
#ifdef CHECK_WITH_VALGRIND
static char **string_pool = NULL;
static unsigned string_pool_count = 0;
#endif #endif
# include <stdlib.h>
# include <string.h>
# include <assert.h>
StringHeap::StringHeap() StringHeap::StringHeap()
{ {
@ -46,6 +48,12 @@ const char* StringHeap::add(const char*text)
unsigned rem = HEAPCELL - cell_ptr_; unsigned rem = HEAPCELL - cell_ptr_;
if (rem < (len+1)) { if (rem < (len+1)) {
cell_base_ = (char*)malloc(HEAPCELL); cell_base_ = (char*)malloc(HEAPCELL);
#ifdef CHECK_WITH_VALGRIND
string_pool_count += 1;
string_pool = (char **) realloc(string_pool,
string_pool_count*sizeof(char **));
string_pool[string_pool_count-1] = cell_base_;
#endif
cell_ptr_ = 0; cell_ptr_ = 0;
cell_count_ += 1; cell_count_ += 1;
assert(cell_base_ != 0); assert(cell_base_ != 0);
@ -80,6 +88,22 @@ StringHeapLex::~StringHeapLex()
{ {
} }
void StringHeapLex::cleanup()
{
#ifdef CHECK_WITH_VALGRIND
for (unsigned idx = 0 ; idx < string_pool_count ; idx += 1) {
free(string_pool[idx]);
}
free(string_pool);
string_pool = NULL;
string_pool_count = 0;
for (unsigned idx = 0 ; idx < HASH_SIZE ; idx += 1) {
hash_table_[idx] = 0;
}
#endif
}
unsigned StringHeapLex::add_hit_count() const unsigned StringHeapLex::add_hit_count() const
{ {
return hit_count_; return hit_count_;
@ -175,4 +199,3 @@ bool operator < (perm_string a, perm_string b)
return false; return false;
} }

View File

@ -1,7 +1,7 @@
#ifndef __StringHeap_H #ifndef __StringHeap_H
#define __StringHeap_H #define __StringHeap_H
/* /*
* Copyright (c) 2002-2004 Stephen Williams (steve@icarus.com) * Copyright (c) 2002-2009 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -38,7 +38,7 @@ class perm_string {
operator const char* () const { return str(); } operator const char* () const { return str(); }
// This is an escape for making perm_string objects out of // This is an escape for making perm_string objects out of
// literals. For example, per_string::literal("Label"); Please // literals. For example, perm_string::literal("Label"); Please
// do *not* cheat and pass arbitrary const char* items here. // do *not* cheat and pass arbitrary const char* items here.
static perm_string literal(const char*t) { return perm_string(t); } static perm_string literal(const char*t) { return perm_string(t); }
@ -104,6 +104,7 @@ class StringHeapLex : private StringHeap {
unsigned add_count() const; unsigned add_count() const;
unsigned add_hit_count() const; unsigned add_hit_count() const;
void cleanup();
private: private:
enum { HASH_SIZE = 4096 }; enum { HASH_SIZE = 4096 };

46
aclocal.m4 vendored
View File

@ -6,7 +6,9 @@
# different builds. Remember to change the default suffix string to some # different builds. Remember to change the default suffix string to some
# value appropriate for the current version. # value appropriate for the current version.
AC_DEFUN([AX_ENABLE_SUFFIX], AC_DEFUN([AX_ENABLE_SUFFIX],
[AC_ARG_ENABLE([suffix],[Set the installation command suffix],[true],[enable_suffix=no]) [AC_ARG_ENABLE([suffix],[AC_HELP_STRING([--enable-suffix],
[Use/set the installation command suffix])],
[true],[enable_suffix=no])
if test X$enable_suffix = Xyes; then if test X$enable_suffix = Xyes; then
install_suffix='-0.9' install_suffix='-0.9'
elif test X$enable_suffix = Xno; then elif test X$enable_suffix = Xno; then
@ -24,7 +26,7 @@ AC_SUBST(install_suffix)
# - the object file produced by AC_COMPILE_IFELSE is called "conftest.$ac_objext" # - the object file produced by AC_COMPILE_IFELSE is called "conftest.$ac_objext"
# - the nm(1) utility is available, and its name is "nm". # - the nm(1) utility is available, and its name is "nm".
AC_DEFUN([_AX_C_UNDERSCORES_MATCH_IF], 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])], [AS_IF([nm conftest.$ac_objext|grep $1 >/dev/null 2>/dev/null],[$2],[$3])],
[AC_MSG_ERROR([underscore test crashed])] [AC_MSG_ERROR([underscore test crashed])]
)]) )])
@ -62,7 +64,7 @@ fi
# AX_WIN32 # AX_WIN32
# -------- # --------
# Combined check for several flavors of Microsoft Windows so # Combined check for several flavors of Microsoft Windows so
# their "issues" can be dealt with # their "issues" can be dealt with
AC_DEFUN([AX_WIN32], AC_DEFUN([AX_WIN32],
[AC_MSG_CHECKING([for Microsoft Windows]) [AC_MSG_CHECKING([for Microsoft Windows])
AC_REQUIRE([AC_CANONICAL_HOST]) []dnl AC_REQUIRE([AC_CANONICAL_HOST]) []dnl
@ -125,6 +127,13 @@ case "${host}" in
*-*-darwin*) *-*-darwin*)
shared="-bundle -undefined suppress -flat_namespace" shared="-bundle -undefined suppress -flat_namespace"
;; ;;
*-*-solaris*)
if test ${using_sunpro_c} = 1
then
shared="-G"
fi
;;
esac esac
AC_SUBST(shared) AC_SUBST(shared)
AC_MSG_RESULT($shared) AC_MSG_RESULT($shared)
@ -151,6 +160,12 @@ case "${host}" in
PICFLAG=+z PICFLAG=+z
;; ;;
*-*-solaris*)
if test ${using_sunpro_c} = 1
then
PICFLAG=-G
fi
;;
esac esac
AC_SUBST(PICFLAG) AC_SUBST(PICFLAG)
AC_MSG_RESULT($PICFLAG) AC_MSG_RESULT($PICFLAG)
@ -214,3 +229,28 @@ case "${host}" in
;; ;;
esac esac
])# AX_CPP_PRECOMP ])# AX_CPP_PRECOMP
# AX_C99_STRTOD
# -------------
AC_DEFUN([AX_C99_STRTOD],
[# On MinGW we need to jump through hoops to get a C99 compliant strtod().
case "${host}" in
*-*-mingw*)
LDFLAGS+=" -Wl,--undefined=___strtod,--wrap,strtod,--defsym,___wrap_strtod=___strtod"
;;
esac
])# AX_C99_STRTOD
# When config.status generates a header, we must update the stamp-h file.
# This file resides in the same directory as the config header
# that is generated. The stamp file name are based on the header name.
# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
# loop where config.status creates the headers, so we can generate
# our stamp files there.
AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
[
_config_header=$1
_stamp_name=stamp-`expr //$_config_header : '.*/\([[^./]]*\)\.[[^./]]*$'`-h
echo "timestamp for $_config_header" > `AS_DIRNAME(["$_config_header"])`/[]$_stamp_name
]) #_AC_AM_CONFIG_HEADER_HOOK

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2002-2008 Stephen Williams (steve@icarus.com) * Copyright (c) 2002-2010 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -21,7 +21,7 @@
# include "functor.h" # include "functor.h"
# include "netlist.h" # include "netlist.h"
# include <assert.h> # include <cassert>
bool NetAssign::is_asynchronous() bool NetAssign::is_asynchronous()
{ {

View File

@ -38,11 +38,9 @@ INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@ INSTALL_DATA = @INSTALL_DATA@
CPPFLAGS = -I$(srcdir) -I$(srcdir)/.. -I.. @CPPFLAGS@ @DEFS@ @PICFLAG@ CPPFLAGS = -I$(srcdir) -I$(srcdir)/.. -I.. @CPPFLAGS@ @DEFS@ @PICFLAG@
CFLAGS = -Wall @CFLAGS@ CFLAGS = @WARNING_FLAGS@ @CFLAGS@
LDFLAGS = @LDFLAGS@ LDFLAGS = @LDFLAGS@
SHARED = @shared@
all: all:
all: dep cadpli.vpl $(ALL32) all: dep cadpli.vpl $(ALL32)
@ -54,13 +52,13 @@ dep:
mkdir dep mkdir dep
%.o: %.c %.o: %.c
$(CC) $(CPPFLAGS) $(CFLAGS) -MD -c $< $(CC) $(CPPFLAGS) $(CFLAGS) @DEPENDENCY_FLAG@ -c $<
mv $*.d dep mv $*.d dep
O = cadpli.o O = cadpli.o
Makefile: $(srcdir)/Makefile.in ../config.status Makefile: $(srcdir)/Makefile.in ../config.status
../config.status --file=$@ cd ..; ./config.status --file=cadpli/$@
SYSTEM_VPI_LDFLAGS = -L../vvp -lvpi SYSTEM_VPI_LDFLAGS = -L../vvp -lvpi
ifeq (@MINGW32@,yes) ifeq (@MINGW32@,yes)
@ -68,10 +66,10 @@ ifeq (@MINGW32@,yes)
endif endif
cadpli.vpl: $O ../vvp/libvpi.a ../libveriuser/libveriuser.o cadpli.vpl: $O ../vvp/libvpi.a ../libveriuser/libveriuser.o
$(CC) @shared@ -o $@ $O ../libveriuser/libveriuser.o $(SYSTEM_VPI_LDFLAGS) $(CC) @shared@ $(LDFLAGS) -o $@ $O ../libveriuser/libveriuser.o $(SYSTEM_VPI_LDFLAGS)
clean: clean:
rm -rf *.o dep cadpli.vpl bin32 rm -rf *.o dep cadpli.vpl
distclean: clean distclean: clean
rm -f Makefile config.log rm -f Makefile config.log

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2003-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 * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -20,9 +20,6 @@
# include <vpi_user.h> # include <vpi_user.h>
# include <veriuser.h> # include <veriuser.h>
# include <stdlib.h> # include <stdlib.h>
#ifdef HAVE_MALLOC_H
# include <malloc.h>
#endif
# include <string.h> # include <string.h>
# include <assert.h> # include <assert.h>
# include "config.h" # include "config.h"

View File

@ -2,7 +2,6 @@
CADENCE PLI1 MODULES CADENCE PLI1 MODULES
Copyright 2003 Stephen Williams Copyright 2003 Stephen Williams
$Id: cadpli.txt,v 1.2 2003/02/17 00:01:25 steve Exp $
With the cadpli module, Icarus Verilog is able to load PLI1 With the cadpli module, Icarus Verilog is able to load PLI1
applications that were compiled and linked to be dynamic loaded by applications that were compiled and linked to be dynamic loaded by
@ -34,15 +33,3 @@ the +loadpli1= argument to Verilog-XL.
The integration from this point is seamless. The PLI application The integration from this point is seamless. The PLI application
hardly knows that it is being invoked by Icarus Verilog instead of hardly knows that it is being invoked by Icarus Verilog instead of
Verilog-XL, so operates as it would otherwise. Verilog-XL, so operates as it would otherwise.
$Log: cadpli.txt,v $
Revision 1.2 2003/02/17 00:01:25 steve
Use a variant of ivl_dlfcn to do dynamic loading
from within the cadpli module.
Change the +cadpli flag to -cadpli, to keep the
plusargs namespace clear.
Revision 1.1 2003/02/16 02:44:47 steve
Add the cadpli HOWTO.

View File

@ -1,7 +1,7 @@
#ifndef __compiler_H #ifndef __compiler_H
#define __compiler_H #define __compiler_H
/* /*
* Copyright (c) 1999-2008 Stephen Williams (steve@icarus.com) * Copyright (c) 1999-2009 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -36,6 +36,12 @@
*/ */
extern unsigned integer_width; extern unsigned integer_width;
/*
* This is the maximum number of recursive module loops allowed within
* a generate block.
*/
extern unsigned recursive_mod_limit;
/* The TIME_WIDTH is the width of time variables. */ /* The TIME_WIDTH is the width of time variables. */
#ifndef TIME_WIDTH #ifndef TIME_WIDTH
# define TIME_WIDTH 64 # define TIME_WIDTH 64
@ -76,9 +82,17 @@ extern bool warn_timescale;
/* Warn about legal but questionable module port bindings. */ /* Warn about legal but questionable module port bindings. */
extern bool warn_portbinding; extern bool warn_portbinding;
/* Warn about constant out of bound selects. */
extern bool warn_ob_select;
/* Warn about structures that may have infinite loops. */ /* Warn about structures that may have infinite loops. */
extern bool warn_inf_loop; extern bool warn_inf_loop;
/* Warn about always @* statements where a part or word select causes
sensitivity to an entire vector or array. */
extern bool warn_sens_entire_vec;
extern bool warn_sens_entire_arr;
/* This is true if verbose output is requested. */ /* This is true if verbose output is requested. */
extern bool verbose_flag; extern bool verbose_flag;
@ -89,6 +103,12 @@ extern bool debug_elab_pexpr;
extern bool debug_synth2; extern bool debug_synth2;
extern bool debug_optimizer; extern bool debug_optimizer;
/* Possibly temporary flag to control virtualization of pin arrays */
extern bool disable_virtual_pins;
/* Limit to size of devirtualized arrays */
extern unsigned long array_size_limit;
/* Path to a directory useful for finding subcomponents. */ /* Path to a directory useful for finding subcomponents. */
extern const char*basedir; extern const char*basedir;
@ -101,9 +121,10 @@ extern int build_library_index(const char*path, bool key_case_sensitive);
specific language features. */ specific language features. */
enum generation_t { enum generation_t {
GN_VER1995 = 1, GN_VER1995 = 1,
GN_VER2001 = 2, GN_VER2001_NOCONFIG = 2,
GN_VER2005 = 3, GN_VER2001 = 3,
GN_DEFAULT = 3 GN_VER2005 = 4,
GN_DEFAULT = 4
}; };
extern generation_t generation_flag; extern generation_t generation_flag;
@ -189,5 +210,6 @@ struct sfunc_return_type {
extern const struct sfunc_return_type* lookup_sys_func(const char*name); extern const struct sfunc_return_type* lookup_sys_func(const char*name);
extern int load_sys_func_table(const char*path); extern int load_sys_func_table(const char*path);
extern void cleanup_sys_func_table();
#endif #endif

965
config.guess vendored

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
#ifndef __config_H /* -*- c++ -*- */ #ifndef __config_H /* -*- c++ -*- */
#define __config_H #define __config_H
/* /*
* Copyright (c) 2001 Stephen Williams (steve@icarus.com) * Copyright (c) 2001-2012 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -36,7 +36,6 @@
# undef HAVE_GETOPT_H # undef HAVE_GETOPT_H
# undef HAVE_INTTYPES_H # undef HAVE_INTTYPES_H
# undef HAVE_LIBIBERTY_H # undef HAVE_LIBIBERTY_H
# undef HAVE_MALLOC_H
# undef HAVE_DLFCN_H # undef HAVE_DLFCN_H
# undef HAVE_DL_H # undef HAVE_DL_H
# undef HAVE_FCHMOD # undef HAVE_FCHMOD
@ -50,4 +49,16 @@
# include <inttypes.h> # include <inttypes.h>
#endif #endif
/* These two are needed by the lxt and lxt2 files (copied from GTKWave). */
# undef HAVE_ALLOCA_H
# undef HAVE_FSEEKO
/* And this is needed by the fst files (copied from GTKWave). */
# undef HAVE_LIBPTHREAD
/*
* Define this if you want to compile vvp with memory freeing and
* special valgrind hooks for the memory pools.
*/
# undef CHECK_WITH_VALGRIND
#endif /* __config_H */ #endif /* __config_H */

415
config.sub vendored
View File

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

View File

@ -11,9 +11,20 @@ AC_CONFIG_HEADER(tgt-vhdl/vhdl_config.h)
AC_CANONICAL_HOST AC_CANONICAL_HOST
dnl Checks for programs. dnl Checks for programs.
AC_PROG_CC AC_PROG_CC
# AC_PROG_CC_C99 is only available in autoconf version 2.60 and later.
# If you must use an older version then comment out the following two
# lines, but be warned that there could be issues with finding the
# nan(), etc. functions. It is really best to upgrade to a supported
# version of autoconf.
AC_PREREQ([2.60])
AC_PROG_CC_C99
AC_PROG_CXX AC_PROG_CXX
AC_PROG_RANLIB AC_PROG_RANLIB
AC_CHECK_TOOL(LD, ld, true)
AC_CHECK_TOOL(AR, ar, true)
AC_CHECK_TOOL(DLLTOOL, dlltool, true)
AC_CHECK_TOOL(STRIP, strip, true) AC_CHECK_TOOL(STRIP, strip, true)
AC_CHECK_TOOL(WINDRES, windres, true)
AC_CHECK_PROGS(XGPERF,gperf,none) AC_CHECK_PROGS(XGPERF,gperf,none)
AC_CHECK_PROGS(MAN,man,none) AC_CHECK_PROGS(MAN,man,none)
AC_CHECK_PROGS(PS2PDF,ps2pdf,none) AC_CHECK_PROGS(PS2PDF,ps2pdf,none)
@ -51,9 +62,43 @@ AC_SUBST(EXEEXT)
# Combined check for Microsoft-related bogosities; sets WIN32 if found # Combined check for Microsoft-related bogosities; sets WIN32 if found
AX_WIN32 AX_WIN32
AC_LANG_CPLUSPLUS # Check to see if we are using the Sun compiler. If so then configure
# some of the flags to match the Sun compiler syntax. This is also used
# in the aclocal.m4 file to configure the flags used to build and link
# dynamic libraries
AC_CHECK_DECL(__SUNPRO_C, using_sunpro_c=1, using_sunpro_c=0)
if test ${using_sunpro_c} = 1
then
AC_SUBST(DEPENDENCY_FLAG, [-xMMD])
AC_SUBST(WARNING_FLAGS, [""])
else
AC_SUBST(DEPENDENCY_FLAG, [-MD])
AC_SUBST(WARNING_FLAGS, ["-Wall -Wshadow"])
fi
AC_CHECK_HEADERS(getopt.h malloc.h inttypes.h libiberty.h iosfwd sys/wait.h) AC_LANG(C++)
# Check that we are using either the GNU compilers or the Sun compilers
# but not a mixture of the two (not currently supported).
AC_CHECK_DECL(__SUNPRO_CC, using_sunpro_cc=1, using_sunpro_cc=0)
if test ${using_sunpro_c} = 1
then
if test ${using_sunpro_cc} = 0
then
echo "*** Error: No support for mixing GNU and Sun compilers. ***"
echo " Using Sun C compiler and GNU C++ compiler.."
exit 1
fi
else
if test ${using_sunpro_cc} = 1
then
echo "*** Error: No support for mixing GNU and Sun compilers. ***"
echo " Using GNU C compiler and Sun C++ compiler.."
exit 1
fi
fi
AC_CHECK_HEADERS(getopt.h inttypes.h libiberty.h iosfwd sys/wait.h)
AC_CHECK_SIZEOF(unsigned long long) AC_CHECK_SIZEOF(unsigned long long)
AC_CHECK_SIZEOF(unsigned long) AC_CHECK_SIZEOF(unsigned long)
@ -79,12 +124,17 @@ AC_CHECK_LIB(bz2, BZ2_bzdopen, HAVE_LIBBZ2=yes, HAVE_LIBBZ2=no)
fi fi
AC_SUBST(HAVE_LIBBZ2) AC_SUBST(HAVE_LIBBZ2)
# The lxt/lxt2 files from GTKWave use these...
AC_FUNC_ALLOCA
AC_FUNC_FSEEKO
# valgrind checks # valgrind checks
AC_ARG_WITH([valgrind], [AS_HELP_STRING([--with-valgrind], AC_ARG_WITH([valgrind], [AC_HELP_STRING([--with-valgrind],
[Add valgrind hooks])], [Add valgrind hooks])],
[], [check_valgrind=yes]) [], [check_valgrind=yes])
AS_IF([test "x$check_valgrind" == xyes], AS_IF([test "x$check_valgrind" = xyes],
[AC_MSG_NOTICE([Not using valgrind hooks])], [AC_MSG_NOTICE([Not using valgrind hooks])],
[AC_CHECK_HEADER([valgrind/memcheck.h], [AC_CHECK_HEADER([valgrind/memcheck.h],
[AC_DEFINE([CHECK_WITH_VALGRIND], [1], [AC_DEFINE([CHECK_WITH_VALGRIND], [1],
@ -117,7 +167,7 @@ AC_SUBST(DLLIB)
AC_PROG_INSTALL AC_PROG_INSTALL
AC_LANG_C AC_LANG(C)
AC_C_BIGENDIAN AC_C_BIGENDIAN
# $host # $host
@ -133,6 +183,9 @@ AX_C_PICFLAG
# may modify CPPFLAGS and CFLAGS # may modify CPPFLAGS and CFLAGS
AX_CPP_PRECOMP AX_CPP_PRECOMP
# may modify LDFLAGS
AX_C99_STRTOD
# Processor specific compile flags # Processor specific compile flags
case "${host}" in case "${host}" in
alpha*-*-linux*) alpha*-*-linux*)
@ -156,7 +209,41 @@ AC_SUBST(file64_support)
# Check that these functions exist. They are mostly C99 # Check that these functions exist. They are mostly C99
# functions that older compilers may not yet support. # functions that older compilers may not yet support.
AC_CHECK_FUNCS(lround nan fmin fmax fopen64) AC_CHECK_FUNCS(fopen64)
# The following math functions may be defined in the math library so look
# in the default libraries first and then look in -lm for them. On some
# systems we may need to use the compiler in C99 mode to get a definition.
# We requested C99 mode earlier with AC_PROG_CC_C99.
AC_SEARCH_LIBS([lround], [m], [AC_DEFINE([HAVE_LROUND], [1])])
AC_SEARCH_LIBS([llround], [m], [AC_DEFINE([HAVE_LLROUND], [1])])
AC_SEARCH_LIBS([nan], [m], [AC_DEFINE([HAVE_NAN], [1])])
AC_SEARCH_LIBS([fmin], [m], [AC_DEFINE([HAVE_FMIN], [1])])
AC_SEARCH_LIBS([fmax], [m], [AC_DEFINE([HAVE_FMAX], [1])])
# Check to see if an unsigned long and uint64_t are the same from
# a compiler perspective. We can not just check that they are the
# same size since unsigned long and unsigned long long are not the
# same from an overloading perspective even though they could be
# the same size on some 64 bit machines. The result from this test
# is only used if inttypes.h is available, so if the test fails for
# that reason we don't care.
AC_LANG(C++)
AC_MSG_CHECKING(if uint64_t and unsigned long are identical)
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include "inttypes.h"
static bool check(unsigned long val)
{
return val != 0;
}
static bool check(uint64_t val)
{
return val != 0;
}]], [[unsigned long ulval = 1;
bool result = check(ulval);
uint64_t uival = 1;
result &= check(uival);
return !result;]])],
[AC_MSG_RESULT(no)],
[AC_DEFINE([UINT64_T_AND_ULONG_SAME], [1]) AC_MSG_RESULT(yes)])
# Linker option used when compiling the target # Linker option used when compiling the target
AX_LD_RDYNAMIC AX_LD_RDYNAMIC
@ -181,21 +268,21 @@ AX_C_UNDERSCORES_TRAILING
####################### #######################
AC_MSG_CHECKING(for sanity of prefix) AC_MSG_CHECKING(for sanity of prefix)
if test X`echo "$prefix" | wc -w` != X1 if test `echo "$prefix" | wc -w` != 1
then then
AC_MSG_ERROR(cannot configure white space in prefix: $prefix) AC_MSG_ERROR(cannot configure white space in prefix: $prefix)
fi fi
AC_MSG_RESULT(ok) AC_MSG_RESULT(ok)
AC_MSG_CHECKING(for sanity of exec_prefix) AC_MSG_CHECKING(for sanity of exec_prefix)
if test X`echo "$exec_prefix" | wc -w` != X1 if test `echo "$exec_prefix" | wc -w` != 1
then then
AC_MSG_ERROR(cannot configure white space in exec_prefix: $exec_prefix) AC_MSG_ERROR(cannot configure white space in exec_prefix: $exec_prefix)
fi fi
AC_MSG_RESULT(ok) AC_MSG_RESULT(ok)
AC_MSG_CHECKING(for sanity of libdir) AC_MSG_CHECKING(for sanity of libdir)
if test X`echo "$libdir" | wc -w` != X1 if test `echo "$libdir" | wc -w` != 1
then then
AC_MSG_ERROR(cannot configure white space in libdir: $libdir) AC_MSG_ERROR(cannot configure white space in libdir: $libdir)
fi fi

View File

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

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1998-2008 Stephen Williams (steve@icarus.com) * Copyright (c) 1998-2010 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -119,7 +119,8 @@ ostream& operator << (ostream&o, ivl_switch_type_t val)
static inline void dump_scope_path(ostream&o, const NetScope*scope) static inline void dump_scope_path(ostream&o, const NetScope*scope)
{ {
if (const NetScope*parent = scope->parent()) { const NetScope*parent = scope->parent();
if (parent) {
dump_scope_path(o, parent); dump_scope_path(o, parent);
o << "."; o << ".";
} }
@ -208,8 +209,12 @@ void NetNet::dump_net(ostream&o, unsigned ind) const
o << " scope=" << scope_path(scope()); o << " scope=" << scope_path(scope());
o << " #(" << rise_time() << "," << fall_time() << "," o << " #(" << rise_time() << "," << fall_time() << ","
<< decay_time() << ") vector_width=" << vector_width() << decay_time() << ") vector_width=" << vector_width()
<< " pin_count=" << pin_count() << " pin_count=" << pin_count();
<< " init="; if (pins_are_virtual()) {
o << " pins_are_virtual" << endl;
return;
}
o << " init=";
for (unsigned idx = pin_count() ; idx > 0 ; idx -= 1) for (unsigned idx = pin_count() ; idx > 0 ; idx -= 1)
o << pin(idx-1).get_init(); o << pin(idx-1).get_init();
@ -936,7 +941,7 @@ void NetEvProbe::dump_node(ostream&o, unsigned ind) const
o << "negedge "; o << "negedge ";
break; break;
} }
o << setw(ind) << "" << "-> " << event_->name() << "; " << endl; o << setw(ind) << "" << "-> " << scope_path(event_->scope()) << "." << event_->name() << "; " << endl;
dump_node_pins(o, ind+4); dump_node_pins(o, ind+4);
dump_obj_attr(o, ind+4); dump_obj_attr(o, ind+4);
} }
@ -952,10 +957,10 @@ void NetEvWait::dump(ostream&o, unsigned ind) const
o << setw(ind) <<"" << "@("; o << setw(ind) <<"" << "@(";
if (nevents() > 0) if (nevents() > 0)
o << event(0)->name(); o << scope_path(event(0)->scope()) << "." << event(0)->name();
for (unsigned idx = 1 ; idx < nevents() ; idx += 1) for (unsigned idx = 1 ; idx < nevents() ; idx += 1)
o << " or " << event(idx)->name(); o << " or " << scope_path(event(idx)->scope()) << "." << event(idx)->name();
o << ") // " << get_fileline() << endl; o << ") // " << get_fileline() << endl;
@ -976,10 +981,10 @@ void NetEvWait::dump_inline(ostream&o) const
o << "@("; o << "@(";
if (nevents() > 0) if (nevents() > 0)
o << event(0)->name(); o << scope_path(event(0)->scope()) << "." << event(0)->name();
for (unsigned idx = 1 ; idx < nevents() ; idx += 1) for (unsigned idx = 1 ; idx < nevents() ; idx += 1)
o << " or " << event(idx)->name(); o << " or " << scope_path(event(idx)->scope())<<"."<<event(idx)->name();
o << ") "; o << ") ";
} }
@ -1073,29 +1078,11 @@ void NetRepeat::dump(ostream&o, unsigned ind) const
void NetScope::dump(ostream&o) const void NetScope::dump(ostream&o) const
{ {
/* This is a constructed hierarchical name. */ /* This is a constructed hierarchical name. */
o << scope_path(this); o << scope_path(this) << " ";
switch (type_) { print_type(o);
case BEGIN_END:
o << " sequential block";
break;
case FORK_JOIN:
o << " parallel block";
break;
case FUNC:
o << " function";
break;
case MODULE:
o << " module <" << (module_name_? module_name_.str() : "") << ">";
break;
case TASK:
o << " task";
break;
case GENBLOCK:
o << " generate block";
break;
}
if (is_auto()) o << " (automatic)"; if (is_auto()) o << " (automatic)";
if (is_cell()) o << " (cell)";
o << endl; o << endl;
for (unsigned idx = 0 ; idx < attr_cnt() ; idx += 1) for (unsigned idx = 0 ; idx < attr_cnt() ; idx += 1)

View File

@ -1,7 +1,7 @@
#ifndef __discipline_H #ifndef __discipline_H
#define __discipline_H #define __discipline_H
/* /*
* Copyright (c) 2008 Stephen Williams (steve@icarus.com) * Copyright (c) 2008-2010 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -55,8 +55,8 @@ class ivl_discipline_s : public LineInfo {
perm_string name() const { return name_; } perm_string name() const { return name_; }
ivl_dis_domain_t domain() const { return domain_; } ivl_dis_domain_t domain() const { return domain_; }
const ivl_nature_t potential() const { return potential_; } ivl_nature_t potential() const { return potential_; }
const ivl_nature_t flow() const { return flow_; } ivl_nature_t flow() const { return flow_; }
private: private:
perm_string name_; perm_string name_;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2001 Stephen Williams (steve@icarus.com) * Copyright (c) 2001-2009 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -16,9 +16,6 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#ifdef HAVE_CVS_IDENT
#ident "$Id: dosify.c,v 1.5 2003/07/15 16:17:47 steve Exp $"
#endif
/* /*
* This is a simple program to make a dosified copy of the * This is a simple program to make a dosified copy of the
@ -51,6 +48,7 @@ int main(int argc, char*argv[])
ofile = fopen(argv[2], "wb"); ofile = fopen(argv[2], "wb");
if (ofile == 0) { if (ofile == 0) {
fprintf(stderr, "Unable to open %s for output.\n", argv[2]); fprintf(stderr, "Unable to open %s for output.\n", argv[2]);
fclose(ifile);
return 2; return 2;
} }
@ -64,25 +62,7 @@ int main(int argc, char*argv[])
pr = ch; pr = ch;
} }
fclose(ifile);
fclose(ofile);
return 0; return 0;
} }
/*
* $Log: dosify.c,v $
* Revision 1.5 2003/07/15 16:17:47 steve
* Fix spelling of ifdef.
*
* Revision 1.4 2003/07/15 03:49:22 steve
* Spelling fixes.
*
* Revision 1.3 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.2 2002/08/11 23:47:04 steve
* Add missing Log and Ident strings.
*
* Revision 1.1 2001/08/03 17:06:47 steve
* Add install of examples for Windows.
*
*/

View File

@ -37,12 +37,13 @@ mandir = @mandir@
dllib=@DLLIB@ dllib=@DLLIB@
CC = @CC@ CC = @CC@
WINDRES = @WINDRES@
INSTALL = @INSTALL@ INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@ INSTALL_DATA = @INSTALL_DATA@
CPPFLAGS = -I. -I$(srcdir)/.. @CPPFLAGS@ @DEFS@ CPPFLAGS = -I. -I$(srcdir)/.. @CPPFLAGS@ @DEFS@
CFLAGS = -Wall @CFLAGS@ CFLAGS = @WARNING_FLAGS@ @CFLAGS@
LDFLAGS = @LDFLAGS@ LDFLAGS = @LDFLAGS@
all: iverilog-vpi@EXEEXT@ all: iverilog-vpi@EXEEXT@
@ -50,20 +51,20 @@ all: iverilog-vpi@EXEEXT@
check: all check: all
clean: clean:
rm -f *.o config.h iverilog-vpi@EXEEXT@ rm -f *.o config.h iverilog-vpi@EXEEXT@ res.rc
distclean: clean distclean: clean
rm -f Makefile config.log rm -f Makefile config.log
Makefile: $(srcdir)/Makefile.in ../config.status Makefile: $(srcdir)/Makefile.in ../config.status
../config.status --file=$@ cd ..; ./config.status --file=driver-vpi/$@
O = main.o res.o O = main.o res.o
iverilog-vpi@EXEEXT@: $O iverilog-vpi@EXEEXT@: $O
$(CC) $(LDFLAGS) $O -o iverilog-vpi@EXEEXT@ @EXTRALIBS@ $(CC) $(LDFLAGS) $O -o iverilog-vpi@EXEEXT@ @EXTRALIBS@
main.o: main.c config.h main.o: $(srcdir)/main.c config.h
$(CC) $(CPPFLAGS) $(CFLAGS) -c $(srcdir)/main.c $(CC) $(CPPFLAGS) $(CFLAGS) -c $(srcdir)/main.c
@ -74,8 +75,12 @@ config.h: $(srcdir)/config.h.in Makefile
-e 's;@SHARED@;@shared@;' $< > $@ -e 's;@SHARED@;@shared@;' $< > $@
# Windows specific... # Windows specific...
res.rc: $(srcdir)/res.rc.in ../version.exe
sed -e 's;@PRODUCTVERSION@;'`../version.exe '%M,%m,%n,0'`';' \
$(srcdir)/res.rc.in > $@
res.o: res.rc res.o: res.rc
windres -i res.rc -o res.o $(WINDRES) -i res.rc -o res.o
# #
install: all installdirs $(bindir)/iverilog-vpi$(suffix)@EXEEXT@ install: all installdirs $(bindir)/iverilog-vpi$(suffix)@EXEEXT@

View File

@ -236,7 +236,9 @@ static int GetRegistryKey(char *key, char **value)
} }
regKeyBuffer[regKeySize] = 0; /* makes sure there is a trailing NULL */ regKeyBuffer[regKeySize] = 0; /* makes sure there is a trailing NULL */
lrv = RegQueryValueEx(hkKey,key,NULL,&regKeyType,regKeyBuffer,&regKeySize); /* This needs an unsigned char *, but for MinGW the char is signed. */
lrv = RegQueryValueEx(hkKey, key, NULL, &regKeyType,
(unsigned char *) regKeyBuffer, &regKeySize);
if ((lrv != ERROR_SUCCESS) || (regKeyType != REG_SZ) || (!regKeySize)) { if ((lrv != ERROR_SUCCESS) || (regKeyType != REG_SZ) || (!regKeySize)) {
lrv = RegCloseKey(hkKey); lrv = RegCloseKey(hkKey);
free(regKeyBuffer); free(regKeyBuffer);
@ -269,7 +271,9 @@ static void SetRegistryKey(char *key, char *value)
&res) != ERROR_SUCCESS) &res) != ERROR_SUCCESS)
return; return;
RegSetValueEx(hkKey,key,0,REG_SZ,value,strlen(value)+1); /* This needs an unsigned char *, but for MinGW the char is signed. */
RegSetValueEx(hkKey, key, 0, REG_SZ, (unsigned char *) value,
strlen(value)+1);
RegCloseKey(hkKey); RegCloseKey(hkKey);
printf("info: storing %s in Windows' registry entry\n",value); printf("info: storing %s in Windows' registry entry\n",value);
@ -413,11 +417,18 @@ static void checkMingwDir(char *root)
int irv; int irv;
struct _stat stat_buf; struct _stat stat_buf;
char *path; char *path, *comp, *cp;
initDynString(&path); initDynString(&path);
assign(&path,gstr.pMINGW); assign(&path,gstr.pMINGW);
appendBackSlash(&path); appendBackSlash(&path);
append(&path,"bin\\" IVERILOG_VPI_CC ".exe"); append(&path,"bin\\");
/* Get just the compiler name (the first word) */
comp = strdup(IVERILOG_VPI_CC);
cp = strchr(comp, ' ');
if (cp != NULL) *cp = '\0';
append(&path, comp);
append(&path,".exe");
free(comp);
irv = _stat(path,&stat_buf); irv = _stat(path,&stat_buf);
deInitDynString(path); deInitDynString(path);
@ -511,16 +522,16 @@ static void setup_ivl_environment()
} }
/* Build up the CFLAGS option string */ /* Build up the CFLAGS option string */
assign(&gstr.pCFLAGS,IVERILOG_VPI_CFLAGS " -I"); assign(&gstr.pCFLAGS,IVERILOG_VPI_CFLAGS " -I\"");
append(&gstr.pCFLAGS,gstr.pIVL); append(&gstr.pCFLAGS,gstr.pIVL);
appendBackSlash(&gstr.pCFLAGS); appendBackSlash(&gstr.pCFLAGS);
append(&gstr.pCFLAGS,"\\include\\\\iverilog" IVERILOG_SUFFIX); append(&gstr.pCFLAGS,"\\include\\\\iverilog\"" IVERILOG_SUFFIX);
/* Build up the LDFLAGS option string */ /* Build up the LDFLAGS option string */
assign(&gstr.pLDLIBS,"-L"); assign(&gstr.pLDLIBS,"-L\"");
append(&gstr.pLDLIBS,gstr.pIVL); append(&gstr.pLDLIBS,gstr.pIVL);
appendBackSlash(&gstr.pLDLIBS); appendBackSlash(&gstr.pLDLIBS);
append(&gstr.pLDLIBS,"\\lib " IVERILOG_VPI_LDLIBS); append(&gstr.pLDLIBS,"\\lib\" " IVERILOG_VPI_LDLIBS);
} }
/* compile source modules */ /* compile source modules */

View File

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

View File

@ -38,28 +38,29 @@ CC = @CC@
INSTALL = @INSTALL@ INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@ INSTALL_DATA = @INSTALL_DATA@
LEX = @LEX@
YACC = @YACC@
MAN = @MAN@ MAN = @MAN@
PS2PDF = @PS2PDF@ PS2PDF = @PS2PDF@
CPPFLAGS = -I. -I.. -I$(srcdir)/.. -I$(srcdir) @CPPFLAGS@ @DEFS@ CPPFLAGS = -I. -I.. -I$(srcdir)/.. -I$(srcdir) @CPPFLAGS@ @DEFS@
CFLAGS = -Wall @CFLAGS@ CFLAGS = @WARNING_FLAGS@ @CFLAGS@
LDFLAGS = @LDFLAGS@ LDFLAGS = @LDFLAGS@
all: dep iverilog@EXEEXT@ all: dep iverilog@EXEEXT@ iverilog.man
check: all check: all
clean: clean:
rm -f *.o lexor.c parse.c parse.h parse.output rm -f *.o cflexor.c cfparse.c cfparse.h cfparse.output
rm -f cflexor.c cfparse.c cfparse.h cfparse.output rm -f iverilog@EXEEXT@ iverilog.man iverilog.pdf iverilog.ps
rm -f iverilog@EXEEXT@ iverilog.pdf iverilog.ps
rm -rf dep rm -rf dep
distclean: clean distclean: clean
rm -f Makefile config.log rm -f Makefile config.log
Makefile: $(srcdir)/Makefile.in ../config.status Makefile: $(srcdir)/Makefile.in ../config.status
../config.status --file=$@ cd ..; ./config.status --file=driver/$@
O = main.o substit.o cflexor.o cfparse.o O = main.o substit.o cflexor.o cfparse.o
@ -67,26 +68,32 @@ iverilog@EXEEXT@: $O
$(CC) $(LDFLAGS) $O -o iverilog@EXEEXT@ @EXTRALIBS@ $(CC) $(LDFLAGS) $O -o iverilog@EXEEXT@ @EXTRALIBS@
cflexor.c: cflexor.lex cflexor.c: cflexor.lex
flex -s -Pcf -ocflexor.c $(srcdir)/cflexor.lex $(LEX) -Pcf -s -t $< > $@
cfparse.h cfparse.c: cfparse.y # Build this in two steps to avoid parallel build issues (see pr3462585)
bison --verbose -t -d -o cfparse.c --name-prefix=cf $(srcdir)/cfparse.y cfparse.c: cfparse.y
$(YACC) --verbose -t -p cf -d -o $@ $<
cfparse.h: cfparse.c
dep: dep:
mkdir dep mkdir dep
%.o: %.c %.o: %.c
$(CC) $(CPPFLAGS) $(CFLAGS) -MD -c $< -o $*.o $(CC) $(CPPFLAGS) $(CFLAGS) @DEPENDENCY_FLAG@ -c $< -o $*.o
mv $*.d dep mv $*.d dep
main.o: main.c globals.h ../version.h Makefile main.o: main.c globals.h $(srcdir)/../version_base.h ../version_tag.h Makefile
$(CC) $(CPPFLAGS) $(CFLAGS) -MD -c -DIVL_ROOT='"@libdir@/ivl$(suffix)"' -DIVL_INC='"@includedir@"' -DIVL_LIB='"@libdir@"' -DDLLIB='"@DLLIB@"' $(srcdir)/main.c $(CC) $(CPPFLAGS) $(CFLAGS) @DEPENDENCY_FLAG@ -c -DIVL_ROOT='"@libdir@/ivl$(suffix)"' -DIVL_SUFFIX='"$(suffix)"' -DIVL_INC='"@includedir@"' -DIVL_LIB='"@libdir@"' -DDLLIB='"@DLLIB@"' $(srcdir)/main.c
mv $*.d dep mv $*.d dep
cflexor.o: cflexor.c cfparse.h cflexor.o: cflexor.c cfparse.h
iverilog.ps: $(srcdir)/iverilog.man iverilog.man: $(srcdir)/iverilog.man.in ../version.exe
$(MAN) -t $(srcdir)/iverilog.man > iverilog.ps ../version.exe `head -1 $(srcdir)/iverilog.man.in`'\n' > $@
tail -n +2 $(srcdir)/iverilog.man.in >> $@
iverilog.ps: iverilog.man
$(MAN) -t ./iverilog.man > iverilog.ps
iverilog.pdf: iverilog.ps iverilog.pdf: iverilog.ps
$(PS2PDF) iverilog.ps iverilog.pdf $(PS2PDF) iverilog.ps iverilog.pdf
@ -113,8 +120,8 @@ install: all installdirs $(bindir)/iverilog$(suffix)@EXEEXT@ $(INSTALL_DOC)
$(bindir)/iverilog$(suffix)@EXEEXT@: ./iverilog@EXEEXT@ $(bindir)/iverilog$(suffix)@EXEEXT@: ./iverilog@EXEEXT@
$(INSTALL_PROGRAM) ./iverilog@EXEEXT@ "$(DESTDIR)$(bindir)/iverilog$(suffix)@EXEEXT@" $(INSTALL_PROGRAM) ./iverilog@EXEEXT@ "$(DESTDIR)$(bindir)/iverilog$(suffix)@EXEEXT@"
$(mandir)/man1/iverilog$(suffix).1: $(srcdir)/iverilog.man $(mandir)/man1/iverilog$(suffix).1: iverilog.man
$(INSTALL_DATA) $(srcdir)/iverilog.man "$(DESTDIR)$(mandir)/man1/iverilog$(suffix).1" $(INSTALL_DATA) iverilog.man "$(DESTDIR)$(mandir)/man1/iverilog$(suffix).1"
$(prefix)/iverilog$(suffix).pdf: iverilog.pdf $(prefix)/iverilog$(suffix).pdf: iverilog.pdf
$(INSTALL_DATA) iverilog.pdf "$(DESTDIR)$(prefix)/iverilog$(suffix).pdf" $(INSTALL_DATA) iverilog.pdf "$(DESTDIR)$(prefix)/iverilog$(suffix).pdf"

View File

@ -4,7 +4,7 @@
%{ %{
/* /*
* Copyright (c) 2001 Stephen Williams (steve@icarus.com) * Copyright (c) 2001-2010 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -21,9 +21,6 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#ifdef HAVE_CVS_IDENT
#ident "$Id: cflexor.lex,v 1.11 2007/03/22 16:08:18 steve Exp $"
#endif
# include "cfparse.h" # include "cfparse.h"
# include "cfparse_misc.h" # include "cfparse_misc.h"
@ -79,13 +76,15 @@ int cmdfile_stack_ptr = 0;
"+incdir+" { BEGIN(PLUS_ARGS); return TOK_INCDIR; } "+incdir+" { BEGIN(PLUS_ARGS); return TOK_INCDIR; }
"+integer-width+" { BEGIN(PLUS_ARGS); return TOK_INTEGER_WIDTH; }
"+libdir+" { BEGIN(PLUS_ARGS); return TOK_LIBDIR; } "+libdir+" { BEGIN(PLUS_ARGS); return TOK_LIBDIR; }
"+libdir-nocase+" { BEGIN(PLUS_ARGS); return TOK_LIBDIR_NOCASE; } "+libdir-nocase+" { BEGIN(PLUS_ARGS); return TOK_LIBDIR_NOCASE; }
"+libext+" { BEGIN(PLUS_ARGS); return TOK_LIBEXT; } "+libext+" { BEGIN(PLUS_ARGS); return TOK_LIBEXT; }
"+integer-width+" { BEGIN(PLUS_ARGS); return TOK_INTEGER_WIDTH; } "+timescale+" { BEGIN(PLUS_ARGS); return TOK_TIMESCALE; }
/* If it is not any known plus-flag, return the generic form. */ /* If it is not any known plus-flag, return the generic form. */
"+"[^\n \t\b\f\r+]* { "+"[^\n \t\b\f\r+]* {
@ -236,3 +235,17 @@ void cfreset(FILE*fd, const char*path)
current_file = strdup(path); current_file = strdup(path);
cflloc.first_line = 1; cflloc.first_line = 1;
} }
/*
* Modern version of flex (>=2.5.9) can clean up the scanner data.
*/
void destroy_lexor()
{
# ifdef FLEX_SCANNER
# if YY_FLEX_MAJOR_VERSION >= 2 && YY_FLEX_MINOR_VERSION >= 5
# if defined(YY_FLEX_SUBMINOR_VERSION) && YY_FLEX_SUBMINOR_VERSION >= 9
yylex_destroy();
# endif
# endif
# endif
}

View File

@ -1,6 +1,6 @@
%{ %{
/* /*
* Copyright (c) 20001 Stephen Williams (steve@icarus.com) * Copyright (c) 2001-2010 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -17,15 +17,12 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#ifdef HAVE_CVS_IDENT
#ident "$Id: cfparse.y,v 1.12 2007/04/19 02:52:53 steve Exp $"
#endif
# include "globals.h" # include "globals.h"
# include "cfparse_misc.h" # include "cfparse_misc.h"
# include <ctype.h> # include <ctype.h>
# include <stdlib.h> # include <stdlib.h>
# include <stdio.h>
# include <string.h> # include <string.h>
@ -41,13 +38,13 @@ static void translate_file_name(char*text)
break; break;
case 1: case 1:
while (*text) { while (*text) {
*text = toupper(*text); *text = toupper((int)*text);
text += 1; text += 1;
} }
break; break;
case 2: case 2:
while (*text) { while (*text) {
*text = tolower(*text); *text = tolower((int)*text);
text += 1; text += 1;
} }
break; break;
@ -61,8 +58,8 @@ static void translate_file_name(char*text)
}; };
%token TOK_Da TOK_Dc TOK_Dv TOK_Dy %token TOK_Da TOK_Dc TOK_Dv TOK_Dy
%token TOK_DEFINE TOK_INCDIR TOK_LIBDIR TOK_LIBDIR_NOCASE TOK_LIBEXT %token TOK_DEFINE TOK_INCDIR TOK_INTEGER_WIDTH TOK_LIBDIR TOK_LIBDIR_NOCASE
%token TOK_INTEGER_WIDTH %token TOK_LIBEXT TOK_TIMESCALE
%token <text> TOK_PLUSARG TOK_PLUSWORD TOK_STRING %token <text> TOK_PLUSARG TOK_PLUSWORD TOK_STRING
%% %%
@ -139,6 +136,13 @@ item
free(tmp); free(tmp);
} }
| TOK_TIMESCALE TOK_PLUSARG
{ char*tmp = substitutions($2);
process_timescale(tmp);
free($2);
free(tmp);
}
| TOK_DEFINE TOK_PLUSARG | TOK_DEFINE TOK_PLUSARG
{ process_define($2); { process_define($2);
free($2); free($2);

View File

@ -1,8 +1,7 @@
#ifndef __cfparse_misc_H #ifndef __cfparse_misc_H
#define __cfparse_misc_H #define __cfparse_misc_H
/* /*
* Copyright (c) 2001 Picture Elements, Inc. * Copyright (c) 2001-2009 Stephen Williams (steve@icarus.com)
* Stephen Williams (steve@picturel.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -17,7 +16,7 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/ */
/* /*
@ -38,6 +37,7 @@ int cflex(void);
int cferror(const char *); int cferror(const char *);
int cfparse(void); int cfparse(void);
void switch_to_command_file(const char *); void switch_to_command_file(const char *);
void destroy_lexor();
char *current_file; char *current_file;
#endif #endif

View File

@ -1,7 +1,7 @@
#ifndef __globals_H #ifndef __globals_H
#define __globals_H #define __globals_H
/* /*
* Copyright (c) 2000 Stephen Williams (steve@icarus.com) * Copyright (c) 2000-2010 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -21,31 +21,6 @@
# include <stddef.h> # include <stddef.h>
/* This is the base (i.e. -B<value>) of the Icarus Verilog files. */
extern const char*base;
/* This is the path to the iconfig file sent to ivl. */
extern char* iconfig_path;
extern char* iconfig_common_path;
/* This is the optional -M<dependfile> value, if one was supplied. */
extern const char*depfile;
/* This is the optional -N<path> value, if one was supplied. */
extern const char*npath;
/* This is the name of the output file that the user selected. */
extern const char*opath;
/* This pointer is set if there were -s<value> parameters. */
extern char*start;
/* This flag is true if the -S flag was used on the command line. */
extern int synth_flag;
/* This is the name of the selected target. */
extern const char*targ;
/* This is the integer-width argument that will be passed to ivl. */ /* This is the integer-width argument that will be passed to ivl. */
extern unsigned integer_width; extern unsigned integer_width;
@ -66,13 +41,7 @@ extern void process_include_dir(const char*name);
/* Add a new -D define. */ /* Add a new -D define. */
extern void process_define(const char*name); extern void process_define(const char*name);
/* -v */ /* Set the default timescale for the simulator. */
extern int verbose_flag; extern void process_timescale(const char*ts_string);
extern char warning_flags[];
/* -y and -Y flags from the command line. */
extern char* library_flags;
extern char* library_flags2;
#endif #endif

View File

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

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2000-2009 Stephen Williams (steve@icarus.com) * Copyright (c) 2000-2011 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -18,7 +18,8 @@
*/ */
# include "config.h" # include "config.h"
# include "version.h" # include "version_base.h"
# include "version_tag.h"
const char NOTICE[] = const char NOTICE[] =
" This program is free software; you can redistribute it and/or modify\n" " This program is free software; you can redistribute it and/or modify\n"
@ -146,8 +147,7 @@ FILE*iconfig_file = 0;
char*compiled_defines_path = 0; char*compiled_defines_path = 0;
static char iconfig_common_path_buf[4096] = ""; static char iconfig_common_path[4096] = "";
char*iconfig_common_path = iconfig_common_path_buf;
int synth_flag = 0; int synth_flag = 0;
int verbose_flag = 0; int verbose_flag = 0;
@ -230,6 +230,23 @@ static FILE*fopen_safe(const char*path)
} }
#endif #endif
#ifdef __MINGW32__
/*
* The MinGW version of getenv() returns the path with a forward
* slash. This should be converted to a back slash to keep every
* thing in the code using a back slash. This function wraps the
* code for this in one place. The conversion can not be done
* directly on the getenv() result since it is const char*.
*/
static void convert_to_MS_path(char *path)
{
char *t;
for (t = path; *t; t++) {
if (*t == '/') *t = '\\';
}
}
#endif
static const char*my_tempfile(const char*str, FILE**fout) static const char*my_tempfile(const char*str, FILE**fout)
{ {
FILE*file; FILE*file;
@ -258,7 +275,11 @@ static const char*my_tempfile(const char*str, FILE**fout)
file = NULL; file = NULL;
while ((retry > 0) && (file == NULL)) { while ((retry > 0) && (file == NULL)) {
unsigned code = rand(); unsigned code = rand();
sprintf(pathbuf, "%s%c%s%04x", tmpdir, sep, str, code); snprintf(pathbuf, sizeof pathbuf, "%s%c%s%04x",
tmpdir, sep, str, code);
#ifdef __MINGW32__
convert_to_MS_path(pathbuf);
#endif
file = fopen_safe(pathbuf); file = fopen_safe(pathbuf);
retry -= 1; retry -= 1;
} }
@ -281,7 +302,7 @@ static int t_version_only(void)
} }
fflush(0); fflush(0);
snprintf(tmp, sizeof tmp, "%s%civl -V -C%s -C%s", pbase, sep, snprintf(tmp, sizeof tmp, "%s%civl -V -C\"%s\" -C\"%s\"", base, sep,
iconfig_path, iconfig_common_path); iconfig_path, iconfig_common_path);
rc = system(tmp); rc = system(tmp);
if (rc != 0) { if (rc != 0) {
@ -302,8 +323,8 @@ static int t_version_only(void)
static void build_preprocess_command(int e_flag) static void build_preprocess_command(int e_flag)
{ {
snprintf(tmp, sizeof tmp, "%s%civlpp %s%s -F%s -f%s -p%s ", snprintf(tmp, sizeof tmp, "%s%civlpp %s%s -F\"%s\" -f\"%s\" -p\"%s\" ",
pbase,sep, verbose_flag?" -v":"", pbase, sep, verbose_flag?" -v":"",
e_flag?"":" -L", defines_path, source_path, e_flag?"":" -L", defines_path, source_path,
compiled_defines_path); compiled_defines_path);
} }
@ -321,7 +342,7 @@ static int t_preprocess_only(void)
strcpy(cmd, tmp); strcpy(cmd, tmp);
if (strcmp(opath,"-") != 0) { if (strcmp(opath,"-") != 0) {
snprintf(tmp, sizeof tmp, " > %s", opath); snprintf(tmp, sizeof tmp, " > \"%s\"", opath);
cmd = realloc(cmd, ncmd+strlen(tmp)+1); cmd = realloc(cmd, ncmd+strlen(tmp)+1);
strcpy(cmd+ncmd, tmp); strcpy(cmd+ncmd, tmp);
ncmd += strlen(tmp); ncmd += strlen(tmp);
@ -346,6 +367,7 @@ static int t_preprocess_only(void)
if (rc != 0) { if (rc != 0) {
if (WIFEXITED(rc)) { if (WIFEXITED(rc)) {
fprintf(stderr, "errors preprocessing Verilog program.\n"); fprintf(stderr, "errors preprocessing Verilog program.\n");
free(cmd);
return WEXITSTATUS(rc); return WEXITSTATUS(rc);
} }
@ -374,14 +396,12 @@ static int t_compile()
char*cmd = malloc(ncmd + 1); char*cmd = malloc(ncmd + 1);
strcpy(cmd, tmp); strcpy(cmd, tmp);
#ifdef __MINGW32__ #ifndef __MINGW32__
unsigned ncmd_start = ncmd;
#else
int rtn; int rtn;
#endif #endif
/* Build the ivl command and pipe it to the preprocessor. */ /* Build the ivl command and pipe it to the preprocessor. */
snprintf(tmp, sizeof tmp, " | %s/ivl", base); snprintf(tmp, sizeof tmp, " | %s%civl", base, sep);
rc = strlen(tmp); rc = strlen(tmp);
cmd = realloc(cmd, ncmd+rc+1); cmd = realloc(cmd, ncmd+rc+1);
strcpy(cmd+ncmd, tmp); strcpy(cmd+ncmd, tmp);
@ -396,35 +416,25 @@ static int t_compile()
} }
if (npath != 0) { if (npath != 0) {
snprintf(tmp, sizeof tmp, " -N%s", npath); snprintf(tmp, sizeof tmp, " -N\"%s\"", npath);
rc = strlen(tmp); rc = strlen(tmp);
cmd = realloc(cmd, ncmd+rc+1); cmd = realloc(cmd, ncmd+rc+1);
strcpy(cmd+ncmd, tmp); strcpy(cmd+ncmd, tmp);
ncmd += rc; ncmd += rc;
} }
snprintf(tmp, sizeof tmp, " -C%s", iconfig_path); snprintf(tmp, sizeof tmp, " -C\"%s\"", iconfig_path);
rc = strlen(tmp); rc = strlen(tmp);
cmd = realloc(cmd, ncmd+rc+1); cmd = realloc(cmd, ncmd+rc+1);
strcpy(cmd+ncmd, tmp); strcpy(cmd+ncmd, tmp);
ncmd += rc; ncmd += rc;
snprintf(tmp, sizeof tmp, " -C%s -- -", iconfig_common_path); snprintf(tmp, sizeof tmp, " -C\"%s\" -- -", iconfig_common_path);
rc = strlen(tmp); rc = strlen(tmp);
cmd = realloc(cmd, ncmd+rc+1); cmd = realloc(cmd, ncmd+rc+1);
strcpy(cmd+ncmd, tmp); strcpy(cmd+ncmd, tmp);
ncmd += rc; ncmd += rc;
#ifdef __MINGW32__
{
char *t;
for (t = cmd+ncmd_start; *t; t++)
{
if (*t == '/') *t = '\\';
}
}
#endif
if (verbose_flag) if (verbose_flag)
printf("translate: %s\n", cmd); printf("translate: %s\n", cmd);
@ -469,13 +479,18 @@ static void process_warning_switch(const char*name)
if (strcmp(name,"all") == 0) { if (strcmp(name,"all") == 0) {
process_warning_switch("implicit"); process_warning_switch("implicit");
process_warning_switch("portbind"); process_warning_switch("portbind");
process_warning_switch("select-range");
process_warning_switch("timescale"); process_warning_switch("timescale");
process_warning_switch("sensitivity-entire-array");
} else if (strcmp(name,"implicit") == 0) { } else if (strcmp(name,"implicit") == 0) {
if (! strchr(warning_flags, 'i')) if (! strchr(warning_flags, 'i'))
strcat(warning_flags, "i"); strcat(warning_flags, "i");
} else if (strcmp(name,"portbind") == 0) { } else if (strcmp(name,"portbind") == 0) {
if (! strchr(warning_flags, 'p')) if (! strchr(warning_flags, 'p'))
strcat(warning_flags, "p"); strcat(warning_flags, "p");
} else if (strcmp(name,"select-range") == 0) {
if (! strchr(warning_flags, 's'))
strcat(warning_flags, "s");
} else if (strcmp(name,"timescale") == 0) { } else if (strcmp(name,"timescale") == 0) {
if (! strchr(warning_flags, 't')) if (! strchr(warning_flags, 't'))
strcat(warning_flags, "t"); strcat(warning_flags, "t");
@ -484,6 +499,12 @@ static void process_warning_switch(const char*name)
} else if (strcmp(name,"infloop") == 0) { } else if (strcmp(name,"infloop") == 0) {
if (! strchr(warning_flags, 'l')) if (! strchr(warning_flags, 'l'))
strcat(warning_flags, "l"); strcat(warning_flags, "l");
} else if (strcmp(name,"sensitivity-entire-vector") == 0) {
if (! strchr(warning_flags, 'v'))
strcat(warning_flags, "v");
} else if (strcmp(name,"sensitivity-entire-array") == 0) {
if (! strchr(warning_flags, 'a'))
strcat(warning_flags, "a");
} else if (strcmp(name,"no-implicit") == 0) { } else if (strcmp(name,"no-implicit") == 0) {
char*cp = strchr(warning_flags, 'i'); char*cp = strchr(warning_flags, 'i');
if (cp) while (*cp) { if (cp) while (*cp) {
@ -496,12 +517,30 @@ static void process_warning_switch(const char*name)
cp[0] = cp[1]; cp[0] = cp[1];
cp += 1; cp += 1;
} }
} else if (strcmp(name,"no-select-range") == 0) {
char*cp = strchr(warning_flags, 's');
if (cp) while (*cp) {
cp[0] = cp[1];
cp += 1;
}
} else if (strcmp(name,"no-timescale") == 0) { } else if (strcmp(name,"no-timescale") == 0) {
char*cp = strchr(warning_flags, 't'); char*cp = strchr(warning_flags, 't');
if (cp) while (*cp) { if (cp) while (*cp) {
cp[0] = cp[1]; cp[0] = cp[1];
cp += 1; cp += 1;
} }
} else if (strcmp(name,"no-sensitivity-entire-vector") == 0) {
char*cp = strchr(warning_flags, 'v');
if (cp) while (*cp) {
cp[0] = cp[1];
cp += 1;
}
} else if (strcmp(name,"no-sensitivity-entire-array") == 0) {
char*cp = strchr(warning_flags, 'a');
if (cp) while (*cp) {
cp[0] = cp[1];
cp += 1;
}
} }
} }
@ -530,6 +569,11 @@ void process_define(const char*name)
fprintf(defines_file,"D:%s\n", name); fprintf(defines_file,"D:%s\n", name);
} }
void process_timescale(const char*ts_string)
{
fprintf(iconfig_file, "timescale:%s\n", ts_string);
}
/* /*
* This function is called while processing a file name in a command * This function is called while processing a file name in a command
* file, or a file name on the command line. Look to see if there is a * file, or a file name on the command line. Look to see if there is a
@ -557,6 +601,9 @@ int process_generation(const char*name)
else if (strcmp(name,"2001") == 0) else if (strcmp(name,"2001") == 0)
generation = "2001"; generation = "2001";
else if (strcmp(name,"2001-noconfig") == 0)
generation = "2001-noconfig";
else if (strcmp(name,"2005") == 0) else if (strcmp(name,"2005") == 0)
generation = "2005"; generation = "2005";
@ -598,10 +645,10 @@ int process_generation(const char*name)
else if (strcmp(name,"no-std-include") == 0) else if (strcmp(name,"no-std-include") == 0)
gen_std_include = 0; gen_std_include = 0;
else if (strcmp(name,"relative-include") == 0) else if (strcmp(name,"relative-include") == 0)
gen_relative_include = 1; gen_relative_include = 1;
else if (strcmp(name,"no-relative-include") == 0) else if (strcmp(name,"no-relative-include") == 0)
gen_relative_include = 0; gen_relative_include = 0;
@ -622,7 +669,7 @@ int process_generation(const char*name)
else if (strcmp(name,"no-verilog-ams") == 0) else if (strcmp(name,"no-verilog-ams") == 0)
gen_verilog_ams = "no-verilog-ams"; gen_verilog_ams = "no-verilog-ams";
else if (strcmp(name,"system-verilog") == 0) else if (strcmp(name,"system-verilog") == 0)
gen_system_verilog = "system-verilog"; gen_system_verilog = "system-verilog";
@ -670,34 +717,42 @@ int main(int argc, char **argv)
int opt, idx; int opt, idx;
#ifdef __MINGW32__ #ifdef __MINGW32__
{ char * s; /* Calculate the ivl_root from the path to the command. This
char basepath[1024]; is necessary because of the installation process on
GetModuleFileName(NULL,basepath,1024); Windows. Mostly, it is those darn drive letters, but oh
well. We know the command path is formed like this:
/* Calculate the ivl_root from the path to the command. This D:\iverilog\bin\iverilog.exe
is necessary because of the installation process in
Windows. Mostly, it is those darn drive letters, but oh
well. We know the command path is formed like this:
D:\iverilog\bin\iverilog.exe The module path in a Windows installation is the path:
The IVL_ROOT in a Windows installation is the path: D:\iverilog\lib\ivl$(suffix)
D:\iverilog\lib\ivl so we chop the file name and the last directory by
turning the last two \ characters to null. Then we append
so we chop the file name and the last directory by the lib\ivl$(suffix) to finish. */
turning the last two \ characters to null. Then we append char *s;
the lib\ivl to finish. */ char tmppath[MAXSIZE];
GetModuleFileName(NULL, tmppath, sizeof tmppath);
strncpy(ivl_root, basepath, MAXSIZE); /* Convert to a short name to remove any embedded spaces. */
s = strrchr(ivl_root, sep); GetShortPathName(tmppath, ivl_root, sizeof ivl_root);
if (s) *s = 0; s = strrchr(ivl_root, sep);
s = strrchr(ivl_root, sep); if (s) *s = 0;
if (s) *s = 0; else {
strcat(ivl_root, "\\lib\\ivl"); fprintf(stderr, "%s: Missing first %c in exe path!\n",
argv[0], sep);
base = ivl_root; exit(1);
} }
s = strrchr(ivl_root, sep);
if (s) *s = 0;
else {
fprintf(stderr, "%s: Missing second %c in exe path!\n",
argv[0], sep);
exit(1);
}
strcat(ivl_root, "\\lib\\ivl" IVL_SUFFIX);
base = ivl_root;
#else #else
/* In a UNIX environment, the IVL_ROOT from the Makefile is /* In a UNIX environment, the IVL_ROOT from the Makefile is
@ -866,6 +921,20 @@ int main(int argc, char **argv)
break; break;
case '?': case '?':
default: default:
fclose(source_file);
remove(source_path);
free(source_path);
fclose(defines_file);
remove(defines_path);
free(defines_path);
fclose(iconfig_file);
remove(iconfig_path);
free(iconfig_path);
remove(compiled_defines_path);
free(compiled_defines_path);
while( (command_filename = get_cmd_file()) ) {
free(command_filename);
}
return 1; return 1;
} }
} }
@ -875,13 +944,22 @@ int main(int argc, char **argv)
if (version_flag || verbose_flag) { if (version_flag || verbose_flag) {
printf("Icarus Verilog version " VERSION " (" VERSION_TAG ")\n\n"); printf("Icarus Verilog version " VERSION " (" VERSION_TAG ")\n\n");
printf("Copyright 1998-2009 Stephen Williams\n\n"); printf("Copyright 1998-2010 Stephen Williams\n\n");
puts(NOTICE); puts(NOTICE);
} }
if (synth_flag) {
fprintf(stderr, "Warning: Synthesis is not currently being "
"maintained and may not\n");
fprintf(stderr, " function correctly. V0.8 was the "
"last release branch to\n");
fprintf(stderr, " have active synthesis development "
"and support!\n");
}
/* Make a common conf file path to reflect the target. */ /* Make a common conf file path to reflect the target. */
sprintf(iconfig_common_path, "%s%c%s%s.conf", snprintf(iconfig_common_path, sizeof iconfig_common_path, "%s%c%s%s.conf",
base,sep, targ, synth_flag? "-s" : ""); base, sep, targ, synth_flag? "-s" : "");
/* Write values to the iconfig file. */ /* Write values to the iconfig file. */
fprintf(iconfig_file, "basedir:%s\n", base); fprintf(iconfig_file, "basedir:%s\n", base);
@ -937,7 +1015,9 @@ int main(int argc, char **argv)
return 1; return 1;
} }
free(command_filename); free(command_filename);
fclose(fp);
} }
destroy_lexor();
if (depfile) { if (depfile) {
fprintf(defines_file, "M:%s\n", depfile); fprintf(defines_file, "M:%s\n", depfile);
@ -969,7 +1049,7 @@ int main(int argc, char **argv)
/* If we are planning on opening a dependencies file, then /* If we are planning on opening a dependencies file, then
open and truncate it here. The other phases of compilation open and truncate it here. The other phases of compilation
will append to the file, so this is necessray to make sure will append to the file, so this is necessary to make sure
it starts out empty. */ it starts out empty. */
if (depfile) { if (depfile) {
FILE*fd = fopen(depfile, "w"); FILE*fd = fopen(depfile, "w");
@ -986,7 +1066,7 @@ int main(int argc, char **argv)
/* Write the preprocessor command needed to preprocess a /* Write the preprocessor command needed to preprocess a
single file. This may be used to preprocess library single file. This may be used to preprocess library
files. */ files. */
fprintf(iconfig_file, "ivlpp:%s%civlpp -L -F%s -P%s\n", fprintf(iconfig_file, "ivlpp:%s%civlpp -L -F\"%s\" -P\"%s\"\n",
pbase, sep, defines_path, compiled_defines_path); pbase, sep, defines_path, compiled_defines_path);
/* Done writing to the iconfig file. Close it now. */ /* Done writing to the iconfig file. Close it now. */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2002 Stephen Williams (steve@icarus.com) * Copyright (c) 2002-2010 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -16,15 +16,10 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#ifdef HAVE_CVS_IDENT
#ident "$Id: substit.c,v 1.5 2003/12/19 01:27:10 steve Exp $"
#endif
# include <string.h> # include <string.h>
# include <stdlib.h> # include <stdlib.h>
#ifdef HAVE_MALLOC_H # include <stdio.h>
# include <malloc.h>
#endif
char* substitutions(const char*str) char* substitutions(const char*str)
@ -35,13 +30,13 @@ char* substitutions(const char*str)
while (*str) { while (*str) {
if ((str[0] == '$') && (str[1] == '(')) { if ((str[0] == '$') && ((str[1] == '(') || str[1] == '{')) {
/* If I find a $(x) string in the source, replace /* If I find a $(x) or ${x} string in the source, replace
it in the destination with the contents of the it in the destination with the contents of the
environment variable x. */ environment variable x. */
char*name; char*name;
char*value; char*value;
const char*ep = strchr(str, ')'); const char*ep = strchr(str, (str[1]=='(') ? ')' : '}');
str += 2; str += 2;
name = malloc(ep-str+1); name = malloc(ep-str+1);
@ -51,9 +46,14 @@ char* substitutions(const char*str)
str = ep + 1; str = ep + 1;
value = getenv(name); value = getenv(name);
free(name); if (value == 0) {
if (value == 0) fprintf(stderr, "Warning: environment variable "
"\"%s\" not found during command file "
"processing.\n", name);
free(name);
continue; continue;
}
free(name);
if (strlen(value) >= (nbuf - (cp-buf))) { if (strlen(value) >= (nbuf - (cp-buf))) {
size_t old_size = cp - buf; size_t old_size = cp - buf;
@ -92,24 +92,3 @@ char* substitutions(const char*str)
return buf; return buf;
} }
/*
* $Log: substit.c,v $
* Revision 1.5 2003/12/19 01:27:10 steve
* Fix various unsigned compare warnings.
*
* Revision 1.4 2002/08/12 01:35:01 steve
* conditional ident string using autoconfig.
*
* Revision 1.3 2002/08/11 23:47:04 steve
* Add missing Log and Ident strings.
*
* Revision 1.2 2002/06/25 01:33:01 steve
* include malloc.h only when available.
*
* Revision 1.1 2002/06/23 20:10:51 steve
* Variable substitution in command files.
*
*/

View File

@ -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 * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -21,7 +21,7 @@
# include "netlist.h" # include "netlist.h"
# include <cassert> # include <cassert>
# include <stdlib.h> # include <cstdlib>
# include "ivl_assert.h" # include "ivl_assert.h"
NetEAccess* NetEAccess::dup_expr() const NetEAccess* NetEAccess::dup_expr() const

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2000-2009 Stephen Williams (steve@icarus.com) * Copyright (c) 2000-2013 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -118,17 +118,20 @@ NetAssign_* PEConcat::elaborate_lval(Design*des,
NetAssign_*tmp = parms_[idx]->elaborate_lval(des, scope, is_force); NetAssign_*tmp = parms_[idx]->elaborate_lval(des, scope, is_force);
if (tmp->expr_type() == IVL_VT_REAL) {
cerr << parms_[idx]->get_fileline() << ": error: "
<< "concatenation operand can not be real: "
<< *parms_[idx] << endl;
des->errors += 1;
continue;
}
/* If the l-value doesn't elaborate, the error was /* If the l-value doesn't elaborate, the error was
already detected and printed. We just skip it and let already detected and printed. We just skip it and let
the compiler catch more errors. */ the compiler catch more errors. */
if (tmp == 0) if (tmp == 0) continue;
continue;
assert(tmp);
/* Link the new l-value to the previous one. */ /* Link the new l-value to the previous one. */
NetAssign_*last = tmp; NetAssign_*last = tmp;
while (last->more) while (last->more)
last = last->more; last = last->more;
@ -195,6 +198,17 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
if (reg->array_dimensions() > 0) if (reg->array_dimensions() > 0)
return elaborate_lval_net_word_(des, scope, reg); return elaborate_lval_net_word_(des, scope, reg);
// This must be after the array word elaboration above!
if (reg->get_scalar() &&
use_sel != index_component_t::SEL_NONE) {
cerr << get_fileline() << ": error: can not select part of ";
if (reg->data_type() == IVL_VT_REAL) cerr << "real: ";
else cerr << "scalar: ";
cerr << reg->name() << endl;
des->errors += 1;
return 0;
}
if (use_sel == index_component_t::SEL_PART) { if (use_sel == index_component_t::SEL_PART) {
NetAssign_*lv = new NetAssign_(reg); NetAssign_*lv = new NetAssign_(reg);
elaborate_lval_net_part_(des, scope, lv); elaborate_lval_net_part_(des, scope, lv);
@ -243,13 +257,11 @@ NetAssign_* PEIdent::elaborate_lval_net_word_(Design*des,
ivl_assert(*this, index_head.msb != 0); ivl_assert(*this, index_head.msb != 0);
ivl_assert(*this, index_head.lsb == 0); ivl_assert(*this, index_head.lsb == 0);
// These are not used, but they need to have a default value.
ivl_variable_type_t expr_type_tmp = IVL_VT_NO_TYPE; ivl_variable_type_t expr_type_tmp = IVL_VT_NO_TYPE;
// This not used, but it needs to have a default value.
bool unsized_flag_tmp = false; bool unsized_flag_tmp = false;
index_head.msb->test_width(des, scope, index_head.msb->test_width(des, scope, integer_width, integer_width,
reg->vector_width(), reg->vector_width(), expr_type_tmp, unsized_flag_tmp);
expr_type_tmp,
unsized_flag_tmp);
NetExpr*word = elab_and_eval(des, scope, index_head.msb, -1); NetExpr*word = elab_and_eval(des, scope, index_head.msb, -1);
@ -257,7 +269,8 @@ NetAssign_* PEIdent::elaborate_lval_net_word_(Design*des,
// expression to calculate the canonical address. // expression to calculate the canonical address.
if (long base = reg->array_first()) { if (long base = reg->array_first()) {
word = make_add_expr(word, 0-base); word = normalize_variable_array_base(word, base,
reg->array_count());
eval_expr(word); eval_expr(word);
} }
@ -289,6 +302,20 @@ NetAssign_* PEIdent::elaborate_lval_net_word_(Design*des,
if (name_tail.index.size() > 1) if (name_tail.index.size() > 1)
use_sel = name_tail.index.back().sel; use_sel = name_tail.index.back().sel;
if (reg->get_scalar() &&
use_sel != index_component_t::SEL_NONE) {
cerr << get_fileline() << ": error: can not select part of ";
if (reg->data_type() == IVL_VT_REAL) cerr << "real";
else cerr << "scalar";
cerr << " array word: " << reg->name()
<< "[" << *word << "]" << endl;
des->errors += 1;
return 0;
}
if (use_sel == index_component_t::SEL_BIT)
elaborate_lval_net_bit_(des, scope, lv);
if (use_sel == index_component_t::SEL_PART) if (use_sel == index_component_t::SEL_PART)
elaborate_lval_net_part_(des, scope, lv); elaborate_lval_net_part_(des, scope, lv);
@ -309,34 +336,41 @@ bool PEIdent::elaborate_lval_net_bit_(Design*des,
ivl_assert(*this, index_tail.lsb == 0); ivl_assert(*this, index_tail.lsb == 0);
NetNet*reg = lv->sig(); NetNet*reg = lv->sig();
assert(reg);
// These are not used, but they need to have a default value.
ivl_variable_type_t expr_type_tmp = IVL_VT_NO_TYPE; ivl_variable_type_t expr_type_tmp = IVL_VT_NO_TYPE;
// This not used, but it needs to have a default value.
bool unsized_flag_tmp = false; bool unsized_flag_tmp = false;
index_tail.msb->test_width(des, scope, index_tail.msb->test_width(des, scope, integer_width, integer_width,
lv->lwidth(), lv->lwidth(), expr_type_tmp, unsized_flag_tmp);
expr_type_tmp,
unsized_flag_tmp);
// Bit selects have a single select expression. Evaluate the
// Bit selects have a single select expression. Evaluate the
// constant value and treat it as a part select with a bit // constant value and treat it as a part select with a bit
// width of 1. // width of 1.
NetExpr*mux = elab_and_eval(des, scope, index_tail.msb, -1); NetExpr*mux = elab_and_eval(des, scope, index_tail.msb, -1);
long lsb = 0; long lsb = 0;
if (NetEConst*index_con = dynamic_cast<NetEConst*> (mux)) { if (NetEConst*index_con = dynamic_cast<NetEConst*> (mux)) {
lsb = index_con->value().as_long(); // The index has a constant defined value.
mux = 0; if (index_con->value().is_defined()) {
lsb = index_con->value().as_long();
mux = 0;
// The index is undefined.
} else {
cerr << get_fileline() << ": warning: L-value bit select of "
<< reg->name();
if (reg->array_dimensions() > 0) cerr << "[]";
cerr << " has an undefined index." << endl;
lv->set_part(new NetEConst(verinum(verinum::Vx)), 1);
return true;
}
} }
if (mux) { if (mux) {
// Non-constant bit mux. Correct the mux for the range // Non-constant bit mux. Correct the mux for the range
// of the vector, then set the l-value part select expression. // of the vector, then set the l-value part select expression.
if (reg->msb() < reg->lsb()) mux = normalize_variable_base(mux, reg->msb(), reg->lsb(), 1, true);
mux = make_sub_expr(reg->lsb(), mux);
else if (reg->lsb() != 0)
mux = make_add_expr(mux, - reg->lsb());
lv->set_part(mux, 1); lv->set_part(mux, 1);
@ -372,14 +406,21 @@ bool PEIdent::elaborate_lval_net_part_(Design*des,
long msb, lsb; long msb, lsb;
bool parts_defined_flag; bool parts_defined_flag;
bool flag = calculate_parts_(des, scope, msb, lsb, parts_defined_flag); bool flag = calculate_parts_(des, scope, msb, lsb, parts_defined_flag);
if (!flag) if (!flag) return false;
return false;
ivl_assert(*this, parts_defined_flag);
NetNet*reg = lv->sig(); NetNet*reg = lv->sig();
assert(reg); assert(reg);
if (! parts_defined_flag) {
cerr << get_fileline() << ": warning: L-value part select of "
<< reg->name();
if (reg->array_dimensions() > 0) cerr << "[]";
cerr << " has an undefined index." << endl;
lv->set_part(new NetEConst(verinum(verinum::Vx)), 1);
return true;
}
if (msb == reg->msb() && lsb == reg->lsb()) { if (msb == reg->msb() && lsb == reg->lsb()) {
/* Part select covers the entire vector. Simplest case. */ /* Part select covers the entire vector. Simplest case. */
@ -444,24 +485,73 @@ bool PEIdent::elaborate_lval_net_idx_(Design*des,
unsigned long wid; unsigned long wid;
calculate_up_do_width_(des, scope, wid); calculate_up_do_width_(des, scope, wid);
// These are not used, but they need to have a default value.
ivl_variable_type_t expr_type_tmp = IVL_VT_NO_TYPE; ivl_variable_type_t expr_type_tmp = IVL_VT_NO_TYPE;
// This not used, but it needs to have a default value.
bool unsized_flag_tmp = false; bool unsized_flag_tmp = false;
index_tail.msb->test_width(des, scope, index_tail.msb->test_width(des, scope, integer_width, integer_width,
wid, wid, expr_type_tmp, unsized_flag_tmp);
expr_type_tmp,
unsized_flag_tmp);
NetExpr*base = elab_and_eval(des, scope, index_tail.msb, -1); NetExpr*base = elab_and_eval(des, scope, index_tail.msb, -1);
/* Correct the mux for the range of the vector. */ // Handle the special case that the base is constant. For this
if (reg->msb() < reg->lsb()) // case we can reduce the expression.
base = make_sub_expr(reg->lsb(), base); if (NetEConst*base_c = dynamic_cast<NetEConst*> (base)) {
else if (reg->lsb() != 0) // For the undefined case just let the constant pass and
base = make_add_expr(base, - reg->lsb()); // we will handle it in the code generator.
if (base_c->value().is_defined()) {
if (use_sel == index_component_t::SEL_IDX_DO && wid > 1 ) { long lsv = base_c->value().as_long();
base = make_add_expr(base, 1-(long)wid); long offset = 0;
if (((reg->msb() < reg->lsb()) &&
use_sel == index_component_t::SEL_IDX_UP) ||
((reg->msb() > reg->lsb()) &&
use_sel == index_component_t::SEL_IDX_DO)) {
offset = -wid + 1;
}
delete base;
long rel_base = reg->sb_to_idx(lsv) + offset;
/* If we cover the entire lvalue just skip the select. */
if (rel_base == 0 && wid == reg->vector_width()) return true;
base = new NetEConst(verinum(rel_base));
if (warn_ob_select) {
if (rel_base < 0) {
cerr << get_fileline() << ": warning: " << reg->name();
if (reg->array_dimensions() > 0) cerr << "[]";
cerr << "[" << lsv;
if (use_sel == index_component_t::SEL_IDX_UP) {
cerr << "+:";
} else {
cerr << "-:";
}
cerr << wid << "] is selecting before vector." << endl;
}
if (rel_base + wid > reg->vector_width()) {
cerr << get_fileline() << ": warning: " << reg->name();
if (reg->array_dimensions() > 0) cerr << "[]";
cerr << "[" << lsv;
if (use_sel == index_component_t::SEL_IDX_UP) {
cerr << "+:";
} else {
cerr << "-:";
}
cerr << wid << "] is selecting after vector." << endl;
}
}
} else {
cerr << get_fileline() << ": warning: L-value indexed part "
<< "select of " << reg->name();
if (reg->array_dimensions() > 0) cerr << "[]";
cerr << " has an undefined base." << endl;
}
} else {
/* Correct the mux for the range of the vector. */
if (use_sel == index_component_t::SEL_IDX_UP) {
base = normalize_variable_base(base, reg->msb(), reg->lsb(),
wid, true);
} else {
// This is assumed to be a SEL_IDX_DO.
base = normalize_variable_base(base, reg->msb(), reg->lsb(),
wid, false);
}
} }
if (debug_elaborate) if (debug_elaborate)

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1999-2009 Stephen Williams (steve@icarus.com) * Copyright (c) 1999-2011 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -72,18 +72,21 @@ NetNet* PEConcat::elaborate_lnet_common_(Design*des, NetScope*scope,
} else { } else {
nets[idx] = parms_[idx]->elaborate_lnet(des, scope); nets[idx] = parms_[idx]->elaborate_lnet(des, scope);
} }
if (nets[idx] == 0)
if (nets[idx] == 0) {
errors += 1;
} else if (nets[idx]->data_type() == IVL_VT_REAL) {
cerr << parms_[idx]->get_fileline() << ": error: "
<< "concatenation operand can no be real: "
<< *parms_[idx] << endl;
errors += 1; errors += 1;
else continue;
width += nets[idx]->vector_width(); } else {
width += nets[idx]->vector_width();
}
} }
/* If any of the sub expressions failed to elaborate, then
delete all those that did and abort myself. */
if (errors) { if (errors) {
for (unsigned idx = 0 ; idx < nets.count() ; idx += 1) {
if (nets[idx]) delete nets[idx];
}
des->errors += errors; des->errors += errors;
return 0; return 0;
} }
@ -164,6 +167,28 @@ NetNet* PEConcat::elaborate_bi_net(Design*des, NetScope*scope) const
return elaborate_lnet_common_(des, scope, true); return elaborate_lnet_common_(des, scope, true);
} }
bool PEConcat::is_collapsible_net(Design*des, NetScope*scope) const
{
assert(scope);
// Repeat concatenations are not currently supported.
if (repeat_)
return false;
// Test the operands of the concatenation.
for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) {
// Empty expressions are not allowed in concatenations
if (parms_[idx] == 0)
return false;
if (!parms_[idx]->is_collapsible_net(des, scope))
return false;
}
return true;
}
/* /*
* A private method to create an implicit net. * A private method to create an implicit net.
*/ */
@ -173,7 +198,7 @@ NetNet* PEIdent::make_implicit_net_(Design*des, NetScope*scope) const
assert(nettype != NetNet::NONE); assert(nettype != NetNet::NONE);
NetNet*sig = new NetNet(scope, peek_tail_name(path_), NetNet*sig = new NetNet(scope, peek_tail_name(path_),
NetNet::IMPLICIT, 1); nettype, 1);
sig->set_line(*this); sig->set_line(*this);
/* Implicit nets are always scalar logic. */ /* Implicit nets are always scalar logic. */
sig->data_type(IVL_VT_LOGIC); sig->data_type(IVL_VT_LOGIC);
@ -220,7 +245,9 @@ bool PEIdent::eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
case index_component_t::SEL_IDX_DO: case index_component_t::SEL_IDX_DO:
case index_component_t::SEL_IDX_UP: { case index_component_t::SEL_IDX_UP: {
need_constant_expr = true;
NetExpr*tmp_ex = elab_and_eval(des, scope, index_tail.msb, -1); NetExpr*tmp_ex = elab_and_eval(des, scope, index_tail.msb, -1);
need_constant_expr = false;
NetEConst*tmp = dynamic_cast<NetEConst*>(tmp_ex); NetEConst*tmp = dynamic_cast<NetEConst*>(tmp_ex);
if (!tmp) { if (!tmp) {
cerr << get_fileline() << ": error: indexed part select of " cerr << get_fileline() << ": error: indexed part select of "
@ -230,15 +257,33 @@ bool PEIdent::eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
return 0; return 0;
} }
long midx_val = tmp->value().as_long();
midx = sig->sb_to_idx(midx_val);
delete tmp_ex;
/* The width (a constant) is calculated here. */ /* The width (a constant) is calculated here. */
unsigned long wid = 0; unsigned long wid = 0;
bool flag = calculate_up_do_width_(des, scope, wid); bool flag = calculate_up_do_width_(des, scope, wid);
if (! flag) if (! flag) return false;
/* We have an undefined index and that is out of range. */
if (! tmp->value().is_defined()) {
if (warn_ob_select) {
cerr << get_fileline() << ": warning: "
<< sig->name();
if (sig->array_dimensions() > 0) cerr << "[]";
cerr << "['bx";
if (index_tail.sel ==
index_component_t::SEL_IDX_UP) {
cerr << "+:";
} else {
cerr << "-:";
}
cerr << wid << "] is always outside vector."
<< endl;
}
return false; return false;
}
long midx_val = tmp->value().as_long();
midx = sig->sb_to_idx(midx_val);
delete tmp_ex;
if (index_tail.sel == index_component_t::SEL_IDX_UP) if (index_tail.sel == index_component_t::SEL_IDX_UP)
lidx = sig->sb_to_idx(midx_val+wid-1); lidx = sig->sb_to_idx(midx_val+wid-1);
@ -252,9 +297,19 @@ bool PEIdent::eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
} }
/* Warn about an indexed part select that is out of range. */ /* Warn about an indexed part select that is out of range. */
if (midx >= (long)sig->vector_width() || lidx < 0) { if (warn_ob_select && (lidx < 0)) {
cerr << get_fileline() << ": warning: Indexed part " cerr << get_fileline() << ": warning: " << sig->name();
"select " << sig->name(); if (sig->array_dimensions() > 0) cerr << "[]";
cerr << "[" << midx_val;
if (index_tail.sel == index_component_t::SEL_IDX_UP) {
cerr << "+:";
} else {
cerr << "-:";
}
cerr << wid << "] is selecting before vector." << endl;
}
if (warn_ob_select && (midx >= (long)sig->vector_width())) {
cerr << get_fileline() << ": warning: " << sig->name();
if (sig->array_dimensions() > 0) { if (sig->array_dimensions() > 0) {
cerr << "[]"; cerr << "[]";
} }
@ -264,7 +319,7 @@ bool PEIdent::eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
} else { } else {
cerr << "-:"; cerr << "-:";
} }
cerr << wid << "] is out of range." << endl; cerr << wid << "] is selecting after vector." << endl;
} }
/* This is completely out side the signal so just skip it. */ /* This is completely out side the signal so just skip it. */
@ -404,18 +459,13 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
return 0; return 0;
} }
if (sig->port_type() == NetNet::PINPUT) {
cerr << get_fileline() << ": warning: L-value ``"
<< sig->name() << "'' is also an input port." << endl;
cerr << sig->get_fileline() << ": warning: input "
<< sig->name() << "; is coerced to inout." << endl;
sig->port_type(NetNet::PINOUT);
}
// Default part select is the entire word. // Default part select is the entire word.
unsigned midx = sig->vector_width()-1, lidx = 0; unsigned midx = sig->vector_width()-1, lidx = 0;
// The default word select is the first. // The default word select is the first.
unsigned widx = 0; long widx = 0;
// The widx_val is the word select as entered in the source
// code. It's used for error messages.
long widx_val = 0;
const name_component_t&name_tail = path_.back(); const name_component_t&name_tail = path_.back();
@ -437,7 +487,15 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
} }
ivl_assert(*this, index_head.sel == index_component_t::SEL_BIT); ivl_assert(*this, index_head.sel == index_component_t::SEL_BIT);
// These are not used, but they need to have a default value.
ivl_variable_type_t expr_type_tmp = IVL_VT_NO_TYPE;
bool unsized_flag_tmp = false;
index_head.msb->test_width(des, scope,
integer_width, integer_width,
expr_type_tmp, unsized_flag_tmp);
need_constant_expr = true;
NetExpr*tmp_ex = elab_and_eval(des, scope, index_head.msb, -1); NetExpr*tmp_ex = elab_and_eval(des, scope, index_head.msb, -1);
need_constant_expr = false;
NetEConst*tmp = dynamic_cast<NetEConst*>(tmp_ex); NetEConst*tmp = dynamic_cast<NetEConst*>(tmp_ex);
if (!tmp) { if (!tmp) {
cerr << get_fileline() << ": error: array " << sig->name() cerr << get_fileline() << ": error: array " << sig->name()
@ -446,8 +504,11 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
return 0; return 0;
} }
long widx_val = tmp->value().as_long(); widx_val = tmp->value().as_long();
widx = sig->array_index_to_address(widx_val); if (sig->array_index_is_valid(widx_val))
widx = sig->array_index_to_address(widx_val);
else
widx = -1;
delete tmp_ex; delete tmp_ex;
if (debug_elaborate) if (debug_elaborate)
@ -456,12 +517,23 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
/* The array has a part/bit select at the end. */ /* The array has a part/bit select at the end. */
if (name_tail.index.size() > sig->array_dimensions()) { if (name_tail.index.size() > sig->array_dimensions()) {
if (sig->get_scalar()) {
cerr << get_fileline() << ": error: "
<< "can not select part of ";
if (sig->data_type() == IVL_VT_REAL) cerr << "real";
else cerr << "scalar";
cerr << " array word: " << sig->name()
<< "[" << widx_val << "]" << endl;
des->errors += 1;
return 0;
}
long midx_tmp, lidx_tmp; long midx_tmp, lidx_tmp;
if (! eval_part_select_(des, scope, sig, midx_tmp, lidx_tmp)) if (! eval_part_select_(des, scope, sig, midx_tmp, lidx_tmp))
return 0; return 0;
if (lidx_tmp < 0) { if (lidx_tmp < 0) {
cerr << get_fileline() << ": sorry: part selects " cerr << get_fileline() << ": sorry: part selects "
"straddling the start of signal (" << path_ "straddling the start of signal (" << path_
<< ") are not currently supported." << endl; << ") are not currently supported." << endl;
des->errors += 1; des->errors += 1;
@ -471,12 +543,22 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
lidx = lidx_tmp; lidx = lidx_tmp;
} }
} else if (!name_tail.index.empty()) { } else if (!name_tail.index.empty()) {
if (sig->get_scalar()) {
cerr << get_fileline() << ": error: "
<< "can not select part of ";
if (sig->data_type() == IVL_VT_REAL) cerr << "real: ";
else cerr << "scalar: ";
cerr << sig->name() << endl;
des->errors += 1;
return 0;
}
long midx_tmp, lidx_tmp; long midx_tmp, lidx_tmp;
if (! eval_part_select_(des, scope, sig, midx_tmp, lidx_tmp)) if (! eval_part_select_(des, scope, sig, midx_tmp, lidx_tmp))
return 0; return 0;
if (lidx_tmp < 0) { if (lidx_tmp < 0) {
cerr << get_fileline() << ": sorry: part selects " cerr << get_fileline() << ": sorry: part selects "
"straddling the start of signal (" << path_ "straddling the start of signal (" << path_
<< ") are not currently supported." << endl; << ") are not currently supported." << endl;
des->errors += 1; des->errors += 1;
@ -489,7 +571,12 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
unsigned subnet_wid = midx-lidx+1; unsigned subnet_wid = midx-lidx+1;
if (sig->pin_count() > 1) { if (sig->pin_count() > 1) {
assert(widx < sig->pin_count()); if (widx < 0 || widx >= (long) sig->pin_count()) {
cerr << get_fileline() << ": warning: ignoring out of "
"bounds l-value array access "
<< sig->name() << "[" << widx_val << "]." << endl;
return 0;
}
NetNet*tmp = new NetNet(scope, scope->local_symbol(), NetNet*tmp = new NetNet(scope, scope->local_symbol(),
sig->type(), sig->vector_width()); sig->type(), sig->vector_width());
@ -640,22 +727,20 @@ NetNet* PEIdent::elaborate_port(Design*des, NetScope*scope) const
switch (sig->port_type()) { switch (sig->port_type()) {
case NetNet::PINPUT: case NetNet::PINPUT:
ps = new NetPartSelect(sig, sig->sb_to_idx(lidx), swid, ps = new NetPartSelect(sig, lidx, swid, NetPartSelect::PV);
NetPartSelect::PV);
connect(tmp->pin(0), ps->pin(0)); connect(tmp->pin(0), ps->pin(0));
sig = tmp; sig = tmp;
break; break;
case NetNet::POUTPUT: case NetNet::POUTPUT:
ps = new NetPartSelect(sig, sig->sb_to_idx(lidx), swid, ps = new NetPartSelect(sig, lidx, swid, NetPartSelect::VP);
NetPartSelect::VP);
connect(tmp->pin(0), ps->pin(0)); connect(tmp->pin(0), ps->pin(0));
sig = tmp; sig = tmp;
break; break;
case NetNet::PINOUT: case NetNet::PINOUT:
ps = new NetTran(scope, scope->local_symbol(), sig->vector_width(), ps = new NetTran(scope, scope->local_symbol(), sig->vector_width(),
swid, sig->sb_to_idx(lidx)); swid, lidx);
connect(sig->pin(0), ps->pin(0)); connect(sig->pin(0), ps->pin(0));
connect(tmp->pin(0), ps->pin(1)); connect(tmp->pin(0), ps->pin(1));
sig = tmp; sig = tmp;
@ -671,3 +756,27 @@ NetNet* PEIdent::elaborate_port(Design*des, NetScope*scope) const
return sig; return sig;
} }
bool PEIdent::is_collapsible_net(Design*des, NetScope*scope) const
{
assert(scope);
NetNet* sig = 0;
const NetExpr*par = 0;
NetEvent* eve = 0;
symbol_search(this, des, scope, path_, sig, par, eve);
if (eve != 0)
return false;
if (sig == 0)
return false;
assert(sig);
if (sig->type() == NetNet::REG)
return false;
return true;
}

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2000-2009 Stephen Williams (steve@icarus.com) * Copyright (c) 2000-2010 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -150,11 +150,19 @@ NetEConcat* PEConcat::elaborate_pexpr(Design*des, NetScope*scope) const
/* Elaborate all the operands and attach them to the concat /* Elaborate all the operands and attach them to the concat
node. Use the elaborate_pexpr method instead of the node. Use the elaborate_pexpr method instead of the
elaborate_expr method. */ elaborate_expr method. */
bool fail = false;
for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) { for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) {
assert(parms_[idx]); assert(parms_[idx]);
NetExpr*ex = parms_[idx]->elaborate_pexpr(des, scope); NetExpr*ex = parms_[idx]->elaborate_pexpr(des, scope);
if (ex == 0) continue; if (ex == 0) continue;
if (ex->expr_type() == IVL_VT_REAL) {
cerr << ex->get_fileline() << ": error: concatenation "
<< "operand can not be real: " << *ex << endl;
des->errors += 1;
fail = true;
continue;
}
ex->set_line(*parms_[idx]); ex->set_line(*parms_[idx]);
if (dynamic_cast<NetEParam*>(ex)) { if (dynamic_cast<NetEParam*>(ex)) {
@ -167,13 +175,18 @@ NetEConcat* PEConcat::elaborate_pexpr(Design*des, NetScope*scope) const
<< "concatenation has indefinite width: " << "concatenation has indefinite width: "
<< *ex << endl; << *ex << endl;
des->errors += 1; des->errors += 1;
delete tmp; fail = true;
return 0; continue;
} }
tmp->set(idx, ex); tmp->set(idx, ex);
} }
if (fail) {
delete tmp;
return 0;
}
return tmp; return tmp;
} }
@ -194,6 +207,14 @@ NetExpr*PEIdent::elaborate_pexpr(Design*des, NetScope*scope) const
name_component_t name_tail = path_.back(); name_component_t name_tail = path_.back();
oldpath.pop_back(); oldpath.pop_back();
if (path_.size() > 1) {
cerr << get_fileline() << ": error: parameter r-value expression "
"does not support hierarchical references `" << path_
<< "`." << endl;
des->errors += 1;
return 0;
}
NetScope*pscope = scope; NetScope*pscope = scope;
if (path_.size() > 0) { if (path_.size() > 0) {
list<hname_t> tmp = eval_scope_path(des, scope, oldpath); list<hname_t> tmp = eval_scope_path(des, scope, oldpath);
@ -216,8 +237,9 @@ NetExpr*PEIdent::elaborate_pexpr(Design*des, NetScope*scope) const
ivl_assert(*this, pscope); ivl_assert(*this, pscope);
} }
if (ex == 0) { if (ex == 0) {
cerr << get_fileline() << ": error: identifier ``" << name_tail.name << cerr << get_fileline() << ": error: identifier `"
"'' is not a parameter in "<< scope_path(scope)<< "." << endl; << name_tail.name << "` is not a parameter in "
<< scope_path(scope)<< "." << endl;
des->errors += 1; des->errors += 1;
return 0; return 0;
} }
@ -392,9 +414,9 @@ NetExpr* PECallFunction::elaborate_pexpr(Design*des, NetScope*scope) const
return rtn; return rtn;
} }
/* These are only available with verilog-ams or icarus-misc. */ /* This is only available with verilog-ams or icarus-misc. */
if ((gn_icarus_misc_flag || gn_verilog_ams_flag) && if ((gn_icarus_misc_flag || gn_verilog_ams_flag) &&
(nm == "$log" || nm == "$abs")) { (nm == "$abs")) {
if (parms_.size() != 1 || parms_[0] == 0) { if (parms_.size() != 1 || parms_[0] == 0) {
cerr << get_fileline() << ": error: " << nm cerr << get_fileline() << ": error: " << nm
<< " takes a single argument." << endl; << " takes a single argument." << endl;
@ -404,15 +426,11 @@ NetExpr* PECallFunction::elaborate_pexpr(Design*des, NetScope*scope) const
NetExpr*arg = parms_[0]->elaborate_pexpr(des, scope); NetExpr*arg = parms_[0]->elaborate_pexpr(des, scope);
if (arg == 0) return 0; if (arg == 0) return 0;
NetESFunc*rtn; NetESFunc*rtn;
if (nm == "$log") { /* This can return either a real or an arbitrary
rtn = new NetESFunc(nm, IVL_VT_REAL, 1, 1); * width vector, so set things to fail if this
} else { * does not get replaced with a constant during
/* This can return either a real or an arbitrary * elaboration. */
* width vector, so set things to fail if this rtn = new NetESFunc(nm, IVL_VT_NO_TYPE, 0, 1);
* does not get replaced with a constant during
* elaboration. */
rtn = new NetESFunc(nm, IVL_VT_NO_TYPE, 0, 1);
}
rtn->set_line(*this); rtn->set_line(*this);
rtn->cast_signed(true); rtn->cast_signed(true);
rtn->parm(0, arg); rtn->parm(0, arg);
@ -429,7 +447,7 @@ NetExpr* PECallFunction::elaborate_pexpr(Design*des, NetScope*scope) const
NetExpr*arg0 = parms_[0]->elaborate_pexpr(des, scope); NetExpr*arg0 = parms_[0]->elaborate_pexpr(des, scope);
NetExpr*arg1 = parms_[1]->elaborate_pexpr(des, scope); NetExpr*arg1 = parms_[1]->elaborate_pexpr(des, scope);
if (arg0 == 0 || arg1 == 0) return 0; if (arg0 == 0 || arg1 == 0) return 0;
/* See $log above for why this has no type or width. */ /* See $abs above for why this has no type or width. */
NetESFunc*rtn = new NetESFunc(nm, IVL_VT_NO_TYPE, 0, 2); NetESFunc*rtn = new NetESFunc(nm, IVL_VT_NO_TYPE, 0, 2);
rtn->set_line(*this); rtn->set_line(*this);
rtn->cast_signed(true); rtn->cast_signed(true);
@ -490,7 +508,7 @@ void NetEParam::resolve_pexpr_type(void)
if (reference_->second.signed_flag) { if (reference_->second.signed_flag) {
cast_signed_base_(true); cast_signed_base_(true);
} else { } else if (reference_->second.expr) {
cast_signed_base_( reference_->second.expr->has_sign() ); cast_signed_base_( reference_->second.expr->has_sign() );
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2000-2008 Stephen Williams (steve@icarus.com) * Copyright (c) 2000-2012 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -23,7 +23,7 @@
# include <cstring> # include <cstring>
# include <iostream> # include <iostream>
# include <cstdlib> # include <cstdlib>
# include <stdio.h> # include <cstdio>
/* /*
* Elaboration happens in two passes, generally. The first scans the * Elaboration happens in two passes, generally. The first scans the
@ -44,7 +44,7 @@
# include "netlist.h" # include "netlist.h"
# include "util.h" # include "util.h"
# include <typeinfo> # include <typeinfo>
# include <assert.h> # include <cassert>
# include "ivl_assert.h" # include "ivl_assert.h"
typedef map<perm_string,LexicalScope::param_expr_t>::const_iterator mparm_it_t; typedef map<perm_string,LexicalScope::param_expr_t>::const_iterator mparm_it_t;
@ -150,19 +150,6 @@ static void elaborate_parm_item_(perm_string name,
return; return;
} }
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();
}
val = scope->set_parameter(name, val, cur.type, msb, lsb, signed_flag, val = scope->set_parameter(name, val, cur.type, msb, lsb, signed_flag,
range_list, cur); range_list, cur);
delete val; delete val;
@ -174,6 +161,15 @@ static void elaborate_scope_parameters_(Design*des, NetScope*scope,
for (mparm_it_t cur = parameters.begin() for (mparm_it_t cur = parameters.begin()
; cur != parameters.end() ; cur ++) { ; cur != parameters.end() ; cur ++) {
// A parameter can not have the same name as a genvar.
if (scope->find_genvar((*cur).first)) {
cerr << cur->second.get_fileline()
<< ": error: parameter and genvar in '"
<< scope->fullname() << "' have the same name '"
<< (*cur).first << "'." << endl;
des->errors += 1;
}
elaborate_parm_item_((*cur).first, (*cur).second, des, scope); elaborate_parm_item_((*cur).first, (*cur).second, des, scope);
} }
} }
@ -184,6 +180,15 @@ static void elaborate_scope_localparams_(Design*des, NetScope*scope,
for (mparm_it_t cur = localparams.begin() for (mparm_it_t cur = localparams.begin()
; cur != localparams.end() ; cur ++) { ; cur != localparams.end() ; cur ++) {
// A localparam can not have the same name as a genvar.
if (scope->find_genvar((*cur).first)) {
cerr << cur->second.get_fileline()
<< ": error: localparam and genvar in '"
<< scope->fullname() << "' have the same name '"
<< (*cur).first << "'." << endl;
des->errors += 1;
}
elaborate_parm_item_((*cur).first, (*cur).second, des, scope); elaborate_parm_item_((*cur).first, (*cur).second, des, scope);
} }
} }
@ -198,7 +203,7 @@ static void replace_scope_parameters_(NetScope*scope, const LineInfo&loc,
if (val == 0) { if (val == 0) {
cerr << loc.get_fileline() << ": internal error: " cerr << loc.get_fileline() << ": internal error: "
<< "Missing expression in parameter replacement for " << "Missing expression in parameter replacement for "
<< (*cur).first; << (*cur).first << endl;;
} }
assert(val); assert(val);
if (debug_scopes) { if (debug_scopes) {
@ -238,13 +243,38 @@ static void elaborate_scope_tasks(Design*des, NetScope*scope,
; cur != tasks.end() ; cur ++ ) { ; cur != tasks.end() ; cur ++ ) {
hname_t use_name( (*cur).first ); hname_t use_name( (*cur).first );
if (scope->child(use_name)) { // A task can not have the same name as another scope object.
cerr << loc.get_fileline() << ": error: task/scope name " const NetScope *child = scope->child(use_name);
<< use_name << " already used in this context." if (child) {
<< endl; cerr << cur->second->get_fileline() << ": error: task and ";
child->print_type(cerr);
cerr << " in '" << scope->fullname()
<< "' have the same name '" << use_name << "'." << endl;
des->errors += 1; des->errors += 1;
continue; continue;
} }
// A task can not have the same name as a genvar.
if (scope->find_genvar((*cur).first)) {
cerr << cur->second->get_fileline()
<< ": error: task and genvar in '"
<< scope->fullname() << "' have the same name '"
<< (*cur).first << "'." << endl;
des->errors += 1;
}
// A task can not have the same name as a parameter.
const NetExpr *ex_msb, *ex_lsb;
const NetExpr *parm = scope->get_parameter((*cur).first, ex_msb,
ex_lsb);
if (parm) {
cerr << cur->second->get_fileline()
<< ": error: task and parameter in '"
<< scope->fullname() << "' have the same name '"
<< (*cur).first << "'." << endl;
des->errors += 1;
}
NetScope*task_scope = new NetScope(scope, use_name, NetScope*task_scope = new NetScope(scope, use_name,
NetScope::TASK); NetScope::TASK);
task_scope->is_auto((*cur).second->is_auto()); task_scope->is_auto((*cur).second->is_auto());
@ -268,13 +298,39 @@ static void elaborate_scope_funcs(Design*des, NetScope*scope,
; cur != funcs.end() ; cur ++ ) { ; cur != funcs.end() ; cur ++ ) {
hname_t use_name( (*cur).first ); hname_t use_name( (*cur).first );
if (scope->child(use_name)) { // A function can not have the same name as another scope object.
cerr << loc.get_fileline() << ": error: function/scope name " const NetScope *child = scope->child(use_name);
<< use_name << " already used in this context." if (child) {
<< endl; cerr << cur->second->get_fileline()
<< ": error: function and ";
child->print_type(cerr);
cerr << " in '" << scope->fullname()
<< "' have the same name '" << use_name << "'." << endl;
des->errors += 1; des->errors += 1;
continue; continue;
} }
// A function can not have the same name as a genvar.
if (scope->find_genvar((*cur).first)) {
cerr << cur->second->get_fileline()
<< ": error: function and genvar in '"
<< scope->fullname() << "' have the same name '"
<< (*cur).first << "'." << endl;
des->errors += 1;
}
// A function can not have the same name as a parameter.
const NetExpr *ex_msb, *ex_lsb;
const NetExpr *parm = scope->get_parameter((*cur).first, ex_msb,
ex_lsb);
if (parm) {
cerr << cur->second->get_fileline()
<< ": error: function and parameter in '"
<< scope->fullname() << "' have the same name '"
<< (*cur).first << "'." << endl;
des->errors += 1;
}
NetScope*func_scope = new NetScope(scope, use_name, NetScope*func_scope = new NetScope(scope, use_name,
NetScope::FUNC); NetScope::FUNC);
func_scope->is_auto((*cur).second->is_auto()); func_scope->is_auto((*cur).second->is_auto());
@ -328,6 +384,12 @@ bool Module::elaborate_scope(Design*des, NetScope*scope,
<< scope_path(scope) << "." << endl; << scope_path(scope) << "." << endl;
} }
// Add the genvars to the scope.
typedef map<perm_string,LineInfo*>::const_iterator genvar_it_t;
for (genvar_it_t cur = genvars.begin(); cur != genvars.end(); cur++ ) {
scope->add_genvar((*cur).first, (*cur).second);
}
// Generate all the parameters that this instance of this // Generate all the parameters that this instance of this
// module introduces to the design. This loop elaborates the // module introduces to the design. This loop elaborates the
// parameters, but doesn't evaluate references to // parameters, but doesn't evaluate references to
@ -446,6 +508,8 @@ bool Module::elaborate_scope(Design*des, NetScope*scope,
elaborate_scope_events_(des, scope, events); elaborate_scope_events_(des, scope, events);
scope->is_cell(is_cell);
return des->errors == 0; return des->errors == 0;
} }
@ -486,8 +550,16 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
{ {
// Check that the loop_index variable was declared in a // Check that the loop_index variable was declared in a
// genvar statement. // genvar statement.
NetScope*cscope = container;
// MISSING CODE! while (cscope && !cscope->find_genvar(loop_index))
cscope = cscope->parent();
if (!cscope) {
cerr << get_fileline() << ": error: genvar is missing for "
"generate \"loop\" variable '" << loop_index << "'."
<< endl;
des->errors += 1;
return false;
}
// We're going to need a genvar... // We're going to need a genvar...
int genvar; int genvar;
@ -496,7 +568,9 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
// use) the genvar itself, so we can evaluate this expression // use) the genvar itself, so we can evaluate this expression
// the same way any other parameter value is evaluated. // the same way any other parameter value is evaluated.
probe_expr_width(des, container, loop_init); probe_expr_width(des, container, loop_init);
need_constant_expr = true;
NetExpr*init_ex = elab_and_eval(des, container, loop_init, -1); NetExpr*init_ex = elab_and_eval(des, container, loop_init, -1);
need_constant_expr = false;
NetEConst*init = dynamic_cast<NetEConst*> (init_ex); NetEConst*init = dynamic_cast<NetEConst*> (init_ex);
if (init == 0) { if (init == 0) {
cerr << get_fileline() << ": error: Cannot evaluate genvar" cerr << get_fileline() << ": error: Cannot evaluate genvar"
@ -505,19 +579,53 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
return false; return false;
} }
// Since we will be adding the genvar value as a local parameter // Check the generate block name.
// to each instances scope. We need to make sure a parameter does
// not already exist. // A generate "loop" can not have the same name as another scope object.
const NetExpr*tmsb; const NetScope *child = container->child(hname_t(scope_name));
const NetExpr*tlsb; if (child) {
const NetExpr*texpr = container->get_parameter(loop_index, tmsb, tlsb); cerr << get_fileline() << ": error: generate \"loop\" and ";
if (texpr != 0) { child->print_type(cerr);
cerr << get_fileline() << ": error: Cannot have a genvar " cerr << " in '" << container->fullname()
<< "and parameter with the same name: " << loop_index << endl; << "' have the same name '" << scope_name << "'." << endl;
des->errors += 1; des->errors += 1;
return false; return false;
} }
// A generate "loop" can not have the same name as a genvar.
if (container->find_genvar(scope_name)) {
cerr << get_fileline() << ": error: generate \"loop\" and "
"genvar in '" << container->fullname()
<< "' have the same name '" << scope_name << "'." << endl;
des->errors += 1;
}
// A generate "loop" can not have the same name as a named event.
const NetEvent *event = container->find_event(scope_name);
if (event) {
cerr << get_fileline() << ": error: generate \"loop\" and "
"named event in '" << container->fullname()
<< "' have the same name '" << scope_name << "'." << endl;
des->errors += 1;
}
// A generate "loop" can not have the same name as a parameter.
const NetExpr*tmsb;
const NetExpr*tlsb;
const NetExpr*texpr = container->get_parameter(scope_name, tmsb, tlsb);
if (texpr != 0) {
cerr << get_fileline() << ": error: generate \"loop\" and "
"parameter in '" << container->fullname()
<< "' have the same name '" << scope_name << "'." << endl;
des->errors += 1;
}
// These have all been checked so we just need to skip the actual
// generation for these name conflicts. Not skipping these two will
// cause the compiler to have problems (assert, inf. loop, etc.).
if (container->get_parameter(loop_index, tmsb, tlsb)) return false;
if (container->find_event(loop_index)) return false;
genvar = init->value().as_long(); genvar = init->value().as_long();
delete init_ex; delete init_ex;
@ -526,7 +634,9 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
container->genvar_tmp = loop_index; container->genvar_tmp = loop_index;
container->genvar_tmp_val = genvar; container->genvar_tmp_val = genvar;
probe_expr_width(des, container, loop_test); probe_expr_width(des, container, loop_test);
need_constant_expr = true;
NetExpr*test_ex = elab_and_eval(des, container, loop_test, -1); NetExpr*test_ex = elab_and_eval(des, container, loop_test, -1);
need_constant_expr = false;
NetEConst*test = dynamic_cast<NetEConst*>(test_ex); NetEConst*test = dynamic_cast<NetEConst*>(test_ex);
if (test == 0) { if (test == 0) {
cerr << get_fileline() << ": error: Cannot evaluate genvar" cerr << get_fileline() << ": error: Cannot evaluate genvar"
@ -541,13 +651,7 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
// container. The format of using [] is part of the // container. The format of using [] is part of the
// Verilog standard. // Verilog standard.
hname_t use_name (scope_name, genvar); hname_t use_name (scope_name, genvar);
if (container->child(use_name)) {
cerr << get_fileline() << ": error: block/scope name "
<< use_name << " already used in this context."
<< endl;
des->errors += 1;
return false;
}
if (debug_scopes) if (debug_scopes)
cerr << get_fileline() << ": debug: " cerr << get_fileline() << ": debug: "
<< "Create generated scope " << use_name << endl; << "Create generated scope " << use_name << endl;
@ -579,7 +683,9 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
// Calculate the step for the loop variable. // Calculate the step for the loop variable.
probe_expr_width(des, container, loop_step); probe_expr_width(des, container, loop_step);
need_constant_expr = true;
NetExpr*step_ex = elab_and_eval(des, container, loop_step, -1); NetExpr*step_ex = elab_and_eval(des, container, loop_step, -1);
need_constant_expr = false;
NetEConst*step = dynamic_cast<NetEConst*>(step_ex); NetEConst*step = dynamic_cast<NetEConst*>(step_ex);
if (step == 0) { if (step == 0) {
cerr << get_fileline() << ": error: Cannot evaluate genvar" cerr << get_fileline() << ": error: Cannot evaluate genvar"
@ -602,7 +708,7 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
} }
// Clear the genvar_tmp field in the scope to reflect that the // Clear the genvar_tmp field in the scope to reflect that the
// genvar is no longer value for evaluating expressions. // genvar is no longer valid for evaluating expressions.
container->genvar_tmp = perm_string(); container->genvar_tmp = perm_string();
return true; return true;
@ -611,7 +717,9 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
bool PGenerate::generate_scope_condit_(Design*des, NetScope*container, bool else_flag) bool PGenerate::generate_scope_condit_(Design*des, NetScope*container, bool else_flag)
{ {
probe_expr_width(des, container, loop_test); probe_expr_width(des, container, loop_test);
need_constant_expr = true;
NetExpr*test_ex = elab_and_eval(des, container, loop_test, -1); NetExpr*test_ex = elab_and_eval(des, container, loop_test, -1);
need_constant_expr = false;
NetEConst*test = dynamic_cast<NetEConst*> (test_ex); NetEConst*test = dynamic_cast<NetEConst*> (test_ex);
if (test == 0) { if (test == 0) {
cerr << get_fileline() << ": error: Cannot evaluate genvar" cerr << get_fileline() << ": error: Cannot evaluate genvar"
@ -634,14 +742,45 @@ bool PGenerate::generate_scope_condit_(Design*des, NetScope*container, bool else
} }
hname_t use_name (scope_name); hname_t use_name (scope_name);
if (container->child(use_name)) { // A generate "if" can not have the same name as another scope object.
cerr << get_fileline() << ": error: block/scope name " const NetScope *child = container->child(use_name);
<< scope_name << " already used in this context." if (child) {
<< endl; cerr << get_fileline() << ": error: generate \"if\" and ";
child->print_type(cerr);
cerr << " in '" << container->fullname()
<< "' have the same name '" << use_name << "'." << endl;
des->errors += 1; des->errors += 1;
return false; return false;
} }
// A generate "if" can not have the same name as a genvar.
if (container->find_genvar(scope_name)) {
cerr << get_fileline() << ": error: generate \"if\" and "
"genvar in '" << container->fullname()
<< "' have the same name '" << scope_name << "'." << endl;
des->errors += 1;
}
// A generate "if" can not have the same name as a named event.
const NetEvent *event = container->find_event(scope_name);
if (event) {
cerr << get_fileline() << ": error: generate \"if\" and "
"named event in '" << container->fullname()
<< "' have the same name '" << use_name << "'." << endl;
des->errors += 1;
}
// A generate "if" can not have the same name as a parameter.
const NetExpr *ex_msb, *ex_lsb;
const NetExpr *parm = container->get_parameter(scope_name, ex_msb,
ex_lsb);
if (parm) {
cerr << get_fileline() << ": error: generate \"if\" and "
"parameter in '" << container->fullname()
<< "' have the same name '" << use_name << "'." << endl;
des->errors += 1;
}
if (debug_scopes) if (debug_scopes)
cerr << get_fileline() << ": debug: Generate condition " cerr << get_fileline() << ": debug: Generate condition "
<< (else_flag? "(else)" : "(if)") << (else_flag? "(else)" : "(if)")
@ -671,7 +810,9 @@ bool PGenerate::generate_scope_condit_(Design*des, NetScope*container, bool else
bool PGenerate::generate_scope_case_(Design*des, NetScope*container) bool PGenerate::generate_scope_case_(Design*des, NetScope*container)
{ {
probe_expr_width(des, container, loop_test); probe_expr_width(des, container, loop_test);
need_constant_expr = true;
NetExpr*case_value_ex = elab_and_eval(des, container, loop_test, -1); NetExpr*case_value_ex = elab_and_eval(des, container, loop_test, -1);
need_constant_expr = false;
NetEConst*case_value_co = dynamic_cast<NetEConst*>(case_value_ex); NetEConst*case_value_co = dynamic_cast<NetEConst*>(case_value_ex);
if (case_value_co == 0) { if (case_value_co == 0) {
cerr << get_fileline() << ": error: Cannot evaluate genvar case" cerr << get_fileline() << ": error: Cannot evaluate genvar case"
@ -702,9 +843,17 @@ bool PGenerate::generate_scope_case_(Design*des, NetScope*container)
bool match_flag = false; bool match_flag = false;
for (unsigned idx = 0 ; idx < item->item_test.size() && !match_flag ; idx +=1 ) { for (unsigned idx = 0 ; idx < item->item_test.size() && !match_flag ; idx +=1 ) {
probe_expr_width(des, container, item->item_test[idx]); probe_expr_width(des, container, item->item_test[idx]);
need_constant_expr = true;
NetExpr*item_value_ex = elab_and_eval(des, container, item->item_test[idx], -1); NetExpr*item_value_ex = elab_and_eval(des, container, item->item_test[idx], -1);
need_constant_expr = false;
NetEConst*item_value_co = dynamic_cast<NetEConst*>(item_value_ex); NetEConst*item_value_co = dynamic_cast<NetEConst*>(item_value_ex);
assert(item_value_co); if (item_value_co == 0) {
cerr << get_fileline() << ": error: Cannot evaluate "
<< " genvar case item expression: "
<< *item->item_test[idx] << endl;
des->errors += 1;
return false;
}
if (debug_scopes) if (debug_scopes)
cerr << get_fileline() << ": debug: Generate case " cerr << get_fileline() << ": debug: Generate case "
@ -739,6 +888,44 @@ bool PGenerate::generate_scope_case_(Design*des, NetScope*container)
// The name of the scope to generate, whatever that item is. // The name of the scope to generate, whatever that item is.
hname_t use_name (item->scope_name); hname_t use_name (item->scope_name);
// A generate "case" can not have the same name as another scope object.
const NetScope *child = container->child(use_name);
if (child) {
cerr << get_fileline() << ": error: generate \"case\" and ";
child->print_type(cerr);
cerr << " in '" << container->fullname()
<< "' have the same name '" << use_name << "'." << endl;
des->errors += 1;
return false;
}
// A generate "case" can not have the same name as a genvar.
if (container->find_genvar(item->scope_name)) {
cerr << get_fileline() << ": error: generate \"case\" and "
"genvar in '" << container->fullname()
<< "' have the same name '" << use_name << "'." << endl;
des->errors += 1;
}
// A generate "case" can not have the same name as a named event.
const NetEvent *event = container->find_event(item->scope_name);
if (event) {
cerr << get_fileline() << ": error: generate \"case\" and "
"named event in '" << container->fullname()
<< "' have the same name '" << use_name << "'." << endl;
des->errors += 1;
}
// A generate "case" can not have the same name as a parameter.
const NetExpr *ex_msb, *ex_lsb;
const NetExpr *parm = container->get_parameter(item->scope_name, ex_msb,
ex_lsb);
if (parm) {
cerr << get_fileline() << ": error: generate \"case\" and "
"parameter in '" << container->fullname()
<< "' have the same name '" << use_name << "'." << endl;
des->errors += 1;
}
item->probe_for_direct_nesting_(); item->probe_for_direct_nesting_();
if (item->direct_nested_) { if (item->direct_nested_) {
@ -760,13 +947,46 @@ bool PGenerate::generate_scope_case_(Design*des, NetScope*container)
bool PGenerate::generate_scope_nblock_(Design*des, NetScope*container) bool PGenerate::generate_scope_nblock_(Design*des, NetScope*container)
{ {
hname_t use_name (scope_name); hname_t use_name (scope_name);
if (container->child(use_name)) { // A generate "block" can not have the same name as another scope
cerr << get_fileline() << ": error: block/scope name " // object.
<< scope_name << " already used in this context." const NetScope *child = container->child(use_name);
<< endl; if (child) {
cerr << get_fileline() << ": error: generate \"block\" and ";
child->print_type(cerr);
cerr << " in '" << container->fullname()
<< "' have the same name '" << use_name << "'." << endl;
des->errors += 1; des->errors += 1;
return false; return false;
} }
// A generate "block" can not have the same name as a genvar.
if (container->find_genvar(scope_name)) {
cerr << get_fileline() << ": error: generate \"block\" and "
"genvar in '" << container->fullname()
<< "' have the same name '" << scope_name << "'." << endl;
des->errors += 1;
}
// A generate "block" can not have the same name as a named event.
const NetEvent *event = container->find_event(scope_name);
if (event) {
cerr << get_fileline() << ": error: generate \"block\" and "
"named event in '" << container->fullname()
<< "' have the same name '" << use_name << "'." << endl;
des->errors += 1;
}
// A generate "block" can not have the same name as a parameter.
const NetExpr *ex_msb, *ex_lsb;
const NetExpr *parm = container->get_parameter(scope_name, ex_msb,
ex_lsb);
if (parm) {
cerr << get_fileline() << ": error: generate \"block\" and "
"parameter in '" << container->fullname()
<< "' have the same name '" << use_name << "'." << endl;
des->errors += 1;
}
if (debug_scopes) if (debug_scopes)
cerr << get_fileline() << ": debug: Generate named block " cerr << get_fileline() << ": debug: Generate named block "
<< ": Generate scope=" << use_name << endl; << ": Generate scope=" << use_name << endl;
@ -791,14 +1011,10 @@ void PGenerate::elaborate_subscope_direct_(Design*des, NetScope*scope)
void PGenerate::elaborate_subscope_(Design*des, NetScope*scope) void PGenerate::elaborate_subscope_(Design*des, NetScope*scope)
{ {
// Scan the generated scope for nested generate schemes, // Add the genvars to this scope.
// and *generate* new scopes, which is slightly different typedef map<perm_string,LineInfo*>::const_iterator genvar_it_t;
// from simple elaboration. for (genvar_it_t cur = genvars.begin(); cur != genvars.end(); cur++ ) {
scope->add_genvar((*cur).first, (*cur).second);
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);
} }
// Scan the localparams in this scope, and create stub parameter // Scan the localparams in this scope, and create stub parameter
@ -809,6 +1025,39 @@ void PGenerate::elaborate_subscope_(Design*des, NetScope*scope)
// for use as parameter values. // for use as parameter values.
elaborate_scope_localparams_(des, scope, localparams); elaborate_scope_localparams_(des, scope, localparams);
// Run through the defparams for this module, elaborate the
// expressions in this context and save the result is a table
// for later final override.
// It is OK to elaborate the expressions of the defparam here
// because Verilog requires that the expressions only use
// local parameter names. It is *not* OK to do the override
// here because the parameter receiving the assignment may be
// in a scope not discovered by this pass.
typedef list<PGenerate::named_expr_t>::const_iterator defparms_iter_t;
for (defparms_iter_t cur = defparms.begin()
; cur != defparms.end() ; cur ++) {
PExpr*ex = cur->second;
assert(ex);
NetExpr*val = ex->elaborate_pexpr(des, scope);
if (val == 0) continue;
scope->defparams.push_back(make_pair(cur->first, val));
}
// 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 = generate_schemes.begin()
; cur != generate_schemes.end() ; cur ++ ) {
(*cur) -> generate_scope(des, scope);
}
// Scan through all the task and function declarations in this // Scan through all the task and function declarations in this
// scope. // scope.
elaborate_scope_tasks(des, scope, *this, tasks); elaborate_scope_tasks(des, scope, *this, tasks);
@ -886,36 +1135,77 @@ void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const
// Missing module instance names have already been rejected. // Missing module instance names have already been rejected.
assert(get_name() != ""); assert(get_name() != "");
// Check for duplicate scopes. Simply look up the scope I'm // A module instance can not have the same name as another scope object.
// about to create, and if I find it then somebody beat me to const NetScope *child = sc->child(hname_t(get_name()));
// it. if (child) {
cerr << get_fileline() << ": error: module <" << mod->mod_name()
if (sc->child(hname_t(get_name()))) { << "> instance and ";
cerr << get_fileline() << ": error: Instance/Scope name " << child->print_type(cerr);
get_name() << " already used in this context." << cerr << " in '" << sc->fullname()
endl; << "' have the same name '" << get_name() << "'." << endl;
des->errors += 1; des->errors += 1;
return; return;
} }
// A module instance can not have the same name as a genvar.
if (sc->find_genvar(get_name())) {
cerr << get_fileline() << ": error: module <" << mod->mod_name()
<< "> instance and genvar in '" << sc->fullname()
<< "' have the same name '" << get_name() << "'." << endl;
des->errors += 1;
}
// A module instance can not have the same name as a parameter.
const NetExpr *ex_msb, *ex_lsb;
const NetExpr *parm = sc->get_parameter(get_name(), ex_msb, ex_lsb);
if (parm) {
cerr << get_fileline() << ": error: module <" << mod->mod_name()
<< "> instance and parameter in '" << sc->fullname()
<< "' have the same name '" << get_name() << "'." << endl;
des->errors += 1;
}
// check for recursive instantiation by scanning the current // check for recursive instantiation by scanning the current
// scope and its parents. Look for a module instantiation of // scope and its parents. Look for a module instantiation of
// the same module, but farther up in the scope. // the same module, but farther up in the scope.
unsigned rl_count = 0;
bool in_genblk = false;
for (NetScope*scn = sc ; scn ; scn = scn->parent()) { for (NetScope*scn = sc ; scn ; scn = scn->parent()) {
if (scn->type() != NetScope::MODULE) // We need to know if we are inside a generate block to allow
// recursive instances.
if (scn->type() == NetScope::GENBLOCK) {
in_genblk = true;
continue; continue;
}
if (strcmp(mod->mod_name(), scn->module_name()) != 0) if (scn->type() != NetScope::MODULE) continue;
if (strcmp(mod->mod_name(), scn->module_name()) != 0) continue;
// We allow nested scopes if they are inside a generate block,
// but only to a certain nesting depth.
if (in_genblk) {
rl_count += 1;
if (rl_count > recursive_mod_limit) {
cerr << get_fileline() << ": error: instance "
<< scope_path(sc) << "." << get_name()
<< " of module " << mod->mod_name()
<< " is nested too deep." << endl;
cerr << get_fileline() << ": : check for "
"proper recursion termination or increase the "
"limit (" << recursive_mod_limit
<< ") with the -pRECURSIVE_MOD_LIMIT flag."
<< endl;
des->errors += 1;
return;
}
continue; continue;
}
cerr << get_fileline() << ": error: You cannot instantiate " cerr << get_fileline() << ": error: You cannot instantiate "
<< "module " << mod->mod_name() << " within itself." << endl; << "module " << mod->mod_name() << " within itself." << endl;
cerr << get_fileline() << ": : The offending instance is " cerr << get_fileline() << ": : The offending instance is "
<< scope_path(sc) << "." << get_name() << " within " << get_name() << " within " << scope_path(scn) << "." << endl;
<< scope_path(scn) << "." << endl;
des->errors += 1; des->errors += 1;
return; return;
} }
@ -952,8 +1242,10 @@ void PGModule::elaborate_scope_mod_instances_(Design*des, Module*mod, NetScope*s
{ {
if (msb_) probe_expr_width(des, sc, msb_); if (msb_) probe_expr_width(des, sc, msb_);
if (lsb_) probe_expr_width(des, sc, lsb_); if (lsb_) probe_expr_width(des, sc, lsb_);
need_constant_expr = true;
NetExpr*mse = msb_ ? elab_and_eval(des, sc, msb_, -1) : 0; NetExpr*mse = msb_ ? elab_and_eval(des, sc, msb_, -1) : 0;
NetExpr*lse = lsb_ ? elab_and_eval(des, sc, lsb_, -1) : 0; NetExpr*lse = lsb_ ? elab_and_eval(des, sc, lsb_, -1) : 0;
need_constant_expr = false;
NetEConst*msb = dynamic_cast<NetEConst*> (mse); NetEConst*msb = dynamic_cast<NetEConst*> (mse);
NetEConst*lsb = dynamic_cast<NetEConst*> (lse); NetEConst*lsb = dynamic_cast<NetEConst*> (lse);
@ -1019,6 +1311,7 @@ void PGModule::elaborate_scope_mod_instances_(Design*des, Module*mod, NetScope*s
// Set time units and precision. // Set time units and precision.
my_scope->time_unit(mod->time_unit); my_scope->time_unit(mod->time_unit);
my_scope->time_precision(mod->time_precision); my_scope->time_precision(mod->time_precision);
my_scope->time_from_timescale(mod->time_from_timescale);
des->set_precision(mod->time_precision); des->set_precision(mod->time_precision);
// Look for module parameter replacements. The "replace" map // Look for module parameter replacements. The "replace" map
@ -1026,7 +1319,7 @@ void PGModule::elaborate_scope_mod_instances_(Design*des, Module*mod, NetScope*s
// passed. It is built up by the ordered overrides or named // passed. It is built up by the ordered overrides or named
// overrides. // overrides.
typedef map<perm_string,PExpr*>::const_iterator mparm_it_t; typedef map<perm_string,PExpr*>::const_iterator mparm_itr_t;
map<perm_string,PExpr*> replace; map<perm_string,PExpr*> replace;
@ -1069,15 +1362,15 @@ void PGModule::elaborate_scope_mod_instances_(Design*des, Module*mod, NetScope*s
// the expression in my context, then replace the sub-scope // the expression in my context, then replace the sub-scope
// parameter value with the new expression. // parameter value with the new expression.
for (mparm_it_t cur = replace.begin() for (mparm_itr_t cur = replace.begin()
; cur != replace.end() ; cur ++ ) { ; cur != replace.end() ; cur ++ ) {
PExpr*tmp = (*cur).second; PExpr*tmp = (*cur).second;
// No expression means that the parameter is not // No expression means that the parameter is not
// replaced at all. // replaced at all.
if (tmp == 0) if (tmp == 0) continue;
continue;
NetExpr*val = tmp->elaborate_pexpr(des, sc); NetExpr*val = tmp->elaborate_pexpr(des, sc);
if (val == 0) continue;
replace_net[(*cur).first] = val; replace_net[(*cur).first] = val;
} }
@ -1109,6 +1402,34 @@ void PGModule::elaborate_scope_mod_instances_(Design*des, Module*mod, NetScope*s
*/ */
void PEvent::elaborate_scope(Design*des, NetScope*scope) const void PEvent::elaborate_scope(Design*des, NetScope*scope) const
{ {
// A named event can not have the same name as another scope object.
const NetScope *child = scope->child(hname_t(name_));
if (child) {
cerr << get_fileline() << ": error: named event and ";
child->print_type(cerr);
cerr << " in '" << scope->fullname()
<< "' have the same name '" << name_ << "'." << endl;
des->errors += 1;
}
// A named event can not have the same name as a genvar.
if (scope->find_genvar(name_)) {
cerr << get_fileline() << ": error: named event and "
<< "genvar in '" << scope->fullname()
<< "' have the same name '" << name_ << "'." << endl;
des->errors += 1;
}
// A named event can not have the same name as a parameter.
const NetExpr *ex_msb, *ex_lsb;
const NetExpr *parm = scope->get_parameter(name_, ex_msb, ex_lsb);
if (parm) {
cerr << get_fileline() << ": error: named event and "
<< "parameter in '" << scope->fullname()
<< "' have the same name '" << name_ << "'." << endl;
des->errors += 1;
}
NetEvent*ev = new NetEvent(name_); NetEvent*ev = new NetEvent(name_);
ev->set_line(*this); ev->set_line(*this);
scope->add_event(ev); scope->add_event(ev);
@ -1189,13 +1510,37 @@ void PBlock::elaborate_scope(Design*des, NetScope*scope) const
if (pscope_name() != 0) { if (pscope_name() != 0) {
hname_t use_name(pscope_name()); hname_t use_name(pscope_name());
if (scope->child(use_name)) { // A named block can not have the same name as another scope
cerr << get_fileline() << ": error: block/scope name " // object.
<< use_name << " already used in this context." const NetScope *child = scope->child(use_name);
<< endl; if (child) {
cerr << get_fileline() << ": error: named block and ";
child->print_type(cerr);
cerr << " in '" << scope->fullname()
<< "' have the same name '" << use_name << "'." << endl;
des->errors += 1; des->errors += 1;
return; return;
} }
// A named block can not have the same name as a genvar.
if (scope->find_genvar(pscope_name())) {
cerr << get_fileline() << ": error: named block and "
"genvar in '" << scope->fullname()
<< "' have the same name '" << use_name << "'." << endl;
des->errors += 1;
}
// A named block can not have the same name as a parameter.
const NetExpr *ex_msb, *ex_lsb;
const NetExpr *parm = scope->get_parameter(pscope_name(), ex_msb,
ex_lsb);
if (parm) {
cerr << get_fileline() << ": error: named block and "
"parameter in '" << scope->fullname()
<< "' have the same name '" << use_name << "'." << endl;
des->errors += 1;
}
if (debug_scopes) if (debug_scopes)
cerr << get_fileline() << ": debug: " cerr << get_fileline() << ": debug: "
<< "Elaborate block scope " << use_name << "Elaborate block scope " << use_name

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2000-2009 Stephen Williams (steve@icarus.com) * Copyright (c) 2000-2010 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -92,10 +92,10 @@ bool PScope::elaborate_sig_wires_(Design*des, NetScope*scope) const
&& (sig->port_type() == NetNet::PINPUT) && (sig->port_type() == NetNet::PINPUT)
&& (sig->type() == NetNet::REG)) { && (sig->type() == NetNet::REG)) {
cerr << cur->get_fileline() << ": error: " cerr << cur->get_fileline() << ": error: Port "
<< cur->basename() << " in " << cur->basename() << " of module "
<< scope->module_name() << scope->module_name()
<< " declared as input and as a reg type." << endl; << " is declared as input and as a reg type." << endl;
des->errors += 1; des->errors += 1;
} }
@ -104,10 +104,22 @@ bool PScope::elaborate_sig_wires_(Design*des, NetScope*scope) const
&& (sig->port_type() == NetNet::PINOUT) && (sig->port_type() == NetNet::PINOUT)
&& (sig->type() == NetNet::REG)) { && (sig->type() == NetNet::REG)) {
cerr << cur->get_fileline() << ": error: " cerr << cur->get_fileline() << ": error: Port "
<< cur->basename() << " in " << cur->basename() << " of module "
<< scope->module_name() << scope->module_name()
<< " declared as inout and as a reg type." << endl; << " is declared as inout and as a reg type." << endl;
des->errors += 1;
}
if (sig && (sig->scope() == scope)
&& (scope->type() == NetScope::MODULE)
&& (sig->port_type() == NetNet::PINOUT)
&& (sig->data_type() == IVL_VT_REAL)) {
cerr << cur->get_fileline() << ": error: Port "
<< cur->basename() << " of module "
<< scope->module_name()
<< " is declared as a real inout port." << endl;
des->errors += 1; des->errors += 1;
} }
@ -126,7 +138,7 @@ static void elaborate_sig_funcs(Design*des, NetScope*scope,
hname_t use_name ( (*cur).first ); hname_t use_name ( (*cur).first );
NetScope*fscope = scope->child(use_name); NetScope*fscope = scope->child(use_name);
if (scope == 0) { if (fscope == 0) {
cerr << (*cur).second->get_fileline() << ": internal error: " cerr << (*cur).second->get_fileline() << ": internal error: "
<< "Child scope for function " << (*cur).first << "Child scope for function " << (*cur).first
<< " missing in " << scope_path(scope) << "." << endl; << " missing in " << scope_path(scope) << "." << endl;
@ -599,9 +611,11 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const
} }
ret_sig = new NetNet(scope, fname, NetNet::REG, mnum, lnum); ret_sig = new NetNet(scope, fname, NetNet::REG, mnum, lnum);
ret_sig->set_scalar(false);
} else { } else {
ret_sig = new NetNet(scope, fname, NetNet::REG); ret_sig = new NetNet(scope, fname, NetNet::REG);
ret_sig->set_scalar(true);
} }
ret_sig->set_line(*this); ret_sig->set_line(*this);
ret_sig->set_signed(return_type_.type == PTF_REG_S); ret_sig->set_signed(return_type_.type == PTF_REG_S);
@ -614,6 +628,7 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const
ret_sig->set_line(*this); ret_sig->set_line(*this);
ret_sig->set_signed(true); ret_sig->set_signed(true);
ret_sig->set_isint(true); ret_sig->set_isint(true);
ret_sig->set_scalar(false);
ret_sig->port_type(NetNet::POUTPUT); ret_sig->port_type(NetNet::POUTPUT);
ret_sig->data_type(IVL_VT_LOGIC); ret_sig->data_type(IVL_VT_LOGIC);
break; break;
@ -623,6 +638,7 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const
ret_sig->set_line(*this); ret_sig->set_line(*this);
ret_sig->set_signed(false); ret_sig->set_signed(false);
ret_sig->set_isint(false); ret_sig->set_isint(false);
ret_sig->set_scalar(false);
ret_sig->port_type(NetNet::POUTPUT); ret_sig->port_type(NetNet::POUTPUT);
ret_sig->data_type(IVL_VT_LOGIC); ret_sig->data_type(IVL_VT_LOGIC);
break; break;
@ -633,6 +649,7 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const
ret_sig->set_line(*this); ret_sig->set_line(*this);
ret_sig->set_signed(true); ret_sig->set_signed(true);
ret_sig->set_isint(false); ret_sig->set_isint(false);
ret_sig->set_scalar(true);
ret_sig->port_type(NetNet::POUTPUT); ret_sig->port_type(NetNet::POUTPUT);
ret_sig->data_type(IVL_VT_REAL); ret_sig->data_type(IVL_VT_REAL);
break; break;
@ -843,23 +860,63 @@ void PWhile::elaborate_sig(Design*des, NetScope*scope) const
/* /*
* Elaborate a source wire. The "wire" is the declaration of wires, * Elaborate a source wire. The "wire" is the declaration of wires,
* registers, ports and memories. The parser has already merged the * registers, ports and memories. The parser has already merged the
* multiple properties of a wire (i.e., "input wire") so come the * multiple properties of a wire (i.e., "input wire"), so come the
* elaboration this creates an object in the design that represent the * elaboration this creates an object in the design that represents the
* defined item. * defined item.
*/ */
NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
{ {
NetNet::Type wtype = type_; NetNet::Type wtype = type_;
if (wtype == NetNet::IMPLICIT) bool is_implicit_scalar = false;
if (wtype == NetNet::IMPLICIT) {
wtype = NetNet::WIRE; wtype = NetNet::WIRE;
if (wtype == NetNet::IMPLICIT_REG) is_implicit_scalar = true;
}
if (wtype == NetNet::IMPLICIT_REG) {
wtype = NetNet::REG; wtype = NetNet::REG;
is_implicit_scalar = true;
}
unsigned wid = 1; unsigned wid = 1;
long lsb = 0, msb = 0; long lsb = 0, msb = 0;
des->errors += error_cnt_; des->errors += error_cnt_;
// A signal can not have the same name as a scope object.
const NetScope *child = scope->child(hname_t(name_));
if (child) {
cerr << get_fileline() << ": error: signal and ";
child->print_type(cerr);
cerr << " in '" << scope->fullname()
<< "' have the same name '" << name_ << "'." << endl;
des->errors += 1;
}
// A signal can not have the same name as a genvar.
const LineInfo *genvar = scope->find_genvar(name_);
if (genvar) {
cerr << get_fileline() << ": error: signal and genvar in '"
<< scope->fullname() << "' have the same name '" << name_
<< "'." << endl;
des->errors += 1;
}
// A signal can not have the same name as a parameter.
const NetExpr *ex_msb, *ex_lsb;
const NetExpr *parm = scope->get_parameter(name_, ex_msb, ex_lsb);
if (parm) {
cerr << get_fileline() << ": error: signal and parameter in '"
<< scope->fullname() << "' have the same name '" << name_
<< "'." << endl;
des->errors += 1;
}
// A signal can not have the same name as a named event.
const NetEvent *event = scope->find_event(name_);
if (event) {
cerr << get_fileline() << ": error: signal and named event in '"
<< scope->fullname() << "' have the same name '" << name_
<< "'." << endl;
des->errors += 1;
}
if (port_set_ || net_set_) { if (port_set_ || net_set_) {
long pmsb = 0, plsb = 0, nmsb = 0, nlsb = 0; long pmsb = 0, plsb = 0, nmsb = 0, nlsb = 0;
bool bad_lsb = false, bad_msb = false; bool bad_lsb = false, bad_msb = false;
@ -902,6 +959,8 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
delete texpr; delete texpr;
nmsb = pmsb; nmsb = pmsb;
nlsb = plsb; nlsb = plsb;
/* An implicit port can have a range so note that here. */
is_implicit_scalar = false;
} }
if (!port_set_) assert(port_msb_ == 0 && port_lsb_ == 0); if (!port_set_) assert(port_msb_ == 0 && port_lsb_ == 0);
if (port_msb_ == 0) assert(port_lsb_ == 0); if (port_msb_ == 0) assert(port_lsb_ == 0);
@ -1060,6 +1119,17 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
array_dimensions = 1; array_dimensions = 1;
} }
if (data_type_ == IVL_VT_REAL && (msb != 0 || lsb != 0)) {
cerr << get_fileline() << ": error: real ";
if (wtype == NetNet::REG) cerr << "variable";
else cerr << "net";
cerr << " '" << name_
<< "' cannot be declared as a vector, found a range ["
<< msb << ":" << lsb << "]." << endl;
des->errors += 1;
return 0;
}
/* If the net type is supply0 or supply1, replace it /* If the net type is supply0 or supply1, replace it
with a simple wire with a pulldown/pullup with supply with a simple wire with a pulldown/pullup with supply
strength. In other words, transform: strength. In other words, transform:
@ -1089,14 +1159,19 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
if (debug_elaborate) { if (debug_elaborate) {
cerr << get_fileline() << ": debug: " cerr << get_fileline() << ": debug: "
<< "Generate a SUPPLY pulldown for the " << "Generate a SUPPLY pull for the ";
<< "supply0 net." << endl; if (wtype == NetNet::SUPPLY0) cerr << "supply0";
else cerr << "supply1";
cerr << " net." << endl;
} }
} }
if (debug_elaborate) { if (debug_elaborate) {
cerr << get_fileline() << ": debug: Create signal " cerr << get_fileline() << ": debug: Create signal " << wtype;
<< wtype << " ["<<msb<<":"<<lsb<<"] " << name_; if (!get_scalar()) {
cerr << " ["<<msb<<":"<<lsb<<"]";
}
cerr << " " << name_;
if (array_dimensions > 0) { if (array_dimensions > 0) {
cerr << " [" << array_s0 << ":" << array_e0 << "]" << endl; cerr << " [" << array_s0 << ":" << array_e0 << "]" << endl;
} }
@ -1108,6 +1183,8 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
? new NetNet(scope, name_, wtype, msb, lsb, array_s0, array_e0) ? new NetNet(scope, name_, wtype, msb, lsb, array_s0, array_e0)
: new NetNet(scope, name_, wtype, msb, lsb); : new NetNet(scope, name_, wtype, msb, lsb);
if (wtype == NetNet::WIRE) sig->devirtualize_pins();
ivl_variable_type_t use_data_type = data_type_; ivl_variable_type_t use_data_type = data_type_;
if (use_data_type == IVL_VT_NO_TYPE) { if (use_data_type == IVL_VT_NO_TYPE) {
use_data_type = IVL_VT_LOGIC; use_data_type = IVL_VT_LOGIC;
@ -1124,6 +1201,8 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
sig->port_type(port_type_); sig->port_type(port_type_);
sig->set_signed(get_signed()); sig->set_signed(get_signed());
sig->set_isint(get_isint()); sig->set_isint(get_isint());
if (is_implicit_scalar) sig->set_scalar(true);
else sig->set_scalar(get_scalar());
if (ivl_discipline_t dis = get_discipline()) { if (ivl_discipline_t dis = get_discipline()) {
sig->set_discipline(dis); sig->set_discipline(dis);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1998-2009 Stephen Williams (steve@icarus.com) * Copyright (c) 1998-2013 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -189,6 +189,15 @@ void PGAssign::elaborate(Design*des, NetScope*scope) const
need_driver_flag = false; need_driver_flag = false;
} }
/* When we are given a non-default strength value and if the drive
* source is a bit, part, indexed select or concatenation we need
* to add a driver (BUFZ) to convey the strength information. */
if ((drive0 != Link::STRONG || drive1 != Link::STRONG) &&
((dynamic_cast<NetESelect*>(rval_expr)) ||
(dynamic_cast<NetEConcat*>(rval_expr)))) {
need_driver_flag = true;
}
if (need_driver_flag) { if (need_driver_flag) {
NetBUFZ*driver = new NetBUFZ(scope, scope->local_symbol(), NetBUFZ*driver = new NetBUFZ(scope, scope->local_symbol(),
rval->vector_width()); rval->vector_width());
@ -234,8 +243,10 @@ unsigned PGBuiltin::calculate_array_count_(Design*des, NetScope*scope,
gates, then I am expected to make more than one gates, then I am expected to make more than one
gate. Figure out how many are desired. */ gate. Figure out how many are desired. */
if (msb_) { if (msb_) {
need_constant_expr = true;
NetExpr*msb_exp = elab_and_eval(des, scope, msb_, -1); NetExpr*msb_exp = elab_and_eval(des, scope, msb_, -1);
NetExpr*lsb_exp = elab_and_eval(des, scope, lsb_, -1); NetExpr*lsb_exp = elab_and_eval(des, scope, lsb_, -1);
need_constant_expr = false;
NetEConst*msb_con = dynamic_cast<NetEConst*>(msb_exp); NetEConst*msb_con = dynamic_cast<NetEConst*>(msb_exp);
NetEConst*lsb_con = dynamic_cast<NetEConst*>(lsb_exp); NetEConst*lsb_con = dynamic_cast<NetEConst*>(lsb_exp);
@ -278,26 +289,35 @@ unsigned PGBuiltin::calculate_array_count_(Design*des, NetScope*scope,
return count; return count;
} }
unsigned PGBuiltin::calculate_output_count_(void) const void PGBuiltin::calculate_gate_and_lval_count_(unsigned&gate_count,
unsigned&lval_count) const
{ {
unsigned output_count;
switch (type()) { switch (type()) {
case BUF: case BUF:
case NOT: case NOT:
if (pin_count() > 2) output_count = pin_count() - 1; if (pin_count() > 2) gate_count = pin_count() - 1;
else output_count = 1; else gate_count = 1;
lval_count = gate_count;
break; break;
case PULLDOWN: case PULLDOWN:
case PULLUP: case PULLUP:
output_count = pin_count(); gate_count = pin_count();
lval_count = gate_count;
break;
case TRAN:
case RTRAN:
case TRANIF0:
case TRANIF1:
case RTRANIF0:
case RTRANIF1:
gate_count = 1;
lval_count = 2;
break; break;
default: default:
output_count = 1; gate_count = 1;
lval_count = 1;
break; break;
} }
return output_count;
} }
NetNode* PGBuiltin::create_gate_for_output_(Design*des, NetScope*scope, NetNode* PGBuiltin::create_gate_for_output_(Design*des, NetScope*scope,
@ -607,23 +627,31 @@ void PGBuiltin::elaborate(Design*des, NetScope*scope) const
if (array_count == 0) if (array_count == 0)
return; return;
unsigned output_count = calculate_output_count_(); unsigned gate_count = 0, lval_count = 0;
calculate_gate_and_lval_count_(gate_count, lval_count);
/* Now we have a gate count. Elaborate the output expressions /* Now we have a gate count. Elaborate the lval (output or
only. We do it early so that we can see if we can make bi-directional) expressions only. We do it early so that
wide gates instead of an array of gates. */ we can see if we can make wide gates instead of an array
of gates. */
vector<NetNet*>lval_sigs (output_count); vector<NetNet*>lval_sigs (lval_count);
for (unsigned idx = 0 ; idx < output_count ; idx += 1) { for (unsigned idx = 0 ; idx < lval_count ; idx += 1) {
if (pin(idx) == 0) { if (pin(idx) == 0) {
cerr << get_fileline() << ": error: Logic gate port " cerr << get_fileline() << ": error: Logic gate port "
"expressions are not optional." << endl; "expressions are not optional." << endl;
des->errors += 1; des->errors += 1;
return; return;
} }
lval_sigs[idx] = pin(idx)->elaborate_lnet(des, scope); if (lval_count > gate_count)
ivl_assert(*this, lval_sigs[idx]); lval_sigs[idx] = pin(idx)->elaborate_bi_net(des, scope);
else
lval_sigs[idx] = pin(idx)->elaborate_lnet(des, scope);
// The only way this should return zero is if an error
// happened, so for that case just return.
if (lval_sigs[idx] == 0) return;
// For now, assume all the outputs are the same width. // For now, assume all the outputs are the same width.
ivl_assert(*this, idx == 0 || lval_sigs[idx]->vector_width() == lval_sigs[0]->vector_width()); ivl_assert(*this, idx == 0 || lval_sigs[idx]->vector_width() == lval_sigs[0]->vector_width());
@ -667,19 +695,19 @@ void PGBuiltin::elaborate(Design*des, NetScope*scope) const
des, scope); des, scope);
/* Allocate all the netlist nodes for the gates. */ /* Allocate all the netlist nodes for the gates. */
vector<NetNode*>cur (array_count*output_count); vector<NetNode*>cur (array_count*gate_count);
/* Now make as many gates as the bit count dictates. Give each /* Now make as many gates as the bit count dictates. Give each
a unique name, and set the delay times. */ a unique name, and set the delay times. */
for (unsigned idx = 0 ; idx < array_count*output_count ; idx += 1) { for (unsigned idx = 0 ; idx < array_count*gate_count ; idx += 1) {
unsigned array_idx = idx/output_count; unsigned array_idx = idx/gate_count;
unsigned output_idx = idx%output_count; unsigned gate_idx = idx%gate_count;
ostringstream tmp; ostringstream tmp;
unsigned index = (low < high)? (low+array_idx) : (low-array_idx); unsigned index = (low < high)? (low+array_idx) : (low-array_idx);
tmp << name << "<" << index << "." << output_idx << ">"; tmp << name << "<" << index << "." << gate_idx << ">";
perm_string inm = lex_strings.make(tmp.str()); perm_string inm = lex_strings.make(tmp.str());
cur[idx] = create_gate_for_output_(des, scope, inm, instance_width); cur[idx] = create_gate_for_output_(des, scope, inm, instance_width);
@ -699,6 +727,10 @@ void PGBuiltin::elaborate(Design*des, NetScope*scope) const
log->pin(0).drive0(drive_type(strength0())); log->pin(0).drive0(drive_type(strength0()));
log->pin(0).drive1(drive_type(strength1())); log->pin(0).drive1(drive_type(strength1()));
} else if (rise_time || fall_time || decay_time) {
cerr << get_fileline() << ": sorry: bi-directional pass "
<< "switch delays are not supported in V0.9." << endl;
des->errors += 1;
} }
cur[idx]->set_line(*this); cur[idx]->set_line(*this);
@ -721,16 +753,24 @@ void PGBuiltin::elaborate(Design*des, NetScope*scope) const
return; return;
} }
NetNet*sig = 0; NetNet*sig = 0;
if (idx < output_count) { if (idx < lval_count) {
sig = lval_sigs[idx]; sig = lval_sigs[idx];
} else { } else {
// If this is an array, the port expression is required
// to be the exact width required (this will be checked
// later). But if this is a single instance, consensus
// is that we just take the LSB of the port expression.
unsigned use_width = array_count * instance_width; unsigned use_width = array_count * instance_width;
ivl_variable_type_t tmp_type = IVL_VT_NO_TYPE; ivl_variable_type_t tmp_type = IVL_VT_NO_TYPE;
bool flag = false; bool flag = false;
ex->test_width(des, scope, 0, use_width, tmp_type, flag); ex->test_width(des, scope, 0, use_width, tmp_type, flag);
NetExpr*tmp = elab_and_eval(des, scope, ex, NetExpr*tmp = elab_and_eval(des, scope, ex, -1,
use_width, use_width); msb_ ? -1 : 1);
if (tmp == 0)
continue;
if (msb_ == 0 && tmp->expr_width() != 1)
tmp = new NetESelect(tmp, make_const_0(1), 1);
sig = tmp->synthesize(des, scope, tmp); sig = tmp->synthesize(des, scope, tmp);
delete tmp; delete tmp;
} }
@ -770,7 +810,7 @@ void PGBuiltin::elaborate(Design*des, NetScope*scope) const
cerr << get_fileline() << ": error: " cerr << get_fileline() << ": error: "
<< "Expression width " << sig->vector_width() << "Expression width " << sig->vector_width()
<< " does not match width " << instance_width << " does not match width " << instance_width
<< " of logic gate array port " << idx << " of logic gate array port " << idx+1
<< "." << endl; << "." << endl;
des->errors += 1; des->errors += 1;
} }
@ -781,11 +821,11 @@ void PGBuiltin::elaborate(Design*des, NetScope*scope) const
// Although in Verilog proper a multiple // Although in Verilog proper a multiple
// output gate has only 1 input, this conditional // output gate has only 1 input, this conditional
// handles gates with N outputs and M inputs. // handles gates with N outputs and M inputs.
if (idx < output_count) { if (idx < gate_count) {
connect(cur[idx]->pin(0), sig->pin(0)); connect(cur[idx]->pin(0), sig->pin(0));
} else { } else {
for (unsigned dev = 0 ; dev < output_count; dev += 1) for (unsigned dev = 0 ; dev < gate_count; dev += 1)
connect(cur[dev]->pin(idx-output_count+1), sig->pin(0)); connect(cur[dev]->pin(idx-gate_count+1), sig->pin(0));
} }
} else if (sig->vector_width() == 1) { } else if (sig->vector_width() == 1) {
@ -795,26 +835,32 @@ void PGBuiltin::elaborate(Design*des, NetScope*scope) const
output port, connect it to all array_count output port, connect it to all array_count
devices that have outputs at this devices that have outputs at this
position. Otherwise, idx is an input to all position. Otherwise, idx is an input to all
array_count*output_count devices. */ array_count*gate_count devices. */
if (idx < output_count) { if (idx < gate_count) {
for (unsigned gdx = 0 ; gdx < array_count ; gdx += 1) { for (unsigned gdx = 0 ; gdx < array_count ; gdx += 1) {
unsigned dev = gdx*output_count; unsigned dev = gdx*gate_count;
connect(cur[dev+idx]->pin(0), sig->pin(0)); connect(cur[dev+idx]->pin(0), sig->pin(0));
} }
} else { } else {
unsigned use_idx = idx - output_count + 1; unsigned use_idx = idx - gate_count + 1;
for (unsigned gdx = 0 ; gdx < cur.size() ; gdx += 1) for (unsigned gdx = 0 ; gdx < cur.size() ; gdx += 1)
connect(cur[gdx]->pin(use_idx), sig->pin(0)); connect(cur[gdx]->pin(use_idx), sig->pin(0));
} }
} else if (sig->vector_width() == array_count) { } else if (sig->vector_width() == array_count) {
/* Bi-directional switches should get collapsed into
a single wide instance, so should never reach this
point. Check this is so, as the following code
doesn't handle bi-directional connections. */
ivl_assert(*this, lval_count == gate_count);
/* Handle the general case that each bit of the /* Handle the general case that each bit of the
value is connected to a different instance. In value is connected to a different instance. In
this case, the output is handled slightly this case, the output is handled slightly
different from the inputs. */ different from the inputs. */
if (idx < output_count) { if (idx < gate_count) {
NetConcat*cc = new NetConcat(scope, NetConcat*cc = new NetConcat(scope,
scope->local_symbol(), scope->local_symbol(),
sig->vector_width(), sig->vector_width(),
@ -826,7 +872,7 @@ void PGBuiltin::elaborate(Design*des, NetScope*scope) const
/* Connect the outputs of the gates to the concat. */ /* Connect the outputs of the gates to the concat. */
for (unsigned gdx = 0 ; gdx < array_count; gdx += 1) { for (unsigned gdx = 0 ; gdx < array_count; gdx += 1) {
unsigned dev = gdx*output_count; unsigned dev = gdx*gate_count;
connect(cur[dev+idx]->pin(0), cc->pin(gdx+1)); connect(cur[dev+idx]->pin(0), cc->pin(gdx+1));
NetNet*tmp2 = new NetNet(scope, NetNet*tmp2 = new NetNet(scope,
@ -850,9 +896,9 @@ void PGBuiltin::elaborate(Design*des, NetScope*scope) const
tmp2->local_flag(true); tmp2->local_flag(true);
tmp2->data_type(sig->data_type()); tmp2->data_type(sig->data_type());
connect(tmp1->pin(0), tmp2->pin(0)); connect(tmp1->pin(0), tmp2->pin(0));
unsigned use_idx = idx - output_count + 1; unsigned use_idx = idx - gate_count + 1;
unsigned dev = gdx*output_count; unsigned dev = gdx*gate_count;
for (unsigned gdx2 = 0 ; gdx2 < output_count ; gdx2 += 1) for (unsigned gdx2 = 0 ; gdx2 < gate_count ; gdx2 += 1)
connect(cur[dev+gdx2]->pin(use_idx), tmp1->pin(0)); connect(cur[dev+gdx2]->pin(use_idx), tmp1->pin(0));
} }
@ -966,6 +1012,28 @@ static bool need_bufz_for_input_port(const vector<NetNet*>&prts)
return false; return false;
} }
/*
* Convert a wire or tri to a tri0 or tri1 as needed to make
* an unconnected drive pull for floating inputs.
*/
static void convert_net(Design*des, const LineInfo *line,
NetNet *net, NetNet::Type type)
{
// If the types already match just return.
if (net->type() == type) return;
// We can only covert a wire or tri to have a default pull.
if (net->type() == NetNet::WIRE || net->type() == NetNet::TRI) {
net->type(type);
return;
}
// We may have to support this at some point in time!
cerr << line->get_fileline() << ": sorry: Can not pull floating "
"input type '" << net->type() << "'." << endl;
des->errors += 1;
}
/* /*
* Instantiate a module by recursively elaborating it. Set the path of * Instantiate a module by recursively elaborating it. Set the path of
* the recursive elaboration so that signal names get properly * the recursive elaboration so that signal names get properly
@ -1058,7 +1126,7 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
// No named bindings, just use the positional list I // No named bindings, just use the positional list I
// already have. // already have.
assert(pin_count() == rmod->port_count()); ivl_assert(*this, pin_count() == rmod->port_count());
pins = get_pins(); pins = get_pins();
} }
@ -1093,28 +1161,50 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
// null parameter is passed in. // null parameter is passed in.
if (pins[idx] == 0) { if (pins[idx] == 0) {
// We need this information to support the
// unconnected_drive directive and for a
// unconnected input warning when asked for.
vector<PEIdent*> mport = rmod->get_port(idx);
if (mport.size() == 0) continue;
// While we're here, look to see if this perm_string pname = peek_tail_name(mport[0]->path());
// unconnected (from the outside) port is an
// input. If so, consider printing a port binding
// warning.
if (warn_portbinding) {
vector<PEIdent*> mport = rmod->get_port(idx);
if (mport.size() == 0)
continue;
perm_string pname = peek_tail_name(mport[0]->path()); NetNet*tmp = instance[0]->find_signal(pname);
ivl_assert(*this, tmp);
NetNet*tmp = instance[0]->find_signal(pname); if (tmp->port_type() == NetNet::PINPUT) {
assert(tmp); // If we have an unconnected input convert it
// as needed if an unconnected_drive directive
// was given. This only works for tri or wire!
switch (rmod->uc_drive) {
case Module::UCD_PULL0:
convert_net(des, this, tmp, NetNet::TRI0);
break;
case Module::UCD_PULL1:
convert_net(des, this, tmp, NetNet::TRI1);
break;
case Module::UCD_NONE:
break;
}
if (tmp->port_type() == NetNet::PINPUT) { // Print a waring for an unconnected input.
if (warn_portbinding) {
cerr << get_fileline() << ": warning: " cerr << get_fileline() << ": warning: "
<< "Instantiating module " << "Instantiating module "
<< rmod->mod_name() << rmod->mod_name()
<< " with dangling input port " << " with dangling input port '"
<< rmod->ports[idx]->name << rmod->ports[idx]->name;
<< "." << endl; switch (rmod->uc_drive) {
case Module::UCD_PULL0:
cerr << "' (pulled low)." << endl;
break;
case Module::UCD_PULL1:
cerr << "' (pulled high)." << endl;
break;
case Module::UCD_NONE:
cerr << "' (floating)." << endl;
break;
}
} }
} }
@ -1146,13 +1236,13 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
for (unsigned ldx = 0 ; ldx < mport.size() ; ldx += 1) { for (unsigned ldx = 0 ; ldx < mport.size() ; ldx += 1) {
unsigned lbase = inst * mport.size(); unsigned lbase = inst * mport.size();
PEIdent*pport = mport[ldx]; PEIdent*pport = mport[ldx];
assert(pport); ivl_assert(*this, pport);
prts[lbase + ldx] prts[lbase + ldx]
= pport->elaborate_port(des, inst_scope); = pport->elaborate_port(des, inst_scope);
if (prts[lbase + ldx] == 0) if (prts[lbase + ldx] == 0)
continue; continue;
assert(prts[lbase + ldx]); ivl_assert(*this, prts[lbase + ldx]);
prts_vector_width += prts[lbase + ldx]->vector_width(); prts_vector_width += prts[lbase + ldx]->vector_width();
} }
} }
@ -1167,12 +1257,21 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
// We know by design that each instance has the same // We know by design that each instance has the same
// width port. Therefore, the prts_pin_count must be an // width port. Therefore, the prts_pin_count must be an
// even multiple of the instance count. // even multiple of the instance count.
assert(prts_vector_width % instance.size() == 0); ivl_assert(*this, prts_vector_width % instance.size() == 0);
unsigned desired_vector_width = prts_vector_width; unsigned desired_vector_width = prts_vector_width;
if (instance.size() != 1) if (instance.size() != 1)
desired_vector_width = 0; desired_vector_width = 0;
if (!prts.empty() && (prts[0]->port_type() == NetNet::PINPUT)
&& prts[0]->pin(0).nexus()->drivers_present()
&& pins[idx]->is_collapsible_net(des, scope)) {
prts[0]->port_type(NetNet::PINOUT);
cerr << pins[idx]->get_fileline() << ": warning: input port "
<< prts[0]->name() << " is coerced to inout." << endl;
}
// Elaborate the expression that connects to the // Elaborate the expression that connects to the
// module[s] port. sig is the thing outside the module // module[s] port. sig is the thing outside the module
// that connects to the port. // that connects to the port.
@ -1230,6 +1329,22 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
sig = tmp2; sig = tmp2;
} }
// If we have a real signal driving a bit/vector port
// then we convert the real value using the appropriate
// width cast. Since a real is only one bit the whole
// thing needs to go to each instance when arrayed.
if ((sig->data_type() == IVL_VT_REAL ) &&
prts.size() && (prts[0]->data_type() != IVL_VT_REAL )) {
sig = cast_to_int(des, scope, sig,
prts_vector_width/instance.size());
}
// If we have a bit/vector signal driving a real port
// then we convert the value to a real.
if ((sig->data_type() != IVL_VT_REAL ) &&
prts.size() && (prts[0]->data_type() == IVL_VT_REAL )) {
sig = cast_to_real(des, scope, sig);
}
} else if (prts[0]->port_type() == NetNet::PINOUT) { } else if (prts[0]->port_type() == NetNet::PINOUT) {
/* Inout to/from module. This is a more /* Inout to/from module. This is a more
@ -1254,8 +1369,33 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
<< "Inout port expression must support " << "Inout port expression must support "
<< "continuous assignment." << endl; << "continuous assignment." << endl;
cerr << pins[idx]->get_fileline() << ": : " cerr << pins[idx]->get_fileline() << ": : "
<< "Port of " << rmod->mod_name() << "Port " << rmod->ports[idx]->name << " of "
<< " is " << rmod->ports[idx]->name << endl; << rmod->mod_name() << " is connected to "
<< *pins[idx] << endl;
des->errors += 1;
continue;
}
// We do not support automatic bits to real conversion
// for inout ports.
if ((sig->data_type() == IVL_VT_REAL ) &&
!prts.empty() && (prts[0]->data_type() != IVL_VT_REAL )) {
cerr << pins[idx]->get_fileline() << ": error: "
<< "Cannot automatically connect bit based "
"inout port " << rmod->ports[idx]->name
<< " of module " << rmod->mod_name() << " to real "
"signal " << sig->name() << "." << endl;
des->errors += 1;
continue;
}
// We do not support real inout ports at all.
if (!prts.empty() && (prts[0]->data_type() == IVL_VT_REAL )) {
cerr << pins[idx]->get_fileline() << ": error: "
<< "No support for connecting real inout ports ("
"port "
<< rmod->ports[idx]->name << " of module "
<< rmod->mod_name() << ")." << endl;
des->errors += 1; des->errors += 1;
continue; continue;
} }
@ -1276,20 +1416,84 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
<< "Output port expression must support " << "Output port expression must support "
<< "continuous assignment." << endl; << "continuous assignment." << endl;
cerr << pins[idx]->get_fileline() << ": : " cerr << pins[idx]->get_fileline() << ": : "
<< "Port of " << rmod->mod_name() << "Port " << rmod->ports[idx]->name << " of "
<< " is " << rmod->ports[idx]->name << endl; << rmod->mod_name() << " is connected to "
<< *pins[idx] << endl;
des->errors += 1;
continue;
}
// If we have a real port driving a bit/vector signal
// then we convert the real value using the appropriate
// width cast. Since a real is only one bit the whole
// thing needs to go to each instance when arrayed.
if ((sig->data_type() != IVL_VT_REAL ) &&
!prts.empty() && (prts[0]->data_type() == IVL_VT_REAL )) {
if (sig->vector_width() % instance.size() != 0) {
cerr << pins[idx]->get_fileline() << ": error: "
"When automatically converting a real "
"port of an arrayed instance to a bit "
"signal" << endl;
cerr << pins[idx]->get_fileline() << ": : "
"the signal width ("
<< sig->vector_width() << ") must be an "
"integer multiple of the instance count ("
<< instance.size() << ")." << endl;
des->errors += 1;
continue;
}
prts_vector_width = sig->vector_width();
for (unsigned pidx = 0; pidx < prts.size(); pidx += 1) {
prts[pidx]->port_type(NetNet::NOT_A_PORT);
prts[pidx] = cast_to_int(des, scope, prts[idx],
prts_vector_width /
instance.size());
prts[pidx]->port_type(NetNet::POUTPUT);
}
}
// If we have a bit/vector port driving a single real
// signal then we convert the value to a real.
if ((sig->data_type() == IVL_VT_REAL ) &&
!prts.empty() && (prts[0]->data_type() != IVL_VT_REAL )) {
prts_vector_width -= prts[0]->vector_width() - 1;
prts[0]->port_type(NetNet::NOT_A_PORT);
prts[0] = cast_to_real(des, scope, prts[0]);
prts[0]->port_type(NetNet::POUTPUT);
// No support for multiple real drivers.
if (instance.size() != 1) {
cerr << pins[idx]->get_fileline() << ": error: "
<< "Cannot connect an arrayed instance of "
"module " << rmod->mod_name() << " to "
"real signal " << sig->name() << "."
<< endl;
des->errors += 1;
continue;
}
}
// A real to real connection is not allowed for arrayed
// instances. You cannot have multiple real drivers.
if ((sig->data_type() == IVL_VT_REAL ) &&
!prts.empty() && (prts[0]->data_type() == IVL_VT_REAL ) &&
instance.size() != 1) {
cerr << pins[idx]->get_fileline() << ": error: "
<< "An arrayed instance of " << rmod->mod_name()
<< " cannot have a real port ("
<< rmod->ports[idx]->name << ") connected to a "
"real signal (" << sig->name() << ")." << endl;
des->errors += 1; des->errors += 1;
continue; continue;
} }
} }
assert(sig); ivl_assert(*this, sig);
#ifndef NDEBUG #ifndef NDEBUG
if ((prts.size() >= 1) if ((prts.size() >= 1)
&& (prts[0]->port_type() != NetNet::PINPUT)) { && (prts[0]->port_type() != NetNet::PINPUT)) {
assert(sig->type() != NetNet::REG); ivl_assert(*this, sig->type() != NetNet::REG);
} }
#endif #endif
@ -1364,7 +1568,11 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
<< " high bits of the port." << " high bits of the port."
<< endl; << endl;
} else { } else {
cerr << get_fileline() << ": : Padding "; if (prts[0]->port_type() == NetNet::PINPUT) {
cerr << get_fileline() << ": : Pruning ";
} else {
cerr << get_fileline() << ": : Padding ";
}
if (as_signed) cerr << "(signed) "; if (as_signed) cerr << "(signed) ";
cerr << (sig->vector_width()-prts_vector_width) cerr << (sig->vector_width()-prts_vector_width)
<< " high bits of the expression." << " high bits of the expression."
@ -1390,14 +1598,6 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
if (instance.size() == 1 && sig->vector_width() < ccount) if (instance.size() == 1 && sig->vector_width() < ccount)
ccount = sig->vector_width(); ccount = sig->vector_width();
// The spin_modulus is the width of the signal (not the
// port) if this is an instance array. This causes
// signals wide enough for a single instance to be
// connected to all the instances.
unsigned spin_modulus = prts_vector_width;
if (instance.size() != 1)
spin_modulus = sig->vector_width();
// Now scan the concatenation that makes up the port, // Now scan the concatenation that makes up the port,
// connecting pins until we run out of port pins or sig // connecting pins until we run out of port pins or sig
// pins. The sig object is the NetNet that is connected // pins. The sig object is the NetNet that is connected
@ -1515,43 +1715,34 @@ void PGModule::elaborate_udp_(Design*des, PUdp*udp, NetScope*scope) const
module or primitive, it interprets them as parameter module or primitive, it interprets them as parameter
overrides. Correct that misconception here. */ overrides. Correct that misconception here. */
if (overrides_) { if (overrides_) {
PDelays tmp_del; if (overrides_->count() > 2) {
tmp_del.set_delays(overrides_, false); cerr << get_fileline() << ": error: UDPs take at most two "
tmp_del.eval_delays(des, scope, rise_expr, fall_expr, decay_expr); "delay arguments." << endl;
if (dynamic_cast<NetEConst*> (rise_expr)) {
} else {
cerr << get_fileline() << ": error: Delay expressions must be "
<< "constant for primitives." << endl;
cerr << get_fileline() << ": : Cannot calculate "
<< *rise_expr << endl;
des->errors += 1; des->errors += 1;
}
if (dynamic_cast<NetEConst*> (fall_expr)) {
} else { } else {
cerr << get_fileline() << ": error: Delay expressions must be " PDelays tmp_del;
<< "constant for primitives." << endl; tmp_del.set_delays(overrides_, false);
cerr << get_fileline() << ": : Cannot calculate " tmp_del.eval_delays(des, scope, rise_expr, fall_expr,
<< *rise_expr << endl; decay_expr);
des->errors += 1;
if (! dynamic_cast<NetEConst*> (rise_expr)) {
cerr << get_fileline() << ": error: UDP rising delay "
"expression must be constant." << endl;
cerr << get_fileline() << ": : Cannot calculate "
<< *rise_expr << endl;
des->errors += 1;
}
if (! dynamic_cast<NetEConst*> (fall_expr)) {
cerr << get_fileline() << ": error: UDP falling delay "
"expression must be constant." << endl;
cerr << get_fileline() << ": : Cannot calculate "
<< *fall_expr << endl;
des->errors += 1;
}
} }
if (dynamic_cast<NetEConst*> (decay_expr)) {
} else {
cerr << get_fileline() << ": error: Delay expressions must be "
<< "constant for primitives." << endl;
cerr << get_fileline() << ": : Cannot calculate "
<< *rise_expr << endl;
des->errors += 1;
}
} }
assert(udp); assert(udp);
NetUDP*net = new NetUDP(scope, my_name, udp->ports.count(), udp); NetUDP*net = new NetUDP(scope, my_name, udp->ports.count(), udp);
net->rise_time(rise_expr); net->rise_time(rise_expr);
@ -1668,6 +1859,7 @@ void PGModule::elaborate_udp_(Design*des, PUdp*udp, NetScope*scope) const
if (pins[idx] == 0) if (pins[idx] == 0)
continue; continue;
probe_expr_width(des, scope, pins[idx]);
NetExpr*expr_tmp = elab_and_eval(des, scope, pins[idx], 1, 1); NetExpr*expr_tmp = elab_and_eval(des, scope, pins[idx], 1, 1);
if (expr_tmp == 0) { if (expr_tmp == 0) {
cerr << "internal error: Expression too complicated " cerr << "internal error: Expression too complicated "
@ -1815,6 +2007,20 @@ static NetExpr*elaborate_delay_expr(PExpr*expr, Design*des, NetScope*scope)
probe_expr_width(des, scope, expr); probe_expr_width(des, scope, expr);
NetExpr*dex = elab_and_eval(des, scope, expr, -1); NetExpr*dex = elab_and_eval(des, scope, expr, -1);
/* Print a warning if we find default and `timescale based
* delays in the design, since this is likely an error. */
if (scope->time_from_timescale()) dly_used_timescale = true;
else dly_used_no_timescale = true;
if (display_ts_dly_warning &&
dly_used_no_timescale && dly_used_timescale) {
cerr << "warning: Found both default and "
"`timescale based delays. Use" << endl;
cerr << " -Wtimescale to find the "
"module(s) with no `timescale." << endl;
display_ts_dly_warning = false;
}
/* If the delay expression is a real constant or vector /* If the delay expression is a real constant or vector
constant, then evaluate it, scale it to the local time constant, then evaluate it, scale it to the local time
units, and return an adjusted NetEConst. */ units, and return an adjusted NetEConst. */
@ -2583,11 +2789,22 @@ NetProc* PCallTask::elaborate_usr(Design*des, NetScope*scope) const
ivl_variable_type_t lv_type = lv->expr_type(); ivl_variable_type_t lv_type = lv->expr_type();
NetExpr*rv = elaborate_rval_expr(des, scope, lv_type, wid, parms_[idx]); NetExpr*rv = elaborate_rval_expr(des, scope, lv_type, wid, parms_[idx]);
if (wid > rv->expr_width()) { if (NetEEvent*evt = dynamic_cast<NetEEvent*> (rv)) {
rv->set_width(wid); cerr << evt->get_fileline() << ": error: An event '"
rv = pad_to_width(rv, wid, *this); << evt->event()->name() << "' can not be a user "
"task argument." << endl;
des->errors += 1;
continue;
}
/* Don't pad real values, they will be converted in the
* assignment below. */
if (rv->expr_type() != IVL_VT_REAL) {
if (wid > rv->expr_width()) {
rv->set_width(wid);
rv = pad_to_width(rv, wid, *this);
}
ivl_assert(*this, rv->expr_width() >= wid);
} }
ivl_assert(*this, rv->expr_width() >= wid);
NetAssign*pr = new NetAssign(lv, rv); NetAssign*pr = new NetAssign(lv, rv);
block->append(pr); block->append(pr);
@ -2939,10 +3156,20 @@ NetProc* PEventStatement::elaborate_st(Design*des, NetScope*scope,
} }
if (nset->count() == 0) { if (nset->count() == 0) {
cerr << get_fileline() << ": error: No inputs to statement." cerr << get_fileline() << ": warning: @* found no "
<< " The @* cannot execute." << endl; "sensitivities so it will never trigger."
des->errors += 1; << endl;
return enet; /* Add the currently unreferenced event to the scope. */
scope->add_event(ev);
/* Delete the current wait, create a new one with no
* statement and add the event to it. This creates a
* perpetual wait since nothing will ever trigger the
* unreferenced event. */
delete wa;
wa = new NetEvWait(0);
wa->set_line(*this);
wa->add_event(ev);
return wa;
} }
NetEvProbe*pr = new NetEvProbe(scope, scope->local_symbol(), NetEvProbe*pr = new NetEvProbe(scope, scope->local_symbol(),
@ -2975,6 +3202,25 @@ NetProc* PEventStatement::elaborate_st(Design*des, NetScope*scope,
if (found_in && eve) { if (found_in && eve) {
wa->add_event(eve); wa->add_event(eve);
/* You can not look for the posedge or negedge of
* an event. */
if (expr_[idx]->type() != PEEvent::ANYEDGE) {
cerr << get_fileline() << ": error: ";
switch (expr_[idx]->type()) {
case PEEvent::POSEDGE:
cerr << "posedge";
break;
case PEEvent::NEGEDGE:
cerr << "negedge";
break;
default:
cerr << "unknown edge type!";
assert(0);
}
cerr << " can not be used with a named event ("
<< eve->name() << ")." << endl;
des->errors += 1;
}
continue; continue;
} }
} }
@ -3041,6 +3287,7 @@ NetProc* PEventStatement::elaborate_st(Design*des, NetScope*scope,
break; break;
default: default:
pr = NULL;
assert(0); assert(0);
} }
@ -3516,6 +3763,7 @@ NetProc* PRepeat::elaborate(Design*des, NetScope*scope) const
{ {
assert(scope); assert(scope);
probe_expr_width(des, scope, expr_);
NetExpr*expr = elab_and_eval(des, scope, expr_, -1); NetExpr*expr = elab_and_eval(des, scope, expr_, -1);
if (expr == 0) { if (expr == 0) {
cerr << get_fileline() << ": Unable to elaborate" cerr << get_fileline() << ": Unable to elaborate"
@ -3716,15 +3964,26 @@ void PSpecPath::elaborate(Design*des, NetScope*scope) const
/* Do not elaborate specify delay paths if this feature is /* Do not elaborate specify delay paths if this feature is
turned off. */ turned off. */
if (!gn_specify_blocks_flag) if (!gn_specify_blocks_flag) return;
return;
ivl_assert(*this, conditional || (condition==0)); ivl_assert(*this, conditional || (condition==0));
ndelays = delays.size(); ndelays = delays.size();
if (ndelays > 12) if (ndelays > 12) ndelays = 12;
ndelays = 12;
/* Print a warning if we find default and `timescale based
* delays in the design, since this is likely an error. */
if (scope->time_from_timescale()) dly_used_timescale = true;
else dly_used_no_timescale = true;
if (display_ts_dly_warning &&
dly_used_no_timescale && dly_used_timescale) {
cerr << "warning: Found both default and "
"`timescale based delays. Use" << endl;
cerr << " -Wtimescale to find the "
"module(s) with no `timescale." << endl;
display_ts_dly_warning = false;
}
int shift = scope->time_unit() - des->get_precision(); int shift = scope->time_unit() - des->get_precision();
/* Elaborate the delay values themselves. Remember to scale /* Elaborate the delay values themselves. Remember to scale
@ -3780,6 +4039,38 @@ void PSpecPath::elaborate(Design*des, NetScope*scope) const
ivl_assert(*condition, condit_sig); ivl_assert(*condition, condit_sig);
} }
/* A parallel connection does not support more than a one to one
connection (source/destination). */
if (! full_flag && ((src.size() != 1) || (dst.size() != 1))) {
/* To be compatible with NC-Verilog we allow a parallel connection
* with multiple sources/destinations if all the paths are only a
* single bit wide (a scalar or a one bit vector). */
bool all_single = true;
typedef std::vector<perm_string>::const_iterator str_vec_iter;
for (str_vec_iter cur = src.begin();
( cur != src.end() && all_single); ++ cur) {
NetNet *psig = scope->find_signal(*cur);
/* We will report a missing signal as invalid later. For
* now assume it's a single bit. */
if (psig == 0) continue;
if (psig->vector_width() != 1) all_single = false;
}
for (str_vec_iter cur = dst.begin();
( cur != dst.end() && all_single); ++ cur) {
NetNet *psig = scope->find_signal(*cur);
/* The same as above for source paths. */
if (psig == 0) continue;
if (psig->vector_width() != 1) all_single = false;
}
if (! all_single) {
cerr << get_fileline() << ": error: Parallel connections "
"only support one source/destination path found ("
<< src.size() << "/" << dst.size() << ")." << endl;
des->errors += 1;
}
}
/* Create all the various paths from the path specifier. */ /* Create all the various paths from the path specifier. */
typedef std::vector<perm_string>::const_iterator str_vector_iter; typedef std::vector<perm_string>::const_iterator str_vector_iter;
for (str_vector_iter cur = dst.begin() for (str_vector_iter cur = dst.begin()
@ -3796,12 +4087,14 @@ void PSpecPath::elaborate(Design*des, NetScope*scope) const
NetNet*dst_sig = scope->find_signal(*cur); NetNet*dst_sig = scope->find_signal(*cur);
if (dst_sig == 0) { if (dst_sig == 0) {
cerr << get_fileline() << ": error: No such wire " cerr << get_fileline() << ": error: No wire '"
<< *cur << " in this module." << endl; << *cur << "' in this module." << endl;
des->errors += 1; des->errors += 1;
continue; continue;
} }
unsigned long dst_wid = dst_sig->vector_width();
if (dst_sig->port_type() != NetNet::POUTPUT if (dst_sig->port_type() != NetNet::POUTPUT
&& dst_sig->port_type() != NetNet::PINOUT) { && dst_sig->port_type() != NetNet::PINOUT) {
@ -3853,7 +4146,12 @@ void PSpecPath::elaborate(Design*des, NetScope*scope) const
for (str_vector_iter cur_src = src.begin() for (str_vector_iter cur_src = src.begin()
; cur_src != src.end() ; cur_src ++) { ; cur_src != src.end() ; cur_src ++) {
NetNet*src_sig = scope->find_signal(*cur_src); NetNet*src_sig = scope->find_signal(*cur_src);
assert(src_sig); if (src_sig == 0) {
cerr << get_fileline() << ": error: No wire '"
<< *cur_src << "' in this module." << endl;
des->errors += 1;
continue;
}
if (debug_elaborate) { if (debug_elaborate) {
if (cur_src != src.begin()) cerr << " and "; if (cur_src != src.begin()) cerr << " and ";
@ -3869,6 +4167,20 @@ void PSpecPath::elaborate(Design*des, NetScope*scope) const
des->errors += 1; des->errors += 1;
} }
// For a parallel connection the source and destination
// must be the same width.
if (! full_flag) {
unsigned long src_wid = src_sig->vector_width();
if (src_wid != dst_wid) {
cerr << get_fileline() << ": error: For a "
"parallel connection the "
"source/destination width must match "
"found (" << src_wid << "/" << dst_wid
<< ")." << endl;
des->errors += 1;
}
}
connect(src_sig->pin(0), path->pin(idx)); connect(src_sig->pin(0), path->pin(idx));
idx += 1; idx += 1;
} }
@ -3881,7 +4193,6 @@ void PSpecPath::elaborate(Design*des, NetScope*scope) const
dst_sig->add_delay_path(path); dst_sig->add_delay_path(path);
} }
} }
static void elaborate_functions(Design*des, NetScope*scope, static void elaborate_functions(Design*des, NetScope*scope,
@ -3921,49 +4232,50 @@ bool Module::elaborate(Design*des, NetScope*scope) const
bool result_flag = true; bool result_flag = true;
error_implicit = true; error_implicit = true;
if (gn_specify_blocks_flag) { // Elaborate specparams
// Elaborate specparams typedef map<perm_string,PExpr*>::const_iterator specparam_it_t;
typedef map<perm_string,PExpr*>::const_iterator specparam_it_t; for (specparam_it_t cur = specparams.begin() ;
for (specparam_it_t cur = specparams.begin() cur != specparams.end() ; cur ++ ) {
; cur != specparams.end() ; cur ++ ) {
need_constant_expr = true; probe_expr_width(des, scope, (*cur).second);
NetExpr*val = elab_and_eval(des, scope, (*cur).second, -1); need_constant_expr = true;
need_constant_expr = false; NetExpr*val = elab_and_eval(des, scope, (*cur).second, -1);
NetScope::spec_val_t value; need_constant_expr = false;
NetScope::spec_val_t value;
if (NetECReal*val_cr = dynamic_cast<NetECReal*> (val)) { if (NetECReal*val_cr = dynamic_cast<NetECReal*> (val)) {
value.type = IVL_VT_REAL; value.type = IVL_VT_REAL;
value.real_val = val_cr->value().as_double(); value.real_val = val_cr->value().as_double();
if (debug_elaborate) if (debug_elaborate) {
cerr << get_fileline() << ": debug: Elaborate " cerr << get_fileline() << ": debug: Elaborate "
<< "specparam " << (*cur).first << "specparam " << (*cur).first
<< " value=" << value.real_val << endl; << " value=" << value.real_val << endl;
} else if (NetEConst*val_c = dynamic_cast<NetEConst*> (val)) {
value.type = IVL_VT_BOOL;
value.integer = val_c->value().as_long();
if (debug_elaborate)
cerr << get_fileline() << ": debug: Elaborate "
<< "specparam " << (*cur).first
<< " value=" << value.integer << endl;
} else {
value.type = IVL_VT_NO_TYPE;
cerr << (*cur).second->get_fileline() << ": error: "
<< "specparam " << (*cur).first << " value"
<< " is not constant: " << *val << endl;
des->errors += 1;
} }
assert(val); } else if (NetEConst*val_c = dynamic_cast<NetEConst*> (val)) {
delete val;
scope->specparams[(*cur).first] = value; value.type = IVL_VT_BOOL;
value.integer = val_c->value().as_long();
if (debug_elaborate) {
cerr << get_fileline() << ": debug: Elaborate "
<< "specparam " << (*cur).first
<< " value=" << value.integer << endl;
}
} else {
value.type = IVL_VT_NO_TYPE;
cerr << (*cur).second->get_fileline() << ": error: "
<< "specparam " << (*cur).first << " value"
<< " is not constant: " << *val << endl;
des->errors += 1;
} }
assert(val);
delete val;
scope->specparams[(*cur).first] = value;
} }
// Elaborate within the generate blocks. // Elaborate within the generate blocks.
@ -4289,6 +4601,7 @@ Design* elaborate(list<perm_string>roots)
scope->set_line(rmod); scope->set_line(rmod);
scope->time_unit(rmod->time_unit); scope->time_unit(rmod->time_unit);
scope->time_precision(rmod->time_precision); scope->time_precision(rmod->time_precision);
scope->time_from_timescale(rmod->time_from_timescale);
scope->default_nettype(rmod->default_nettype); scope->default_nettype(rmod->default_nettype);
des->set_precision(rmod->time_precision); des->set_precision(rmod->time_precision);
@ -4308,14 +4621,17 @@ Design* elaborate(list<perm_string>roots)
des->elaboration_work_list.push_back(es); des->elaboration_work_list.push_back(es);
} }
// After the work items for the root scope elaboration, push a
// work item to process the defparams.
des->elaboration_work_list.push_back(new top_defparams(des));
// Run the work list of scope elaborations until the list is // Run the work list of scope elaborations until the list is
// empty. This list is initially populated above where the // empty. This list is initially populated above where the
// initial root scopes are primed. // initial root scopes are primed.
while (! des->elaboration_work_list.empty()) { while (! des->elaboration_work_list.empty()) {
// Push a work item to process the defparams of any scopes
// that are elaborated during this pass. For the first pass
// this will be all the root scopes. For subsequent passes
// it will be any scopes created during the previous pass
// by a generate construct or instance array.
des->elaboration_work_list.push_back(new top_defparams(des));
// Transfer the queue to a temporary queue. // Transfer the queue to a temporary queue.
list<elaborator_work_item_t*> cur_queue; list<elaborator_work_item_t*> cur_queue;
while (! des->elaboration_work_list.empty()) { while (! des->elaboration_work_list.empty()) {
@ -4369,6 +4685,7 @@ Design* elaborate(list<perm_string>roots)
NetScope *scope = root_elems[i]->scope; NetScope *scope = root_elems[i]->scope;
rc &= rmod->elaborate(des, scope); rc &= rmod->elaborate(des, scope);
delete root_elems[i];
} }
if (rc == false) { if (rc == false) {

View File

@ -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 * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -22,7 +22,7 @@
# include "PExpr.h" # include "PExpr.h"
# include "netlist.h" # include "netlist.h"
# include <iostream> # include <iostream>
# include <assert.h> # include <cassert>
/* /*
* The evaluate_attributes function evaluates the attribute * The evaluate_attributes function evaluates the attribute
@ -72,4 +72,3 @@ attrib_list_t* evaluate_attributes(const map<perm_string,PExpr*>&att,
assert(idx == natt); assert(idx == natt);
return table; return table;
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1999-2009 Stephen Williams (steve@icarus.com) * Copyright (c) 1999-2010 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -23,7 +23,7 @@
# include <iostream> # include <iostream>
# include <cstdlib> # include <cstdlib>
# include <cstring> # include <cstring>
# include <math.h> # include <cmath>
# include "netlist.h" # include "netlist.h"
# include "ivl_assert.h" # include "ivl_assert.h"
@ -133,7 +133,7 @@ NetExpr* NetEBAdd::eval_tree(int prune_to_width)
if (debug_eval_tree) { if (debug_eval_tree) {
cerr << get_fileline() << ": debug: " cerr << get_fileline() << ": debug: "
<< "Partially evalutate " << *this << "Partially evaluate " << *this
<< " using (a+2)-1 --> (a+1) transform." << endl; << " using (a+2)-1 --> (a+1) transform." << endl;
} }
@ -381,6 +381,7 @@ NetEConst* NetEBComp::eval_leeq_real_(NetExpr*le, NetExpr*ri, bool eq_flag)
break; break;
default: default:
lv = 0.0;
cerr << get_fileline() << ": internal error: " cerr << get_fileline() << ": internal error: "
<< "Unexpected expression type? " << le->expr_type() << endl; << "Unexpected expression type? " << le->expr_type() << endl;
assert(0); assert(0);
@ -401,6 +402,7 @@ NetEConst* NetEBComp::eval_leeq_real_(NetExpr*le, NetExpr*ri, bool eq_flag)
break; break;
default: default:
rv = 0.0;
cerr << get_fileline() << ": internal error: " cerr << get_fileline() << ": internal error: "
<< "Unexpected expression type? " << ri->expr_type() << endl; << "Unexpected expression type? " << ri->expr_type() << endl;
assert(0); assert(0);
@ -585,6 +587,7 @@ NetEConst* NetEBComp::eval_eqeq_real_(NetExpr*le, NetExpr*ri, bool ne_flag)
break; break;
default: default:
lv = 0.0;
cerr << get_fileline() << ": internal error: " cerr << get_fileline() << ": internal error: "
<< "Unexpected expression type? " << le->expr_type() << endl; << "Unexpected expression type? " << le->expr_type() << endl;
assert(0); assert(0);
@ -605,6 +608,7 @@ NetEConst* NetEBComp::eval_eqeq_real_(NetExpr*le, NetExpr*ri, bool ne_flag)
break; break;
default: default:
rv = 0.0;
cerr << get_fileline() << ": internal error: " cerr << get_fileline() << ": internal error: "
<< "Unexpected expression type? " << ri->expr_type() << endl; << "Unexpected expression type? " << ri->expr_type() << endl;
assert(0); assert(0);
@ -734,53 +738,61 @@ NetEConst* NetEBComp::eval_eqeq_(bool ne_flag)
return new NetEConst(verinum(res)); return new NetEConst(verinum(res));
} }
NetEConst* NetEBComp::eval_eqeqeq_() NetEConst* NetEBComp::eval_eqeqeq_(bool ne_flag)
{ {
NetEConst*l = dynamic_cast<NetEConst*>(left_); NetEConst*lc = dynamic_cast<NetEConst*>(left_);
if (l == 0) return 0; NetEConst*rc = dynamic_cast<NetEConst*>(right_);
NetEConst*r = dynamic_cast<NetEConst*>(right_); if (lc == 0 || rc == 0) return 0;
if (r == 0) return 0;
const verinum&lv = l->value(); const verinum&lv = lc->value();
const verinum&rv = r->value(); const verinum&rv = rc->value();
verinum::V res = verinum::V1; verinum::V res = verinum::V1;
// Find the smallest argument length.
unsigned cnt = lv.len(); unsigned cnt = lv.len();
if (cnt > rv.len()) if (cnt > rv.len()) cnt = rv.len();
cnt = rv.len();
// Check the common bits.
for (unsigned idx = 0 ; idx < cnt ; idx += 1) for (unsigned idx = 0 ; idx < cnt ; idx += 1)
if (lv.get(idx) != rv.get(idx)) if (lv.get(idx) != rv.get(idx)) {
res = verinum::V0; res = verinum::V0;
break;
}
for (unsigned idx = cnt ; idx < lv.len() ; idx += 1) bool is_signed = lv.has_sign() && rv.has_sign();
if (lv.get(idx) != verinum::V0)
res = verinum::V0;
for (unsigned idx = cnt ; idx < rv.len() ; idx += 1) // If the left value is longer check it against the pad bit.
if (rv.get(idx) != verinum::V0) if (res == verinum::V1) {
res = verinum::V0; verinum::V pad = verinum::V0;
if (is_signed) pad = rv.get(rv.len()-1);
for (unsigned idx = cnt ; idx < lv.len() ; idx += 1)
if (lv.get(idx) != pad) {
res = verinum::V0;
break;
}
}
return new NetEConst(verinum(res, 1)); // If the right value is longer check it against the pad bit.
} if (res == verinum::V1) {
verinum::V pad = verinum::V0;
if (is_signed) pad = lv.get(lv.len()-1);
for (unsigned idx = cnt ; idx < rv.len() ; idx += 1)
if (rv.get(idx) != pad) {
res = verinum::V0;
break;
}
}
NetEConst* NetEBComp::eval_neeqeq_() if (ne_flag) {
{ if (res == verinum::V0) res = verinum::V1;
NetEConst*tmp = eval_eqeqeq_(); else res = verinum::V0;
if (tmp == 0) }
return 0;
NetEConst*res; NetEConst*result = new NetEConst(verinum(res, 1));
ivl_assert(*this, result);
if (tmp->value().get(0) == verinum::V0) result->set_line(*this);
res = new NetEConst(verinum(verinum::V1,1)); return result;
else
res = new NetEConst(verinum(verinum::V0,1));
delete tmp;
res->set_line(*this);
return res;
} }
NetEConst* NetEBComp::eval_tree(int prune_to_width) NetEConst* NetEBComp::eval_tree(int prune_to_width)
@ -790,7 +802,7 @@ NetEConst* NetEBComp::eval_tree(int prune_to_width)
switch (op_) { switch (op_) {
case 'E': // Case equality (===) case 'E': // Case equality (===)
return eval_eqeqeq_(); return eval_eqeqeq_(false);
case 'e': // Equality (==) case 'e': // Equality (==)
return eval_eqeq_(false); return eval_eqeq_(false);
@ -802,7 +814,7 @@ NetEConst* NetEBComp::eval_tree(int prune_to_width)
return eval_leeq_(); return eval_leeq_();
case 'N': // Case inequality (!==) case 'N': // Case inequality (!==)
return eval_neeqeq_(); return eval_eqeqeq_(true);
case 'n': // not-equal (!=) case 'n': // not-equal (!=)
return eval_eqeq_(true); return eval_eqeq_(true);
@ -854,7 +866,7 @@ NetExpr* NetEBDiv::eval_tree(int prune_to_width)
eval_expr(right_); eval_expr(right_);
if (expr_type() == IVL_VT_REAL) return eval_tree_real_(); if (expr_type() == IVL_VT_REAL) return eval_tree_real_();
assert(expr_type() == IVL_VT_LOGIC); assert(expr_type() == IVL_VT_LOGIC);
NetEConst*lc = dynamic_cast<NetEConst*>(left_); NetEConst*lc = dynamic_cast<NetEConst*>(left_);
@ -880,11 +892,57 @@ NetExpr* NetEBDiv::eval_tree(int prune_to_width)
return tmp; return tmp;
} }
NetEConst* NetEBLogic::eval_tree_real_()
{
verireal lval;
verireal rval;
bool flag = get_real_arguments_(lval, rval);
if (! flag) return 0;
verinum::V res;
switch (op_) {
case 'a': { // Logical AND (&&)
if ((lval.as_double() != 0.0) && (rval.as_double() != 0.0))
res = verinum::V1;
else
res = verinum::V0;
break;
}
case 'o': { // Logical OR (||)
if ((lval.as_double() != 0.0) || (rval.as_double() != 0.0))
res = verinum::V1;
else
res = verinum::V0;
break;
}
default:
return 0;
}
NetEConst*tmp = new NetEConst(verinum(res, 1));
ivl_assert(*this, tmp);
tmp->set_line(*this);
if (debug_eval_tree)
cerr << get_fileline() << ": debug: Evaluated (real): " << *this
<< " --> " << *tmp << endl;
return tmp;
}
NetEConst* NetEBLogic::eval_tree(int prune_to_width) NetEConst* NetEBLogic::eval_tree(int prune_to_width)
{ {
eval_expr(left_); eval_expr(left_);
eval_expr(right_); eval_expr(right_);
if (left_->expr_type() == IVL_VT_REAL ||
right_->expr_type() == IVL_VT_REAL)
return eval_tree_real_();
assert(expr_type() == IVL_VT_LOGIC);
NetEConst*lc = dynamic_cast<NetEConst*>(left_); NetEConst*lc = dynamic_cast<NetEConst*>(left_);
NetEConst*rc = dynamic_cast<NetEConst*>(right_); NetEConst*rc = dynamic_cast<NetEConst*>(right_);
if (lc == 0 || rc == 0) return 0; if (lc == 0 || rc == 0) return 0;
@ -894,57 +952,61 @@ NetEConst* NetEBLogic::eval_tree(int prune_to_width)
verinum v = lc->value(); verinum v = lc->value();
for (unsigned idx = 0 ; idx < v.len() ; idx += 1) for (unsigned idx = 0 ; idx < v.len() ; idx += 1)
if (v.get(idx) == verinum::V1) if (v.get(idx) == verinum::V1) {
lv = verinum::V1; lv = verinum::V1;
break;
}
if (lv == verinum::V0) if (lv == verinum::V0 && ! v.is_defined()) lv = verinum::Vx;
for (unsigned idx = 0 ; idx < v.len() ; idx += 1)
if (v.get(idx) != verinum::V0)
lv = verinum::Vx;
v = rc->value(); v = rc->value();
for (unsigned idx = 0 ; idx < v.len() ; idx += 1) for (unsigned idx = 0 ; idx < v.len() ; idx += 1)
if (v.get(idx) == verinum::V1) if (v.get(idx) == verinum::V1) {
rv = verinum::V1; rv = verinum::V1;
break;
}
if (rv == verinum::V0) if (rv == verinum::V0 && ! v.is_defined()) rv = verinum::Vx;
for (unsigned idx = 0 ; idx < v.len() ; idx += 1)
if (v.get(idx) != verinum::V0)
rv = verinum::Vx;
verinum::V res; verinum::V res;
switch (op_) { switch (op_) {
case 'a': { // Logical AND (&&) case 'a': // Logical AND (&&)
if ((lv == verinum::V0) || (rv == verinum::V0)) if ((lv == verinum::V0) || (rv == verinum::V0))
res = verinum::V0; res = verinum::V0;
else if ((lv == verinum::V1) && (rv == verinum::V1)) else if ((lv == verinum::V1) && (rv == verinum::V1))
res = verinum::V1; res = verinum::V1;
else else
res = verinum::Vx; res = verinum::Vx;
break; break;
}
case 'o': { // Logical OR (||) case 'o': // Logical OR (||)
if ((lv == verinum::V1) || (rv == verinum::V1)) if ((lv == verinum::V1) || (rv == verinum::V1))
res = verinum::V1; res = verinum::V1;
else if ((lv == verinum::V0) && (rv == verinum::V0)) else if ((lv == verinum::V0) && (rv == verinum::V0))
res = verinum::V0; res = verinum::V0;
else else
res = verinum::Vx; res = verinum::Vx;
break; break;
}
default: default:
return 0; return 0;
} }
return new NetEConst(verinum(res, 1)); NetEConst*tmp = new NetEConst(verinum(res, 1));
ivl_assert(*this, tmp);
tmp->set_line(*this);
if (debug_eval_tree)
cerr << get_fileline() << ": debug: Evaluated: " << *this
<< " --> " << *tmp << endl;
return tmp;
} }
@ -996,6 +1058,11 @@ NetExpr* NetEBPow::eval_tree_real_()
NetECReal*res = new NetECReal( pow(lval,rval) ); NetECReal*res = new NetECReal( pow(lval,rval) );
res->set_line(*this); res->set_line(*this);
if (debug_eval_tree)
cerr << get_fileline() << ": debug: Evaluate (real) "
<< lval << " ** " << rval << " --> " << *res << endl;
return res; return res;
} }
@ -1016,7 +1083,14 @@ NetExpr* NetEBPow::eval_tree(int prune_to_width)
verinum lval = lc->value(); verinum lval = lc->value();
verinum rval = rc->value(); verinum rval = rc->value();
return new NetEConst( pow(lval,rval) ); NetEConst*res = new NetEConst( pow(lval,rval) );
res->set_line(*this);
if (debug_eval_tree)
cerr << get_fileline() << ": debug: Evaluate "
<< lval << " ** " << rval << " --> " << *res << endl;
return res;
} }
/* /*
@ -1161,16 +1235,6 @@ NetEConst* NetEConcat::eval_tree(int prune_to_width)
if (local_errors > 0) return 0; if (local_errors > 0) return 0;
// Handle the special case that the repeat expression is
// zero. In this case, just return a 0 value with the expected
// width.
if (repeat_val == 0) {
verinum val (verinum::V0, expr_width());
NetEConst*res = new NetEConst(val);
res->set_width(val.len());
return res;
}
// At this point, the "gap" is the width of a single repeat of // At this point, the "gap" is the width of a single repeat of
// the concatenation. The total width of the result is the gap // the concatenation. The total width of the result is the gap
// times the repeat count. // times the repeat count.
@ -1222,38 +1286,52 @@ NetExpr* NetEParam::eval_tree(int prune_to_width)
<< *this << endl; << *this << endl;
} }
if (solving()) {
cerr << get_fileline() << ": warning: Recursive parameter "
"reference found involving " << *this << "." << endl;
return 0;
}
assert(scope_); assert(scope_);
perm_string name = (*reference_).first; perm_string name = (*reference_).first;
const NetExpr*expr = (*reference_).second.expr; const NetExpr*expr = (*reference_).second.expr;
ivl_assert(*this, expr); // Since constant user functions are not supported we can get
// parameters/localparams that are not defined. For now generate
NetExpr*nexpr = expr->dup_expr(); // an appropriate error message.
assert(nexpr); if (expr == NULL) {
cerr << get_fileline() << ": internal error: parameter/localparam "
<< *this << " cannot be evaluated." << endl;
return 0;
}
// If the parameter that I refer to is already evaluated, then // If the parameter that I refer to is already evaluated, then
// return the constant value. // return the constant value.
if (NetEConst*tmp = dynamic_cast<NetEConst*>(nexpr)) { if (const NetEConst*tmp = dynamic_cast<const NetEConst*>(expr)) {
verinum val = tmp->value(); verinum val = tmp->value();
NetEConstParam*ptmp = new NetEConstParam(scope_, name, val); NetEConstParam*ptmp = new NetEConstParam(scope_, name, val);
ptmp->set_line(*this); ptmp->set_line(*this);
delete nexpr;
return ptmp; return ptmp;
} }
if (NetECReal*tmp = dynamic_cast<NetECReal*>(nexpr)) { if (const NetECReal*tmp = dynamic_cast<const NetECReal*>(expr)) {
verireal val = tmp->value(); verireal val = tmp->value();
NetECRealParam*ptmp = new NetECRealParam(scope_, name, val); NetECRealParam*ptmp = new NetECRealParam(scope_, name, val);
ptmp->set_line(*this); ptmp->set_line(*this);
delete nexpr;
return ptmp; return ptmp;
} }
// Try to evaluate the expression. If I cannot, then the // Try to evaluate the expression. If I cannot, then the
// expression is not a constant expression and I fail here. // expression is not a constant expression and I fail here.
solving(true);
NetExpr*nexpr = expr->dup_expr();
assert(nexpr);
NetExpr*res = nexpr->eval_tree(); NetExpr*res = nexpr->eval_tree();
solving(false);
if (res == 0) { if (res == 0) {
cerr << get_fileline() << ": internal error: Unable to evaluate " cerr << get_fileline() << ": internal error: Unable to evaluate ";
<< "parameter " << name << " expression: " if (expr_type() == IVL_VT_REAL) cerr << "real ";
cerr << "parameter " << name << " expression: "
<< *nexpr << endl; << *nexpr << endl;
delete nexpr; delete nexpr;
return 0; return 0;
@ -1583,9 +1661,25 @@ NetExpr* NetEUBits::eval_tree(int prune_to_width)
return NetEUnary::eval_tree(prune_to_width); return NetEUnary::eval_tree(prune_to_width);
} }
NetEConst* NetEUReduce::eval_tree_real_()
{
ivl_assert(*this, op_ == '!');
NetECReal*val= dynamic_cast<NetECReal*> (expr_);
if (val == 0) return 0;
verinum::V res = val->value().as_double() == 0.0 ? verinum::V1 :
verinum::V0;
return new NetEConst(verinum(res, 1));
}
NetEConst* NetEUReduce::eval_tree(int prune_to_width) NetEConst* NetEUReduce::eval_tree(int prune_to_width)
{ {
eval_expr(expr_); eval_expr(expr_);
if (expr_type() == IVL_VT_REAL) return eval_tree_real_();
NetEConst*rval = dynamic_cast<NetEConst*>(expr_); NetEConst*rval = dynamic_cast<NetEConst*>(expr_);
if (rval == 0) return 0; if (rval == 0) return 0;
@ -1713,6 +1807,7 @@ NetExpr* evaluate_clog2(NetExpr*&arg_)
res = integer_width; res = integer_width;
verinum tmp (res, integer_width); verinum tmp (res, integer_width);
tmp.has_sign(true);
NetEConst*rtn = new NetEConst(tmp); NetEConst*rtn = new NetEConst(tmp);
return rtn; return rtn;
} }
@ -1735,8 +1830,6 @@ NetExpr* evaluate_math_one_arg(NetExpr*&arg_, const char*name)
if (strcmp(name, "$ln") == 0) { if (strcmp(name, "$ln") == 0) {
return new NetECReal(verireal(log(arg))); return new NetECReal(verireal(log(arg)));
} else if (strcmp(name, "$log") == 0) {
return new NetECReal(verireal(log10(arg)));
} else if (strcmp(name, "$log10") == 0) { } else if (strcmp(name, "$log10") == 0) {
return new NetECReal(verireal(log10(arg))); return new NetECReal(verireal(log10(arg)));
} else if (strcmp(name, "$exp") == 0) { } else if (strcmp(name, "$exp") == 0) {
@ -1934,18 +2027,14 @@ NetExpr* NetESFunc::eval_tree(int prune_to_width)
} }
if ((gn_icarus_misc_flag || gn_verilog_ams_flag) && if ((gn_icarus_misc_flag || gn_verilog_ams_flag) &&
(strcmp(nm, "$log") == 0 || strcmp(nm, "$abs") == 0)) { (strcmp(nm, "$abs") == 0)) {
if (nparms() != 1 || parm(0) == 0) { if (nparms() != 1 || parm(0) == 0) {
cerr << get_fileline() << ": error: " << nm cerr << get_fileline() << ": error: " << nm
<< " takes a single argument." << endl; << " takes a single argument." << endl;
return 0; return 0;
} }
NetExpr*arg = parm(0)->dup_expr(); NetExpr*arg = parm(0)->dup_expr();
if (strcmp(nm, "$log") == 0) { rtn = evaluate_abs(arg);
rtn = evaluate_math_one_arg(arg, nm);
} else {
rtn = evaluate_abs(arg);
}
delete arg; delete arg;
} }

File diff suppressed because it is too large Load Diff

View File

@ -55,12 +55,12 @@
module register (out, val, clk, oe); module register (out, val, clk, oe);
output [7:0] out; output [7:0] out;
input [7:0] val; input [7:0] val;
input clk, oe; 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); bufif0 drv[7:0](out, Q, oe);

View File

@ -252,7 +252,7 @@ endmodule // sqrt32
module main; module main;
reg [31:0] x; reg [31:0] x;
reg clk, reset; reg clk, reset;
wire [15:0] y; wire [15:0] y;
wire rdy; wire rdy;
@ -354,7 +354,7 @@ module chip_root(clk, rdy, reset, x, y);
input [31:0] x; input [31:0] x;
output [15:0] y; output [15:0] y;
wire clk_int; wire clk_int;
(* cellref="BUFG:O,I" *) (* cellref="BUFG:O,I" *)
buf gbuf (clk_int, clk); buf gbuf (clk_int, clk);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1999-2009 Stephen Williams (steve@icarus.com) * Copyright (c) 1999-2010 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -122,6 +122,7 @@ NetNet* NetEBAdd::synthesize(Design*des, NetScope*scope, NetExpr*root)
NetNet*osig = new NetNet(lsig->scope(), path, NetNet::IMPLICIT, width); NetNet*osig = new NetNet(lsig->scope(), path, NetNet::IMPLICIT, width);
osig->local_flag(true); osig->local_flag(true);
osig->data_type(expr_type()); osig->data_type(expr_type());
osig->set_signed(has_sign());
perm_string oname = osig->scope()->local_symbol(); perm_string oname = osig->scope()->local_symbol();
NetAddSub *adder = new NetAddSub(lsig->scope(), oname, width); NetAddSub *adder = new NetAddSub(lsig->scope(), oname, width);
@ -199,6 +200,7 @@ NetNet* NetEBBits::synthesize(Design*des, NetScope*scope, NetExpr*root)
gate = new NetLogic(scope, oname, 3, NetLogic::XNOR, width); gate = new NetLogic(scope, oname, 3, NetLogic::XNOR, width);
break; break;
default: default:
gate = NULL;
assert(0); assert(0);
} }
@ -390,6 +392,7 @@ NetNet* NetEBPow::synthesize(Design*des, NetScope*scope, NetExpr*root)
NetNet::IMPLICIT, width); NetNet::IMPLICIT, width);
osig->set_line(*this); osig->set_line(*this);
osig->data_type(expr_type()); osig->data_type(expr_type());
osig->set_signed(has_sign());
osig->local_flag(true); osig->local_flag(true);
connect(powr->pin_Result(), osig->pin(0)); connect(powr->pin_Result(), osig->pin(0));
@ -426,6 +429,7 @@ NetNet* NetEBMult::synthesize(Design*des, NetScope*scope, NetExpr*root)
NetNet::IMPLICIT, width); NetNet::IMPLICIT, width);
osig->set_line(*this); osig->set_line(*this);
osig->data_type(expr_type()); osig->data_type(expr_type());
osig->set_signed(has_sign());
osig->local_flag(true); osig->local_flag(true);
connect(mult->pin_Result(), osig->pin(0)); connect(mult->pin_Result(), osig->pin(0));
@ -601,8 +605,8 @@ NetNet* NetEBShift::synthesize(Design*des, NetScope*scope, NetExpr*root)
return 0; return 0;
} }
const bool right_flag = op_ == 'r' || op_ == 'R'; const bool right_flag = op_ == 'r' || op_ == 'R';
const bool signed_flag = op_ == 'R'; const bool signed_flag = has_sign() && op_ == 'R';
/* Detect the special case where the shift amount is /* Detect the special case where the shift amount is
constant. Evaluate the shift amount, and simply reconnect constant. Evaluate the shift amount, and simply reconnect
@ -719,28 +723,42 @@ NetNet* NetEBShift::synthesize(Design*des, NetScope*scope, NetExpr*root)
NetNet* NetEConcat::synthesize(Design*des, NetScope*scope, NetExpr*root) NetNet* NetEConcat::synthesize(Design*des, NetScope*scope, NetExpr*root)
{ {
/* First, synthesize the operands. */ /* First, synthesize the operands. */
unsigned num_parms = parms_.count();
NetNet**tmp = new NetNet*[parms_.count()]; NetNet**tmp = new NetNet*[parms_.count()];
bool flag = true; bool flag = true;
ivl_variable_type_t data_type = IVL_VT_NO_TYPE;
for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) { for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) {
tmp[idx] = parms_[idx]->synthesize(des, scope, root); if (parms_[idx]->expr_width() == 0) {
if (tmp[idx] == 0) /* We need to synthesize a replication of zero. */
flag = false; tmp[idx] = parms_[idx]->synthesize(des, scope, root);
assert(tmp[idx] == 0);
num_parms -= 1;
} else {
tmp[idx] = parms_[idx]->synthesize(des, scope, root);
if (tmp[idx] == 0) flag = false;
/* Set the data type to the first one found. */
if (data_type == IVL_VT_NO_TYPE) {
data_type = tmp[idx]->data_type();
}
}
} }
if (flag == false) if (flag == false) return 0;
return 0;
ivl_assert(*this, tmp[0]); ivl_assert(*this, data_type != IVL_VT_NO_TYPE);
/* If this is a replication of zero just return 0. */
if (expr_width() == 0) return 0;
/* Make a NetNet object to carry the output vector. */ /* Make a NetNet object to carry the output vector. */
perm_string path = scope->local_symbol(); perm_string path = scope->local_symbol();
NetNet*osig = new NetNet(scope, path, NetNet::IMPLICIT, expr_width()); NetNet*osig = new NetNet(scope, path, NetNet::IMPLICIT, expr_width());
osig->local_flag(true); osig->local_flag(true);
osig->data_type(tmp[0]->data_type()); osig->data_type(data_type);
NetConcat*concat = new NetConcat(scope, scope->local_symbol(), NetConcat*concat = new NetConcat(scope, scope->local_symbol(),
osig->vector_width(), osig->vector_width(),
parms_.count() * repeat()); num_parms * repeat());
concat->set_line(*this); concat->set_line(*this);
des->add_node(concat); des->add_node(concat);
connect(concat->pin(0), osig->pin(0)); connect(concat->pin(0), osig->pin(0));
@ -750,7 +768,7 @@ NetNet* NetEConcat::synthesize(Design*des, NetScope*scope, NetExpr*root)
for (unsigned rpt = 0; rpt < repeat(); rpt += 1) { for (unsigned rpt = 0; rpt < repeat(); rpt += 1) {
for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) { for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) {
unsigned concat_item = parms_.count()-idx-1; unsigned concat_item = parms_.count()-idx-1;
ivl_assert(*this, tmp[concat_item]); if (tmp[concat_item] == 0) continue;
connect(concat->pin(cur_pin), tmp[concat_item]->pin(0)); connect(concat->pin(cur_pin), tmp[concat_item]->pin(0));
cur_pin += 1; cur_pin += 1;
count_input_width += tmp[concat_item]->vector_width(); count_input_width += tmp[concat_item]->vector_width();
@ -773,6 +791,11 @@ NetNet* NetEConst::synthesize(Design*des, NetScope*scope, NetExpr*)
{ {
perm_string path = scope->local_symbol(); perm_string path = scope->local_symbol();
unsigned width=expr_width(); unsigned width=expr_width();
if (width == 0) {
cerr << get_fileline() << ": internal error: "
<< "Found a zero width constant!" << endl;
return 0;
}
NetNet*osig = new NetNet(scope, path, NetNet::IMPLICIT, width); NetNet*osig = new NetNet(scope, path, NetNet::IMPLICIT, width);
osig->local_flag(true); osig->local_flag(true);
@ -841,6 +864,7 @@ NetNet* NetEUBits::synthesize(Design*des, NetScope*scope, NetExpr*root)
gate = new NetLogic(scope, oname, 2, NetLogic::NOT, width); gate = new NetLogic(scope, oname, 2, NetLogic::NOT, width);
break; break;
default: default:
gate = NULL;
assert(0); assert(0);
} }
@ -883,7 +907,7 @@ NetNet* NetEUnary::synthesize(Design*des, NetScope*scope, NetExpr*root)
return sig; return sig;
} }
cerr << get_fileline() << ": iternal error: " cerr << get_fileline() << ": internal error: "
<< "NetEUnary::synthesize cannot handle op_=" << op_ << endl; << "NetEUnary::synthesize cannot handle op_=" << op_ << endl;
des->errors += 1; des->errors += 1;
return expr_->synthesize(des, scope, root); return expr_->synthesize(des, scope, root);
@ -909,11 +933,6 @@ NetNet* NetEUReduce::synthesize(Design*des, NetScope*scope, NetExpr*root)
return 0; return 0;
} }
NetNet*osig = new NetNet(scope, scope->local_symbol(),
NetNet::IMPLICIT, 1);
osig->data_type(expr_type());
osig->local_flag(true);
NetUReduce::TYPE rtype = NetUReduce::NONE; NetUReduce::TYPE rtype = NetUReduce::NONE;
switch (op()) { switch (op()) {
@ -944,8 +963,13 @@ NetNet* NetEUReduce::synthesize(Design*des, NetScope*scope, NetExpr*root)
NetUReduce*gate = new NetUReduce(scope, scope->local_symbol(), NetUReduce*gate = new NetUReduce(scope, scope->local_symbol(),
rtype, isig->vector_width()); rtype, isig->vector_width());
des->add_node(gate); des->add_node(gate);
NetNet*osig = new NetNet(scope, scope->local_symbol(),
NetNet::IMPLICIT, 1);
osig->data_type(expr_type());
osig->local_flag(true);
connect(gate->pin(0), osig->pin(0)); connect(gate->pin(0), osig->pin(0));
for (unsigned idx = 0 ; idx < isig->pin_count() ; idx += 1) for (unsigned idx = 0 ; idx < isig->pin_count() ; idx += 1)
connect(gate->pin(1+idx), isig->pin(idx)); connect(gate->pin(1+idx), isig->pin(idx));
@ -1024,6 +1048,7 @@ NetNet* NetESelect::synthesize(Design *des, NetScope*scope, NetExpr*root)
NetPartSelect::VP); NetPartSelect::VP);
des->add_node(sel); des->add_node(sel);
ivl_assert(*this, select_width > 0);
NetNet*tmp = new NetNet(scope, scope->local_symbol(), NetNet*tmp = new NetNet(scope, scope->local_symbol(),
NetNet::WIRE, select_width); NetNet::WIRE, select_width);
tmp->data_type(sub->data_type()); tmp->data_type(sub->data_type());
@ -1067,7 +1092,8 @@ NetNet* NetESelect::synthesize(Design *des, NetScope*scope, NetExpr*root)
if (base_ != 0) { if (base_ != 0) {
off = base_->synthesize(des, scope, root); off = base_->synthesize(des, scope, root);
NetPartSelect*sel = new NetPartSelect(sub, off, expr_width()); NetPartSelect*sel = new NetPartSelect(sub, off, expr_width(),
base_->has_sign());
sel->set_line(*this); sel->set_line(*this);
des->add_node(sel); des->add_node(sel);
@ -1279,7 +1305,7 @@ static NetEvWait* make_func_trigger(Design*des, NetScope*scope, NetExpr*root)
delete nset; delete nset;
return trigger; return trigger;
} }
NetNet* NetESFunc::synthesize(Design*des, NetScope*scope, NetExpr*root) NetNet* NetESFunc::synthesize(Design*des, NetScope*scope, NetExpr*root)
{ {
@ -1347,6 +1373,10 @@ NetNet* NetEUFunc::synthesize(Design*des, NetScope*scope, NetExpr*root)
/* Synthesize the arguments. */ /* Synthesize the arguments. */
bool errors = false; bool errors = false;
for (unsigned idx = 0; idx < eparms.count(); idx += 1) { for (unsigned idx = 0; idx < eparms.count(); idx += 1) {
if (dynamic_cast<NetEEvent*> (parms_[idx])) {
errors = true;
continue;
}
NetNet*tmp = parms_[idx]->synthesize(des, scope, root); NetNet*tmp = parms_[idx]->synthesize(des, scope, root);
if (tmp == 0) { if (tmp == 0) {
cerr << get_fileline() << ": error: Unable to synthesize " cerr << get_fileline() << ": error: Unable to synthesize "
@ -1384,9 +1414,15 @@ NetNet* NetEUFunc::synthesize(Design*des, NetScope*scope, NetExpr*root)
/* Connect the pins to the arguments. */ /* Connect the pins to the arguments. */
NetFuncDef*def = func_->func_def(); NetFuncDef*def = func_->func_def();
for (unsigned idx = 0; idx < eparms.count(); idx += 1) { for (unsigned idx = 0; idx < eparms.count(); idx += 1) {
NetNet*tmp = pad_to_width(des, eparms[idx], unsigned width = def->port(idx)->vector_width();
def->port(idx)->vector_width(), *this); NetNet*tmp;
connect(net->pin(idx+1), tmp->pin(0)); if (eparms[idx]->get_signed()) {
tmp = pad_to_width_signed(des, eparms[idx], width, *this);
} else {
tmp = pad_to_width(des, eparms[idx], width, *this);
}
NetNet*tmpc = crop_to_width(des, tmp, width);
connect(net->pin(idx+1), tmpc->pin(0));
} }
return osig; return osig;

View File

@ -499,65 +499,3 @@ already seems to exist amongst VCD viewers in the wild, this behavior
seems to be acceptable according to the standard, is a better mirror seems to be acceptable according to the standard, is a better mirror
of 4-value behavior in the dead zone, and appears more user friendly of 4-value behavior in the dead zone, and appears more user friendly
when viewed by reasonable viewers. when viewed by reasonable viewers.
$Id: ieee1364-notes.txt,v 1.19 2007/04/18 02:36:13 steve Exp $
$Log: ieee1364-notes.txt,v $
Revision 1.19 2007/04/18 02:36:13 steve
Put to iverilog wiki for further notes.
Revision 1.18 2007/03/22 16:08:16 steve
Spelling fixes from Larry
Revision 1.17 2003/07/15 03:49:22 steve
Spelling fixes.
Revision 1.16 2003/04/14 03:40:21 steve
Make some effort to preserve bits while
operating on constant values.
Revision 1.15 2003/02/16 23:39:08 steve
NaN in dead zones of VCD dumps.
Revision 1.14 2003/02/06 17:51:36 steve
Edge of vectors notes.
Revision 1.13 2002/08/20 04:11:53 steve
Support parameters with defined ranges.
Revision 1.12 2002/06/11 03:34:33 steve
Spelling patch (Larry Doolittle)
Revision 1.11 2002/04/27 02:38:04 steve
Support selecting bits from parameters.
Revision 1.10 2002/03/31 01:54:13 steve
Notes about scheduling
Revision 1.9 2002/01/26 02:08:07 steve
Handle x in l-value of set/x
Revision 1.8 2001/08/01 05:17:31 steve
Accept empty port lists to module instantiation.
Revision 1.7 2001/02/17 05:27:31 steve
I allow function ports to have types.
Revision 1.6 2001/02/12 16:48:04 steve
Rant about bit widths.
Revision 1.5 2001/01/02 17:28:08 steve
Resolve repeat ambiguity in favor of loop.
Revision 1.4 2001/01/01 19:12:35 steve
repeat loops ambiguity.
Revision 1.3 2000/12/15 00:21:46 steve
rounding of time and x in primitives.
Revision 1.2 2000/11/19 22:03:04 steve
Integer parameter comments.
Revision 1.1 2000/07/23 18:06:31 steve
Document ieee1364 issues.

View File

@ -1,15 +1,15 @@
.TH iverilog-vpi 1 "November 19th, 2008" "" "Version 0.9.devel" .TH iverilog-vpi 1 "April 17th, 2009" "" "Version %M.%m.%n %E"
.SH NAME .SH NAME
iverilog-vpi - Compile front end for VPI modules iverilog-vpi - Compile front end for VPI modules
.SH SYNOPSIS .SH SYNOPSIS
.B iverilog-vpi .B iverilog-vpi
[--name=\fIname\fP] [\-\-name=\fIname\fP]
\fIsourcefile\fP... \fIsourcefile\fP...
.SH DESCRIPTION .SH DESCRIPTION
.PP .PP
\fIiverilog-vpi\fP is a tool to simplify the compilation of VPI \fIiverilog\-vpi\fP is a tool to simplify the compilation of VPI
modules for use with Icarus Verilog. It takes on the command line a modules for use with Icarus Verilog. It takes on the command line a
list of C or C++ source files, and generates as output a linked VPI list of C or C++ source files, and generates as output a linked VPI
module. See the \fBvvp\fP(1) man page for a description of how the module. See the \fBvvp\fP(1) man page for a description of how the
@ -20,8 +20,7 @@ first source file is named \fIfoo.c\fP, the output becomes
\fIfoo.vpi\fP. \fIfoo.vpi\fP.
.SH OPTIONS .SH OPTIONS
.l \fIiverilog\-vpi\fP accepts the following options:
\fIiverilog-vpi\fP accepts the following options:
.TP 8 .TP 8
.B -l\fIlibrary\fP .B -l\fIlibrary\fP
Include the named library in the link of the VPI module. This allows Include the named library in the link of the VPI module. This allows
@ -49,12 +48,12 @@ modules, then exit. It is a convenience for makefiles or automated
plug-in installers. plug-in installers.
.TP 8 .TP 8
.B --cflags, --ldflags and -ldlibs .B --cflags, --ldflags and --ldlibs
These flags provide compile time information. These flags provide compile time information.
.SH "PC-ONLY OPTIONS" .SH "PC-ONLY OPTIONS"
The PC port of \fIiverilog-vpi\fP includes two special flags needed to The PC port of \fIiverilog\-vpi\fP includes two special flags needed to
support the more intractable development environment. These flags help support the more intractable development environment. These flags help
the program locate parts that it needs. the program locate parts that it needs.
@ -62,7 +61,7 @@ the program locate parts that it needs.
.B -mingw=\fIpath\fP .B -mingw=\fIpath\fP
Tell the program the root of the Mingw compiler tool suite. The Tell the program the root of the Mingw compiler tool suite. The
\fBvvp\fP runtime is compiled with this compiler, and this is the \fBvvp\fP runtime is compiled with this compiler, and this is the
compiler that \fIiverilog-vpi\fP expects to use to compile your source compiler that \fIiverilog\-vpi\fP expects to use to compile your source
code. This is normally not needed, and if you do use it, it is only code. This is normally not needed, and if you do use it, it is only
needed once. The compiler will save the \fIpath\fP in the registry for needed once. The compiler will save the \fIpath\fP in the registry for
use later. use later.
@ -76,7 +75,7 @@ stored in the registry for future use.
.SH "UNIX-ONLY OPTIONS" .SH "UNIX-ONLY OPTIONS"
The UNIX version of \fIiverilog-vpi\fP includes additional flags to The UNIX version of \fIiverilog\-vpi\fP includes additional flags to
let Makefile gurus peek at the configuration of the \fIiverilog\fP let Makefile gurus peek at the configuration of the \fIiverilog\fP
installation. This way, Makefiles can be written that handle complex VPI installation. This way, Makefiles can be written that handle complex VPI
builds natively, and without hard-coding values that depend on the builds natively, and without hard-coding values that depend on the
@ -104,9 +103,9 @@ requests a 32bit vpi binary instead of the default 64bit binary.
.P .P
Example GNU makefile that takes advantage of these flags: Example GNU makefile that takes advantage of these flags:
.IP "" 4 .IP "" 4
CFLAGS = -Wall -O $(CFLAGS_$@) CFLAGS = \-Wall \-O $(CFLAGS_$@)
.br .br
VPI_CFLAGS := $(shell iverilog-vpi --cflags) VPI_CFLAGS := $(shell iverilog-vpi \-\-cflags)
.br .br
CFLAGS_messagev.o = $(VPI_CFLAGS) CFLAGS_messagev.o = $(VPI_CFLAGS)
.br .br
@ -129,7 +128,7 @@ iverilog(1), vvp(1),
.SH COPYRIGHT .SH COPYRIGHT
.nf .nf
Copyright \(co 2002-2008 Stephen Williams Copyright \(co 2002\-2009 Stephen Williams
This document can be freely redistributed according to the terms of the This document can be freely redistributed according to the terms of the
GNU General Public License version 2.0 GNU General Public License version 2.0

View File

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

View File

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

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2007 Stephen Williams (steve@icarus.com) * Copyright (c) 2007-2010 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -20,7 +20,7 @@
#ifndef __ivl_assert_h #ifndef __ivl_assert_h
#define __ivl_assert_h #define __ivl_assert_h
# include <assert.h> # include <cassert>
#define ivl_assert(tok, expression) \ #define ivl_assert(tok, expression) \
do { \ do { \

View File

@ -1,7 +1,7 @@
#ifndef __ivl_target_H #ifndef __ivl_target_H
#define __ivl_target_H #define __ivl_target_H
/* /*
* Copyright (c) 2000-2009 Stephen Williams (steve@icarus.com) * Copyright (c) 2000-2011 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -158,7 +158,15 @@ typedef struct ivl_array_s *ivl_array_t;
typedef struct ivl_branch_s *ivl_branch_t; typedef struct ivl_branch_s *ivl_branch_t;
typedef struct ivl_delaypath_s*ivl_delaypath_t; typedef struct ivl_delaypath_s*ivl_delaypath_t;
typedef struct ivl_design_s *ivl_design_t; typedef struct ivl_design_s *ivl_design_t;
/* clang++ wants this to be class to match the definition, but clang
* (the C) compiler needs it to be a struct since class is not defined
* in C. They are effecively both pointers to an object so everything
* works out. */
#ifdef __cplusplus
typedef class ivl_discipline_s*ivl_discipline_t;
#else
typedef struct ivl_discipline_s*ivl_discipline_t; typedef struct ivl_discipline_s*ivl_discipline_t;
#endif
typedef struct ivl_event_s *ivl_event_t; typedef struct ivl_event_s *ivl_event_t;
typedef struct ivl_expr_s *ivl_expr_t; typedef struct ivl_expr_s *ivl_expr_t;
typedef struct ivl_island_s *ivl_island_t; typedef struct ivl_island_s *ivl_island_t;
@ -167,7 +175,12 @@ typedef struct ivl_lval_s *ivl_lval_t;
typedef struct ivl_net_const_s*ivl_net_const_t; typedef struct ivl_net_const_s*ivl_net_const_t;
typedef struct ivl_net_logic_s*ivl_net_logic_t; typedef struct ivl_net_logic_s*ivl_net_logic_t;
typedef struct ivl_udp_s *ivl_udp_t; typedef struct ivl_udp_s *ivl_udp_t;
/* See the comments above. */
#ifdef __cplusplus
typedef class ivl_nature_s *ivl_nature_t;
#else
typedef struct ivl_nature_s *ivl_nature_t; typedef struct ivl_nature_s *ivl_nature_t;
#endif
typedef struct ivl_net_probe_s*ivl_net_probe_t; typedef struct ivl_net_probe_s*ivl_net_probe_t;
typedef struct ivl_nexus_s *ivl_nexus_t; typedef struct ivl_nexus_s *ivl_nexus_t;
typedef struct ivl_nexus_ptr_s*ivl_nexus_ptr_t; typedef struct ivl_nexus_ptr_s*ivl_nexus_ptr_t;
@ -594,7 +607,7 @@ extern double ivl_const_real(ivl_net_const_t net);
* *
* The discipline domain will not be IVL_DIS_NONE. The "none" domain * The discipline domain will not be IVL_DIS_NONE. The "none" domain
* is a place-holder internally for incomplete parsing, and is also * is a place-holder internally for incomplete parsing, and is also
* available for code generaters to use. * available for code generators to use.
*/ */
extern const char*ivl_discipline_name(ivl_discipline_t net); extern const char*ivl_discipline_name(ivl_discipline_t net);
extern ivl_dis_domain_t ivl_discipline_domain(ivl_discipline_t net); extern ivl_dis_domain_t ivl_discipline_domain(ivl_discipline_t net);
@ -1537,6 +1550,9 @@ extern unsigned ivl_parameter_lineno(ivl_parameter_t net);
* ivl_scope_is_auto * ivl_scope_is_auto
* Is the task or function declared to be automatic? * Is the task or function declared to be automatic?
* *
* ivl_scope_is_cell
* Is the module defined to be a cell?
*
* ivl_scope_var * ivl_scope_var
* ivl_scope_vars * ivl_scope_vars
* REMOVED * REMOVED
@ -1614,6 +1630,7 @@ extern unsigned ivl_scope_events(ivl_scope_t net);
extern ivl_event_t ivl_scope_event(ivl_scope_t net, unsigned idx); extern ivl_event_t ivl_scope_event(ivl_scope_t net, unsigned idx);
extern const char* ivl_scope_file(ivl_scope_t net); extern const char* ivl_scope_file(ivl_scope_t net);
extern unsigned ivl_scope_is_auto(ivl_scope_t net); extern unsigned ivl_scope_is_auto(ivl_scope_t net);
extern unsigned ivl_scope_is_cell(ivl_scope_t net);
extern unsigned ivl_scope_lineno(ivl_scope_t net); extern unsigned ivl_scope_lineno(ivl_scope_t net);
extern unsigned ivl_scope_logs(ivl_scope_t net); extern unsigned ivl_scope_logs(ivl_scope_t net);
extern ivl_net_logic_t ivl_scope_log(ivl_scope_t net, unsigned idx); extern ivl_net_logic_t ivl_scope_log(ivl_scope_t net, unsigned idx);
@ -1670,7 +1687,7 @@ extern int ivl_scope_time_units(ivl_scope_t net);
* *
* ivl_signal_discipline * ivl_signal_discipline
* If the signal has been declared with a domain (Verilog-AMS) then * If the signal has been declared with a domain (Verilog-AMS) then
* this function wil return a non-nil ivl_discipline_t. * this function will return a non-nil ivl_discipline_t.
* *
* ivl_signal_msb * ivl_signal_msb
* ivl_signal_lsb * ivl_signal_lsb

View File

@ -2,7 +2,6 @@
Icarus Verilog LOADABLE TARGET API (ivl_target) Icarus Verilog LOADABLE TARGET API (ivl_target)
Copyright 2002 Stephen Williams <steve@icarus.com> Copyright 2002 Stephen Williams <steve@icarus.com>
$Id: ivl_target.txt,v 1.3 2002/06/11 03:34:33 steve Exp $
The ivl_target API is the interface available to modules that the The ivl_target API is the interface available to modules that the
@ -38,14 +37,3 @@ other LPM device with outputs.
There are ivl_lpm_size() input ports, each with the width There are ivl_lpm_size() input ports, each with the width
ivl_lpm_data2_width(). The actual nexus is indexed by ivl_lpm_data2(). ivl_lpm_data2_width(). The actual nexus is indexed by ivl_lpm_data2().
$Log: ivl_target.txt,v $
Revision 1.3 2002/06/11 03:34:33 steve
Spelling patch (Larry Doolittle)
Revision 1.2 2002/03/17 19:31:17 steve
Add API to support user defined function.
Revision 1.1 2002/03/09 02:10:22 steve
Add the NetUserFunc netlist node.

View File

@ -3,9 +3,7 @@
# and/or modify it in source code form under the terms of the GNU # and/or modify it in source code form under the terms of the GNU
# Library General Public License as published by the Free Software # Library General Public License as published by the Free Software
# Foundation; either version 2 of the License, or (at your option) # Foundation; either version 2 of the License, or (at your option)
# any later version. In order to redistribute the software in # any later version.
# binary form, you will need a Picture Elements Binary Software
# License.
# #
# This program is distributed in the hope that it will be useful, # This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of # but WITHOUT ANY WARRANTY; without even the implied warranty of
@ -36,9 +34,10 @@ CC = @CC@
INSTALL = @INSTALL@ INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@ INSTALL_DATA = @INSTALL_DATA@
LEX = @LEX@
CPPFLAGS = -I. -I.. -I$(srcdir)/.. -I$(srcdir) @CPPFLAGS@ @DEFS@ CPPFLAGS = -I. -I.. -I$(srcdir)/.. -I$(srcdir) @CPPFLAGS@ @DEFS@
CFLAGS = -Wall @CFLAGS@ CFLAGS = @WARNING_FLAGS@ @CFLAGS@
LDFLAGS = @LDFLAGS@ LDFLAGS = @LDFLAGS@
all: ivlpp@EXEEXT@ all: ivlpp@EXEEXT@
@ -52,15 +51,15 @@ distclean: clean
rm -f Makefile config.log rm -f Makefile config.log
Makefile: $(srcdir)/Makefile.in ../config.status Makefile: $(srcdir)/Makefile.in ../config.status
../config.status --file=$@ cd ..; ./config.status --file=ivlpp/$@
O = main.o lexor.o O = main.o lexor.o
ivlpp@EXEEXT@: $O ivlpp@EXEEXT@: $O
$(CC) $(LDFLAGS) $O -o ivlpp@EXEEXT@ @EXTRALIBS@ $(CC) $(LDFLAGS) $O -o ivlpp@EXEEXT@ @EXTRALIBS@
lexor.c: lexor.lex lexor.c: $(srcdir)/lexor.lex
flex -olexor.c $(srcdir)/lexor.lex $(LEX) -t $< > $@
install: all installdirs $(libdir)/ivl$(suffix)/ivlpp@EXEEXT@ install: all installdirs $(libdir)/ivl$(suffix)/ivlpp@EXEEXT@
@ -74,4 +73,4 @@ uninstall:
rm -f "$(DESTDIR)$(libdir)/ivl$(suffix)/ivlpp@EXEEXT@" rm -f "$(DESTDIR)$(libdir)/ivl$(suffix)/ivlpp@EXEEXT@"
lexor.o: lexor.c globals.h lexor.o: lexor.c globals.h
main.o: main.c globals.h ../version.h main.o: main.c globals.h $(srcdir)/../version_base.h ../version_tag.h

View File

@ -1,6 +1,6 @@
%{ %{
/* /*
* Copyright (c) 1999-2009 Stephen Williams (steve@icarus.com) * Copyright (c) 1999-2011 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -21,9 +21,6 @@
# include "config.h" # include "config.h"
# include <stdio.h> # include <stdio.h>
#ifdef HAVE_MALLOC_H
# include <malloc.h>
#endif
# include <stdlib.h> # include <stdlib.h>
# include <string.h> # include <string.h>
# include <ctype.h> # include <ctype.h>
@ -44,10 +41,10 @@ static int is_defined(const char*name);
static int macro_needs_args(const char*name); static int macro_needs_args(const char*name);
static void macro_start_args(); static void macro_start_args();
static void macro_add_to_arg(); static void macro_add_to_arg(int is_white_space);
static void macro_finish_arg(); static void macro_finish_arg();
static void do_expand(int use_args); static void do_expand(int use_args);
static char* macro_name(); static const char* macro_name();
static void include_filename(); static void include_filename();
static void do_include(); static void do_include();
@ -64,13 +61,8 @@ struct include_stack_t
/* If we are reparsing a macro expansion, file is 0 and this /* If we are reparsing a macro expansion, file is 0 and this
* member points to the string in progress * member points to the string in progress
*/ */
const char* str; char* str;
char* orig_str;
/* If we are reparsing a macro expansion, this member indicates
* the amount of space it occupies in the macro expansion buffer.
* This will be zero for macros without arguments.
*/
int ebs;
int stringify_flag; int stringify_flag;
@ -462,7 +454,7 @@ keywords (include|define|undef|ifdef|ifndef|else|elseif|endif)
<IFCCOMMENT>\n\r | <IFCCOMMENT>\n\r |
<IFCCOMMENT>\r\n | <IFCCOMMENT>\r\n |
<IFCCOMMENT>\n | <IFCCOMMENT>\n |
<IFCCOMMENT>\r { istack->lineno += 1; } <IFCCOMMENT>\r { istack->lineno += 1; fputc('\n', yyout); }
<IFCCOMMENT>"*/" { BEGIN(comment_enter); } <IFCCOMMENT>"*/" { BEGIN(comment_enter); }
<IFDEF_FALSE,IFDEF_SUPR>[^\r\n] { } <IFDEF_FALSE,IFDEF_SUPR>[^\r\n] { }
@ -599,7 +591,8 @@ keywords (include|define|undef|ifdef|ifndef|else|elseif|endif)
<MA_ADD>"(" { macro_add_to_arg(0); ma_parenthesis_level++; } <MA_ADD>"(" { macro_add_to_arg(0); ma_parenthesis_level++; }
<MA_ADD>"," { macro_finish_arg(); } <MA_ADD>"," { if (ma_parenthesis_level > 0) macro_add_to_arg(0);
else macro_finish_arg(); }
<MA_ADD>")" { <MA_ADD>")" {
if (ma_parenthesis_level > 0) { if (ma_parenthesis_level > 0) {
@ -758,7 +751,7 @@ static void def_add_arg()
check_for_max_args(); check_for_max_args();
/* Remove trailing white space and, if necessary, opening brace. */ /* Remove trailing white space and, if necessary, opening brace. */
while (isspace(yytext[length - 1])) while (isspace((int)yytext[length - 1]))
length--; length--;
if (yytext[length - 1] == '(') if (yytext[length - 1] == '(')
@ -888,8 +881,8 @@ static char *find_arg(char*ptr, char*head, char*arg)
* match is not in the middle of another identifier. * match is not in the middle of another identifier.
*/ */
if (cp != head && if (cp != head &&
(isalnum(*(cp-1)) || *(cp-1) == '_' || *(cp-1) == '$' || (isalnum((int)*(cp-1)) || *(cp-1) == '_' || *(cp-1) == '$' ||
isalnum(*(cp+len)) || *(cp+len) == '_' || *(cp+len) == '$')) { isalnum((int)*(cp+len)) || *(cp+len) == '_' || *(cp+len) == '$')) {
cp++; cp++;
continue; continue;
} }
@ -956,7 +949,7 @@ static void do_define()
cp = yytext + strlen(yytext); cp = yytext + strlen(yytext);
while (cp > yytext) while (cp > yytext)
{ {
if (!isspace(cp[-1])) if (!isspace((int)cp[-1]))
break; break;
cp -= 1; cp -= 1;
@ -972,7 +965,7 @@ static void do_define()
cp -= 1; cp -= 1;
cp[0] = 0; cp[0] = 0;
while ((cp > yytext) && isspace(cp[-1])) { while ((cp > yytext) && isspace((int)cp[-1])) {
cp -= 1; cp -= 1;
*cp = 0; *cp = 0;
} }
@ -1208,7 +1201,7 @@ static int macro_needs_args(const char*text)
} }
} }
static char* macro_name() static const char* macro_name()
{ {
return cur_macro ? cur_macro->name : ""; return cur_macro ? cur_macro->name : "";
} }
@ -1224,7 +1217,7 @@ static void macro_start_args()
def_argo[0] = 0; def_argo[0] = 0;
def_argl[0] = 0; def_argl[0] = 0;
def_argc = 1; def_argc = 1;
}; }
static void macro_add_to_arg(int is_white_space) static void macro_add_to_arg(int is_white_space)
{ {
@ -1352,10 +1345,17 @@ static void do_expand(int use_args)
struct include_stack_t*isp; struct include_stack_t*isp;
int head = 0; int head = 0;
int tail = 0; int tail = 0;
const char *cp;
unsigned escapes = 0;
char *str_buf = 0;
if (cur_macro->keyword) if (cur_macro->keyword)
{ {
fprintf(yyout, "%s", cur_macro->value); fprintf(yyout, "%s", cur_macro->value);
if (do_expand_stringify_flag) {
do_expand_stringify_flag = 0;
fputc('"', yyout);
}
return; return;
} }
@ -1364,6 +1364,7 @@ static void do_expand(int use_args)
head = exp_buf_size - exp_buf_free; head = exp_buf_size - exp_buf_free;
expand_using_args(); expand_using_args();
tail = exp_buf_size - exp_buf_free; tail = exp_buf_size - exp_buf_free;
exp_buf_free += tail - head;
if (tail == head) if (tail == head)
return; return;
@ -1376,14 +1377,47 @@ static void do_expand(int use_args)
if (use_args) if (use_args)
{ {
isp->str = &exp_buf[head]; isp->str = &exp_buf[head];
isp->ebs = tail - head;
} }
else else
{ {
isp->str = cur_macro->value; isp->str = cur_macro->value;
isp->ebs = 0;
} }
/* Escape some characters if we are making a string version. */
for (cp = isp->str; (cp = strpbrk(cp, "\"\\")); cp += 1, escapes += 1);
if (escapes && isp->stringify_flag) {
unsigned idx = 0;
str_buf = (char *) malloc(strlen(isp->str)+3*escapes+1);
for (cp = isp->str; *cp; cp += 1) {
if (*cp == '"') {
str_buf[idx] = '\\';
str_buf[idx+1] = '0';
str_buf[idx+2] = '4';
str_buf[idx+3] = '2';
idx += 4;
continue;
}
if (*cp == '\\') {
str_buf[idx] = '\\';
str_buf[idx+1] = '1';
str_buf[idx+2] = '3';
str_buf[idx+3] = '4';
idx += 4;
continue;
}
str_buf[idx] = *cp;
idx += 1;
}
str_buf[idx] = 0;
idx += 1;
exp_buf_free -= idx;
isp->str = str_buf;
} else
isp->str = strdup(isp->str);
isp->orig_str = isp->str;
isp->next = istack; isp->next = istack;
istack->yybs = YY_CURRENT_BUFFER; istack->yybs = YY_CURRENT_BUFFER;
istack = isp; istack = isp;
@ -1449,10 +1483,17 @@ static void do_include()
unsigned idx, start = 1; unsigned idx, start = 1;
char path[4096]; char path[4096];
char *cp; char *cp;
struct include_stack_t* isp;
/* Add the current path to the start of the include_dir list. */ /* Add the current path to the start of the include_dir list. */
strcpy(path, istack->path); isp = istack;
cp = strrchr(path, '/'); while(isp && (isp->path == NULL))
isp = isp->next;
assert(isp);
strcpy(path, isp->path);
cp = strrchr(path, '/');
/* I may need the relative path for a planned warning even when /* I may need the relative path for a planned warning even when
* we are not in relative mode, so for now keep it around. */ * we are not in relative mode, so for now keep it around. */
@ -1474,10 +1515,11 @@ static void do_include()
} }
} }
fprintf(stderr, "%s:%u: Include file %s not found\n", istack->path, istack->lineno, standby->path); emit_pathline(istack);
fprintf(stderr, "Include file %s not found\n", standby->path);
exit(1); exit(1);
code_that_switches_buffers: code_that_switches_buffers:
/* Clear the current files path from the search list. */ /* Clear the current files path from the search list. */
free(include_dir[0]); free(include_dir[0]);
@ -1572,7 +1614,7 @@ static int load_next_input()
else else
line_mask_flag = 1; line_mask_flag = 1;
exp_buf_free += isp->ebs; free(isp->orig_str);
} }
if (isp->stringify_flag) { if (isp->stringify_flag) {
@ -1749,7 +1791,6 @@ void reset_lexor(FILE* out, char* paths[])
isp->path = strdup(paths[0]); isp->path = strdup(paths[0]);
isp->file = fopen(paths[0], "r"); isp->file = fopen(paths[0], "r");
isp->str = 0; isp->str = 0;
isp->ebs = 0;
isp->lineno = 0; isp->lineno = 0;
isp->stringify_flag = 0; isp->stringify_flag = 0;
isp->comment = NULL; isp->comment = NULL;
@ -1779,7 +1820,6 @@ void reset_lexor(FILE* out, char* paths[])
isp->path = strdup(paths[idx]); isp->path = strdup(paths[idx]);
isp->file = 0; isp->file = 0;
isp->str = 0; isp->str = 0;
isp->ebs = 0;
isp->next = 0; isp->next = 0;
isp->lineno = 0; isp->lineno = 0;
isp->stringify_flag = 0; isp->stringify_flag = 0;
@ -1807,4 +1847,5 @@ void destroy_lexor()
# endif # endif
# endif # endif
free(def_buf); free(def_buf);
free(exp_buf);
} }

View File

@ -1,5 +1,5 @@
const char COPYRIGHT[] = const char COPYRIGHT[] =
"Copyright (c) 1999-2009 Stephen Williams (steve@icarus.com)"; "Copyright (c) 1999-2011 Stephen Williams (steve@icarus.com)";
/* /*
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -18,7 +18,8 @@ const char COPYRIGHT[] =
*/ */
# include "config.h" # include "config.h"
# include "version.h" # include "version_base.h"
# include "version_tag.h"
const char NOTICE[] = const char NOTICE[] =
" This program is free software; you can redistribute it and/or modify\n" " This program is free software; you can redistribute it and/or modify\n"
@ -38,9 +39,6 @@ const char NOTICE[] =
# include <stdio.h> # include <stdio.h>
# include <stdlib.h> # include <stdlib.h>
#ifdef HAVE_MALLOC_H
# include <malloc.h>
#endif
# include <unistd.h> # include <unistd.h>
# include <string.h> # include <string.h>
# include <ctype.h> # include <ctype.h>
@ -107,7 +105,7 @@ static int flist_read_flags(const char*path)
char*arg; char*arg;
while (tail > cp) { while (tail > cp) {
if (! isspace(tail[-1])) if (! isspace((int)tail[-1]))
break; break;
tail -= 1; tail -= 1;
tail[0] = 0; tail[0] = 0;
@ -126,12 +124,13 @@ static int flist_read_flags(const char*path)
if (strcmp(cp,"D") == 0) { if (strcmp(cp,"D") == 0) {
char*val = strchr(arg, '='); char*val = strchr(arg, '=');
if (val) const char *valo = "1";
if (val) {
*val++ = 0; *val++ = 0;
else valo = val;
val = "1"; }
define_macro(arg, val, 0, 0); define_macro(arg, valo, 0, 0);
} else if (strcmp(cp,"I") == 0) { } else if (strcmp(cp,"I") == 0) {
include_dir = realloc(include_dir, include_dir = realloc(include_dir,
@ -188,7 +187,7 @@ static int flist_read_names(const char*path)
char*cp = line_buf + strspn(line_buf, " \t\r\b\f"); char*cp = line_buf + strspn(line_buf, " \t\r\b\f");
char*tail = cp + strlen(cp); char*tail = cp + strlen(cp);
while (tail > cp) { while (tail > cp) {
if (! isspace(tail[-1])) if (! isspace((int)tail[-1]))
break; break;
tail -= 1; tail -= 1;
tail[0] = 0; tail[0] = 0;
@ -214,26 +213,34 @@ int main(int argc, char*argv[])
FILE*precomp_out = NULL; FILE*precomp_out = NULL;
/* Define preprocessor keywords that I plan to just pass. */ /* Define preprocessor keywords that I plan to just pass. */
/* From 1364-2005 Chapter 19. */
define_macro("begin_keywords", "`begin_keywords", 1, 0);
define_macro("celldefine", "`celldefine", 1, 0); define_macro("celldefine", "`celldefine", 1, 0);
define_macro("default_decay_time", "`default_decay_time", 1, 0);
define_macro("default_nettype", "`default_nettype", 1, 0); define_macro("default_nettype", "`default_nettype", 1, 0);
define_macro("default_trireg_strength", "`default_trireg_strength", 1, 0); define_macro("end_keywords", "`end_keywords", 1, 0);
define_macro("delay_mode_distributed", "`delay_mode_distributed", 1, 0);
define_macro("delay_mode_unit", "`delay_mode_unit", 1, 0);
define_macro("delay_mode_path", "`delay_mode_path", 1, 0);
define_macro("delay_mode_zero", "`delay_mode_zero", 1, 0);
define_macro("disable_portfaults", "`disable_portfaults", 1, 0);
define_macro("enable_portfaults", "`enable_portfaults", 1, 0);
define_macro("endcelldefine", "`endcelldefine", 1, 0); define_macro("endcelldefine", "`endcelldefine", 1, 0);
define_macro("endprotect", "`endprotect", 1, 0);
define_macro("line", "`line", 1, 0); define_macro("line", "`line", 1, 0);
define_macro("nosuppress_faults", "`nosuppress_faults", 1, 0);
define_macro("nounconnected_drive", "`nounconnected_drive", 1, 0); define_macro("nounconnected_drive", "`nounconnected_drive", 1, 0);
define_macro("protect", "`protect", 1, 0); define_macro("pragma", "`pragma", 1, 0);
define_macro("resetall", "`resetall", 1, 0); define_macro("resetall", "`resetall", 1, 0);
define_macro("suppress_faults", "`suppress_faults", 1, 0);
define_macro("timescale", "`timescale", 1, 0); define_macro("timescale", "`timescale", 1, 0);
define_macro("unconnected_drive", "`unconnected_drive", 1, 0); define_macro("unconnected_drive", "`unconnected_drive", 1, 0);
/* From 1364-2005 Annex D. */
define_macro("default_decay_time", "`default_decay_time", 1, 0);
define_macro("default_trireg_strength", "`default_trireg_strength", 1, 0);
define_macro("delay_mode_distributed", "`delay_mode_distributed", 1, 0);
define_macro("delay_mode_path", "`delay_mode_path", 1, 0);
define_macro("delay_mode_unit", "`delay_mode_unit", 1, 0);
define_macro("delay_mode_zero", "`delay_mode_zero", 1, 0);
/* From other places. */
define_macro("disable_portfaults", "`disable_portfaults", 1, 0);
define_macro("enable_portfaults", "`enable_portfaults", 1, 0);
define_macro("endprotect", "`endprotect", 1, 0);
define_macro("nosuppress_faults", "`nosuppress_faults", 1, 0);
define_macro("protect", "`protect", 1, 0);
define_macro("suppress_faults", "`suppress_faults", 1, 0);
define_macro("uselib", "`uselib", 1, 0); define_macro("uselib", "`uselib", 1, 0);
include_cnt = 2; include_cnt = 2;
@ -357,14 +364,17 @@ int main(int argc, char*argv[])
if (precomp_out_path) { if (precomp_out_path) {
precomp_out = fopen(precomp_out_path, "wb"); precomp_out = fopen(precomp_out_path, "wb");
if (precomp_out == 0) { if (precomp_out == 0) {
if (out_path) fclose(out);
perror(precomp_out_path); perror(precomp_out_path);
exit(1); exit(1);
} }
} }
if(dep_path) { if (dep_path) {
depend_file = fopen(dep_path, "a"); depend_file = fopen(dep_path, "a");
if (depend_file == 0) { if (depend_file == 0) {
if (out_path) fclose(out);
if (precomp_out) fclose(precomp_out);
perror(dep_path); perror(dep_path);
exit(1); exit(1);
} }
@ -372,24 +382,32 @@ int main(int argc, char*argv[])
if (source_cnt == 0) { if (source_cnt == 0) {
fprintf(stderr, "%s: No input files given.\n", argv[0]); fprintf(stderr, "%s: No input files given.\n", argv[0]);
if (out_path) fclose(out);
if (depend_file) fclose(depend_file);
if (precomp_out) fclose(precomp_out);
return 1; return 1;
} }
/* Pass to the lexical analyzer the list of input file, and /* Pass to the lexical analyzer the list of input file, and
start scanning. */ start scanning. */
reset_lexor(out, source_list); reset_lexor(out, source_list);
if (yylex()) return -1; if (yylex()) {
if (out_path) fclose(out);
if (depend_file) fclose(depend_file);
if (precomp_out) fclose(precomp_out);
return -1;
}
destroy_lexor(); destroy_lexor();
if(depend_file) { if (depend_file) fclose(depend_file);
fclose(depend_file);
}
if (precomp_out) { if (precomp_out) {
dump_precompiled_defines(precomp_out); dump_precompiled_defines(precomp_out);
fclose(precomp_out); fclose(precomp_out);
} }
if (out_path) fclose(out);
/* Free the source and include directory lists. */ /* Free the source and include directory lists. */
for (lp = 0; lp < source_cnt; lp += 1) { for (lp = 0; lp < source_cnt; lp += 1) {
free(source_list[lp]); free(source_list[lp]);

554
lexor.lex
View File

@ -4,7 +4,7 @@
%{ %{
/* /*
* Copyright (c) 1998-2009 Stephen Williams (steve@icarus.com) * Copyright (c) 1998-2011 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -31,8 +31,8 @@
# include "parse_misc.h" # include "parse_misc.h"
# include "parse_api.h" # include "parse_api.h"
# include "parse.h" # include "parse.h"
# include <ctype.h> # include <cctype>
# include <string.h> # include <cstring>
# include "lexor_keyword.h" # include "lexor_keyword.h"
# include "discipline.h" # include "discipline.h"
# include <list> # include <list>
@ -40,6 +40,8 @@
# define YY_USER_INIT reset_lexor(); # define YY_USER_INIT reset_lexor();
# define yylval VLlval # define yylval VLlval
# define YY_NO_INPUT
/* /*
* Lexical location information is passed in the yylloc variable to th * 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 * parser. The file names, strings, are kept in a list so that I can
@ -67,9 +69,6 @@ static const char* set_file_name(char*text)
return path; return path;
} }
extern void pform_set_timescale(int, int, const char*file, unsigned line);
void reset_lexor(); void reset_lexor();
static void line_directive(); static void line_directive();
static void line_directive2(); static void line_directive2();
@ -83,11 +82,15 @@ static verinum*make_unsized_hex(const char*txt);
static int dec_buf_div2(char *buf); static int dec_buf_div2(char *buf);
static void process_timescale(const char*txt); static void process_timescale(const char*txt);
static void process_ucdrive(const char*txt);
static list<int> keyword_mask_stack; static list<int> keyword_mask_stack;
static int comment_enter; static int comment_enter;
static bool in_module = false; static bool in_module = false;
static bool in_UDP = false;
bool in_celldefine = false;
UCDriveType uc_drive = UCD_NONE;
%} %}
%x CCOMMENT %x CCOMMENT
@ -96,6 +99,7 @@ static bool in_module = false;
%x CSTRING %x CSTRING
%s UDPTABLE %s UDPTABLE
%x PPTIMESCALE %x PPTIMESCALE
%x PPUCDRIVE
%x PPDEFAULT_NETTYPE %x PPDEFAULT_NETTYPE
%x PPBEGIN_KEYWORDS %x PPBEGIN_KEYWORDS
%s EDGES %s EDGES
@ -107,8 +111,9 @@ S [afpnumkKMGT]
%% %%
^"#line"[ ]+\"[^\"]*\"[ ]+[0-9]+.* { line_directive(); } /* Recognize the various line directives. */
^"`line"[ ]+[0-9]+[ ]+\"[^\"]*\".* { line_directive2(); } ^"#line"[ \t]+.+ { line_directive(); }
^[ \t]?"`line"[ \t]+.+ { line_directive2(); }
[ \t\b\f\r] { ; } [ \t\b\f\r] { ; }
\n { yylloc.first_line += 1; } \n { yylloc.first_line += 1; }
@ -237,6 +242,14 @@ S [afpnumkKMGT]
in_module = false; in_module = false;
break; break;
case K_primitive:
in_UDP = true;
break;
case K_endprimitive:
in_UDP = false;
break;
default: default:
yylval.text = 0; yylval.text = 0;
break; break;
@ -263,22 +276,35 @@ S [afpnumkKMGT]
return IDENTIFIER; } return IDENTIFIER; }
\$([a-zA-Z0-9$_]+) { \$([a-zA-Z0-9$_]+) {
if (strcmp(yytext,"$setuphold") == 0) /* The 1364-1995 timing checks. */
return K_Ssetuphold;
if (strcmp(yytext,"$attribute") == 0)
return KK_attribute;
if (strcmp(yytext,"$hold") == 0) if (strcmp(yytext,"$hold") == 0)
return K_Shold; return K_Shold;
if (strcmp(yytext,"$nochange") == 0)
return K_Snochange;
if (strcmp(yytext,"$period") == 0) if (strcmp(yytext,"$period") == 0)
return K_Speriod; return K_Speriod;
if (strcmp(yytext,"$recovery") == 0) if (strcmp(yytext,"$recovery") == 0)
return K_Srecovery; return K_Srecovery;
if (strcmp(yytext,"$recrem") == 0)
return K_Srecrem;
if (strcmp(yytext,"$setup") == 0) if (strcmp(yytext,"$setup") == 0)
return K_Ssetup; return K_Ssetup;
if (strcmp(yytext,"$setuphold") == 0)
return K_Ssetuphold;
if (strcmp(yytext,"$skew") == 0)
return K_Sskew;
if (strcmp(yytext,"$width") == 0) if (strcmp(yytext,"$width") == 0)
return K_Swidth; return K_Swidth;
/* The new 1364-2001 timing checks. */
if (strcmp(yytext,"$fullskew") == 0)
return K_Sfullskew;
if (strcmp(yytext,"$recrem") == 0)
return K_Srecrem;
if (strcmp(yytext,"$removal") == 0)
return K_Sremoval;
if (strcmp(yytext,"$timeskew") == 0)
return K_Stimeskew;
if (strcmp(yytext,"$attribute") == 0)
return KK_attribute;
yylval.text = strdupnew(yytext); yylval.text = strdupnew(yytext);
return SYSTEM_IDENTIFIER; } return SYSTEM_IDENTIFIER; }
@ -348,7 +374,7 @@ S [afpnumkKMGT]
return REALTIME; } return REALTIME; }
/* Notice and handle the timescale directive. */ /* Notice and handle the `timescale directive. */
^{W}?`timescale { BEGIN(PPTIMESCALE); } ^{W}?`timescale { BEGIN(PPTIMESCALE); }
<PPTIMESCALE>.* { process_timescale(yytext); } <PPTIMESCALE>.* { process_timescale(yytext); }
@ -362,28 +388,74 @@ S [afpnumkKMGT]
yylloc.first_line += 1; yylloc.first_line += 1;
BEGIN(0); } BEGIN(0); }
/* Notice and handle the `celldefine and `endcelldefine directives. */
^{W}?`celldefine{W}? { in_celldefine = true; }
^{W}?`endcelldefine{W}? { in_celldefine = false; }
/* Notice and handle the resetall directive. */
^{W}?`resetall{W}? {
if (in_module) {
cerr << yylloc.text << ":" << yylloc.first_line << ": error: "
"`resetall directive can not be inside a module "
"definition." << endl;
error_count += 1;
} else if (in_UDP) {
cerr << yylloc.text << ":" << yylloc.first_line << ": error: "
"`resetall directive can not be inside a UDP "
"definition." << endl;
error_count += 1;
} else {
pform_set_default_nettype(NetNet::WIRE, yylloc.text,
yylloc.first_line);
in_celldefine = false;
uc_drive = UCD_NONE;
pform_set_timescale(def_ts_units, def_ts_prec, 0, 0);
} }
/* Notice and handle the `unconnected_drive directive. */
^{W}?`unconnected_drive { BEGIN(PPUCDRIVE); }
<PPUCDRIVE>.* { process_ucdrive(yytext); }
<PPUCDRIVE>\n {
if (in_module) {
cerr << yylloc.text << ":" << yylloc.first_line << ": error: "
"`unconnected_drive directive can not be inside a "
"module definition." << endl;
error_count += 1;
}
yylloc.first_line += 1;
BEGIN(0); }
^{W}?`nounconnected_drive{W}? {
if (in_module) {
cerr << yylloc.text << ":" << yylloc.first_line << ": error: "
"`nounconnected_drive directive can not be inside a "
"module definition." << endl;
error_count += 1;
}
uc_drive = UCD_NONE; }
/* These are directives that I do not yet support. I think that IVL /* These are directives that I do not yet support. I think that IVL
should handle these, not an external preprocessor. */ should handle these, not an external preprocessor. */
/* From 1364-2005 Chapter 19. */
^{W}?`pragme{W}?.* { }
^{W}?`celldefine{W}?.* { } /* From 1364-2005 Annex D. */
^{W}?`default_decay_time{W}?.* { } ^{W}?`default_decay_time{W}?.* { }
^{W}?`default_trireg_strength{W}?.* { } ^{W}?`default_trireg_strength{W}?.* { }
^{W}?`delay_mode_distributed{W}?.* { } ^{W}?`delay_mode_distributed{W}?.* { }
^{W}?`delay_mode_unit{W}?.* { }
^{W}?`delay_mode_path{W}?.* { } ^{W}?`delay_mode_path{W}?.* { }
^{W}?`delay_mode_unit{W}?.* { }
^{W}?`delay_mode_zero{W}?.* { } ^{W}?`delay_mode_zero{W}?.* { }
/* From other places. */
^{W}?`disable_portfaults{W}?.* { } ^{W}?`disable_portfaults{W}?.* { }
^{W}?`enable_portfaults{W}?.* { } ^{W}?`enable_portfaults{W}?.* { }
^{W}?`endcelldefine{W}?.* { }
`endprotect { } `endprotect { }
^{W}?`line{W}?.* { }
^{W}?`nosuppress_faults{W}?.* { } ^{W}?`nosuppress_faults{W}?.* { }
^{W}?`nounconnected_drive{W}?.* { }
`protect { } `protect { }
^{W}?`resetall{W}?.* { }
^{W}?`suppress_faults{W}?.* { } ^{W}?`suppress_faults{W}?.* { }
^{W}?`unconnected_drive{W}?.* { }
^{W}?`uselib{W}?.* { } ^{W}?`uselib{W}?.* { }
^{W}?`begin_keywords{W}? { BEGIN(PPBEGIN_KEYWORDS); } ^{W}?`begin_keywords{W}? { BEGIN(PPBEGIN_KEYWORDS); }
@ -447,16 +519,38 @@ S [afpnumkKMGT]
NetNet::Type net_type; NetNet::Type net_type;
size_t wordlen = strcspn(yytext, " \t\f\r\n"); size_t wordlen = strcspn(yytext, " \t\f\r\n");
yytext[wordlen] = 0; yytext[wordlen] = 0;
/* Add support for other wire types and better error detection. */
if (strcmp(yytext,"wire") == 0) { if (strcmp(yytext,"wire") == 0) {
net_type = NetNet::WIRE; net_type = NetNet::WIRE;
} else if (strcmp(yytext,"tri") == 0) {
net_type = NetNet::TRI;
} else if (strcmp(yytext,"tri0") == 0) {
net_type = NetNet::TRI0;
} else if (strcmp(yytext,"tri1") == 0) {
net_type = NetNet::TRI1;
} else if (strcmp(yytext,"wand") == 0) {
net_type = NetNet::WAND;
} else if (strcmp(yytext,"triand") == 0) {
net_type = NetNet::TRIAND;
} else if (strcmp(yytext,"wor") == 0) {
net_type = NetNet::WOR;
} else if (strcmp(yytext,"trior") == 0) {
net_type = NetNet::TRIOR;
} else if (strcmp(yytext,"none") == 0) { } else if (strcmp(yytext,"none") == 0) {
net_type = NetNet::NONE; net_type = NetNet::NONE;
} else { } else {
cerr << yylloc.text << ":" << yylloc.first_line cerr << yylloc.text << ":" << yylloc.first_line
<< ": error: Net type " << yytext << ": error: Net type " << yytext
<< " is not a valid (and supported)" << " is not a valid (or supported)"
<< " default net type." << endl; << " default net type." << endl;
net_type = NetNet::WIRE; net_type = NetNet::WIRE;
error_count += 1; error_count += 1;
@ -483,6 +577,12 @@ S [afpnumkKMGT]
<< endl; << endl;
} }
^{W}?`elsif{W}?.* {
cerr << yylloc.text << ":" << yylloc.first_line <<
": warning: `elsif not supported. Use an external preprocessor."
<< endl;
}
^{W}?`endif{W}?.* { ^{W}?`endif{W}?.* {
cerr << yylloc.text << ":" << yylloc.first_line << cerr << yylloc.text << ":" << yylloc.first_line <<
": warning: `endif not supported. Use an external preprocessor." ": warning: `endif not supported. Use an external preprocessor."
@ -495,6 +595,12 @@ S [afpnumkKMGT]
<< endl; << endl;
} }
^{W}?`ifndef{W}?.* {
cerr << yylloc.text << ":" << yylloc.first_line <<
": warning: `ifndef not supported. Use an external preprocessor."
<< endl;
}
^`include{W}?.* { ^`include{W}?.* {
cerr << yylloc.text << ":" << yylloc.first_line << cerr << yylloc.text << ":" << yylloc.first_line <<
": warning: `include not supported. Use an external preprocessor." ": warning: `include not supported. Use an external preprocessor."
@ -516,14 +622,14 @@ S [afpnumkKMGT]
error_count += 1; } error_count += 1; }
/* Final catchall. something got lost or mishandled. */ /* Final catchall. something got lost or mishandled. */
/* XXX Should we tell the luser something about the lexical state? */ /* XXX Should we tell the user something about the lexical state? */
<*>.|\n { cerr << yylloc.text << ":" << yylloc.first_line <*>.|\n { cerr << yylloc.text << ":" << yylloc.first_line
<< ": error: unmatched character ("; << ": error: unmatched character (";
if (isgraph(yytext[0])) if (isprint(yytext[0]))
cerr << yytext[0]; cerr << yytext[0];
else else
cerr << "hex " << hex << (0xffU & ((unsigned) (yytext[0]))); cerr << "hex " << hex << ((unsigned char) yytext[0]);
cerr << ")" << endl; cerr << ")" << endl;
error_count += 1; } error_count += 1; }
@ -936,6 +1042,128 @@ static verinum*make_unsized_dec(const char*ptr)
return res; return res;
} }
/*
* Convert the string to a time unit or precision.
* Returns true on failure.
*/
static bool get_timescale_const(const char *&cp, int &res, bool is_unit)
{
/* Check for the 1 digit. */
if (*cp != '1') {
if (is_unit) {
VLerror(yylloc, "Invalid `timescale unit constant "
"(1st digit)");
} else {
VLerror(yylloc, "Invalid `timescale precision constant "
"(1st digit)");
}
return true;
}
cp += 1;
/* Check the number of zeros after the 1. */
res = strspn(cp, "0");
if (res > 2) {
if (is_unit) {
VLerror(yylloc, "Invalid `timescale unit constant "
"(number of zeros)");
} else {
VLerror(yylloc, "Invalid `timescale precision constant "
"(number of zeros)");
}
return true;
}
cp += res;
/* Skip any space between the digits and the scaling string. */
cp += strspn(cp, " \t");
/* Now process the scaling string. */
if (strncmp("s", cp, 1) == 0) {
res -= 0;
cp += 1;
return false;
} else if (strncmp("ms", cp, 2) == 0) {
res -= 3;
cp += 2;
return false;
} else if (strncmp("us", cp, 2) == 0) {
res -= 6;
cp += 2;
return false;
} else if (strncmp("ns", cp, 2) == 0) {
res -= 9;
cp += 2;
return false;
} else if (strncmp("ps", cp, 2) == 0) {
res -= 12;
cp += 2;
return false;
} else if (strncmp("fs", cp, 2) == 0) {
res -= 15;
cp += 2;
return false;
}
if (is_unit) {
VLerror(yylloc, "Invalid `timescale unit scale");
} else {
VLerror(yylloc, "Invalid `timescale precision scale");
}
return true;
}
/*
* process either a pull0 or a pull1.
*/
static void process_ucdrive(const char*txt)
{
UCDriveType ucd = UCD_NONE;
const char*cp = txt + strspn(txt, " \t");
/* Skip the space after the `unconnected_drive directive. */
if (cp == txt) {
VLerror(yylloc, "Space required after `unconnected_drive "
"directive.");
return;
}
/* Check for the pull keyword. */
if (strncmp("pull", cp, 4) != 0) {
VLerror(yylloc, "pull required for `unconnected_drive "
"directive.");
return;
}
cp += 4;
if (*cp == '0') ucd = UCD_PULL0;
else if (*cp == '1') ucd = UCD_PULL1;
else {
cerr << yylloc.text << ":" << yylloc.first_line << ": error: "
"`unconnected_drive does not support 'pull" << *cp
<< "'." << endl;
error_count += 1;
return;
}
cp += 1;
/* Verify that only space and/or a single line comment is left. */
cp += strspn(cp, " \t");
if (strncmp(cp, "//", 2) != 0 &&
(size_t)(cp-yytext) != strlen(yytext)) {
VLerror(yylloc, "Invalid `unconnected_drive directive (extra "
"garbage after precision).");
return;
}
uc_drive = ucd;
}
/* /*
* The timescale parameter has the form: * The timescale parameter has the form:
@ -943,98 +1171,46 @@ static verinum*make_unsized_dec(const char*ptr)
*/ */
static void process_timescale(const char*txt) static void process_timescale(const char*txt)
{ {
unsigned num;
const char*cp = txt + strspn(txt, " \t"); const char*cp = txt + strspn(txt, " \t");
char*tmp;
const char*ctmp; /* Skip the space after the `timescale directive. */
if (cp == txt) {
VLerror(yylloc, "Space required after `timescale directive.");
return;
}
int unit = 0; int unit = 0;
int prec = 0; int prec = 0;
num = strtoul(cp, &tmp, 10); /* Get the time units. */
if (num == 0) { if (get_timescale_const(cp, unit, true)) return;
VLerror(yylloc, "Invalid timescale string.");
return;
}
while (num >= 10) { /* Skip any space after the time units, the '/' and any
unit += 1; * space after the '/'. */
num /= 10;
}
if (num != 1) {
VLerror(yylloc, "Invalid timescale unit number.");
return;
}
cp = tmp;
cp += strspn(cp, " \t"); cp += strspn(cp, " \t");
ctmp = cp + strcspn(cp, " \t/"); if (*cp != '/') {
VLerror(yylloc, "`timescale separator '/' appears to be missing.");
if (strncmp("s", cp, ctmp-cp) == 0) {
unit -= 0;
} else if (strncmp("ms", cp, ctmp-cp) == 0) {
unit -= 3;
} else if (strncmp("us", cp, ctmp-cp) == 0) {
unit -= 6;
} else if (strncmp("ns", cp, ctmp-cp) == 0) {
unit -= 9;
} else if (strncmp("ps", cp, ctmp-cp) == 0) {
unit -= 12;
} else if (strncmp("fs", cp, ctmp-cp) == 0) {
unit -= 15;
} else {
VLerror(yylloc, "Invalid timescale unit of measurement");
return; return;
} }
cp += 1;
cp = ctmp;
cp += strspn(cp, " \t/");
num = strtoul(cp, &tmp, 10);
if (num == 0) {
VLerror(yylloc, "Invalid timescale string.");
return;
}
assert(num);
while (num >= 10) {
prec += 1;
num /= 10;
}
if (num != 1) {
VLerror(yylloc, "Invalid timescale precision number.");
return;
}
cp = tmp;
cp += strspn(cp, " \t"); cp += strspn(cp, " \t");
ctmp = cp + strcspn(cp, " \t\r");
if (strncmp("s", cp, ctmp-cp) == 0) { /* Get the time precision. */
prec -= 0; if (get_timescale_const(cp, prec, false)) return;
} else if (strncmp("ms", cp, ctmp-cp) == 0) { /* Verify that only space and/or a single line comment is left. */
prec -= 3; cp += strspn(cp, " \t");
if (strncmp(cp, "//", 2) != 0 &&
(size_t)(cp-yytext) != strlen(yytext)) {
VLerror(yylloc, "Invalid `timescale directive (extra garbage "
"after precision).");
return;
}
} else if (strncmp("us", cp, ctmp-cp) == 0) { /* The time unit must be greater than or equal to the precision. */
prec -= 6; if (unit < prec) {
VLerror(yylloc, "error: `timescale unit must not be less than "
} else if (strncmp("ns", cp, ctmp-cp) == 0) { "the precision.");
prec -= 9;
} else if (strncmp("ps", cp, ctmp-cp) == 0) {
prec -= 12;
} else if (strncmp("fs", cp, ctmp-cp) == 0) {
prec -= 15;
} else {
VLerror(yylloc, "Invalid timescale precision units of measurement");
return; return;
} }
@ -1053,47 +1229,149 @@ int yywrap()
*/ */
static void line_directive() static void line_directive()
{ {
char*qt1 = strchr(yytext, '"'); char *cpr;
assert(qt1); /* Skip any leading space. */
qt1 += 1; char *cp = strchr(yytext, '#');
/* Skip the #line directive. */
assert(strncmp(cp, "#line", 5) == 0);
cp += 5;
/* Skip the space after the #line directive. */
cp += strspn(cp, " \t");
char*qt2 = strchr(qt1, '"'); /* Find the starting " and skip it. */
assert(qt2); char*fn_start = strchr(cp, '"');
if (cp != fn_start) {
VLerror(yylloc, "Invalid #line directive (file name start).");
return;
}
fn_start += 1;
char*buf = new char[qt2-qt1+1]; /* Find the last ". */
strncpy(buf, qt1, qt2-qt1); char*fn_end = strrchr(fn_start, '"');
buf[qt2-qt1] = 0; if (!fn_end) {
VLerror(yylloc, "Invalid #line directive (file name end).");
return;
}
/* Copy the file name and assign it to yylloc. */
char*buf = new char[fn_end-fn_start+1];
strncpy(buf, fn_start, fn_end-fn_start);
buf[fn_end-fn_start] = 0;
/* Skip the space after the file name. */
cp = fn_end;
cp += 1;
cpr = cp;
cpr += strspn(cp, " \t");
if (cp == cpr) {
VLerror(yylloc, "Invalid #line directive (missing space after "
"file name).");
return;
}
cp = cpr;
/* Get the line number and verify that it is correct. */
unsigned long lineno = strtoul(cp, &cpr, 10);
if (cp == cpr) {
VLerror(yylloc, "Invalid line number for #line directive.");
return;
}
cp = cpr;
/* Verify that only space is left. */
cpr += strspn(cp, " \t");
if ((size_t)(cpr-yytext) != strlen(yytext)) {
VLerror(yylloc, "Invalid #line directive (extra garbage after "
"line number).");
return;
}
/* Now we can assign the new values to yyloc. */
yylloc.text = set_file_name(buf); yylloc.text = set_file_name(buf);
yylloc.first_line = lineno;
qt2 += 1;
yylloc.first_line = strtoul(qt2,0,0);
} }
/*
* The line directive matches lines of the form `line N "foo" M and
* calls this function. Here I parse out the file name and line
* number, and change the yylloc to suite. M is ignored.
*/
static void line_directive2() static void line_directive2()
{ {
assert(strncmp(yytext,"`line",5) == 0); char *cpr;
char*cp = yytext + strlen("`line"); /* Skip any leading space. */
cp += strspn(cp, " "); char *cp = strchr(yytext, '`');
yylloc.first_line = strtoul(cp,&cp,10); /* Skip the `line directive. */
assert(strncmp(cp, "`line", 5) == 0);
cp += 5;
yylloc.first_line -= 1; /* strtoul skips leading space. */
unsigned long lineno = strtoul(cp, &cpr, 10);
if (cp == cpr) {
VLerror(yylloc, "Invalid line number for `line directive.");
return;
}
lineno -= 1;
cp = cpr;
cp += strspn(cp, " "); /* Skip the space between the line number and the file name. */
if (*cp == 0) return; cpr += strspn(cp, " \t");
if (cp == cpr) {
VLerror(yylloc, "Invalid `line directive (missing space after "
"line number).");
return;
}
cp = cpr;
char*qt1 = strchr(yytext, '"'); /* Find the starting " and skip it. */
assert(qt1); char*fn_start = strchr(cp, '"');
qt1 += 1; if (cp != fn_start) {
VLerror(yylloc, "Invalid `line directive (file name start).");
return;
}
fn_start += 1;
char*qt2 = strchr(qt1, '"'); /* Find the last ". */
assert(qt2); char*fn_end = strrchr(fn_start, '"');
if (!fn_end) {
VLerror(yylloc, "Invalid `line directive (file name end).");
return;
}
char*buf = new char[qt2-qt1+1]; /* Skip the space after the file name. */
strncpy(buf, qt1, qt2-qt1); cp = fn_end + 1;
buf[qt2-qt1] = 0; cpr = cp;
cpr += strspn(cp, " \t");
if (cp == cpr) {
VLerror(yylloc, "Invalid `line directive (missing space after "
"file name).");
return;
}
cp = cpr;
/* Check that the level is correct, we do not need the level. */
if (strspn(cp, "012") != 1) {
VLerror(yylloc, "Invalid level for `line directive.");
return;
}
cp += 1;
/* Verify that only space and/or a single line comment is left. */
cp += strspn(cp, " \t");
if (strncmp(cp, "//", 2) != 0 &&
(size_t)(cp-yytext) != strlen(yytext)) {
VLerror(yylloc, "Invalid `line directive (extra garbage after "
"level).");
return;
}
/* Copy the file name and assign it and the line number to yylloc. */
char*buf = new char[fn_end-fn_start+1];
strncpy(buf, fn_start, fn_end-fn_start);
buf[fn_end-fn_start] = 0;
yylloc.text = set_file_name(buf); yylloc.text = set_file_name(buf);
yylloc.first_line = lineno;
} }
extern FILE*vl_input; extern FILE*vl_input;
@ -1105,3 +1383,17 @@ void reset_lexor()
/* Announce the first file name. */ /* Announce the first file name. */
yylloc.text = set_file_name(strdupnew(vl_file.c_str())); yylloc.text = set_file_name(strdupnew(vl_file.c_str()));
} }
/*
* Modern version of flex (>=2.5.9) can clean up the scanner data.
*/
void destroy_lexor()
{
# ifdef FLEX_SCANNER
# if YY_FLEX_MAJOR_VERSION >= 2 && YY_FLEX_MINOR_VERSION >= 5
# if defined(YY_FLEX_SUBMINOR_VERSION) && YY_FLEX_SUBMINOR_VERSION >= 9
yylex_destroy();
# endif
# endif
# endif
}

View File

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

View File

@ -31,14 +31,16 @@ libdir = @libdir@
includedir = $(prefix)/include includedir = $(prefix)/include
CC = @CC@ CC = @CC@
RANLIB = @RANLIB@
AR = @AR@
LD = @LD@
INSTALL = @INSTALL@ INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@ INSTALL_DATA = @INSTALL_DATA@
CPPFLAGS = -I. -I.. -I$(srcdir) -I$(srcdir)/.. @CPPFLAGS@ @DEFS@ @PICFLAG@ CPPFLAGS = -I. -I.. -I$(srcdir) -I$(srcdir)/.. @CPPFLAGS@ @DEFS@ @PICFLAG@
CFLAGS = -Wall @CFLAGS@ CFLAGS = @WARNING_FLAGS@ @CFLAGS@
LDFLAGS = @LDFLAGS@ LDFLAGS = @LDFLAGS@
RANLIB = @RANLIB@
A = a_close.o a_compare_handles.o a_configure.o a_fetch_argc.o \ A = a_close.o a_compare_handles.o a_configure.o a_fetch_argc.o \
a_fetch_argv.o a_fetch_dir.o a_fetch_fullname.o a_fetch_location.o \ a_fetch_argv.o a_fetch_dir.o a_fetch_fullname.o a_fetch_location.o \
@ -59,33 +61,36 @@ all: dep libveriuser.a $(ALL32)
check: all check: all
Makefile: $(srcdir)/Makefile.in ../config.status Makefile: $(srcdir)/Makefile.in
../config.status --file=$@ cd ..; ./config.status --file=libveriuser/$@
config.h: $(srcdir)/config.h.in ../config.status stamp-config-h: $(srcdir)/config.h.in ../config.status
../config.status --header=$@ @rm -f $@
cd ..; ./config.status --header=libveriuser/config.h
config.h: stamp-config-h
libveriuser.o: $O libveriuser.o: $O
$(LD) -r -o $@ $O $(LD) -r -o $@ $O
libveriuser.a: libveriuser.o libveriuser.a: libveriuser.o
rm -f $@ rm -f $@
ar cvq $@ libveriuser.o $(AR) cvq $@ libveriuser.o
$(RANLIB) $@ $(RANLIB) $@
dep: dep:
mkdir dep mkdir dep
%.o: %.c %.o: %.c config.h
$(CC) $(CPPFLAGS) $(CFLAGS) -MD -c $< -o $*.o $(CC) $(CPPFLAGS) $(CFLAGS) @DEPENDENCY_FLAG@ -c $< -o $*.o
mv $*.d dep mv $*.d dep
clean: clean:
rm -rf *.o dep libveriuser.a libveriuser.o bin32 rm -rf *.o dep libveriuser.a libveriuser.o
distclean: clean distclean: clean
rm -f Makefile config.log config.h rm -f Makefile config.log
rm -f config.h stamp-config-h
install:: all installdirs $(libdir)/libveriuser$(suffix).a $(INSTALL32) install:: all installdirs $(libdir)/libveriuser$(suffix).a $(INSTALL32)

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2003 Stephen Williams (steve@icarus.com) * Copyright (c) 2003-2009 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -16,9 +16,6 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#ifdef HAVE_CVS_IDENT
#ident "$Id: a_configure.c,v 1.4 2003/12/17 15:45:07 steve Exp $"
#endif
#include <acc_user.h> #include <acc_user.h>
#include <vpi_user.h> #include <vpi_user.h>
@ -70,41 +67,14 @@ int acc_configure(PLI_INT32 config_param, const char*value)
if (pli_trace) { if (pli_trace) {
fprintf(pli_trace, "acc_configure(config=%d, %s)\n", fprintf(pli_trace, "acc_configure(config=%d, %s)\n",
config_param, value); (int)config_param, value);
} }
vpi_printf("XXXX acc_configure(%d, %s)\n", config_param, value); vpi_printf("XXXX acc_configure(%d, %s)\n", (int)config_param,
value);
rc = 0; rc = 0;
break; break;
} }
return rc; return rc;
} }
/*
* $Log: a_configure.c,v $
* Revision 1.4 2003/12/17 15:45:07 steve
* Add acc_set_scope function.
*
* Revision 1.3 2003/06/17 16:55:07 steve
* 1) setlinebuf() for vpi_trace
* 2) Addes error checks for trace file opens
* 3) removes now extraneous flushes
* 4) fixes acc_next() bug
*
* Revision 1.2 2003/05/18 00:16:35 steve
* Add PLI_TRACE tracing of PLI1 modules.
*
* Add tf_isetdelay and friends, and add
* callback return values for acc_vcl support.
*
* Revision 1.1 2003/02/17 06:39:47 steve
* Add at least minimal implementations for several
* acc_ functions. Add support for standard ACC
* string handling.
*
* Add the _pli_types.h header file to carry the
* IEEE1364-2001 standard PLI type declarations.
*
*/

View File

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

View File

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

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2003 Stephen Williams (steve@icarus.com) * Copyright (c) 2003-2010 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -16,9 +16,6 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#ifdef HAVE_CVS_IDENT
#ident "$Id: a_fetch_type.c,v 1.8 2004/10/04 01:10:56 steve Exp $"
#endif
# include <acc_user.h> # include <acc_user.h>
# include <vpi_user.h> # include <vpi_user.h>
@ -59,14 +56,11 @@ PLI_INT32 acc_fetch_type(handle obj)
case vpiModule: case vpiModule:
return accModule; return accModule;
default:
vpi_printf("acc_fetch_type: vpiType %d is what accType?\n",
vpi_get(vpiType, obj));
return accUnknown;
} }
return 0; vpi_printf("acc_fetch_type: vpiType %d is what accType?\n",
(int)vpi_get(vpiType, obj));
return accUnknown;
} }
PLI_INT32 acc_fetch_fulltype(handle obj) PLI_INT32 acc_fetch_fulltype(handle obj)
@ -118,43 +112,3 @@ PLI_INT32 acc_fetch_fulltype(handle obj)
return accUnknown; return accUnknown;
} }
} }
/*
* $Log: a_fetch_type.c,v $
* Revision 1.8 2004/10/04 01:10:56 steve
* Clean up spurious trailing white space.
*
* Revision 1.7 2003/06/04 01:56:20 steve
* 1) Adds configure logic to clean up compiler warnings
* 2) adds acc_compare_handle, acc_fetch_range, acc_next_scope and
* tf_isetrealdelay, acc_handle_scope
* 3) makes acc_next reentrant
* 4) adds basic vpiWire type support
* 5) fills in some acc_object_of_type() and acc_fetch_{full}type()
* 6) add vpiLeftRange/RigthRange to signals
*
* Revision 1.6 2003/05/30 04:18:31 steve
* Add acc_next function.
*
* Revision 1.5 2003/05/29 02:35:41 steve
* acc_fetch_type supports module.
*
* Revision 1.4 2003/04/24 18:57:06 steve
* Add acc_fetch_fulltype function.
*
* Revision 1.3 2003/04/12 18:57:14 steve
* More acc_ function stubs.
*
* Revision 1.2 2003/03/13 04:35:09 steve
* Add a bunch of new acc_ and tf_ functions.
*
* Revision 1.1 2003/02/17 06:39:47 steve
* Add at least minimal implementations for several
* acc_ functions. Add support for standard ACC
* string handling.
*
* Add the _pli_types.h header file to carry the
* IEEE1364-2001 standard PLI type declarations.
*
*/

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2003 Stephen Williams (steve@icarus.com) * Copyright (c) 2003-2010 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -16,9 +16,6 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#ifdef HAVE_CVS_IDENT
#ident "$Id: a_fetch_type_str.c,v 1.5 2003/04/12 18:57:14 steve Exp $"
#endif
#include <assert.h> #include <assert.h>
#include <vpi_user.h> #include <vpi_user.h>
@ -39,36 +36,8 @@ char* acc_fetch_type_str(PLI_INT32 type)
case accConstant: case accConstant:
return "accConstant"; return "accConstant";
default:
vpi_printf("XXXX acc_fetch_type_str(%d);\n", type);
return "acc_fetch_type_str(unknown)";
} }
return ""; vpi_printf("acc_fetch_type_str: type %d is what accType?\n", (int)type);
return "acc_fetch_type_str(unknown)";
} }
/*
* $Log: a_fetch_type_str.c,v $
* Revision 1.5 2003/04/12 18:57:14 steve
* More acc_ function stubs.
*
* Revision 1.4 2003/03/13 05:07:46 steve
* Declaration warnings.
*
* Revision 1.3 2003/03/13 04:35:09 steve
* Add a bunch of new acc_ and tf_ functions.
*
* Revision 1.2 2003/02/19 04:37:04 steve
* fullname for accConstant.
*
* Revision 1.1 2003/02/17 06:39:47 steve
* Add at least minimal implementations for several
* acc_ functions. Add support for standard ACC
* string handling.
*
* Add the _pli_types.h header file to carry the
* IEEE1364-2001 standard PLI type declarations.
*
*/

View File

@ -1,5 +1,5 @@
/* vi:sw=6 /*
* Copyright (c) 2003 Michael Ruff (mruff at chiaro.com) * Copyright (c) 2003-2009 Michael Ruff (mruff at chiaro.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -16,9 +16,6 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#ifdef HAVE_CVS_IDENT
#ident "$Id: a_next.c,v 1.4 2006/10/30 22:45:37 steve Exp $"
#endif
#include <stdio.h> #include <stdio.h>
#include <acc_user.h> #include <acc_user.h>
@ -37,7 +34,7 @@ handle acc_next(PLI_INT32 *type, handle scope, handle prev)
PLI_INT32 *ip; PLI_INT32 *ip;
fprintf(pli_trace, "acc_next(%p <", type); fprintf(pli_trace, "acc_next(%p <", type);
for (ip = type; *ip; ip++) { for (ip = type; *ip; ip++) {
fprintf(pli_trace, "%s%d", ip != type ? "," : "", *ip); fprintf(pli_trace, "%s%d", ip != type ? "," : "", (int)*ip);
} }
fprintf(pli_trace, ">, %p", scope); fprintf(pli_trace, ">, %p", scope);
if (scope) if (scope)
@ -91,28 +88,3 @@ handle acc_next_scope(handle scope, handle prev)
PLI_INT32 type[2] = {accScope, 0}; PLI_INT32 type[2] = {accScope, 0};
return acc_next(type, scope, prev); return acc_next(type, scope, prev);
} }
/*
* $Log: a_next.c,v $
* Revision 1.4 2006/10/30 22:45:37 steve
* Updates for Cygwin portability (pr1585922)
*
* Revision 1.3 2003/06/17 16:55:07 steve
* 1) setlinebuf() for vpi_trace
* 2) Addes error checks for trace file opens
* 3) removes now extraneous flushes
* 4) fixes acc_next() bug
*
* Revision 1.2 2003/06/04 01:56:20 steve
* 1) Adds configure logic to clean up compiler warnings
* 2) adds acc_compare_handle, acc_fetch_range, acc_next_scope and
* tf_isetrealdelay, acc_handle_scope
* 3) makes acc_next reentrant
* 4) adds basic vpiWire type support
* 5) fills in some acc_object_of_type() and acc_fetch_{full}type()
* 6) add vpiLeftRange/RigthRange to signals
*
* Revision 1.1 2003/05/30 04:18:31 steve
* Add acc_next function.
*
*/

View File

@ -1,5 +1,5 @@
/* vi:sw=6 /*
* Copyright (c) 2002, 2003 Michael Ruff (mruff at chiaro.com) * Copyright (c) 2002-2009 Michael Ruff (mruff at chiaro.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -16,9 +16,6 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#ifdef HAVE_CVS_IDENT
#ident "$Id: a_object_of_type.c,v 1.6 2004/02/18 02:51:59 steve Exp $"
#endif
#include <assert.h> #include <assert.h>
#include <vpi_user.h> #include <vpi_user.h>
@ -35,7 +32,7 @@ int acc_object_of_type(handle object, PLI_INT32 type)
if (pli_trace) { if (pli_trace) {
fprintf(pli_trace, "acc_object_of_type(%p \"%s\", %d)", fprintf(pli_trace, "acc_object_of_type(%p \"%s\", %d)",
object, vpi_get_str(vpiName, object), type); object, vpi_get_str(vpiName, object), (int)type);
fflush(pli_trace); fflush(pli_trace);
} }
@ -77,7 +74,8 @@ int acc_object_of_type(handle object, PLI_INT32 type)
break; break;
default: default:
vpi_printf("acc_object_of_type: Unknown type %d\n", type); vpi_printf("acc_object_of_type: Unknown type %d\n",
(int)type);
rtn = 0; rtn = 0;
} }
@ -98,36 +96,3 @@ int acc_object_in_typelist(handle object, PLI_INT32*typelist)
return 0; return 0;
} }
/*
* $Log: a_object_of_type.c,v $
* Revision 1.6 2004/02/18 02:51:59 steve
* Fix type mismatches of various VPI functions.
*
* Revision 1.5 2003/06/04 01:56:20 steve
* 1) Adds configure logic to clean up compiler warnings
* 2) adds acc_compare_handle, acc_fetch_range, acc_next_scope and
* tf_isetrealdelay, acc_handle_scope
* 3) makes acc_next reentrant
* 4) adds basic vpiWire type support
* 5) fills in some acc_object_of_type() and acc_fetch_{full}type()
* 6) add vpiLeftRange/RigthRange to signals
*
* Revision 1.4 2003/05/30 04:18:31 steve
* Add acc_next function.
*
* Revision 1.3 2003/02/17 06:39:47 steve
* Add at least minimal implementations for several
* acc_ functions. Add support for standard ACC
* string handling.
*
* Add the _pli_types.h header file to carry the
* IEEE1364-2001 standard PLI type declarations.
*
* Revision 1.2 2002/08/12 01:35:02 steve
* conditional ident string using autoconfig.
*
* Revision 1.1 2002/06/07 02:58:58 steve
* Add a bunch of acc/tf functions. (mruff)
*
*/

View File

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

View File

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

View File

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

View File

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

View File

@ -1,5 +1,5 @@
/* vi:sw=6 /*
* Copyright (c) 2002,2003 Michael Ruff (mruff at chiaro.com) * Copyright (c) 2002-2011 Michael Ruff (mruff at chiaro.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -16,9 +16,6 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#ifdef HAVE_CVS_IDENT
#ident "$Id: getsimtime.c,v 1.11 2003/06/21 23:40:15 steve Exp $"
#endif
#include <veriuser.h> #include <veriuser.h>
#include <vpi_user.h> #include <vpi_user.h>
@ -32,6 +29,15 @@
* some TF time routines implemented using VPI interface * some TF time routines implemented using VPI interface
*/ */
// On some platforms (e.g. MinGW), pow() may not always generate an
// exact integer result when supplied with integer operands. Converting
// the result to an integer before we use it seems to be enough to work
// round this issue.
static ivl_u64_t pow10u(PLI_INT32 val)
{
return (ivl_u64_t)pow(10, val);
}
static ivl_u64_t static ivl_u64_t
scale(int high, int low, void*obj) { scale(int high, int low, void*obj) {
vpiHandle hand = vpi_handle(vpiScope, vpi_handle(vpiSysTfCall,0)); vpiHandle hand = vpi_handle(vpiScope, vpi_handle(vpiSysTfCall,0));
@ -39,8 +45,8 @@ scale(int high, int low, void*obj) {
scaled = high; scaled = high;
scaled = (scaled << 32) | low; scaled = (scaled << 32) | low;
scaled *= pow(10, vpi_get(vpiTimePrecision,0) - scaled /= pow10u(vpi_get(vpiTimeUnit,obj ? (vpiHandle)obj : hand) -
vpi_get(vpiTimeUnit,obj ? (vpiHandle)obj : hand)); vpi_get(vpiTimePrecision,0));
return scaled; return scaled;
} }
@ -48,33 +54,34 @@ scale(int high, int low, void*obj) {
PLI_INT32 tf_gettime(void) PLI_INT32 tf_gettime(void)
{ {
s_vpi_time time; s_vpi_time timerec;
time.type = vpiSimTime; timerec.type = vpiSimTime;
vpi_get_time (0, &time); vpi_get_time (0, &timerec);
return scale(time.high, time.low, 0) & 0xffffffff; return scale(timerec.high, timerec.low, 0) & 0xffffffff;
} }
char *tf_strgettime(void) char *tf_strgettime(void)
{ {
static char buf[32]; static char buf[32];
s_vpi_time time; s_vpi_time timerec;
time.type = vpiSimTime; timerec.type = vpiSimTime;
vpi_get_time (0, &time); vpi_get_time (0, &timerec);
if (time.high) if (timerec.high)
snprintf(buf, sizeof(buf)-1, "%u%08u", time.high, time.low); snprintf(buf, sizeof(buf)-1, "%u%08u", (unsigned int)timerec.high,
(unsigned int)timerec.low);
else else
snprintf(buf, sizeof(buf)-1, "%u", time.low); snprintf(buf, sizeof(buf)-1, "%u", (unsigned int)timerec.low);
return buf; return buf;
} }
PLI_INT32 tf_igetlongtime(PLI_INT32 *high, void*obj) PLI_INT32 tf_igetlongtime(PLI_INT32 *high, void*obj)
{ {
s_vpi_time time; s_vpi_time timerec;
ivl_u64_t scaled; ivl_u64_t scaled;
time.type = vpiSimTime; timerec.type = vpiSimTime;
vpi_get_time ((vpiHandle)obj, &time); vpi_get_time ((vpiHandle)obj, &timerec);
scaled = scale(time.high, time.low, obj); scaled = scale(timerec.high, timerec.low, obj);
*high = (scaled >> 32) & 0xffffffff; *high = (scaled >> 32) & 0xffffffff;
return scaled & 0xffffffff; return scaled & 0xffffffff;
@ -85,9 +92,24 @@ PLI_INT32 tf_getlongtime(PLI_INT32 *high)
return tf_igetlongtime(high, 0); return tf_igetlongtime(high, 0);
} }
/* Alias for commercial simulators */ /*
PLI_INT32 tf_getlongsimtime(PLI_INT32 *high) \ * This function is not defined in the IEE standard, but is provided for
__attribute__ ((weak, alias ("tf_getlongtime"))); * compatibility with other simulators. On platforms that support this,
* make it a weak symbol just in case the user has defined their own
* function for this.
*/
#if !defined(__CYGWIN__) && !defined(__MINGW32__)
PLI_INT32 tf_getlongsimtime(PLI_INT32 *high) __attribute__ ((weak));
#endif
PLI_INT32 tf_getlongsimtime(PLI_INT32 *high)
{
s_vpi_time timerec;
timerec.type = vpiSimTime;
vpi_get_time (0, &timerec);
*high = timerec.high;
return timerec.low;
}
void tf_scale_longdelay(void*obj, PLI_INT32 low, PLI_INT32 high, void tf_scale_longdelay(void*obj, PLI_INT32 low, PLI_INT32 high,
PLI_INT32 *alow, PLI_INT32 *ahigh) PLI_INT32 *alow, PLI_INT32 *ahigh)
@ -116,8 +138,8 @@ void tf_scale_realdelay(void*obj, double real, double *areal)
{ {
vpiHandle hand = vpi_handle(vpiScope, vpi_handle(vpiSysTfCall,0)); vpiHandle hand = vpi_handle(vpiScope, vpi_handle(vpiSysTfCall,0));
*areal = real * pow(10, vpi_get(vpiTimePrecision, 0) - *areal = real / pow(10, vpi_get(vpiTimeUnit, hand) -
vpi_get(vpiTimeUnit, hand)); vpi_get(vpiTimePrecision, 0));
} }
void tf_unscale_realdelay(void*obj, double real, double *areal) void tf_unscale_realdelay(void*obj, double real, double *areal)
@ -140,7 +162,7 @@ PLI_INT32 tf_gettimeprecision(void)
if (pli_trace) if (pli_trace)
fprintf(pli_trace, "tf_gettimeprecision(<%s>) --> %d\n", fprintf(pli_trace, "tf_gettimeprecision(<%s>) --> %d\n",
vpi_get_str(vpiName, sys), rc); vpi_get_str(vpiName, sys), (int)rc);
return rc; return rc;
} }
@ -163,7 +185,7 @@ PLI_INT32 tf_igettimeprecision(void*obj)
if (pli_trace) if (pli_trace)
fprintf(pli_trace, "tf_igettimeprecision(<%s>) --> %d\n", fprintf(pli_trace, "tf_igettimeprecision(<%s>) --> %d\n",
obj? vpi_get_str(vpiName, obj) : ".", rc); obj? vpi_get_str(vpiName, obj) : ".", (int)rc);
return rc; return rc;
} }
@ -179,47 +201,3 @@ PLI_INT32 tf_igettimeunit(void*obj)
{ {
return vpi_get(!obj ? vpiTimePrecision : vpiTimeUnit, (vpiHandle)obj); return vpi_get(!obj ? vpiTimePrecision : vpiTimeUnit, (vpiHandle)obj);
} }
/*
* $Log: getsimtime.c,v $
* Revision 1.11 2003/06/21 23:40:15 steve
* gettimeprecision will null argument has specific meaning.
*
* Revision 1.10 2003/06/13 19:23:42 steve
* Add a bunch more PLI1 routines.
*
* Revision 1.9 2003/06/04 01:56:20 steve
* 1) Adds configure logic to clean up compiler warnings
* 2) adds acc_compare_handle, acc_fetch_range, acc_next_scope and
* tf_isetrealdelay, acc_handle_scope
* 3) makes acc_next reentrant
* 4) adds basic vpiWire type support
* 5) fills in some acc_object_of_type() and acc_fetch_{full}type()
* 6) add vpiLeftRange/RigthRange to signals
*
* Revision 1.8 2003/05/30 04:01:55 steve
* Add tf_scale_longdelay.
*
* Revision 1.7 2003/05/28 03:14:20 steve
* Missing time related declarations.
*
* Revision 1.6 2003/05/27 16:22:10 steve
* PLI get time units/precision.
*
* Revision 1.5 2003/04/12 18:57:14 steve
* More acc_ function stubs.
*
* Revision 1.4 2003/03/13 04:35:09 steve
* Add a bunch of new acc_ and tf_ functions.
*
* Revision 1.3 2003/03/06 00:27:54 steve
* Fill in required fields when getting time.
*
* Revision 1.2 2002/08/12 01:35:02 steve
* conditional ident string using autoconfig.
*
* Revision 1.1 2002/05/31 18:25:51 steve
* Add tf_getlongtime (mruff)
*
*/

View File

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

View File

@ -1,5 +1,5 @@
/* vi:sw=6 /*
* Copyright (c) 2002-2009 Michael Ruff (mruff at chiaro.com) * Copyright (c) 2002-2011 Michael Ruff (mruff at chiaro.com)
* Michael Runyan (mrunyan at chiaro.com) * Michael Runyan (mrunyan at chiaro.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
@ -322,6 +322,7 @@ static PLI_INT32 callback(p_cb_data data)
reason = reason_reactivate; reason = reason_reactivate;
break; break;
default: default:
reason = -1;
assert(0); assert(0);
} }
@ -402,7 +403,7 @@ PLI_INT32 tf_isetrealdelay(double dly, void*obj)
/* Scale delay to SimTime */ /* Scale delay to SimTime */
ivl_u64_t delay = ((dly ivl_u64_t delay = ((dly
* pow(10, tf_gettimeprecision() - tf_gettimeunit())) / pow(10, tf_gettimeunit() - tf_gettimeprecision()))
+ 0.5); + 0.5);
ti.high = delay >> 32 & 0xffffffff; ti.high = delay >> 32 & 0xffffffff;
ti.low = delay & 0xffffffff; ti.low = delay & 0xffffffff;

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 * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -16,16 +16,10 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#ifdef HAVE_CVS_IDENT
#ident "$Id: workarea.c,v 1.1 2002/12/19 21:37:04 steve Exp $"
#endif
# include <veriuser.h> # include <veriuser.h>
# include <vpi_user.h> # include <vpi_user.h>
# include <stdlib.h> # include <stdlib.h>
#ifdef HAVE_MALLOC_H
# include <malloc.h>
#endif
/* /*
* Keep a list of sys handle to work area bindings. * Keep a list of sys handle to work area bindings.
@ -82,13 +76,3 @@ PLI_BYTE8* tf_getworkarea(void)
return 0; return 0;
} }
/*
* $Log: workarea.c,v $
* Revision 1.1 2002/12/19 21:37:04 steve
* Add tf_message, tf_get/setworkarea, and
* ty_typep functions, along with defines
* related to these functions.
*
*/

View File

@ -1,5 +1,5 @@
/* /*
* 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 * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -28,8 +28,8 @@
# include <string> # include <string>
# include <sys/types.h> # include <sys/types.h>
# include <dirent.h> # include <dirent.h>
# include <ctype.h> # include <cctype>
# include <assert.h> # include <cassert>
/* /*
* The module library items are maps of key names to file name within * The module library items are maps of key names to file name within
@ -78,10 +78,11 @@ bool load_module(const char*type)
if (ivlpp_string) { if (ivlpp_string) {
char*cmdline = (char*)malloc(strlen(ivlpp_string) + char*cmdline = (char*)malloc(strlen(ivlpp_string) +
strlen(path) + 2); strlen(path) + 4);
strcpy(cmdline, ivlpp_string); strcpy(cmdline, ivlpp_string);
strcat(cmdline, " "); strcat(cmdline, " \"");
strcat(cmdline, path); strcat(cmdline, path);
strcat(cmdline, "\"");
FILE*file = popen(cmdline, "r"); FILE*file = popen(cmdline, "r");
if (verbose_flag) if (verbose_flag)

225
main.cc
View File

@ -1,6 +1,5 @@
const char COPYRIGHT[] = const char COPYRIGHT[] =
"Copyright (c) 1998-2009 Stephen Williams (steve@icarus.com)"; "Copyright (c) 1998-2011 Stephen Williams (steve@icarus.com)";
/* /*
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
@ -20,7 +19,8 @@ const char COPYRIGHT[] =
*/ */
# include "config.h" # include "config.h"
# include "version.h" # include "version_base.h"
# include "version_tag.h"
const char NOTICE[] = const char NOTICE[] =
" This program is free software; you can redistribute it and/or modify\n" " This program is free software; you can redistribute it and/or modify\n"
@ -38,7 +38,7 @@ const char NOTICE[] =
" 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n" " 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n"
; ;
# include <stdio.h> # include <cstdio>
# include <iostream> # include <iostream>
# include <fstream> # include <fstream>
# include <queue> # include <queue>
@ -46,7 +46,7 @@ const char NOTICE[] =
# include <list> # include <list>
# include <map> # include <map>
# include <unistd.h> # include <unistd.h>
# include <stdlib.h> # include <cstdlib>
#if defined(HAVE_TIMES) #if defined(HAVE_TIMES)
# include <sys/times.h> # include <sys/times.h>
#endif #endif
@ -77,7 +77,7 @@ extern "C" const char*optarg;
/* Count errors detected in flag processing. */ /* Count errors detected in flag processing. */
unsigned flag_errors = 0; unsigned flag_errors = 0;
const char*basedir = "."; const char*basedir = strdup(".");
/* /*
* These are the language support control flags. These support which * These are the language support control flags. These support which
@ -115,6 +115,9 @@ bool warn_implicit = false;
bool warn_timescale = false; bool warn_timescale = false;
bool warn_portbinding = false; bool warn_portbinding = false;
bool warn_inf_loop = false; bool warn_inf_loop = false;
bool warn_ob_select = false;
bool warn_sens_entire_vec = false;
bool warn_sens_entire_arr = false;
bool error_implicit = false; bool error_implicit = false;
@ -128,6 +131,13 @@ bool debug_elab_pexpr = false;
bool debug_synth2 = false; bool debug_synth2 = false;
bool debug_optimizer = false; bool debug_optimizer = false;
/*
* Miscellaneous flags.
*/
bool disable_virtual_pins = false;
unsigned long array_size_limit = 16777216; // Minimum required by IEEE-1364?
unsigned recursive_mod_limit = 10;
/* /*
* Verbose messages enabled. * Verbose messages enabled.
*/ */
@ -135,6 +145,9 @@ bool verbose_flag = false;
unsigned integer_width = 32; unsigned integer_width = 32;
int def_ts_units = 0;
int def_ts_prec = 0;
/* /*
* Keep a heap of identifier strings that I encounter. This is a more * Keep a heap of identifier strings that I encounter. This is a more
* efficient way to allocate those strings. * efficient way to allocate those strings.
@ -214,6 +227,9 @@ static void process_generation_flag(const char*gen)
} else if (strcmp(gen,"2001") == 0) { } else if (strcmp(gen,"2001") == 0) {
generation_flag = GN_VER2001; generation_flag = GN_VER2001;
} else if (strcmp(gen,"2001-noconfig") == 0) {
generation_flag = GN_VER2001_NOCONFIG;
} else if (strcmp(gen,"2005") == 0) { } else if (strcmp(gen,"2005") == 0) {
generation_flag = GN_VER2005; generation_flag = GN_VER2005;
@ -267,7 +283,7 @@ static void parm_to_flagmap(const string&flag)
unsigned off = flag.find('='); unsigned off = flag.find('=');
if (off > flag.size()) { if (off > flag.size()) {
key = flag; key = flag;
value = ""; value = strdup("");
} else { } else {
key = flag.substr(0, off); key = flag.substr(0, off);
@ -280,6 +296,127 @@ static void parm_to_flagmap(const string&flag)
static void find_module_mention(map<perm_string,bool>&check_map, Module*m); static void find_module_mention(map<perm_string,bool>&check_map, Module*m);
static void find_module_mention(map<perm_string,bool>&check_map, PGenerate*s); static void find_module_mention(map<perm_string,bool>&check_map, PGenerate*s);
/*
* Convert a string to a time unit or precision.
*
* Returns true on failure.
*/
static bool get_ts_const(const char*&cp, int&res, bool is_units)
{
/* Check for the 1 digit. */
if (*cp != '1') {
if (is_units) {
cerr << "Error: Invalid +timescale units constant "
"(1st digit)." << endl;
} else {
cerr << "Error: Invalid +timescale precision constant "
"(1st digit)." << endl;
}
return true;
}
cp += 1;
/* Check the number of zeros after the 1. */
res = strspn(cp, "0");
if (res > 2) {
if (is_units) {
cerr << "Error: Invalid +timescale units constant "
"(number of zeros)." << endl;
} else {
cerr << "Error: Invalid +timescale precision constant "
"(number of zeros)." << endl;
}
return true;
}
cp += res;
/* Now process the scaling string. */
if (strncmp("s", cp, 1) == 0) {
res -= 0;
cp += 1;
return false;
} else if (strncmp("ms", cp, 2) == 0) {
res -= 3;
cp += 2;
return false;
} else if (strncmp("us", cp, 2) == 0) {
res -= 6;
cp += 2;
return false;
} else if (strncmp("ns", cp, 2) == 0) {
res -= 9;
cp += 2;
return false;
} else if (strncmp("ps", cp, 2) == 0) {
res -= 12;
cp += 2;
return false;
} else if (strncmp("fs", cp, 2) == 0) {
res -= 15;
cp += 2;
return false;
}
if (is_units) {
cerr << "Error: Invalid +timescale units scale." << endl;
} else {
cerr << "Error: Invalid +timescale precision scale." << endl;
}
return true;
}
/*
* Process a string with the following form (no space allowed):
*
* num = < '1' | '10' | '100' >
* scale = < 's' | 'ms' | 'us' | 'ns' | 'ps' | 'fs' >
*
* "<num> <scale> '/' <num> <scale>
*
* and set the default time units and precision if successful.
*
* Return true if we have an error processing the timescale string.
*/
static bool set_default_timescale(const char*ts_string)
{
/* Because this came from a command file we can not have embedded
* space in this string. */
const char*cp = ts_string;
int units = 0;
int prec = 0;
/* Get the time units. */
if (get_ts_const(cp, units, true)) return true;
/* Skip the '/'. */
if (*cp != '/') {
cerr << "Error: +timescale separator '/' is missing." << endl;
return true;
}
cp += 1;
/* Get the time precision. */
if (get_ts_const(cp, prec, false)) return true;
/* The time unit must be greater than or equal to the precision. */
if (units < prec) {
cerr << "Error: +timescale unit must not be less than the "
"precision." << endl;
return true;
}
/* We have valid units and precision so set the global defaults. */
def_ts_units = units;
def_ts_prec = prec;
return false;
}
/* /*
* Read the contents of a config file. This file is a temporary * Read the contents of a config file. This file is a temporary
* configuration file made by the compiler driver to carry the bulky * configuration file made by the compiler driver to carry the bulky
@ -352,6 +489,7 @@ static void find_module_mention(map<perm_string,bool>&check_map, PGenerate*s);
* warnings:<string> * warnings:<string>
* Warning flag letters. * Warning flag letters.
*/ */
bool had_timescale = false;
static void read_iconfig_file(const char*ipath) static void read_iconfig_file(const char*ipath)
{ {
char buf[8*1024]; char buf[8*1024];
@ -386,6 +524,7 @@ static void read_iconfig_file(const char*ipath)
} }
if (strcmp(buf, "basedir") == 0) { if (strcmp(buf, "basedir") == 0) {
free((void *)basedir);
basedir = strdup(cp); basedir = strdup(cp);
} else if (strcmp(buf, "debug") == 0) { } else if (strcmp(buf, "debug") == 0) {
@ -459,6 +598,7 @@ static void read_iconfig_file(const char*ipath)
flags["VPI_MODULE_LIST"] = vpi_module_list; flags["VPI_MODULE_LIST"] = vpi_module_list;
} else if (strcmp(buf, "out") == 0) { } else if (strcmp(buf, "out") == 0) {
free((void *)flags["-o"]);
flags["-o"] = strdup(cp); flags["-o"] = strdup(cp);
} else if (strcmp(buf, "sys_func") == 0) { } else if (strcmp(buf, "sys_func") == 0) {
@ -476,12 +616,21 @@ static void read_iconfig_file(const char*ipath)
case 'l': case 'l':
warn_inf_loop = true; warn_inf_loop = true;
break; break;
case 's':
warn_ob_select = true;
break;
case 'p': case 'p':
warn_portbinding = true; warn_portbinding = true;
break; break;
case 't': case 't':
warn_timescale = true; warn_timescale = true;
break; break;
case 'v':
warn_sens_entire_vec = true;
break;
case 'a':
warn_sens_entire_arr = true;
break;
default: default:
break; break;
} }
@ -514,8 +663,20 @@ static void read_iconfig_file(const char*ipath)
flag_errors += 1; flag_errors += 1;
} }
} else if (strcmp(buf, "timescale") == 0) {
if (had_timescale) {
cerr << "Command File: Warning: default timescale "
"is being set multiple times." << endl;
cerr << " : using the last valid "
"+timescale found." << endl;
}
if (set_default_timescale(cp)) {
cerr << " : with +timescale+" << cp << "+" << endl;
flag_errors += 1;
} else had_timescale = true;
} }
} }
fclose(ifile);
} }
extern Design* elaborate(list <perm_string> root); extern Design* elaborate(list <perm_string> root);
@ -539,9 +700,33 @@ static double cycles_diff(struct tms *a, struct tms *b)
// Provide dummies // Provide dummies
struct tms { int x; }; struct tms { int x; };
inline static void times(struct tms *) { } inline static void times(struct tms *) { }
inline static double cycles_diff(struct tms *a, struct tms *b) { return 0; } inline static double cycles_diff(struct tms *, struct tms *) { return 0; }
#endif // ! defined(HAVE_TIMES) #endif // ! defined(HAVE_TIMES)
static void EOC_cleanup(void)
{
cleanup_sys_func_table();
for (list<const char*>::iterator suf = library_suff.begin() ;
suf != library_suff.end() ; suf ++ ) {
free((void *)*suf);
}
library_suff.clear();
free((void *) basedir);
free(ivlpp_string);
free(depfile_name);
for (map<string, const char*>::iterator flg = flags.begin() ;
flg != flags.end() ; flg ++ ) {
free((void *)flg->second);
}
flags.clear();
lex_strings.cleanup();
filename_strings.cleanup();
}
int main(int argc, char*argv[]) int main(int argc, char*argv[])
{ {
bool help_flag = false; bool help_flag = false;
@ -554,11 +739,11 @@ int main(int argc, char*argv[])
struct tms cycles[5]; struct tms cycles[5];
library_suff.push_back(".v"); library_suff.push_back(strdup(".v"));
vpi_module_list = strdup("system"); vpi_module_list = strdup("system");
flags["VPI_MODULE_LIST"] = vpi_module_list; flags["VPI_MODULE_LIST"] = vpi_module_list;
flags["-o"] = "a.out"; flags["-o"] = strdup("a.out");
min_typ_max_flag = TYP; min_typ_max_flag = TYP;
min_typ_max_warn = 10; min_typ_max_warn = 10;
@ -650,9 +835,10 @@ int main(int argc, char*argv[])
lexor_keyword_mask |= GN_KEYWORDS_1364_1995; lexor_keyword_mask |= GN_KEYWORDS_1364_1995;
break; break;
case GN_VER2001: case GN_VER2001:
lexor_keyword_mask |= GN_KEYWORDS_1364_2001_CONFIG;
case GN_VER2001_NOCONFIG:
lexor_keyword_mask |= GN_KEYWORDS_1364_1995; lexor_keyword_mask |= GN_KEYWORDS_1364_1995;
lexor_keyword_mask |= GN_KEYWORDS_1364_2001; lexor_keyword_mask |= GN_KEYWORDS_1364_2001;
lexor_keyword_mask |= GN_KEYWORDS_1364_2001_CONFIG;
break; break;
case GN_VER2005: case GN_VER2005:
lexor_keyword_mask |= GN_KEYWORDS_1364_1995; lexor_keyword_mask |= GN_KEYWORDS_1364_1995;
@ -664,7 +850,7 @@ int main(int argc, char*argv[])
if (gn_cadence_types_flag) if (gn_cadence_types_flag)
lexor_keyword_mask |= GN_KEYWORDS_ICARUS; lexor_keyword_mask |= GN_KEYWORDS_ICARUS;
if (gn_system_verilog_flag) if (gn_system_verilog_flag)
lexor_keyword_mask |= GN_KEYWORDS_1800_2005; lexor_keyword_mask |= GN_KEYWORDS_1800_2005;
@ -680,6 +866,9 @@ int main(int argc, char*argv[])
case GN_VER1995: case GN_VER1995:
cout << "IEEE1364-1995"; cout << "IEEE1364-1995";
break; break;
case GN_VER2001_NOCONFIG:
cout << "IEEE1364-2001-noconfig";
break;
case GN_VER2001: case GN_VER2001:
cout << "IEEE1364-2001"; cout << "IEEE1364-2001";
break; break;
@ -709,7 +898,17 @@ int main(int argc, char*argv[])
cout << endl << "PARSING INPUT" << endl; cout << endl << "PARSING INPUT" << endl;
} }
const char *flag_tmp = flags["DISABLE_VIRTUAL_PINS"];
if (flag_tmp) disable_virtual_pins = strcmp(flag_tmp,"true")==0;
flag_tmp = flags["ARRAY_SIZE_LIMIT"];
if (flag_tmp) array_size_limit = strtoul(flag_tmp,NULL,0);
flag_tmp = flags["RECURSIVE_MOD_LIMIT"];
if (flag_tmp) recursive_mod_limit = strtoul(flag_tmp,NULL,0);
/* Parse the input. Make the pform. */ /* Parse the input. Make the pform. */
pform_set_timescale(def_ts_units, def_ts_prec, 0, 0);
int rc = pform_parse(argv[optind]); int rc = pform_parse(argv[optind]);
if (pf_path) { if (pf_path) {
@ -906,6 +1105,8 @@ int main(int argc, char*argv[])
<< endl; << endl;
} }
delete des;
EOC_cleanup();
return 0; return 0;
errors_summary: errors_summary:

409
mingw.txt
View File

@ -1,22 +1,21 @@
MINGW PORT OF ICARUS VERILOG MINGW PORT OF ICARUS VERILOG
Copyright 2006 Stephen Williams <steve@icarus.com> Copyright 2006 Stephen Williams <steve@icarus.com>
Copyright 2010 Martin Whitaker
Icarus Verilog source can be compiled with the mingw C/C++ compilers Icarus Verilog source can be compiled with the MinGW C/C++ compilers
to get a Windows binary that does not require the POSIX compatibility to get a Windows binary that does not require the POSIX compatibility
cruft of the Cygwin.dll library. The resulting program can be run with cruft of the Cygwin.dll library. The resulting program can be run with
or without Cygwin, so this is the preferred Windows distribution form. or without Cygwin, so this is the preferred Windows distribution form.
The configure scripts automatically detect that the compilers in use The configure scripts automatically detect that the compilers in use
are the mingw compilers and will configure the Makefiles appropriately. are the MinGW compilers and will configure the Makefiles appropriately.
The mingw patch doesn't contain tools beyond the compiler, but there The base MinGW package doesn't contain tools beyond the compiler, but
is the "msys" package that the makers of Mingw publish that has enough there is the MSYS package that the makers of MinGW publish that has
extra tools to get most everything else working. There are a few extra enough extra tools to get most everything else working. There are a
packages needed beyond mingw and msys, and the following instructions few extra packages needed beyond MinGW and MSYS, and the following
explain how to get them and install them. instructions explain how to get them and install them.
* Some Preliminary Comments -- PLEASE READ ME -- * Some Preliminary Comments -- PLEASE READ ME --
@ -29,269 +28,253 @@ software development can do this, but some patience (and access to the
Internet) is required. You may choose to print these instructions. FOR Internet) is required. You may choose to print these instructions. FOR
BEST RESULTS, FOLLOW THESE INSTRUCTIONS CAREFULLY. BEST RESULTS, FOLLOW THESE INSTRUCTIONS CAREFULLY.
NOTE that if you have Cygwin installed, it is best to not use a cygwin NOTE that if you have Cygwin installed, it is best to not use a Cygwin
window to do the build, as the Cygwin tools will intermix with the window to do the build, as the Cygwin tools will intermix with the
mingw tools such that it is hard to be sure you are using the right MinGW tools such that it is hard to be sure you are using the right
compiler. Thus, it is recommended that these steps be *not* done in a compiler. Thus, it is recommended that these steps *not* be done in a
Cygwin window. Use an MSYS window instead, and be careful that your Cygwin window. Use a MinGW window instead, and be careful that your
msys/mingw tools are not masked by paths that point to Cygwin binaries. MSYS/MinGW tools are not masked by paths that point to Cygwin binaries.
I have no plans to intentionally support MSVC++ compilation. Don't ask. We have no plans to intentionally support MSVC++ compilation. Don't ask.
* Summary of Prerequisites Incidentally, besides MinGW, none of the packages installed in the
following steps are needed after installation of Icarus Verilog is
complete. They are only needed to build the compiler. The MinGW
package can be used to compile VPI modules if you choose.
This is a brief list of prerequisite packages, along with the URL * Install MinGW and MSYS Base Packages
where each can be found. In most cases, the specific version is not
critical, but these are the versions I use.
msys-1.0 <http://www.mingw/org> From the MinGW project (http://www.mingw.org), download and run the
msysDTK-1.0 <http://www.mingw.org> MinGW graphical installer (mingw-get-inst). Select the following
Mingw32-5.x <http://www.mingw.org> components to be installed:
... including the sub-packages binutils, gcc-core and gcc-g++
if you are given the option.
readline-4.2-20010727.zip <http://mingwrep.sourceforge.net>
bzip2-1.0.3 <http://gnuwin32.sourceforge.net>
zlib-1.2.3 <http://gnuwin32.sourceforge.net>
gperf-3.0.1 <http://gnuwin32.sourceforge.net>
bison-2.1 <http://gnuwin32.sourceforge.net>
flex-2.5.4a <http://gnuwin32.sourceforge.net>
The above table lists the packages required. It is convenient to C Compiler
install them in the above order. Many of these packages are also C++ Compiler
collected into the directory: MSYS Basic System
MinGW Developer Toolkit
<ftp://icarus.com/pub/eda/verilog/win32-build-parts> NOTE: If the download site is responding slowly, the installer tends
to time out. If this happens it will skip the package it is
currently trying to download and continue. If this happens,
you can install the skipped packages later using the mingw-get
command in a MinGW shell.
Incidentally, besides Mingw32, none of these packages are needed after The default installation path is C:\MinGW, but you can change this to
installation of Icarus Verilog is complete. These are only needed to anything you like (but make sure there are no spaces in the path names).
build the compiler. The Mingw32 package can be used to compile VPI This path is referred to as <mingw> in subsequent instructions.
modules if you choose.
* Install MSYS and msysDTK The installation will leave a "MinGW Shell" icon in the MinGW sub-menu
of your Start menu. This icon brings up a shell window (a command line)
that has paths all set up for executing MSYS and MinGW commands.
The msys package is available from the mingw download site. This is NOTE: If you intend to compile VPI modules for Icarus Verilog, you
not the compiler but a collection of *nix tools ported to Windows and need MinGW, even if you are using a precompiled binary. VPI
wrapped in a convenient installer. The msys package is all the various modules only require MinGW, and none of the other libraries.
basic tools (shells, file utils, etc) and the msysDTK is extra
developer tools other than the compiler.
Download the msys-1.x.x.exe and msysdtc-1.x.x.exe binaries. These are * Install Additional MinGW Packages
self-installing packages. Install msys first, and then msysDTC. Most
likely, you want to install them in c:/msys. (The msysDTK is installed
in the same location, as it is an add-on.)
This install should be easy and reliable. Start a MinGW shell. In the shell window, execute the following
commands:
The installation will leave an "msys" icon on your desktop and in the mingw-get install libz
mingw sub-menu of your Start menu. This icon brings up a shell window mingw-get install bzip2
(a command line) that has paths all set up for executing msys and mingw-get install pthreads-w32
mingw commands. This is what you will want to use while executing mingw-get install msys-man
commands below.
* Install Mingw32 If you also want to build Git (optional):
The obvious step 2, then, is install the mingw compilers. These can be mingw-get install libiconv
found at the web page <http://www.mingw.org>. The Mingw-5.x.x package mingw-get install msys-perl
is a convenient remote installer. Download this program and run
it. The installer will ask which components you want to install. You
need only the base C compiler and the C++ compiler. (You may install
other languages if you wish.)
When I install Mingw32 (using the installer) I typically set a NOTE: Building Git allows you to execute Git commands in a MinGW shell,
destination directory of d:\mingw or the like. You will be using and allows the Icarus Verilog tools to report more detailed version
that path later. information when called with the -V option.
NOTES:
If you intend to compile VPI modules for Icarus Verilog, you
need Mingw32, even if you are using a precompiled binary. VPI
modules only require Mingw32, and none of the other libraries.
Finally, as part of installing the mingw32 compilers, remember to add
the mingw/bin directory to your path. You will need that to be able to
find the compilers later.
* Install Mingw32 Packages
There is a collection of precompiled libraries and add-on packages
that are intended for use with the Mingw32 compiler. These do not come
with simplified Windows installers, but they are pretty easy to
install by hand. Icarus Verilog uses the readline-4.2 package from
that collection.
Since I installed Mingw32 in c:\mingw, I also created a
Mingw-packages directory called c:\mingw-packages. The install, then,
is as easy as this:
<msys shell>
$ cd c:/mingw-packages
$ unzip readline-4.2-20010727.zip
[lots of inflating...]
There is no need to adjust your execution path for this package as we
are only using a library out of here. However, do remember the
directory name, as you will need it later.
Done. On to the next packages.
* Install GnuWin32 Packages * Install GnuWin32 Packages
The GnuWin32 project is a collections of open source programs and The GnuWin32 project is a collection of open source programs and libraries
libraries ported to Windows. These also work well with the Mingw ported to Windows. These also work well with the MinGW compiler, and in
compiler, and in fact Icarus Verilog uses a few pieces from this fact Icarus Verilog uses a few pieces from this collection.
collection.
You will need these gnuwin32 packages to compile Icarus Verilog: From the GnuWin project (http://gnuwin32.sourceforge.net), download the
following packages:
<http://gnuwin32.sourceforge.net> gperf-3.0.1-bin
bzip2-1.0.3.exe readline-5.0.1-bin
zlib-1.2.3.exe
gperf-3.0.1.exe
bison-2.1.exe
flex-2.5.4a.exe
I suggest creating a common directory for holding all your gnuwin32 NOTE: You need the binaries and the developer files, but you do not
packages. I use C:\gnuwin32. The download page at the gnuwin32 site need the source to these packages.
has a "setup" link for each of these packages. Click the setup to
download the installer for each of the desired programs, then execute
the downloaded .exe files to invoke the installer. Install into the
c:\gunwin32 directory.
NOTES: From the downloaded gperf-3.0.1-bin zip archive:
You need the binaries and the developer files, but you do not
need the source to these packages. The installer gives you the
choice.
After you are done installing the gnuwin32 tools, you should add the extract bin\gperf.exe to <mingw>\bin
c:\gnuwin32\bin directory (assuming you installed in c:\gnuwin32) to
your Windows path. The msys shell will pick up your Windows path.
* Unpack Icarus Verilog source From the downloaded readline-5.0.1-bin zip archive:
Unpack the compressed tar file (.tar.gz) of the source with a command extract bin\* to <mingw>\bin
like this: extract lib\* to <mingw>\lib
extract include\* to <mingw>\include
$ gunzip -d verilog-xxxxxxxx.tar.gz | tar xvf - where <mingw> is the location you chose to install MinGW.
NOTE: readline is only required to enable command line editing when
in the vvp interactive mode.
* Install Git for Windows (optional)
NOTE: You can skip this step if you are building from a snapshot or
stable release.
From the msysgit project (http://code.google.com/p/msysgit), download
and install the Git for Windows binary package.
NOTE: When installing, you must select the option of preserving Unix
style line endings.
The installation will leave a "Git Shell" icon on the desktop and in the
Git sub-menu of your Start menu. This icon brings up a shell window (a
command line) that has paths all set up for executing Git commands.
* Get the Git Source (optional)
NOTE: You can skip this step if you don't want to build Git.
Start a Git shell. In the Git shell window, change directory to the
location where you wish to store the source code and execute the
following command:
git clone git://repo.or.cz/git/mingw.git git
This will create a directory "git" that contains all the source code
for Icarus Verilog.
The path to the directory containing the source code is referred to as
<git-source> in subsequent instructions.
NOTE: Make sure there are no spaces in the <git-source> path names.
Use forward slashes in place of back slashes when using
<git-source> in a MinGW shell.
* Build Git (optional)
NOTE: You can skip this step if you don't want to build Git.
In the MinGW shell window, execute the following commands:
cd <git-source>
make NO_OPENSSL=YesPlease NO_TCLTK=YesPlease INSTALL=/bin/install \
prefix=/usr/local install
You can now uninstall the Git for Windows binary package if you wish,
as Git commands can now be executed in the MinGW shell.
* Get the Icarus Verilog Source
In the MinGW shell window, change directory to the location where you
wish to store the source code.
If you are building from a snapshot, execute the following command:
gunzip -d verilog-xxxxxxxx.tar.gz | tar xvf -
This will create a directory "verilog-xxxxxxxx" that contains all the This will create a directory "verilog-xxxxxxxx" that contains all the
source for Icarus Verilog. Descend into that directory, as that is source code for Icarus Verilog.
where we will work from now on.
$ cd verilog-xxxxxxxx NOTE: The exact name of the file will vary according to the snapshot.
The 'xxxxxxxx' name is only an example.
NOTES: If you are obtaining source from Git, execute the following command:
The exact name of the file will vary according to the
snapshot. The 20030303 name is only an example.
Unpack the source into a directory that has no spaces. The git clone git://icarus.com/~steve-icarus/verilog verilog
makefiles included in the source get confused by white space in
directory names.
* Preconfigure Icarus Verilog (Not normally needed) This will create a directory "verilog" that contains all the source code
for Icarus Verilog.
NOTE: If you haven't built Git, you will need to execute the above
command in a Git shell.
The path to the directory containing the source code is referred to as
<ivl-source> in subsequent instructions.
NOTE: Make sure there are no spaces in the <ivl-source> path names.
Use forward slashes in place of back slashes when using
<ivl-source> in a MinGW shell.
* Preconfigure Icarus Verilog (not normally needed)
Under certain cases, you may need to "preconfigure" the Icarus Verilog Under certain cases, you may need to "preconfigure" the Icarus Verilog
source tree. You should only need to do this if you are getting the source tree. You should only need to do this if you are obtaining source
Icarus Verilog source tree from CVS, or you are using an existing from Git, or you are using an existing source tree that you've patched to
source tree that you've patched to cause configure.in files to change. cause configure.in files to change.
NOTE: If you are building from a fresh, bundled source tree that NOTE: If you are building from a fresh, bundled source tree that you
you downloaded from an FTP site, then SKIP THIS STEP. Go on to downloaded from an FTP site, then SKIP THIS STEP. Go on to the
the "Configure Icarus Verilog" step below. "Configure Icarus Verilog" step below.
First, remove any autom4te.cache directories that may exist in your First, remove any autom4te.cache directories that may exist in your
source tree. These can make a mess of autoconf runs. Then, generate source tree. These can make a mess of autoconf runs. Then, in the
configure scripts with this command: MinGW shell window, execute the following commands:
$ sh autoconf.sh cd <ivl-source>
sh autoconf.sh
This script will run the "autoconf" command (part of the msysDTK) to This script will run the "autoconf" command to generate all the necessary
generate all the necessary "configure" scripts. This will take a few "configure" scripts.
minutes. This should go smoothly.
* Configure Icarus Verilog * Configure and Build Icarus Verilog
Now we are all set to configure and compile Icarus Verilog. Choose a Now we are all set to configure and compile Icarus Verilog. Choose a
destination path where you will want to install the binaries. I chose destination path where you will want to install the binaries. This
on my system the directory "D:\iverilog". This choice is not choice is not permanent, so don't get too much angst over it. Just
permanent, so don't get too much angst over it. Just choose a name choose a name without white space. The destination path is referred
without white space. to as <ivl-install> in subsequent instructions.
Now, configure the source to make the makefiles and configuration NOTE: Make sure there are no spaces in the <ivl-install> path names.
details. Run these commands: Use forward slashes in place of back slashes when using
<ivl-install> in a MinGW shell.
$ CPPFLAGS="-Ic:/gnuwin32/include -Ic:/mingw-packages/include" In the MinGW shell window, execute the following commands:
$ LDFLAGS="-Lc:/gnuwin32/lib -Lc:/mingw-packages/lib"
$ export CPPFLAGS LDFLAGS
$ ./configure --prefix=c:/iverilog
NOTES: cd <ivl-source>
The CPPFLAGS and LDFLAGS variables tell configure where ./configure --prefix=<ivl-install>
the gnuwin32 packages are. The configure program will make
write these values into the Makefiles, so you only need to
keep these variables long enough for the configure program
to work.
Your PATH variable was set in the previous step.
Use forward slashes as directory characters. All the various
tools prefer the forward slash.
Substitute your chosen directory for the prefix. This will cause the
makefiles to build and the source code to configure. The configure
program will detect that this is a mingw environment and set things up
to build properly.
(For a prefix, use the drive letter notation; the mingw compiled parts
require it, and the Cygwin tools should be able to handle it. You may
need to check or upgrade your Cygwin installation if this causes
problems for you.)
* Compile Icarus Verilog
This, believe it or not, should be the easy part:
$ make
It could take a while. Now is a good time to go get some coffee or
take a tea break.
NOTE: If you execute configure without the --prefix option, the
default installation path is <mingw>\msys\1.0\local, which
in a MinGW shell is aliased to /usr/local/bin.
* Install Icarus Verilog * Install Icarus Verilog
If the compile ran OK, then next you install Icarus Verilog in the If the compile ran OK, then next you install Icarus Verilog in the
directory you have chosen. When you are ready, install like this: directory you have chosen.
$ make install In the MinGW shell window, execute the following commands:
cd <ivl-source>
make install
This is part of what the configure program did for you. The Makefiles This is part of what the configure program did for you. The Makefiles
now know to put the files under the D:\iverilog directory (or whatever know to put the files in the <ivl-install> directory.
directory you chose) and away you go.
You may find that you need to put some of the prerequisite DLLs into You now need to add <ivl-install>\bin and <mingw>\bin to your Windows
the d:\iverilog\bin directory. These include: "PATH" environment variable. Alternatively, you can copy the DLLs
needed by Icarus Verilog from <mingw>\bin to <ivl-install>bin, and
c:\mingw\bin\mingw10.dll just add <ivl-install>\bin to your Windows "PATH" environment variable.
c:\mingw-packages\bin\libreadline.dll
c:\gnuwin32\bin\bzip2.dll
c:\gnuwin32\bin\zlib.dll
If you already have these in your Windows path (i.e. your system32
directory) then you do not need to copy them into the iverilog
directory. However, prepackaged Icarus Verilog binaries include these
files.
* Running Icarus Verilog * Running Icarus Verilog
Finally, put the C:\iverilog\bin directory in your Windows path, and You can run Icarus Verilog either from a Windows command shell window
you should be able to run the iverilog and vvp commands to your or from a MinGW shell window.
heart's content.
Currently, the iverilog.exe uses the path to itself to locate the NOTE: You will need to start a new shell to pick up any changes you
libraries and modules associated with itself. In other words, if you have made to the "PATH" environment variable.
execute the C:\iverilog\bin\iverilog.exe program, it will locate its
subparts in the C:\iverilog directory and subdirectories below Currently, iverilog.exe uses the path to itself to locate the libraries
that. This means you can move the Icarus Verilog installation by and modules associated with itself. In other words, if you execute the
simply moving the root directory and all its contents. <ivl-install>\bin\iverilog.exe program, it will locate its subparts in
the <ivl-install> directory and subdirectories below that. This means
you can move the Icarus Verilog installation by simply moving the root
directory and all its contents.
The vvp.pdf and iverilog.pdf files document the main commands. View The vvp.pdf and iverilog.pdf files document the main commands. View
these with Acrobat reader, or any other viewer capable of displaying these with Acrobat reader, or any other viewer capable of displaying

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2000-2008 Stephen Williams (steve@icarus.com) * Copyright (c) 2000-2011 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -41,6 +41,7 @@ NetAssign_::NetAssign_(NetNet*s)
lwid_ = sig_->vector_width(); lwid_ = sig_->vector_width();
sig_->incr_lref(); sig_->incr_lref();
more = 0; more = 0;
turn_sig_to_wire_on_release_ = false;
} }
NetAssign_::~NetAssign_() NetAssign_::~NetAssign_()

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2000-2007 Stephen Williams (steve@icarus.com) * Copyright (c) 2000-2010 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -294,7 +294,7 @@ void NetScope::run_defparams_later(Design*des)
(*cur)->evaluate_parameters(des); (*cur)->evaluate_parameters(des);
// If there are some scopes that still have missing scopes, // If there are some scopes that still have missing scopes,
// then sav them back into the defparams_later list for a // then save them back into the defparams_later list for a
// later pass. // later pass.
defparams_later = defparams_even_later; defparams_later = defparams_even_later;
if (! defparams_later.empty()) if (! defparams_later.empty())
@ -319,8 +319,7 @@ void NetScope::evaluate_parameter_logic_(Design*des, param_ref_t cur)
eval_expr((*cur).second.msb); eval_expr((*cur).second.msb);
if (! eval_as_long(msb, (*cur).second.msb)) { if (! eval_as_long(msb, (*cur).second.msb)) {
cerr << (*cur).second.expr->get_fileline() cerr << (*cur).second.expr->get_fileline()
<< ": internal error: " << ": error: Unable to evaluate msb expression "
<< "unable to evaluate msb expression "
<< "for parameter " << (*cur).first << ": " << "for parameter " << (*cur).first << ": "
<< *(*cur).second.msb << endl; << *(*cur).second.msb << endl;
des->errors += 1; des->errors += 1;
@ -335,8 +334,7 @@ void NetScope::evaluate_parameter_logic_(Design*des, param_ref_t cur)
eval_expr((*cur).second.lsb); eval_expr((*cur).second.lsb);
if (! eval_as_long(lsb, (*cur).second.lsb)) { if (! eval_as_long(lsb, (*cur).second.lsb)) {
cerr << (*cur).second.expr->get_fileline() cerr << (*cur).second.expr->get_fileline()
<< ": internal error: " << ": error: Unable to evaluate lsb expression "
<< "unable to evaluate lsb expression "
<< "for parameter " << (*cur).first << ": " << "for parameter " << (*cur).first << ": "
<< *(*cur).second.lsb << endl; << *(*cur).second.lsb << endl;
des->errors += 1; des->errors += 1;
@ -362,10 +360,10 @@ void NetScope::evaluate_parameter_logic_(Design*des, param_ref_t cur)
case IVL_VT_REAL: case IVL_VT_REAL:
if (! dynamic_cast<const NetECReal*>(expr)) { if (! dynamic_cast<const NetECReal*>(expr)) {
cerr << expr->get_fileline() cerr << expr->get_fileline()
<< ": internal error: " << ": error: Unable to evaluate real parameter "
<< "unable to evaluate real parameter value: " << (*cur).first << " value: " << *expr << endl;
<< *expr << endl;
des->errors += 1; des->errors += 1;
(*cur).second.expr = NULL;
return; return;
} }
break; break;
@ -374,11 +372,10 @@ void NetScope::evaluate_parameter_logic_(Design*des, param_ref_t cur)
case IVL_VT_BOOL: case IVL_VT_BOOL:
if (! dynamic_cast<const NetEConst*>(expr)) { if (! dynamic_cast<const NetEConst*>(expr)) {
cerr << expr->get_fileline() cerr << expr->get_fileline()
<< ": internal error: " << ": error: Unable to evaluate parameter "
<< "unable to evaluate parameter " << (*cur).first << " value: " << *expr << endl;
<< (*cur).first
<< " value: " << *expr << endl;
des->errors += 1; des->errors += 1;
(*cur).second.expr = NULL;
return; return;
} }
break; break;
@ -386,15 +383,16 @@ void NetScope::evaluate_parameter_logic_(Design*des, param_ref_t cur)
default: default:
cerr << expr->get_fileline() cerr << expr->get_fileline()
<< ": internal error: " << ": internal error: "
<< "unhandled expression type?" << endl; << "Unhandled expression type?" << endl;
des->errors += 1; des->errors += 1;
(*cur).second.expr = NULL;
return; return;
} }
/* If the parameter has range information, then make /* If the parameter has type or range information, then make
sure the value is set right. Note that if the sure the type is set right. Note that if the parameter
parameter doesn't have an explicit range, then it doesn't have an explicit type or range, then it will get
will get the signedness from the expression itself. */ the signedness from the expression itself. */
if (range_flag) { if (range_flag) {
unsigned long wid = (msb >= lsb)? msb - lsb : lsb - msb; unsigned long wid = (msb >= lsb)? msb - lsb : lsb - msb;
wid += 1; wid += 1;
@ -422,6 +420,8 @@ void NetScope::evaluate_parameter_logic_(Design*des, param_ref_t cur)
val = new NetEConst(tmp); val = new NetEConst(tmp);
(*cur).second.expr = expr = val; (*cur).second.expr = expr = val;
} }
} else if ((*cur).second.signed_flag) {
(*cur).second.expr->cast_signed(true);
} }
// If there are no value ranges to test the value against, // If there are no value ranges to test the value against,
@ -490,7 +490,7 @@ void NetScope::evaluate_parameter_logic_(Design*des, param_ref_t cur)
void NetScope::evaluate_parameter_real_(Design*des, param_ref_t cur) void NetScope::evaluate_parameter_real_(Design*des, param_ref_t cur)
{ {
NetExpr*expr = (*cur).second.expr; NetExpr*expr = (*cur).second.expr;
assert(expr); if (expr == NULL) return; // This is an invalid parameter so return.
NetECReal*res = 0; NetECReal*res = 0;
eval_expr(expr); eval_expr(expr);
@ -500,7 +500,13 @@ void NetScope::evaluate_parameter_real_(Design*des, param_ref_t cur)
if (NetECReal*tmp = dynamic_cast<NetECReal*>(expr)) { if (NetECReal*tmp = dynamic_cast<NetECReal*>(expr)) {
res = tmp; res = tmp;
} else { } else {
ivl_assert(*expr, 0); cerr << expr->get_fileline()
<< ": error: "
<< "Unable to evaluate real parameter "
<< (*cur).first << " value: " << *expr << endl;
des->errors += 1;
(*cur).second.expr = NULL;
return;
} }
break; break;
@ -511,12 +517,23 @@ void NetScope::evaluate_parameter_real_(Design*des, param_ref_t cur)
res = new NetECReal(val); res = new NetECReal(val);
res->set_line(*tmp); res->set_line(*tmp);
} else { } else {
ivl_assert(*expr, 0); cerr << expr->get_fileline()
<< ": error: "
<< "Unable to evaluate parameter "
<< (*cur).first << " value: " << *expr << endl;
des->errors += 1;
(*cur).second.expr = NULL;
return;
} }
break; break;
default: default:
ivl_assert(*expr, 0); cerr << expr->get_fileline()
<< ": internal error: "
<< "Unhandled expression type?" << endl;
des->errors += 1;
(*cur).second.expr = NULL;
return;
break; break;
} }
@ -564,7 +581,7 @@ void NetScope::evaluate_parameter_real_(Design*des, param_ref_t cur)
if (! from_flag) { if (! from_flag) {
cerr << res->get_fileline() << ": error: " cerr << res->get_fileline() << ": error: "
<< "Parameter value " << value << "Parameter value " << value
<< " is out of range for parameter " << (*cur).first << " is out of range for real parameter " << (*cur).first
<< "." << endl; << "." << endl;
des->errors += 1; des->errors += 1;
} }
@ -592,7 +609,7 @@ void NetScope::evaluate_parameters(Design*des)
// Resolve the expression type (signed/unsigned) if the // Resolve the expression type (signed/unsigned) if the
// expression is present. It is possible to not be // expression is present. It is possible to not be
// present if there are earlier errors en elaboration. // present if there are earlier errors in elaboration.
if (cur->second.expr) if (cur->second.expr)
cur->second.expr->resolve_pexpr_type(); cur->second.expr->resolve_pexpr_type();

View File

@ -20,6 +20,9 @@
# include "config.h" # include "config.h"
# include "compiler.h" # include "compiler.h"
# include "netlist.h" # include "netlist.h"
# include <set>
using namespace std;
/* /*
* NOTE: The name_ is perm-allocated by the caller. * NOTE: The name_ is perm-allocated by the caller.
@ -119,6 +122,52 @@ unsigned NetEvent::nexpr() const
return exprref_; return exprref_;
} }
static bool probes_are_similar(NetEvProbe*a, NetEvProbe*b)
{
if ( a->edge() != b->edge() )
return false;
set<const Nexus*> aset;
for (unsigned idx = 0 ; idx < a->pin_count() ; idx += 1)
aset .insert( a->pin(idx).nexus() );
set<const Nexus*> bset;
for (unsigned idx = 0 ; idx < b->pin_count() ; idx += 1)
bset .insert( b->pin(idx).nexus() );
return aset == bset;
}
static bool events_are_similar(NetEvent*a, NetEvent*b)
{
if (a->nprobe() != b->nprobe())
return false;
vector<bool> amatched (a->nprobe());
vector<bool> bmatched (b->nprobe());
for (unsigned adx = 0 ; adx < a->nprobe() ; adx += 1) {
NetEvProbe*ap = a->probe(adx);
for (unsigned bdx = 0 ; bdx < b->nprobe() ; bdx += 1) {
if (bmatched[bdx]) continue;
NetEvProbe*bp = b->probe(bdx);
if (! probes_are_similar(ap, bp)) continue;
amatched[adx] = true;
bmatched[bdx] = true;
break;
}
}
for (unsigned idx = 0 ; idx < amatched.size() ; idx += 1)
if (amatched[idx] == false) return false;
for (unsigned idx = 0 ; idx < bmatched.size() ; idx += 1)
if (bmatched[idx] == false) return false;
return true;
}
/* /*
* A "similar" event is one that has an identical non-nil set of * A "similar" event is one that has an identical non-nil set of
* probes. * probes.
@ -128,63 +177,23 @@ void NetEvent::find_similar_event(list<NetEvent*>&event_list)
if (probes_ == 0) if (probes_ == 0)
return; return;
map<NetEvent*,unsigned> event_matches; set<NetEvent*> event_candidates;
/* First, get a list of all the NetEvProbes that are connected
to my first probe. Then use that to create a set of
candidate events. These candidate events are a superset of
the similar events, so I will be culling this list later. */
list<NetEvProbe*>first_probes; list<NetEvProbe*>first_probes;
probes_->find_similar_probes(first_probes); probes_->find_similar_probes(first_probes);
for (list<NetEvProbe*>::iterator idx = first_probes.begin() for (list<NetEvProbe*>::iterator idx = first_probes.begin()
; idx != first_probes.end() ; idx ++) { ; idx != first_probes.end() ; idx ++) {
event_matches[ (*idx)->event() ] = 1; event_candidates .insert( (*idx)->event() );
} }
/* Now scan the remaining probes, in each case ticking the for (set<NetEvent*>::iterator idx = event_candidates.begin()
candidate event. The events that really are similar to this ; idx != event_candidates.end() ; idx ++) {
one will turn up in every probe list. */ if (this == *idx)
unsigned probe_count = 1;
for (NetEvProbe*cur = probes_->enext_ ; cur ; cur = cur->enext_) {
list<NetEvProbe*>similar_probes;
cur->find_similar_probes(similar_probes);
for (list<NetEvProbe*>::iterator idx = similar_probes.begin()
; idx != similar_probes.end() ; idx ++) {
event_matches[ (*idx)->event() ] += 1;
}
probe_count += 1;
}
/* Now scan the candidate events. Those events that are
connected to all my probes (match_count[x] == probe_count)
are possible. If those events have the same number of
events, then jackpot. */
for (map<NetEvent*,unsigned>::iterator idx = event_matches.begin()
; idx != event_matches.end() ; idx ++) {
NetEvent*tmp = (*idx).first;
if (tmp == this)
continue; continue;
if (scope()->is_auto() && (scope() != (*idx)->scope()))
/* For automatic tasks, the VVP runtime holds state for events
in the automatically allocated context. This means we can't
merge similar events in different automatic tasks. */
if (scope()->is_auto() && (tmp->scope() != scope()))
continue;
if ((*idx).second != probe_count)
continue; continue;
if (events_are_similar(this, *idx))
unsigned tcnt = 0; event_list.push_back(*idx);
for (NetEvProbe*cur = tmp->probes_ ; cur ; cur = cur->enext_)
tcnt += 1;
if (tcnt == probe_count)
event_list .push_back(tmp);
} }
} }
@ -448,4 +457,3 @@ NetProc* NetEvWait::statement()
{ {
return statement_; return statement_;
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2002-2008 Stephen Williams (steve@icarus.com) * Copyright (c) 2002-2012 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -257,15 +257,13 @@ ivl_variable_type_t NetEBMinMax::expr_type() const
NetEBMult::NetEBMult(char op__, NetExpr*l, NetExpr*r) NetEBMult::NetEBMult(char op__, NetExpr*l, NetExpr*r)
: NetEBinary(op__, l, r) : NetEBinary(op__, l, r)
{ {
if (expr_type() == IVL_VT_REAL) if (expr_type() == IVL_VT_REAL) {
expr_width(1); expr_width(1);
else
expr_width(l->expr_width() + r->expr_width());
if (expr_type() == IVL_VT_REAL)
cast_signed(true); cast_signed(true);
else } else {
expr_width(l->expr_width() + r->expr_width());
cast_signed(l->has_sign() && r->has_sign()); cast_signed(l->has_sign() && r->has_sign());
}
} }
NetEBMult::~NetEBMult() NetEBMult::~NetEBMult()
@ -276,6 +274,7 @@ NetEBMult* NetEBMult::dup_expr() const
{ {
NetEBMult*result = new NetEBMult(op_, left_->dup_expr(), NetEBMult*result = new NetEBMult(op_, left_->dup_expr(),
right_->dup_expr()); right_->dup_expr());
result->expr_width(expr_width());
return result; return result;
} }
@ -294,8 +293,8 @@ NetEBPow::NetEBPow(char op__, NetExpr*l, NetExpr*r)
: NetEBinary(op__, l, r) : NetEBinary(op__, l, r)
{ {
assert(op__ == 'p'); assert(op__ == 'p');
/* This is incorrect! a * (2^b - 1) is close. */ /* You could need up to a * (2^b - 1) bits. */
expr_width(l->expr_width()+r->expr_width()); expr_width(l->expr_width());
cast_signed(l->has_sign() || r->has_sign()); cast_signed(l->has_sign() || r->has_sign());
} }
@ -438,6 +437,7 @@ NetECReal::NetECReal(const verireal&val)
: value_(val) : value_(val)
{ {
expr_width(1); expr_width(1);
cast_signed(true);
} }
NetECReal::~NetECReal() NetECReal::~NetECReal()
@ -489,18 +489,21 @@ const NetScope* NetECRealParam::scope() const
NetEParam::NetEParam() NetEParam::NetEParam()
: des_(0), scope_(0) : des_(0), scope_(0)
{ {
solving_ = false;
} }
NetEParam::NetEParam(Design*d, NetScope*s, perm_string n) NetEParam::NetEParam(Design*d, NetScope*s, perm_string n)
: des_(d), scope_(s), reference_(scope_->find_parameter(n)) : des_(d), scope_(s), reference_(scope_->find_parameter(n))
{ {
cast_signed_base_(reference_->second.signed_flag); cast_signed_base_(reference_->second.signed_flag);
solving_ = false;
} }
NetEParam::NetEParam(Design*d, NetScope*s, ref_t ref) NetEParam::NetEParam(Design*d, NetScope*s, ref_t ref)
: des_(d), scope_(s), reference_(ref) : des_(d), scope_(s), reference_(ref)
{ {
cast_signed_base_(reference_->second.signed_flag); cast_signed_base_(reference_->second.signed_flag);
solving_ = false;
} }
NetEParam::~NetEParam() NetEParam::~NetEParam()
@ -520,10 +523,21 @@ ivl_variable_type_t NetEParam::expr_type() const
NetEParam* NetEParam::dup_expr() const NetEParam* NetEParam::dup_expr() const
{ {
NetEParam*tmp = new NetEParam(des_, scope_, reference_); NetEParam*tmp = new NetEParam(des_, scope_, reference_);
tmp->solving(solving_);
tmp->set_line(*this); tmp->set_line(*this);
return tmp; return tmp;
} }
void NetEParam::solving(bool arg)
{
solving_ = arg;
}
bool NetEParam::solving() const
{
return solving_;
}
NetESelect::NetESelect(NetExpr*exp, NetExpr*base, unsigned wid) NetESelect::NetESelect(NetExpr*exp, NetExpr*base, unsigned wid)
: expr_(exp), base_(base) : expr_(exp), base_(base)
{ {

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 * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -29,9 +29,10 @@
* which accounts for all the inputs, plus one for the phantom output * which accounts for all the inputs, plus one for the phantom output
* that is the result. * that is the result.
*/ */
NetUserFunc::NetUserFunc(NetScope*s, perm_string n, NetScope*d, NetEvWait*trigger) NetUserFunc::NetUserFunc(NetScope*s, perm_string n, NetScope*d,
NetEvWait*trigger__)
: NetNode(s, n, d->func_def()->port_count()+1), : NetNode(s, n, d->func_def()->port_count()+1),
def_(d), trigger_(trigger) def_(d), trigger_(trigger__)
{ {
pin(0).set_dir(Link::OUTPUT); pin(0).set_dir(Link::OUTPUT);
@ -128,8 +129,8 @@ bool PECallFunction::check_call_matches_definition_(Design*des, NetScope*dscope)
NetSysFunc::NetSysFunc(NetScope*s, perm_string n, NetSysFunc::NetSysFunc(NetScope*s, perm_string n,
const struct sfunc_return_type*def, const struct sfunc_return_type*def,
unsigned ports, NetEvWait*trigger) unsigned ports, NetEvWait*trigger__)
: NetNode(s, n, ports), def_(def), trigger_(trigger) : NetNode(s, n, ports), def_(def), trigger_(trigger__)
{ {
pin(0).set_dir(Link::OUTPUT); // Q pin(0).set_dir(Link::OUTPUT); // Q

View File

@ -26,9 +26,7 @@
# include <cstring> # include <cstring>
# include <string> # include <string>
# include <typeinfo> # include <typeinfo>
#ifdef HAVE_MALLOC_H # include <cstdlib>
# include <malloc.h>
#endif
void connect(Nexus*l, Link&r) void connect(Nexus*l, Link&r)
{ {
@ -173,7 +171,7 @@ void Link::unlink()
bool Link::is_equal(const Link&that) const bool Link::is_equal(const Link&that) const
{ {
return (node_ == that.node_) && (pin_ == that.pin_); return (get_obj() == that.get_obj()) && (get_pin() == that.get_pin());
} }
bool Link::is_linked() const bool Link::is_linked() const
@ -261,6 +259,25 @@ verinum::V Nexus::get_init() const
return verinum::Vz; return verinum::Vz;
} }
bool Nexus::assign_lval() const
{
assert(list_);
for (Link*cur = list_ ; cur ; cur = cur->next_) {
const NetPins*obj;
unsigned pin;
cur->cur_link(obj, pin);
const NetNet*net = dynamic_cast<const NetNet*> (obj);
if (net == 0)
continue;
if (net->peek_lref())
return true;
}
return false;
}
bool Nexus::drivers_present() const bool Nexus::drivers_present() const
{ {
assert(list_); assert(list_);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2002-2008 Stephen Williams (steve@icarus.com) * Copyright (c) 2002-2011 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -23,6 +23,7 @@
# include <cassert> # include <cassert>
# include <typeinfo> # include <typeinfo>
# include "compiler.h"
# include "netlist.h" # include "netlist.h"
# include "netmisc.h" # include "netmisc.h"
@ -114,26 +115,58 @@ NexusSet* NetESelect::nex_input(bool rem_out)
} }
result->add(*tmp); result->add(*tmp);
delete tmp; delete tmp;
/* See the comment for NetESignal below. */
if (base_ && warn_sens_entire_vec) {
cerr << get_fileline() << ": warning: @* is sensitive to all "
"bits in '" << *expr_ << "'." << endl;
}
return result; return result;
} }
/*
* The $fread, etc. system functions can have NULL arguments.
*/
NexusSet* NetESFunc::nex_input(bool rem_out) NexusSet* NetESFunc::nex_input(bool rem_out)
{ {
if (nparms_ == 0) if (nparms_ == 0)
return new NexusSet; return new NexusSet;
NexusSet*result = parms_[0]->nex_input(rem_out); NexusSet*result;
if (parms_[0]) result = parms_[0]->nex_input(rem_out);
else result = new NexusSet;
for (unsigned idx = 1 ; idx < nparms_ ; idx += 1) { for (unsigned idx = 1 ; idx < nparms_ ; idx += 1) {
NexusSet*tmp = parms_[idx]->nex_input(rem_out); if (parms_[idx]) {
result->add(*tmp); NexusSet*tmp = parms_[idx]->nex_input(rem_out);
delete tmp; result->add(*tmp);
delete tmp;
}
} }
return result; return result;
} }
NexusSet* NetESignal::nex_input(bool rem_out) NexusSet* NetESignal::nex_input(bool rem_out)
{ {
/*
* This is not what I would expect for the various selects (bit,
* part, index, array). This code adds all the bits/array words
* instead of building the appropriate select and then using it
* as the trigger. Other simulators also add everything.
*/
NexusSet*result = new NexusSet; NexusSet*result = new NexusSet;
/* Local signals are not added to the sensitivity list. */
if (net_->local_flag()) return result;
/* If we have an array index add it to the sensitivity list. */
if (word_) {
NexusSet*tmp;
tmp = word_->nex_input(rem_out);
result->add(*tmp);
delete tmp;
if (warn_sens_entire_arr) {
cerr << get_fileline() << ": warning: @* is sensitive to all "
<< net_->array_count() << " words in array '"
<< name() << "'." << endl;
}
}
for (unsigned idx = 0 ; idx < net_->pin_count() ; idx += 1) for (unsigned idx = 0 ; idx < net_->pin_count() ; idx += 1)
result->add(net_->pin(idx).nexus()); result->add(net_->pin(idx).nexus());
@ -363,16 +396,23 @@ NexusSet* NetRepeat::nex_input(bool rem_out)
return result; return result;
} }
/*
* The $display, etc. system tasks can have NULL arguments.
*/
NexusSet* NetSTask::nex_input(bool rem_out) NexusSet* NetSTask::nex_input(bool rem_out)
{ {
if (parms_.count() == 0) if (parms_.count() == 0)
return new NexusSet; return new NexusSet;
NexusSet*result = parms_[0]->nex_input(rem_out); NexusSet*result;
if (parms_[0]) result = parms_[0]->nex_input(rem_out);
else result = new NexusSet;
for (unsigned idx = 1 ; idx < parms_.count() ; idx += 1) { for (unsigned idx = 1 ; idx < parms_.count() ; idx += 1) {
NexusSet*tmp = parms_[idx]->nex_input(rem_out); if (parms_[idx]) {
result->add(*tmp); NexusSet*tmp = parms_[idx]->nex_input(rem_out);
delete tmp; result->add(*tmp);
delete tmp;
}
} }
return result; return result;

View File

@ -20,7 +20,7 @@
# include "config.h" # include "config.h"
# include "netlist.h" # include "netlist.h"
# include <assert.h> # include <cassert>
NetBlock::NetBlock(Type t, NetScope*ss) NetBlock::NetBlock(Type t, NetScope*ss)
: type_(t), subscope_(ss), last_(0) : type_(t), subscope_(ss), last_(0)

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