Compare commits

...
134 Commits
Author SHA1 Message Date
Martin Whitaker b2f2414f48 Add regression test for issue #756.
(cherry picked from commit 899d459233)
2022-08-27 16:23:46 +01:00
Martin Whitaker 689a1c27a8 Fix expansion of unbased unsized literal in port assignment (issue #756)
(cherry picked from commit 310e239637)
2022-08-27 16:22:39 +01:00
Martin Whitaker af2b952769 Add regression test for br_gh672.
(cherry picked from commit 6b5d7a3695)
2022-04-12 17:25:14 +01:00
Martin Whitaker 0ad16a6c0b Fix behaviour of fork/join_none with only one statement (issue #672).
The compiler normally optimises away the enclosing block statement
if a block only contains one statement. But this is not valid for
a fork/join_none block.

(cherry picked from commit 313f376394)
2022-04-12 17:21:14 +01:00
Martin Whitaker f8e29ee5e1 Add regression test for br_gh674.
(cherry picked from commit 50ae8cf552)
2022-04-10 22:43:17 +01:00
Martin Whitaker 14d458dd78 Handle negative OOB access to local array in constant function (issue #674)
The word select expression is a zero-based canonical index, but the
expression evaluation may return a negative value.

(cherry picked from commit 82caccd4eb)
2022-04-10 22:42:56 +01:00
Martin Whitaker 05e3e13fbd Add multi-file VPI test.
(cherry picked from commit 8a19380a5d)
2022-03-27 11:26:24 +01:00
Martin Whitaker 38ab5f9b2c Fix iverilog-vpi on Windows to handle more than one source file (issue #602)
Use the string containing the current source file path to derive the
object file name, not the string containing the space-separated list
of source files.

(thanks to DavidC-75 for pointing out the error)

(cherry picked from commit 7dcde37475)
2022-03-27 11:26:09 +01:00
Martin Whitaker 1f4e65ee08 vvp: Fix implementation of strndup for Windows (issue #608).
The maximum length to copy, n, does not include the terminating null
character.

(cherry picked from commit 4c36b2a8a7)
2022-03-25 21:07:52 +00:00
Martin Whitaker 5aef565b94 vvp: Fix error message output when a VPI module can't be found.
(cherry picked from commit 3c58ca908d)
2022-03-25 21:07:42 +00:00
Martin Whitaker 20b5377989 vvp: Accept either \ or / as path separators in the -m option (issue #606).
Windows system calls will accept either of these. This is already done in
the iverilog driver.

(cherry picked from commit 2bf753fd8f)
2022-03-25 21:07:32 +00:00
Cary R f247fe532f Update to the latest from GTKWave 2022-03-22 23:32:36 -07:00
Martin Whitaker 598363de84 vvp: ensure array ports are added to the correct context (issue #621)
Array ports are created via a resolve list. We need to detect and
record whether they need to be created in an automatic context at
the point they are declared, not at the time they are created.

(cherry picked from commit b3f7ce6020)
2022-03-21 20:10:43 +00:00
Martin Whitaker 7b9407f66d Add regression test for issue #621.
(cherry picked from commit 2c505f0040)
2022-03-21 20:09:42 +00:00
Martin Whitaker fcb64232de Report correct net name in synthesis "sorry" message (issue #649).
(cherry picked from commit b7f948193a)
2022-03-19 13:03:48 +00:00
Martin Whitaker ff21f02c6c Further fixes for vvp code generation for c. assign of an array word.
The draw_net_input() function can write additional statements to the output
file, so must not be called in the midst of writing a statement.

(cherry picked from commit e53b2e774b)
2022-03-19 11:36:36 +00:00
Martin Whitaker 92e4597607 Fix vvp code generation for c. assign shift of array word (issue #632)
(cherry picked from commit 831db5a0d7)
2022-03-15 09:31:22 +00:00
Stephen Williams 37a8b9a6c7 Merge pull request #625 from steveicarus/vvp_stop_scopes-v11
Add more types to vvp-stop
2022-02-26 12:54:41 -08:00
Stephen Williams 899a240311 Add more types to vvp-stop
Several scope types were not understood by the push command, and
a few types were not displayed reasonably. Flesh these out.

(cherry picked from commit de579f2650)
2022-02-26 12:19:16 -08:00
Stephen Williams 631fa17002 Merge pull request #588 from steveicarus/ivtests-fail-exit-v11
v11 fulling using included ivtests, and remove the checked in regression_report files.
2022-01-16 16:39:33 -08:00
Stephen Williams a48769f5d4 ivtest: Mark as NI tests that are known to fail.
Mark them as NI so that in the fugure they might be turned back
on if they can be made to work. Keep the tests around as reference.

Also, remove reports that are no longer tested in CI. This is because
they are no longer tested by a previous patch that relies on the
change vvp_reg.pl behavior around failed tests.

Remove now obsolete update_msys2_report.pl, and simplify the test.sh
script, since diff commands and Windows specific trickery are no
longer needed.
2022-01-16 16:03:03 -08:00
Stephen Williams 5b82d69636 ivtest: vvp_reg.pl sets exit status
If there are any failures, return a non-zero exit status so that
invoking scripts can detect that failures happen. This eliminates
the need to use regression report reference outputs, and should
make it easier to merge PRs that add or impact tests.
2022-01-16 15:56:20 -08:00
Stephen Williams c4d07b6a62 Drop workaround that documentation goes missing for msys2 build. 2022-01-16 09:00:16 -08:00
Martin Whitaker 9bf45e89f0 Fix CI on Windows again.
man-db has now been removed from the base-devel group.

(cherry picked from commit f705e7b61c)
2022-01-15 23:45:14 +00:00
Stephen Williams b17a967ced Merge pull request #583 from steveicarus/bring-in-ivtest
v11: Add ivtest to the iverilog source tree
2022-01-15 13:42:59 -08:00
Stephen Williams 6f114cce17 Do not fail msys build if there are no pdf files installed. 2022-01-15 13:15:12 -08:00
Stephen Williams fd30e57337 Fix up some v11 issues brought on by ivtests issues
The ivtest suite from the master branch has a few bits that the
v11-branch cannot handle. So here we start seeing the test suites
diverge for releases.
2022-01-15 11:53:31 -08:00
Stephen Williams 74f7dacc86 Add ivtest to the iverilog source tree
By adding ivtest to the iverilog source tree, it is easier to keep
the regression test synchronized with the source that is being tested.
This should be especially helpful for PRs that add a new feature, and
have a matching ivtest PR with the regression test for that feature.
2022-01-15 11:05:49 -08:00
Miodrag Milanovic 3e84e6e93a Fix find_ivl_root for OSX
(cherry picked from commit 57cfbc0cea)
2022-01-06 08:34:04 +00:00
Lars-Peter Clausen 7d3c25f39a Short circuit logical operator to constant if possible
If the left-hand side of a logical operator is a constant that causes the
right-hand side to be short-circuited the right-hand side can be discarded
even if it is not constant.

In this case replace the expression by a constant.

E.g.
 * `0 && expr` will be replaced by a constant 0.
 * `1 || expr` will be replaced by a constant 1.
 * `0 -> expr` will be replaced by a constant 1.

Note that it is not possible to replace the expression by a constant if
only the right-hand side is a constant, even when the value of the
expression is constant. The left side still has to be evaluated for side
effects.

E.g. it is known at elaboration that `a++ && 0` will yield 0, but the
increment on `a` has to be executed regardless.

Signed-off-by: Lars-Peter Clausen <[email protected]>
(cherry picked from commit 957e3d482f)
2021-12-31 09:48:23 +00:00
Lars-Peter Clausen 48e26a44d7 tgt-vvp: Short circuit logical operators
Section 11.4.7 of the SystemVerilog LRM states

```
The && and || operators shall use short circuit evaluation as follows:
  - The first operand expression shall always be evaluated.
  - For &&, if the first operand value is logically false then the second operand shall not be evaluated.
  - For ||, if the first operand value is logically true then the second operand shall not be evaluated.
```

vvp currently evaluates both operands of a logical operator. This works
fine as long as the right-hand side does not have a side effect. But if it
has the result might be incorrect.

E.g. for `a && b++` `b` must not be incremented if `a` evaluates to false.

The Verilog LRM mentions that it is allowed to short circuit any expression
"if the final result of an expression can be determined early". But there
is no requirement to do so.

So the new and the old behavior are both correct implementations in
Verilog.

Use the new behavior in both Verilog and SystemVerilog mode to make sure
the behavior is consistent when an expression has side effects.

Signed-off-by: Lars-Peter Clausen <[email protected]>
(cherry picked from commit d4334139d3)
2021-12-31 09:47:20 +00:00
Lars-Peter Clausen f436565dfe tgt-vvp: Consolidate vec4 logical and and or generation
The code for generating the logical `and` and `or` operators is identical
except for the final opcode to combine the two results.

Consolidate this into a single function to reduce the code a bit.

Signed-off-by: Lars-Peter Clausen <[email protected]>
(cherry picked from commit 2fa7260a4c)
2021-12-31 09:47:15 +00:00
Michael Singer 6b494eaa11 Fix unique0 keyword/token mapping
(cherry picked from commit 6c60851558)
2021-12-31 09:46:26 +00:00
Miodrag Milanovic 687dc0c751 Fix for cross compile build
(cherry picked from commit 1341dee0e6)
2021-12-31 09:45:34 +00:00
Martin Whitaker f7ca845a47 Fix CI on Windows.
autoconf has been removed from the MSYS2 base-devel group.
2021-12-30 11:33:36 +00:00
Martin Whitaker 48ab896fa6 Warn when a negative value is assigned to a genvar (-g2001 only) (issue #567)
(cherry picked from commit 668f9850bc)
2021-12-13 22:17:16 +00:00
Martin Whitaker cdbc2c466f Fix genvar increment/decrement operations to be signed (issue #568)
(cherry picked from commit e1d6fd78f4)
2021-12-13 22:17:08 +00:00
Martin Whitaker 038fbe609d Change compiler's generate loop counter from int to long.
This matches the type of the values assigned to it, and exposes a bug that
was previously only showing up under Windows.

(cherry picked from commit 67b9374c69)
2021-12-13 22:17:00 +00:00
Martin Whitaker a317a066af Improve error message on assignment to an array or array slice (issue #562).
This is valid SystemVerilog, but not something we support yet.

(cherry picked from commit 71c36d1289)
2021-11-12 22:52:02 +00:00
Martin Whitaker c7ee6157fc Fix an assertion failure when a variable name is replicated in the same list.
(cherry picked from commit 61aed6882c)
2021-11-12 22:51:52 +00:00
Martin Whitaker c00104bc50 Remove unreachable code.
pform_get_or_make_wire() should always return a valid pointer. Replace the
existing unreachable code with an assertion.

(cherry picked from commit 3c23180af3)
2021-11-12 22:51:41 +00:00
Cary R 56d69f498b Fix valgrind compile to work with new using std reorg 2021-11-10 18:21:23 -08:00
Martin Whitaker 12d67bb9ae Support SV [size] dimension for module and gate instances (issue #553).
Also output a proper error message if multiple dimensions are supplied
instead of failing an assertion.

(cherry picked from commit dcc9b59f6d)
2021-11-06 08:44:13 +00:00
Martin Whitaker c288487810 Clean up indentation.
(cherry picked from commit dbf55da0f5)
2021-11-06 08:40:58 +00:00
Martin Whitaker 7ba381a0d0 Remove buggy assertion.
If this assert fires, the "this" pointer we pass to it will be a
null pointer, so will cause a null pointer dereference. We've
tested it is not null earlier, so we don't need the assertion.
2021-11-04 19:35:22 +00:00
Martin Whitaker 97b5ac91cb Remove "using namespace std" from vvp header files and fix the fallout.
(cherry picked from commit 9cc09b8513)
2021-11-04 19:32:09 +00:00
Martin Whitaker 5533ff848b Remove "using namespace std" from tgt-vhdl header files and fix the fallout.
(cherry picked from commit 23390c1ba3)
2021-11-04 19:30:21 +00:00
Martin Whitaker 52b099feae Remove "using namespace std" from compiler header files and fix the fallout.
(cherry picked from commit ecbbb60fb6)
2021-11-04 19:22:43 +00:00
Martin Whitaker 9ac6154068 Handle run-time out-of-bounds access for wire real arrays (issue #556).
(cherry picked from commit 3dda39bce3)
2021-11-04 18:48:22 +00:00
Cary R 2b7ee675ee Update fstapi.c to the latest from GTKWave 2021-10-26 19:41:37 -07:00
Martin Whitaker 5ea6ee130e Fix signedness of non-ANSI port declarations (issue #540).
For non-ANSI port declarations that have both a port declaration and
a corresponding variable declaration, the signed attribute may be
attached to either the port declaration or the variable declaration,
or both declarations.

(cherry picked from commit ef01dd1e81)
2021-09-10 23:12:42 +01:00
Martin Whitaker 066eb0aca7 Check that a genvar is not shadowed when used in a generate loop construct.
This also ensures the same genvar cannot be used in two nested loops
(issue #533), because the implicit localparam with the same name
shadows the genvar declaration.

(cherry picked from commit 7ee7a48310)
2021-08-04 15:41:21 +01:00
Martin Whitaker 4c428a536e Include named events in checks for name collisions.
(cherry picked from commit cefcffecda)
2021-08-04 15:41:10 +01:00
Martin Whitaker 1ff4bfa63d Include typedefs in checks for name collisions.
This requires us to make a copy of the typedefs map when adding it to
a NetScope object, because the pform data is deleted before we are
finished with it.

(cherry picked from commit a17557575d)
2021-08-04 15:41:02 +01:00
Martin Whitaker 79a5e90e4d Avoid name collisions when naming unnamed generate blocks.
As specified in the IEEE standard, the automatically generated name
must not conflict with any explicitly declared name (not just scope
names).

(cherry picked from commit 7445b424f1)
2021-08-04 15:40:53 +01:00
Martin Whitaker 2f75fe4053 Fix naming of unnamed generate blocks (issue #528)
The IEEE standard specifies that the numbering of generate blocks
restarts at 1 in each new scope, and that the 'else' part of an 'if'
construct is part of the same constuct, so has the same number.

(cherry picked from commit ceb2581368)
2021-08-04 15:40:42 +01:00
Martin Whitaker 19dc81a242 Fix detection of directly nested generate constructs.
If a generate construct is enclosed in a begin-end pair, it can't
be directly nested (1364-2005 section 12.4.2).

(cherry picked from commit c34167b2c0)
2021-08-04 15:40:20 +01:00
Martin Whitaker 987ac819a9 Use a list instead of a set for storing the potential package imports.
This eliminates some indeterminism in the error messages, which was
causing occasional failures in CI. We don't expect this list to be
very large, so the O(n) insertion time should not be a problem.

(cherry picked from commit 389e2a3a94)
2021-07-31 19:22:44 +01:00
Martin Whitaker c564184bd1 Fix evaluation of out-of-bounds bit/part-select in constant function (issue #531).
(cherry picked from commit 3b1b611a18)
2021-07-30 22:52:02 +01:00
Martin Whitaker b48cdff89e Fix segfault in wildcard port connection with unnamed port (issue #530).
A module port list may contain unnamed entries, e.g.

  module dut(a,);

When performing a wildcard connection, these entries should be skipped,
as there is no name to match.

(cherry picked from commit 061121203b)
2021-07-30 22:51:52 +01:00
Cary R d3b0992a22 Cleanup space 2021-06-20 22:51:41 -07:00
Cary R 5a9ff97df5 Update pform_dump copyright year 2021-06-20 22:40:34 -07:00
Cary R 87d7881365 Correctly dump case items 2021-06-20 22:39:53 -07:00
Cary R afe008ca75 Update fstapi files to latest from GTKWave 2021-06-17 21:41:46 -07:00
Martin Whitaker b45a52a164 Fix .event/or connectivity when inputs have multiple fanout (issue #508).
The old implementation connected all inputs to the same vvp_net_t port,
on the basis that we don't care about the data values or what port they
arrived on. But if one or more of the inputs fans out to multiple nets,
the chains get tangled, which either results in connections being lost
or inappropriate connections being made, depending on the order that
the inputs are linked.

This could have been fixed by using a standard wide functor. But as we
don't care about the data values, that would be unnecessary overhead.
We just need separate vvp_net_t objects to handle the input connectivity
and can keep using a single shared functor.

(cherry picked from commit 1f8876be1c)
2021-05-18 10:08:01 +01:00
Martin Whitaker a676db798a Remove redundant elab_and_eval_lossless().
(cherry picked from commit 711623f682)
2021-05-16 22:38:53 +01:00
Martin Whitaker a14118cd6c Do not force lossless calculation for index expressions (issue #515)
The standard Verilog expression bit length rules must be used.

(cherry picked from commit a040ddc070)
2021-05-16 22:38:44 +01:00
Martin Whitaker 0bd51dbfb8 Record the actual data type when a module port has an enum type.
This fixes assignment compatibility problems (issue #498).

(cherry picked from commit cf0bf4d9aa)
2021-04-28 20:35:57 +01:00
Martin Whitaker ada3067899 Fix waveform dumpers to use vpiInstance when dumping all variables.
(cherry picked from commit a7cb93842e)
2021-04-21 11:42:14 +01:00
Martin Whitaker 69cf8d8901 Add support for vpiInstance as the type code in calls to vpi_iterate().
This is needed for the waveform dumpers now that vpi_iterate(vpiModule, NULL)
has been ficed to only return modules.

This includes recognising vpiProgram and vpiInterface, although the compiler
and vvp currently incorrectly classify them as modules.

(cherry picked from commit d2521878d7)
2021-04-21 11:41:51 +01:00
Martin Whitaker a83a205b06 Properly report errors for out-of-bounds constant indexed part selects.
(replacing assertions)

The IEEE standard either requires out-of-bounds bits to be ignored on
write, returned as 1'bx on read, or requires a compile-time error message.
The latter is easier to implement.

(cherry picked from commit 7d7aa0604c)
2021-04-21 11:41:07 +01:00
Martin Whitaker c0c46dc173 Support indexed part selects that index sub-arrays (issue #497)
(cherry picked from commit 4af830187e)
2021-04-21 11:39:48 +01:00
Cary R cccf36d76f Fix warning and little E full vector up/down selects
(cherry picked from commit 0c12344b27)
2021-04-21 11:39:40 +01:00
Martin Whitaker f64c831688 Fix width calculation for bit/part selects of multi-dimensioned packed arrays.
If we have a bit/part select that is selecting one or more sub-arrays, e.g.

  wire [3:0][3:0] foo;
  assign foo[1] = 4'd1;

we need to take into account the bit width of the sub-array when calculating
the bit width of the select.

(cherry picked from commit 7c024d6cab)
2021-04-21 11:39:01 +01:00
Martin Whitaker adb4be5c75 Don't return packages when iterating over root modules (issue #496)
The code assumed all handles stored in vpip_root_table were modules. This
is true for traditional Verilog, but not so for SystemVerilog.

Whilst here, also add support for iterating over packages.

(cherry picked from commit 3167b2ed24)
2021-04-18 10:53:34 +01:00
Cary R eaea698027 V11: Add support to include macro expanded strings 2021-02-13 16:58:09 -08:00
Cary R 338b9a69ee Update severity tasks to match devel 2021-02-01 00:23:35 -08:00
Cary R b613cf4bf5 Update warning to match devel 2021-01-30 14:29:09 -08:00
Martin Whitaker a89eab47f5 CI: run 'make check' before 'make install'.
This makes sure 'make check' works when iverilog isn't already
installed on the system.
2021-01-28 00:38:45 +00:00
Martin Whitaker 0d9268cdbc Don't exit when ivl_root not found - the user may have supplied it.
When running 'make check' without having an installed copy, find_ivl_root()
will fail on Unix systems that don't provide /proc/self/exe (e.g. MacOS).

(cherry picked from commit 56d2d798ec)
2021-01-28 00:34:11 +00:00
Cary R f806ed5084 Add define to indicate Icarus synthesis 2021-01-14 00:15:58 -08:00
Cary R e396369410 Update copyright data to match patch 2021-01-11 21:39:26 -08:00
Cary R 9771be8ba1 Fix index down part selects to work with multiple dimensions 2021-01-11 21:39:16 -08:00
Martin Whitaker 3d7d2e5502 Explicitly require C99 if using autoconf < 2.70.
(cherry picked from commit 57e87149e8)
2021-01-05 21:02:12 +00:00
Martin Whitaker 8c4dd80944 Remove redundant assignment. 2021-01-03 19:59:09 +00:00
Martin Whitaker b58ca95909 Elaborate package scopes in textual order (fix for issue #461)
When elaborating a subclass, the base class scope needs to be elaborated
before the subclass scope. If the base class and subclass are defined in
different packages, this requires the package scopes to be elaborated in
the correct order. SystemVerilog reqires packages to be defined before
they are used, so that is the order we should elaborate them in.

(cherry picked from commit ba25b55f53)
2021-01-03 19:50:49 +00:00
Martin Whitaker 7866168cf7 Protect against infinite recursion in NetScope::find_class().
(cherry picked from commit 9fa9a9d95a)
2021-01-03 19:50:40 +00:00
Martin Whitaker d56efebbfe Fix build with clang.
(cherry picked from commit aae3a570c2)
2021-01-03 19:50:05 +00:00
Martin Whitaker 48615fb8ac Fix warnings about implicit copy assignments.
(cherry picked from commit 51a171a399)
2021-01-03 19:49:06 +00:00
Martin Whitaker 25154b6482 Avoid possible truncation of path strings when writing config file.
(cherry picked from commit 2e4bf05e21)
2021-01-03 19:47:29 +00:00
Martin Whitaker d9484b4f75 Fix configure scripts to work with autoconf 2.70.
Numerous deprecated features have now become obsolete. Mostly done by
running autoupdate, but that left a few fixes to be done manually.

This includes the latest version of AX_PROG_CC_FOR_BUILD from
https://www.gnu.org/software/autoconf-archive/ax_prog_cc_for_build.html

(cherry picked from commit 4b3e1099e5)
2021-01-03 19:08:32 +00:00
Stephen Williams 859e3e39be Merge pull request #458 from steveicarus/steveicarus/v11-real-output-port
output ports of type real are variables, not wires.
2020-12-29 22:45:10 -08:00
Stephen Williams c690558cd6 output ports of type real are variables, not wires. 2020-12-29 22:22:20 -08:00
Cary R 838349590e Remove R-value class check until class variables are found correctly 2020-12-28 04:55:50 -08:00
Cary R 5aac481d9a Report operators that cannot be used with null/class vars 2020-12-27 19:06:01 -08:00
Cary R 363f45cd7d Handle a void function call in the delay type calculation 2020-12-27 12:54:39 -08:00
Cary R b4d8108409 Check if no argument task calls are allowed in the current context 2020-12-27 12:52:33 -08:00
Martin Whitaker c8aa7bf873 Fix search for class imported from another package (issue #437).
(cherry picked from commit a019994513)
2020-12-23 19:17:59 +00:00
Cary R 864c09d034 Add support for calling queue/darray functions as tasks 2020-12-20 16:50:44 -08:00
Cary R b62c37ea58 Update to the latest GTKWave files 2020-12-20 12:52:05 -08:00
Martin Whitaker ebad47937e Support macro text continuation after single line comment (issue #435)
(cherry picked from commit fe79f130b5)
2020-12-20 13:16:02 +00:00
Martin Whitaker 45c52d5291 Fix CI test.sh to return an exit code of 1 if any step fails.
(cherry picked from commit a1dd6bb056)
2020-12-14 11:37:08 +00:00
Martin Whitaker 8d8cb16b72 tgt-vlog95: fix assertion failure when function calls a void function
(cherry picked from commit f4d22af4bd)
2020-12-13 22:59:26 +00:00
Martin Whitaker 04b0a1f80d Add extra debug output.
(cherry picked from commit fbd87b4fee)
2020-12-13 22:59:01 +00:00
Martin Whitaker 1fda3ff23e Fix assertion failure when elaborating a void function call (issue #318)
Depending on the order of elaboration, a function may not have been
elaborated before a call to it is elaborated, so don't assert that it
has been. As an optimisation, try to elaborate it on the fly, so we can
elide the call if the function body is empty.

(cherry picked from commit 393236a9a8)
2020-12-13 22:58:48 +00:00
Martin Whitaker bfac44a630 Fix assertion failure for function body with single null statement (GH issue #411)
(cherry picked from commit 94b503fc64)
2020-12-10 17:42:10 +00:00
Martin Whitaker 27986477fb Further fix to CI test script. 2020-12-05 22:55:23 +00:00
Martin Whitaker 0b991f5a28 Fix CI test script. 2020-12-05 22:01:38 +00:00
Martin Whitaker e3ed4b28e7 Fix MSYS2 pkgver to only use allowed characters. 2020-12-05 21:55:18 +00:00
Martin Whitaker 9de8577e04 Convert CI from Travis to GitHub Actions.
Copied and adapted from the master branch, with thanks to
umarcor <[email protected]> who did the original
work.
2020-12-05 21:43:09 +00:00
Tim b415678d5c Clarify "Standard inconsistency" warning
Fixes #343

(cherry picked from commit 2dcbfca5d9)
2020-12-05 21:28:01 +00:00
Martin Whitaker eec64de190 Fix vvp segfault on Windows when vvp_net_ptr_t values exceed 4GB.
Under Windows unsigned long is 32 bits, so we must use unsigned long long
values for 64-bit address masks.

(cherry picked from commit 0d6a2f95a8)
2020-12-05 21:08:30 +00:00
umarcor 1baeb0d671 driver-vpi: add DESTDIR to iverilog-vpi install path
(cherry picked from commit dbe15b6a46)
2020-12-05 21:08:10 +00:00
umarcor 26aaa42831 doc: add MSYS2 readme
(cherry picked from commit ae5be2b61f)
2020-12-05 21:04:05 +00:00
Martin Whitaker 7befefc65f Fix the libveriuser TF and ACC functions to work in callbacks.
Use the new cur_instance variable to get the call handle instead of calling
vpi_handle(vpiSysTfCall, 0).

This completes a proper fix for issue #141, to replace the problematic fix
that was reverted in commit 8da8261f.

(cherry picked from commit 360d1ca447)
2020-12-05 21:03:07 +00:00
Martin Whitaker 5667c63907 Rework libveriuser to make vpiSysTfCall handles available in callbacks.
PLI 1.0 callbacks are directly associated with the instance of the system
task/function that initiated them, allowing them to access the task/function
arguments. However, we implement them using VPI callbacks, which are not so
associated. So we need to pass the VPI handle for the associated task/function
instance to the callback routine via the VPI callback user_data pointer,
because vpi_handle(vpiSysTfCall, 0) will return null when called from the
callback function.

This is the first step to a proper fix for issue #141, to replace the
problematic fix that was reverted in commit 8da8261f.

(cherry picked from commit 3f9a49ae01)
2020-12-05 21:02:53 +00:00
Martin Whitaker 580170d974 Fix segfault under mingw32 due to dynamic cast of invalid pointer value.
sync_cb::run_run() attempts to cast the obj field of the callback data to a
__vpiSysTaskCall pointer. But a sync_cb object is only used for simulation
time callbacks, where the obj field is (mostly) not used, so I can't see
that would ever succeed. As the obj field is not required to be set by the
user, the dynamic cast results in undefined behaviour, so mingw32 is not to
blame.

This code was introduced by Johann Klammer in commit c79df7c44, but the user
klammerj and all trace of that pull request have vanished from GitHub, and
there is no associated regression test, so I can't establish the rationale
for it.

(cherry picked from commit 8da8261fc3)
2020-12-05 21:02:27 +00:00
Cary R d0e2ed1509 Report a package connot be dumped with most dumpers 2020-11-29 12:44:15 -08:00
Martin Whitaker 4598341e85 In Windows, export VPI functions from vvp.exe (GitHub issue #395)
This is to support cocotb, who don't use our vpi_user.h and libvpi.a,
instead building their own import library to directly link to vvp.

(cherry picked from commit 159af4d4ba)
2020-11-24 20:04:26 +00:00
Martin Whitaker 55e2c5abef Support passing class objects as task/function arguments (GitHub issure #391)
(cherry picked from commit b0b44fdd8a)
2020-11-24 17:19:03 +00:00
Martin Whitaker 20c6d83ae9 Support calls to inherited methods without "this." prefix (GitHub issue #388).
(cherry picked from commit 55e06db693)
2020-11-23 22:06:47 +00:00
Cary R f0b3056bfc Add support for an empty ';' in the description text 2020-11-20 21:42:47 -08:00
Cary R 412195e660 Update module items to include just a ';' 2020-11-20 21:01:12 -08:00
Martin Whitaker 103f1fa4bb Add enumeration assignment compatibility check for continuous assignments.
(cherry picked from commit 1b3f0dd689)
2020-11-20 17:38:10 +00:00
Martin Whitaker d521585901 Fix expression type for packed struct member access (GitHub issue #386)
A NetESelect is used for accessing packed struct members and also for
accessing dynamic array elements. In these cases the expr_type() and
enumeration() methods should reflect the member/element type.

(cherry picked from commit 0fada92389)
2020-11-20 17:38:01 +00:00
Cary R 84fa910820 Move GNU lesser to tgt-vvp since that is the only place where LGPL code is located 2020-11-14 20:31:34 -08:00
Cary R ae0ee87363 Update some queue code since deques support random access 2020-11-14 20:31:27 -08:00
Martin Whitaker c09ae8869c Fix assertion failure when no value supplied with -P option (GitHub issue #377)
(cherry picked from commit d6e01d0c55)
2020-10-24 23:06:05 +01:00
Martin Whitaker 5b1d97fac7 Support escaped identifiers as macro names.
(cherry picked from commit 359b2b65c2)
2020-10-09 12:01:20 +01:00
Martin Whitaker 794e15ac56 Fix GitHub issue #374 - ordering of `` and embedded macro expansion.
The IEEE standard does not clearly state whether the `` directive is applied
before or after embedded macros are expanded. Other simulators vary in their
behaviour. For maximum compatibility, this fix adopts the behaviour found in
Verilator, where `prefix``suffix expands to <prefix>suffix if prefix is a
defined macro, otherwise it expands to <prefixsuffix> (where <...> is the
expanded macro text). Other simulators show this behaviour in at least some
circumstances.

(cherry picked from commit 6566072741)
2020-10-09 12:01:13 +01:00
Martin Whitaker 50cd3b107c Refactor task declaration parsing and fix warning for empty port list.
1364-2005 and later allow a task declaration with an empty port list.

(cherry picked from commit 6880b39770)
2020-10-03 09:38:46 +01:00
Martin Whitaker 59b67b69f6 Fix width of localparam created from genvar when using -gstrict-expr-width.
(cherry picked from commit c4883da334)
2020-10-01 11:37:04 +01:00
Stephen Williams 84b4ebee0c Mark version as stable. 2020-09-26 15:44:25 -07:00
Stephen Williams e66fbc9bf9 Prepare for Version 11.0 2020-09-26 13:36:43 -07:00
4060 changed files with 266797 additions and 2330 deletions
+14
View File
@@ -0,0 +1,14 @@
#!/usr/bin/env sh
echo "Using the bundled ivtest to run regression tests."
echo " pwd = $(pwd)"
cd ivtest
status=0
perl vvp_reg.pl || status=1
perl vpi_reg.pl || status=1
exit $status
+85
View File
@@ -0,0 +1,85 @@
name: test
on:
push:
pull_request:
jobs:
lin:
strategy:
fail-fast: false
matrix:
os: [
'18.04',
'20.04'
]
runs-on: ubuntu-${{ matrix.os }}
name: '🐧 Ubuntu ${{ matrix.os }}'
steps:
- uses: actions/checkout@v2
- name: Install dependencies
run: |
sudo apt update -qq
sudo apt install -y make g++ git bison flex gperf libreadline-dev autoconf
- name: Build, check and install
run: |
autoconf
./configure
make check
sudo make install
- name: Test
run: ./.github/test.sh
win:
runs-on: windows-latest
strategy:
fail-fast: false
matrix:
include: [
{ msystem: MINGW64, arch: x86_64 },
{ msystem: MINGW32, arch: i686 }
]
name: 🟪 ${{ matrix.msystem}} · ${{ matrix.arch }}
defaults:
run:
shell: msys2 {0}
env:
MINGW_INSTALLS: ${{ matrix.msystem }}
steps:
- run: git config --global core.autocrlf input
shell: bash
- uses: actions/checkout@v2
- uses: msys2/setup-msys2@v2
with:
msystem: ${{ matrix.msystem }}
update: true
install: >
git
base-devel
mingw-w64-${{ matrix.arch }}-toolchain
- name: Build and check
run: |
cd msys2
makepkg-mingw --noconfirm --noprogressbar -sCLf
- name: Install
run: pacman -U --noconfirm msys2/*.zst
- name: Test
run: ./.github/test.sh
- uses: actions/upload-artifact@v2
with:
name: ${{ matrix.msystem }}-${{ matrix.arch }}
path: msys2/*.zst
-71
View File
@@ -1,71 +0,0 @@
language: cpp
sudo: required
dist: xenial
addons:
apt:
packages:
- gperf
sudo: false
notifications:
email: false
jobs:
include:
- stage: Test
os: linux
dist: xenial
before_install:
- git clone https://github.com/steveicarus/ivtest.git
- export PATH=$HOME/bin:$PATH
script:
- autoconf
- ./configure --prefix=$HOME
- make install
- make check
- cd ivtest
- perl vvp_reg.pl
- diff regression_report-devel.txt regression_report.txt
- perl vpi_reg.pl
- stage: Test
os: linux
dist: bionic
before_install:
- git clone https://github.com/steveicarus/ivtest.git
- export PATH=$HOME/bin:$PATH
script:
- autoconf
- ./configure --prefix=$HOME
- make install
- make check
- cd ivtest
- perl vvp_reg.pl
- diff regression_report-devel.txt regression_report.txt
- perl vpi_reg.pl
- stage: Test
os: windows
before_install:
- git clone https://github.com/steveicarus/ivtest.git
- choco uninstall -y mingw
- choco upgrade --no-progress -y msys2
- export msys2='cmd //C RefreshEnv.cmd '
- export msys2+='& set MSYS=winsymlinks:nativestrict '
- export msys2+='& C:\\tools\\msys64\\msys2_shell.cmd -defterm -no-start'
- export mingw64="$msys2 -mingw64 -full-path -here -c "\"\$@"\" --"
- export msys2+=" -msys2 -c "\"\$@"\" --"
- $msys2 pacman --sync --noconfirm --needed base-devel mingw-w64-x86_64-toolchain
script:
- $mingw64 ./autoconf.sh
- $mingw64 ./configure
- $mingw64 make install
- $mingw64 make check
- cd ivtest
- $mingw64 perl update_msys2_report.pl
- $mingw64 perl vvp_reg.pl
- diff --strip-trailing-cr regression_report-msys2.txt regression_report.txt
- $mingw64 perl vpi_reg.pl
+4 -4
View File
@@ -1,7 +1,7 @@
#ifndef IVL_AStatement_H
#define IVL_AStatement_H
/*
* Copyright (c) 2008-2014 Stephen Williams ([email protected])
* Copyright (c) 2008-2021 Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -42,7 +42,7 @@ class AContrib : public Statement {
AContrib(PExpr*lval, PExpr*rval);
~AContrib();
virtual void dump(ostream&out, unsigned ind) const;
virtual void dump(std::ostream&out, unsigned ind) const;
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
private:
@@ -68,10 +68,10 @@ class AProcess : public LineInfo {
ivl_process_type_t type() const { return type_; }
Statement*statement() { return statement_; }
map<perm_string,PExpr*> attributes;
std::map<perm_string,PExpr*> attributes;
// Dump the analog process
void dump(ostream&out, unsigned ind) const;
void dump(std::ostream&out, unsigned ind) const;
private:
ivl_process_type_t type_;
+5 -5
View File
@@ -1,7 +1,7 @@
#ifndef IVL_HName_H
#define IVL_HName_H
/*
* Copyright (c) 2001-2014 Stephen Williams ([email protected])
* Copyright (c) 2001-2021 Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -36,7 +36,7 @@
class hname_t {
friend ostream& operator<< (ostream&out, const hname_t&that);
friend std::ostream& operator<< (std::ostream&out, const hname_t&that);
public:
hname_t ();
@@ -92,14 +92,14 @@ inline size_t hname_t::has_numbers() const
return number_.size();
}
extern ostream& operator<< (ostream&, const hname_t&);
extern std::ostream& operator<< (std::ostream&, const hname_t&);
inline bool operator != (const hname_t&l, const hname_t&r)
{ return ! (l == r); }
inline ostream& operator<< (ostream&out, const list<hname_t>&ll)
inline std::ostream& operator<< (std::ostream&out, const std::list<hname_t>&ll)
{
list<hname_t>::const_iterator cur = ll.begin();
std::list<hname_t>::const_iterator cur = ll.begin();
out << *cur;
++ cur;
while (cur != ll.end()) {
+2 -3
View File
@@ -19,8 +19,8 @@ diffs or instructions to the address given in the `README' so they can
be considered for the next release. If at some point `config.cache'
contains results you don't want to keep, you may remove or edit it.
The file `configure.in' is used to create `configure' by a program
called `autoconf'. You only need `configure.in' if you want to change
The file `configure.ac' is used to create `configure' by a program
called `autoconf'. You only need `configure.ac' if you want to change
it or regenerate `configure' using a newer version of `autoconf'.
The simplest way to compile this package is:
@@ -178,4 +178,3 @@ operates.
script, and exit.
`configure' also accepts some other, not widely useful, options.
+1 -1
View File
@@ -202,7 +202,7 @@ stamp-_pli_types-h: $(srcdir)/_pli_types.h.in config.status
./config.status _pli_types.h
_pli_types.h: stamp-_pli_types-h
$(srcdir)/configure: $(srcdir)/configure.in $(srcdir)/aclocal.m4
$(srcdir)/configure: $(srcdir)/configure.ac $(srcdir)/aclocal.m4
cd $(srcdir) && autoconf
config.status: $(srcdir)/configure
+2
View File
@@ -24,6 +24,8 @@
# include "PWire.h"
# include <cassert>
using namespace std;
list<Module::named_expr_t> Module::user_defparms;
/* n is a permallocated string. */
+17 -17
View File
@@ -64,7 +64,7 @@ class Module : public PScopeExtra, public PNamedItem {
public:
struct port_t {
perm_string name;
vector<PEIdent*> expr;
std::vector<PEIdent*> expr;
};
public:
@@ -97,15 +97,15 @@ class Module : public PScopeExtra, public PNamedItem {
/* specparams are simpler than other parameters, in that they
can have a range, but not an explicit type. The restrictions
are enforced by the parser. */
map<perm_string,param_expr_t*>specparams;
std::map<perm_string,param_expr_t*>specparams;
/* The module also has defparam assignments which don't create
new parameters within the module, but may be used to set
values within this module (when instantiated) or in other
instantiated modules. */
typedef pair<pform_name_t,PExpr*> named_expr_t;
list<named_expr_t>defparms;
static list<named_expr_t>user_defparms;
typedef std::pair<pform_name_t,PExpr*> named_expr_t;
std::list<named_expr_t>defparms;
static std::list<named_expr_t>user_defparms;
/* Parameters may be overridden at instantiation time;
the overrides do not contain explicit parameter names,
@@ -113,17 +113,17 @@ class Module : public PScopeExtra, public PNamedItem {
appear in the instantiated module. Therefore a
list of names in module-order is needed to pass from
a parameter-index to its name. */
list<perm_string> param_names;
std::list<perm_string> param_names;
/* This is an array of port descriptors, which is in turn a
named array of PEident pointers. */
vector<port_t*> ports;
std::vector<port_t*> ports;
map<perm_string,PExpr*> attributes;
std::map<perm_string,PExpr*> attributes;
/* The module has a list of generate schemes that appear in
the module definition. These are used at elaboration time. */
list<PGenerate*> generate_schemes;
std::list<PGenerate*> generate_schemes;
/* Nested modules are placed here, and are not elaborated
unless they are instantiated, implicitly or explicitly. */
@@ -132,9 +132,9 @@ class Module : public PScopeExtra, public PNamedItem {
/* An interface can contain one or more named modport lists.
The parser will ensure these don't appear in modules or
program blocks. */
map<perm_string,PModport*> modports;
std::map<perm_string,PModport*> modports;
list<PSpecPath*> specify_paths;
std::list<PSpecPath*> specify_paths;
// The mod_name() is the name of the module type.
perm_string mod_name() const { return pscope_name(); }
@@ -142,7 +142,7 @@ class Module : public PScopeExtra, public PNamedItem {
void add_gate(PGate*gate);
unsigned port_count() const;
const vector<PEIdent*>& get_port(unsigned idx) const;
const std::vector<PEIdent*>& get_port(unsigned idx) const;
unsigned find_port(const char*name) const;
// Return port name ("" for undeclared port)
@@ -150,12 +150,12 @@ class Module : public PScopeExtra, public PNamedItem {
PGate* get_gate(perm_string name);
const list<PGate*>& get_gates() const;
const std::list<PGate*>& get_gates() const;
void dump(ostream&out) const;
void dump(std::ostream&out) const;
bool elaborate(Design*, NetScope*scope) const;
typedef map<perm_string,PExpr*> replace_t;
typedef std::map<perm_string,PExpr*> replace_t;
bool elaborate_scope(Design*, NetScope*scope, const replace_t&rep);
bool elaborate_sig(Design*, NetScope*scope) const;
@@ -163,8 +163,8 @@ class Module : public PScopeExtra, public PNamedItem {
SymbolType symbol_type() const;
private:
void dump_specparams_(ostream&out, unsigned indent) const;
list<PGate*> gates_;
void dump_specparams_(std::ostream&out, unsigned indent) const;
std::list<PGate*> gates_;
private: // Not implemented
Module(const Module&);
+3 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1999-2017 Stephen Williams ([email protected])
* Copyright (c) 1999-2021 Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -26,6 +26,8 @@
# include "verinum.h"
# include "netmisc.h"
using namespace std;
PDelays::PDelays()
{
delete_flag_ = true;
+4 -10
View File
@@ -1,7 +1,7 @@
#ifndef IVL_PDelays_H
#define IVL_PDelays_H
/*
* Copyright (c) 1999-2014 Stephen Williams ([email protected])
* Copyright (c) 1999-2021 Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -24,12 +24,6 @@
# include <list>
# include <iostream>
#ifdef __GNUC__
#if __GNUC__ > 2
using namespace std;
#endif
#endif
class Design;
class NetScope;
class NetExpr;
@@ -49,7 +43,7 @@ class PDelays {
this object takes ownership of the expressions, and will
delete it in the destructor. */
void set_delay(PExpr*);
void set_delays(const list<PExpr*>*del, bool delete_flag=true);
void set_delays(const std::list<PExpr*>*del, bool delete_flag=true);
unsigned delay_count() const;
@@ -59,7 +53,7 @@ class PDelays {
NetExpr*&decay_time,
bool as_nets_flag =false) const;
void dump_delays(ostream&out) const;
void dump_delays(std::ostream&out) const;
private:
PExpr* delay_[3];
@@ -70,6 +64,6 @@ class PDelays {
PDelays& operator= (const PDelays&);
};
ostream& operator << (ostream&o, const PDelays&);
std::ostream& operator << (std::ostream&o, const PDelays&);
#endif /* IVL_PDelays_H */
+2
View File
@@ -30,6 +30,8 @@
# include "util.h"
# include <typeinfo>
using namespace std;
PExpr::PExpr()
{
expr_type_ = IVL_VT_NO_TYPE;
+26 -26
View File
@@ -60,7 +60,7 @@ class PExpr : public LineInfo {
PExpr();
virtual ~PExpr();
virtual void dump(ostream&) const;
virtual void dump(std::ostream&) const;
// This method tests whether the expression contains any identifiers
// that have not been previously declared in the specified scope or
@@ -202,7 +202,7 @@ class PExpr : public LineInfo {
PExpr& operator= (const PExpr&);
};
ostream& operator << (ostream&, const PExpr&);
std::ostream& operator << (std::ostream&, const PExpr&);
class PEAssignPattern : public PExpr {
public:
@@ -230,11 +230,11 @@ class PEAssignPattern : public PExpr {
class PEConcat : public PExpr {
public:
PEConcat(const list<PExpr*>&p, PExpr*r =0);
explicit PEConcat(const std::list<PExpr*>&p, PExpr*r =0);
~PEConcat();
virtual verinum* eval_const(Design*des, NetScope*sc) const;
virtual void dump(ostream&) const;
virtual void dump(std::ostream&) const;
virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type);
@@ -261,7 +261,7 @@ class PEConcat : public PExpr {
NetNet* elaborate_lnet_common_(Design*des, NetScope*scope,
bool bidirectional_flag) const;
private:
vector<PExpr*>parms_;
std::vector<PExpr*>parms_;
std::valarray<width_mode_t>width_modes_;
PExpr*repeat_;
@@ -289,7 +289,7 @@ class PEEvent : public PExpr {
edge_t type() const;
PExpr* expr() const;
virtual void dump(ostream&) const;
virtual void dump(std::ostream&) const;
virtual bool has_aa_term(Design*des, NetScope*scope) const;
@@ -322,7 +322,7 @@ class PEFNumber : public PExpr {
unsigned expr_wid,
unsigned flags) const;
virtual void dump(ostream&) const;
virtual void dump(std::ostream&) const;
private:
verireal*value_;
@@ -340,7 +340,7 @@ class PEIdent : public PExpr {
// current identifier.
void append_name(perm_string);
virtual void dump(ostream&) const;
virtual void dump(std::ostream&) const;
virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type);
@@ -540,7 +540,7 @@ class PENewArray : public PExpr {
explicit PENewArray (PExpr*s, PExpr*i);
~PENewArray();
virtual void dump(ostream&) const;
virtual void dump(std::ostream&) const;
virtual unsigned test_width(Design*des, NetScope*scope,
width_mode_t&mode);
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
@@ -564,7 +564,7 @@ class PENewClass : public PExpr {
~PENewClass();
virtual void dump(ostream&) const;
virtual void dump(std::ostream&) const;
// Class objects don't have a useful width, but the expression
// is IVL_VT_CLASS.
virtual unsigned test_width(Design*des, NetScope*scope,
@@ -589,7 +589,7 @@ class PENewCopy : public PExpr {
explicit PENewCopy(PExpr*src);
~PENewCopy();
virtual void dump(ostream&) const;
virtual void dump(std::ostream&) const;
// Class objects don't have a useful width, but the expression
// is IVL_VT_CLASS.
virtual unsigned test_width(Design*des, NetScope*scope,
@@ -609,7 +609,7 @@ class PENull : public PExpr {
explicit PENull();
~PENull();
virtual void dump(ostream&) const;
virtual void dump(std::ostream&) const;
virtual unsigned test_width(Design*des, NetScope*scope,
width_mode_t&mode);
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
@@ -627,7 +627,7 @@ class PENumber : public PExpr {
const verinum& value() const;
virtual void dump(ostream&) const;
virtual void dump(std::ostream&) const;
virtual unsigned test_width(Design*des, NetScope*scope,
width_mode_t&mode);
@@ -661,8 +661,8 @@ class PEString : public PExpr {
explicit PEString(char*s);
~PEString();
string value() const;
virtual void dump(ostream&) const;
std::string value() const;
virtual void dump(std::ostream&) const;
virtual unsigned test_width(Design*des, NetScope*scope,
width_mode_t&mode);
@@ -683,7 +683,7 @@ class PETypename : public PExpr {
explicit PETypename(data_type_t*data_type);
~PETypename();
virtual void dump(ostream&) const;
virtual void dump(std::ostream&) const;
virtual unsigned test_width(Design*des, NetScope*scope,
width_mode_t&mode);
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
@@ -701,7 +701,7 @@ class PEUnary : public PExpr {
explicit PEUnary(char op, PExpr*ex);
~PEUnary();
virtual void dump(ostream&out) const;
virtual void dump(std::ostream&out) const;
virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type);
@@ -733,7 +733,7 @@ class PEBinary : public PExpr {
explicit PEBinary(char op, PExpr*l, PExpr*r);
~PEBinary();
virtual void dump(ostream&out) const;
virtual void dump(std::ostream&out) const;
virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type);
@@ -858,7 +858,7 @@ class PETernary : public PExpr {
explicit PETernary(PExpr*e, PExpr*t, PExpr*f);
~PETernary();
virtual void dump(ostream&out) const;
virtual void dump(std::ostream&out) const;
virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type);
@@ -890,7 +890,7 @@ class PETernary : public PExpr {
*/
class PECallFunction : public PExpr {
public:
explicit PECallFunction(const pform_name_t&n, const vector<PExpr *> &parms);
explicit PECallFunction(const pform_name_t&n, const std::vector<PExpr *> &parms);
// Call function defined in package.
explicit PECallFunction(PPackage*pkg, perm_string n, const std::vector<PExpr *> &parms);
explicit PECallFunction(PPackage*pkg, perm_string n, const std::list<PExpr *> &parms);
@@ -899,16 +899,16 @@ class PECallFunction : public PExpr {
explicit PECallFunction(PPackage*pkg, const pform_name_t&n, const std::vector<PExpr *> &parms);
// Call of system function (name is not hierarchical)
explicit PECallFunction(perm_string n, const vector<PExpr *> &parms);
explicit PECallFunction(perm_string n, const std::vector<PExpr *> &parms);
explicit PECallFunction(perm_string n);
// std::list versions. Should be removed!
explicit PECallFunction(const pform_name_t&n, const list<PExpr *> &parms);
explicit PECallFunction(perm_string n, const list<PExpr *> &parms);
explicit PECallFunction(const pform_name_t&n, const std::list<PExpr *> &parms);
explicit PECallFunction(perm_string n, const std::list<PExpr *> &parms);
~PECallFunction();
virtual void dump(ostream &) const;
virtual void dump(std::ostream &) const;
virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type);
@@ -975,7 +975,7 @@ class PECastSize : public PExpr {
explicit PECastSize(PExpr*size, PExpr*base);
~PECastSize();
void dump(ostream &out) const;
void dump(std::ostream &out) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
unsigned expr_wid,
@@ -998,7 +998,7 @@ class PECastType : public PExpr {
explicit PECastType(data_type_t*target, PExpr*base);
~PECastType();
void dump(ostream &out) const;
void dump(std::ostream &out) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
ivl_type_t type, unsigned flags) const;
+2
View File
@@ -23,6 +23,8 @@
# include <cassert>
# include "ivl_assert.h"
using namespace std;
PFunction::PFunction(perm_string name, LexicalScope*parent, bool is_auto__)
: PTaskFunc(name, parent), statement_(0)
{
+17 -27
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1999-2019 Stephen Williams ([email protected])
* Copyright (c) 1999-2021 Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -24,6 +24,8 @@
# include "verinum.h"
# include <cassert>
using namespace std;
void PGate::set_pins_(list<PExpr*>*pins)
{
assert(pins);
@@ -39,7 +41,7 @@ void PGate::set_pins_(list<PExpr*>*pins)
}
PGate::PGate(perm_string name, list<PExpr*>*pins, const list<PExpr*>*del)
: name_(name), pins_(pins? pins->size() : 0)
: name_(name), pins_(pins? pins->size() : 0), ranges_(0)
{
if (pins) set_pins_(pins);
if (del) delay_.set_delays(del);
@@ -48,7 +50,7 @@ PGate::PGate(perm_string name, list<PExpr*>*pins, const list<PExpr*>*del)
}
PGate::PGate(perm_string name, list<PExpr*>*pins, PExpr*del)
: name_(name), pins_(pins? pins->size() : 0)
: name_(name), pins_(pins? pins->size() : 0), ranges_(0)
{
if (pins) set_pins_(pins);
if (del) delay_.set_delay(del);
@@ -57,7 +59,7 @@ PGate::PGate(perm_string name, list<PExpr*>*pins, PExpr*del)
}
PGate::PGate(perm_string name, list<PExpr*>*pins)
: name_(name), pins_(pins? pins->size() : 0)
: name_(name), pins_(pins? pins->size() : 0), ranges_(0)
{
if (pins) set_pins_(pins);
str0_ = IVL_DR_STRONG;
@@ -68,6 +70,12 @@ PGate::~PGate()
{
}
void PGate::set_ranges(list<pform_range_t>*ranges)
{
assert(ranges_ == 0);
ranges_ = ranges;
}
ivl_drive_t PGate::strength0() const
{
return str0_;
@@ -141,14 +149,14 @@ PGAssign::~PGAssign()
PGBuiltin::PGBuiltin(Type t, perm_string name,
list<PExpr*>*pins,
list<PExpr*>*del)
: PGate(name, pins, del), type_(t), msb_(0), lsb_(0)
: PGate(name, pins, del), type_(t)
{
}
PGBuiltin::PGBuiltin(Type t, perm_string name,
list<PExpr*>*pins,
PExpr*del)
: PGate(name, pins, del), type_(t), msb_(0), lsb_(0)
: PGate(name, pins, del), type_(t)
{
}
@@ -157,15 +165,6 @@ PGBuiltin::~PGBuiltin()
{
}
void PGBuiltin::set_range(PExpr*msb, PExpr*lsb)
{
assert(msb_ == 0);
assert(lsb_ == 0);
msb_ = msb;
lsb_ = lsb;
}
const char* PGBuiltin::gate_name() const
{
switch(type_) {
@@ -266,20 +265,20 @@ const char* PGBuiltin::gate_name() const
PGModule::PGModule(perm_string type, perm_string name, list<PExpr*>*pins)
: PGate(name, pins), bound_type_(0), type_(type), overrides_(0), pins_(0),
npins_(0), parms_(0), nparms_(0), msb_(0), lsb_(0)
npins_(0), parms_(0), nparms_(0)
{
}
PGModule::PGModule(perm_string type, perm_string name,
named<PExpr*>*pins, unsigned npins)
: PGate(name, 0), bound_type_(0), type_(type), overrides_(0), pins_(pins),
npins_(npins), parms_(0), nparms_(0), msb_(0), lsb_(0)
npins_(npins), parms_(0), nparms_(0)
{
}
PGModule::PGModule(Module*type, perm_string name)
: PGate(name, 0), bound_type_(type), overrides_(0), pins_(0),
npins_(0), parms_(0), nparms_(0), msb_(0), lsb_(0)
npins_(0), parms_(0), nparms_(0)
{
}
@@ -301,15 +300,6 @@ void PGModule::set_parameters(named<PExpr*>*pa, unsigned npa)
nparms_ = npa;
}
void PGModule::set_range(PExpr*msb, PExpr*lsb)
{
assert(msb_ == 0);
assert(lsb_ == 0);
msb_ = msb;
lsb_ = lsb;
}
perm_string PGModule::get_type() const
{
return type_;
+33 -41
View File
@@ -1,7 +1,7 @@
#ifndef IVL_PGate_H
#define IVL_PGate_H
/*
* Copyright (c) 1998-2019 Stephen Williams ([email protected])
* Copyright (c) 1998-2021 Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -50,16 +50,19 @@ class Module;
class PGate : public PNamedItem {
public:
explicit PGate(perm_string name, list<PExpr*>*pins,
const list<PExpr*>*del);
explicit PGate(perm_string name, std::list<PExpr*>*pins,
const std::list<PExpr*>*del);
explicit PGate(perm_string name, list<PExpr*>*pins,
explicit PGate(perm_string name, std::list<PExpr*>*pins,
PExpr*del);
explicit PGate(perm_string name, list<PExpr*>*pins);
explicit PGate(perm_string name, std::list<PExpr*>*pins);
virtual ~PGate();
void set_ranges(std::list<pform_range_t>*ranges);
bool is_array() const { return ranges_ != 0; }
perm_string get_name() const { return name_; }
// This evaluates the delays as far as possible, but returns
@@ -81,9 +84,9 @@ class PGate : public PNamedItem {
void strength0(ivl_drive_t);
void strength1(ivl_drive_t);
map<perm_string,PExpr*> attributes;
std::map<perm_string,PExpr*> attributes;
virtual void dump(ostream&out, unsigned ind =4) const;
virtual void dump(std::ostream&out, unsigned ind =4) const;
virtual void elaborate(Design*des, NetScope*scope) const;
virtual void elaborate_scope(Design*des, NetScope*sc) const;
virtual bool elaborate_sig(Design*des, NetScope*scope) const;
@@ -91,19 +94,25 @@ class PGate : public PNamedItem {
SymbolType symbol_type() const;
protected:
const vector<PExpr*>& get_pins() const { return pins_; }
const std::vector<PExpr*>& get_pins() const { return pins_; }
void dump_pins(ostream&out) const;
void dump_delays(ostream&out) const;
unsigned calculate_array_size_(Design*, NetScope*,
long&high, long&low) const;
void dump_pins(std::ostream&out) const;
void dump_delays(std::ostream&out) const;
void dump_ranges(std::ostream&out) const;
private:
perm_string name_;
PDelays delay_;
vector<PExpr*>pins_;
std::vector<PExpr*>pins_;
std::list<pform_range_t>*ranges_;
ivl_drive_t str0_, str1_;
void set_pins_(list<PExpr*>*pins);
void set_pins_(std::list<PExpr*>*pins);
private: // not implemented
PGate(const PGate&);
@@ -117,11 +126,11 @@ class PGate : public PNamedItem {
class PGAssign : public PGate {
public:
explicit PGAssign(list<PExpr*>*pins);
explicit PGAssign(list<PExpr*>*pins, list<PExpr*>*dels);
explicit PGAssign(std::list<PExpr*>*pins);
explicit PGAssign(std::list<PExpr*>*pins, std::list<PExpr*>*dels);
~PGAssign();
void dump(ostream&out, unsigned ind =4) const;
void dump(std::ostream&out, unsigned ind =4) const;
virtual void elaborate(Design*des, NetScope*scope) const;
virtual bool elaborate_sig(Design*des, NetScope*scope) const;
@@ -150,25 +159,21 @@ class PGBuiltin : public PGate {
public:
explicit PGBuiltin(Type t, perm_string name,
list<PExpr*>*pins,
list<PExpr*>*del);
std::list<PExpr*>*pins,
std::list<PExpr*>*del);
explicit PGBuiltin(Type t, perm_string name,
list<PExpr*>*pins,
std::list<PExpr*>*pins,
PExpr*del);
~PGBuiltin();
Type type() const { return type_; }
const char * gate_name() const;
void set_range(PExpr*msb, PExpr*lsb);
virtual void dump(ostream&out, unsigned ind =4) const;
virtual void dump(std::ostream&out, unsigned ind =4) const;
virtual void elaborate(Design*, NetScope*scope) const;
virtual bool elaborate_sig(Design*des, NetScope*scope) const;
private:
unsigned calculate_array_count_(Design*, NetScope*,
long&high, long&low) const;
void calculate_gate_and_lval_count_(unsigned&gate_count,
unsigned&lval_count) const;
@@ -179,8 +184,6 @@ class PGBuiltin : public PGate {
bool check_delay_count(Design*des) const;
Type type_;
PExpr*msb_;
PExpr*lsb_;
};
/*
@@ -197,7 +200,7 @@ class PGModule : public PGate {
// If the binding of ports is by position, this constructor
// builds everything all at once.
explicit PGModule(perm_string type, perm_string name,
list<PExpr*>*pins);
std::list<PExpr*>*pins);
// If the binding of ports is by name, this constructor takes
// the bindings and stores them for later elaboration.
@@ -212,16 +215,12 @@ class PGModule : public PGate {
// Parameter overrides can come as an ordered list, or a set
// of named expressions.
void set_parameters(list<PExpr*>*o);
void set_parameters(std::list<PExpr*>*o);
void set_parameters(named<PExpr*>*pa, unsigned npa);
// Modules can be instantiated in ranges. The parser uses this
// method to pass the range to the pform.
void set_range(PExpr*msb, PExpr*lsb);
std::map<perm_string,PExpr*> attributes;
map<perm_string,PExpr*> attributes;
virtual void dump(ostream&out, unsigned ind =4) const;
virtual void dump(std::ostream&out, unsigned ind =4) const;
virtual void elaborate(Design*, NetScope*scope) const;
virtual void elaborate_scope(Design*des, NetScope*sc) const;
virtual bool elaborate_sig(Design*des, NetScope*scope) const;
@@ -233,7 +232,7 @@ class PGModule : public PGate {
private:
Module*bound_type_;
perm_string type_;
list<PExpr*>*overrides_;
std::list<PExpr*>*overrides_;
named<PExpr*>*pins_;
unsigned npins_;
@@ -241,16 +240,9 @@ class PGModule : public PGate {
named<PExpr*>*parms_;
unsigned nparms_;
// Arrays of modules are give if these are set.
PExpr*msb_;
PExpr*lsb_;
friend class delayed_elaborate_scope_mod_instances;
void elaborate_mod_(Design*, Module*mod, NetScope*scope) const;
void elaborate_udp_(Design*, PUdp *udp, NetScope*scope) const;
unsigned calculate_instance_count_(Design*, NetScope*,
long&high, long&low,
perm_string name) const;
void elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const;
void elaborate_scope_mod_instances_(Design*des, Module*mod, NetScope*sc) const;
bool elaborate_sig_mod_(Design*des, NetScope*scope, Module*mod) const;
+3 -46
View File
@@ -21,11 +21,13 @@
# include "PWire.h"
# include "ivl_assert.h"
using namespace std;
PGenerate::PGenerate(LexicalScope*parent, unsigned id)
: LexicalScope(parent), id_number(id)
{
direct_nested_ = false;
scheme_type = GS_NONE;
directly_nested = false;
local_index = false;
loop_init = 0;
loop_test = 0;
@@ -41,51 +43,6 @@ void PGenerate::add_gate(PGate*gate)
gates.push_back(gate);
}
void PGenerate::probe_for_direct_nesting_(void)
{
direct_nested_ = false;
ivl_assert(*this, scheme_type==GS_CASE_ITEM || scheme_type==GS_CONDIT || scheme_type==GS_ELSE);
// If this scheme has received an explicit name, then it
// cannot be direct nested.
if (scope_name[0] != '$') return;
if (! tasks.empty()) return;
if (! funcs.empty()) return;
if (! gates.empty()) return;
if (! parameters.empty()) return;
if (! localparams.empty()) return;
if (! events.empty()) return;
if (! wires.empty()) return;
if (! genvars.empty()) return;
if (! behaviors.empty()) return;
if (! analog_behaviors.empty()) return;
if (generate_schemes.empty()) return;
switch (generate_schemes.size()) {
case 1: {
PGenerate*child = generate_schemes.front();
if (child->scheme_type == GS_CONDIT)
direct_nested_ = true;
if (child->scheme_type == GS_CASE)
direct_nested_ = true;
break;
}
case 2: {
PGenerate*child1 = generate_schemes.front();
PGenerate*child2 = generate_schemes.back();
if (child1->scheme_type==GS_CONDIT && child2->scheme_type==GS_ELSE)
direct_nested_ = true;
if (child2->scheme_type==GS_CONDIT && child1->scheme_type==GS_ELSE)
direct_nested_ = true;
break;
}
}
}
ostream& operator << (ostream&out, PGenerate::scheme_t type)
{
switch (type) {
+12 -16
View File
@@ -1,7 +1,7 @@
#ifndef IVL_PGenerate_H
#define IVL_PGenerate_H
/*
* Copyright (c) 2006-2020 Stephen Williams ([email protected])
* Copyright (c) 2006-2021 Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -69,6 +69,8 @@ class PGenerate : public PNamedItem, public LexicalScope {
GS_CASE, GS_CASE_ITEM, GS_NBLOCK};
scheme_t scheme_type;
bool directly_nested;
// generate loops have an index variable and three
// expressions: for (index = <init>; <test>; index=<step>)
// the index is local if it was declared in the init expression,
@@ -84,18 +86,18 @@ class PGenerate : public PNamedItem, public LexicalScope {
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;
typedef std::pair<pform_name_t,PExpr*> named_expr_t;
std::list<named_expr_t>defparms;
list<PGate*> gates;
std::list<PGate*> gates;
void add_gate(PGate*);
// Tasks instantiated within this scheme.
map<perm_string,PTask*> tasks;
map<perm_string,PFunction*>funcs;
std::map<perm_string,PTask*> tasks;
std::map<perm_string,PFunction*>funcs;
// Generate schemes can contain further generate schemes.
list<PGenerate*> generate_schemes;
std::list<PGenerate*> generate_schemes;
// PGenerate*parent;
// This method is called by the elaboration of a module to
@@ -108,29 +110,23 @@ class PGenerate : public PNamedItem, public LexicalScope {
bool elaborate_sig(Design*des, NetScope*container) const;
bool elaborate(Design*des, NetScope*container) const;
void dump(ostream&out, unsigned indent) const;
void dump(std::ostream&out, unsigned indent) const;
SymbolType symbol_type() const;
private:
void check_for_valid_genvar_value_(long value);
bool generate_scope_loop_(Design*des, NetScope*container);
bool generate_scope_condit_(Design*des, NetScope*container, bool else_flag);
bool generate_scope_case_(Design*des, NetScope*container);
bool generate_scope_nblock_(Design*des, NetScope*container);
// Call probe during elaborate_scope to calculate the
// direct_nested_ flag. It is OK to store the direct_nested_
// information here because "direct nested" is a property of
// the lexical generate code.
void probe_for_direct_nesting_(void);
bool direct_nested_;
// Elaborate_scope within a generated scope.
void elaborate_subscope_(Design*des, NetScope*scope);
void elaborate_subscope_direct_(Design*des, NetScope*scope);
// These are the scopes created by generate_scope.
list<NetScope*>scope_list_;
std::list<NetScope*>scope_list_;
// internal function called on each scope generated by this scheme.
bool elaborate_sig_(Design*des, NetScope*scope) const;
bool elaborate_sig_direct_(Design*des, NetScope*scope) const;
+3 -3
View File
@@ -1,7 +1,7 @@
#ifndef IVL_PModport_H
#define IVL_PModport_H
/*
* Copyright (c) 2015-2019 Stephen Williams ([email protected])
* Copyright (c) 2015-2021 Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -38,8 +38,8 @@ class PModport : public PNamedItem {
perm_string name() const { return name_; }
typedef pair <NetNet::PortType,PExpr*> simple_port_t;
map<perm_string,simple_port_t> simple_ports;
typedef std::pair <NetNet::PortType,PExpr*> simple_port_t;
std::map<perm_string,simple_port_t> simple_ports;
SymbolType symbol_type() const;
+3 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2008-2019 Stephen Williams ([email protected])
* Copyright (c) 2008-2021 Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -19,6 +19,8 @@
# include "PScope.h"
using namespace std;
bool LexicalScope::var_init_needs_explicit_lifetime() const
{
return false;
+27 -21
View File
@@ -55,7 +55,8 @@ class LexicalScope {
public:
enum lifetime_t { INHERITED, STATIC, AUTOMATIC };
explicit LexicalScope(LexicalScope*parent) : default_lifetime(INHERITED), parent_(parent) { }
explicit LexicalScope(LexicalScope*parent)
: default_lifetime(INHERITED), generate_counter(0), parent_(parent) { }
// A virtual destructor is so that dynamic_cast can work.
virtual ~LexicalScope() { }
@@ -71,7 +72,7 @@ class LexicalScope {
// Packages that are wildcard imported. When identifiers from
// these packages are referenced, they will be added to the
// explicit imports (IEEE 1800-2012 26.3).
std::set<PPackage*>potential_imports;
std::list<PPackage*>potential_imports;
// A task or function call may reference a task or function defined
// later in the scope. So here we stash the potential imports for
@@ -111,52 +112,57 @@ class LexicalScope {
SymbolType symbol_type() const;
};
map<perm_string,param_expr_t*>parameters;
map<perm_string,param_expr_t*>localparams;
std::map<perm_string,param_expr_t*>parameters;
std::map<perm_string,param_expr_t*>localparams;
// Defined types in the scope.
map<perm_string,data_type_t*>typedefs;
std::map<perm_string,data_type_t*>typedefs;
// Named events in the scope.
map<perm_string,PEvent*>events;
std::map<perm_string,PEvent*>events;
// Nets and variables (wires) in the scope
map<perm_string,PWire*>wires;
std::map<perm_string,PWire*>wires;
PWire* wires_find(perm_string name);
// Genvars in the scope. These will only be present in module
// scopes, but are listed here to allow them to be found when
// creating implicit nets.
map<perm_string,LineInfo*> genvars;
std::map<perm_string,LineInfo*> genvars;
// Variable initializations in this scope
vector<Statement*> var_inits;
std::vector<Statement*> var_inits;
// Behaviors (processes) in this scope
list<PProcess*> behaviors;
list<AProcess*> analog_behaviors;
std::list<PProcess*> behaviors;
std::list<AProcess*> analog_behaviors;
// Enumeration sets.
std::set<enum_type_t*> enum_sets;
// A count of the generate constructs in this scope. This is
// used to automatically name unnamed generate blocks, as
// specified in the LRM.
unsigned generate_counter;
LexicalScope* parent_scope() const { return parent_; }
virtual bool var_init_needs_explicit_lifetime() const;
protected:
void dump_typedefs_(ostream&out, unsigned indent) const;
void dump_typedefs_(std::ostream&out, unsigned indent) const;
void dump_parameters_(ostream&out, unsigned indent) const;
void dump_parameters_(std::ostream&out, unsigned indent) const;
void dump_localparams_(ostream&out, unsigned indent) const;
void dump_localparams_(std::ostream&out, unsigned indent) const;
void dump_enumerations_(ostream&out, unsigned indent) const;
void dump_enumerations_(std::ostream&out, unsigned indent) const;
void dump_events_(ostream&out, unsigned indent) const;
void dump_events_(std::ostream&out, unsigned indent) const;
void dump_wires_(ostream&out, unsigned indent) const;
void dump_wires_(std::ostream&out, unsigned indent) const;
void dump_var_inits_(ostream&out, unsigned indent) const;
void dump_var_inits_(std::ostream&out, unsigned indent) const;
bool elaborate_var_inits_(Design*des, NetScope*scope) const;
@@ -227,9 +233,9 @@ class PScopeExtra : public PScope {
bool time_prec_is_local;
protected:
void dump_classes_(ostream&out, unsigned indent) const;
void dump_tasks_(ostream&out, unsigned indent) const;
void dump_funcs_(ostream&out, unsigned indent) const;
void dump_classes_(std::ostream&out, unsigned indent) const;
void dump_tasks_(std::ostream&out, unsigned indent) const;
void dump_funcs_(std::ostream&out, unsigned indent) const;
};
#endif /* IVL_PScope_H */
+3 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1999-2019 Stephen Williams ([email protected])
* Copyright (c) 1999-2021 Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -21,6 +21,8 @@
# include "PTask.h"
# include <cassert>
using namespace std;
PTaskFunc::PTaskFunc(perm_string n, LexicalScope*p)
: PScope(n,p), this_type_(0), ports_(0)
{
+2 -2
View File
@@ -97,7 +97,7 @@ class PTask : public PTaskFunc {
bool is_auto() const { return is_auto_; };
void dump(ostream&, unsigned) const;
void dump(std::ostream&, unsigned) const;
SymbolType symbol_type() const;
@@ -148,7 +148,7 @@ class PFunction : public PTaskFunc {
bool is_auto() const { return is_auto_; };
void dump(ostream&, unsigned) const;
void dump(std::ostream&, unsigned) const;
SymbolType symbol_type() const;
+5 -5
View File
@@ -1,7 +1,7 @@
#ifndef IVL_PUdp_H
#define IVL_PUdp_H
/*
* Copyright (c) 1998-2014 Stephen Williams ([email protected])
* Copyright (c) 1998-2021 Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -53,20 +53,20 @@ class PUdp : public LineInfo {
public:
explicit PUdp(perm_string n, unsigned nports);
svector<string>ports;
svector<std::string>ports;
unsigned find_port(const char*name);
bool sequential;
svector<string>tinput;
svector<std::string>tinput;
svector<char> tcurrent;
svector<char> toutput;
verinum::V initial;
map<string,PExpr*> attributes;
std::map<std::string,PExpr*> attributes;
void dump(ostream&out) const;
void dump(std::ostream&out) const;
perm_string name_;
private:
+11 -3
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1999-2019 Stephen Williams ([email protected])
* Copyright (c) 1999-2021 Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -22,6 +22,8 @@
# include "PExpr.h"
# include <cassert>
using namespace std;
PWire::PWire(perm_string n,
NetNet::Type t,
NetNet::PortType pt,
@@ -132,7 +134,13 @@ ivl_variable_type_t PWire::get_data_type() const
void PWire::set_signed(bool flag)
{
signed_ = flag;
// For a non-ANSI style port declaration where the data type is
// specified in a corresponding variable declaration, the signed
// attribute may be attached to either the port declaration or to
// the variable declaration (IEEE 1364-2005 section 12.3.3). The
// signal is signed if either the port or the variable is signed.
// Handle that here.
signed_ = signed_ || flag;
}
bool PWire::get_signed() const
@@ -264,7 +272,7 @@ void PWire::set_unpacked_idx(const list<pform_range_t>&ranges)
void PWire::set_data_type(data_type_t*type)
{
assert(set_data_type_ == 0);
assert(set_data_type_ == 0 || set_data_type_ == type);
set_data_type_ = type;
if (vector_type_t*tmp = dynamic_cast<vector_type_t*>(type)) {
+4 -4
View File
@@ -1,7 +1,7 @@
#ifndef IVL_PWire_H
#define IVL_PWire_H
/*
* Copyright (c) 1998-2019 Stephen Williams ([email protected])
* Copyright (c) 1998-2021 Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -28,7 +28,7 @@
#ifdef HAVE_IOSFWD
# include <iosfwd>
#else
class ostream;
# include <iostream>
#endif
class PExpr;
@@ -87,10 +87,10 @@ class PWire : public PNamedItem {
void set_discipline(ivl_discipline_t);
ivl_discipline_t get_discipline(void) const;
map<perm_string,PExpr*> attributes;
std::map<perm_string,PExpr*> attributes;
// Write myself to the specified stream.
void dump(ostream&out, unsigned ind=4) const;
void dump(std::ostream&out, unsigned ind=4) const;
NetNet* elaborate_sig(Design*, NetScope*scope) const;
+1 -1
View File
@@ -72,7 +72,7 @@ If you are building from git, you will also need software to generate
the configure scripts.
- autoconf 2.53 or later
This generates configure scripts from configure.in. The 2.53
This generates configure scripts from configure.ac. The 2.53
or later versions are known to work, autoconf 2.13 is
reported to *not* work.
+2
View File
@@ -23,6 +23,8 @@
# include "PExpr.h"
# include "ivl_assert.h"
using namespace std;
Statement::~Statement()
{
}
+40 -33
View File
@@ -61,9 +61,9 @@ class PProcess : public LineInfo {
ivl_process_type_t type() const { return type_; }
Statement*statement() { return statement_; }
map<perm_string,PExpr*> attributes;
std::map<perm_string,PExpr*> attributes;
virtual void dump(ostream&out, unsigned ind) const;
virtual void dump(std::ostream&out, unsigned ind) const;
private:
ivl_process_type_t type_;
@@ -81,12 +81,12 @@ class Statement : virtual public LineInfo {
Statement() { }
virtual ~Statement() =0;
virtual void dump(ostream&out, unsigned ind) const;
virtual void dump(std::ostream&out, unsigned ind) const;
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
virtual void elaborate_scope(Design*des, NetScope*scope) const;
virtual void elaborate_sig(Design*des, NetScope*scope) const;
map<perm_string,PExpr*> attributes;
std::map<perm_string,PExpr*> attributes;
};
/*
@@ -139,7 +139,7 @@ class PAssign : public PAssign_ {
explicit PAssign(PExpr*lval, PExpr*ex, bool is_constant);
~PAssign();
virtual void dump(ostream&out, unsigned ind) const;
virtual void dump(std::ostream&out, unsigned ind) const;
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
private:
@@ -155,7 +155,7 @@ class PAssignNB : public PAssign_ {
explicit PAssignNB(PExpr*lval, PExpr*cnt, PEventStatement*de, PExpr*ex);
~PAssignNB();
virtual void dump(ostream&out, unsigned ind) const;
virtual void dump(std::ostream&out, unsigned ind) const;
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
private:
@@ -200,7 +200,7 @@ class PBlock : public PScope, public Statement, public PNamedItem {
// block.
void push_statement_front(Statement*that);
virtual void dump(ostream&out, unsigned ind) const;
virtual void dump(std::ostream&out, unsigned ind) const;
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
virtual void elaborate_scope(Design*des, NetScope*scope) const;
virtual void elaborate_sig(Design*des, NetScope*scope) const;
@@ -215,14 +215,14 @@ class PBlock : public PScope, public Statement, public PNamedItem {
class PCallTask : public Statement {
public:
explicit PCallTask(PPackage*pkg, const pform_name_t&n, const list<PExpr*>&parms);
explicit PCallTask(const pform_name_t&n, const list<PExpr*>&parms);
explicit PCallTask(perm_string n, const list<PExpr*>&parms);
explicit PCallTask(PPackage*pkg, const pform_name_t&n, const std::list<PExpr*>&parms);
explicit PCallTask(const pform_name_t&n, const std::list<PExpr*>&parms);
explicit PCallTask(perm_string n, const std::list<PExpr*>&parms);
~PCallTask();
const pform_name_t& path() const;
virtual void dump(ostream&out, unsigned ind) const;
virtual void dump(std::ostream&out, unsigned ind) const;
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
private:
@@ -245,18 +245,25 @@ class PCallTask : public Statement {
NetNet*net,
perm_string method_name,
const char*sys_task_name) const;
NetProc*elaborate_method_func_(NetScope*scope,
NetNet*net,
ivl_variable_type_t type,
unsigned width,
bool signed_flag,
perm_string method_name,
const char*sys_task_name) const;
bool test_task_calls_ok_(Design*des, NetScope*scope) const;
PPackage*package_;
pform_name_t path_;
vector<PExpr*> parms_;
std::vector<PExpr*> parms_;
};
class PCase : public Statement {
public:
struct Item {
list<PExpr*>expr;
std::list<PExpr*>expr;
Statement*stat;
};
@@ -266,7 +273,7 @@ class PCase : public Statement {
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
virtual void elaborate_scope(Design*des, NetScope*scope) const;
virtual void elaborate_sig(Design*des, NetScope*scope) const;
virtual void dump(ostream&out, unsigned ind) const;
virtual void dump(std::ostream&out, unsigned ind) const;
private:
ivl_case_quality_t quality_;
@@ -287,7 +294,7 @@ class PCAssign : public Statement {
~PCAssign();
virtual NetCAssign* elaborate(Design*des, NetScope*scope) const;
virtual void dump(ostream&out, unsigned ind) const;
virtual void dump(std::ostream&out, unsigned ind) const;
private:
PExpr*lval_;
@@ -301,11 +308,11 @@ class PCAssign : public Statement {
*/
class PChainConstructor : public Statement {
public:
explicit PChainConstructor(const list<PExpr*>&parms);
explicit PChainConstructor(const std::list<PExpr*>&parms);
~PChainConstructor();
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
virtual void dump(ostream&out, unsigned ind) const;
virtual void dump(std::ostream&out, unsigned ind) const;
inline const std::vector<PExpr*>& chain_args(void) const
{ return parms_; }
@@ -323,7 +330,7 @@ class PCondit : public Statement {
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
virtual void elaborate_scope(Design*des, NetScope*scope) const;
virtual void elaborate_sig(Design*des, NetScope*scope) const;
virtual void dump(ostream&out, unsigned ind) const;
virtual void dump(std::ostream&out, unsigned ind) const;
private:
PExpr*expr_;
@@ -342,7 +349,7 @@ class PDeassign : public Statement {
~PDeassign();
virtual NetDeassign* elaborate(Design*des, NetScope*scope) const;
virtual void dump(ostream&out, unsigned ind) const;
virtual void dump(std::ostream&out, unsigned ind) const;
private:
PExpr*lval_;
@@ -354,7 +361,7 @@ class PDelayStatement : public Statement {
PDelayStatement(PExpr*d, Statement*st);
~PDelayStatement();
virtual void dump(ostream&out, unsigned ind) const;
virtual void dump(std::ostream&out, unsigned ind) const;
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
virtual void elaborate_scope(Design*des, NetScope*scope) const;
virtual void elaborate_sig(Design*des, NetScope*scope) const;
@@ -374,7 +381,7 @@ class PDisable : public Statement {
explicit PDisable(const pform_name_t&sc);
~PDisable();
virtual void dump(ostream&out, unsigned ind) const;
virtual void dump(std::ostream&out, unsigned ind) const;
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
private:
@@ -390,7 +397,7 @@ class PDoWhile : public Statement {
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
virtual void elaborate_scope(Design*des, NetScope*scope) const;
virtual void elaborate_sig(Design*des, NetScope*scope) const;
virtual void dump(ostream&out, unsigned ind) const;
virtual void dump(std::ostream&out, unsigned ind) const;
private:
PExpr*cond_;
@@ -419,10 +426,10 @@ class PEventStatement : public Statement {
void set_statement(Statement*st);
virtual void dump(ostream&out, unsigned ind) const;
virtual void dump(std::ostream&out, unsigned ind) const;
// Call this with a NULL statement only. It is used to print
// the event expression for inter-assignment event controls.
virtual void dump_inline(ostream&out) const;
virtual void dump_inline(std::ostream&out) const;
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
virtual void elaborate_scope(Design*des, NetScope*scope) const;
virtual void elaborate_sig(Design*des, NetScope*scope) const;
@@ -442,7 +449,7 @@ class PEventStatement : public Statement {
bool always_sens_;
};
ostream& operator << (ostream&o, const PEventStatement&obj);
std::ostream& operator << (std::ostream&o, const PEventStatement&obj);
class PForce : public Statement {
@@ -451,7 +458,7 @@ class PForce : public Statement {
~PForce();
virtual NetForce* elaborate(Design*des, NetScope*scope) const;
virtual void dump(ostream&out, unsigned ind) const;
virtual void dump(std::ostream&out, unsigned ind) const;
private:
PExpr*lval_;
@@ -466,7 +473,7 @@ class PForeach : public Statement {
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
virtual void elaborate_scope(Design*des, NetScope*scope) const;
virtual void elaborate_sig(Design*des, NetScope*scope) const;
virtual void dump(ostream&out, unsigned ind) const;
virtual void dump(std::ostream&out, unsigned ind) const;
private:
NetProc* elaborate_static_array_(Design*des, NetScope*scope,
@@ -486,7 +493,7 @@ class PForever : public Statement {
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
virtual void elaborate_scope(Design*des, NetScope*scope) const;
virtual void elaborate_sig(Design*des, NetScope*scope) const;
virtual void dump(ostream&out, unsigned ind) const;
virtual void dump(std::ostream&out, unsigned ind) const;
private:
Statement*statement_;
@@ -502,7 +509,7 @@ class PForStatement : public Statement {
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
virtual void elaborate_scope(Design*des, NetScope*scope) const;
virtual void elaborate_sig(Design*des, NetScope*scope) const;
virtual void dump(ostream&out, unsigned ind) const;
virtual void dump(std::ostream&out, unsigned ind) const;
private:
PExpr* name1_;
@@ -530,7 +537,7 @@ class PRepeat : public Statement {
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
virtual void elaborate_scope(Design*des, NetScope*scope) const;
virtual void elaborate_sig(Design*des, NetScope*scope) const;
virtual void dump(ostream&out, unsigned ind) const;
virtual void dump(std::ostream&out, unsigned ind) const;
private:
PExpr*expr_;
@@ -544,7 +551,7 @@ class PRelease : public Statement {
~PRelease();
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
virtual void dump(ostream&out, unsigned ind) const;
virtual void dump(std::ostream&out, unsigned ind) const;
private:
PExpr*lval_;
@@ -574,7 +581,7 @@ class PTrigger : public Statement {
~PTrigger();
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
virtual void dump(ostream&out, unsigned ind) const;
virtual void dump(std::ostream&out, unsigned ind) const;
private:
PPackage*package_;
@@ -590,7 +597,7 @@ class PWhile : public Statement {
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
virtual void elaborate_scope(Design*des, NetScope*scope) const;
virtual void elaborate_sig(Design*des, NetScope*scope) const;
virtual void dump(ostream&out, unsigned ind) const;
virtual void dump(std::ostream&out, unsigned ind) const;
private:
PExpr*cond_;
Vendored
+35 -22
View File
@@ -6,7 +6,7 @@
# different builds. Remember to change the default suffix string to some
# value appropriate for the current version.
AC_DEFUN([AX_ENABLE_SUFFIX],
[AC_ARG_ENABLE([suffix],[AC_HELP_STRING([--enable-suffix],
[AC_ARG_ENABLE([suffix],[AS_HELP_STRING([--enable-suffix],
[Use/set the installation command suffix])],
[true],[enable_suffix=no])
if test X$enable_suffix = Xyes; then
@@ -250,7 +250,7 @@ echo "timestamp for $_config_header" > `AS_DIRNAME(["$_config_header"])`/[]$_sta
]) #_AC_AM_CONFIG_HEADER_HOOK
# ===========================================================================
# http://www.gnu.org/software/autoconf-archive/ax_prog_cc_for_build.html
# https://www.gnu.org/software/autoconf-archive/ax_prog_cc_for_build.html
# ===========================================================================
#
# SYNOPSIS
@@ -283,31 +283,35 @@ echo "timestamp for $_config_header" > `AS_DIRNAME(["$_config_header"])`/[]$_sta
# and this notice are preserved. This file is offered as-is, without any
# warranty.
#serial 8
#serial 18
AU_ALIAS([AC_PROG_CC_FOR_BUILD], [AX_PROG_CC_FOR_BUILD])
AC_DEFUN([AX_PROG_CC_FOR_BUILD], [dnl
AC_REQUIRE([AC_PROG_CC])dnl
AC_REQUIRE([AC_PROG_CPP])dnl
AC_REQUIRE([AC_EXEEXT])dnl
AC_REQUIRE([AC_CANONICAL_HOST])dnl
AC_REQUIRE([AC_CANONICAL_BUILD])dnl
dnl Use the standard macros, but make them use other variable names
dnl
pushdef([ac_cv_prog_CPP], ac_cv_build_prog_CPP)dnl
pushdef([ac_cv_prog_cc_c89], ac_cv_build_prog_cc_c89)dnl
pushdef([ac_cv_prog_gcc], ac_cv_build_prog_gcc)dnl
pushdef([ac_cv_prog_cc_works], ac_cv_build_prog_cc_works)dnl
pushdef([ac_cv_prog_cc_cross], ac_cv_build_prog_cc_cross)dnl
pushdef([ac_cv_prog_cc_g], ac_cv_build_prog_cc_g)dnl
pushdef([ac_cv_c_compiler_gnu], ac_cv_build_c_compiler_gnu)dnl
pushdef([ac_cv_exeext], ac_cv_build_exeext)dnl
pushdef([ac_cv_objext], ac_cv_build_objext)dnl
pushdef([ac_exeext], ac_build_exeext)dnl
pushdef([ac_objext], ac_build_objext)dnl
pushdef([CC], CC_FOR_BUILD)dnl
pushdef([CPP], CPP_FOR_BUILD)dnl
pushdef([GCC], GCC_FOR_BUILD)dnl
pushdef([CFLAGS], CFLAGS_FOR_BUILD)dnl
pushdef([CPPFLAGS], CPPFLAGS_FOR_BUILD)dnl
pushdef([EXEEXT], BUILD_EXEEXT)dnl
pushdef([LDFLAGS], LDFLAGS_FOR_BUILD)dnl
pushdef([OBJEXT], BUILD_OBJEXT)dnl
pushdef([host], build)dnl
pushdef([host_alias], build_alias)dnl
pushdef([host_cpu], build_cpu)dnl
@@ -318,27 +322,29 @@ pushdef([ac_cv_host_alias], ac_cv_build_alias)dnl
pushdef([ac_cv_host_cpu], ac_cv_build_cpu)dnl
pushdef([ac_cv_host_vendor], ac_cv_build_vendor)dnl
pushdef([ac_cv_host_os], ac_cv_build_os)dnl
pushdef([ac_cpp], ac_build_cpp)dnl
pushdef([ac_compile], ac_build_compile)dnl
pushdef([ac_link], ac_build_link)dnl
pushdef([ac_tool_prefix], ac_build_tool_prefix)dnl
pushdef([am_cv_CC_dependencies_compiler_type], am_cv_build_CC_dependencies_compiler_type)dnl
pushdef([am_cv_prog_cc_c_o], am_cv_build_prog_cc_c_o)dnl
pushdef([cross_compiling], cross_compiling_build)dnl
save_cross_compiling=$cross_compiling
save_ac_tool_prefix=$ac_tool_prefix
cross_compiling=no
ac_tool_prefix=
cross_compiling_build=no
ac_build_tool_prefix=
AS_IF([test -n "$build"], [ac_build_tool_prefix="$build-"],
[test -n "$build_alias"],[ac_build_tool_prefix="$build_alias-"])
AC_LANG_PUSH([C])
AC_PROG_CC
_AC_COMPILER_EXEEXT
_AC_COMPILER_OBJEXT
AC_PROG_CPP
AC_EXEEXT
ac_tool_prefix=$save_ac_tool_prefix
cross_compiling=$save_cross_compiling
dnl Restore the old definitions
dnl
popdef([ac_link])dnl
popdef([ac_compile])dnl
popdef([ac_cpp])dnl
popdef([cross_compiling])dnl
popdef([am_cv_prog_cc_c_o])dnl
popdef([am_cv_CC_dependencies_compiler_type])dnl
popdef([ac_tool_prefix])dnl
popdef([ac_cv_host_os])dnl
popdef([ac_cv_host_vendor])dnl
popdef([ac_cv_host_cpu])dnl
@@ -349,29 +355,36 @@ popdef([host_vendor])dnl
popdef([host_cpu])dnl
popdef([host_alias])dnl
popdef([host])dnl
popdef([OBJEXT])dnl
popdef([LDFLAGS])dnl
popdef([EXEEXT])dnl
popdef([CPPFLAGS])dnl
popdef([CFLAGS])dnl
popdef([GCC])dnl
popdef([CPP])dnl
popdef([CC])dnl
popdef([ac_objext])dnl
popdef([ac_exeext])dnl
popdef([ac_cv_objext])dnl
popdef([ac_cv_exeext])dnl
popdef([ac_cv_c_compiler_gnu])dnl
popdef([ac_cv_prog_cc_g])dnl
popdef([ac_cv_prog_cc_cross])dnl
popdef([ac_cv_prog_cc_works])dnl
popdef([ac_cv_prog_cc_c89])dnl
popdef([ac_cv_prog_gcc])dnl
popdef([ac_cv_prog_CPP])dnl
dnl restore global variables ac_ext, ac_cpp, ac_compile,
dnl ac_link, ac_compiler_gnu (dependant on the current
dnl language after popping):
AC_LANG_POP([C])
dnl Finally, set Makefile variables
dnl
BUILD_EXEEXT=$ac_build_exeext
BUILD_OBJEXT=$ac_build_objext
AC_SUBST(BUILD_EXEEXT)dnl
AC_SUBST(BUILD_OBJEXT)dnl
AC_SUBST([CFLAGS_FOR_BUILD])dnl
AC_SUBST([CPPFLAGS_FOR_BUILD])dnl
AC_SUBST([LDFLAGS_FOR_BUILD])dnl
])
+3 -3
View File
@@ -147,7 +147,7 @@ extern unsigned long array_size_limit;
extern const char*basedir;
/* This is an ordered list of library suffixes to search. */
extern list<const char*>library_suff;
extern std::list<const char*>library_suff;
extern int build_library_index(const char*path, bool key_case_sensitive);
/* This is the generation of Verilog that the compiler is asked to
@@ -244,14 +244,14 @@ extern int lexor_keyword_mask;
/* This is the string to use to invoke the preprocessor. */
extern char*ivlpp_string;
extern map<perm_string,unsigned> missing_modules;
extern std::map<perm_string,unsigned> missing_modules;
/* Files that are library files are in this map. The lexor compares
file names as it processes `line directives, and if the file name
matches an entry in this table, it will turn on the
library_active_flag so that modules know that they are in a
library. */
extern map<perm_string,bool> library_file_map;
extern std::map<perm_string,bool> library_file_map;
/*
* the lex_strings are perm_strings made up of tokens from the source
+1 -9
View File
@@ -1,7 +1,7 @@
#ifndef IVL_config_H /* -*- c++ -*- */
#define IVL_config_H
/*
* Copyright (c) 2001-2015 Stephen Williams ([email protected])
* Copyright (c) 2001-2021 Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -19,14 +19,6 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#if defined(__cplusplus)
# if !defined(__GNUC__)
using namespace std;
# elif (__GNUC__ == 3)
using namespace std;
# endif
#endif
# undef NEED_LU
# undef NEED_TU
# undef WLU
+25 -26
View File
@@ -1,21 +1,22 @@
dnl Process this file with autoconf to produce a configure script.
AC_INIT(netlist.h)
AC_CONFIG_HEADER(config.h)
AC_CONFIG_HEADER(_pli_types.h)
AC_CONFIG_HEADER(vhdlpp/vhdlpp_config.h)
AC_CONFIG_HEADER(vvp/config.h)
AC_CONFIG_HEADER(vpi/vpi_config.h)
AC_CONFIG_HEADER(libveriuser/config.h)
AC_CONFIG_HEADER(tgt-vvp/vvp_config.h)
AC_CONFIG_HEADER(tgt-vhdl/vhdl_config.h)
AC_CONFIG_HEADER(tgt-pcb/pcb_config.h)
AC_INIT
AC_CONFIG_SRCDIR([netlist.h])
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_HEADERS([_pli_types.h])
AC_CONFIG_HEADERS([vhdlpp/vhdlpp_config.h])
AC_CONFIG_HEADERS([vvp/config.h])
AC_CONFIG_HEADERS([vpi/vpi_config.h])
AC_CONFIG_HEADERS([libveriuser/config.h])
AC_CONFIG_HEADERS([tgt-vvp/vvp_config.h])
AC_CONFIG_HEADERS([tgt-vhdl/vhdl_config.h])
AC_CONFIG_HEADERS([tgt-pcb/pcb_config.h])
AC_CANONICAL_HOST
dnl Checks for programs.
AC_PROG_CC
# AC_PROG_CC_C99 is only available in autoconf version 2.60 and later.
AC_PREREQ([2.60])
AC_PROG_CC_C99
AX_PROG_CC_FOR_BUILD
AC_PREREQ([2.62])
m4_version_prereq([2.70], [], [AC_PROG_CC_C99])
AC_PROG_CXX
AC_PROG_RANLIB
AC_CHECK_TOOL(LD, ld, false)
@@ -92,7 +93,7 @@ fi
AC_LANG(C++)
AC_ARG_WITH([m32], [AC_HELP_STRING([--with-m32], [Compile 32-bit on x86_64])],
AC_ARG_WITH([m32], [AS_HELP_STRING([--with-m32],[Compile 32-bit on x86_64])],
[ with_m32=yes ],[ with_m32=no ])
AS_IF( [test "x$with_m32" = xyes],
@@ -135,6 +136,7 @@ CXXFLAGS="$iverilog_temp_cxxflags"
AC_CHECK_SIZEOF(unsigned long long)
AC_CHECK_SIZEOF(unsigned long)
AC_CHECK_SIZEOF(unsigned)
AC_CHECK_SIZEOF(void *)
# vvp uses these...
AC_CHECK_LIB(termcap, tputs)
@@ -169,8 +171,7 @@ AC_FUNC_ALLOCA
AC_FUNC_FSEEKO
# valgrind checks
AC_ARG_WITH([valgrind], [AC_HELP_STRING([--with-valgrind],
[Add valgrind hooks])],
AC_ARG_WITH([valgrind], [AS_HELP_STRING([--with-valgrind],[Add valgrind hooks])],
[], [check_valgrind=yes])
AS_IF([test "x$check_valgrind" = xyes],
@@ -181,14 +182,11 @@ AS_IF([test "x$check_valgrind" = xyes],
[AC_MSG_ERROR([Could not find <valgrind/memcheck.h>])])])
AC_MSG_CHECKING(for sys/times)
AC_TRY_LINK(
#include <unistd.h>
AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <unistd.h>
#include <sys/times.h>
,{clock_t a = times(0)/sysconf(_SC_CLK_TCK);},
do_times=yes
AC_DEFINE([HAVE_TIMES], [1], [The times system call is available in the host operating system.]),
do_times=no
)
]], [[{clock_t a = times(0)/sysconf(_SC_CLK_TCK);}]])],[do_times=yes
AC_DEFINE(HAVE_TIMES, 1, The times system call is available in the host operating system.)],[do_times=no
])
AC_MSG_RESULT($do_times)
# --
@@ -261,7 +259,8 @@ 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.
# autoconf >= 2.70 will enable C99 if it is available. For older autoconf
# versions, 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])])
@@ -335,5 +334,5 @@ then
AC_MSG_ERROR(cannot configure white space in libdir: $libdir)
fi
AC_MSG_RESULT(ok)
AX_PROG_CC_FOR_BUILD
AC_OUTPUT(Makefile ivlpp/Makefile vhdlpp/Makefile vvp/Makefile vpi/Makefile driver/Makefile driver-vpi/Makefile cadpli/Makefile libveriuser/Makefile tgt-null/Makefile tgt-stub/Makefile tgt-vvp/Makefile tgt-vhdl/Makefile tgt-fpga/Makefile tgt-verilog/Makefile tgt-pal/Makefile tgt-vlog95/Makefile tgt-pcb/Makefile tgt-blif/Makefile tgt-sizer/Makefile)
AC_CONFIG_FILES([Makefile ivlpp/Makefile vhdlpp/Makefile vvp/Makefile vpi/Makefile driver/Makefile driver-vpi/Makefile cadpli/Makefile libveriuser/Makefile tgt-null/Makefile tgt-stub/Makefile tgt-vvp/Makefile tgt-vhdl/Makefile tgt-fpga/Makefile tgt-verilog/Makefile tgt-pal/Makefile tgt-vlog95/Makefile tgt-pcb/Makefile tgt-blif/Makefile tgt-sizer/Makefile])
AC_OUTPUT
+1
View File
@@ -28,6 +28,7 @@
# include "compiler.h"
# include "ivl_assert.h"
using namespace std;
/*
* The cprop function below invokes constant propagation where
+2
View File
@@ -35,6 +35,8 @@
# include "ivl_assert.h"
# include "PExpr.h"
using namespace std;
static ostream& operator<< (ostream&o, NetBlock::Type t)
{
switch (t) {
+4 -4
View File
@@ -1,7 +1,7 @@
#ifndef IVL_discipline_H
#define IVL_discipline_H
/*
* Copyright (c) 2008-2014 Stephen Williams (steve@icarus.com)
* Copyright (c) 2008-2021 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -69,9 +69,9 @@ class ivl_discipline_s : public LineInfo {
ivl_discipline_s& operator = (const ivl_discipline_s&);
};
extern map<perm_string,ivl_nature_t> natures;
extern map<perm_string,ivl_discipline_t> disciplines;
extern std::map<perm_string,ivl_nature_t> natures;
extern std::map<perm_string,ivl_discipline_t> disciplines;
// Map access function name to the nature that it accesses.
extern map<perm_string,ivl_nature_t> access_function_nature;
extern std::map<perm_string,ivl_nature_t> access_function_nature;
#endif /* IVL_discipline_H */
+3 -3
View File
@@ -99,7 +99,7 @@ install: all installdirs installfiles
F = ./iverilog-vpi@EXEEXT@
installfiles: $(F) | installdirs
$(INSTALL_PROGRAM) ./iverilog-vpi@EXEEXT@ "$(bindir)/iverilog-vpi$(suffix)@EXEEXT@"
$(INSTALL_PROGRAM) ./iverilog-vpi@EXEEXT@ "$(DESTDIR)$(bindir)/iverilog-vpi$(suffix)@EXEEXT@"
ifeq (@WIN32@,yes)
ifneq ($(HOSTCC),$(CC))
$(INSTALL_PROGRAM) $(shell $(HOSTCC) --print-file-name=libwinpthread-1.dll) "$(DESTDIR)$(bindir)"
@@ -109,7 +109,7 @@ endif
endif
installdirs: $(srcdir)/../mkinstalldirs
$(srcdir)/../mkinstalldirs "$(bindir)"
$(srcdir)/../mkinstalldirs "$(DESTDIR)$(bindir)"
uninstall:
rm -f $(bindir)/iverilog-vpi$(suffix)@EXEEXT@
rm -f $(DESTDIR)$(bindir)/iverilog-vpi$(suffix)@EXEEXT@
+4 -4
View File
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2015-2022 Martin Whitaker
* Copyright (c) 2002 Gus Baldauf (gus@picturel.com)
* Copyright (c) 2015 Martin Whitaker
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -564,10 +564,10 @@ static void compile(char *pSource, char *pFlags, char **pObject, int *compile_er
assignn(&src, ptr1, len);
/* Build the object file name */
ostart = strrchr(ptr1, '/');
if (ostart == NULL) ostart = ptr1;
ostart = strrchr(src, '/');
if (ostart == NULL) ostart = src;
else ostart += 1;
olen = strrchr(ptr1, '.') - ostart;
olen = strrchr(ostart, '.') - ostart;
assignn(&obj, ostart, olen);
append(&obj, ".o");
+7 -3
View File
@@ -1,4 +1,4 @@
.TH iverilog 1 "Aug 10th, 2020" "" "Version %M.%n%E"
.TH iverilog 1 "Jan 14th, 2021" "" "Version %M.%n%E"
.SH NAME
iverilog - Icarus Verilog compiler
@@ -582,9 +582,13 @@ The following macros are predefined by the compiler:
.B __ICARUS__ = 1
This is always defined when compiling with Icarus Verilog.
.TP 8
.B __ICARUS_SYNTH__ = 1
This is defined when synthesis is enabled.
.TP 8
.B __VAMS_ENABLE__ = 1
This is defined if Verilog\-AMS is enabled.
This is defined when Verilog\-AMS is enabled.
.SH ENVIRONMENT
.PP
@@ -633,7 +637,7 @@ Tips on using, debugging, and developing the compiler can be found at
.SH COPYRIGHT
.nf
Copyright \(co 2002\-2020 Stephen Williams
Copyright \(co 2002\-2021 Stephen Williams
This document can be freely redistributed according to the terms of the
GNU General Public License version 2.0
+16 -6
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2000-2020 Stephen Williams (steve@icarus.com)
* Copyright (c) 2000-2021 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -184,7 +184,7 @@ int verbose_flag = 0;
FILE *fp;
char line[MAXSIZE];
char tmp[MAXSIZE];
char tmp[MAXSIZE+24];
static char ivl_root[MAXSIZE];
@@ -1046,7 +1046,7 @@ static void find_ivl_root(void)
if the user has overridden $(bindir) or $(libdir), but there's
not a lot we can do in that case.
*/
#ifdef __MINGW32__
#if defined(__MINGW32__)
char tmppath[MAXSIZE];
len = GetModuleFileName(NULL, tmppath, sizeof tmppath);
if (len >= (ssize_t) sizeof ivl_root) {
@@ -1054,6 +1054,9 @@ static void find_ivl_root(void)
}
/* Convert to a short name to remove any embedded spaces. */
len = GetShortPathName(tmppath, ivl_root, sizeof ivl_root);
#elif defined(__APPLE__)
uint32_t size = sizeof ivl_root;
len = _NSGetExecutablePath(ivl_root, &size) + 1;
#else
len = readlink("/proc/self/exe", ivl_root, sizeof ivl_root);
#endif
@@ -1061,7 +1064,11 @@ static void find_ivl_root(void)
find_ivl_root_failed("command path exceeds size of string buffer.");
}
if (len <= 0) {
find_ivl_root_failed("couldn't get command path from OS.");
// We've failed, but we may yet find a -B option on the command line.
// Use the built-in path so the user sees a sensible error message.
assert(strlen(IVL_ROOT) < sizeof ivl_root);
strcpy(ivl_root, IVL_ROOT);
return;
}
s = strrchr(ivl_root, sep);
if (s == 0) {
@@ -1116,8 +1123,6 @@ int main(int argc, char **argv)
}
fprintf(defines_file, "D:__ICARUS__=1\n");
if (strcmp(gen_verilog_ams,"verilog-ams") == 0)
fprintf(defines_file, "D:__VAMS_ENABLE__=1\n");
/* Create another temporary file for passing configuration
information to ivl. */
@@ -1301,6 +1306,11 @@ int main(int argc, char **argv)
}
}
if (strcmp(gen_verilog_ams,"verilog-ams") == 0)
fprintf(defines_file, "D:__VAMS_ENABLE__=1\n");
if (synth_flag)
fprintf(defines_file, "D:__ICARUS_SYNTH__=1\n");
if (vpi_dir == 0)
vpi_dir = base;
if (ivlpp_dir == 0)
+3 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1999-2019 Stephen Williams (steve@icarus.com)
* Copyright (c) 1999-2021 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -24,6 +24,8 @@
# include <cstdlib>
# include "ivl_assert.h"
using namespace std;
NetEAccess* NetEAccess::dup_expr() const
{
NetEAccess*tmp = new NetEAccess(branch_, nature_);
+3 -2
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2000-2003 Stephen Williams (steve@icarus.com)
* Copyright (c) 2000-2021 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -29,6 +29,8 @@
# include "netmisc.h"
# include <iostream>
using namespace std;
NetNet* PExpr::elaborate_anet(Design*des, NetScope*scope) const
{
cerr << get_line() << ": error: Invalid expression on left side "
@@ -163,4 +165,3 @@ NetNet* PEIdent::elaborate_anet(Design*des, NetScope*scope) const
return sig;
}
+180 -43
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1999-2020 Stephen Williams (steve@icarus.com)
* Copyright (c) 1999-2021 Stephen Williams (steve@icarus.com)
* Copyright CERN 2013 / Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
@@ -41,6 +41,8 @@
# include "util.h"
# include "ivl_assert.h"
using namespace std;
bool type_is_vectorable(ivl_variable_type_t type)
{
switch (type) {
@@ -110,6 +112,7 @@ NetExpr* elaborate_rval_expr(Design*des, NetScope*scope, ivl_type_t lv_net_type,
switch (lv_type) {
case IVL_VT_DARRAY:
case IVL_VT_QUEUE:
case IVL_VT_CLASS:
// For these types, use a different elab_and_eval that
// uses the lv_net_type. We should eventually transition
// all the types to this new form.
@@ -127,12 +130,6 @@ NetExpr* elaborate_rval_expr(Design*des, NetScope*scope, ivl_type_t lv_net_type,
case IVL_VT_NO_TYPE:
ivl_assert(*expr, 0);
break;
case IVL_VT_CLASS:
cerr << expr->get_fileline() << ": sorry: "
<< "I do not know how to elaborate r-value as IVL_VT_CLASS." << endl;
des->errors += 1;
return 0;
break;
}
return elab_and_eval(des, scope, expr, context_wid, need_const,
@@ -282,6 +279,13 @@ unsigned PEBinary::test_width(Design*des, NetScope*scope, width_mode_t&mode)
ivl_variable_type_t l_type = left_->expr_type();
ivl_variable_type_t r_type = right_->expr_type();
if (l_type == IVL_VT_CLASS || r_type == IVL_VT_CLASS) {
cerr << get_fileline() << ": error: "
<< "Class/null is not allowed with the '"
<< human_readable_op(op_) << "' operator." << endl;
des->errors += 1;
}
if (l_type == IVL_VT_REAL || r_type == IVL_VT_REAL)
expr_type_ = IVL_VT_REAL;
else if (l_type == IVL_VT_LOGIC || r_type == IVL_VT_LOGIC)
@@ -627,6 +631,34 @@ unsigned PEBComp::test_width(Design*des, NetScope*scope, width_mode_t&)
<< r_width_ << " bits." << endl;
}
switch (op_) {
case 'e': /* == */
case 'n': /* != */
case 'E': /* === */
case 'N': /* !== */
// FIXME: A class variable/array inside a class is not
// reported correctly so this cannot be used.
#if 0
if ((l_type == IVL_VT_CLASS || r_type == IVL_VT_CLASS) &&
l_type != r_type) {
cerr << get_fileline() << ": error: "
<< "Both arguments ("<< l_type << ", " << r_type
<< ") must be class/null for '"
<< human_readable_op(op_) << "' operator." << endl;
des->errors += 1;
}
#endif
break;
default:
if (l_type == IVL_VT_CLASS || r_type == IVL_VT_CLASS) {
cerr << get_fileline() << ": error: "
<< "Class/null is not allowed with the '"
<< human_readable_op(op_) << "' operator." << endl;
des->errors += 1;
}
}
return expr_width_;
}
@@ -760,6 +792,13 @@ unsigned PEBLeftWidth::test_width(Design*des, NetScope*scope, width_mode_t&mode)
expr_type_ = left_->expr_type();
signed_flag_ = left_->has_sign();
if (expr_type_ == IVL_VT_CLASS || right_->expr_type() == IVL_VT_CLASS) {
cerr << get_fileline() << ": error: "
<< "Class/null is not allowed with the '"
<< human_readable_op(op_) << "' operator." << endl;
des->errors += 1;
}
if (mode==SIZED)
mode = l_mode;
@@ -1958,6 +1997,7 @@ static NetExpr* check_for_struct_members(const LineInfo*li,
unsigned long use_width = struct_type->packed_width();
pform_name_t completed_path;
ivl_type_t member_type = 0;
do {
const name_component_t member_comp = member_path.front();
const perm_string&member_name = member_comp.name;
@@ -1985,28 +2025,29 @@ static NetExpr* check_for_struct_members(const LineInfo*li,
des->errors += 1;
return 0;
}
member_type = member->net_type;
if (debug_elaborate) {
cerr << li->get_fileline() << ": check_for_struct_members: "
<< "Member type: " << *(member->net_type)
<< " (" << typeid(*(member->net_type)).name() << ")"
<< "Member type: " << *member_type
<< " (" << typeid(*member_type).name() << ")"
<< endl;
}
off += tmp_off;
ivl_assert(*li, use_width >= (unsigned long)member->net_type->packed_width());
use_width = member->net_type->packed_width();
ivl_assert(*li, use_width >= (unsigned long)member_type->packed_width());
use_width = member_type->packed_width();
// At this point, off and use_width are the part select
// expressed by the member_comp, which is a member of the
// struct. We can further refine the part select with any
// indices that might be present.
if (const netstruct_t*tmp_struct = dynamic_cast<const netstruct_t*>(member->net_type)) {
if (const netstruct_t*tmp_struct = dynamic_cast<const netstruct_t*>(member_type)) {
// If the member is itself a struct, then get
// ready to go on to the next iteration.
struct_type = tmp_struct;
} else if (const netenum_t*tmp_enum = dynamic_cast<const netenum_t*> (member->net_type)) {
} else if (const netenum_t*tmp_enum = dynamic_cast<const netenum_t*> (member_type)) {
// If the element is an enum, then we don't have
// anything special to do.
@@ -2017,7 +2058,7 @@ static NetExpr* check_for_struct_members(const LineInfo*li,
}
struct_type = 0;
} else if (const netvector_t*mem_vec = dynamic_cast<const netvector_t*>(member->net_type)) {
} else if (const netvector_t*mem_vec = dynamic_cast<const netvector_t*>(member_type)) {
if (debug_elaborate) {
cerr << li->get_fileline() << ": check_for_struct_members: "
@@ -2104,7 +2145,7 @@ static NetExpr* check_for_struct_members(const LineInfo*li,
// there is no next struct type.
struct_type = 0;
} else if (const netparray_t*array = dynamic_cast<const netparray_t*>(member->net_type)) {
} else if (const netparray_t*array = dynamic_cast<const netparray_t*>(member_type)) {
// If the member is a parray, then the elements
// are themselves packed object, including
@@ -2178,7 +2219,7 @@ static NetExpr* check_for_struct_members(const LineInfo*li,
} else {
// Unknown type?
cerr << li->get_fileline() << ": internal error: "
<< "Unexpected member type? " << *(member->net_type)
<< "Unexpected member type? " << *member_type
<< endl;
des->errors += 1;
struct_type = 0;
@@ -2224,7 +2265,7 @@ static NetExpr* check_for_struct_members(const LineInfo*li,
NetESignal*sig = new NetESignal(net);
NetExpr *base = packed_base? packed_base : make_const_val(off);
NetESelect*sel = new NetESelect(sig, base, use_width);
NetESelect*sel = new NetESelect(sig, base, use_width, member_type);
if (debug_elaborate) {
cerr << li->get_fileline() << ": check_for_struct_member: "
@@ -3556,6 +3597,15 @@ unsigned PEIdent::test_width(Design*des, NetScope*scope, width_mode_t&mode)
}
if (use_width != UINT_MAX) {
// We have a bit/part select. Account for any remaining dimensions
// beyond the indexed dimension.
size_t use_depth = name_tail.index.size();
if (net) {
if (use_depth >= net->unpacked_dimensions())
use_depth -= net->unpacked_dimensions();
use_width *= net->slice_width(use_depth);
}
expr_type_ = IVL_VT_LOGIC; // Assume bit/parts selects are logic
expr_width_ = use_width;
min_width_ = use_width;
@@ -5085,11 +5135,19 @@ NetExpr* PEIdent::elaborate_expr_net_part_(Design*des, NetScope*scope,
// range.
long loff, moff;
unsigned long lwid, mwid;
bool lrc;
bool lrc, mrc;
lrc = net->sig()->sb_to_slice(prefix_indices, lsv, loff, lwid);
ivl_assert(*this, lrc);
lrc = net->sig()->sb_to_slice(prefix_indices, msv, moff, mwid);
ivl_assert(*this, lrc);
mrc = net->sig()->sb_to_slice(prefix_indices, msv, moff, mwid);
if (!mrc || !lrc) {
cerr << get_fileline() << ": error: ";
cerr << "Part-select [" << msv << ":" << lsv;
cerr << "] exceeds the declared bounds for ";
cerr << net->sig()->name();
if (net->sig()->unpacked_dimensions() > 0) cerr << "[]";
cerr << "." << endl;
des->errors += 1;
return 0;
}
ivl_assert(*this, lwid == mwid);
if (moff > loff) {
@@ -5195,19 +5253,48 @@ NetExpr* PEIdent::elaborate_expr_net_idx_up_(Design*des, NetScope*scope,
NetExpr*ex;
if (base_c->value().is_defined()) {
long lsv = base_c->value().as_long();
long offset = 0;
long rel_base = 0;
// Get the signal range.
const vector<netrange_t>&packed = net->sig()->packed_dims();
ivl_assert(*this, packed.size() == prefix_indices.size()+1);
if (prefix_indices.size()+1 < net->sig()->packed_dims().size()) {
// Here we are selecting one or more sub-arrays.
// Make this work by finding the indexed sub-arrays and
// creating a generated slice that spans the whole range.
unsigned long swid = net->sig()->slice_width(prefix_indices.size()+1);
ivl_assert(*this, swid > 0);
long loff, moff;
unsigned long lwid, mwid;
bool lrc, mrc;
mrc = net->sig()->sb_to_slice(prefix_indices, lsv, moff, mwid);
lrc = net->sig()->sb_to_slice(prefix_indices, lsv+(wid/swid)-1, loff, lwid);
if (!mrc || !lrc) {
cerr << get_fileline() << ": error: ";
cerr << "Part-select [" << lsv << "+:" << (wid/swid);
cerr << "] exceeds the declared bounds for ";
cerr << net->sig()->name();
if (net->sig()->unpacked_dimensions() > 0) cerr << "[]";
cerr << "." << endl;
des->errors += 1;
return 0;
}
ivl_assert(*this, mwid == swid);
ivl_assert(*this, lwid == swid);
// We want the last range, which is where we work.
const netrange_t&rng = packed.back();
if (rng.get_msb() < rng.get_lsb()) {
offset = -wid + 1;
if (moff > loff) {
rel_base = loff;
} else {
rel_base = moff;
}
} else {
long offset = 0;
// We want the last range, which is where we work.
const netrange_t&rng = packed.back();
if (rng.get_msb() < rng.get_lsb()) {
offset = -wid + 1;
}
rel_base = net->sig()->sb_to_idx(prefix_indices, lsv) + offset;
}
long rel_base = net->sig()->sb_to_idx(prefix_indices, lsv);
// If the part select covers exactly the entire
// vector, then do not bother with it. Return the
// signal itself.
@@ -5219,7 +5306,7 @@ NetExpr* PEIdent::elaborate_expr_net_idx_up_(Design*des, NetScope*scope,
// Otherwise, make a part select that covers the right
// range.
ex = new NetEConst(verinum(rel_base + offset));
ex = new NetEConst(verinum(rel_base));
if (warn_ob_select) {
if (rel_base < 0) {
cerr << get_fileline() << ": warning: "
@@ -5298,31 +5385,66 @@ NetExpr* PEIdent::elaborate_expr_net_idx_do_(Design*des, NetScope*scope,
NetExpr*ex;
if (base_c->value().is_defined()) {
long lsv = base_c->value().as_long();
long rel_base = 0;
// Get the signal range.
const vector<netrange_t>&packed = net->sig()->packed_dims();
if (prefix_indices.size()+1 < net->sig()->packed_dims().size()) {
// Here we are selecting one or more sub-arrays.
// Make this work by finding the indexed sub-arrays and
// creating a generated slice that spans the whole range.
unsigned long swid = net->sig()->slice_width(prefix_indices.size()+1);
ivl_assert(*this, swid > 0);
long loff, moff;
unsigned long lwid, mwid;
bool lrc, mrc;
mrc = net->sig()->sb_to_slice(prefix_indices, lsv, moff, mwid);
lrc = net->sig()->sb_to_slice(prefix_indices, lsv-(wid/swid)+1, loff, lwid);
if (!mrc || !lrc) {
cerr << get_fileline() << ": error: ";
cerr << "Part-select [" << lsv << "-:" << (wid/swid);
cerr << "] exceeds the declared bounds for ";
cerr << net->sig()->name();
if (net->sig()->unpacked_dimensions() > 0) cerr << "[]";
cerr << "." << endl;
des->errors += 1;
return 0;
}
ivl_assert(*this, mwid == swid);
ivl_assert(*this, lwid == swid);
if (moff > loff) {
rel_base = loff;
} else {
rel_base = moff;
}
} else {
long offset = 0;
// We want the last range, which is where we work.
const netrange_t&rng = packed.back();
if (rng.get_msb() > rng.get_lsb()) {
offset = -wid + 1;
}
rel_base = net->sig()->sb_to_idx(prefix_indices, lsv) + offset;
}
// If the part select covers exactly the entire
// vector, then do not bother with it. Return the
// signal itself.
if (net->sig()->sb_to_idx(prefix_indices,lsv) == (signed) (wid-1) &&
wid == net->vector_width()) {
if (rel_base == (long)(wid-1) && wid == net->vector_width()) {
delete base;
net->cast_signed(false);
return net;
}
long offset = 0;
if (net->msi() > net->lsi()) {
offset = -wid + 1;
}
// Otherwise, make a part select that covers the right
// range.
ex = new NetEConst(verinum(net->sig()->sb_to_idx(prefix_indices,lsv) + offset));
ex = new NetEConst(verinum(rel_base));
if (warn_ob_select) {
long rel_base = net->sig()->sb_to_idx(prefix_indices,lsv) + offset;
if (rel_base < 0) {
cerr << get_fileline() << ": warning: "
<< net->name();
if (net->word_index()) cerr << "[]";
cerr << "[" << lsv << "+:" << wid
cerr << "[" << lsv << "-:" << wid
<< "] is selecting before vector." << endl;
}
if (rel_base + wid > net->vector_width()) {
@@ -5353,7 +5475,11 @@ NetExpr* PEIdent::elaborate_expr_net_idx_do_(Design*des, NetScope*scope,
return ss;
}
base = normalize_variable_base(base, net->msi(), net->lsi(), wid, false);
ivl_assert(*this, prefix_indices.size()+1 == net->sig()->packed_dims().size());
// Convert the non-constant part select index expression into
// an expression that returns a canonical base.
base = normalize_variable_part_base(prefix_indices, base, net->sig(), wid, false);
NetESelect*ss = new NetESelect(net, base, wid, IVL_SEL_IDX_DOWN);
ss->set_line(*this);
@@ -5395,7 +5521,7 @@ NetExpr* PEIdent::elaborate_expr_net_bit_(Design*des, NetScope*scope,
cerr << get_fileline() << ": debug: "
<< "Bit select of a dynamic array becomes NetESelect." << endl;
}
NetESelect*res = new NetESelect(net, mux, darray->element_width());
NetESelect*res = new NetESelect(net, mux, darray->element_width(), darray->element_type());
res->set_line(*net);
return res;
}
@@ -5597,13 +5723,15 @@ NetExpr* PEIdent::elaborate_expr_net_bit_last_(Design*, NetScope*,
}
unsigned use_width = 1;
ivl_type_t use_type = 0;
if (const netdarray_t*darray = net->sig()->darray_type()) {
use_width = darray->element_width();
use_type = darray->element_type();
}
NetELast*mux = new NetELast(net->sig());
mux->set_line(*this);
NetESelect*ss = new NetESelect(net, mux, use_width);
NetESelect*ss = new NetESelect(net, mux, use_width, use_type);
ss->set_line(*this);
return ss;
}
@@ -6262,6 +6390,16 @@ NetExpr*PETypename::elaborate_expr(Design*des, NetScope*,
unsigned PEUnary::test_width(Design*des, NetScope*scope, width_mode_t&mode)
{
// Evaluate the expression width to get the correct type information
expr_width_ = expr_->test_width(des, scope, mode);
if (expr_->expr_type() == IVL_VT_CLASS) {
cerr << get_fileline() << ": error: "
<< "Class/null is not allowed with the '"
<< human_readable_op(op_) << "' operator." << endl;
des->errors += 1;
}
switch (op_) {
case '&': // Reduction AND
case '|': // Reduction OR
@@ -6291,7 +6429,6 @@ unsigned PEUnary::test_width(Design*des, NetScope*scope, width_mode_t&mode)
return expr_width_;
}
expr_width_ = expr_->test_width(des, scope, mode);
expr_type_ = expr_->expr_type();
min_width_ = expr_->min_width();
signed_flag_ = expr_->has_sign();
+73 -20
View File
@@ -36,6 +36,8 @@
# include <climits>
# include "ivl_assert.h"
using namespace std;
/*
* These methods generate a NetAssign_ object for the l-value of the
* assignment. This is common code for the = and <= statements.
@@ -247,12 +249,18 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
use_sel = name_tail.index.back().sel;
// Special case: The l-value is an entire memory, or array
// slice. This is, in fact, an error in l-values. Detect the
// situation by noting if the index count is less than the
// array dimensions (unpacked).
// slice. Detect the situation by noting if the index count
// is less than the array dimensions (unpacked).
if (reg->unpacked_dimensions() > name_tail.index.size()) {
cerr << get_fileline() << ": error: Cannot assign to array "
<< path_ << ". Did you forget a word index?" << endl;
if (gn_system_verilog()) {
cerr << get_fileline() << ": sorry: Assignment to an entire"
" array or to an array slice is not yet supported."
<< endl;
} else {
cerr << get_fileline() << ": error: Assignment to an entire"
" array or to an array slice requires SystemVerilog."
<< endl;
}
des->errors += 1;
return 0;
}
@@ -853,12 +861,20 @@ bool PEIdent::elaborate_lval_net_part_(Design*des,
// If there are fewer indices then there are packed
// dimensions, then this is a range of slices. Calculate
// it into a big slice.
bool lrc;
bool lrc, mrc;
unsigned long tmp_lwid, tmp_mwid;
lrc = reg->sb_to_slice(prefix_indices,lsb, loff, tmp_lwid);
ivl_assert(*this, lrc);
lrc = reg->sb_to_slice(prefix_indices,msb, moff, tmp_mwid);
ivl_assert(*this, lrc);
lrc = reg->sb_to_slice(prefix_indices, lsb, loff, tmp_lwid);
mrc = reg->sb_to_slice(prefix_indices, msb, moff, tmp_mwid);
if (!mrc || !lrc) {
cerr << get_fileline() << ": error: ";
cerr << "Part-select [" << msb << ":" << lsb;
cerr << "] exceeds the declared bounds for ";
cerr << reg->name();
if (reg->unpacked_dimensions() > 0) cerr << "[]";
cerr << "." << endl;
des->errors += 1;
return 0;
}
if (loff < moff) {
moff = moff + tmp_mwid - 1;
@@ -938,21 +954,58 @@ bool PEIdent::elaborate_lval_net_idx_(Design*des,
// we will handle it in the code generator.
if (base_c->value().is_defined()) {
long lsv = base_c->value().as_long();
long offset = 0;
long rel_base = 0;
// Get the signal range.
const vector<netrange_t>&packed = reg->packed_dims();
ivl_assert(*this, packed.size() == prefix_indices.size()+1);
if (prefix_indices.size()+1 < reg->packed_dims().size()) {
// Here we are selecting one or more sub-arrays.
// Make this work by finding the indexed sub-arrays and
// creating a generated slice that spans the whole range.
long loff, moff;
unsigned long lwid, mwid;
bool lrc, mrc;
mrc = reg->sb_to_slice(prefix_indices, lsv, moff, mwid);
if (use_sel == index_component_t::SEL_IDX_UP)
lrc = reg->sb_to_slice(prefix_indices, lsv+wid-1, loff, lwid);
else
lrc = reg->sb_to_slice(prefix_indices, lsv-wid+1, loff, lwid);
if (!mrc || !lrc) {
cerr << get_fileline() << ": error: ";
cerr << "Part-select [" << lsv;
if (index_tail.sel == index_component_t::SEL_IDX_UP) {
cerr << "+:";
} else {
cerr << "-:";
}
cerr << wid << "] exceeds the declared bounds for ";
cerr << reg->name();
if (reg->unpacked_dimensions() > 0) cerr << "[]";
cerr << "." << endl;
des->errors += 1;
return 0;
}
ivl_assert(*this, lwid == mwid);
// We want the last range, which is where we work.
const netrange_t&rng = packed.back();
if (((rng.get_msb() < rng.get_lsb()) &&
use_sel == index_component_t::SEL_IDX_UP) ||
((rng.get_msb() > rng.get_lsb()) &&
use_sel == index_component_t::SEL_IDX_DO)) {
offset = -wid + 1;
if (moff > loff) {
rel_base = loff;
wid = moff + mwid - loff;
} else {
rel_base = moff;
wid = loff + lwid - moff;
}
} else {
long offset = 0;
// We want the last range, which is where we work.
const netrange_t&rng = packed.back();
if (((rng.get_msb() < rng.get_lsb()) &&
use_sel == index_component_t::SEL_IDX_UP) ||
((rng.get_msb() > rng.get_lsb()) &&
use_sel == index_component_t::SEL_IDX_DO)) {
offset = -wid + 1;
}
rel_base = reg->sb_to_idx(prefix_indices,lsv) + offset;
}
delete base;
long rel_base = reg->sb_to_idx(prefix_indices,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));
+90 -42
View File
@@ -32,6 +32,8 @@
# include <iostream>
# include "ivl_assert.h"
using namespace std;
/*
* The concatenation is also OK an an l-value. This method elaborates
* it as a structural l-value. The return values is the *input* net of
@@ -262,49 +264,87 @@ bool PEIdent::eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
}
long midx_val = tmp->value().as_long();
midx = sig->sb_to_idx(prefix_indices, midx_val);
delete tmp_ex;
if (prefix_indices.size()+1 < sig->packed_dims().size()) {
// Here we are selecting one or more sub-arrays.
// Make this work by finding the indexed sub-arrays and
// creating a generated slice that spans the whole range.
long loff, moff;
unsigned long lwid, mwid;
bool mrc, lrc;
mrc = sig->sb_to_slice(prefix_indices, midx_val, moff, mwid);
if (index_tail.sel == index_component_t::SEL_IDX_UP)
lrc = sig->sb_to_slice(prefix_indices, midx_val+wid-1, loff, lwid);
else
lrc = sig->sb_to_slice(prefix_indices, midx_val-wid+1, loff, lwid);
if (!mrc || !lrc) {
cerr << get_fileline() << ": error: ";
cerr << "Part-select [" << midx_val;
if (index_tail.sel == index_component_t::SEL_IDX_UP) {
cerr << "+:";
} else {
cerr << "-:";
}
cerr << wid << "] exceeds the declared bounds for ";
cerr << sig->name();
if (sig->unpacked_dimensions() > 0) cerr << "[]";
cerr << "." << endl;
des->errors += 1;
return 0;
}
ivl_assert(*this, lwid == mwid);
if (index_tail.sel == index_component_t::SEL_IDX_UP)
lidx = sig->sb_to_idx(prefix_indices, midx_val+wid-1);
else
lidx = sig->sb_to_idx(prefix_indices, midx_val-wid+1);
if (midx < lidx) {
long tmpx = midx;
midx = lidx;
lidx = tmpx;
}
/* Warn about an indexed part select that is out of range. */
if (warn_ob_select && (lidx < 0)) {
cerr << get_fileline() << ": warning: " << sig->name();
if (sig->unpacked_dimensions() > 0) cerr << "[]";
cerr << "[" << midx_val;
if (index_tail.sel == index_component_t::SEL_IDX_UP) {
cerr << "+:";
if (moff > loff) {
lidx = loff;
midx = moff + mwid - 1;
} else {
cerr << "-:";
lidx = moff;
midx = loff + lwid - 1;
}
cerr << wid << "] is selecting before vector." << endl;
}
if (warn_ob_select && (midx >= (long)sig->vector_width())) {
cerr << get_fileline() << ": warning: " << sig->name();
if (sig->unpacked_dimensions() > 0) {
cerr << "[]";
}
cerr << "[" << midx_val;
if (index_tail.sel == index_component_t::SEL_IDX_UP) {
cerr << "+:";
} else {
cerr << "-:";
}
cerr << wid << "] is selecting after vector." << endl;
}
} else {
midx = sig->sb_to_idx(prefix_indices, midx_val);
/* This is completely out side the signal so just skip it. */
if (lidx >= (long)sig->vector_width() || midx < 0) {
return false;
if (index_tail.sel == index_component_t::SEL_IDX_UP)
lidx = sig->sb_to_idx(prefix_indices, midx_val+wid-1);
else
lidx = sig->sb_to_idx(prefix_indices, midx_val-wid+1);
if (midx < lidx) {
long tmpx = midx;
midx = lidx;
lidx = tmpx;
}
/* Warn about an indexed part select that is out of range. */
if (warn_ob_select && (lidx < 0)) {
cerr << get_fileline() << ": warning: " << sig->name();
if (sig->unpacked_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->unpacked_dimensions() > 0) {
cerr << "[]";
}
cerr << "[" << midx_val;
if (index_tail.sel == index_component_t::SEL_IDX_UP) {
cerr << "+:";
} else {
cerr << "-:";
}
cerr << wid << "] is selecting after vector." << endl;
}
/* This is completely out side the signal so just skip it. */
if (lidx >= (long)sig->vector_width() || midx < 0) {
return false;
}
}
break;
@@ -338,11 +378,19 @@ bool PEIdent::eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
// range.
long loff, moff;
unsigned long lwid, mwid;
bool lrc;
bool lrc, mrc;
lrc = sig->sb_to_slice(prefix_indices, lsb, loff, lwid);
ivl_assert(*this, lrc);
lrc = sig->sb_to_slice(prefix_indices, msb, moff, mwid);
ivl_assert(*this, lrc);
mrc = sig->sb_to_slice(prefix_indices, msb, moff, mwid);
if (!mrc || !lrc) {
cerr << get_fileline() << ": error: ";
cerr << "Part-select [" << msb << ":" << lsb;
cerr << "] exceeds the declared bounds for ";
cerr << sig->name();
if (sig->unpacked_dimensions() > 0) cerr << "[]";
cerr << "." << endl;
des->errors += 1;
return 0;
}
ivl_assert(*this, lwid == mwid);
if (moff > loff) {
+42 -41
View File
@@ -54,6 +54,7 @@
# include <cassert>
# include "ivl_assert.h"
using namespace std;
void set_scope_timescale(Design*des, NetScope*scope, PScope*pscope)
{
@@ -468,7 +469,7 @@ static void elaborate_scope_class(Design*des, NetScope*scope, PClass*pclass)
netclass_t*use_base_class = 0;
if (base_class) {
use_base_class = scope->find_class(base_class->name);
use_base_class = scope->find_class(des, base_class->name);
if (use_base_class == 0) {
cerr << pclass->get_fileline() << ": error: "
<< "Base class " << base_class->name
@@ -894,6 +895,18 @@ bool PGenerate::generate_scope(Design*des, NetScope*container)
}
}
void PGenerate::check_for_valid_genvar_value_(long value)
{
if (generation_flag < GN_VER2005 && value < 0) {
cerr << get_fileline() << ": warning: A negative value (" << value
<< ") has been assigned to genvar '" << loop_index << "'."
<< endl;
cerr << get_fileline() << ": : This is illegal in "
"Verilog-2001. Use at least -g2005 to remove this warning."
<< endl;
}
}
/*
* This is the elaborate scope method for a generate loop.
*/
@@ -903,8 +916,16 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
// Check that the loop_index variable was declared in a
// genvar statement.
NetScope*cscope = container;
while (cscope && !cscope->find_genvar(loop_index))
while (cscope && !cscope->find_genvar(loop_index)) {
if (cscope->symbol_exists(loop_index)) {
cerr << get_fileline() << ": error: "
<< "generate loop variable '" << loop_index
<< "' is not a genvar in this scope." << endl;
des->errors += 1;
return false;
}
cscope = cscope->parent();
}
if (!cscope) {
cerr << get_fileline() << ": error: genvar is missing for "
"generate \"loop\" variable '" << loop_index << "'."
@@ -915,7 +936,7 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
}
// We're going to need a genvar...
int genvar;
long genvar;
// The initial value for the genvar does not need (nor can it
// use) the genvar itself, so we can evaluate this expression
@@ -930,6 +951,7 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
}
genvar = init->value().as_long();
check_for_valid_genvar_value_(genvar);
delete init_ex;
if (debug_scopes)
@@ -966,7 +988,11 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
// block. Code within this scope thus has access to the
// genvar as a constant.
{
verinum genvar_verinum(genvar);
verinum genvar_verinum;
if (gn_strict_expr_width_flag)
genvar_verinum = verinum(genvar, integer_width);
else
genvar_verinum = verinum(genvar);
genvar_verinum.has_sign(true);
NetEConstParam*gp = new NetEConstParam(scope,
loop_index,
@@ -996,6 +1022,7 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
<< genvar << " to " << step->value().as_long() << endl;
genvar = step->value().as_long();
check_for_valid_genvar_value_(genvar);
container->genvar_tmp_val = genvar;
delete step;
delete test_ex;
@@ -1042,8 +1069,7 @@ bool PGenerate::generate_scope_condit_(Design*des, NetScope*container, bool else
<< " value=" << test->value() << ": Generate scope="
<< use_name << endl;
probe_for_direct_nesting_();
if (direct_nested_) {
if (directly_nested) {
if (debug_scopes)
cerr << get_fileline() << ": debug: Generate condition "
<< (else_flag? "(else)" : "(if)")
@@ -1141,8 +1167,7 @@ bool PGenerate::generate_scope_case_(Design*des, NetScope*container)
// The name of the scope to generate, whatever that item is.
hname_t use_name (item->scope_name);
item->probe_for_direct_nesting_();
if (item->direct_nested_) {
if (item->directly_nested) {
if (debug_scopes)
cerr << get_fileline() << ": debug: Generate case item " << scope_name
<< " detected direct nesting." << endl;
@@ -1355,7 +1380,7 @@ void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const
return;
}
if (msb_ || lsb_) {
if (is_array()) {
// If there are expressions to evaluate in order to know
// the actual number of instances that will be
// instantiated, then we have to delay further scope
@@ -1385,41 +1410,17 @@ void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const
*/
void PGModule::elaborate_scope_mod_instances_(Design*des, Module*mod, NetScope*sc) const
{
NetExpr*mse = msb_ ? elab_and_eval(des, sc, msb_, -1, true) : 0;
NetExpr*lse = lsb_ ? elab_and_eval(des, sc, lsb_, -1, true) : 0;
NetEConst*msb = dynamic_cast<NetEConst*> (mse);
NetEConst*lsb = dynamic_cast<NetEConst*> (lse);
assert( (msb == 0) || (lsb != 0) );
long instance_low = 0;
long instance_high = 0;
long instance_count = 1;
bool instance_array = false;
if (msb) {
instance_array = true;
instance_high = msb->value().as_long();
instance_low = lsb->value().as_long();
if (instance_high > instance_low)
instance_count = instance_high - instance_low + 1;
else
instance_count = instance_low - instance_high + 1;
delete mse;
delete lse;
}
long instance_count = calculate_array_size_(des, sc, instance_high, instance_low);
if (instance_count == 0)
return;
NetScope::scope_vec_t instances (instance_count);
if (debug_scopes) {
cerr << get_fileline() << ": debug: Create " << instance_count
<< " instances of " << get_name()
<< "." << endl;
}
struct attrib_list_t*attrib_list;
unsigned attrib_list_n = 0;
attrib_list = evaluate_attributes(attributes, attrib_list_n, des, sc);
struct attrib_list_t*attrib_list;
unsigned attrib_list_n = 0;
attrib_list = evaluate_attributes(attributes, attrib_list_n, des, sc);
// Run through the module instances, and make scopes out of
// them. Also do parameter overrides that are done on the
@@ -1428,8 +1429,8 @@ void PGModule::elaborate_scope_mod_instances_(Design*des, Module*mod, NetScope*s
hname_t use_name (get_name());
if (instance_array) {
int instance_idx = idx;
if (is_array()) {
int instance_idx;
if (instance_low < instance_high)
instance_idx = instance_low + idx;
else
+5 -5
View File
@@ -198,7 +198,7 @@ static void elaborate_sig_classes(Design*des, NetScope*scope,
{
for (map<perm_string,PClass*>::const_iterator cur = classes.begin()
; cur != classes.end() ; ++ cur) {
netclass_t*use_class = scope->find_class(cur->second->pscope_name());
netclass_t*use_class = scope->find_class(des, cur->second->pscope_name());
use_class->elaborate_sig(des, cur->second);
}
}
@@ -429,7 +429,7 @@ bool PGModule::elaborate_sig_udp_(Design*des, NetScope*scope, PUdp*udp) const
bool PGenerate::elaborate_sig(Design*des, NetScope*container) const
{
if (direct_nested_)
if (directly_nested)
return elaborate_sig_direct_(des, container);
bool flag = true;
@@ -448,7 +448,7 @@ bool PGenerate::elaborate_sig(Design*des, NetScope*container) const
for (generate_it_t cur = generate_schemes.begin()
; cur != generate_schemes.end() ; ++ cur ) {
PGenerate*item = *cur;
if (item->direct_nested_ || !item->scope_list_.empty()) {
if (item->directly_nested || !item->scope_list_.empty()) {
flag &= item->elaborate_sig(des, container);
}
}
@@ -496,12 +496,12 @@ bool PGenerate::elaborate_sig_direct_(Design*des, NetScope*container) const
for (generate_it_t icur = item->generate_schemes.begin()
; icur != item->generate_schemes.end() ; ++ icur ) {
PGenerate*case_item = *icur;
if (case_item->direct_nested_ || !case_item->scope_list_.empty()) {
if (case_item->directly_nested || !case_item->scope_list_.empty()) {
flag &= case_item->elaborate_sig(des, container);
}
}
} else {
if (item->direct_nested_ || !item->scope_list_.empty()) {
if (item->directly_nested || !item->scope_list_.empty()) {
// Found the item, and it is direct nested.
flag &= item->elaborate_sig(des, container);
}
+189 -170
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998-2020 Stephen Williams (steve@icarus.com)
* Copyright (c) 1998-2021 Stephen Williams (steve@icarus.com)
* Copyright CERN 2013 / Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
@@ -51,6 +51,7 @@
# include "compiler.h"
# include "ivl_assert.h"
using namespace std;
// Implemented in elab_scope.cc
extern void set_scope_timescale(Design*des, NetScope*scope, PScope*pscope);
@@ -61,6 +62,44 @@ void PGate::elaborate(Design*, NetScope*) const
typeid(*this).name() << endl;
}
unsigned PGate::calculate_array_size_(Design*des, NetScope*scope,
long&high, long&low) const
{
if (ranges_ && ranges_->size() > 1) {
if (gn_system_verilog()) {
cerr << get_fileline() << ": sorry: Multi-dimensional"
<< " arrays of instances are not yet supported." << endl;
} else {
cerr << get_fileline() << ": error: Multi-dimensional"
<< " arrays of instances require SystemVerilog." << endl;
}
des->errors += 1;
return 0;
}
unsigned size = 1;
high = 0;
low = 0;
if (ranges_) {
if (!evaluate_range(des, scope, this, ranges_->front(), high, low))
return 0;
if (high > low)
size = high - low + 1;
else
size = low - high + 1;
if (debug_elaborate) {
cerr << get_fileline() << ": debug: PGate: Make array "
<< "[" << high << ":" << low << "]" << " of "
<< size << " instances for " << get_name() << endl;
}
}
return size;
}
/*
* Elaborate the continuous assign. (This is *not* the procedural
* assign.) Elaborate the lvalue and rvalue, and do the assignment.
@@ -110,6 +149,18 @@ void PGAssign::elaborate(Design*des, NetScope*scope) const
return;
}
if (lval->enumeration()) {
if (! rval_expr->enumeration()) {
cerr << get_fileline() << ": error: "
"This assignment requires an explicit cast." << endl;
des->errors += 1;
} else if (! lval->enumeration()->matches(rval_expr->enumeration())) {
cerr << get_fileline() << ": error: "
"Enumeration type mismatch in assignment." << endl;
des->errors += 1;
}
}
NetNet*rval = rval_expr->synthesize(des, scope, rval_expr);
if (rval == 0) {
@@ -220,61 +271,6 @@ void PGAssign::elaborate_unpacked_array_(Design*des, NetScope*scope, NetNet*lval
assign_unpacked_with_bufz(des, scope, this, lval, rval_net);
}
unsigned PGBuiltin::calculate_array_count_(Design*des, NetScope*scope,
long&high, long&low) const
{
unsigned count = 1;
high = 0;
low = 0;
/* If the Verilog source has a range specification for the
gates, then I am expected to make more than one
gate. Figure out how many are desired. */
if (msb_) {
NetExpr*msb_exp = elab_and_eval(des, scope, msb_, -1, true);
NetExpr*lsb_exp = elab_and_eval(des, scope, lsb_, -1, true);
NetEConst*msb_con = dynamic_cast<NetEConst*>(msb_exp);
NetEConst*lsb_con = dynamic_cast<NetEConst*>(lsb_exp);
if (msb_con == 0) {
cerr << get_fileline() << ": error: Unable to evaluate "
"expression " << *msb_ << endl;
des->errors += 1;
return 0;
}
if (lsb_con == 0) {
cerr << get_fileline() << ": error: Unable to evaluate "
"expression " << *lsb_ << endl;
des->errors += 1;
return 0;
}
verinum msb = msb_con->value();
verinum lsb = lsb_con->value();
delete msb_exp;
delete lsb_exp;
if (msb.as_long() > lsb.as_long())
count = msb.as_long() - lsb.as_long() + 1;
else
count = lsb.as_long() - msb.as_long() + 1;
low = lsb.as_long();
high = msb.as_long();
if (debug_elaborate) {
cerr << get_fileline() << ": debug: PGBuiltin: Make array "
<< "[" << high << ":" << low << "]" << " of "
<< count << " gates for " << get_name() << endl;
}
}
return count;
}
void PGBuiltin::calculate_gate_and_lval_count_(unsigned&gate_count,
unsigned&lval_count) const
{
@@ -710,7 +706,7 @@ void PGBuiltin::elaborate(Design*des, NetScope*scope) const
the count is 1, and high==low==0. */
long low=0, high=0;
unsigned array_count = calculate_array_count_(des, scope, high, low);
unsigned array_count = calculate_array_size_(des, scope, high, low);
if (array_count == 0) return;
unsigned gate_count = 0, lval_count = 0;
@@ -841,10 +837,10 @@ void PGBuiltin::elaborate(Design*des, NetScope*scope) const
// 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.
NetExpr*tmp = elab_and_eval(des, scope, ex, msb_ ? -1 : 1);
NetExpr*tmp = elab_and_eval(des, scope, ex, is_array() ? -1 : 1);
if (tmp == 0)
continue;
if (msb_ == 0 && tmp->expr_width() != 1)
if (!is_array() && tmp->expr_width() != 1)
tmp = new NetESelect(tmp, make_const_0(1), 1,
IVL_SEL_IDX_UP);
sig = tmp->synthesize(des, scope, tmp);
@@ -1188,7 +1184,7 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
// Handle wildcard named port
if (pins_[idx].name[0] == '*') {
for (unsigned j = 0 ; j < nexp ; j += 1) {
if ((!pins[j]) && (!pins_is_explicitly_not_connected[j])) {
if (rmod->ports[j] && !pins[j] && !pins_is_explicitly_not_connected[j]) {
pins_fromwc[j] = true;
NetNet* net = 0;
const NetExpr*par = 0;
@@ -1476,17 +1472,23 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
continue;
}
/* Input to module. elaborate the expression to
the desired width. If this in an instance
array, then let the net determine its own
width. We use that, then, to decide how to hook
it up.
/* Input to module. Here we elaborate the source expression
using its self-determined width. This allows us to check
for and warn about port width mismatches. But in the
special case that the source expression is a SV unbased
unsized literal, we need to force the expression width
to match the destination.
NOTE that this also handles the case that the
port is actually empty on the inside. We assume
in that case that the port is input. */
NetExpr*tmp_expr = elab_and_eval(des, scope, pins[idx], -1);
int context_width = -1;
if (PENumber*literal = dynamic_cast<PENumber*>(pins[idx])) {
if (literal->value().is_single())
context_width = prts_vector_width;
}
NetExpr*tmp_expr = elab_and_eval(des, scope, pins[idx], context_width);
if (tmp_expr == 0) {
cerr << pins[idx]->get_fileline()
<< ": error: Failed to elaborate port expression."
@@ -1956,62 +1958,6 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
}
unsigned PGModule::calculate_instance_count_(Design*des, NetScope*scope,
long&high, long&low,
perm_string name) const
{
unsigned count = 1;
high = 0;
low = 0;
/* If the Verilog source has a range specification for the UDP, then
* I am expected to make more than one gate. Figure out how many are
* desired. */
if (msb_) {
NetExpr*msb_exp = elab_and_eval(des, scope, msb_, -1, true);
NetExpr*lsb_exp = elab_and_eval(des, scope, lsb_, -1, true);
NetEConst*msb_con = dynamic_cast<NetEConst*>(msb_exp);
NetEConst*lsb_con = dynamic_cast<NetEConst*>(lsb_exp);
if (msb_con == 0) {
cerr << get_fileline() << ": error: Unable to evaluate "
"expression " << *msb_ << endl;
des->errors += 1;
return 0;
}
if (lsb_con == 0) {
cerr << get_fileline() << ": error: Unable to evaluate "
"expression " << *lsb_ << endl;
des->errors += 1;
return 0;
}
verinum msb = msb_con->value();
verinum lsb = lsb_con->value();
delete msb_exp;
delete lsb_exp;
if (msb.as_long() > lsb.as_long())
count = msb.as_long() - lsb.as_long() + 1;
else
count = lsb.as_long() - msb.as_long() + 1;
low = lsb.as_long();
high = msb.as_long();
if (debug_elaborate) {
cerr << get_fileline() << ": debug: PGModule: Make range "
<< "[" << high << ":" << low << "]" << " of "
<< count << " UDPs for " << name << endl;
}
}
return count;
}
/*
* From a UDP definition in the source, make a NetUDP
* object. Elaborate the pin expressions as netlists, then connect
@@ -2043,8 +1989,7 @@ void PGModule::elaborate_udp_(Design*des, PUdp*udp, NetScope*scope) const
}
long low = 0, high = 0;
unsigned inst_count = calculate_instance_count_(des, scope, high, low,
my_name);
unsigned inst_count = calculate_array_size_(des, scope, high, low);
if (inst_count == 0) return;
if (inst_count != 1) {
@@ -3524,8 +3469,10 @@ NetProc* PCallTask::elaborate_usr(Design*des, NetScope*scope) const
// For SystemVerilog this may be a few other things.
if (gn_system_verilog()) {
NetProc *tmp;
// This could be a method attached to a signal?
tmp = elaborate_method_(des, scope);
// This could be a method attached to a signal
// or defined in this object?
bool try_implicit_this = scope->get_class_scope() && path_.size() == 1;
tmp = elaborate_method_(des, scope, try_implicit_this);
if (tmp) return tmp;
// Or it could be a function call ignoring the return?
tmp = elaborate_function_(des, scope);
@@ -3567,6 +3514,9 @@ NetProc* PCallTask::elaborate_usr(Design*des, NetScope*scope) const
/* Handle non-automatic tasks with no parameters specially. There is
no need to make a sequential block to hold the generated code. */
if ((parm_count == 0) && !task->is_auto()) {
// Check if a task call is allowed in this context.
test_task_calls_ok_(des, scope);
NetUTask*cur = new NetUTask(task);
cur->set_line(*this);
return cur;
@@ -3701,6 +3651,38 @@ NetProc* PCallTask::elaborate_queue_method_(Design*des, NetScope*scope,
return sys;
}
/*
* This is used for array/queue function methods called as tasks.
*/
NetProc* PCallTask::elaborate_method_func_(NetScope*scope,
NetNet*net,
ivl_variable_type_t type,
unsigned width,
bool signed_flag,
perm_string method_name,
const char*sys_task_name) const
{
cerr << get_fileline() << ": warning: method function '"
<< method_name << "' is being called as a task." << endl;
// Generate the function.
NetESFunc*sys_expr = new NetESFunc(sys_task_name, type, width, 1);
sys_expr->set_line(*this);
NetESignal*arg = new NetESignal(net);
arg->set_line(*net);
sys_expr->parm(0, arg);
// Create a L-value that matches the function return type.
NetNet*tmp;
netvector_t*tmp_vec = new netvector_t(type, width-1, 0, signed_flag);
tmp = new NetNet(scope, scope->local_symbol(), NetNet::REG, tmp_vec);
tmp->set_line(*this);
NetAssign_*lv = new NetAssign_(tmp);
// Generate an assign to the fake L-value.
NetAssign*cur = new NetAssign(lv, sys_expr);
cur->set_line(*this);
return cur;
}
NetProc* PCallTask::elaborate_method_(Design*des, NetScope*scope,
bool add_this_flag) const
{
@@ -3732,13 +3714,21 @@ NetProc* PCallTask::elaborate_method_(Design*des, NetScope*scope,
if (net == 0)
return 0;
// Is this a delete method for dynamic arrays?
if (net->darray_type() && method_name=="delete") {
return elaborate_sys_task_method_(des, scope, net, method_name,
"$ivl_darray_method$delete");
// Is this a delete method for dynamic arrays or queues?
if (net->darray_type()) {
if (method_name=="delete")
return elaborate_sys_task_method_(des, scope, net, method_name,
"$ivl_darray_method$delete");
else if (method_name=="size")
// This returns an int. It could be removed, but keep for now.
return elaborate_method_func_(scope, net,
IVL_VT_BOOL, 32,
true, method_name,
"$size");
}
if (net->queue_type()) {
const netdarray_t*use_darray = net->darray_type();
if (method_name == "push_back")
return elaborate_queue_method_(des, scope, net, method_name,
"$ivl_queue_method$push_back");
@@ -3748,6 +3738,18 @@ NetProc* PCallTask::elaborate_method_(Design*des, NetScope*scope,
else if (method_name == "insert")
return elaborate_queue_method_(des, scope, net, method_name,
"$ivl_queue_method$insert");
else if (method_name == "pop_front")
return elaborate_method_func_(scope, net,
use_darray->element_base_type(),
use_darray->element_width(),
false, method_name,
"$ivl_queue_method$pop_front");
else if (method_name == "pop_back")
return elaborate_method_func_(scope, net,
use_darray->element_base_type(),
use_darray->element_width(),
false, method_name,
"$ivl_queue_method$pop_back");
}
if (const netclass_t*class_type = net->class_type()) {
@@ -3779,7 +3781,7 @@ NetProc* PCallTask::elaborate_method_(Design*des, NetScope*scope,
* If during elaboration we determine (for sure) that we are calling a
* task (and not just a void function) then this method tests if that
* task call is allowed in the current context. If so, return true. If
* not, print and error message and return false;
* not, print an error message and return false;
*/
bool PCallTask::test_task_calls_ok_(Design*des, NetScope*scope) const
{
@@ -3835,7 +3837,14 @@ NetProc* PCallTask::elaborate_void_function_(Design*des, NetScope*scope,
<< endl;
}
ivl_assert(*this, dscope->elab_stage() >= 3);
// If we haven't already elaborated the function, do so now.
// This allows elaborate_build_call_ to elide the function call
// if the function body is empty.
if (dscope->elab_stage() < 3) {
const PFunction*pfunc = dscope->func_pform();
ivl_assert(*this, pfunc);
pfunc->elaborate(des, dscope);
}
return elaborate_build_call_(des, scope, dscope, 0);
}
@@ -3884,8 +3893,13 @@ NetProc* PCallTask::elaborate_build_call_(Design*des, NetScope*scope,
task, all the assignments, etc. Just return a no-op. */
if (const NetBlock*tp = dynamic_cast<const NetBlock*>(def->proc())) {
if (tp->proc_first() == 0)
if (tp->proc_first() == 0) {
if (debug_elaborate) {
cerr << get_fileline() << ": PCallTask::elaborate_build_call_: "
<< "Eliding call to empty task " << task->basename() << endl;
}
return block;
}
}
/* If this is an automatic task, generate a statement to
@@ -5261,14 +5275,18 @@ void PFunction::elaborate(Design*des, NetScope*scope) const
}
assert(def);
ivl_assert(*this, statement_);
NetProc*st = statement_->elaborate(des, scope);
if (st == 0) {
cerr << statement_->get_fileline() << ": error: Unable to elaborate "
"statement in function " << scope->basename() << "." << endl;
scope->is_const_func(true); // error recovery
des->errors += 1;
return;
NetProc*st;
if (statement_ == 0) {
st = new NetBlock(NetBlock::SEQU, 0);
} else {
st = statement_->elaborate(des, scope);
if (st == 0) {
cerr << statement_->get_fileline() << ": error: Unable to elaborate "
"statement in function " << scope->basename() << "." << endl;
scope->is_const_func(true); // error recovery
des->errors += 1;
return;
}
}
// Handle any variable initialization statements in this scope.
@@ -5900,7 +5918,7 @@ static void elaborate_classes(Design*des, NetScope*scope,
{
for (map<perm_string,PClass*>::const_iterator cur = classes.begin()
; cur != classes.end() ; ++ cur) {
netclass_t*use_class = scope->find_class(cur->second->pscope_name());
netclass_t*use_class = scope->find_class(des, cur->second->pscope_name());
use_class->elaborate(des, cur->second);
if (use_class->test_for_missing_initializers()) {
@@ -6041,7 +6059,7 @@ void netclass_t::elaborate(Design*des, PClass*pclass)
bool PGenerate::elaborate(Design*des, NetScope*container) const
{
if (direct_nested_)
if (directly_nested)
return elaborate_direct_(des, container);
bool flag = true;
@@ -6066,7 +6084,7 @@ bool PGenerate::elaborate(Design*des, NetScope*container) const
for (generate_it_t cur = generate_schemes.begin()
; cur != generate_schemes.end() ; ++ cur ) {
PGenerate*item = *cur;
if (item->direct_nested_ || !item->scope_list_.empty()) {
if (item->directly_nested || !item->scope_list_.empty()) {
flag &= item->elaborate(des, container);
}
}
@@ -6128,7 +6146,7 @@ bool PGenerate::elaborate_direct_(Design*des, NetScope*container) const
cerr << get_fileline() << ": PGenerate::elaborate_direct_: "
<< "item->scope_name=" << item->scope_name
<< ", item->scheme_type=" << item->scheme_type
<< ", item->direct_nested_=" << item->direct_nested_
<< ", item->directly_nested=" << item->directly_nested
<< ", item->scope_list_.size()=" << item->scope_list_.size()
<< "." << endl;
}
@@ -6141,12 +6159,12 @@ bool PGenerate::elaborate_direct_(Design*des, NetScope*container) const
for (generate_it_t icur = item->generate_schemes.begin()
; icur != item->generate_schemes.end() ; ++ icur ) {
PGenerate*case_item = *icur;
if (case_item->direct_nested_ || !case_item->scope_list_.empty()) {
if (case_item->directly_nested || !case_item->scope_list_.empty()) {
flag &= case_item->elaborate(des, container);
}
}
} else {
if (item->direct_nested_ || !item->scope_list_.empty()) {
if (item->directly_nested || !item->scope_list_.empty()) {
// Found the item, and it is direct nested.
flag &= item->elaborate(des, container);
}
@@ -6560,7 +6578,7 @@ static void check_event_probe_width(const LineInfo *info, const NetEvProbe *prb)
assert(prb->pin(0).is_linked());
if (prb->edge() == NetEvProbe::ANYEDGE) return;
if (prb->pin(0).nexus()->vector_width() > 1) {
cerr << info->get_fileline() << " Warning: Synthesis wants "
cerr << info->get_fileline() << " warning: Synthesis wants "
"the sensitivity list expressions for '";
switch (prb->edge()) {
case NetEvProbe::POSEDGE:
@@ -6590,7 +6608,7 @@ static void check_ff_sensitivity(const NetProc* statement)
const NetEvProbe *prb = evt->probe(cprb);
check_event_probe_width(evwt, prb);
if (prb->edge() == NetEvProbe::ANYEDGE) {
cerr << evwt->get_fileline() << " Warning: Synthesis "
cerr << evwt->get_fileline() << " warning: Synthesis "
"requires the sensitivity list of an "
"always_ff process to only be edge "
"sensitive. ";
@@ -6657,18 +6675,18 @@ static void check_timescales()
if (some_explicit && some_implicit)
break;
}
map<perm_string,PPackage*>::iterator pkg;
vector<PPackage*>::iterator pkg;
if (gn_system_verilog() && !(some_explicit && some_implicit)) {
for (pkg = pform_packages.begin(); pkg != pform_packages.end(); ++pkg) {
const PPackage*pp = (*pkg).second;
const PPackage*pp = *pkg;
check_timescales(some_explicit, some_implicit, pp);
if (some_explicit && some_implicit)
break;
}
}
if (gn_system_verilog() && !(some_explicit && some_implicit)) {
for (unsigned idx = 0; idx < pform_units.size(); idx += 1) {
const PPackage*pp = pform_units[idx];
for (pkg = pform_units.begin(); pkg != pform_units.end(); ++pkg) {
const PPackage*pp = *pkg;
// We don't need a timescale if the compilation unit
// contains no items outside a design element.
if (pp->parameters.empty() &&
@@ -6719,15 +6737,15 @@ static void check_timescales()
return;
for (pkg = pform_packages.begin(); pkg != pform_packages.end(); ++pkg) {
PPackage*pp = (*pkg).second;
PPackage*pp = *pkg;
if (pp->has_explicit_timescale())
continue;
cerr << " : -- package " << (*pkg).first
cerr << " : -- package " << pp->pscope_name()
<< " declared here: " << pp->get_fileline() << endl;
}
for (unsigned idx = 0; idx < pform_units.size(); idx += 1) {
PPackage*pp = pform_units[idx];
for (pkg = pform_units.begin(); pkg != pform_units.end(); ++pkg) {
PPackage*pp = *pkg;
if (pp->has_explicit_timescale())
continue;
@@ -6783,8 +6801,9 @@ Design* elaborate(list<perm_string>roots)
// Elaborate the compilation unit scopes. From here on, these are
// treated as an additional set of packages.
if (gn_system_verilog()) {
for (i = 0; i < pform_units.size(); i += 1) {
PPackage*unit = pform_units[i];
for (vector<PPackage*>::iterator pkg = pform_units.begin()
; pkg != pform_units.end() ; ++pkg) {
PPackage*unit = *pkg;
NetScope*scope = des->make_package_scope(unit->pscope_name(), 0, true);
scope->set_line(unit);
scope->add_imports(&unit->explicit_imports);
@@ -6795,6 +6814,7 @@ Design* elaborate(list<perm_string>roots)
pack_elems[i].pack = unit;
pack_elems[i].scope = scope;
i += 1;
unit_scopes[unit] = scope;
}
@@ -6805,20 +6825,19 @@ Design* elaborate(list<perm_string>roots)
// in SystemVerilog, packages are not allowed to refer to
// the compilation unit scope, but the VHDL preprocessor
// assumes they can.
for (map<perm_string,PPackage*>::iterator pac = pform_packages.begin()
; pac != pform_packages.end() ; ++ pac) {
for (vector<PPackage*>::iterator pkg = pform_packages.begin()
; pkg != pform_packages.end() ; ++pkg) {
PPackage*pack = *pkg;
NetScope*unit_scope = unit_scopes[pack->parent_scope()];
NetScope*scope = des->make_package_scope(pack->pscope_name(), unit_scope, false);
scope->set_line(pack);
scope->add_imports(&pack->explicit_imports);
set_scope_timescale(des, scope, pack);
ivl_assert(*pac->second, pac->first == pac->second->pscope_name());
NetScope*unit_scope = unit_scopes[pac->second->parent_scope()];
NetScope*scope = des->make_package_scope(pac->first, unit_scope, false);
scope->set_line(pac->second);
scope->add_imports(&pac->second->explicit_imports);
set_scope_timescale(des, scope, pac->second);
elaborator_work_item_t*es = new elaborate_package_t(des, scope, pac->second);
elaborator_work_item_t*es = new elaborate_package_t(des, scope, pack);
des->elaboration_work_list.push_back(es);
pack_elems[i].pack = pac->second;
pack_elems[i].pack = pack;
pack_elems[i].scope = scope;
i += 1;
}
+3 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2008-2012 Stephen Williams (steve@icarus.com)
* Copyright (c) 2008-2021 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -26,6 +26,8 @@
# include <typeinfo>
using namespace std;
NetProc* AContrib::elaborate(Design*des, NetScope*scope) const
{
NetExpr*lval = elab_and_eval(des, scope, lval_, -1);
+2
View File
@@ -33,6 +33,8 @@
# include <cassert>
# include <cstring>
using namespace std;
bool NetNode::emit_node(struct target_t*) const
{
cerr << "EMIT: Gate type? " << typeid(*this).name() << endl;
+3 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998-2014 Stephen Williams (steve@icarus.com)
* Copyright (c) 1998-2021 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -27,6 +27,8 @@
# include "netmisc.h"
# include "compiler.h"
using namespace std;
verinum* PExpr::eval_const(Design*, NetScope*) const
{
return 0;
+3 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2010 Stephen Williams (steve@icarus.com)
* Copyright (c) 2002-2021 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -24,6 +24,8 @@
# include <iostream>
# include <cassert>
using namespace std;
/*
* The evaluate_attributes function evaluates the attribute
* expressions from the map, and returns a table in a form suitable
+32 -7
View File
@@ -29,6 +29,8 @@
# include "ivl_assert.h"
# include "netmisc.h"
using namespace std;
NetExpr* NetExpr::eval_tree()
{
return 0;
@@ -404,7 +406,6 @@ NetEConst* NetEBComp::eval_leeq_(const NetExpr*le, const NetExpr*re) const
{
if (le->expr_type() == IVL_VT_REAL || re->expr_type() == IVL_VT_REAL)
return eval_leeq_real_(le, re, true);
// assert(expr_type() == IVL_VT_LOGIC);
const NetEConst*r = dynamic_cast<const NetEConst*>(re);
if (r == 0) return 0;
@@ -416,12 +417,6 @@ NetEConst* NetEBComp::eval_leeq_(const NetExpr*le, const NetExpr*re) const
return res;
}
if (le->expr_width() == 0) {
cerr << get_fileline() << ": internal error: Something wrong "
<< "with the left side width of <= ?" << endl;
cerr << get_fileline() << ": : " << *this << endl;
}
if (NetEConst*tmp = must_be_leeq_(le, rv, true)) {
return tmp;
}
@@ -816,6 +811,36 @@ NetEConst* NetEBLogic::eval_arguments_(const NetExpr*l, const NetExpr*r) const
const NetEConst*lc = dynamic_cast<const NetEConst*>(l);
const NetEConst*rc = dynamic_cast<const NetEConst*>(r);
// If the left side is constant and the right side is short circuited
// replace the expression with a constant
if (rc == 0 && lc != 0) {
verinum v = lc->value();
verinum::V res = verinum::Vx;
switch (op_) {
case 'a': // Logical AND (&&)
if (v.is_zero())
res = verinum::V0;
break;
case 'o': // Logical OR (||)
if (! v.is_zero() && v.is_defined())
res = verinum::V1;
break;
case 'q': // Logical implication (->)
if (v.is_zero())
res = verinum::V1;
break;
default:
break;
}
if (res != verinum::Vx) {
NetEConst*tmp = new NetEConst(verinum(res, 1));
ivl_assert(*this, tmp);
eval_debug(this, tmp, false);
return tmp;
}
}
if (lc == 0 || rc == 0) return 0;
verinum::V lv = verinum::V0;
+2 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2016 Martin Whitaker (icarus@martin-whitaker.me.uk)
* Copyright (c) 2016-2021 Martin Whitaker (icarus@martin-whitaker.me.uk)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -26,6 +26,7 @@
# include "compiler.h"
# include "ivl_assert.h"
using namespace std;
/*
* The exposenodes functor is primarily provided for use by the vlog95
+2
View File
@@ -28,6 +28,8 @@
# include "netmisc.h"
# include "ivl_assert.h"
using namespace std;
static NetNet* convert_to_real_const(Design*des, NetScope*scope, NetEConst*expr)
{
verireal vrl(expr->value().as_double());
+4 -4
View File
@@ -1,7 +1,7 @@
#ifndef IVL_ivl_assert_H
#define IVL_ivl_assert_H
/*
* Copyright (c) 2007-2014 Stephen Williams (steve@icarus.com)
* Copyright (c) 2007-2021 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -24,9 +24,9 @@
#define ivl_assert(tok, expression) \
do { \
if (! (expression)) { \
cerr << (tok).get_fileline() << ": assert: " \
<< __FILE__ << ":" << __LINE__ \
<< ": failed assertion " << #expression << endl; \
std::cerr << (tok).get_fileline() << ": assert: " \
<< __FILE__ << ":" << __LINE__ \
<< ": failed assertion " << #expression << std::endl; \
abort(); \
} \
} while (0)
+47 -16
View File
@@ -1,7 +1,7 @@
%option prefix="yy"
%{
/*
* Copyright (c) 1999-2020 Stephen Williams ([email protected])
* Copyright (c) 1999-2021 Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -50,7 +50,7 @@ static void do_expand(int use_args);
static const char* do_magic(const char*name);
static const char* macro_name(void);
static void include_filename(void);
static void include_filename(int macro_str);
static void do_include(void);
static int load_next_input(void);
@@ -154,9 +154,9 @@ static void ifdef_leave(void)
result = (rc == 0) ? YY_NULL : rc; \
} else { \
/* We are expanding a macro. Handle the SV `` delimiter. \
If the delimiter terminates a compiler directive, leave \
If the delimiter terminates a defined macro usage, leave \
it in place, otherwise remove it now. */ \
if (yytext[0] != '`') { \
if (!(yytext[0] == '`' && is_defined(yytext+1))) { \
while ((istack->str[0] == '`') && \
(istack->str[1] == '`')) { \
istack->str += 2; \
@@ -186,9 +186,11 @@ static int ma_parenthesis_level = 0;
%x PPINCLUDE
%x DEF_NAME
%x DEF_ESC
%x DEF_ARG
%x DEF_SEP
%x DEF_TXT
%x MN_ESC
%x MA_START
%x MA_ADD
%x CCOMMENT
@@ -286,7 +288,8 @@ keywords (include|define|undef|ifdef|ifndef|else|elseif|endif)
if (macro_needs_args(yytext+1)) yy_push_state(MA_START); else do_expand(0);
}
<PPINCLUDE>\"[^\"]*\" { include_filename(); }
<PPINCLUDE>\"[^\"]*\" { include_filename(0); } /* A normal (") string */
<PPINCLUDE>`\"[^\"]*`\" { include_filename(1); } /* A macro (`") string */
<PPINCLUDE>[ \t\b\f] { ; }
@@ -338,6 +341,11 @@ keywords (include|define|undef|ifdef|ifndef|else|elseif|endif)
<DEF_NAME>[a-zA-Z_][a-zA-Z0-9_$]*"("{W}? { BEGIN(DEF_ARG); def_start(); }
<DEF_NAME>[a-zA-Z_][a-zA-Z0-9_$]*{W}? { BEGIN(DEF_TXT); def_start(); }
<DEF_NAME>\\ { BEGIN(DEF_ESC); }
<DEF_ESC>[^ \t\b\f\n\r]+{W}"("{W}? { BEGIN(DEF_ARG); def_start(); }
<DEF_ESC>[^ \t\b\f\n\r]+{W} { BEGIN(DEF_TXT); def_start(); }
/* define arg: <name> = <text> */
<DEF_ARG>[a-zA-Z_][a-zA-Z0-9_$]*{W}*"="[^,\)]*{W}? { BEGIN(DEF_SEP); def_add_arg(); }
/* define arg: <name> */
@@ -352,7 +360,7 @@ keywords (include|define|undef|ifdef|ifndef|else|elseif|endif)
<DEF_ARG,DEF_SEP>(\n|"\r\n"|"\n\r"|\r){W}? { istack->lineno += 1; fputc('\n', yyout); }
<DEF_NAME,DEF_ARG,DEF_SEP>. {
<DEF_NAME,DEF_ESC,DEF_ARG,DEF_SEP>. {
emit_pathline(istack);
fprintf(stderr, "error: malformed `define directive.\n");
error_count += 1;
@@ -535,6 +543,24 @@ keywords (include|define|undef|ifdef|ifndef|else|elseif|endif)
do_expand(0);
}
`\\ { yy_push_state(MN_ESC); }
<MN_ESC>[^ \t\b\f\n\r]+ {
yy_pop_state();
if (macro_needs_args(yytext))
yy_push_state(MA_START);
else
do_expand(0);
}
<MN_ESC>. {
yy_pop_state();
unput(yytext[0]);
emit_pathline(istack);
fprintf(stderr, "error: malformed macro name.\n");
error_count += 1;
}
/* Stringified version of macro expansion. This is an Icarus extension.
When expanding macro text, the SV usage of `` takes precedence. */
``[a-zA-Z_][a-zA-Z0-9_$]* {
@@ -825,8 +851,13 @@ static void def_add_arg(void)
/* This can happen because we are also processing "argv[0]", the
macro name, as a pseudo-argument. The lexor will match that
as name(, so chop off the ( here. */
if (yytext[length - 1] == '(') length--;
as name(, so chop off the ( here. If we have an escaped name,
we also need to strip off the white space that terminates the
name. */
if (yytext[length - 1] == '(') {
length--;
while (isspace((int)yytext[length - 1])) length--;
}
yytext[length] = 0;
@@ -1052,15 +1083,15 @@ static void do_define(void)
define_continue_flag = 0;
/* Look for comments in the definition, and remove them. The
* "//" style comments go to the end of the line and terminate
* the definition, but the multi-line comments are simply cut
* out, and the define continues.
*/
/* Look for comments in the definition, and remove them. */
cp = strchr(yytext, '/');
while (cp && *cp) {
if (cp[1] == '/') {
if (cp[strlen(cp) - 1] == '\\') {
define_continue_flag = 1;
*cp++ = '\\';
}
*cp = 0;
break;
}
@@ -1657,7 +1688,7 @@ static void output_init(void)
}
}
static void include_filename(void)
static void include_filename(int macro_str)
{
if(standby) {
emit_pathline(istack);
@@ -1667,8 +1698,8 @@ static void include_filename(void)
}
standby = malloc(sizeof(struct include_stack_t));
standby->path = strdup(yytext+1);
standby->path[strlen(standby->path)-1] = 0;
standby->path = strdup(yytext+1+macro_str);
standby->path[strlen(standby->path)-1-macro_str] = 0;
standby->lineno = 0;
standby->comment = NULL;
}
+5
View File
@@ -0,0 +1,5 @@
# This test is sensitive to the number of bytes in the text file.
ivltests/pr1819452.txt text eol=lf
# MSY2 expected results require LF line endings.
regression_report-msys2.txt text eol=lf
+33
View File
@@ -0,0 +1,33 @@
# Lines that start with '#' are comments.
#
# This file is for the development branch of Icarus Verilog.
#
# The following files will be ignored by git.
# The log and work directories
ivl_vhdl_work/
log/
work/
vpi_log/
vhdl/
# The normal regression output files.
regression_report.txt
vhdl_regression_report.txt
# These should be cleaned up, but ignore them as well.
*~
*.o
*.vpi
*.tmp
src/vcddiff
vsim
vlog95.v
tmp_blif.blif
tmp_blif.v
tmp_blif.vvp
# Some tests do not work out of the work directory, so
# ignore these files that they leave in the home directory.
dump.vcd
+339
View File
@@ -0,0 +1,339 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
Appendix: How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) 19yy <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) 19yy name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.
+120
View File
@@ -0,0 +1,120 @@
####################
#
# Main test script
#
####################
There are a group of tests that are meant to exercise the compiler
and the run time. To run them just type:
./regress
or
perl vvp_reg.pl
or if perl is located in /usr/bin
./vvp_reg.pl
The output from these tests are displayed on the screen
and are also placed in the regression_report.txt file.
The expected output for the current development release
is located in the regression_report-devel.txt file. The
expected output for stable (released) versions can be
found in files named regression_report-v<version>.txt.
The results from individual tests can be found in the
log directory and gold files, when needed, are in the
gold directory. The source files can be found in the
ivltests and contrib directories. The list of tests
and how they are run are in the regress-*.list files.
To check a specific suffixed version of Icarus Verilog
use the --suffix=<suffix> flag to tell the script which
version to run e.g.(--suffix=-10 will test iverilog-10,
etc.). You can also run the test with valgrind (very very
slow) by giving the script the --with-valgrind flag.
####################
#
# VPI test script
#
####################
To test the VPI interface type:
perl vpi_reg.pl
or if perl is located in /usr/bin
./vpi_reg.pl
All these tests should pass for V11.devel. There are
some expected failures for V10, which are flagged as
Not Implemented
The individual test results are found in the vpi_log
directory and the gold files are in the vpi_gold
directory. The source files are in the vpi directory.
The vpi_regress.list file has the tests to perform.
This script also takes the --suffix=<suffix> and the
--with-valgrind flags described above.
####################
#
# VHDL test script
#
####################
** Note this is no longer maintained **
This test script require that ghdl be installed in your
path and is used to test the Verilog to VHDL translation.
perl vhdl_reg.pl
or if perl is located in /usr/bin
./vhdl_reg.pl
The expected output for V0.10.devel and V0.9 is located
in the vhdl_regression_report-devel.txt file. V0.8 does
not support converting Verilog to VHDL.
This script also takes the --suffix=<suffix> and the
--with-valgrind flags described above.
####################
#
# BLIF test script
#
####################
This test script require that abc be installed in your
path and is used to test the Verilog to VHDL translation.
python blif_reg.py
There is no expected output as of yet so to check for
regressions simply run with and without your patches.
####################
#
# Windows (MinGW) test issues
#
####################
When running under Windows using a MinGW build in a MSYS2
shell, the expected output from vvp_reg.pl can be found in
regression_report-msys2.txt. The MinGW/MSYS2 specific test
exceptions can be found in regress-msys2.list. Exceptions
for the VPI tests can be found in the vpi_regress.list file.
With Windows 10 and MSYS2, there are now very few differences
between the Windows and Linux builds.
+21
View File
@@ -0,0 +1,21 @@
blif01a
blif01b
blif01c
blif01d
blif01e
blif01f
blif01g
blif01h
blif01i
blif02a
blif02b
blif02c
blif02d
blif02e
blif02f
blif02g
blif02h
blif02i
blif02j
blif02k
blif_shift
+66
View File
@@ -0,0 +1,66 @@
/*
* Generate a combinational adder of any width. The width parameter can
* be any integer value >0. The A and B inputs have WID bits, and the Q
* output has WID+1 bits to include the overflow.
*/
module addN
#(parameter WID = 4)
(input wire [WID-1:0] A,
input wire [WID-1:0] B,
output wire [WID:0] Q
/* */);
wire [WID-1:0] Cout;
/* The least significant slice has no Cin */
add1 U0 (.A(A[0]), .B(B[0]), .Cin(1'b0), .Q(Q[0]), .Cout(Cout[0]));
/* Generate all the remaining slices */
genvar i;
for (i = 1 ; i < WID ; i = i+1) begin : U
add1 Un (.A(A[i]), .B(B[i]), .Cin(Cout[i-1]), .Q(Q[i]), .Cout(Cout[i]));
end
assign Q[WID] = Cout[WID-1];
endmodule // add
/*
* This is a single-bit combinational adder used by the addH module
* above.
*/
module add1(input A, input B, input Cin, output Q, output Cout);
assign Q = A ^ B ^ Cin;
assign Cout = A&B | A&Cin | B&Cin;
endmodule // hadd
`ifdef TEST_BENCH
module main;
parameter WID = 4;
reg [WID-1:0] A, B;
wire [WID:0] Q;
addN #(.WID(WID)) usum (.A(A), .B(B), .Q(Q));
int adx;
int bdx;
initial begin
for (bdx = 0 ; bdx[WID]==0 ; bdx = bdx+1) begin
for (adx = 0 ; adx[WID]==0 ; adx = adx+1) begin
A <= adx[WID-1:0];
B <= bdx[WID-1:0];
#1 if (Q !== (adx+bdx)) begin
$display("FAILED -- A=%b, B=%b, Q=%b", A, B, Q);
$finish;
end
end
end
$display("PASSED");
end
endmodule // main
`endif
+40
View File
@@ -0,0 +1,40 @@
/*
* This is a post-wynthesis test for the blif01a.v test. Run this
* simulation in these steps:
*
* $ iverilog -tblif -o foo.blif blif01a.v
* $ abc
* abc 01> read_blif foo.blif
* abc 02> write_verilog foo.v
* abc 03> quit
* $ iverilog -g2009 -o foo.vvp blif02a_tb.v foo.v
* $ vvp foo.vvp
*/
module main;
parameter WID = 4;
reg [WID-1:0] A, B;
wire [WID:0] Q;
addN usum(.\A[3] (A[3]), .\A[2] (A[2]), .\A[1] (A[1]), .\A[0] (A[0]),
.\B[3] (B[3]), .\B[2] (B[2]), .\B[1] (B[1]), .\B[0] (B[0]),
.\Q[4] (Q[4]), .\Q[3] (Q[3]), .\Q[2] (Q[2]), .\Q[1] (Q[1]), .\Q[0] (Q[0]));
int adx;
int bdx;
initial begin
for (bdx = 0 ; bdx[WID]==0 ; bdx = bdx+1) begin
for (adx = 0 ; adx[WID]==0 ; adx = adx+1) begin
A <= adx[WID-1:0];
B <= bdx[WID-1:0];
#1 if (Q !== (adx+bdx)) begin
$display("FAILED -- A=%b, B=%b, Q=%b", A, B, Q);
$finish;
end
end
end
$display("PASSED");
end
endmodule // main
+9
View File
@@ -0,0 +1,9 @@
module test_logic(input A, B, output q_nand, q_nor, q_xnor, q_not);
assign q_nand = A ~& B;
assign q_nor = A ~| B;
assign q_xnor = A ~^ B;
assign q_not = ~A;
endmodule // test_logic
+34
View File
@@ -0,0 +1,34 @@
module main;
reg [2:0] X;
wire q_nand, q_nor, q_xnor, q_not;
test_logic DUT(.A(X[0]), .B(X[1]), .q_nand(q_nand), .q_nor(q_nor),
.q_xnor(q_xnor), .q_not(q_not));
initial begin
for (X = 0 ; X < 4 ; X = X+1) begin
#1 /* Let gates settle. */;
if (q_nand !== (X[0] ~& X[1])) begin
$display("FAILED -- q_nand=%b, X=%b", q_nand, X[1:0]);
$finish;
end
if (q_nor !== (X[0] ~| X[1])) begin
$display("FAILED -- q_nor=%b, X=%b", q_nor, X[1:0]);
$finish;
end
if (q_xnor !== (X[0] ~^ X[1])) begin
$display("FAILED -- q_xnor=%b, X=%b", q_xnor, X[1:0]);
$finish;
end
if (q_not !== (~X[0])) begin
$display("FAILED -- q_not=%b, X=%b", q_not, X[0]);
$finish;
end
end
$display("PASSED");
end
endmodule // main
+11
View File
@@ -0,0 +1,11 @@
module addN
#(parameter WID = 4)
(input wire [WID-1:0] A,
input wire [WID-1:0] B,
output wire [WID:0] Q
/* */);
assign Q = A + B;
endmodule // add
+40
View File
@@ -0,0 +1,40 @@
/*
* This is a post-wynthesis test for the blif01a.v test. Run this
* simulation in these steps:
*
* $ iverilog -tblif -o foo.blif blif01a.v
* $ abc
* abc 01> read_blif foo.blif
* abc 02> write_verilog foo.v
* abc 03> quit
* $ iverilog -g2009 -o foo.vvp blif02a_tb.v foo.v
* $ vvp foo.vvp
*/
module main;
parameter WID = 4;
reg [WID-1:0] A, B;
wire [WID:0] Q;
addN usum(.\A[3] (A[3]), .\A[2] (A[2]), .\A[1] (A[1]), .\A[0] (A[0]),
.\B[3] (B[3]), .\B[2] (B[2]), .\B[1] (B[1]), .\B[0] (B[0]),
.\Q[4] (Q[4]), .\Q[3] (Q[3]), .\Q[2] (Q[2]), .\Q[1] (Q[1]), .\Q[0] (Q[0]));
int adx;
int bdx;
initial begin
for (bdx = 0 ; bdx[WID]==0 ; bdx = bdx+1) begin
for (adx = 0 ; adx[WID]==0 ; adx = adx+1) begin
A <= adx[WID-1:0];
B <= bdx[WID-1:0];
#1 if (Q !== (adx+bdx)) begin
$display("FAILED -- A=%b, B=%b, Q=%b", A, B, Q);
$finish;
end
end
end
$display("PASSED");
end
endmodule // main
+11
View File
@@ -0,0 +1,11 @@
module subN
#(parameter WID = 4)
(input wire [WID-1:0] A,
input wire [WID-1:0] B,
output wire [WID:0] Q
/* */);
assign Q = A - B;
endmodule // add
+40
View File
@@ -0,0 +1,40 @@
/*
* This is a post-wynthesis test for the blif01a.v test. Run this
* simulation in these steps:
*
* $ iverilog -tblif -o foo.blif blif01a.v
* $ abc
* abc 01> read_blif foo.blif
* abc 02> write_verilog foo.v
* abc 03> quit
* $ iverilog -g2009 -o foo.vvp blif02a_tb.v foo.v
* $ vvp foo.vvp
*/
module main;
parameter WID = 4;
reg [WID-1:0] A, B;
wire [WID:0] Q;
subN usum(.\A[3] (A[3]), .\A[2] (A[2]), .\A[1] (A[1]), .\A[0] (A[0]),
.\B[3] (B[3]), .\B[2] (B[2]), .\B[1] (B[1]), .\B[0] (B[0]),
.\Q[4] (Q[4]), .\Q[3] (Q[3]), .\Q[2] (Q[2]), .\Q[1] (Q[1]), .\Q[0] (Q[0]));
int adx;
int bdx;
initial begin
for (bdx = 0 ; bdx[WID]==0 ; bdx = bdx+1) begin
for (adx = 0 ; adx[WID]==0 ; adx = adx+1) begin
A <= adx[WID-1:0];
B <= bdx[WID-1:0];
#1 if (Q !== (adx[WID-1:0]-bdx[WID-1:0])) begin
$display("FAILED -- A=%b, B=%b, Q=%b", A, B, Q);
$finish;
end
end
end
$display("PASSED");
end
endmodule // main
+14
View File
@@ -0,0 +1,14 @@
module cmpN
#(parameter WID = 4)
(input wire [WID-1:0] A,
input wire [WID-1:0] B,
output wire QE, QN, QGT, QGE
/* */);
assign QE = A == B;
assign QN = A != B;
assign QGT = A > B;
assign QGE = A >= B;
endmodule // add
+53
View File
@@ -0,0 +1,53 @@
/*
* This is a post-synthesis test for the blif01a.v test. Run this
* simulation in these steps:
*
* $ iverilog -tblif -o foo.blif blif01a.v
* $ abc
* abc 01> read_blif foo.blif
* abc 02> write_verilog foo.v
* abc 03> quit
* $ iverilog -g2009 -o foo.vvp blif02a_tb.v foo.v
* $ vvp foo.vvp
*/
module main;
parameter WID = 4;
reg [WID-1:0] A, B;
wire QE, QN, QGT, QGE;
cmpN ucmp(.\A[3] (A[3]), .\A[2] (A[2]), .\A[1] (A[1]), .\A[0] (A[0]),
.\B[3] (B[3]), .\B[2] (B[2]), .\B[1] (B[1]), .\B[0] (B[0]),
.QE(QE), .QN(QN), .QGT(QGT), .QGE(QGE));
int adx;
int bdx;
initial begin
for (bdx = 0 ; bdx[WID]==0 ; bdx = bdx+1) begin
for (adx = 0 ; adx[WID]==0 ; adx = adx+1) begin
A <= adx[WID-1:0];
B <= bdx[WID-1:0];
#1 ;
if (QE !== (adx[WID-1:0]==bdx[WID-1:0])) begin
$display("FAILED -- A=%b, B=%b, QE=%b", A, B, QE);
$finish;
end
if (QN !== (adx[WID-1:0]!=bdx[WID-1:0])) begin
$display("FAILED -- A=%b, B=%b, QN=%b", A, B, QN);
$finish;
end
if (QGT !== (adx[WID-1:0] > bdx[WID-1:0])) begin
$display("FAILED -- A=%b, B=%b, QGT=%b", A, B, QGT);
$finish;
end
if (QGE !== (adx[WID-1:0] >= bdx[WID-1:0])) begin
$display("FAILED -- A=%b, B=%b, QGE=%b", A, B, QGE);
$finish;
end
end
end
$display("PASSED");
end
endmodule // main
+11
View File
@@ -0,0 +1,11 @@
module muxN
#(parameter WID = 4, parameter SWID = 2)
(input wire [WID-1:0] D,
input wire [SWID-1:0] S,
output wire Q
/* */);
assign Q = D[S];
endmodule // add
+32
View File
@@ -0,0 +1,32 @@
module main;
parameter WID = 4;
parameter SWID = 2;
reg [WID-1:0] D;
reg [SWID-1:0] S;
wire Q;
muxN dut(.\D[3] (D[3]), .\D[2] (D[2]), .\D[1] (D[1]), .\D[0] (D[0]),
.\S[1] (S[1]), .\S[0] (S[0]),
.Q(Q));
integer idx, sdx;
initial begin
for (idx = 0 ; idx < 50 ; idx += 1) begin
D = $random;
for (sdx = 0 ; sdx < (1<<SWID) ; sdx = sdx+1) begin
S = sdx[SWID-1:0];
#1 ;
if (Q !== D[S]) begin
$display("FAILED = D=%b, S=%0d, Q=%b", D, S, Q);
$finish;
end
end
end // for (idx = 0 ; idx < 50 ; idx += 1)
$display("PASSED");
end // initial begin
endmodule // main
+14
View File
@@ -0,0 +1,14 @@
module test_logic
#(parameter WID = 4)
(input wire [WID-1:0] A,
output q_and, q_or, q_xor, q_nand, q_nor, q_xnor);
assign q_and = & A;
assign q_or = | A;
assign q_xor = ^ A;
assign q_nand= ~& A;
assign q_nor = ~| A;
assign q_xnor= ~^ A;
endmodule // test_logic
+44
View File
@@ -0,0 +1,44 @@
module main;
localparam WID = 4;
reg [WID:0] X;
wire q_and, q_or, q_xor, q_nand, q_nor, q_xnor;
test_logic DUT(.\A[3] (X[3]), .\A[2] (X[2]), .\A[1] (X[1]), .\A[0] (X[0]),
.q_and(q_and), .q_or(q_or), .q_xor(q_xor),
.q_nand(q_nand), .q_nor(q_nor), .q_xnor(q_xnor));
initial begin
for (X = 0 ; X < 16 ; X = X+1) begin
#1 /* Let gates settle. */;
if (q_and !== & X[WID-1:0]) begin
$display("FAILED -- q_and=%b, X=%b", q_and, X[WID-1:0]);
$finish;
end
if (q_or !== | X[WID-1:0]) begin
$display("FAILED -- q_or=%b, X=%b", q_or, X[WID-1:0]);
$finish;
end
if (q_xor !== ^ X[WID-1:0]) begin
$display("FAILED -- q_xor=%b, X=%b", q_xor, X[WID-1:0]);
$finish;
end
if (q_nand !== ~& X[WID-1:0]) begin
$display("FAILED -- q_nand=%b, X=%b", q_nand, X[WID-1:0]);
$finish;
end
if (q_nor !== ~| X[WID-1:0]) begin
$display("FAILED -- q_nor=%b, X=%b", q_nor, X[WID-1:0]);
$finish;
end
if (q_xnor !== ~^ X[WID-1:0]) begin
$display("FAILED -- q_xnor=%b, X=%b", q_xnor, X[WID-1:0]);
$finish;
end
end
$display("PASSED");
end
endmodule // main
+9
View File
@@ -0,0 +1,9 @@
module test_mux
(input wire [1:0] D0, D1,
input wire S,
output wire [1:0] Q);
assign Q = S? D1 : D0;
endmodule // test_mux
+33
View File
@@ -0,0 +1,33 @@
module main;
reg [1:0] D0, D1;
reg sel;
wire [1:0] Q;
test_mux DUT(.S(sel),
.\D0[1] (D0[1]), .\D0[0] (D0[0]),
.\D1[1] (D1[1]), .\D1[0] (D1[0]),
.\Q[1] (Q[1]), .\Q[0] (Q[0]));
initial begin
D0 = 'b01;
D1 = 'b10;
sel = 0;
#1 ;
if (Q !== D0) begin
$display("FAILED -- D0=%b, D1=%b, S=%b, Q=%b", D0, D1, sel, Q);
$finish;
end
sel = 1;
#1 ;
if (Q !== D1) begin
$display("FAILED -- D0=%b, D1=%b, S=%b, Q=%b", D0, D1, sel, Q);
$finish;
end
$display("PASSED");
end
endmodule // main
+12
View File
@@ -0,0 +1,12 @@
module ivtest
(
input [3:0] x,
input [3:0] y,
output [3:0] z
);
assign z = x ^ y;
endmodule // ivtest
+25
View File
@@ -0,0 +1,25 @@
module main;
reg [3:0] x, y;
wire [3:0] z;
ivtest dut (.\x[3] (x[3]), .\x[2] (x[2]), .\x[1] (x[1]), .\x[0] (x[0]),
.\y[3] (y[3]), .\y[2] (y[2]), .\y[1] (y[1]), .\y[0] (y[0]),
.\z[3] (z[3]), .\z[2] (z[2]), .\z[1] (z[1]), .\z[0] (z[0]));
integer idx;
initial begin
for (idx = 0 ; idx[8]==0 ; idx = idx+1) begin
x = idx[3:0];
y = idx[7:4];
#1 /* let devices settle. */ ;
if (z !== (x ^ y)) begin
$display("FAILED -- x=%b, y=%b, x^y=%b", x, y, z);
$finish;
end
end
$display("PASSED");
end // initial begin
endmodule // main
+40
View File
@@ -0,0 +1,40 @@
/*
* Generate a combinational adder of any width. The width parameter can
* be any integer value >0. The A and B inputs have WID bits, and the Q
* output has WID+1 bits to include the overflow.
*/
module addN
#(parameter WID = 4)
(input wire [WID-1:0] A,
input wire [WID-1:0] B,
output wire [WID:0] Q
/* */);
wire [WID-1:0] Cout;
/* The least significant slice has no Cin */
add1 U0 (.A(A[0]), .B(B[0]), .Cin(1'b0), .Q(Q[0]), .Cout(Cout[0]));
/* Generate all the remaining slices */
genvar i;
for (i = 1 ; i < WID ; i = i+1) begin : U
add1 Un (.A(A[i]), .B(B[i]), .Cin(Cout[i-1]), .Q(Q[i]), .Cout(Cout[i]));
end
assign Q[WID] = Cout[WID-1];
endmodule // add
/*
* This is a single-bit combinational adder used by the addH module
* above.
*/
module add1(input A, input B, input Cin, output reg Q, output reg Cout);
always @* begin
Q = A ^ B ^ Cin;
Cout = A&B | A&Cin | B&Cin;
end
endmodule // hadd
+40
View File
@@ -0,0 +1,40 @@
/*
* This is a post-wynthesis test for the blif01a.v test. Run this
* simulation in these steps:
*
* $ iverilog -tblif -o foo.blif blif01a.v
* $ abc
* abc 01> read_blif foo.blif
* abc 02> write_verilog foo.v
* abc 03> quit
* $ iverilog -g2009 -o foo.vvp blif02a_tb.v foo.v
* $ vvp foo.vvp
*/
module main;
parameter WID = 4;
reg [WID-1:0] A, B;
wire [WID:0] Q;
addN usum(.\A[3] (A[3]), .\A[2] (A[2]), .\A[1] (A[1]), .\A[0] (A[0]),
.\B[3] (B[3]), .\B[2] (B[2]), .\B[1] (B[1]), .\B[0] (B[0]),
.\Q[4] (Q[4]), .\Q[3] (Q[3]), .\Q[2] (Q[2]), .\Q[1] (Q[1]), .\Q[0] (Q[0]));
int adx;
int bdx;
initial begin
for (bdx = 0 ; bdx[WID]==0 ; bdx = bdx+1) begin
for (adx = 0 ; adx[WID]==0 ; adx = adx+1) begin
A <= adx[WID-1:0];
B <= bdx[WID-1:0];
#1 if (Q !== (adx+bdx)) begin
$display("FAILED -- A=%b, B=%b, Q=%b", A, B, Q);
$finish;
end
end
end
$display("PASSED");
end
endmodule // main
+11
View File
@@ -0,0 +1,11 @@
module test_logic(input A, B, output reg q_nand, q_nor, q_xnor, q_not);
always @(A, B) begin
q_nand = A ~& B;
q_nor = A ~| B;
q_xnor = A ~^ B;
q_not = ~A;
end
endmodule // test_logic
+34
View File
@@ -0,0 +1,34 @@
module main;
reg [2:0] X;
wire q_nand, q_nor, q_xnor, q_not;
test_logic DUT(.A(X[0]), .B(X[1]), .q_nand(q_nand), .q_nor(q_nor),
.q_xnor(q_xnor), .q_not(q_not));
initial begin
for (X = 0 ; X < 4 ; X = X+1) begin
#1 /* Let gates settle. */;
if (q_nand !== (X[0] ~& X[1])) begin
$display("FAILED -- q_nand=%b, X=%b", q_nand, X[1:0]);
$finish;
end
if (q_nor !== (X[0] ~| X[1])) begin
$display("FAILED -- q_nor=%b, X=%b", q_nor, X[1:0]);
$finish;
end
if (q_xnor !== (X[0] ~^ X[1])) begin
$display("FAILED -- q_xnor=%b, X=%b", q_xnor, X[1:0]);
$finish;
end
if (q_not !== (~X[0])) begin
$display("FAILED -- q_not=%b, X=%b", q_not, X[0]);
$finish;
end
end
$display("PASSED");
end
endmodule // main
+11
View File
@@ -0,0 +1,11 @@
module addN
#(parameter WID = 4)
(input wire [WID-1:0] A,
input wire [WID-1:0] B,
output reg [WID:0] Q
/* */);
always @* Q = A + B;
endmodule // add
+40
View File
@@ -0,0 +1,40 @@
/*
* This is a post-wynthesis test for the blif01a.v test. Run this
* simulation in these steps:
*
* $ iverilog -tblif -o foo.blif blif01a.v
* $ abc
* abc 01> read_blif foo.blif
* abc 02> write_verilog foo.v
* abc 03> quit
* $ iverilog -g2009 -o foo.vvp blif02a_tb.v foo.v
* $ vvp foo.vvp
*/
module main;
parameter WID = 4;
reg [WID-1:0] A, B;
wire [WID:0] Q;
addN usum(.\A[3] (A[3]), .\A[2] (A[2]), .\A[1] (A[1]), .\A[0] (A[0]),
.\B[3] (B[3]), .\B[2] (B[2]), .\B[1] (B[1]), .\B[0] (B[0]),
.\Q[4] (Q[4]), .\Q[3] (Q[3]), .\Q[2] (Q[2]), .\Q[1] (Q[1]), .\Q[0] (Q[0]));
int adx;
int bdx;
initial begin
for (bdx = 0 ; bdx[WID]==0 ; bdx = bdx+1) begin
for (adx = 0 ; adx[WID]==0 ; adx = adx+1) begin
A <= adx[WID-1:0];
B <= bdx[WID-1:0];
#1 if (Q !== (adx+bdx)) begin
$display("FAILED -- A=%b, B=%b, Q=%b", A, B, Q);
$finish;
end
end
end
$display("PASSED");
end
endmodule // main
+11
View File
@@ -0,0 +1,11 @@
module subN
#(parameter WID = 4)
(input wire [WID-1:0] A,
input wire [WID-1:0] B,
output reg [WID:0] Q
/* */);
always @(A or B) Q = A - B;
endmodule // add
+40
View File
@@ -0,0 +1,40 @@
/*
* This is a post-wynthesis test for the blif01a.v test. Run this
* simulation in these steps:
*
* $ iverilog -tblif -o foo.blif blif01a.v
* $ abc
* abc 01> read_blif foo.blif
* abc 02> write_verilog foo.v
* abc 03> quit
* $ iverilog -g2009 -o foo.vvp blif02a_tb.v foo.v
* $ vvp foo.vvp
*/
module main;
parameter WID = 4;
reg [WID-1:0] A, B;
wire [WID:0] Q;
subN usum(.\A[3] (A[3]), .\A[2] (A[2]), .\A[1] (A[1]), .\A[0] (A[0]),
.\B[3] (B[3]), .\B[2] (B[2]), .\B[1] (B[1]), .\B[0] (B[0]),
.\Q[4] (Q[4]), .\Q[3] (Q[3]), .\Q[2] (Q[2]), .\Q[1] (Q[1]), .\Q[0] (Q[0]));
int adx;
int bdx;
initial begin
for (bdx = 0 ; bdx[WID]==0 ; bdx = bdx+1) begin
for (adx = 0 ; adx[WID]==0 ; adx = adx+1) begin
A <= adx[WID-1:0];
B <= bdx[WID-1:0];
#1 if (Q !== (adx[WID-1:0]-bdx[WID-1:0])) begin
$display("FAILED -- A=%b, B=%b, Q=%b", A, B, Q);
$finish;
end
end
end
$display("PASSED");
end
endmodule // main
+27
View File
@@ -0,0 +1,27 @@
module cmpN
#(parameter WID = 4)
(input wire [WID-1:0] A,
input wire [WID-1:0] B,
output reg QE, QN, QGT, QGE
/* */);
always @(A, B)
if (A > B) begin
QE = 0;
QN = 1;
QGT = 1;
QGE = 1;
end else if (A == B) begin
QE = 1;
QN = 0;
QGT = 0;
QGE = 1;
end else begin
QE = 0;
QN = 1;
QGT = 0;
QGE = 0;
end
endmodule // add
+53
View File
@@ -0,0 +1,53 @@
/*
* This is a post-synthesis test for the blif01a.v test. Run this
* simulation in these steps:
*
* $ iverilog -tblif -o foo.blif blif01a.v
* $ abc
* abc 01> read_blif foo.blif
* abc 02> write_verilog foo.v
* abc 03> quit
* $ iverilog -g2009 -o foo.vvp blif02a_tb.v foo.v
* $ vvp foo.vvp
*/
module main;
parameter WID = 4;
reg [WID-1:0] A, B;
wire QE, QN, QGT, QGE;
cmpN ucmp(.\A[3] (A[3]), .\A[2] (A[2]), .\A[1] (A[1]), .\A[0] (A[0]),
.\B[3] (B[3]), .\B[2] (B[2]), .\B[1] (B[1]), .\B[0] (B[0]),
.QE(QE), .QN(QN), .QGT(QGT), .QGE(QGE));
int adx;
int bdx;
initial begin
for (bdx = 0 ; bdx[WID]==0 ; bdx = bdx+1) begin
for (adx = 0 ; adx[WID]==0 ; adx = adx+1) begin
A <= adx[WID-1:0];
B <= bdx[WID-1:0];
#1 ;
if (QE !== (adx[WID-1:0]==bdx[WID-1:0])) begin
$display("FAILED -- A=%b, B=%b, QE=%b", A, B, QE);
$finish;
end
if (QN !== (adx[WID-1:0]!=bdx[WID-1:0])) begin
$display("FAILED -- A=%b, B=%b, QN=%b", A, B, QN);
$finish;
end
if (QGT !== (adx[WID-1:0] > bdx[WID-1:0])) begin
$display("FAILED -- A=%b, B=%b, QGT=%b", A, B, QGT);
$finish;
end
if (QGE !== (adx[WID-1:0] >= bdx[WID-1:0])) begin
$display("FAILED -- A=%b, B=%b, QGE=%b", A, B, QGE);
$finish;
end
end
end
$display("PASSED");
end
endmodule // main
+11
View File
@@ -0,0 +1,11 @@
module muxN
#(parameter WID = 4, parameter SWID = 2)
(input wire [WID-1:0] D,
input wire [SWID-1:0] S,
output reg Q
/* */);
always @* Q = D[S];
endmodule // add
+32
View File
@@ -0,0 +1,32 @@
module main;
parameter WID = 4;
parameter SWID = 2;
reg [WID-1:0] D;
reg [SWID-1:0] S;
wire Q;
muxN dut(.\D[3] (D[3]), .\D[2] (D[2]), .\D[1] (D[1]), .\D[0] (D[0]),
.\S[1] (S[1]), .\S[0] (S[0]),
.Q(Q));
integer idx, sdx;
initial begin
for (idx = 0 ; idx < 50 ; idx += 1) begin
D = $random;
for (sdx = 0 ; sdx < (1<<SWID) ; sdx = sdx+1) begin
S = sdx[SWID-1:0];
#1 ;
if (Q !== D[S]) begin
$display("FAILED = D=%b, S=%0d, Q=%b", D, S, Q);
$finish;
end
end
end // for (idx = 0 ; idx < 50 ; idx += 1)
$display("PASSED");
end // initial begin
endmodule // main
+16
View File
@@ -0,0 +1,16 @@
module test_logic
#(parameter WID = 4)
(input wire [WID-1:0] A,
output reg q_and, q_or, q_xor, q_nand, q_nor, q_xnor);
always @(A) begin
q_and = &A;
q_or = |A;
q_xor = ^A;
q_nand = ~q_and;
q_nor = ~q_or;
q_xnor = ~q_xor;
end
endmodule // test_logic
+44
View File
@@ -0,0 +1,44 @@
module main;
localparam WID = 4;
reg [WID:0] X;
wire q_and, q_or, q_xor, q_nand, q_nor, q_xnor;
test_logic DUT(.\A[3] (X[3]), .\A[2] (X[2]), .\A[1] (X[1]), .\A[0] (X[0]),
.q_and(q_and), .q_or(q_or), .q_xor(q_xor),
.q_nand(q_nand), .q_nor(q_nor), .q_xnor(q_xnor));
initial begin
for (X = 0 ; X < 16 ; X = X+1) begin
#1 /* Let gates settle. */;
if (q_and !== & X[WID-1:0]) begin
$display("FAILED -- q_and=%b, X=%b", q_and, X[WID-1:0]);
$finish;
end
if (q_or !== | X[WID-1:0]) begin
$display("FAILED -- q_or=%b, X=%b", q_or, X[WID-1:0]);
$finish;
end
if (q_xor !== ^ X[WID-1:0]) begin
$display("FAILED -- q_xor=%b, X=%b", q_xor, X[WID-1:0]);
$finish;
end
if (q_nand !== ~& X[WID-1:0]) begin
$display("FAILED -- q_nand=%b, X=%b", q_nand, X[WID-1:0]);
$finish;
end
if (q_nor !== ~| X[WID-1:0]) begin
$display("FAILED -- q_nor=%b, X=%b", q_nor, X[WID-1:0]);
$finish;
end
if (q_xnor !== ~^ X[WID-1:0]) begin
$display("FAILED -- q_xnor=%b, X=%b", q_xnor, X[WID-1:0]);
$finish;
end
end
$display("PASSED");
end
endmodule // main
+15
View File
@@ -0,0 +1,15 @@
module test_mux
(input wire [1:0] D0, D1,
input wire [1:0] S,
output reg [1:0] Q);
always @(*) begin
case (S)
2'b00: Q = D0;
2'b01: Q = D1;
default: Q = 0;
endcase // case (S)
end
endmodule // test_mux
+33
View File
@@ -0,0 +1,33 @@
module main;
reg [1:0] D0, D1;
reg sel;
wire [1:0] Q;
test_mux DUT(.\S[1] (1'b0), .\S[0] (sel),
.\D0[1] (D0[1]), .\D0[0] (D0[0]),
.\D1[1] (D1[1]), .\D1[0] (D1[0]),
.\Q[1] (Q[1]), .\Q[0] (Q[0]));
initial begin
D0 = 'b01;
D1 = 'b10;
sel = 0;
#1 ;
if (Q !== D0) begin
$display("FAILED -- D0=%b, D1=%b, S=%b, Q=%b", D0, D1, sel, Q);
$finish;
end
sel = 1;
#1 ;
if (Q !== D1) begin
$display("FAILED -- D0=%b, D1=%b, S=%b, Q=%b", D0, D1, sel, Q);
$finish;
end
$display("PASSED");
end
endmodule // main
+53
View File
@@ -0,0 +1,53 @@
module cmpN
#(parameter WID = 4)
(input wire [WID-1:0] A,
input wire [WID-1:0] B,
output reg QE, QN, QGT, QGE
/* */);
always @(A, B)
if (A > B)
QGT = 1;
else
QGT = 0;
always @(A, B)
if (A >= B)
QGE = 1;
else
QGE = 0;
always @(A, B)
if (A == B)
QE = 1;
else
QE = 0;
always @(A, B)
if (A != B)
QN = 1;
else
QN = 0;
/*
always @(A, B)
if (A > B) begin
QE = 0;
QN = 1;
QGT = 1;
QGE = 1;
end else if (A == B) begin
QE = 1;
QN = 0;
QGT = 0;
QGE = 1;
end else begin
QE = 0;
QN = 1;
QGT = 0;
QGE = 0;
end
*/
endmodule // add
+53
View File
@@ -0,0 +1,53 @@
/*
* This is a post-synthesis test for the blif01a.v test. Run this
* simulation in these steps:
*
* $ iverilog -tblif -o foo.blif blif01a.v
* $ abc
* abc 01> read_blif foo.blif
* abc 02> write_verilog foo.v
* abc 03> quit
* $ iverilog -g2009 -o foo.vvp blif02a_tb.v foo.v
* $ vvp foo.vvp
*/
module main;
parameter WID = 4;
reg [WID-1:0] A, B;
wire QE, QN, QGT, QGE;
cmpN ucmp(.\A[3] (A[3]), .\A[2] (A[2]), .\A[1] (A[1]), .\A[0] (A[0]),
.\B[3] (B[3]), .\B[2] (B[2]), .\B[1] (B[1]), .\B[0] (B[0]),
.QE(QE), .QN(QN), .QGT(QGT), .QGE(QGE));
int adx;
int bdx;
initial begin
for (bdx = 0 ; bdx[WID]==0 ; bdx = bdx+1) begin
for (adx = 0 ; adx[WID]==0 ; adx = adx+1) begin
A <= adx[WID-1:0];
B <= bdx[WID-1:0];
#1 ;
if (QE !== (adx[WID-1:0]==bdx[WID-1:0])) begin
$display("FAILED -- A=%b, B=%b, QE=%b", A, B, QE);
$finish;
end
if (QN !== (adx[WID-1:0]!=bdx[WID-1:0])) begin
$display("FAILED -- A=%b, B=%b, QN=%b", A, B, QN);
$finish;
end
if (QGT !== (adx[WID-1:0] > bdx[WID-1:0])) begin
$display("FAILED -- A=%b, B=%b, QGT=%b", A, B, QGT);
$finish;
end
if (QGE !== (adx[WID-1:0] >= bdx[WID-1:0])) begin
$display("FAILED -- A=%b, B=%b, QGE=%b", A, B, QGE);
$finish;
end
end
end
$display("PASSED");
end
endmodule // main
+17
View File
@@ -0,0 +1,17 @@
module test_mux
(input wire [1:0] D0, D1,
input wire [1:0] S,
output reg [1:0] Q);
always @(*) begin
if (S[1]==1'b0)
case (S[0])
1'b0: Q = D0;
1'b1: Q = D1;
endcase // case (S[0])
else
Q = 2'b0;
end
endmodule // test_mux
+33
View File
@@ -0,0 +1,33 @@
module main;
reg [1:0] D0, D1;
reg sel;
wire [1:0] Q;
test_mux DUT(.\S[1] (1'b0), .\S[0] (sel),
.\D0[1] (D0[1]), .\D0[0] (D0[0]),
.\D1[1] (D1[1]), .\D1[0] (D1[0]),
.\Q[1] (Q[1]), .\Q[0] (Q[0]));
initial begin
D0 = 'b01;
D1 = 'b10;
sel = 0;
#1 ;
if (Q !== D0) begin
$display("FAILED -- D0=%b, D1=%b, S=%b, Q=%b", D0, D1, sel, Q);
$finish;
end
sel = 1;
#1 ;
if (Q !== D1) begin
$display("FAILED -- D0=%b, D1=%b, S=%b, Q=%b", D0, D1, sel, Q);
$finish;
end
$display("PASSED");
end
endmodule // main

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