Compare commits

...
571 Commits
Author SHA1 Message Date
Stephen Williams 3d14281e0d Prepare for version 10.2 2017-08-24 08:22:49 -07:00
Stephen Williams 2564554178 Minor tweak to some assertions. 2017-08-24 08:18:55 -07:00
Martin Whitaker 8cd697fd24 Fix for br1019 - allow multiple array words to be attached to a vpi callback.
Normally there is at most one signal attached to a vvp functor, but
due to port collapsing, there can be more than one. If these signals
are array words, we need to trigger vpi callbacks on all the associated
arrays when the functor value changes.

(cherry picked from commit ac87138c44)
2017-08-12 12:31:14 +01:00
Cary R 306d2fb53b V10: Fix class versus struct warning in clang 2017-06-19 21:26:35 -07:00
Martin Whitaker 52b497f74c Don't allow localparams to be overridden (GitHub issue #157)
Currently we only issue a warning if a parameter override references
a parameter that doesn't exist, so do the same in this case.

(cherry picked from commit 42422d9940)
2017-06-16 21:11:18 +01:00
Martin Whitaker ce7f28202a Ensure value passed to named event via vpi_put_value() is initialised.
The __vpiNamedEvent::vpi_put_value() function ignores the value, but
intermediate code looks at it.

(cherry picked from commit e2be64558b)
2017-06-15 09:15:31 +01:00
Martin Whitaker 49bea6a01a Implement vpi_put_value() for named events (GitHub issue #158).
(cherry picked from commit 3de7c234f7)
2017-06-15 08:52:15 +01:00
Martin Whitaker 8ab100c1c7 Fix for GitHub issue #152 - segfault on gate connection syntax error.
If there is a syntax error in the source code, pform_makegate may be
passed a null list of port connections. The error is already reported,
so we just need to ignore it.

(cherry picked from commit 8a5cbd4415)
2017-04-21 21:44:27 +01:00
Martin Whitaker 177ae7c220 Improved error checking for defparam values supplied on the command line.
Fixes GitHub issue #139 plus various assertion failures when invalid
values are specified.

(cherry picked from commit 3c91630b53)
2017-01-29 20:25:04 +00:00
Martin Whitaker b04d5a9068 Fix for GitHub issue #142 - assertion failure when parameter expression
contains undefined variable.

(cherry picked from commit 8f6f999ea7)
2017-01-29 20:24:56 +00:00
Martin Whitaker b8c8f03037 Add library search path option to iverilog-vpi (GitHub issue #145).
(cherry picked from commit 4e2ba29dc6)
2017-01-29 20:24:47 +00:00
Stephen Williams 38013f7a34 Sorry message for procedural assertion statements. 2017-01-10 12:18:38 -08:00
Cary R 561638a31f Allocate the correct amount of memory when escaping a string 2017-01-08 20:46:29 -08:00
Martin Whitaker bb91512e75 Fix for GitHub issue #128 - disable CONCATZ generation for vhdl target.
(cherry picked from commit b4e8a12309)
2016-11-25 22:36:19 +00:00
Martin Whitaker 09ff851483 Fix for GitHub issue #130 part 2 : assertion failure on unsupported cast.
(cherry picked from commit 7cac4677bf)
2016-11-25 22:36:00 +00:00
Martin Whitaker 19d8f43e9b Fix for GitHub issue #130 part 1 - null dereference when assigning int to enum.
(cherry picked from commit 002f118bb5)
2016-11-25 22:35:37 +00:00
Henry Wong ce88deaa97 Fix segfault when error in multi-dimensional part select.
(cherry picked from commit 182c08b528)
2016-11-25 21:33:47 +00:00
Henry Wong 1a8b19baf2 Fix null-pointer when trying to dump null statements.
(cherry picked from commit 69a96112e8)
2016-11-25 21:33:41 +00:00
Henry Wong b3cf533b3c Pop current_block_stack after for_variable_declaration and foreach.
(cherry picked from commit f827e4f748)
2016-11-25 21:33:33 +00:00
Martin Whitaker ba3856ebb0 Fix indentation in previous patch.
(cherry picked from commit 991d7d7582)
2016-10-20 16:49:37 +01:00
Henry Wong c06e2790a7 Adding implementation of NetEvWait::nex_input to handle event controls inside always@(*) blocks
(cherry picked from commit 1f9bf656ed)
2016-10-20 16:49:29 +01:00
Maciej Suminski 6e460a6a3f Fixed warnings about shifting a negative value 2016-10-14 23:41:11 +01:00
Maciej Suminski dbc536c4fb Added missing brackets
(cherry picked from commit 3710d35dd1)
2016-10-14 23:22:26 +01:00
Stephen Williams 5e41c86d01 Merge branch 'v10-branch' of github.com:steveicarus/iverilog into v10-branch 2016-10-14 10:31:58 -07:00
Martin Whitaker 572124e1e9 Allow library files to be specified on the iverilog command line.
This was already supported in command files, using the '-v' flag.
'-v' is already in use on the command line, so use '-l' instead,
and make that an alias for '-v' in command files.

(cherry picked from commit 7ddc514518)
2016-10-02 19:17:24 +01:00
Martin Whitaker 37ecdb4cfb Stop tgt-vvp from generating .alias records.
(partial backport of commit d44c814bab)

Net arrays can be handled by nets directly, instead of creating
.alias records. But keep support for .alias records in vvp. to
maintain backwards compatibility.
2016-09-17 19:49:26 +01:00
Martin Whitaker a11dc8b472 Backport Nexus::has_floating_input() from master branch.
Needed to support check for output port coercion.
2016-09-17 19:40:05 +01:00
Martin Whitaker e7852f8f9c Fix for GitHub issue #127 - coerce output ports to inout when necessary.
(cherry picked from commit 080dd0323d)
2016-09-17 19:24:04 +01:00
Martin Whitaker 9449c46865 Use gn_system_verilog() where appropriate.
Replace explicit comparisons against generation_flag with calls to
the gn_system_verilog helper function, both for code clarity and
to fix a couple of bugs. Also simplify the implementation of the
function, as we already rely on the generation_flag enumeration
being an ordered list.

(cherry picked from commit 3c9b39846c)
2016-09-17 19:23:48 +01:00
Martin Whitaker 8a780ece56 Merge branch 'v10-branch' of github.com:steveicarus/iverilog into v10-branch 2016-08-15 20:49:51 +01:00
Cary R 8bb4777789 Fix getting timeunit outside of module to use a defined check value 2016-08-14 17:26:31 -07:00
Cary R 3b705d95a6 Update fstapi.c to latest from GTKWave 2016-08-14 12:47:15 -07:00
Martin Whitaker f9559853f1 Fix for br1007 - out-of-range constant bit select should be a warning.
An out-of-range constant bit select on the LHS of an assignment was being
treated as an error, whereas an out-of range constant part select would
only result in a warning. In any other context, either case would result
in a warning, so convert the error to a warning.

In addition, all warnings for out-of-range or undefined constant bit/part
selects should be controlled by -Wselect-range.

(cherry picked from commit b51e58fa9d)
2016-08-08 22:26:05 +01:00
Martin Whitaker cda95c1554 Fix vlog95 target to handle hierarchical references in root-level tasks.
(cherry picked from commit 8461e1d9c4)
2016-07-26 22:04:05 +01:00
Martin Whitaker 4066031add Fix for GitHub issue #104 - assigning hierarchical signal from top level task.
When emitting a design, all scopes must be emitted before emitting any
top level task/function/method definitions, otherwise hierarchical
references can't always be resolved.

(cherry picked from commit 2bc42fc6e2)
2016-07-26 22:03:59 +01:00
Martin Whitaker d6d50e9b68 Update vlog95 target to handle timescales for root scope tasks/functions.
(cherry picked from commit b1b91f49c8)
2016-07-23 00:15:55 +01:00
Martin Whitaker 0ffbb2b1de Fix for GitHub issue #115 - synthesis aborts on case with max guard of 0.
The calculation of the required multiplexer width was incorrect for
the corner case of a single guard value of zero.

(cherry picked from commit 27213f2af8)
2016-07-23 00:15:43 +01:00
Martin Whitaker 9b55a3d67f Support timescales in design units that aren't inside a module.
SystemVerilog allows tasks, functions, and classes to be defined at the
root level or inside packages, so we can't rely on an enclosing module
being present to provide the timescale.

(cherry picked from commit 7bed181f68)
2016-07-23 00:15:15 +01:00
Martin Whitaker 07623bef2e Fix assignment of outputs from class methods.
As for inputs, skip over the implicit 'this' parameter.

(cherry picked from commit e316cc708b)
2016-07-23 00:13:07 +01:00
Martin Whitaker 73d688c313 Fix for br1003 - prevent segfault when delays are used outside a module.
(cherry picked from commit b8f9ed27c5)
2016-07-23 00:12:57 +01:00
Martin Whitaker 6155986d1c Fix for br1005 - segfault when SV queue is declared inside a class.
For now, output a "sorry" message to indicate this is not yet
supported.

(cherry picked from commit ad1101cc80)
2016-07-11 20:13:52 +01:00
Martin Whitaker face462cc2 Partial fix for br1006 - allow part selects in path declarations.
This just enables the compiler to parse path declarations that
contain part selects. As for bit selects, the part select is
discarded, and if elaboration of specify blocks is enabled,
the path declaration will be applied to the entire vector. If
elaboration is enabled, a warning message will now be output
when a bit or part select is discarded.

(cherry picked from commit ad87704809)
2016-07-10 20:25:39 +01:00
Martin Whitaker a5f6329500 Improved fix for GitHub issue #112.
This does a better job of setting the intermediate expression types
and widths when calculating the canonical index into a packed array.
It still doesn't properly handle out-of-bound indices (br953).

(cherry picked from commit 7f612270b3)
2016-07-10 13:38:44 +01:00
Martin Whitaker 3e13594816 Fix for GitHub issue 112 - index calculation for >2D packed arrays.
(cherry picked from commit 1448210f28)
2016-07-10 13:38:36 +01:00
Martin Whitaker 99138eafb1 Fix vector width calculation for multi-dimensional packed arrays.
(cherry picked from commit d496b095ff)
2016-07-10 13:38:23 +01:00
Martin Whitaker 86968e3752 Fix for GitHub issue #106 - prevent VPI writes during read-only synch.
(cherry picked from commit 8234f1845d)
2016-06-09 21:29:32 +01:00
Martin Whitaker 27a46f4afe Fix for GitHub issue #105 - fully support SV macro escape sequences.
The existing support for ``, `", and `\`" did not work in nested macro
definitions. Note that the new implementation only detects and replaces
these sequences inside the macro text (as required by the IEEE standard),
whereas the old implementation would detect and replace them anywhere in
the source files.

(cherry picked from commit 332170d36b)
2016-06-06 20:26:52 +01:00
Martin Whitaker d770199550 Add tgt-vvp sorry message for unsupported mixed NB/CA to vector. 2016-05-10 23:02:04 +01:00
Martin Whitaker 06f6a72770 Fix for GitHub issue #103 - vvp assertion failure on part select propagation.
The implementation of vvp_fun_part_pv::recv_vec4_pv was incorrect, and
propagated the incoming widths rather than the stored widths.

(cherry picked from commit 0c66116f51)
2016-05-10 22:41:58 +01:00
Maciej Suminski 30257e0914 ivl: Support for part selection in multidimensional packed ports assignment.
(cherry picked from commit b4baace4b1)
2016-04-19 21:32:38 +01:00
Maciej Suminski b2281b0e65 ivl: Fixed slice base calculation
when range is rising (e.g. logic [0:3] arr) or when it
starts with a non-zero integer (e.g. logic [4:1] arr).

(cherry picked from commit de775975e8)
2016-04-19 21:26:35 +01:00
Maciej Suminski 161cebb178 vvp: Corrected vvp_net_fun_t::recv_vec4_pv() (commit de968e18)
(cherry picked from commit 9cf1dcbae2)
2016-04-19 21:04:48 +01:00
Martin Whitaker b46d8b8389 Fix for br974 - support SV types in non-ansi port declarations.
(cherry picked from commit 6ba2bee977)
2016-04-19 20:47:33 +01:00
Martin Whitaker 2689ebacfe Extended fix for GitHub issue #99.
Most vvp functors need to support recv_vec4_pv. Any that are strength-aware
also need to support recv_vec8_pv. Note the simplifying assumption that is
documented in the base class recv_vec4_pv_ implementation.

(cherry picked from commit 6e5ed73b09)
2016-04-19 20:46:55 +01:00
Martin Whitaker 5bbb054173 Add check for explicit lifetime when initialising static variables.
If a static variable declared in a task, function, or block has an
initialisation expression, SystemVerilog requires the declaration to
have an explicit static lifetime. This is supposed to be a compile
error, but for now just output a warning.

Implementing this required adding support in the parser for explicit
lifetimes in variable declarations. For now, just output an error if
the user asks for a lifetime that isn't the default for that scope.

(cherry picked from commit 9538c81d34)
2016-04-19 20:43:25 +01:00
Martin Whitaker 7d2eeb0137 Added support for default subroutine lifetimes (SystemVerilog).
(cherry picked from commit 6e718c2e0c)
2016-04-19 20:43:14 +01:00
Martin Whitaker 4aef636559 Variable initialization blocks should be unamed.
Also add file/line info to initial process.

(cherry picked from commit 72bb63cf42)
2016-04-19 20:41:48 +01:00
Martin Whitaker 72fc3d712d For SystemVerilog, run variable initialization before main simulation starts.
(cherry picked from commit 54feb89bf5)
2016-04-19 20:41:25 +01:00
Martin Whitaker 3f75f6b155 Fully support variable initialization in tasks/functions/named blocks.
(cherry picked from commit 635adfc01e)
2016-04-19 20:40:14 +01:00
Martin Whitaker 9be3fc3a56 Fix GitHub issue #99 - recv_vec4_pv not implemented for arithmetic functors.
Also initialise the stored operand values to 'bz instead of 'bx to get
the correct results when bits are not driven.

(cherry picked from commit b2f7d09f0d)
2016-04-04 22:41:10 +01:00
Larry Doolittle aa2260f4fa Capitalize Verilog in a few places
(cherry picked from commit 89edf62206)
2016-04-02 22:42:26 +01:00
Martin Whitaker 6974613bff Fix for GitHub issue #96 - support mixed constant/variable delays in vvp.
If all three rise/fall/decay delay values are constant, we can use
the vvp .delay statement variant that takes three literal numbers.
If not, we have to use the variant that takes three net inputs. If
some of the delay values are constant, we need to create constant
drivers for those delay inputs.

(cherry picked from commit 20104c92c8)
2016-04-02 20:04:08 +01:00
Martin Whitaker 8bd4e9d481 Refactor to use new pad_to_width/cast_to_width functions.
(cherry picked from commit 7f475d4210)
2016-03-25 22:42:20 +00:00
Martin Whitaker 04ae07f03c Fix for GitHub issue #94 - enhance support for SystemVerilog size casting.
Allow the size expression to be any constant expression. Also ensure that
the expression width and type are correctly calculated and applied.

(cherry picked from commit dc1c3a4043)
2016-03-25 22:41:50 +00:00
Cary R d9be5318f9 Fix a cppcheck warning 2016-03-24 20:24:03 -07:00
Cary R 88cd5534c4 Use correct type when printing supply pull message 2016-03-15 03:51:39 -07:00
Martin Whitaker 3b577340ad Fix for br1001 - connect undriven wand/wor to 'bz in tgt-vvp.
(cherry picked from commit dbaf2471f2)
2016-03-13 16:45:22 +00:00
Martin Whitaker 583a31c121 Changed default for -gshared-loop-index to false. 2016-03-05 17:52:58 +00:00
Martin Whitaker a391c3ae28 Fix for br1000 - avoid infinite loop when processes share a for-loop index.
(cherry picked from commit b4d5248c67)
2016-03-05 17:45:37 +00:00
Martin Whitaker b551a783e8 Add support for real valued compressed assignment statements in tgt-vvp.
(cherry picked from commit a0bee0a76f)
2016-02-23 23:02:23 +00:00
Martin Whitaker 33db07ab8d Fix expression/operator type for compressed assignment/shift.
(cherry picked from commit a7066e3686)
2016-02-23 21:28:40 +00:00
Martin Whitaker e2aae72880 Fix expression type for compressed assignment statements.
A compressed assignment statement should give exactly the same
result as the equivalent uncompressed statement. This means
that the type (signed/unsigned) of the LHS affects the type of
the RHS expression (unlike in normal assignments). We need to
take care that bit/part selects and concatenations are correctly
identified as unsigned values, even in the cases where they
reduce to a single whole signal.

(cherry picked from commit 0199ad129d)
2016-02-23 21:27:55 +00:00
Martin Whitaker ec9897af5a Fix lval extension for compressed assignment in constant function.
The type of extension (zero/sign) is determined by the expression
type, not the operand type, so we need to cast to the expression
type before extending the value.

(cherry picked from commit 241b6723e5)
2016-02-23 21:22:25 +00:00
Martin Whitaker 2771abf86a Fix compressed assignments to concatenations.
When loading a lval concatenation, tgt-vvp was loading the elements
in the wrong order for the %concat instruction.

(cherry picked from commit b77d758f19)
2016-02-23 21:22:03 +00:00
Martin Whitaker b0461787c8 Extended constant function assignment operator support to real values.
(cherry-picked from master branch)

Also output a "sorry" message if the LHS is a concatenation.
2016-02-22 23:34:27 +00:00
Martin Whitaker 6f41576930 Add support for SystemVerilog assignment operators in constant functions.
(cherry-picked from master branch)
2016-02-22 22:24:11 +00:00
Stephen Williams cc7516eab3 Minor release update. 2016-02-10 11:39:12 -08:00
Stephen Williams 1a5ae96540 Fix broken "inherits dimensions from var/net" warning.
(cherry picked from commit 12c39aa4bb)
2016-02-10 11:23:44 -08:00
Stephen Williams 1ea8a13bf8 Prepare for 10.1 release. 2016-02-06 17:23:23 -08:00
Stephen Williams 490884cf7b Add the -Wimplicit-dimensions warning.
(cherry picked from commit f3647578d4)

Conflicts:
	scripts/devel-stub.conf
2016-02-06 16:48:43 -08:00
Martin Whitaker ca1d7ccffe Temporary fix for br993 - assertion failure in flip-flop synthesis.
(cherry-picked from master branch)

Synthesis does not currently support some commonly used styles for
representing flip-flops, e.g.

  q <= 0;
  if (en) q <= 1;

or

  if (clr) q <= 0;
  if (set) q <= 1;

For now, output a "sorry" message.
2016-01-30 22:44:26 +00:00
Martin Whitaker faf9bfe158 Fix for br994 - assertion failure when synthesising a mux.
(cherry-picked from master branch)

The elaborator allows the RHS of assignment to be wider than the
LHS. When using an if statement to represent a mux, this meant the
mux inputs could be different widths, resulting in an assertion
failure during synthesis. The fix is to prune the RHS to match the
LHS for each assignment. This has the benefit of minimising the
mux width.
2016-01-30 20:19:05 +00:00
Martin Whitaker 086ce04cf5 Temporary fix for br995 - assignment to memory not supported in synthesis.
(cherry-picked from master branch)

For now, output a "sorry" message.
2016-01-30 17:05:09 +00:00
Martin Whitaker 7b7231c417 Fix for br999 - incorrect result from binary comparison.
(cherry-picked from master branch)

When a binary (in)equality comparison has a constant left operand,
the tgt-vvp code generator swaps the left and right operands to
allow the cmpi instruction to be used. The code for swapping the
operands was incorrect.
2016-01-07 19:23:36 +00:00
Cary R d7b919f6d0 Update cppcheck suppression file 2015-12-19 11:58:38 -08:00
Cary R 9b34a96cb9 V10: Fix some compile warnings 2015-12-19 11:15:32 -08:00
Cary R 90cf0e5794 VHDL-10: fix a compile warning and add some missing newlines 2015-12-19 10:50:42 -08:00
Cary R 818379b9bc GTKWave (fstapi.c) needs realpath() so check for it 2015-12-19 09:11:56 -08:00
Cary R 9fbb7f84e6 A VHDL ExpAttribute() can share the base so don't just delete them 2015-12-13 19:02:26 -08:00
Cary R ed7d6c1002 Fix memory leak found with valgrind 2015-12-13 14:56:49 -08:00
Cary R a4306dbac1 Fix the modpath delay to ignore bits that are not changing 2015-10-21 22:02:17 -07:00
Cary R a682e13d82 Update LZ4 files to latest from GTKWave 2015-10-02 10:32:45 -07:00
Cary R 643e0a984e Fix some cppcheck warnings 2015-10-02 09:44:02 -07:00
Stephen Williams 63d2059b85 Have scope auto-rename generate names that use the index numbers
In generate blocks such as for loops, there may be many generated
scopes that have the same generated name. But in these cases, there
is an index number in the hname that can be used. So do so.

(cherry picked from commit 81f54ec0cb)
2015-09-30 09:48:56 -07:00
Martin Whitaker d9e09ceb59 Fix for GitHub issue #79 - literal numbers must have at least one digit.
(cherry-picked from master branch)

The bug report was for an assertion failure when a number contained only
a lowline (e.g. 'b_), but the standard says that a number can't start
with a lowline (e.g. 'b_1). The parser already rejected these cases for
decimal numbers, but allowed them through for binary/octal/hex numbers.
2015-09-23 00:15:50 +01:00
Stephen Williams 6d0ab9978f rpm spec file aware of stable versions. 2015-08-23 14:41:41 -07:00
Martin Whitaker e25cdf86ac Fix for br992 - prevent assertion/crash on declarations outside a module.
parse.y has been updated to allow declarations outside a module (legal
in SystemVerilog), but not all types of declaration are supported yet.
Output a sorry or error message as appropriate.
2015-08-21 00:11:59 +01:00
Stephen Williams 13bff8c50d Remove synthesis warning.
(cherry picked from commit d2c72a126d)
2015-08-20 13:53:13 -07:00
Stephen Williams b1b017251a Fix windres input version string for v10 and later. 2015-08-20 13:50:57 -07:00
Cary R e13a52637a A concatenation or the expression being replicated must have a non-zero width 2015-08-18 16:23:33 -07:00
Stephen Williams 4803f0d12b Rework vvp file version checking. 2015-08-17 15:38:27 -07:00
Martin Whitaker be44289fc0 Updated a few more copyright dates. 2015-08-17 22:23:43 +01:00
Martin Whitaker e682166253 Fix for br991 - compiler crashes due to null statements.
The reported problem was caused by a null statement in a case statement,
which caused the check for an infinite loop to fail. Further testing
exposed more problems with null statements in loop statements - these
caused crashes earlier in elaboration.
2015-08-17 22:19:36 +01:00
Larry Doolittle e2a1f21896 Squelch just a few trailing spaces in source code 2015-08-17 11:44:55 -07:00
Larry Doolittle cb73accd84 Spelling fixes 2015-08-17 11:34:58 -07:00
Stephen Williams a66361a4f2 Update some copyright dates. 2015-08-17 08:02:51 -07:00
Martin Whitaker 1159de0482 Fixed version number in vvp man page. 2015-08-16 23:11:54 +01:00
Stephen Williams ac5d4114ad Update v10 vvp examples to have correct version number 2015-08-16 12:30:43 -07:00
Stephen Williams 85f796fda2 Release compatible version stamp 2015-08-15 14:26:33 -07:00
Stephen Williams 8612ec5452 Main copyright date update. 2015-08-15 14:15:32 -07:00
Stephen Williams 870a351944 Change Version numbering scheme. 2015-08-15 13:42:57 -07:00
Maciej Suminski 434bf0fe46 Fixed vhdlpp bison conflicts. 2015-08-12 11:43:09 -07:00
Stephen Williams 5147105042 Merge pull request #76 from orsonmmz/fixes
Fixes for br985, br986, br987
2015-08-11 10:40:59 -07:00
Maciej Suminski fc2139f01c vhdlpp: Allow sequence_of_statements to be empty.
Fix for br987.
2015-08-09 19:45:44 +02:00
Maciej Suminski 775904ab0f vhdlpp: ExpName::elaborate_rval accepts enum values.
Fix for br986.
2015-08-09 18:48:59 +02:00
Maciej Suminski 0ae3414ec5 vhdlpp: ExpUnary::elaborate_expr() elaborates its operand as well.
Fix for br985.
2015-08-09 18:48:15 +02:00
Maciej Suminski f3321126ed vhdlpp: Fixed a problem with types defined as an array of arrays. 2015-08-09 16:43:04 +02:00
Martin Whitaker 428f059c58 Fix shadow warning introduced by MVSE 2015 hacks. 2015-08-07 23:05:02 +01:00
Martin Whitaker e98bcb61bb Fix for br988 - support begin/end blocks nested inside generate blocks.
This is syntax permitted in 1364-2001 but removed in 1364-2005.

Also update the iverilog man page to document the anachronisms warning
class that warns about use of this feature when a later generation is
selected.
2015-08-07 22:46:09 +01:00
Martin Whitaker 5facf243cd Fix for br990 - handle empty expression in parameter assignment by name. 2015-08-07 21:11:07 +01:00
Martin Whitaker 853f119d83 Fix for br989 - unsupported attributes are not fatal.
The compiler was emitting a "sorry" message and aborting compilation when
it encountered attributes on a wire declaration/assignment. Change this
to a warning, as most attributes are ignored anyway.
2015-08-05 18:22:25 +01:00
Larry Doolittle 3e2196651a Remove unused parameter to indices_to_expressions
need_addr has been hanging around, unused, since commit 078a3fd4 on Jan 17, 2014.
2015-07-31 09:48:33 -07:00
Stephen Williams 64b72cf7e1 Clean up MCS/GNU portability hacks in header files. 2015-07-23 17:35:31 -07:00
Frederick C. Kurz d766e82aa1 Changes for vvp/vvp_net.h
"# include  <string>" was added so "Microsoft Visual Studio Express 2015 RC Web" could compile it without error. "static void operator delete[](void*); was preprocessed so "Microsoft Visual Studio Express 2015 RC Web" could link it without error for a function not yet implemented.
2015-07-22 18:02:52 -07:00
Frederick C. Kurz c35f2f8334 Changes to vvp/vthread.cc
"child->delay_delete = 1;" was added, for when building with "Microsoft Visual Studio Express 2015 RC Web" in DEBUG mode, so that pr2909555.v would pass with -strict, otherwise it would cause memory access error will trying to access the previously deleted "child" variable.
2015-07-22 18:02:45 -07:00
Frederick C. Kurz afd225a44d Changes to vvp/vpi_vthr_vector.cc
Changed for "Microsoft Visual Studio Express 2015 RC Web" so gold files would match.
2015-07-22 18:00:59 -07:00
Frederick C. Kurz b36a0a2c54 Changes to vvp/vpi_signal.cc
Changed the #ifdef structure so "Microsoft Visual Studio Express 2015 RC Web" could compile it without error.
2015-07-22 17:56:58 -07:00
Frederick C. Kurz a3728dcf20 Changes to vvp/vpi_mcd.cc
Changed for"Microsoft Visual Studio Express 2015 RC Web" so vpi/pr723.v would pass.
2015-07-22 17:56:20 -07:00
Frederick C. Kurz 4cf4cdabcd Changes to vhdlpp/expression.cc
Changed for "Microsoft Visual Studio Express 2015 RC Web" for runtime memory access violation for vhdl_test4.vhd.
2015-07-22 13:19:50 -07:00
Frederick C. Kurz 5f906369b5 Changes to vvp/vpi_callback.cc
Changed for"Microsoft Visual Studio Express 2015 RC Web" so gold files would match.
2015-07-22 10:10:32 -07:00
Frederick C. Kurz 12f4d29df3 Changes to vvp/class_type.cc
Changed for "Microsoft Visual Studio Express 2015 RC Web" so sv_class14.v would pass without runtime memory error.
2015-07-22 10:06:19 -07:00
Frederick C. Kurz 5e931b7e89 Changes to vpi/v2009_array.c
"Microsoft Visual Studio Express 2015 RC Web" cannot have a variable for the size when declaring an array, it won't compile.
2015-07-22 10:02:33 -07:00
Frederick C. Kurz 11d7cbd3e2 Changes to vpi/sys_fileio.c
Changed for "Microsoft Visual Studio Express 2015 RC Web" so running vvp on pr2800985a.v won't crash.
2015-07-22 09:53:42 -07:00
Frederick C. Kurz 7aff1adf99 Changes to vpi/sys_display.c
First and second areas were changed for "Microsoft Visual Studio Express 2015 RC Web" so that gold files would match.  For the third area of change, "Microsoft Visual Studio Express 2015 RC Web" wanted to print 6 zeros after the decimals for the values of 0.0 and -0.0, and then the gold files wouldn't match.
2015-07-22 09:48:01 -07:00
Frederick C. Kurz 093e7eb2c8 Changes to netlist.h
Changes so "Microsoft Visual Studio Express 2015 RC Web" could build it without a bunch of runtime errors and crashes during regression testing.  When declaring an bitfield variable of type enum in a struct, the enum has to have an underlying integer type for MSVC++ when compiling a C++ file, and for these cases, it had to be unsigned integer for everything to work okay during regression testing.
2015-07-22 09:39:58 -07:00
Frederick C. Kurz 82d46a5e1a Changes to ivl_target.h
Changes so "Microsoft Visual Studio Express 2015 RC Web" could build it without a bunch of runtime errors and crashes during regression testing.  When declaring an bitfield variable of type enum in a struct, the enum has to have an underlying integer type for MSVC++ when compiling a C++ file, and for these cases, it had to be unsigned integer for everything to work okay during regression testing.
2015-07-22 09:23:48 -07:00
Frederick C. Kurz fc976bdb97 Changes for pform.cc
First area of Change for "Microsoft Visual Studio Express 2015 RC Web" was for compiling with error when NDEBUG defined.  The second and third areas of change for "Microsoft Visual Studio Express 2015 RC Web", the dynamic_cast has to come first so parpkg_test.v, parpkg_test1.v, parpkg_test2.v would pass.
2015-07-22 09:22:26 -07:00
Frederick C. Kurz 9f7995f648 Changes for ivl_alloc.h
Changed so "Microsoft Visual Studio Express 2015 RC Web" could compile it without error.
2015-07-22 09:14:24 -07:00
Frederick C. Kurz 9bcafe39c6 Changes to elab_type.c
Changes for "Microsoft Visual Studio Express 2015 RC Web" to first check for a dereferencable iterator so pr1741212.v, and many others, will pass with a DEBUG build.
2015-07-22 09:09:47 -07:00
Cary R 9635f031a1 Correctly display events when dumping using the FST format
This patch is from Tony Bybell and fixes a segmentation fault when dumping
an event to a FST file.
2015-07-22 00:30:13 -07:00
Martin Whitaker e6be9dec08 Improve error reporting for unnamed module ports.
Implicit ports may be unnamed, either because the port expression
is not a simple/escaped identifier, or because there is no port
expression. To handle these cases, error messages should report
the port position as well as the port name.
2015-07-10 23:02:27 +01:00
Martin Whitaker 97c6339241 Ensure VPI release on net connected to island returns correct value. 2015-07-01 09:00:43 +01:00
Martin Whitaker 8d2149f5aa Further fix for GitHub issue #73 - also handle part selects. 2015-06-30 23:59:00 +01:00
Martin Whitaker e8225bd39e Fix for GitHub issue #73 - allow for island ports in vpi_put_value.
In the special case that a net is attached to an island port, values
driven onto the net via the VPI must go to the functor, not the filter,
so that they propagate through the island.
2015-06-30 21:50:13 +01:00
Stephen Williams 935ee6137d Merge pull request #71 from orsonmmz/procedure_calls
Procedure calls
2015-06-30 08:27:51 -07:00
Martin Whitaker 586e415d96 Allow macro arguments to be omitted when default values are available.
SystemVerilog allows fewer actual arguments than formal arguments when
all remaining formal arguments have default values.
2015-06-27 19:02:02 +01:00
Martin Whitaker 637fc40dd9 Fix various bugs in vpi_put_value.
When putting a value onto a wire, the value needs to be sent to the
filter, not the functor (the functor may be part of the expression
that drives the wire).

Force and release weren't implemented properly (or at all in the
case of real values). They need to behave the same as the force
and release operations in vthread.cc.
2015-06-26 08:49:41 +01:00
Martin Whitaker 05a52e55e9 Create a BUFZ to drive the 0.0 value onto an undriven real wire.
This is needed to allow forced values to propagate correctly.
2015-06-26 00:45:00 +01:00
Martin Whitaker 59c211d20c Fix stub target to handle real valued constants. 2015-06-26 00:41:43 +01:00
Martin Whitaker dad223316e Fix propagation of unforced bits when forcing a part select.
vvp_net_t::force_vec4 propagates all bits of the forced value passed
to it, regardless of the mask value. I can't see any way to fix this
directly, so instead make sure anything that calls force_vec4 sets
the unforced bits of the passed value to the correct value.
2015-06-25 00:13:57 +01:00
Maciej Suminski df597e19cb vhdlpp: Removed conversion of '*_edge(sig)' to 'always begin..end @(*edge sig)'. 2015-06-24 23:53:33 +02:00
Maciej Suminski 7597270939 vhdlpp: Fixed $ivlh_rising/falling_edge().
Conditions to detect rising/falling edges were incorrect.
VHDL standard specifies it has to detect the current value,
rather than compare against the previous one.
2015-06-24 23:53:33 +02:00
Maciej Suminski 5509b3c7a5 vhdlpp: Enums are based on integer type.
This way than can be used as output ports.
2015-06-24 23:53:33 +02:00
Maciej Suminski 49253c43ba vhdlpp: Do not emit reg/wire prefix for enums. 2015-06-24 23:53:33 +02:00
Maciej Suminski 311ffb27f2 ivl: Enum output ports are implicit regs when based on 'logic' type. 2015-06-24 23:53:33 +02:00
Maciej Suminski f0fd73e146 ivl: Array querying functions ($left, $low, etc.) for localparams. 2015-06-24 23:53:33 +02:00
Maciej Suminski 5858e1bbac vhdlpp: ExpName::probe_type() checks Subprogram parameters. 2015-06-24 23:53:33 +02:00
Maciej Suminski 95044d9ac7 vhdlpp: VType::type_match() checks definitions provided by VTypeDef. 2015-06-24 23:53:33 +02:00
Maciej Suminski c6f934964f vhdlpp: NOT is translated to either ~(...) or !(...) depending on the argument type. 2015-06-24 23:53:32 +02:00
Maciej Suminski 6f867d6f01 vhdlpp: Changed 'char' to 'byte'. 2015-06-24 23:53:32 +02:00
Maciej Suminski e6b57910a4 vhdlpp: ScopeBase::is_enum_name checks enums from standard libraries. 2015-06-24 23:53:32 +02:00
Maciej Suminski cc9b182eb6 vhdlpp: Procedure calls. 2015-06-24 23:53:32 +02:00
Maciej Suminski d39f692cfd vhdlpp: Refactored the way of handling standard types. 2015-06-24 23:53:32 +02:00
Maciej Suminski b666b9c0bf vhdlpp: Fixed a few memory leaks. 2015-06-24 23:53:32 +02:00
Maciej Suminski b3c1fa3e85 vhdlpp: Elaborate prefix & indices for ExpName. 2015-06-24 23:53:32 +02:00
Maciej Suminski 169228ad0f vhdlpp: Refactored the way of handling standard VHDL library functions. 2015-06-24 23:53:31 +02:00
Maciej Suminski 356a09d295 vhdlpp: VTypeArray::evaluate_ranges uses range boundaries to determine the direction. 2015-06-24 23:53:31 +02:00
Maciej Suminski 47c5ce0ab6 vhdlpp: Subprogram split to SubprogramHeader and SubprogramBody. 2015-06-24 23:53:31 +02:00
Maciej Suminski 3c437874e2 vhdlpp: Allow initializers for variables. 2015-06-24 23:53:31 +02:00
Maciej Suminski c28000c55f vhdlpp: Support for selected assignments. 2015-06-24 23:53:31 +02:00
Maciej Suminski 5a0d967682 vhdlpp: More renaming in ExpConditional. 2015-06-24 23:53:31 +02:00
Maciej Suminski 49efe6573c vhdlpp: Minor ExpConditional refactoring.
Merged cond_ and true_clause_ to else_clause_ list to make
code more generic.
2015-06-24 23:53:31 +02:00
Maciej Suminski ea12c0fe23 vhdlp: Renamed ExpConditional::else_t to ExpConditional::option_t. 2015-06-24 23:53:31 +02:00
Martin Whitaker 44dfc41004 Detect and report excess function arguments.
Also enhance a couple of error messages.
2015-06-21 09:07:11 +01:00
Martin Whitaker bdd0657140 Reject default task/function arguments when parsing traditional Verilog. 2015-06-21 09:05:39 +01:00
Martin Whitaker 1d279798d8 Fix for br982 - detect and report missing output arguments in task calls. 2015-06-20 22:39:55 +01:00
Martin Whitaker 0e66e9781a Add support for non-constant default subroutine arguments.
Input ports only at the moment. Output "sorry" message for other
port types.
2015-06-20 21:39:45 +01:00
Larry Doolittle b23faff27c Just a few more spelling fixes
Includes some user-visible messages
2015-06-17 08:09:34 -07:00
Martin Whitaker b242663cae Support negedge flip-flops in synthesis and in vvp.
Also extend the support for FF asynchronous set values to vvp and
fix the dff functor in vvp to correctly model asynchronous set/clr
behaviour.
2015-06-13 16:47:57 +01:00
Martin Whitaker d39c284055 Observe and propagate failures when synthesising lval concatenations. 2015-06-13 16:47:57 +01:00
Stephen Williams 6a73de0c43 Merge pull request #70 from orsonmmz/time
Time expressions for vhdlpp
2015-06-08 16:17:40 -07:00
Martin Whitaker e0cdd71984 Minor cleanup and simplification of aset_value changes. 2015-06-08 21:20:49 +01:00
Johann Klammer 81e1735959 establish support for aset_value and reorder clauses so vlog95 doesn't fail anymore. 2015-06-08 20:34:50 +01:00
Johann Klammer 3fb65eb51a single bit reset 2015-06-08 20:34:43 +01:00
Martin Whitaker 3080f5730d Better implementation of assignment lval concatenation synthesis. 2015-06-08 20:27:38 +01:00
Maciej Suminski 29ddd5208f vhdlpp: 'wait on' and 'wait until' statements. 2015-06-08 18:42:52 +02:00
Maciej Suminski 4a31f36646 vhdlpp: Minor code cleaning. 2015-06-08 18:42:52 +02:00
Maciej Suminski 1f1d47887e vhdlpp: Visitor for Expression class. 2015-06-08 18:42:52 +02:00
Maciej Suminski 80403d2ade ivl: Disabled reg_flag for time type in SV. 2015-06-08 18:42:52 +02:00
Maciej Suminski cd3180d1c2 ivl: TIME_LITERAL added as a primary expression. 2015-06-08 18:42:52 +02:00
Maciej Suminski 68f8007fc4 vhdlpp: 'wait for' statement. 2015-06-08 18:42:52 +02:00
Maciej Suminski d6ff1946f9 vhdlpp: Support for time expressions. 2015-06-08 18:42:52 +02:00
Martin Whitaker 4068c172f4 Fix overzealous detection of duplicate net/variable declarations.
As reported by Larry Doolittle on iverilog-devel.
2015-06-07 08:48:33 +01:00
Stephen Williams 9ac9f1c9f2 Merge branch 'master' of github.com:steveicarus/iverilog 2015-06-04 15:11:29 -07:00
Larry Doolittle 2739f83702 Spelling fixes in C and C++ comments 2015-06-04 15:00:29 -07:00
Cary R 7af3280215 Update cppcheck suppression file in VPI 2015-06-04 09:50:08 -07:00
Stephen Williams 05d591ccd6 Fix broken write to log files. 2015-06-03 14:32:04 -07:00
Stephen Williams fbedf4ae22 Snapshot 2015-06-03 2015-06-03 11:16:07 -07:00
Stephen Williams e6c6f6c81e Use fwrite to write $display output, instead of fprintf
This change makes it safe to write non-ascii characters, which
is an issue when the %u format is used.
2015-06-03 10:00:35 -07:00
Larry Doolittle 33c651aa00 Spelling fixes in .txt files 2015-05-25 12:52:03 -07:00
Stephen Williams 358bb4d5d9 Merge branch 'master' of github.com:steveicarus/iverilog 2015-05-25 12:51:20 -07:00
Martin Whitaker d5b41853fd Fix for br979 part 2 - handle blank lines in macro definition continuation. 2015-05-22 18:44:25 +01:00
Martin Whitaker 0fc10e3e70 Fix for br979 part 1 - strip leading/trailing space from macro actual args.
Although the IEEE standard doesn't explicitly state this is required,
the examples added in the SystemVerilog standard show that this is
expected.

Also add a preprocessor lexical rule to recognise `` inside a macro
definition when it is not immediately followed by an identifier.
2015-05-22 18:11:24 +01:00
Martin Whitaker ab688613cc Fix for br978 - assertion involving addition of $ivlh_to_unsigned() result.
$ivlh_to_unsigned, unlike $signed and $signed, can cause a reduction
in width. The shared PECallFunction::cast_to_width_ method did not
support this.
2015-05-22 00:05:39 +01:00
Stephen Williams 79042e38ad Merge branch 'master' of github.com:steveicarus/iverilog 2015-05-21 10:05:37 -07:00
Stephen Williams ced9759c65 Merge pull request #69 from orsonmmz/fixes
Various fixes
2015-05-21 10:05:26 -07:00
Stephen Williams 8f22998447 Merge branch 'master' of github.com:steveicarus/iverilog 2015-05-21 09:58:36 -07:00
Maciej Suminski 51d7237d52 vhdlpp: Display error message for undefined generic values. 2015-05-21 01:25:34 +02:00
Maciej Suminski 7aab315ce5 vhdlpp: Allow assigning values to inout ports. 2015-05-20 17:30:07 +02:00
Maciej Suminski bc83d2914a vhdlpp: Corrected an error message for attributes. 2015-05-20 14:23:57 +02:00
Maciej Suminski bb2e6782fa Copy constructor for LineInfo. 2015-05-19 22:40:56 +02:00
Larry Doolittle 9231ad51a4 vhdlpp: generics without a default value are set to 1'bx. 2015-05-19 22:40:56 +02:00
Maciej Suminski 25458b8cc2 vhdlpp: inout direction for ports. 2015-05-19 22:40:56 +02:00
Maciej Suminski 515ab40ffe vhdlpp: Special handling for string type emission. 2015-05-19 22:40:56 +02:00
Maciej Suminski ddc204391e vhdlpp: Add 'sub' prefix for subtypes while emitting packages. 2015-05-19 22:40:55 +02:00
Maciej Suminski a33bbecc98 vhdlpp: VTypeRange::write_to_stream uses to/downto depending on the range boundaries. 2015-05-19 22:40:55 +02:00
Martin Whitaker 61ace52f31 Fix vlog95 target to not output data types in port declarations.
This avoids variable redeclaration errors.
2015-05-18 23:16:53 +01:00
Martin Whitaker 71b1546a7d Fail gracefully when an unpacked struct is declared. 2015-05-17 21:59:05 +01:00
Martin Whitaker 578a2543f7 Fix for br975 - assertion failure due to duplicate declaration of struct var.
Added proper error handling for duplicate declarations of all variable
types.
2015-05-17 20:54:53 +01:00
Martin Whitaker a479bd6b16 Fix for br977 - preprocessor macros substitute text inside token.
When replacing macro formal parameters, the preprocessor should not
replace matching strings that are not complete tokens. The test for
this was incorrect, and failed when a match was found at the start
of the replacement text.
2015-05-17 20:05:45 +01:00
Martin Whitaker c75498b1d4 Add -i (interactive) option to vvp.
This forces <stdout> to be unbuffered. This is useful when using the
mintty terminal emulator in Windows (as used by MSYS2 and CygWin),
which identifies as a pipe, not a tty.
2015-05-16 00:39:03 +01:00
Martin Whitaker b6304129fa Fix for GutHub issue #64 - vvp interrupt/continue in Windows.
Windows implements the original UNIX semantics for signal(), which
means you have to re-establish the signal handler each time a signal
is caught.
2015-05-15 22:30:03 +01:00
Stephen Williams bb444b6178 Snapshot 2015-05-13 2015-05-13 10:21:19 -07:00
Stephen Williams 7442c14689 Merge pull request #67 from orsonmmz/boolean
Boolean & asserts for vhdlpp
2015-05-13 09:57:18 -07:00
Stephen Williams 0082795967 Merge pull request #61 from orsonmmz/asserts
Asserts
2015-05-13 09:56:27 -07:00
Martin Whitaker ac4f4cf1a0 Update man pages.
Removed obsolete -m32 and -ivl options from iverilog-vpi man page
and revised description of -mingw option. Also removed duplicate
descriptions of --cflags, --ldflags, and --ldlibs options. Updated
link to main iverilog web page in all man pages.
2015-05-10 13:19:51 +01:00
Martin Whitaker 676d23f973 Add extra whitespace in driver-vpi/main.c for readability. 2015-05-10 13:19:16 +01:00
Martin Whitaker 6069cbfc3c Remove outdated instructions in mingw.txt and point to the Wiki instead. 2015-05-10 12:03:58 +01:00
Martin Whitaker cfbc90812b Enable use of MinGW ANSI stdio routines.
Defining __USE_MINGW_ANSI_STDIO=1 provides C99 compatible printf
and scanf routines, which avoids the need for workarounds for the
various failings of the Microsoft C runtime library.
2015-05-10 11:45:42 +01:00
Cary R e530b4e642 Update fstapi.c to the latest from GTKWave 2015-05-08 16:36:12 -07:00
Martin Whitaker 6a3edc63d5 Fix printf format for size_t values when using 64-bit MinGW.
The Microsoft C runtime does not support the %zu and %zd formats.
Previously these were replaced with %u and %d, but for 64-bit we
need to use %llu and %lld.
2015-05-08 20:20:14 +01:00
Martin Whitaker 3069b8dd51 Simplify use of iverilog-vpi under Windows.
iverilog-vpi now automatically finds the IVL root directory,
eliminating the need for the -ivl option. Also, if the MinGW
root path hasn't been added to the registry, it now searches
the system path for it.
2015-05-08 20:15:54 +01:00
Maciej Suminski 7db01d8ded vhdlpp: ScopeBase::is_enum_name() returns VTypeEnum* instead of bool. 2015-05-07 16:28:30 +02:00
Maciej Suminski e4694cb6cb vhdlpp: Changed emitted type from 'bool' to 'bit'. 2015-05-07 16:09:02 +02:00
Maciej Suminski 08e5aa021a vhdlpp: Emits typedef for boolean type. 2015-05-07 16:09:02 +02:00
Larry Doolittle 4304fd503e vhdlpp: and_reduce() and or_reduce() functions. 2015-05-06 10:03:02 +02:00
Maciej Suminski 5438464d67 vhdlpp: Support for reports & asserts. 2015-05-06 10:02:56 +02:00
Maciej Suminski 6df2979998 vhdlpp: Added missing std_logic values in ExpChar and ExpString::emit(). 2015-05-06 09:55:08 +02:00
Maciej Suminski 9de4ced133 vhdlpp: Stop compilation on invalid attributes. 2015-05-06 09:55:08 +02:00
Martin Whitaker 45dc13e496 Use uintptr_t/intptr_t when casting between pointer and integer.
The code was using (unsigned) long, but a long is 32-bits in the
Windows 64-bit ABI.
2015-05-05 23:00:09 +01:00
Martin Whitaker 9e3f1ef1ff Only apply linker renaming of strtod() when using 32-bit MinGW.
mingw-w64 doesn't need this, and the 64-bit version doesn't support it.
2015-05-05 22:55:15 +01:00
Martin Whitaker 1b3e321d35 Eliminate a few new compiler warnings. 2015-05-04 22:32:29 +01:00
Martin Whitaker a27274aa04 Fix driver-vpi makefile to add C++ compiler flags to source code.
Also fix a few compiler warnings.
2015-05-04 22:10:29 +01:00
Martin Whitaker f1be16be7c Update PC version of iverilog-vpi to use CXXFLAGS for C++ compiles.
CFLAGS was being used for both C and C++ source files, but the
rcently added -Wstrict-prototypes flag is not valid for C++.
2015-05-04 18:40:53 +01:00
Martin Whitaker 9ac374501c Updated config.guess and config.sub.
Sourced from the config project at http://git.savannah.gnu.org. This
version correctly identifies both 32 and 64 bit versions of mingw-w64.
2015-05-04 18:40:53 +01:00
Martin Whitaker 250b278d0e Attempt to allow native line endings in Windows git checkouts.
Up to now, I've had to set git to preserve line endings when
building with MinGW. The problem seems to be gperf. Let's see
if this fixes it.
2015-05-01 22:55:19 +01:00
Cary R 52275deb0e Fix compile build failure 2015-04-30 10:18:21 -07:00
Cary R 120ad59017 Merge branch 'master' of github.com:steveicarus/iverilog 2015-04-30 10:13:10 -07:00
Cary R 2ac8a555e1 Remove bison warning and make YACC rule match the rest 2015-04-30 10:12:57 -07:00
Cary R 8d845ae49f Remove bison warning and make YACC rule match the rest 2015-04-27 16:25:40 -07:00
Martin Whitaker 352175d921 Fix for br973 - add support for enum declarations with no dimensions. 2015-04-26 12:46:08 +01:00
Martin Whitaker e78205eacf GitHub issue #60 (part 2) - warn about excessive array/vector dimensions. 2015-04-26 12:00:21 +01:00
Martin Whitaker c6e618350d Fix for GitHub issue #60 (part 1) - reject numeric constant with zero size. 2015-04-26 11:04:02 +01:00
Martin Whitaker 301a7e587b Fix for GitHub issue #62 - assertion failure on too many array/vector indices.
Provide an error message for invalid code that contains more indices than
there are dimensions.
2015-04-25 22:57:14 +01:00
Martin Whitaker 3cee5d4567 Fix br972 - assertion failure with combinational loop on logic function.
Observe the warning note on nexus_log_add! The returned pointer is only
valid until the next pin is added to the nexus.
2015-04-25 19:50:00 +01:00
Martin Whitaker e1ae5020c4 Another sorry message to catch non-constant RHS in procedural CA. 2015-04-25 11:25:33 +01:00
Martin Whitaker 22d15f9ca9 Fix handling of expression width with $ivlh_to_unsigned.
The first argument to $ivlh_to_unsigned should be treated as having
a self-determined width.
2015-04-25 09:20:31 +01:00
Larry Doolittle 19d966e235 Try to eliminate spurious -dirty in version_tag.h 2015-04-24 14:31:46 -07:00
Larry Doolittle c8fe897446 vhdlpp: and_reduce() and or_reduce() functions. 2015-04-24 13:46:30 +02:00
Maciej Suminski 5101b3b64b vhdlpp: Boolean values handled without using keywords. 2015-04-24 13:39:41 +02:00
Maciej Suminski bed5ee4529 vhdlpp: Handle 'severity' statements without using keywords. 2015-04-24 13:39:41 +02:00
Maciej Suminski 7c0a191626 vhdlpp: Handle true/false values. 2015-04-23 11:58:40 +02:00
Maciej Suminski cfa43c7742 vhdlpp: Support for reports & asserts. 2015-04-23 11:58:40 +02:00
Maciej Suminski a5138e238f vhdlpp: Added missing std_logic values in ExpChar and ExpString::emit(). 2015-04-23 11:57:27 +02:00
Maciej Suminski d352d8ead3 vhdlpp: Stop compilation on invalid attributes. 2015-04-23 11:57:27 +02:00
Cary R 02ee3874e7 Space/code cleanup and warn that vvp does not support S/R D-FF 2015-04-20 15:41:44 -07:00
Johann Klammer f9fef5d00b driven_mask... 2015-04-20 15:11:52 -07:00
Johann Klammer 891399185f lhs partsel and sync scramble 2015-04-20 15:11:40 -07:00
Larry Doolittle 5dc1396eea Spelling fixes 2015-04-13 11:35:12 -07:00
Martin Whitaker ccf7c042c9 Fix null pointer dereference in debug output.
Don't display an elaborated for loop initial assignment if elaboration
has failed. Also remove duplicated message.
2015-04-13 16:31:28 +01:00
Martin Whitaker 560b9530fd Fix for br970 - iverilog silently eats warnings when comma present in -W flag.
The -W option does not (currently) support comma separated lists and
silently ignores any string that doesn't match a known warning class.
Fix by outputing a warning message when the -W argument is unknown.
2015-04-13 14:53:56 +01:00
Martin Whitaker b89c059153 Fix compiler crash on source code errors in always @* block loops.
The compiler was correctly detecting and reporting errors in loop
expressions and statements, but then crashing when it tried to build
the sensitivity list. Fix this by not adding a loop statement to the
netlist unless all its components have been successfully elaborated.
2015-04-13 14:39:10 +01:00
Cary R 8326fe843b Update format string to use correct format character 2015-04-08 19:36:33 -07:00
Cary R 1cbc38100e Update some cppcheck suppression files 2015-04-08 19:36:21 -07:00
Cary R ba31252226 Update fstapi files to latest from GTKWave 2015-04-02 14:59:38 -07:00
Stephen Williams 008affe557 Merge pull request #57 from orsonmmz/br942
bugfix #942: VHDL function bodies in arch declaration not supported
2015-04-01 08:22:03 -07:00
Maciej Suminski 0ca856d4e8 bugfix #942: VHDL function bodies in arch declaration not supported 2015-03-31 10:46:24 +02:00
Stephen Williams 2a210dfee1 Merge pull request #56 from orsonmmz/expfunc
Expfunc
2015-03-27 17:44:13 -07:00
Maciej Suminski 83d721232d ivl: $ivlh_to_unsigned() also tests its argument width. 2015-03-27 20:53:14 +01:00
Maciej Suminski d5ffb55bfd Corrected ambiguous copyright info. 2015-03-27 18:57:40 +01:00
Maciej Suminski ab9a8ccbf3 vhdlpp: Added fit_type() & probe_type() for ExpFunc. 2015-03-27 18:57:40 +01:00
Maciej Suminski e6525ec35f vhdlpp: Added a constructor for VTypeArray that takes integers as ranges. 2015-03-27 18:57:40 +01:00
Maciej Suminski afaedbd06d vhdlpp: Corrected to_integer() & resize() functions.
to_integer() handles sign and resize() really applies size casting.
2015-03-27 14:53:43 +01:00
Maciej Suminski d4237774a5 vhdlpp: Error message for missing types in VTypePrimitive::get_width(). 2015-03-27 14:53:43 +01:00
Maciej Suminski 2f2539e557 vhdlpp: Renamed a range_t constructor parameter to be more descriptive. 2015-03-27 14:53:43 +01:00
Maciej Suminski 11a86794d9 ivl: Fixed size casting. 2015-03-27 14:53:43 +01:00
Maciej Suminski 3b14797075 vhdlpp: Prefix probe for VTypeArray. 2015-03-27 14:53:43 +01:00
Martin Whitaker e006f9e132 Fix vvp crash when a part select of a wire is passed to $monitor.
When the PV expression is compiled, the parent net may not yet be
resolved, so we may not be able to get its VPI handle straight away.
2015-03-17 21:14:30 +00:00
Stephen Williams 437dc10341 Merge pull request #55 from orsonmmz/const_record
Const record
2015-03-12 10:30:56 -07:00
Cary R 102d2d534f Remove extra warning code. 2015-03-09 14:35:31 -07:00
Cary R 5e437145bf A SV queue can be signed. 2015-03-07 18:07:00 -08:00
Maciej Suminski d1dc98b7f7 vhdlpp: Changed the workaround for accessing localparam arrays & records. 2015-03-07 20:47:20 +01:00
Cary R 50b45dac7b Update queue push front/back code generation 2015-03-06 16:56:22 -08:00
Maciej Suminski 295e4e7dfb vhdlpp: Fixed crash on unassociated generics. 2015-03-06 20:39:10 +01:00
Maciej Suminski 807ad8002d vhdlpp: Check generics when searching through constants. 2015-03-06 20:39:10 +01:00
Maciej Suminski d3229b9068 vhdlpp: 'string' type is emitted as 'string' instead of 'array <> of character'. 2015-03-06 17:58:04 +01:00
Maciej Suminski 099bb427bc vhdlpp: ComponentBase::write_to_stream() saves generics. 2015-03-06 17:58:04 +01:00
Maciej Suminski d406545331 vpi: $ivlh_{rising,falling}_edge functions. 2015-03-06 17:58:04 +01:00
Maciej Suminski 1de3fb1625 vhdlpp: "resize" function. 2015-03-06 17:58:04 +01:00
Maciej Suminski e33b8b4dde vhdlpp: VType::get_width() uses information from Scope to determine the type width. 2015-03-06 17:58:04 +01:00
Maciej Suminski 9128eb67b9 vhdlpp: Evaluates attributes if possible. 2015-03-06 17:32:25 +01:00
Maciej Suminski afbda099fb vhdlpp: Workaround to handle constant arrays of vectors & records. 2015-03-06 17:32:25 +01:00
Maciej Suminski 4b0d220671 vhdlpp: get_width() for VType. 2015-03-06 17:32:25 +01:00
Maciej Suminski a42b056b24 vhdlpp: Alternative way of accessing constant arrays of vectors. 2015-03-06 17:32:25 +01:00
Maciej Suminski 1852c5ab9d Revert "vhdlpp: Support for accessing words in constant arrays."
This reverts commit 9ca754b6db.
2015-03-06 17:32:25 +01:00
Cary R 24be13d825 Add support for SV strings to the scanf routines 2015-03-03 17:13:16 -08:00
Cary R bddfcac823 The === and !== operators cannot be used with a SV string 2015-03-02 15:34:22 -08:00
Cary R ea1c07e234 A dynamic array can have a signed type so pass that correctly 2015-03-02 14:40:38 -08:00
Cary R 8e0ae733ca Add support for a SV string to $swrite and $sformat 2015-02-28 11:46:58 -08:00
Cary R feb710a186 Add support for any width 2-state darray objects 2015-02-27 11:43:25 -08:00
Cary R 62abb199d7 Add support for 4-state dynamic arrays 2015-02-26 17:56:49 -08:00
Cary R 7373bf2224 Merge branch 'master' of github.com:steveicarus/iverilog 2015-02-25 19:21:00 -08:00
Cary R ae629f8c41 Add ability to put a string value to a SV string (from plusargs) 2015-02-25 19:20:50 -08:00
Stephen Williams 03e0e96832 Merge branch 'master' of github.com:steveicarus/iverilog 2015-02-25 17:54:24 -08:00
Larry Doolittle 3c38b2972d Add -Wstrict-prototypes to CFLAGS
... and patch vpi/sys_lxt.c so no new warnings are triggered.
2015-02-25 17:52:44 -08:00
Larry Doolittle 4f1fc6e302 Add -Wstrict-prototypes to CFLAGS
... and patch vpi/sys_lxt.c so no new warnings are triggered.
2015-02-25 17:48:38 -08:00
Cary R f1436fbe62 Update fstapi.h to latest from GTKWave 2015-02-25 17:40:18 -08:00
Stephen Williams a79533ddc9 Merge pull request #54 from orsonmmz/const_array
Update
2015-02-20 10:49:53 -08:00
Stephen Williams d47afb588b Merge pull request #52 from orsonmmz/unbounded_function
Unbounded vectors in VHDL functions.
2015-02-20 10:36:19 -08:00
Stephen Williams 386774ac19 Work towards handing packed arrayed members. 2015-02-19 20:02:15 -08:00
Maciej Suminski 9ca754b6db vhdlpp: Support for accessing words in constant arrays. 2015-02-19 17:07:41 +01:00
Maciej Suminski 0f0bef32f2 vhdlpp: Architecture elaboration counts errors coming from expression elaboration. 2015-02-19 17:07:41 +01:00
Maciej Suminski cd55f30a27 vhdlpp: Minor change to ScopeBase::find_constant(). 2015-02-19 17:07:41 +01:00
Maciej Suminski 5884879b02 vhdlpp: to_integer() function. 2015-02-19 17:07:41 +01:00
Maciej Suminski a1a4f47894 vhdlpp: Unnecessary comment. 2015-02-19 17:07:41 +01:00
Maciej Suminski e569e07d4e vhdlpp: Type 'NATURAL' is translated to 'int unsigned'. 2015-02-19 17:07:41 +01:00
Maciej Suminski ee840391d6 vhdlpp: std_logic_vector, signed & unsigned are considered global types. 2015-02-19 17:07:41 +01:00
Maciej Suminski 0046e9eca0 vhdlpp: ActiveScope::is_vector_name() checks also for constants. 2015-02-19 17:07:41 +01:00
Maciej Suminski f51c037432 vhdlpp: Generics from external packages are accepted (warning instead of error). 2015-02-19 17:07:37 +01:00
Maciej Suminski 763c6fe3c9 vhdlpp: Support for shift operators (SRL, SRR, SRA, SLA).
To be done: ROR & ROL.
2015-02-17 10:15:57 +01:00
Maciej Suminski 49b6ddf93c vhdlpp: Signal/variable assignments can have labels. 2015-02-17 10:15:57 +01:00
Maciej Suminski 12b4914b63 vhdlpp: ExpName resolves enum values. 2015-02-17 10:15:57 +01:00
Maciej Suminski fc0728ab6f vhdlpp: Forward typedefs.
It was required to make it possible to use typedefs in port types.
Types from packages are emitted in `ifdef..`endif instead of package..endpackage.

The purest solution is to keep package..endpackage and emit appropriate prefix.
Also, it would be great to have constants emitted in the same way.
2015-02-17 10:15:57 +01:00
Maciej Suminski 46c41f9be2 ivl: Enum type can be used in port declarations. 2015-02-05 17:17:33 +01:00
Maciej Suminski cdf18de10e vhdlpp: Make integer expressions sized during the emission step. 2015-02-05 16:20:49 +01:00
Maciej Suminski 19ff6a434b vhdlpp: Alternative way of dealing with unbounded vectors in fuctions (instances). 2015-02-05 12:00:25 +01:00
Maciej Suminski 5349ca9a55 vhdlpp: Added Subprogram::write_to_stream_body() method. 2015-02-05 12:00:25 +01:00
Maciej Suminski 5b7b980ead vhdlpp: Support for multiple choices in case statements. 2015-02-05 12:00:25 +01:00
Maciej Suminski a1c2a8e605 vhdlpp: Generic syntax errors display messages. 2015-02-05 11:25:03 +01:00
Maciej Suminski 8777cd8e7c vhdlpp: Fixed ExpBitstring & ExpRelation write_to_stream() method. 2015-02-05 11:25:03 +01:00
Maciej Suminski 11bb7ac348 vhdlpp: Expression::write_to_stream becomes const. 2015-02-05 11:25:03 +01:00
Maciej Suminski 9de69f2f24 vhdlpp: SequentialStmts write_to_stream() methods. 2015-02-05 11:25:03 +01:00
Maciej Suminski dae3410dcd vhdlpp: Variable::write_to_stream(). 2015-02-05 11:25:03 +01:00
Maciej Suminski 1a367c84b6 vhdlpp: Subprograms can have instances that take a different set of parameter types. 2015-02-05 11:25:03 +01:00
Maciej Suminski 8a854affa6 vhdlpp: Clone routines for Expression & VType classes. 2015-02-05 11:25:03 +01:00
Maciej Suminski 60077f4f06 vhdlpp: ExpBitstring elaborate_expr(). 2015-02-05 11:25:03 +01:00
Maciej Suminski 51ce9f1a60 vhdlpp: Minor correction for casting to integer. 2015-02-05 11:25:03 +01:00
Maciej Suminski 48265ecd9b vhdlpp: Subprograms return types have their ranges evaluated if possible.
Added VTypeArray::evaluate_ranges() method.
2015-02-05 11:24:59 +01:00
Maciej Suminski abbcea64d0 vhdlpp: Array attributes can be evaluated in packages/functions. 2015-02-04 16:57:43 +01:00
Maciej Suminski 25c3798248 vhdlpp: Elaborate and emit functions work with ScopeBase instead of Architecture. 2015-02-04 16:57:43 +01:00
Maciej Suminski 90293d8e0a vhdlpp: VTypeArray::is_variable_length() uses ScopeBase to determine if variable has constant length. 2015-02-04 16:57:43 +01:00
Maciej Suminski 621cf37339 vhdlpp: Added ScopeBase::find_param() method. 2015-02-04 16:57:43 +01:00
Maciej Suminski 6d75af86e6 vhdlpp: Added Subprogram::fix_variables() method. 2015-02-04 16:57:43 +01:00
Maciej Suminski 5d26f0e28d vhdlpp: Added VTypeArray::is_variable_length() method. 2015-02-04 16:57:43 +01:00
Maciej Suminski 774609fbbb vhdlpp: VTypeArray stores parent type, in case it is a subtype. 2015-02-04 16:57:43 +01:00
Maciej Suminski 9ba7694484 vhdlpp: Minor assert. 2015-02-04 16:57:43 +01:00
Maciej Suminski 870a826225 vhdlpp: Corrected VTypeDef::emit_def() to allow typedefed names in function headers. 2015-02-04 16:57:43 +01:00
Maciej Suminski 2ecfed0baa vhdlpp: Moved part of check_unb_vector() to fix_logic_darray(). 2015-02-04 16:57:43 +01:00
Maciej Suminski 56e410f386 vhdlpp: SigVarBase::peek_name_() method made public. 2015-02-04 16:57:43 +01:00
Maciej Suminski d4dd635bf6 vhdlpp: Added ExpNew class. 2015-02-04 16:57:43 +01:00
Maciej Suminski c287281bbe vhdlpp: Tries to determine if function return type is fixed size.
Added Subprogram::fixed_return_type() method.
2015-02-04 16:57:43 +01:00
Maciej Suminski 962330f20a vhdlpp: Functions support unbounded vectors as return type and parameters. 2015-02-04 16:57:43 +01:00
Maciej Suminski 777e7e0a3d vhdlpp: Added ExpFunc::func_ret_type() method. 2015-02-04 16:57:43 +01:00
Maciej Suminski 839f9cd7ae vhdlpp: Added ReturnStmt::cast_to() method. 2015-02-04 16:57:43 +01:00
Maciej Suminski b8b2f53027 vhdlpp: Added VType::get_generic_typename() method. 2015-02-04 16:57:43 +01:00
Maciej Suminski 9b3bd039bb vhdlpp: Added ExpCast class. 2015-02-04 16:57:42 +01:00
Maciej Suminski 51b9191021 vhdlpp: Added VType::is_unbounded() method. 2015-02-04 16:57:42 +01:00
Maciej Suminski 756c9ceccf ivl: Functions returning a dynamic array may be casted to vector. 2015-02-04 16:02:38 +01:00
Maciej Suminski 8b3667f76e ivl: Casting vectors to dynamic arrays. 2015-02-04 16:02:38 +01:00
Maciej Suminski a52242745a ivl: Casting dynamic arrays to vectors. 2015-02-04 16:02:38 +01:00
Maciej Suminski ff5b696569 vhdlpp: Improved SequentialStmt visitor. 2015-02-04 16:02:38 +01:00
Maciej Suminski b05a19dffc vhdlpp: VTypeArray emits dimensions in a bit smarter way. 2015-02-04 16:02:38 +01:00
Maciej Suminski e6b22a2bea vhdlpp: Visitor for SequentialStmt. 2015-02-04 16:02:38 +01:00
Maciej Suminski a02ebc3114 $ivl_darray_method$[from/to]_vec works with constants. 2015-02-04 16:02:38 +01:00
Maciej Suminski 0592ba042e vhdlpp: For-loop emission rewritten to handle 'range in subprograms. 2015-02-04 16:02:38 +01:00
Maciej Suminski bcca3cf395 ivl: Unpacked array typedefs are correctly recognized when used in function parameters. 2015-02-04 15:58:12 +01:00
Cary R 01ba41afd8 Only skip zero repeat expressions in a concatenation. 2015-02-02 18:15:12 -08:00
Cary R 84c592b068 Fix white space issue 2015-02-02 15:29:25 -08:00
Cary R bb93a585b6 Generate correct vvp code for zero replication cases 2015-02-02 15:27:57 -08:00
Cary R 47688d234b Assert if an unsupported dynamic array type is given. 2015-01-16 18:54:43 -08:00
Cary R b3425d6cf3 Report that 4-state dynamic arrays are not currently supported in vvp
Also fix some error code propagation issues.
2015-01-16 18:22:16 -08:00
Cary R 40ae1051d4 Report the vvp only supports a dynamic array of size 8, 16, 32 or 64 2015-01-15 18:18:14 -08:00
Cary R 21c60b38e1 Fix space issues in the code. 2015-01-15 17:47:39 -08:00
Cary R 78c6b3cad2 More updates for sys_darray.c (fix 32-bit crash and optimize) 2015-01-15 17:44:13 -08:00
Cary R a04104077f Update top level cppcheck suppression file 2015-01-15 17:37:26 -08:00
Cary R 0e3a758894 Some cleanup of the calltf functions in sys_darray.c 2015-01-14 22:22:02 -08:00
Cary R d682029240 Update compiletf routines in sys_darray to be more exact 2015-01-14 19:58:42 -08:00
Cary R 1ffcd40336 Fix a clear word to be after it has been used 2015-01-14 19:48:24 -08:00
Cary R 09439c55ab Add new object to the vpi_get_str(vpiType, handle) code. 2015-01-14 19:08:00 -08:00
Cary R c858dea2d5 Fix compile warning (remainder is a global) 2015-01-14 17:22:27 -08:00
Cary R 228a3f123a For some local nets fix the local flag and file/line information 2015-01-14 16:40:30 -08:00
Cary R 074f7a7a49 Fix undefined access in for loop synthesis 2015-01-14 15:11:36 -08:00
Stephen Williams f642313e1b Merge pull request #50 from orsonmmz/darray
Unpacked arrays extension
2015-01-12 14:08:22 -08:00
Stephen Williams dd9d96eb07 Merge branch 'master' of github.com:steveicarus/iverilog 2015-01-12 09:24:07 -08:00
Maciej Suminski 35401f0e2c ivl: Functions may return dynamic arrays. 2015-01-12 11:08:31 +01:00
Maciej Suminski b6e16aea6b ivl: Typedefs may use unpacked arrays. 2015-01-12 11:08:31 +01:00
Maciej Suminski eeaf23041b vvp: Support for dynamic arrays of logic type. 2015-01-12 11:08:31 +01:00
Maciej Suminski e8096eda80 ivl: Support for unpacked arrays of structures. 2015-01-12 11:08:31 +01:00
Maciej Suminski 961d6a8f3b vpi: $left and $right functions for arrays and strings. 2015-01-12 11:08:31 +01:00
Maciej Suminski 288ebf011c vpi: Moved $ivl_darray_method$[from/to]_vec to sys_darray.c 2015-01-12 11:08:31 +01:00
Maciej Suminski 0ae304b6a8 vpi: Added $ivl_darray_method$from_vec.
Converts a vector to dynamic array of vectors.
2015-01-12 11:08:31 +01:00
Maciej Suminski 5e61bb64b7 vpi: Added $ivl_darray_method$to_vec.
Converts a dynamic array of vectors to a single vector.
2015-01-12 11:08:31 +01:00
Cary R 3f847fd927 Fix a compile warning 2015-01-10 16:28:55 -08:00
Cary R 4a41a53b42 For valgrind clean up the class definitions at the end. 2015-01-10 16:18:59 -08:00
Martin Whitaker a1630e1d30 Fix for br968.
__vpiVThrVec4Stack::vpi_get_value_int_ was always treating the thread variable
as unsigned, rather than observing the value of __vpiVThrVec4Stack::signed_flag_.
Not sure why this was done - none of the regression tests broke when I changed
this.
2015-01-10 17:24:50 +00:00
Martin Whitaker bca84d9dbb Added parser support for SV modport declarations. 2015-01-10 11:10:41 +00:00
Cary R e61ed48914 Clean up vals_words when a dynamic array is accessed using the vpi 2015-01-09 17:38:39 -08:00
Cary R d29a6d134f Fix valgrind cleanup of dynamic and queue arrays 2015-01-09 15:05:48 -08:00
Cary R 6310b47538 Fix a memory leak when searching for an element by name 2015-01-08 16:14:20 -08:00
Cary R 9c75a4b96b Fix a memory leak when the dump file cannot be opened 2015-01-08 16:14:08 -08:00
Cary R c57e68292c Fix undefined value problem in compiler (found with valgrind) 2015-01-08 10:05:32 -08:00
Stephen Williams 0fecdcbeda Icarus Verilog snapshot 2015-01-05 2015-01-05 10:34:18 -08:00
Cary R 23ad62f317 Update cppcheck results 2014-12-28 09:27:14 -08:00
Cary R ac20008606 Update lz4 files from GTKWave 2014-12-28 09:25:54 -08:00
Stephen Williams 96d181efed Support vpiStrengthVal for vec4 stack objects. 2014-12-23 14:42:45 -08:00
Stephen Williams 18bfe7d497 Merge branch 'master' of github.com:steveicarus/iverilog 2014-12-23 13:52:48 -08:00
Stephen Williams 86562e60ba Work towards nested packed struct member vectors. 2014-12-23 13:52:38 -08:00
Martin Whitaker b400532169 Added support for interface declaration and instantiation.
modport and extern tf declarations are not yet supported.
2014-12-19 23:10:14 +00:00
Stephen Williams 6fd10dedb6 Add some implicit support for std and textio libraries
Patch submitted by Fabrizio Ferrandi.
2014-12-18 08:20:19 -08:00
Cary R c8255952a3 Update cppcheck supprression file 2014-12-16 16:47:00 -08:00
Martin Whitaker 71c4ea36e8 Pass -v compiler option to vvp in the output file shebang line.
Slightly modified version of the patch contributed by Stephan
Böttcheron iverilog-devel.
2014-12-16 21:22:19 +00:00
Martin Whitaker 5df179cd5f Implement feature request #47.
This causes vvp to evaluate all the input expressions for a user
function call before assigning any of them to the function input
variables. This stops the input variables being overwritten if
the same (non-automatic) function is used in one of the input
expressions.
2014-12-14 21:46:28 +00:00
Martin Whitaker ce5c4ca8ba Fix for br967 - allow real value for repeat statement loop length. 2014-12-13 19:50:33 +00:00
Martin Whitaker 6aa8e49b09 Add sorry message for unsupported arrays of named events. 2014-12-13 17:46:56 +00:00
Martin Whitaker f29f4ff4e3 Fix for br965.
When performing constant propagation, we need to take into account
values driven through a tran object. For now, be pessimistic, and
assume that all tran objects connect to a variable driver.
2014-12-13 12:49:13 +00:00
Cary R 3ccc59eaa3 Fix compile with valgrind hooks after vec4-stack changes 2014-12-12 14:28:07 -08:00
Martin Whitaker 0282b8450c Fix potential memory leak when a thread is disabled.
A disable statement can terminate a thread whilst it still has
local variables on the stack (e.g. the loop counter for a repeat
statement). We need to clear the thread stacks when this happens.
2014-12-11 20:10:17 +00:00
Cary R 43841af2f3 Fix a cppcheck warning and fix code style a bit 2014-12-11 09:59:15 -08:00
Cary R b2d8d41e3f Fix some cppcheck warnings in tgt-vvp 2014-12-10 16:30:55 -08:00
Cary R 0e38843ae9 Make verinum output match for either 32-bit or 64-bit systems 2014-12-10 15:11:45 -08:00
Cary R 96472e5537 For a signed R-value we can use the full width when converting to long
When trying to get the value we can use the full width of a long if the
expression is signed.
2014-12-10 14:41:27 -08:00
Cary R 48b0fed29e Use uint64_t casting of constants since UL does not work on 32-bit machines
Using a UL constant in a unit64_t context does not work on a 32-bit
machine since UL is 32-bits. Instead create uint64_t constants using
static casts and the appropriate bit operators.
2014-12-10 14:41:18 -08:00
Cary R 1efa220773 Fix non-blocking assignment to an array error state handling
If either the index or part offset expressions generate an undefined
value then the assignment is skipped. This patch reworks the code that
handles the flags used to detect this. For some simple cases a global
flag is not needed, but for other cases one is needed since there are
two expressions that can generate an error and even when there is only
a variable expression this error state needs to be preserved if there
is a variable delay. An undefined delay value defaults to zero and is
not an error.
2014-12-09 17:29:18 -08:00
Cary R 2d6622e543 vlog95: for a 32-bit width we can generate a signed undefined value 2014-12-08 21:09:36 -08:00
Cary R edf112b900 Update all the vvp examples to work correctly 2014-12-08 20:55:19 -08:00
Cary R f0a0ab100f vlog95: trim binary constants to save space and emit size of undef. consts.
This should not change the functionality, but to save space trim any
unneeded bits from a binary constant. Also for the case of emitting
a signed undefined value when the allow signed flag is not set add
the width to the constant.
2014-12-08 13:08:30 -08:00
Cary R c28188618b File example vvp code so make check passes. 2014-12-08 10:43:46 -08:00
Martin Whitaker 0d7daf5862 Fix vvp memory leak for user function calls in a continuous assignment. 2014-12-07 13:47:50 +00:00
Martin Whitaker 60ab1daa1f Restore some master branch fixes lost in the vec4-stack merge. 2014-12-07 12:10:15 +00:00
Stephen Williams 105521b547 Merge branch 'master' into vec4-stack 2014-12-06 08:24:46 -08:00
Cary R fd3086f0a9 Fix compile warnings on RHEL5 2014-12-05 19:03:07 -08:00
Cary R 77ebfcacb9 Correctly pass if a darray element is signed or unsigned. 2014-12-05 18:23:02 -08:00
Cary R d62a307c34 Fix 32-bit issue in vector4_to_value() 2014-12-05 18:00:08 -08:00
Stephen Williams 011519cb5b Merge branch 'master' into vec4-stack 2014-12-05 13:55:51 -08:00
Stephen Williams 77d1671d8f Merge branch 'master' into vec4-stack 2014-12-05 10:44:49 -08:00
Stephen Williams 409f8c5823 Add the vec4 %subi instruction 2014-12-05 09:45:29 -08:00
Stephen Williams 03198356a5 vec4-stack stack manipulation improvements. 2014-12-04 17:15:27 -08:00
Stephen Williams b1d2393789 Optimize the %sub instruction by integrating it with vvp_vector4_t class 2014-12-04 17:01:16 -08:00
Stephen Williams 0f740289e9 Optimize %mul instructions by integrating with vvp_vector4_t class. 2014-12-04 16:00:57 -08:00
Stephen Williams 46ce236cfb Optimize the %add and %addi instructions
Tightly integrate with the vvp_vector4_t class to get much
better add performance.
2014-12-04 12:38:08 -08:00
Stephen Williams 86139c855d Optimize the vec4-stack %cmp/s and %cmpi/s instructions.
Magnitude compare is called a LOT, so it is worth putting some
special effort into it.
2014-12-04 10:42:48 -08:00
Stephen Williams eb070b061b Optimize the vec4_to_index, which implements %ix/vec4 instructions. 2014-12-03 17:53:45 -08:00
Stephen Williams 2b1393e7b9 Reduce some vector copies in %load/vec4 and %concat/vec4 instructions.
By clever stack manipulations, we can eliminate some vector copies,
which can improve performance.
2014-12-03 13:12:06 -08:00
Stephen Williams 85c7b07a9b Implement %cmp/ne and %cmpi/ne
These pull in the inversion of the output flags so that they more
efficiently implement != and !==, without %flag_inv instructions.
2014-12-03 11:06:11 -08:00
Stephen Williams 0c5ed2b60f Merge branch 'master' into vec4-stack 2014-12-03 08:36:38 -08:00
Stephen Williams 3bd307db85 Expression cast handles size if need be. 2014-12-02 16:54:32 -08:00
Stephen Williams 35db02d35d elaborate dump cast operators. 2014-12-02 16:50:42 -08:00
Stephen Williams f287546f49 Fix a %vpi_call call syntax. 2014-12-02 15:28:22 -08:00
Stephen Williams 1645e682f4 Generate more efficient vec4-stack code for real le compare. 2014-12-02 14:53:01 -08:00
Stephen Williams a57e0a1e3f vvp implementation of copy from vec4 to vec2 can use subarray method. 2014-12-02 14:52:37 -08:00
Stephen Williams b83144c552 The __vpiArray::set_word method should take a reference.
Seem to have missed a case where a vvp_vector4_t can be passed by
const reference instead of by value.
2014-12-02 13:02:46 -08:00
Stephen Williams 58fb80aec4 Implement and put to use the %muli instruction. 2014-12-02 12:46:17 -08:00
Stephen Williams 38f277d81b Merge branch 'master' into vec4-stack
Conflicts:
	vvp/array.cc
	vvp/vthread.cc
2014-12-02 11:21:58 -08:00
Stephen Williams fb5ae48b18 Merge branch 'master' into vec4-stack 2014-12-01 17:00:35 -08:00
Stephen Williams 82ca4cf641 Add a warning if an expression pads itself to a crazy width. 2014-11-25 14:49:04 -08:00
Stephen Williams 679021a1b5 Optimize special cases of immediate value extraction. 2014-11-22 10:38:16 -08:00
Stephen Williams f3392561ed Optimize the vvp pad implementation. 2014-11-22 09:59:02 -08:00
Stephen Williams 7a9a022744 Remove some dead code. 2014-11-21 17:36:22 -08:00
Stephen Williams c222b3b6a4 Minor improvements to the %split/vec4 instruction. 2014-11-21 16:51:59 -08:00
Stephen Williams 663c79d4af Add the %cmp/e instructions, and put them to use.
When testing for == and ===, there is no need to also calculate <,
so it makes sense to have a special instruction for these cases.
2014-11-21 16:45:27 -08:00
Stephen Williams bea03db25d Minor vec4 stack manipulation optimizations. 2014-11-21 14:41:31 -08:00
Stephen Williams b96f04ccce Implement the %parti/X instructions
This allows part select with constant base to be handled optimally.
Also update some more instructions to more optimally work with
the vec4 stack.
2014-11-20 18:43:24 -08:00
Stephen Williams a9db765f98 Generate better code for condition expressions. 2014-11-20 14:47:44 -08:00
Stephen Williams c71ab5869a vvp code generator try to generate condition flags directly.
When generating code for a condition expression, i.e. directly
before a %jmp/X statement, try to generate the result into the
flag bit without passing through the vec4 stack. For example, the
%cmpX/X instructions generate results into the flag bits, so it
makes no sense to push these bits into the vec4 stack then pop
them back into the flag bit. So try to handle this case.
2014-11-19 18:32:19 -08:00
Stephen Williams 04bdfbccee Add %cmpi/s and %cmpi/u instructions for performance
These bypass the vec4 stack in some common cases, saving instructions
and vec4 manipulations.

Also, minor improvement to the %flag/set/vec4 statement.

Kill a few warnings.
2014-11-19 16:38:43 -08:00
Stephen Williams 2acc9fbdee Remove dead instructsion %set/qb and %set/qf / Kill some warnings. 2014-11-19 09:15:01 -08:00
Stephen Williams 725ed869ba Remove dead %load/vp0 instructions and related infrastructure
Also remove some &A<> and &PV<> symbols that use this now dead
infrastructure.
2014-11-19 09:02:21 -08:00
Stephen Williams 301edf69d3 Add and use %concati/vec4 and %addi instructions.
Also, clean up some warnings, and optimize some existing opcodes.
2014-11-18 12:27:55 -08:00
Stephen Williams 1612c6d638 Instruction %concat/vec4, %pad/u and %shiftl manipulate stack in place 2014-11-17 16:32:18 -08:00
Stephen Williams aadd67cd3b Some instructions can do stack manipultations in place.
By doing some stack manipulations in place, certain instructions
can eliminate, or optimize, vector copies.
2014-11-14 18:38:15 -08:00
Stephen Williams c2ca9c3b73 Optimize draw_number_vec4 to use %pushi/vec4 zero-padding. 2014-11-14 18:37:10 -08:00
Stephen Williams 0601b4e43b Optimizations for %pushi/vec4 and %load/vec4
- Have %pushi/vec4 handle some special cases optimally.
- Eliminate some duplicated method calls in %load/vec4.
- Optimize the vvp_vector4_t::copy_from_ method by inlining
some parts.
2014-11-14 14:41:04 -08:00
Stephen Williams 8aca66b109 Performance tweaks
Better performance for %cmp/s and the vvp_fun_part_sa node.
2014-11-14 11:48:36 -08:00
Stephen Williams 2aeb3871ed Merge branch 'master' into vec4-stack
This was a challenging merge...
Conflicts:
	elab_scope.cc
	synth2.cc
	tgt-vvp/eval_expr.c
	vvp/vthread.cc
2014-11-13 16:26:15 -08:00
Stephen Williams ea21fb856e Mux with default, handle possible large selector. 2014-11-09 16:49:21 -08:00
Stephen Williams d5123011b3 Merge branch 'master' into vec4-stack
Conflicts:
	elab_scope.cc
2014-11-01 14:57:05 -07:00
Stephen Williams 8ac06fb63f Support vpiObjTypeVal for vec4Stack values.
Also allow vpi_get_value outside of scope. (Return 'x)
2014-10-25 20:38:39 -07:00
Stephen Williams 4e727adc25 Merge branch 'master' into vec4-stack 2014-10-25 09:49:39 -07:00
Stephen Williams 702a8c3a05 Merge branch 'master' into vec4-stack 2014-10-24 15:17:31 -07:00
Stephen Williams 48d3972299 Remove a bunch of dead vvp opcodes. 2014-10-24 15:13:28 -07:00
Stephen Williams 62fce50f8c Remove dead code for allocate_vec handling. 2014-10-24 13:07:53 -07:00
Stephen Williams e4b862f3d1 Clean up vector handling dead code. 2014-10-24 11:17:36 -07:00
Stephen Williams 09d3a5de59 Port %pushv/str to vec4-stack style. 2014-10-24 10:16:35 -07:00
Stephen Williams 97bde47c31 Remove dead %set/dar and %set/dar/obj instructions. 2014-10-24 10:03:22 -07:00
Stephen Williams 1c80c6e37a Remove dead stuff_ok_flags from draw_eval_vec4 functions. 2014-10-24 09:32:32 -07:00
Stephen Williams 4588f7c615 vec4 stack versions of queue pop methods. 2014-10-24 09:03:20 -07:00
Stephen Williams 24b8752475 More cases where %store/prop/v takes a width. 2014-10-22 16:15:10 -07:00
Stephen Williams 3ddcf03764 Kill some eval_vec4.c warnings. 2014-10-22 13:01:25 -07:00
Stephen Williams 35f5d51028 Support testing nul for property that is an object. 2014-10-22 12:58:50 -07:00
Stephen Williams 87c019c65c Merge branch 'master' into vec4-stack 2014-10-21 12:19:40 -07:00
Stephen Williams 69a1fecd2e Handle arrays of object is comparison with null. 2014-10-21 11:47:22 -07:00
Stephen Williams 9964d67e5e Implicit crop of vectors assigned to vector properties.
The %store/prop/v takes a width so that it is guaranteed that
all assignments to a vector property will get the size right.
2014-10-21 11:46:59 -07:00
Stephen Williams a98f21aa65 Merge branch 'master' into vec4-stack
Conflicts:
	elab_lval.cc
	netmisc.cc
	tgt-vvp/eval_object.c
	tgt-vvp/vvp_process.c
	vvp/codes.h
	vvp/compile.cc
	vvp/opcodes.txt
	vvp/vpi_tasks.cc
	vvp/vpi_vthr_vector.cc
	vvp/vthread.cc
2014-10-21 09:12:02 -07:00
Stephen Williams 88e4938074 Merge branch 'master' into vec4-stack 2014-03-04 19:08:56 -08:00
Stephen Williams e932c7a637 Support get of vpiIntVal from vec4 stack. 2014-03-04 19:02:21 -08:00
Stephen Williams b5e0099f28 Fix support for enum literals with undefined values. 2014-03-01 17:45:13 -08:00
Stephen Williams 1afe7476e3 Handle nested l-values in vec4-stack code generator. 2014-03-01 16:49:15 -08:00
Stephen Williams 4068570f43 Fix %pow and %pow/s to properly account for 'x operands. 2014-03-01 16:11:47 -08:00
Stephen Williams 7ceb18fb37 Merge branch 'master' into vec4-stack
Conflicts:
	netmisc.cc
	tgt-vvp/eval_expr.c
	vvp/vthread.cc
2014-03-01 09:02:14 -08:00
Stephen Williams d2ff77d56c More standard handling of unsized numbers as system task arguments. 2014-03-01 08:38:23 -08:00
Stephen Williams 91b7c6ab55 Merge branch 'master' into vec4-stack
Conflicts:
	vvp/vthread.cc
2014-02-21 18:04:16 -08:00
Stephen Williams ebed793dec Merge branch 'master' into vec4-stack
Conflicts:
	vvp/vthread.cc

Signed-off-by: Stephen Williams <[email protected]>
2014-02-21 17:34:59 -08:00
Stephen Williams be5bfeb172 Elaborate widths of parameters correctly for unsigned values
If there is no size in the parameter type declaration or on the
value itself, then give the parameter value a minimum width of
integer bits.
2014-02-11 18:24:12 -08:00
Stephen Williams 801e795112 Better job of matching adder operand sizes for vec4 code generator. 2014-02-10 18:06:56 -08:00
Stephen Williams e66fc7e5cc Port UWIRE assignments to vec4 branch. 2014-02-10 17:19:52 -08:00
Stephen Williams 1d63875e5d Merge branch 'master' into vec4-stack
Conflicts:
	elab_lval.cc
2014-02-10 16:26:22 -08:00
Stephen Williams 554fb7ebdd Various internal vec4 size mismatches fixed. 2014-02-07 17:50:13 -08:00
Stephen Williams c9e8392dc7 Fix dangling vec4 stack when force assignment is suppressed.
Also improve the %debug/thr instruction.
2014-02-07 16:10:28 -08:00
Stephen Williams 60d37e1f53 More vec4 support for various things. 2014-02-07 11:24:41 -08:00
Stephen Williams 401fccdf6e vec4 handling of DARRAY of vec4 vectors. 2014-02-06 15:05:26 -08:00
Stephen Williams f5564a195f vec4 versions of compressed assignment statements. 2014-02-06 09:55:25 -08:00
Stephen Williams c7e61f3aa4 Merge branch 'master' into vec4-stack 2014-02-05 15:18:25 -08:00
Stephen Williams 1805598eae Fix some vec4 handling of putc, len, and other string methods. 2014-01-31 19:01:28 -08:00
Stephen Williams 0eca210722 Merge branch 'master' into vec4-stack 2014-01-30 17:07:54 -08:00
Stephen Williams fdc9e8590d Merge branch 'master' into vec4-stack 2014-01-30 15:59:51 -08:00
Stephen Williams e497f63e29 Implement string compares for vec4 support. 2014-01-28 17:11:21 -08:00
Stephen Williams 75233a9bca vec4 implementation of auto-increment/decrement. 2014-01-28 16:24:26 -08:00
Stephen Williams 11197baf86 The vec4 %cvt/vr requires a <wid> 2014-01-28 15:51:29 -08:00
Stephen Williams 23ba0bc019 various vec4 fixes. 2014-01-25 19:25:21 -08:00
Stephen Williams 9cfb15a302 Implement assign/vec4/off/e 2014-01-23 18:39:29 -08:00
Stephen Williams 8bebe59e20 Fix vec4 abs() generating duplicat labels. 2014-01-22 17:15:26 -08:00
Stephen Williams 20d415463a vec4 non-blocking assign to array swapped delay and part offset! 2014-01-21 20:58:48 -08:00
Stephen Williams 9c1dcad994 vec4 vvp support for non-blocking assign with delay and part offset. 2014-01-21 19:37:05 -08:00
Stephen Williams 0e13726e83 fix broken call-out of real-valued system functions. 2014-01-21 13:31:49 -08:00
Stephen Williams 54346d7095 vec4 implementations of real ternary and vec4 to real casts. 2014-01-21 12:02:59 -08:00
Stephen Williams 0121fbc88c Remove useless assert. 2014-01-21 11:05:32 -08:00
Stephen Williams f1855eed0e Fix system function call in net types to get proper vector width.
This means using some of the new vec4 infrastructure to get at the
data, instead of using the old thread bit pointers. In the process,
remove the vbit and vwid members that pointed to thread bits. Those
bits no longer exist.
2014-01-20 19:07:11 -08:00
Stephen Williams 0f9828f179 Fix vec4 overflow of times when they are >32bits. 2014-01-19 14:28:39 -08:00
Stephen Williams d2c2d6d8dc vec4 versions of %cassign/vec4/off and %force/vec4/off send flags[4]. 2014-01-18 17:08:36 -08:00
Stephen Williams f94a655121 Yet again, try to fix vec4 calculation of n-dimensional array index. 2014-01-18 16:04:25 -08:00
Stephen Williams 078a3fd409 Was a little too aggressive with the lossless elab_and_eval
The index expressions ARE self-sized context, we just need to
force the EXPAND flag to make this work.
2014-01-17 18:22:11 -08:00
Stephen Williams dfaed128c0 Fix %store/vec4 overlap of vectors written with extreme indices. 2014-01-15 16:30:34 -08:00
Stephen Williams 1fc4093191 Fix possible overflow in calculation of canonical indices. 2014-01-15 14:26:53 -08:00
Stephen Williams ae1f8be277 Wrap up vpi access to vec4 stack items. 2014-01-14 17:10:03 -08:00
Stephen Williams d8533104b0 Cleanup vec4 handling of suppressed store/assign due to bad offset/index math. 2014-01-14 12:00:39 -08:00
Stephen Williams c6c697bdb7 WRap up vec4 support for system function calls. 2014-01-14 09:22:23 -08:00
Stephen Williams 660d59a7a9 vec4 versions of the %force instructions. 2014-01-13 18:57:03 -08:00
Stephen Williams 92a5e6a698 vec4 based calls to simple real system functions. 2014-01-13 17:46:39 -08:00
Stephen Williams aaa054a932 Fix botched implementations of vec4 based shift. 2014-01-13 17:46:14 -08:00
Stephen Williams 079065ea73 Remove some dead code in tgt-vvp. 2014-01-13 17:45:44 -08:00
Stephen Williams 1905264061 vec4 support for part select of memory word to VPI function. 2014-01-13 16:12:56 -08:00
Stephen Williams b0a9430e98 Wrap up vecc4 support for left/right shift expressions. 2014-01-13 16:11:47 -08:00
Stephen Williams 6a93b6a7e4 Fix some subtle code generator bugs with wide literals and large r-values. 2014-01-07 18:46:35 -08:00
Stephen Williams ec6009dd8f Compile out the T<...> format in vvp.
This ifdef's the code out. Leave it in place for a little longer
for reference.
2014-01-06 20:36:26 -08:00
Stephen Williams 4820d46353 Implement some vpi_get_value formats for vec4 stack values. 2014-01-06 20:27:14 -08:00
Stephen Williams a2845cee70 Update %pow instructions to use vec4 stack. 2014-01-06 10:34:07 -08:00
Stephen Williams c897ca017c Update %div instruction to vec4 version. 2014-01-06 10:14:49 -08:00
Stephen Williams aee540d8bb Fix sort of %event command in vvp compile list.
The sort is important, the names must be sorted because the table is
searched using binary search.
2014-01-06 09:12:42 -08:00
Stephen Williams 19402aeef2 get vpiStringVal from vec4 stack positions. 2014-01-06 08:35:49 -08:00
Stephen Williams fcc0a6a203 vec4 string literal expressions 2014-01-06 08:35:23 -08:00
Stephen Williams e5eb754150 vec4 versions of a bunch of unary operators. 2014-01-05 14:12:27 -08:00
Stephen Williams 063c6d6065 Add the %event instruction, remove %ix/get and %ix/get/s. 2014-01-05 12:39:52 -08:00
Stephen Williams 2fc8ce8a16 Implement vec4 basec %assign delay and event / vpiTimeVal for functions. 2014-01-05 12:04:16 -08:00
Stephen Williams 1a3adbe9cd Vec4 store to memories.
This also reworks the working of the %store/vec4 instruction to
take a part offset, and eliminate the %store/vec4/off instruction.
2014-01-05 10:30:59 -08:00
Stephen Williams 63fa44fa4a vec4 support for ufuncs and ligical AND. 2014-01-05 17:15:30 +00:00
Stephen Williams f89dbd48c8 Add vec4 support for bitwise or/nor/nand/xor/xnor. 2014-01-04 23:48:16 +00:00
Stephen Williams 9fc3e84e93 vec4 cassign to part selects. 2014-01-04 22:58:58 +00:00
Stephen Williams e708a5b59d Handle vec4 part selects / vec4 cassign / repeat statements
These features need to be adapted to the vec4 stack.
2014-01-04 22:11:07 +00:00
Stephen Williams d55e4c0552 Redesign support for system functions that return vec4
Redsign the handling of the return value, including a rework of
the %vpi_func syntax to carry the needed information.

Add a few more arithmetic operator instructions.
2014-01-04 22:06:58 +00:00
Stephen Williams 54926840e6 Handle vec4 stack version of concatenation. 2013-12-28 07:50:37 +02:00
Stephen Williams 5ef077fdf6 Start work on converting vec4 expressions to use stack.
Instead of using a bit4 space to hold thread vectors, create a
vec4 stack--much like the real, string, and object stacks--to
hold intermediate values.
2013-12-27 17:04:42 +02:00
284 changed files with 18735 additions and 14544 deletions
+2
View File
@@ -0,0 +1,2 @@
# gperf in MSYS chokes on DOS line endings
*.gperf text eol=lf
+1 -1
View File
@@ -40,7 +40,7 @@ hname_t::hname_t(perm_string text, int num)
number_[0] = num;
}
hname_t::hname_t(perm_string text, vector<int>&nums)
hname_t::hname_t(perm_string text, const vector<int>&nums)
: name_(text), number_(nums)
{
}
+9 -4
View File
@@ -42,7 +42,7 @@ class hname_t {
hname_t ();
explicit hname_t (perm_string text);
explicit hname_t (perm_string text, int num);
explicit hname_t (perm_string text, std::vector<int>&nums);
explicit hname_t (perm_string text, const std::vector<int>&nums);
hname_t (const hname_t&that);
~hname_t();
@@ -56,12 +56,12 @@ class hname_t {
size_t has_numbers() const;
int peek_number(size_t idx) const;
const std::vector<int>&peek_numbers() const;
private:
perm_string name_;
// If the number is anything other than INT_MIN, then this is
// the numeric part of the name. Otherwise, it is not part of
// the name at all.
// If this vector has size, then the numbers all together make
// up part of the hierarchical name.
std::vector<int> number_;
private: // not implemented
@@ -82,6 +82,11 @@ inline int hname_t::peek_number(size_t idx) const
return number_[idx];
}
inline const std::vector<int>& hname_t::peek_numbers(void) const
{
return number_;
}
inline size_t hname_t::has_numbers() const
{
return number_.size();
+3 -3
View File
@@ -118,8 +118,8 @@ O = main.o async.o design_dump.o discipline.o dup_expr.o elaborate.o \
pform_class_type.o pform_string_type.o pform_struct_type.o pform_types.o \
symbol_search.o sync.o sys_funcs.o verinum.o verireal.o target.o \
Attrib.o HName.o Module.o PClass.o PDelays.o PEvent.o PExpr.o PGate.o \
PGenerate.o PPackage.o PScope.o PSpec.o PTask.o PUdp.o PFunction.o PWire.o \
Statement.o AStatement.o $M $(FF) $(TT)
PGenerate.o PModport.o PPackage.o PScope.o PSpec.o PTask.o PUdp.o \
PFunction.o PWire.o Statement.o AStatement.o $M $(FF) $(TT)
all: dep config.h _pli_types.h version_tag.h ivl@EXEEXT@ version.exe iverilog-vpi.man
$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true
@@ -292,7 +292,7 @@ endif
version_tag.h version:
@if $(GIT_PRESENT) && test -d $(srcdir)/.git; then \
echo "Using git-describe for VERSION_TAG"; \
tmp=`$(GIT) --git-dir $(srcdir)/.git describe --always --dirty \
tmp=`(cd $(srcdir) && $(GIT) describe --always --dirty) \
| sed -e 's;\(.*\);#define VERSION_TAG "\1";'`; \
echo "$$tmp" | diff - version_tag.h > /dev/null 2>&1 || echo "$$tmp" > version_tag.h || exit 1; \
elif test -r $(srcdir)/version_tag.h; then \
+6 -7
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998-2010 Stephen Williams ([email protected])
* Copyright (c) 1998-2016 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
@@ -35,9 +35,6 @@ Module::Module(LexicalScope*parent, perm_string n)
program_block = false;
uc_drive = UCD_NONE;
timescale_warn_done = false;
time_unit = 0;
time_precision = 0;
time_from_timescale = false;
}
Module::~Module()
@@ -94,13 +91,15 @@ perm_string Module::get_port_name(unsigned idx) const
{
assert(idx < ports.size());
if (ports[idx] == 0) {
if (ports[idx] == 0 || ports[idx]->name.str() == 0) {
/* It is possible to have undeclared ports. These
are ports that are skipped in the declaration,
for example like so: module foo(x ,, y); The
port between x and y is unnamed and thus
inaccessible to binding by name. */
return perm_string::literal("");
inaccessible to binding by name. Port references
that aren't simple or escaped identifiers are
also inaccessible to binding by name. */
return perm_string::literal("unnamed");
}
return ports[idx]->name;
}
+17 -6
View File
@@ -1,7 +1,7 @@
#ifndef IVL_Module_H
#define IVL_Module_H
/*
* Copyright (c) 1998-2014 Stephen Williams ([email protected])
* Copyright (c) 1998-2016 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
@@ -35,6 +35,7 @@ class PExpr;
class PEIdent;
class PGate;
class PGenerate;
class PModport;
class PSpecPath;
class PTask;
class PFunction;
@@ -47,6 +48,10 @@ class NetScope;
* A module is a named container and scope. A module holds a bunch of
* semantic quantities such as wires and gates. The module is
* therefore the handle for grasping the described circuit.
*
* SystemVerilog introduces program blocks and interfaces. These have
* much in common with modules, so the Module class is used to represent
* these containers as well.
*/
class Module : public PScopeExtra, public LineInfo {
@@ -64,7 +69,7 @@ class Module : public PScopeExtra, public LineInfo {
public:
/* The name passed here is the module name, not the instance
name. This make must be a permallocated string. */
name. This name must be a permallocated string. */
explicit Module(LexicalScope*parent, perm_string name);
~Module();
@@ -81,6 +86,11 @@ class Module : public PScopeExtra, public LineInfo {
restrictions and slightly modify scheduling semantics. */
bool program_block;
/* This is true if the module represents a interface
instead of a module/cell. Interfaces have different
content restrictions and some extra allowed items. */
bool is_interface;
enum UCDriveType { UCD_NONE, UCD_PULL0, UCD_PULL1 };
UCDriveType uc_drive;
@@ -111,10 +121,6 @@ class Module : public PScopeExtra, public LineInfo {
map<perm_string,PExpr*> attributes;
/* These are the timescale for this module. The default is
set by the `timescale directive. */
int time_unit, time_precision;
bool time_from_timescale;
bool timescale_warn_done;
/* The module has a list of generate schemes that appear in
@@ -125,6 +131,11 @@ class Module : public PScopeExtra, public LineInfo {
unless they are instantiated, implicitly or explicitly. */
std::map<perm_string,Module*> nested_modules;
/* 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;
list<PSpecPath*> specify_paths;
// The mod_name() is the name of the module type.
+2 -2
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998-2012 Stephen Williams <[email protected]>
* Copyright (c) 1998-2016 Stephen Williams <[email protected]>
* Copyright CERN 2013 / Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
@@ -137,7 +137,7 @@ bool PEBinary::has_aa_term(Design*des, NetScope*scope) const
return left_->has_aa_term(des, scope) || right_->has_aa_term(des, scope);
}
PECastSize::PECastSize(unsigned si, PExpr*b)
PECastSize::PECastSize(PExpr*si, PExpr*b)
: size_(si), base_(b)
{
}
+11 -6
View File
@@ -1,7 +1,7 @@
#ifndef IVL_PExpr_H
#define IVL_PExpr_H
/*
* Copyright (c) 1998-2014 Stephen Williams <[email protected]>
* Copyright (c) 1998-2016 Stephen Williams <[email protected]>
* Copyright CERN 2013 / Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
@@ -436,7 +436,7 @@ class PEIdent : public PExpr {
const perm_string&) const;
bool elaborate_lval_net_packed_member_(Design*, NetScope*,
NetAssign_*,
const perm_string&) const;
const name_component_t&) const;
bool elaborate_lval_darray_bit_(Design*, NetScope*,
NetAssign_*) const;
@@ -917,8 +917,10 @@ class PECallFunction : public PExpr {
virtual bool has_aa_term(Design*des, NetScope*scope) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
unsigned expr_wid,
unsigned flags) const;
ivl_type_t type, unsigned flags) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
unsigned expr_wid, unsigned flags) const;
virtual unsigned test_width(Design*des, NetScope*scope,
width_mode_t&mode);
@@ -969,7 +971,7 @@ class PECallFunction : public PExpr {
class PECastSize : public PExpr {
public:
explicit PECastSize(unsigned expr_wid, PExpr*base);
explicit PECastSize(PExpr*size, PExpr*base);
~PECastSize();
void dump(ostream &out) const;
@@ -982,7 +984,7 @@ class PECastSize : public PExpr {
width_mode_t&mode);
private:
unsigned size_;
PExpr* size_;
PExpr* base_;
};
@@ -997,6 +999,9 @@ class PECastType : public PExpr {
void dump(ostream &out) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
ivl_type_t type, unsigned flags) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
unsigned expr_wid, unsigned flags) const;
+31
View File
@@ -0,0 +1,31 @@
/*
* Copyright (c) 2015 Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
# include "config.h"
# include "PModport.h"
PModport::PModport(perm_string n)
: name_(n)
{
}
PModport::~PModport()
{
}
+52
View File
@@ -0,0 +1,52 @@
#ifndef IVL_PModport_H
#define IVL_PModport_H
/*
* Copyright (c) 2015 Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
# include "LineInfo.h"
# include "PScope.h"
# include "StringHeap.h"
# include "netlist.h"
# include <vector>
/*
* The PModport class represents a parsed SystemVerilog modport list.
*/
class PModport : public LineInfo {
public:
// The name is a perm-allocated string. It is the simple name
// of the modport, without any scope.
explicit PModport(perm_string name);
~PModport();
perm_string name() const { return name_; }
typedef pair <NetNet::PortType,PExpr*> simple_port_t;
map<perm_string,simple_port_t> simple_ports;
private:
perm_string name_;
private: // not implemented
PModport(const PModport&);
PModport& operator= (const PModport&);
};
#endif /* IVL_PModport_H */
+17 -20
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2008,2010 Stephen Williams ([email protected])
* Copyright (c) 2008,2016 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,21 +19,9 @@
# include "PScope.h"
PScope::PScope(perm_string n, LexicalScope*parent)
: LexicalScope(parent), name_(n)
bool LexicalScope::var_init_needs_explicit_lifetime() const
{
}
PScope::PScope(perm_string n)
: LexicalScope(0), name_(n)
{
}
PScope::~PScope()
{
for(map<perm_string, data_type_t*>::iterator it = typedefs.begin();
it != typedefs.end(); ++it)
delete it->second;
return false;
}
PWire* LexicalScope::wires_find(perm_string name)
@@ -45,17 +33,26 @@ PWire* LexicalScope::wires_find(perm_string name)
return (*cur).second;
}
PScopeExtra::PScopeExtra(perm_string n, LexicalScope*parent)
: PScope(n, parent)
PScope::PScope(perm_string n, LexicalScope*parent)
: LexicalScope(parent), name_(n)
{
time_unit = 0;
time_precision = 0;
time_from_timescale = false;
}
PScopeExtra::PScopeExtra(perm_string n)
: PScope(n)
PScope::~PScope()
{
for(map<perm_string, data_type_t*>::iterator it = typedefs.begin();
it != typedefs.end(); ++it)
delete it->second;
}
PScopeExtra::PScopeExtra(perm_string n, LexicalScope*parent)
: PScope(n, parent)
{
}
PScopeExtra::~PScopeExtra()
{
}
+25 -7
View File
@@ -1,7 +1,7 @@
#ifndef IVL_PScope_H
#define IVL_PScope_H
/*
* Copyright (c) 2008-2014 Stephen Williams ([email protected])
* Copyright (c) 2008-2016 Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -36,6 +36,7 @@ class PProcess;
class PClass;
class PTask;
class PWire;
class Statement;
class Design;
class NetScope;
@@ -52,10 +53,14 @@ class NetScope;
class LexicalScope {
public:
explicit LexicalScope(LexicalScope*parent) : parent_(parent) { }
enum lifetime_t { INHERITED, STATIC, AUTOMATIC };
explicit LexicalScope(LexicalScope*parent) : default_lifetime(INHERITED), parent_(parent) { }
// A virtual destructor is so that dynamic_cast can work.
virtual ~LexicalScope() { }
lifetime_t default_lifetime;
struct range_t {
// True if this is an exclude
bool exclude_flag;
@@ -108,6 +113,9 @@ class LexicalScope {
// creating implicit nets.
map<perm_string,LineInfo*> genvars;
// Variable initializations in this scope
vector<Statement*> var_inits;
// Behaviors (processes) in this scope
list<PProcess*> behaviors;
list<AProcess*> analog_behaviors;
@@ -117,6 +125,8 @@ class LexicalScope {
LexicalScope* parent_scope() const { return parent_; }
virtual bool var_init_needs_explicit_lifetime() const;
protected:
void dump_typedefs_(ostream&out, unsigned indent) const;
@@ -130,6 +140,10 @@ class LexicalScope {
void dump_wires_(ostream&out, unsigned indent) const;
void dump_var_inits_(ostream&out, unsigned indent) const;
bool elaborate_var_inits_(Design*des, NetScope*scope) const;
private:
LexicalScope*parent_;
};
@@ -145,12 +159,17 @@ class PScope : public LexicalScope {
// modules do not nest in Verilog, the parent must be nil for
// modules. Scopes for tasks and functions point to their
// containing module.
PScope(perm_string name, LexicalScope*parent);
PScope(perm_string name);
explicit PScope(perm_string name, LexicalScope*parent =0);
virtual ~PScope();
perm_string pscope_name() const { return name_; }
/* These are the timescale for this scope. The default is
set by the `timescale directive or, in SystemVerilog,
by timeunit and timeprecision statements. */
int time_unit, time_precision;
bool time_from_timescale;
protected:
bool elaborate_sig_wires_(Design*des, NetScope*scope) const;
@@ -168,14 +187,13 @@ class PScope : public LexicalScope {
class PScopeExtra : public PScope {
public:
PScopeExtra(perm_string, LexicalScope*parent);
PScopeExtra(perm_string);
explicit PScopeExtra(perm_string, LexicalScope*parent =0);
~PScopeExtra();
/* Task definitions within this module */
std::map<perm_string,PTask*> tasks;
std::map<perm_string,PFunction*> funcs;
/* class definitions within this module. */
/* Class definitions within this module. */
std::map<perm_string,PClass*> classes;
/* This is the lexical order of the classes, and is used by
elaboration to choose an elaboration order. */
+6 -1
View File
@@ -30,6 +30,11 @@ PTaskFunc::~PTaskFunc()
{
}
bool PTaskFunc::var_init_needs_explicit_lifetime() const
{
return default_lifetime == STATIC;
}
void PTaskFunc::set_ports(vector<pform_tf_port_t>*p)
{
assert(ports_ == 0);
@@ -41,7 +46,7 @@ void PTaskFunc::set_this(class_type_t*type, PWire*this_wire)
assert(this_type_ == 0);
this_type_ = type;
// Push a synthethis argument that is the "this" value.
// Push a synthesis argument that is the "this" value.
if (ports_==0)
ports_ = new vector<pform_tf_port_t>;
+2
View File
@@ -41,6 +41,8 @@ class PTaskFunc : public PScope, public LineInfo {
PTaskFunc(perm_string name, LexicalScope*parent);
~PTaskFunc();
bool var_init_needs_explicit_lifetime() const;
void set_ports(std::vector<pform_tf_port_t>*p);
void set_this(class_type_t*use_type, PWire*this_wire);
+5
View File
@@ -115,6 +115,11 @@ PBlock::~PBlock()
delete list_[idx];
}
bool PBlock::var_init_needs_explicit_lifetime() const
{
return default_lifetime == STATIC;
}
PChainConstructor* PBlock::extract_chain_constructor()
{
if (list_.empty())
+4 -1
View File
@@ -108,7 +108,8 @@ class PAssign_ : public Statement {
NetAssign_* elaborate_lval(Design*, NetScope*scope) const;
NetExpr* elaborate_rval_(Design*, NetScope*, ivl_type_t lv_net_type,
ivl_variable_type_t lv_type,
unsigned lv_width) const;
unsigned lv_width,
bool force_unsigned =false) const;
NetExpr* elaborate_rval_(Design*, NetScope*, ivl_type_t ntype) const;
NetExpr* elaborate_rval_obj_(Design*, NetScope*,
@@ -182,6 +183,8 @@ class PBlock : public PScope, public Statement {
BL_TYPE bl_type() const { return bl_type_; }
bool var_init_needs_explicit_lifetime() const;
// This is only used if this block is the statement list for a
// constructor. We look for a PChainConstructor as the first
// statement, and if it is there, extract it.
Vendored
+2 -1
View File
@@ -223,8 +223,9 @@ AC_SUBST(strip_dynamic)
# -------------
AC_DEFUN([AX_C99_STRTOD],
[# On MinGW we need to jump through hoops to get a C99 compliant strtod().
# mingw-w64 doesn't need this, and the 64-bit version doesn't support it.
case "${host}" in
*-*-mingw*)
*-*-mingw32)
LDFLAGS+=" -Wl,--undefined=___strtod,--wrap,strtod,--defsym,___wrap_strtod=___strtod"
;;
esac
+19 -15
View File
@@ -1,7 +1,7 @@
#ifndef IVL_compiler_H
#define IVL_compiler_H
/*
* Copyright (c) 1999-2014 Stephen Williams ([email protected])
* Copyright (c) 1999-2016 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
@@ -80,6 +80,10 @@ extern unsigned recursive_mod_limit;
/* Implicit definitions of wires. */
extern bool warn_implicit;
/* Warn if dimensions of port or var/net are implicitly taken from
the input/output/inout declaration. */
extern bool warn_implicit_dimensions;
/* inherit timescales across files. */
extern bool warn_timescale;
@@ -138,7 +142,8 @@ extern int build_library_index(const char*path, bool key_case_sensitive);
/* This is the generation of Verilog that the compiler is asked to
support. Then there are also more detailed controls for more
specific language features. */
specific language features. Note that the compiler often assumes
this is an ordered list. */
enum generation_t {
GN_VER1995 = 1,
GN_VER2001_NOCONFIG = 2,
@@ -182,25 +187,24 @@ extern bool gn_strict_ca_eval_flag;
standard expression width rules. */
extern bool gn_strict_expr_width_flag;
/* If variables can be converted to uwires by a continuous assignment
(assuming no procedural assign, then return true. This will be true
for SystemVerilog */
static inline bool gn_var_can_be_uwire(void)
/* If this flag is true, then don't add a for-loop control variable
to an implicit event_expression list if it is only used inside the
loop. */
extern bool gn_shared_loop_index_flag;
static inline bool gn_system_verilog(void)
{
if (generation_flag == GN_VER2005_SV ||
generation_flag == GN_VER2009 ||
generation_flag == GN_VER2012)
if (generation_flag >= GN_VER2005_SV)
return true;
return false;
}
static inline bool gn_system_verilog(void)
/* If variables can be converted to uwires by a continuous assignment
(assuming no procedural assign), then return true. This will be true
for SystemVerilog */
static inline bool gn_var_can_be_uwire(void)
{
if (generation_flag == GN_VER2005_SV ||
generation_flag == GN_VER2009 ||
generation_flag == GN_VER2012)
return true;
return false;
return gn_system_verilog();
}
static inline bool gn_modules_nest(void)
+324 -447
View File
File diff suppressed because it is too large Load Diff
+2 -1
View File
@@ -1,7 +1,7 @@
#ifndef IVL_config_H /* -*- c++ -*- */
#define IVL_config_H
/*
* Copyright (c) 2001-2014 Stephen Williams ([email protected])
* Copyright (c) 2001-2015 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
@@ -55,6 +55,7 @@
# undef HAVE_FSEEKO
/* And this is needed by the fst files (copied from GTKWave). */
# undef HAVE_LIBPTHREAD
# undef HAVE_REALPATH
/*
* Define this if you want to compile vvp with memory freeing and
Vendored
+225 -101
View File
@@ -1,44 +1,40 @@
#! /bin/sh
# Configuration validation subroutine script.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
# Free Software Foundation, Inc.
# Copyright 1992-2015 Free Software Foundation, Inc.
timestamp='2009-04-17'
timestamp='2015-03-08'
# This file is (in principle) common to ALL GNU software.
# The presence of a machine in this file suggests that SOME GNU software
# can handle that machine. It does not imply ALL GNU software can.
#
# This file 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
# This file 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 3 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.
# 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., 51 Franklin Street - Fifth Floor, Boston, MA
# 02110-1301, USA.
# along with this program; if not, see <http://www.gnu.org/licenses/>.
#
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# the same distribution terms that you use for the rest of that
# program. This Exception is an additional permission under section 7
# of the GNU General Public License, version 3 ("GPLv3").
# Please send patches to <[email protected]>. Submit a context
# diff and a properly formatted ChangeLog entry.
# Please send patches to <[email protected]>.
#
# Configuration subroutine to validate and canonicalize a configuration type.
# Supply the specified configuration type as an argument.
# If it is invalid, we print an error message on stderr and exit with code 1.
# Otherwise, we print the canonical config type on stdout and succeed.
# You can get the latest version of this script from:
# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
# This file is supposed to be the same for all GNU packages
# and recognize all the CPU types, system types and aliases
# that are meaningful with *any* GNU software.
@@ -72,8 +68,7 @@ Report bugs and patches to <[email protected]>."
version="\
GNU config.sub ($timestamp)
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
Copyright 1992-2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -120,13 +115,18 @@ esac
# Here we must recognize all the valid KERNEL-OS combinations.
maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
case $maybe_os in
nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \
uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \
nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \
kopensolaris*-gnu* | \
storm-chaos* | os2-emx* | rtmk-nova*)
os=-$maybe_os
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
;;
android-linux)
os=-linux-android
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
;;
*)
basic_machine=`echo $1 | sed 's/-[^-]*$//'`
if [ $basic_machine != $1 ]
@@ -149,10 +149,13 @@ case $os in
-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
-apple | -axis | -knuth | -cray)
-apple | -axis | -knuth | -cray | -microblaze*)
os=
basic_machine=$1
;;
-bluegene*)
os=-cnk
;;
-sim | -cisco | -oki | -wec | -winbond)
os=
basic_machine=$1
@@ -167,10 +170,10 @@ case $os in
os=-chorusos
basic_machine=$1
;;
-chorusrdb)
os=-chorusrdb
-chorusrdb)
os=-chorusrdb
basic_machine=$1
;;
;;
-hiux*)
os=-hiuxwe2
;;
@@ -215,6 +218,12 @@ case $os in
-isc*)
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-lynx*178)
os=-lynxos178
;;
-lynx*5)
os=-lynxos5
;;
-lynx*)
os=-lynxos
;;
@@ -239,20 +248,28 @@ case $basic_machine in
# Some are omitted here because they have special meanings below.
1750a | 580 \
| a29k \
| aarch64 | aarch64_be \
| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
| am33_2.0 \
| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
| arc | arceb \
| arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
| avr | avr32 \
| be32 | be64 \
| bfin \
| c4x | clipper \
| c4x | c8051 | clipper \
| d10v | d30v | dlx | dsp16xx \
| fido | fr30 | frv \
| e2k | epiphany \
| fido | fr30 | frv | ft32 \
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
| hexagon \
| i370 | i860 | i960 | ia64 \
| ip2k | iq2000 \
| k1om \
| le32 | le64 \
| lm32 \
| m32c | m32r | m32rle | m68000 | m68k | m88k \
| maxq | mb | microblaze | mcore | mep | metag \
| maxq | mb | microblaze | microblazeel | mcore | mep | metag \
| mips | mipsbe | mipseb | mipsel | mipsle \
| mips16 \
| mips64 | mips64el \
@@ -266,36 +283,55 @@ case $basic_machine in
| mips64vr5900 | mips64vr5900el \
| mipsisa32 | mipsisa32el \
| mipsisa32r2 | mipsisa32r2el \
| mipsisa32r6 | mipsisa32r6el \
| mipsisa64 | mipsisa64el \
| mipsisa64r2 | mipsisa64r2el \
| mipsisa64r6 | mipsisa64r6el \
| mipsisa64sb1 | mipsisa64sb1el \
| mipsisa64sr71k | mipsisa64sr71kel \
| mipsr5900 | mipsr5900el \
| mipstx39 | mipstx39el \
| mn10200 | mn10300 \
| moxie \
| mt \
| msp430 \
| nios | nios2 \
| nds32 | nds32le | nds32be \
| nios | nios2 | nios2eb | nios2el \
| ns16k | ns32k \
| or32 \
| open8 | or1k | or1knd | or32 \
| pdp10 | pdp11 | pj | pjl \
| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
| powerpc | powerpc64 | powerpc64le | powerpcle \
| pyramid \
| riscv32 | riscv64 \
| rl78 | rx \
| score \
| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
| sh64 | sh64le \
| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
| sparcv8 | sparcv9 | sparcv9b | sparcv9v \
| spu | strongarm \
| tahoe | thumb | tic4x | tic80 | tron \
| v850 | v850e \
| spu \
| tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
| ubicom32 \
| v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
| visium \
| we32k \
| x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \
| x86 | xc16x | xstormy16 | xtensa \
| z8k | z80)
basic_machine=$basic_machine-unknown
;;
m6811 | m68hc11 | m6812 | m68hc12)
# Motorola 68HC11/12.
c54x)
basic_machine=tic54x-unknown
;;
c55x)
basic_machine=tic55x-unknown
;;
c6x)
basic_machine=tic6x-unknown
;;
leon|leon[3-9])
basic_machine=sparc-$basic_machine
;;
m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip)
basic_machine=$basic_machine-unknown
os=-none
;;
@@ -305,6 +341,21 @@ case $basic_machine in
basic_machine=mt-unknown
;;
strongarm | thumb | xscale)
basic_machine=arm-unknown
;;
xgate)
basic_machine=$basic_machine-unknown
os=-none
;;
xscaleeb)
basic_machine=armeb-unknown
;;
xscaleel)
basic_machine=armel-unknown
;;
# We use `pc' rather than `unknown'
# because (1) that's what they normally are, and
# (2) the word "unknown" tends to confuse beginning users.
@@ -319,25 +370,31 @@ case $basic_machine in
# Recognize the basic CPU types with company name.
580-* \
| a29k-* \
| aarch64-* | aarch64_be-* \
| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
| alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \
| arm-* | armbe-* | armle-* | armeb-* | armv*-* \
| avr-* | avr32-* \
| be32-* | be64-* \
| bfin-* | bs2000-* \
| c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
| clipper-* | craynv-* | cydra-* \
| c[123]* | c30-* | [cjt]90-* | c4x-* \
| c8051-* | clipper-* | craynv-* | cydra-* \
| d10v-* | d30v-* | dlx-* \
| elxsi-* \
| e2k-* | elxsi-* \
| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
| h8300-* | h8500-* \
| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
| hexagon-* \
| i*86-* | i860-* | i960-* | ia64-* \
| ip2k-* | iq2000-* \
| k1om-* \
| le32-* | le64-* \
| lm32-* \
| m32c-* | m32r-* | m32rle-* \
| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
| m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
| microblaze-* | microblazeel-* \
| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
| mips16-* \
| mips64-* | mips64el-* \
@@ -351,32 +408,42 @@ case $basic_machine in
| mips64vr5900-* | mips64vr5900el-* \
| mipsisa32-* | mipsisa32el-* \
| mipsisa32r2-* | mipsisa32r2el-* \
| mipsisa32r6-* | mipsisa32r6el-* \
| mipsisa64-* | mipsisa64el-* \
| mipsisa64r2-* | mipsisa64r2el-* \
| mipsisa64r6-* | mipsisa64r6el-* \
| mipsisa64sb1-* | mipsisa64sb1el-* \
| mipsisa64sr71k-* | mipsisa64sr71kel-* \
| mipsr5900-* | mipsr5900el-* \
| mipstx39-* | mipstx39el-* \
| mmix-* \
| mt-* \
| msp430-* \
| nios-* | nios2-* \
| nds32-* | nds32le-* | nds32be-* \
| nios-* | nios2-* | nios2eb-* | nios2el-* \
| none-* | np1-* | ns16k-* | ns32k-* \
| open8-* \
| or1k*-* \
| orion-* \
| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
| pyramid-* \
| romp-* | rs6000-* \
| rl78-* | romp-* | rs6000-* | rx-* \
| sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
| sparclite-* \
| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \
| tahoe-* | thumb-* \
| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* | tile-* \
| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \
| tahoe-* \
| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
| tile*-* \
| tron-* \
| v850-* | v850e-* | vax-* \
| ubicom32-* \
| v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
| vax-* \
| visium-* \
| we32k-* \
| x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \
| x86-* | x86_64-* | xc16x-* | xps100-* \
| xstormy16-* | xtensa*-* \
| ymp-* \
| z8k-* | z80-*)
@@ -401,7 +468,7 @@ case $basic_machine in
basic_machine=a29k-amd
os=-udi
;;
abacus)
abacus)
basic_machine=abacus-unknown
;;
adobe68k)
@@ -451,6 +518,9 @@ case $basic_machine in
basic_machine=i386-pc
os=-aros
;;
asmjs)
basic_machine=asmjs-unknown
;;
aux)
basic_machine=m68k-apple
os=-aux
@@ -467,11 +537,24 @@ case $basic_machine in
basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
os=-linux
;;
bluegene*)
basic_machine=powerpc-ibm
os=-cnk
;;
c54x-*)
basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
c55x-*)
basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
c6x-*)
basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
c90)
basic_machine=c90-cray
os=-unicos
;;
cegcc)
cegcc)
basic_machine=arm-unknown
os=-cegcc
;;
@@ -503,7 +586,7 @@ case $basic_machine in
basic_machine=craynv-cray
os=-unicosmp
;;
cr16)
cr16 | cr16-*)
basic_machine=cr16-unknown
os=-elf
;;
@@ -661,7 +744,6 @@ case $basic_machine in
i370-ibm* | ibm*)
basic_machine=i370-ibm
;;
# I'm not sure what "Sysv32" means. Should this be sysv3.2?
i*86v32)
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
os=-sysv32
@@ -700,6 +782,9 @@ case $basic_machine in
basic_machine=m68k-isi
os=-sysv
;;
leon-*|leon[3-9]-*)
basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'`
;;
m68knommu)
basic_machine=m68k-unknown
os=-linux
@@ -719,8 +804,15 @@ case $basic_machine in
basic_machine=ns32k-utek
os=-sysv
;;
microblaze*)
basic_machine=microblaze-xilinx
;;
mingw64)
basic_machine=x86_64-pc
os=-mingw64
;;
mingw32)
basic_machine=i386-pc
basic_machine=i686-pc
os=-mingw32
;;
mingw32ce)
@@ -748,6 +840,10 @@ case $basic_machine in
basic_machine=powerpc-unknown
os=-morphos
;;
moxiebox)
basic_machine=moxie-unknown
os=-moxiebox
;;
msdos)
basic_machine=i386-pc
os=-msdos
@@ -755,10 +851,18 @@ case $basic_machine in
ms1-*)
basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
;;
msys)
basic_machine=i686-pc
os=-msys
;;
mvs)
basic_machine=i370-ibm
os=-mvs
;;
nacl)
basic_machine=le32-unknown
os=-nacl
;;
ncr3000)
basic_machine=i486-ncr
os=-sysv4
@@ -823,6 +927,12 @@ case $basic_machine in
np1)
basic_machine=np1-gould
;;
neo-tandem)
basic_machine=neo-tandem
;;
nse-tandem)
basic_machine=nse-tandem
;;
nsr-tandem)
basic_machine=nsr-tandem
;;
@@ -905,9 +1015,10 @@ case $basic_machine in
;;
power) basic_machine=power-ibm
;;
ppc) basic_machine=powerpc-unknown
ppc | ppcbe) basic_machine=powerpc-unknown
;;
ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
ppc-* | ppcbe-*)
basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
ppcle | powerpclittle | ppc-le | powerpc-little)
basic_machine=powerpcle-unknown
@@ -932,7 +1043,11 @@ case $basic_machine in
basic_machine=i586-unknown
os=-pw32
;;
rdos)
rdos | rdos64)
basic_machine=x86_64-pc
os=-rdos
;;
rdos32)
basic_machine=i386-pc
os=-rdos
;;
@@ -1001,6 +1116,9 @@ case $basic_machine in
basic_machine=i860-stratus
os=-sysv4
;;
strongarm-* | thumb-*)
basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
sun2)
basic_machine=m68000-sun
;;
@@ -1057,20 +1175,8 @@ case $basic_machine in
basic_machine=t90-cray
os=-unicos
;;
tic54x | c54x*)
basic_machine=tic54x-unknown
os=-coff
;;
tic55x | c55x*)
basic_machine=tic55x-unknown
os=-coff
;;
tic6x | c6x*)
basic_machine=tic6x-unknown
os=-coff
;;
tile*)
basic_machine=tile-unknown
basic_machine=$basic_machine-unknown
os=-linux-gnu
;;
tx39)
@@ -1140,6 +1246,9 @@ case $basic_machine in
xps | xps100)
basic_machine=xps100-honeywell
;;
xscale-* | xscalee[bl]-*)
basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'`
;;
ymp)
basic_machine=ymp-cray
os=-unicos
@@ -1237,9 +1346,12 @@ esac
if [ x"$os" != x"" ]
then
case $os in
# First match some system type aliases
# that might get confused with valid system types.
# First match some system type aliases
# that might get confused with valid system types.
# -solaris* is a basic system type, with this one exception.
-auroraux)
os=-auroraux
;;
-solaris1 | -solaris1.*)
os=`echo $os | sed -e 's|solaris1|sunos4|'`
;;
@@ -1260,30 +1372,31 @@ case $os in
# Each alternative MUST END IN A *, to match a version number.
# -sysv* is not here because it comes later, after sysvr4.
-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
| -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
| -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
| -kopensolaris* \
| -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
| -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
| -sym* | -kopensolaris* | -plan9* \
| -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
| -aos* | -aros* \
| -aos* | -aros* | -cloudabi* \
| -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
| -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
| -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
| -openbsd* | -solidbsd* \
| -bitrig* | -openbsd* | -solidbsd* \
| -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
| -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
| -chorusos* | -chorusrdb* | -cegcc* \
| -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
| -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \
| -uxpv* | -beos* | -mpeix* | -udk* \
| -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
| -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
| -linux-newlib* | -linux-musl* | -linux-uclibc* \
| -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \
| -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
| -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
| -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
| -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
| -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
| -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
| -skyos* | -haiku* | -rdos* | -toppers* | -drops*)
| -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* | -tirtos*)
# Remember, each alternative MUST END IN *, to match a version number.
;;
-qnx*)
@@ -1322,7 +1435,7 @@ case $os in
-opened*)
os=-openedition
;;
-os400*)
-os400*)
os=-os400
;;
-wince*)
@@ -1371,7 +1484,7 @@ case $os in
-sinix*)
os=-sysv4
;;
-tpf*)
-tpf*)
os=-tpf
;;
-triton*)
@@ -1407,15 +1520,14 @@ case $os in
-aros*)
os=-aros
;;
-kaos*)
os=-kaos
;;
-zvmoe)
os=-zvmoe
;;
-dicos*)
os=-dicos
;;
-nacl*)
;;
-none)
;;
*)
@@ -1438,10 +1550,10 @@ else
# system, and we'll never get to this point.
case $basic_machine in
score-*)
score-*)
os=-elf
;;
spu-*)
spu-*)
os=-elf
;;
*-acorn)
@@ -1453,8 +1565,23 @@ case $basic_machine in
arm*-semi)
os=-aout
;;
c4x-* | tic4x-*)
os=-coff
c4x-* | tic4x-*)
os=-coff
;;
c8051-*)
os=-elf
;;
hexagon-*)
os=-elf
;;
tic54x-*)
os=-coff
;;
tic55x-*)
os=-coff
;;
tic6x-*)
os=-coff
;;
# This must come before the *-dec entry.
pdp10-*)
@@ -1474,14 +1601,11 @@ case $basic_machine in
;;
m68000-sun)
os=-sunos3
# This also exists in the configure program, but was not the
# default.
# os=-sunos4
;;
m68*-cisco)
os=-aout
;;
mep-*)
mep-*)
os=-elf
;;
mips*-cisco)
@@ -1508,7 +1632,7 @@ case $basic_machine in
*-ibm)
os=-aix
;;
*-knuth)
*-knuth)
os=-mmixware
;;
*-wec)
@@ -1613,7 +1737,7 @@ case $basic_machine in
-sunos*)
vendor=sun
;;
-aix*)
-cnk*|-aix*)
vendor=ibm
;;
-beos*)
+8 -1
View File
@@ -82,7 +82,7 @@ CFLAGS="$iverilog_temp_cflags"
AC_SUBST(DEPENDENCY_FLAG, [-MD])
AC_SUBST(WARNING_FLAGS, ["-Wall $iverilog_wextra_flag -Wshadow"])
AC_SUBST(WARNING_FLAGS_CC, [""])
AC_SUBST(WARNING_FLAGS_CC, ["-Wstrict-prototypes"])
AC_SUBST(WARNING_FLAGS_CXX, [""])
fi
@@ -223,6 +223,10 @@ case "${host}" in
CPPFLAGS="-mieee $CPPFLAGS"
CFLAGS="-mieee $CFLAGS"
;;
*-*-mingw*)
CXXFLAGS="-D__USE_MINGW_ANSI_STDIO=1 $CXXFLAGS"
CFLAGS="-D__USE_MINGW_ANSI_STDIO=1 $CFLAGS"
;;
esac
# Do some more operating system specific setup. We put the file64_support
@@ -238,6 +242,9 @@ case "${host}" in
esac
AC_SUBST(file64_support)
# fstapi.c (from GTKWave) needs this define.
AC_CHECK_FUNCS(realpath)
# Check that these functions exist. They are mostly C99
# functions that older compilers may not yet support.
AC_CHECK_FUNCS(fopen64)
+2 -2
View File
@@ -1,3 +1,3 @@
// These are correct and are used to find the base (zero) pin.
thisSubtraction:netlist.h:4938
thisSubtraction:netlist.h:4947
thisSubtraction:netlist.h:4976
thisSubtraction:netlist.h:4985
+19 -4
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998-2014 Stephen Williams ([email protected])
* Copyright (c) 1998-2015 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
@@ -677,8 +677,12 @@ void NetConst::dump_node(ostream&o, unsigned ind) const
void NetFF::dump_node(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "LPM_FF: " << name()
<< " scope=" << scope_path(scope())
<< " aset_value=" << aset_value_ << endl;
<< " scope=" << scope_path(scope());
if (negedge_)
o << " negedge";
else
o << " posedge";
o << " aset_value=" << aset_value_ << endl;
dump_node_pins(o, ind+4);
dump_obj_attr(o, ind+4);
@@ -1375,6 +1379,7 @@ void NetScope::dump(ostream&o) const
if (is_cell()) o << " (cell)";
if (nested_module()) o << " (nested)";
if (program_block()) o << " (program)";
if (is_interface()) o << " (interface)";
o << " " << children_.size() << " children, "
<< classes_.size() << " classes" << endl;
@@ -1661,6 +1666,16 @@ void NetEBinary::dump(ostream&o) const
o << ")";
}
void NetECast::dump(ostream&fd) const
{
if (op_=='2')
fd << "bool<" << expr_width() << ">(" << *expr_ << ")";
else if (op_=='4')
fd << "logic<" << expr_width() << ">(" << *expr_ << ")";
else
NetEUnary::dump(fd);
}
void NetEConcat::dump(ostream&o) const
{
if (repeat_ != 1)
@@ -1879,7 +1894,7 @@ void Design::dump(ostream&o) const
cur->second->dump(o);
}
o << "$ROOT CLASSESS:" << endl;
o << "$ROOT CLASSES:" << endl;
for (map<perm_string,netclass_t*>::const_iterator cur = classes_.begin()
; cur != classes_.end() ; ++cur) {
cur->second->dump_scope(o);
+3 -1
View File
@@ -49,6 +49,7 @@ endif
CPPFLAGS = $(INCLUDE_PATH) @CPPFLAGS@ @DEFS@
CFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CC@ @CFLAGS@
CXXFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CXX@ @CXXFLAGS@
LDFLAGS = @LDFLAGS@
O = main.o res.o
@@ -80,11 +81,12 @@ config.h: $(srcdir)/config.h.in Makefile
sed -e 's;@IVLCC@;@CC@;' -e 's;@IVLCXX@;@CXX@;' \
-e 's;@SUFFIX@;$(suffix);g' \
-e 's;@IVLCFLAGS@;$(CFLAGS);' \
-e 's;@IVLCXXFLAGS@;$(CXXFLAGS);' \
-e 's;@SHARED@;@shared@;' $< > $@
# Windows specific...
res.rc: $(srcdir)/res.rc.in ../version.exe
sed -e 's;@PRODUCTVERSION@;'`../version.exe '%M,%m,%n,0'`';' \
sed -e 's;@PRODUCTVERSION@;'`../version.exe '%M,%n,0,0'`';' \
$(srcdir)/res.rc.in > $@
res.o: res.rc
+1
View File
@@ -4,6 +4,7 @@
#define IVERILOG_VPI_CC "@IVLCC@"
#define IVERILOG_VPI_CXX "@IVLCXX@"
#define IVERILOG_VPI_CFLAGS " @IVLCFLAGS@"
#define IVERILOG_VPI_CXXFLAGS " @IVLCXXFLAGS@"
#define IVERILOG_VPI_LDFLAGS "@SHARED@"
#define IVERILOG_VPI_LDLIBS "-lveriuser@SUFFIX@ -lvpi@SUFFIX@"
#define IVERILOG_SUFFIX "@SUFFIX@"
+169 -164
View File
@@ -1,5 +1,6 @@
/*
* 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
@@ -20,7 +21,7 @@
/*
* iverilog-vpi.c
*
* this program provides the functionality of iverilog-vpi.sh under Win32
* this program provides the functionality of iverilog-vpi.sh under Windows
*/
#include <stdio.h>
@@ -32,7 +33,7 @@
#include <windows.h>
static void setup_ivl_environment();
static void setup_ivl_environment(void);
static void assign(char **ptr, char *str);
/* The compile options: compiler, flags, etc. are in here */
@@ -43,16 +44,17 @@ static void assign(char **ptr, char *str);
static struct global_strings {
char *pCCSRC; /* list of C source files (*.c) */
char *pCXSRC; /* list of C++ source files (*.cc, *.cpp) */
char *pOBJ; /* list of object files */
char *pLIB; /* list of library files */
char *pINCS; /* list of include directories */
char *pDEFS; /* list of definitions */
char *pOUT; /* output file name (.vpi extension), if 0 length then no source files specified */
char *pOBJ; /* list of object files */
char *pLIB; /* list of library files */
char *pINCS; /* list of include directories */
char *pDEFS; /* list of definitions */
char *pOUT; /* output file name (.vpi extension), if 0 length then no source files specified */
char *pMINGW; /* path to MinGW directory */
char *pIVL; /* path to IVL directory */
char *pCFLAGS; /* CFLAGS option */
char *pLDLIBS; /* LDLIBS option */
char *pNewPath; /* new PATH environment variable setting */
char *pIVL; /* path to IVL directory */
char *pCCFLAGS; /* compiler flags for compiling C source files */
char *pCXFLAGS; /* compiler flags for compiling C++ source files */
char *pLDLIBS; /* linker flags for final linking stage */
char *pCCNAME; /* base name of compiler */
char *pLD; /* what to use for a linker */
} gstr;
@@ -75,21 +77,21 @@ static void myExit(int exitVal)
deInitDynString(gstr.pOUT);
deInitDynString(gstr.pMINGW);
deInitDynString(gstr.pIVL);
deInitDynString(gstr.pCFLAGS);
deInitDynString(gstr.pCCFLAGS);
deInitDynString(gstr.pCXFLAGS);
deInitDynString(gstr.pLDLIBS);
deInitDynString(gstr.pNewPath);
free(gstr.pLD);
deInitDynString(gstr.pCCNAME);
deInitDynString(gstr.pLD);
exit(exitVal);
}
/* display usage summary and exit */
static void usage()
static void usage(void)
{
fprintf(stderr,"usage: iverilog-vpi" IVERILOG_SUFFIX " [src and obj files]...\n");
fprintf(stderr," or iverilog-vpi" IVERILOG_SUFFIX " -mingw=dir\n");
fprintf(stderr," or iverilog-vpi" IVERILOG_SUFFIX " -ivl=dir\n");
fprintf(stderr, "usage: iverilog-vpi" IVERILOG_SUFFIX " [options] [src and obj files]...\n");
fprintf(stderr, " or iverilog-vpi" IVERILOG_SUFFIX " -mingw=dir\n");
myExit(1);
}
@@ -98,7 +100,7 @@ static void initDynString(char **str)
*str = (char *) malloc(1);
if (!*str) {
fprintf(stderr,"error: out of memory\n");
fprintf(stderr, "error: out of memory\n");
myExit(4);
}
@@ -107,8 +109,10 @@ static void initDynString(char **str)
/* initialize dynamic memory buffers */
static void init()
static void init(void)
{
char *ptr;
initDynString(&gstr.pCCSRC);
initDynString(&gstr.pCXSRC);
initDynString(&gstr.pOBJ);
@@ -118,9 +122,17 @@ static void init()
initDynString(&gstr.pOUT);
initDynString(&gstr.pMINGW);
initDynString(&gstr.pIVL);
initDynString(&gstr.pCFLAGS);
initDynString(&gstr.pCCFLAGS);
initDynString(&gstr.pCXFLAGS);
initDynString(&gstr.pLDLIBS);
initDynString(&gstr.pNewPath);
initDynString(&gstr.pCCNAME);
initDynString(&gstr.pLD);
/* Get the base name of the C compiler. */
assign(&gstr.pCCNAME, IVERILOG_VPI_CC);
ptr = strchr(gstr.pCCNAME, ' ');
if (ptr != NULL) *ptr = '\0';
/* By default use the C compiler to link the programs. */
assign(&gstr.pLD, IVERILOG_VPI_CC);
}
@@ -136,7 +148,7 @@ static int endsIn (char *end, char *str)
ext = str + (strlen(str) - strlen(end));
return stricmp(end,ext) ? 0 : 1;
return stricmp(end, ext) ? 0 : 1;
}
/* return true if "str" begins with "prefix", case insensitive */
@@ -146,35 +158,35 @@ static int startsWith (char *prefix, char *str)
if (strlen(prefix) >= strlen(str))
return 0;
return strnicmp(prefix,str,strlen(prefix)) ? 0 : 1;
return strnicmp(prefix, str, strlen(prefix)) ? 0 : 1;
}
/* append "app" to "ptr", allocating memory as needed */
/* if count is zero, then copy all characters of "app" */
static void appendn (char **ptr, char *app, int count)
static void appendn (char **ptr, char *app, size_t count)
{
char *nptr = (char *) realloc(*ptr, strlen(*ptr) +
(count?count:strlen(app)) + 1);
(count ? count : strlen(app)) + 1);
if (nptr == NULL) {
fprintf(stderr,"error: out of memory\n");
fprintf(stderr, "error: out of memory\n");
free(*ptr);
myExit(4);
}
*ptr = nptr;
if (count)
strncat(*ptr,app,count);
strncat(*ptr, app, count);
else
strcat(*ptr,app);
strcat(*ptr, app);
}
/* append "app" to "ptr", allocating memory as needed */
static void append (char **ptr, char *app)
{
appendn(ptr,app,0);
appendn(ptr, app, 0);
}
/* if the string does not end with a backslash, add one */
@@ -182,36 +194,36 @@ static void append (char **ptr, char *app)
static void appendBackSlash(char **str)
{
if ((*str)[strlen(*str)-1] != '\\')
append(str,"\\");
append(str, "\\");
}
/* copy count characters of "str" to "ptr", allocating memory as needed */
/* if count is zero, then copy all characters of "str" */
static void assignn (char **ptr, char *str, int count)
static void assignn (char **ptr, char *str, size_t count)
{
char *nptr = (char *) realloc(*ptr, (count?count:strlen(str)) + 1);
char *nptr = (char *) realloc(*ptr, (count ? count : strlen(str)) + 1);
if (nptr == NULL) {
fprintf(stderr,"error: out of memory\n");
fprintf(stderr, "error: out of memory\n");
free(*ptr);
myExit(4);
}
*ptr = nptr;
if (count) {
strncpy(*ptr,str,count);
strncpy(*ptr, str, count);
(*ptr)[count] = 0;
}
else
strcpy(*ptr,str);
strcpy(*ptr, str);
}
/* copy count characters of "str" to "ptr", allocating memory as needed */
static void assign (char **ptr, char *str)
{
assignn(ptr,str,0);
assignn(ptr, str, 0);
}
/* get a copy of a Icarus Verilog registry string key */
@@ -223,11 +235,11 @@ static int GetRegistryKey(char *key, char **value)
char *regKeyBuffer;
DWORD regKeyType, regKeySize;
lrv = RegOpenKeyEx(HKEY_LOCAL_MACHINE,"Software\\Icarus Verilog",0,KEY_QUERY_VALUE,&hkKey);
lrv = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\Icarus Verilog", 0, KEY_QUERY_VALUE, &hkKey);
if (lrv != ERROR_SUCCESS)
return 0;
lrv = RegQueryValueEx(hkKey,key,NULL,&regKeyType,NULL,&regKeySize);
lrv = RegQueryValueEx(hkKey, key, NULL, &regKeyType, NULL, &regKeySize);
if ((lrv != ERROR_SUCCESS) || (regKeyType != REG_SZ) || (!regKeySize)) {
lrv = RegCloseKey(hkKey);
return 0;
@@ -236,7 +248,7 @@ static int GetRegistryKey(char *key, char **value)
regKeyBuffer = (char *) malloc(regKeySize+1);
if (!regKeyBuffer) {
lrv = RegCloseKey(hkKey);
fprintf(stderr,"error: out of memory\n");
fprintf(stderr, "error: out of memory\n");
myExit(4);
}
regKeyBuffer[regKeySize] = 0; /* makes sure there is a trailing NULL */
@@ -252,7 +264,7 @@ static int GetRegistryKey(char *key, char **value)
RegCloseKey(hkKey);
assign(value,regKeyBuffer);
assign(value, regKeyBuffer);
free(regKeyBuffer);
return 1;
@@ -262,27 +274,30 @@ static int GetRegistryKey(char *key, char **value)
static void SetRegistryKey(char *key, char *value)
{
long lrv;
HKEY hkKey;
DWORD res;
if (RegCreateKeyEx(
HKEY_LOCAL_MACHINE,
"Software\\Icarus Verilog",
0,
"",
REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS,NULL,
&hkKey,
&res) != ERROR_SUCCESS)
return;
lrv = RegCreateKeyEx(HKEY_LOCAL_MACHINE, "Software\\Icarus Verilog", 0, "",
REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkKey, &res);
if (lrv != ERROR_SUCCESS) {
char message[1024];
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, lrv, LANG_USER_DEFAULT,
message, sizeof(message), NULL);
fprintf(stderr, "error: couldn't write to registry - %s\n", message);
if (lrv == ERROR_ACCESS_DENIED) {
fprintf(stderr, " try running as administrator\n");
}
return;
}
/* This needs an unsigned char *, but for MinGW the char is signed. */
RegSetValueEx(hkKey, key, 0, REG_SZ, (unsigned char *) value,
strlen(value)+1);
RegCloseKey(hkKey);
printf("info: storing %s in Windows' registry entry\n",value);
printf(" HKEY_LOCAL_MACHINE\\Software\\Icarus Verilog\\%s\n",key);
printf("info: storing %s in Windows' registry entry\n", value);
printf(" HKEY_LOCAL_MACHINE\\Software\\Icarus Verilog\\%s\n", key);
}
/* parse the command line, assign results to global variable strings */
@@ -299,7 +314,6 @@ static int parse(int argc, char *argv[])
char lib_option[] = "-l";
char inc_option[] = "-I";
char mingw_option[] = "-mingw=";
char ivl_option[] = "-ivl=";
char def_option[] = "-D";
if (argc == 1) return 0;
@@ -339,7 +353,7 @@ static int parse(int argc, char *argv[])
/* Check for compiled object files */
else if (endsIn(dot_o_ext, argv[idx])) {
++srcFileCnt;
append(&gstr.pOBJ," ");
append(&gstr.pOBJ, " ");
append(&gstr.pOBJ, argv[idx]);
if (!*gstr.pOUT)
assignn(&gstr.pOUT, argv[idx],
@@ -349,10 +363,6 @@ static int parse(int argc, char *argv[])
else if (startsWith(mingw_option, argv[idx]))
assignn(&gstr.pMINGW, argv[idx]+sizeof(mingw_option)-1,
strlen(argv[idx])-(sizeof(mingw_option)-1));
/* Check for the -ivl option */
else if (startsWith(ivl_option, argv[idx]))
assignn(&gstr.pIVL, argv[idx]+sizeof(ivl_option)-1,
strlen(argv[idx])-(sizeof(ivl_option)-1));
/* Check for the --name option */
else if (startsWith(name_option, argv[idx])) {
assignn(&gstr.pOUT, argv[idx]+sizeof(name_option)-1,
@@ -376,7 +386,7 @@ static int parse(int argc, char *argv[])
/* Check for the --cflags option */
else if (stricmp("--cflags", argv[idx]) == 0) {
setup_ivl_environment();
printf("%s\n", gstr.pCFLAGS);
printf("%s\n", gstr.pCCFLAGS);
myExit(0);
}
/* Check for the --ldflags option */
@@ -393,7 +403,7 @@ static int parse(int argc, char *argv[])
/* Check for the --install-dir option */
else if (stricmp("--install-dir", argv[idx]) == 0) {
setup_ivl_environment();
printf("%s\\\\lib\\\\ivl" IVERILOG_SUFFIX "\\\\.\n", gstr.pIVL);
printf("%s\\lib\\ivl" IVERILOG_SUFFIX "\\.\n", gstr.pIVL);
myExit(0);
}
/* This is different than iverilog-vpi.sh, we don't
@@ -402,15 +412,16 @@ static int parse(int argc, char *argv[])
}
/* In case there is a --name without source/object files */
if (0 == srcFileCnt) assign(&gstr.pOUT,"");
if (0 == srcFileCnt) assign(&gstr.pOUT, "");
/* Normally it's an error if there are no source or object files */
/* Unless we are setting the IVL or MinGW registry entries */
if (!*gstr.pOUT) {
if (!*gstr.pMINGW && !*gstr.pIVL) return 0;
} else
if (*gstr.pOUT) {
/* We have a valid result file so add the .vpi extension */
append(&gstr.pOUT, ".vpi");
} else {
/* Unless we are setting the MinGW registry entry, it's
an error if there are no source or object files */
if (!*gstr.pMINGW) return 0;
}
return 1;
}
@@ -421,58 +432,27 @@ static void checkMingwDir(char *root)
{
int irv;
struct _stat stat_buf;
char *path, *comp, *cp;
initDynString(&path);
assign(&path,gstr.pMINGW);
appendBackSlash(&path);
append(&path,"bin\\");
/* Get just the compiler name (the first word) */
comp = strdup(IVERILOG_VPI_CC);
cp = strchr(comp, ' ');
if (cp != NULL) *cp = '\0';
append(&path, comp);
append(&path,".exe");
free(comp);
irv = _stat(path,&stat_buf);
deInitDynString(path);
if (irv) {
fprintf(stderr,"error: %s does not appear to be the valid root directory\n",root);
fprintf(stderr," of MinGW. Use the -mingw option of iverilog-vpi.exe to\n");
fprintf(stderr," point to the MinGW root directory. For a Windows command\n");
fprintf(stderr," shell the option would be something like -mingw=c:\\mingw\n");
fprintf(stderr," For a Cygwin shell the option would be something like\n");
fprintf(stderr," -mingw=c:\\\\mingw\n");
myExit(5);
}
}
/* do minimal check that the Icarus Verilog root directory looks valid */
static void checkIvlDir(char *root)
{
int irv;
struct _stat stat_buf;
char *path;
initDynString(&path);
assign(&path,gstr.pIVL);
assign(&path, gstr.pMINGW);
appendBackSlash(&path);
append(&path,"bin\\vvp" IVERILOG_SUFFIX ".exe");
append(&path, "bin\\");
append(&path, gstr.pCCNAME);
append(&path, ".exe");
irv = _stat(path,&stat_buf);
deInitDynString(path);
if (irv) {
fprintf(stderr,"error: %s does not appear to be the valid root directory of\n",root);
fprintf(stderr," Icarus Verilog. Use the -ivl option of iverilog-vpi" IVERILOG_SUFFIX " to\n");
fprintf(stderr," point to the Icarus Verilog root directory. For a Windows\n");
fprintf(stderr," command shell the option would be something like -ivl=c:\\iverilog\n");
fprintf(stderr," For a Cygwin shell the option would be something like\n");
fprintf(stderr," -ivl=c:\\\\iverilog\n");
myExit(6);
fprintf(stderr, "error: %s\n", root);
fprintf(stderr, " does not appear to be the valid root directory of\n");
fprintf(stderr, " MinGW. Use the -mingw option of iverilog-vpi.exe to\n");
fprintf(stderr, " point to the MinGW root directory. For a Windows command\n");
fprintf(stderr, " shell the option would be something like -mingw=c:\\mingw\n");
fprintf(stderr, " For a Cygwin shell the option would be something like\n");
fprintf(stderr, " -mingw=c:\\\\mingw\n");
myExit(5);
}
}
@@ -480,68 +460,98 @@ static void checkIvlDir(char *root)
#define IVL_REGKEY_MINGW "MingwDir"
static void setup_mingw_environment()
static void setup_mingw_environment(void)
{
char *pOldPATH = getenv("PATH"); /* get current path */
char buffer[1]; /* doesn't matter how big this is, as we don't use the result */
char *path;
if (*gstr.pMINGW) {
checkMingwDir(gstr.pMINGW);
SetRegistryKey(IVL_REGKEY_MINGW,gstr.pMINGW);
} else if (!GetRegistryKey(IVL_REGKEY_MINGW,&gstr.pMINGW)) {
fprintf(stderr,"error: can not locate the MinGW root directory, use the -mingw option of\n");
fprintf(stderr," iverilog-vpi.exe to point to the MinGW root directory. For\n");
fprintf(stderr," a Windows command shell the option would be something like\n");
fprintf(stderr," -mingw=c:\\mingw For a Cygwin shell the option would be\n");
fprintf(stderr," something like -mingw=c:\\\\mingw\n");
myExit(5);
}
if (!*gstr.pOUT) SetRegistryKey(IVL_REGKEY_MINGW, gstr.pMINGW);
} else if (GetRegistryKey(IVL_REGKEY_MINGW, &gstr.pMINGW)) {
checkMingwDir(gstr.pMINGW);
} else if (SearchPath(NULL, gstr.pCCNAME, ".exe", sizeof(buffer), buffer, NULL)) {
return;
} else {
fprintf(stderr, "error: cannot locate the MinGW C compiler - either add its location\n");
fprintf(stderr, " to the PATH environment variable or use the -mingw option of\n");
fprintf(stderr, " iverilog-vpi.exe to point to the MinGW root directory. For\n");
fprintf(stderr, " a Windows command shell the option would be something like\n");
fprintf(stderr, " -mingw=c:\\mingw For a Cygwin shell the option would be\n");
fprintf(stderr, " something like -mingw=c:\\\\mingw\n");
myExit(5);
}
/* Create new path with MinGW in it */
assign(&gstr.pNewPath,"PATH=");
append(&gstr.pNewPath,gstr.pMINGW);
appendBackSlash(&gstr.pNewPath);
append(&gstr.pNewPath, "\\");
append(&gstr.pNewPath,"bin;");
append(&gstr.pNewPath,pOldPATH);
initDynString(&path);
assign(&path, "PATH=");
append(&path, gstr.pMINGW);
appendBackSlash(&path);
append(&path, "bin;");
append(&path, getenv("PATH"));
/* Place new path in environment */
_putenv(gstr.pNewPath);
_putenv(path);
deInitDynString(path);
}
/* see if we can find iverilog root */
/* find the iverilog root and initialise the compiler options */
#define IVL_REGKEY_IVL "InstallDir"
static void setup_ivl_environment()
static void setup_ivl_environment(void)
{
if (*gstr.pIVL) {
checkIvlDir(gstr.pIVL);
SetRegistryKey(IVL_REGKEY_IVL,gstr.pIVL);
} else if (!GetRegistryKey(IVL_REGKEY_IVL,&gstr.pIVL)) {
fprintf(stderr,"error: can not locate the Icarus Verilog root directory, use the -ivl option\n");
fprintf(stderr," of iverilog-vpi" IVERILOG_SUFFIX " to point to the Icarus Verilog root directory.\n");
fprintf(stderr," For a Windows command shell the option would be something like\n");
fprintf(stderr," -ivl=c:\\iverilog For a Cygwin shell the option would be something\n");
fprintf(stderr," like -ivl=c:\\\\iverilog\n");
myExit(6);
}
char path[4096];
char *ptr;
/* Build up the CFLAGS option string */
assign(&gstr.pCFLAGS,IVERILOG_VPI_CFLAGS " -I\"");
append(&gstr.pCFLAGS,gstr.pIVL);
appendBackSlash(&gstr.pCFLAGS);
append(&gstr.pCFLAGS,"\\include\\\\iverilog\"" IVERILOG_SUFFIX);
/* Extract the Icarus Verilog root directory from the path to the
command. The command path will look something like this:
C:\iverilog\bin\iverilog-vpi.exe
The corresponding root directory is
C:\iverilog
so we chop off the file name and the last directory. */
GetModuleFileName(NULL, path, sizeof(path));
ptr = strrchr(path, '\\');
if (!ptr) {
fprintf(stderr, "error: couldn't find start of program name in command path '%s'\n", path);
myExit(6);
}
*ptr = 0;
ptr = strrchr(path, '\\');
if (!ptr) {
fprintf(stderr, "error: couldn't find start of bin directory in command path '%s'\n", path);
myExit(6);
}
*ptr = 0;
assign(&gstr.pIVL, path);
/* Build up the CCFLAGS option string */
assign(&gstr.pCCFLAGS, IVERILOG_VPI_CFLAGS " -I\"");
append(&gstr.pCCFLAGS, gstr.pIVL);
appendBackSlash(&gstr.pCCFLAGS);
append(&gstr.pCCFLAGS, "include\\iverilog\"" IVERILOG_SUFFIX);
/* Build up the CXFLAGS option string */
assign(&gstr.pCXFLAGS, IVERILOG_VPI_CXXFLAGS " -I\"");
append(&gstr.pCXFLAGS, gstr.pIVL);
appendBackSlash(&gstr.pCXFLAGS);
append(&gstr.pCXFLAGS, "include\\iverilog\"" IVERILOG_SUFFIX);
/* Build up the LDFLAGS option string */
assign(&gstr.pLDLIBS,"-L\"");
append(&gstr.pLDLIBS,gstr.pIVL);
assign(&gstr.pLDLIBS, "-L\"");
append(&gstr.pLDLIBS, gstr.pIVL);
appendBackSlash(&gstr.pLDLIBS);
append(&gstr.pLDLIBS,"\\lib\" " IVERILOG_VPI_LDLIBS);
append(&gstr.pLDLIBS, "lib\" " IVERILOG_VPI_LDLIBS);
}
/* compile source modules */
static void compile(char *pSource, char **pObject, int *compile_errors, char *compiler)
static void compile(char *pSource, char *pFlags, char **pObject, int *compile_errors, char *compiler)
{
char *ptr1 = pSource;
char *ptr2 = strchr(ptr1, ' ');
@@ -568,7 +578,7 @@ static void compile(char *pSource, char **pObject, int *compile_errors, char *co
append(&buf, " ");
append(&buf, gstr.pDEFS);
append(&buf, " ");
append(&buf, gstr.pCFLAGS);
append(&buf, pFlags);
append(&buf, " ");
append(&buf, gstr.pINCS);
append(&buf, " ");
@@ -593,27 +603,22 @@ static void compile(char *pSource, char **pObject, int *compile_errors, char *co
/* using the global strings, compile and link */
static void compile_and_link()
static void compile_and_link(void)
{
char *buf=0;
int iRet, compile_errors = 0;
/* To make the output match iverilog-vpi.sh do not print out the
* root directories */
// printf("MinGW root directory: %s.\n", gstr.pMINGW);
checkMingwDir(gstr.pMINGW);
// printf("Icarus Verilog root directory: %s.\n", gstr.pIVL);
checkIvlDir(gstr.pIVL);
/* compile the C source files (*.c) */
compile(gstr.pCCSRC, &gstr.pOBJ, &compile_errors, IVERILOG_VPI_CC );
compile(gstr.pCCSRC, gstr.pCCFLAGS, &gstr.pOBJ, &compile_errors, IVERILOG_VPI_CC );
/* compile the C++ source files (*.cc, *.cpp) */
compile(gstr.pCXSRC, &gstr.pOBJ, &compile_errors, IVERILOG_VPI_CXX);
compile(gstr.pCXSRC, gstr.pCXFLAGS, &gstr.pOBJ, &compile_errors, IVERILOG_VPI_CXX);
if (compile_errors) {
fprintf(stderr,"iverilog-vpi: %d file(s) failed to compile.\n",
fprintf(stderr, "iverilog-vpi: %d file(s) failed to compile.\n",
compile_errors);
myExit(2);
}
@@ -644,7 +649,7 @@ int main(int argc, char *argv[])
{
init();
if (!parse(argc,argv)) usage();
if (!parse(argc, argv)) usage();
setup_mingw_environment();
setup_ivl_environment();
+3 -2
View File
@@ -4,7 +4,7 @@
%{
/*
* Copyright (c) 2001-2014 Stephen Williams ([email protected])
* Copyright (c) 2001-2016 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
@@ -124,7 +124,8 @@ int cmdfile_stack_ptr = 0;
"-c" { return TOK_Dc; }
"-f" { return TOK_Dc; }
/* Notice the -v flag. */
/* Notice the -l or -v flag. */
"-l" { return TOK_Dv; }
"-v" { return TOK_Dv; }
/* Notice the -y flag. */
+47 -9
View File
@@ -1,14 +1,15 @@
.TH iverilog 1 "February 26th, 2014" "" "Version %M.%m.%n %E"
.TH iverilog 1 "Oct 2nd, 2016" "" "Version %M.%n%E"
.SH NAME
iverilog - Icarus Verilog compiler
.SH SYNOPSIS
.B iverilog
[\-ESVv] [\-Bpath] [\-ccmdfile|\-fcmdfile] [\-Dmacro[=defn]]
[\-Pparameter=value] [\-pflag=value]
[\-dname] [\-g1995|\-g2001|\-g2005|\-g2005-sv|\-g2009|\-g2012|\-g<feature>]
[\-Pparameter=value] [\-pflag=value] [\-dname]
[\-g1995\:|\-g2001\:|\-g2005\:|\-g2005-sv\:|\-g2009\:|\-g2012\:|\-g<feature>]
[\-Iincludedir] [\-mmodule] [\-M[mode=]file] [\-Nfile] [\-ooutputfilename]
[\-stopmodule] [\-ttype] [\-Tmin/typ/max] [\-Wclass] [\-ypath] sourcefile
[\-stopmodule] [\-ttype] [\-Tmin/typ/max] [\-Wclass] [\-ypath] [\-lfile]
sourcefile
.SH DESCRIPTION
.PP
@@ -30,7 +31,7 @@ different set of programs. The path given is used to locate
\fIivlpp\fP, \fIivl\fP, code generators and the VPI modules.
.TP 8
.B -c\fIfile\fP -f\fIfile\fP
These flags specifies an input file that contains a list of Verilog
These flags specify an input file that contains a list of Verilog
source files. This is similar to the \fIcommand file\fP of other
Verilog simulators, in that it is a file that contains the file names
instead of taking them on the command line. See \fBCommand Files\fP below.
@@ -133,12 +134,29 @@ parameter assignment is evaluated as a lossless expression, as is any
expression containing an unsized constant number, and unsized constant
numbers are not truncated to integer width.
.TP 8
.B -gshared-loop-index\fI|\fP-gno-shared-loop-index
Enable or disable (default) the exclusion of for-loop control variables
from implicit event_expression lists. When enabled, if a for-loop control
variable (loop index) is only used inside the for-loop statement, the
compiler will not include it in an implicit event_expression list it
calculates for that statement or any enclosing statement. This allows
the same control variable to be used in multiple processes without risk
of entering an infinite loop caused by each process triggering all other
processes that use the same varaible. For strict compliance with the
standards, this behaviour should be disabled.
.TP 8
.B -I\fIincludedir\fP
Append directory \fIincludedir\fP to list of directories searched
for Verilog include files. The \fB\-I\fP switch may be used many times
to specify several directories to search, the directories are searched
in the order they appear on the command line.
.TP 8
.B -l\fIfile\fP
Add the specified file to the list of source files to be compiled,
but mark it as a library file. All modules contained within that
file will be treated as library modules, and only elaborated if
they are instantiated by other modules in the design.
.TP 8
.B -M\fIpath\fP
This is equivalent to \fB\-Mall=path\fP. Preserved for backwards
compatibility.
@@ -213,6 +231,12 @@ a reference to a key temporary file that passes information to the
compiler proper. To keep that file from being deleted at the end
of the process, provide a file name of your own in the environment
variable \fBIVERILOG_ICONFIG\fP.
If the selected target is \fIvvp\fP, the \fB\-v\fP switch is appended
to the shebang line in the compiler output file, so directly executing
the compiler output file will turn on verbose messages in \fIvvp\fP.
This extra verbosity can be avoided by using the \fIvvp\fP command to
indirectly execute the compiler output file.
.TP 8
.B -V
Print the version of the compiler, and exit.
@@ -286,8 +310,13 @@ after a \fB\-Wall\fP argument to suppress isolated warning types.
.TP 8
.B all
This enables the implicit, portbind, select\-range, timescale, and
sensitivity\-entire\-array warning categories.
This enables the anachronisms, implicit, portbind, select\-range,
timescale, and sensitivity\-entire\-array warning categories.
.TP 8
.B anachronisms
This enables warnings for use of features that have been deprecated
or removed in the selected generation of the Verilog language.
.TP 8
.B implicit
@@ -391,6 +420,15 @@ A \fB\-c\fP or \fB\-f\fP token prefixes a command file, exactly like it
does on the command line. The cmdfile may be on the same line or the
next non-comment line.
.TP 8
.B -l\ \fIfile\fP -v\ \fIfile\fP
A \fB\-l\fP token prefixes a library file in the command file,
exactly like it does on the command line. The parameter to the \fB\-l\fP
flag may be on the same line or the next non-comment line. \fB\-v\fP is
an alias for \fB\-l\fP, provided for compatibility with other simulators.
Variables in the \fIfile\fP are substituted.
.TP 8
.B -y\ \fIlibdir\fP
A \fB\-y\fP token prefixes a library directory in the command file,
@@ -514,14 +552,14 @@ Steve Williams ([email protected])
.SH SEE ALSO
vvp(1),
.BR "<http://www.icarus.com/eda/verilog/>"
.BR "<http://iverilog.icarus.com/>"
Tips on using, debugging, and developing the compiler can be found at
.BR "<http://iverilog.wikia.com/>"
.SH COPYRIGHT
.nf
Copyright \(co 2002\-2014 Stephen Williams
Copyright \(co 2002\-2016 Stephen Williams
This document can be freely redistributed according to the terms of the
GNU General Public License version 2.0
+31 -14
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2000-2014 Stephen Williams (steve@icarus.com)
* Copyright (c) 2000-2016 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
@@ -44,7 +44,7 @@ const char HELP[] =
" [-M [mode=]depfile] [-m module]\n"
" [-N file] [-o filename] [-p flag=value]\n"
" [-s topmodule] [-t target] [-T min|typ|max]\n"
" [-W class] [-y dir] [-Y suf] source_file(s)\n"
" [-W class] [-y dir] [-Y suf] [-l file] source_file(s)\n"
"\n"
"See the man page for details.";
@@ -128,6 +128,7 @@ const char*gen_icarus = "icarus-misc";
const char*gen_io_range_error = "io-range-error";
const char*gen_strict_ca_eval = "no-strict-ca-eval";
const char*gen_strict_expr_width = "no-strict-expr-width";
const char*gen_shared_loop_index = "no-shared-loop-index";
const char*gen_verilog_ams = "no-verilog-ams";
/* Boolean: true means use a default include dir, false means don't */
@@ -496,6 +497,7 @@ static void process_warning_switch(const char*name)
if (strcmp(name,"all") == 0) {
process_warning_switch("anachronisms");
process_warning_switch("implicit");
process_warning_switch("implicit-dimensions");
process_warning_switch("portbind");
process_warning_switch("select-range");
process_warning_switch("timescale");
@@ -506,6 +508,9 @@ static void process_warning_switch(const char*name)
} else if (strcmp(name,"implicit") == 0) {
if (! strchr(warning_flags, 'i'))
strcat(warning_flags, "i");
} else if (strcmp(name,"implicit-dimensions") == 0) {
if (! strchr(warning_flags, 'd'))
strcat(warning_flags, "d");
} else if (strcmp(name,"portbind") == 0) {
if (! strchr(warning_flags, 'p'))
strcat(warning_flags, "p");
@@ -538,6 +543,12 @@ static void process_warning_switch(const char*name)
cp[0] = cp[1];
cp += 1;
}
} else if (strcmp(name,"no-implicit-dimensions") == 0) {
char*cp = strchr(warning_flags, 'd');
if (cp) while (*cp) {
cp[0] = cp[1];
cp += 1;
}
} else if (strcmp(name,"no-portbind") == 0) {
char*cp = strchr(warning_flags, 'p');
if (cp) while (*cp) {
@@ -568,6 +579,9 @@ static void process_warning_switch(const char*name)
cp[0] = cp[1];
cp += 1;
}
} else {
fprintf(stderr, "Ignoring unknown warning class "
"%s\n", name);
}
}
@@ -717,6 +731,12 @@ static int process_generation(const char*name)
else if (strcmp(name,"no-strict-expr-width") == 0)
gen_strict_expr_width = "no-strict-expr-width";
else if (strcmp(name,"shared-loop-index") == 0)
gen_shared_loop_index = "shared-loop-index";
else if (strcmp(name,"no-shared-loop-index") == 0)
gen_shared_loop_index = "no-shared-loop-index";
else if (strcmp(name,"verilog-ams") == 0)
gen_verilog_ams = "verilog-ams";
@@ -742,7 +762,8 @@ static int process_generation(const char*name)
" icarus-misc | no-icarus-misc\n"
" io-range-error | no-io-range-error\n"
" strict-ca-eval | no-strict-ca-eval\n"
" strict-expr-width | no-strict-expr-width\n");
" strict-expr-width | no-strict-expr-width\n"
" shared-loop-index | no-shared-loop-index\n");
return 1;
}
@@ -907,7 +928,7 @@ int main(int argc, char **argv)
}
}
while ((opt = getopt(argc, argv, "B:c:D:d:Ef:g:hI:M:m:N:o:P:p:Ss:T:t:vVW:y:Y:")) != EOF) {
while ((opt = getopt(argc, argv, "B:c:D:d:Ef:g:hl:I:M:m:N:o:P:p:Ss:T:t:vVW:y:Y:")) != EOF) {
switch (opt) {
case 'B':
@@ -962,6 +983,10 @@ int main(int argc, char **argv)
process_include_dir(optarg);
break;
case 'l':
process_file_name(optarg, 1);
break;
case 'M':
if (process_depfile(optarg) != 0)
return -1;
@@ -1044,19 +1069,10 @@ int main(int argc, char **argv)
if (version_flag || verbose_flag) {
printf("Icarus Verilog version " VERSION " (" VERSION_TAG ")\n\n");
printf("Copyright 1998-2013 Stephen Williams\n\n");
printf("Copyright 1998-2015 Stephen Williams\n\n");
puts(NOTICE);
}
if (synth_flag) {
fprintf(stderr, "Warning: Synthesis is not currently being "
"maintained and may not\n");
fprintf(stderr, " function correctly. V0.8 was the "
"last release branch to\n");
fprintf(stderr, " have active synthesis development "
"and support!\n");
}
/* Make a common conf file path to reflect the target. */
snprintf(iconfig_common_path, sizeof iconfig_common_path, "%s%c%s%s.conf",
base, sep, targ, synth_flag? "-s" : "");
@@ -1104,6 +1120,7 @@ int main(int argc, char **argv)
fprintf(iconfig_file, "generation:%s\n", gen_io_range_error);
fprintf(iconfig_file, "generation:%s\n", gen_strict_ca_eval);
fprintf(iconfig_file, "generation:%s\n", gen_strict_expr_width);
fprintf(iconfig_file, "generation:%s\n", gen_shared_loop_index);
fprintf(iconfig_file, "generation:%s\n", gen_verilog_ams);
fprintf(iconfig_file, "generation:%s\n", gen_icarus);
fprintf(iconfig_file, "warnings:%s\n", warning_flags);
+260 -94
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1999-2014 Stephen Williams (steve@icarus.com)
* Copyright (c) 1999-2016 Stephen Williams (steve@icarus.com)
* Copyright CERN 2013 / Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
@@ -90,7 +90,7 @@ static NetBranch* find_existing_implicit_branch(NetNet*sig, NetNet*gnd)
NetExpr* elaborate_rval_expr(Design*des, NetScope*scope, ivl_type_t lv_net_type,
ivl_variable_type_t lv_type, unsigned lv_width,
PExpr*expr, bool need_const)
PExpr*expr, bool need_const, bool force_unsigned)
{
if (debug_elaborate) {
cerr << expr->get_fileline() << ": elaborate_rval_expr: "
@@ -135,7 +135,7 @@ NetExpr* elaborate_rval_expr(Design*des, NetScope*scope, ivl_type_t lv_net_type,
}
return elab_and_eval(des, scope, expr, context_wid, need_const,
false, lv_type);
false, lv_type, force_unsigned);
}
/*
@@ -267,6 +267,13 @@ unsigned PEBinary::test_width(Design*des, NetScope*scope, width_mode_t&mode)
unsigned l_width = left_->test_width(des, scope, mode);
if (debug_elaborate) {
cerr << get_fileline() << ": PEBinary::test_width: "
<< "op_=" << op_ << ", l_width=" << l_width
<< ", r_width=" << r_width
<< ", saved_mode=" << saved_mode << endl;
}
// If the width mode changed, retest the right operand, as it
// may choose a different width if it is in a lossless context.
if ((mode >= LOSSLESS) && (saved_mode < LOSSLESS))
@@ -650,10 +657,13 @@ NetExpr* PEBComp::elaborate_expr(Design*des, NetScope*scope,
case 'E': /* === */
case 'N': /* !== */
if (lp->expr_type() == IVL_VT_REAL ||
rp->expr_type() == IVL_VT_REAL) {
lp->expr_type() == IVL_VT_STRING ||
rp->expr_type() == IVL_VT_REAL ||
rp->expr_type() == IVL_VT_STRING) {
cerr << get_fileline() << ": error: "
<< human_readable_op(op_)
<< " operator may not have REAL operands." << endl;
<< " operator may not have REAL or STRING operands."
<< endl;
des->errors += 1;
return 0;
}
@@ -665,10 +675,7 @@ NetExpr* PEBComp::elaborate_expr(Design*des, NetScope*scope,
NetExpr*tmp = new NetEBComp(op_, lp, rp);
tmp->set_line(*this);
tmp = pad_to_width(tmp, expr_wid, *this);
tmp->cast_signed(signed_flag_);
return tmp;
return pad_to_width(tmp, expr_wid, signed_flag_, *this);
}
unsigned PEBLogic::test_width(Design*, NetScope*, width_mode_t&)
@@ -706,10 +713,7 @@ NetExpr*PEBLogic::elaborate_expr(Design*des, NetScope*scope,
NetExpr*tmp = new NetEBLogic(op_, lp, rp);
tmp->set_line(*this);
tmp = pad_to_width(tmp, expr_wid, *this);
tmp->cast_signed(signed_flag_);
return tmp;
return pad_to_width(tmp, expr_wid, signed_flag_, *this);
}
unsigned PEBLeftWidth::test_width(Design*des, NetScope*scope, width_mode_t&mode)
@@ -717,6 +721,14 @@ unsigned PEBLeftWidth::test_width(Design*des, NetScope*scope, width_mode_t&mode)
ivl_assert(*this, left_);
ivl_assert(*this, right_);
if (debug_elaborate) {
cerr << get_fileline() << ": PEBLeftWidth::test_width: "
<< "op_=" << op_
<< ", left_=" << *left_
<< ", right_=" << *right_
<< ", mode=" << width_mode_name(mode) << endl;
}
// The right operand is self determined. Test its type and
// width for use later. We only need to know its width now
// if the left operand is unsized and we need to calculate
@@ -724,11 +736,26 @@ unsigned PEBLeftWidth::test_width(Design*des, NetScope*scope, width_mode_t&mode)
width_mode_t r_mode = SIZED;
unsigned r_width = right_->test_width(des, scope, r_mode);
expr_width_ = left_->test_width(des, scope, mode);
// The left operand is what will determine the size of the
// expression. The l_mode will be converted to UNSIZED if the
// expression does not have a well-determined size.
width_mode_t l_mode = SIZED;
expr_width_ = left_->test_width(des, scope, l_mode);
expr_type_ = left_->expr_type();
signed_flag_ = left_->has_sign();
if (mode==SIZED)
mode = l_mode;
// The left operand width defines the size of the
// expression. If the expression has a well-defined size, the
// left_->test_width() above would have set mode==SIZED and we
// can skip a lot of stuff. But if the mode is an undetermined
// size, we need to figure out what we really want to keep a
// lossless value. That's what the following if(...) {...} is
// all about.
if ((mode >= EXPAND) && type_is_vectorable(expr_type_)) {
// We need to make our best guess at the right operand
// value, to minimize the calculated width. This is
// particularly important for the power operator...
@@ -755,8 +782,18 @@ unsigned PEBLeftWidth::test_width(Design*des, NetScope*scope, width_mode_t&mode)
right_ = tmp;
}
NetEConst*rc = dynamic_cast<NetEConst*> (rp);
if (rc && (r_width < sizeof(long)*8))
r_val = rc->value().as_long();
// Adjust the expression width that can be converter depending
// on if the R-value is signed or not.
unsigned c_width = sizeof(long)*8;
if (! right_->has_sign()) c_width -= 1;
if (rc && (r_width <= c_width)) r_val = rc->value().as_long();
if (debug_elaborate && rc) {
cerr << get_fileline() << ": PEBLeftWidth::test_width: "
<< "Evaluated rc=" << *rc
<< ", r_val=" << r_val
<< ", width_cap=" << width_cap << endl;
}
// Clip to a sensible range to avoid underflow/overflow
// in the following calculations.
@@ -774,7 +811,8 @@ unsigned PEBLeftWidth::test_width(Design*des, NetScope*scope, width_mode_t&mode)
unsigned use_width = expr_width_;
switch (op_) {
case 'l': // <<
use_width += (unsigned)r_val;
if (l_mode != SIZED)
use_width += (unsigned)r_val;
break;
case 'r': // >>
@@ -812,6 +850,12 @@ unsigned PEBLeftWidth::test_width(Design*des, NetScope*scope, width_mode_t&mode)
if ((rc == 0) && (use_width > expr_width_) && (use_width > integer_width))
use_width = integer_width;
if (use_width >= width_cap) {
cerr << get_fileline() << ": warning: "
<< "Unsized expression (" << *this << ")"
<< " expanded beyond and was clipped to " << use_width
<< " bits. Try using sized operands." << endl;
}
expr_width_ = use_width;
}
@@ -820,6 +864,13 @@ unsigned PEBLeftWidth::test_width(Design*des, NetScope*scope, width_mode_t&mode)
else
min_width_ = UINT_MAX; // disable width pruning
if (debug_elaborate) {
cerr << get_fileline() << ": PEBLeftWidth::test_width: "
<< "Done calculating expr_width_=" << expr_width_
<< ", min_width_=" << min_width_
<< ", mode=" << width_mode_name(mode) << endl;
}
return fix_width_(mode);
}
@@ -978,8 +1029,7 @@ NetExpr*PEBShift::elaborate_expr_leaf(Design*des, NetExpr*lp, NetExpr*rp,
tmp->set_line(*this);
tmp = new NetESelect(lp, tmp, 1);
tmp->set_line(*this);
tmp = pad_to_width(tmp, expr_wid, *this);
tmp->cast_signed(true);
tmp = pad_to_width(tmp, expr_wid, true, *this);
delete rp;
return tmp;
@@ -1021,7 +1071,7 @@ unsigned PECallFunction::test_width_sfunc_(Design*des, NetScope*scope,
if (name=="$ivlh_to_unsigned") {
ivl_assert(*this, parms_.size() == 2);
// The Icarus Verilog specific $ivl_unsigned() system
// The Icarus Verilog specific $ivlh_to_unsigned() system
// task takes a second argument which is the output
// size. This can be an arbitrary constant function.
PExpr*pexpr = parms_[1];
@@ -1043,6 +1093,11 @@ unsigned PECallFunction::test_width_sfunc_(Design*des, NetScope*scope,
bool rc = eval_as_long(value, nexpr);
ivl_assert(*this, rc && value>=0);
// The argument type/width is self-determined and doesn't
// affect the result type/width.
width_mode_t arg_mode = SIZED;
parms_[0]->test_width(des, scope, arg_mode);
expr_width_ = value;
signed_flag_= false;
return expr_width_;
@@ -1273,6 +1328,18 @@ unsigned PECallFunction::test_width_method_(Design*des, NetScope*scope,
if (net == 0)
return 0;
// Look for built in string attributes.
if (net->data_type()==IVL_VT_STRING) {
if (method_name == "len") {
expr_type_ = IVL_VT_BOOL;
expr_width_ = 32;
min_width_ = 32;
signed_flag_= true;
return expr_width_;
}
}
// function int size()
if (use_darray && method_name == "size") {
if (debug_elaborate) {
@@ -1333,27 +1400,14 @@ unsigned PECallFunction::test_width_method_(Design*des, NetScope*scope,
NetExpr*PECallFunction::cast_to_width_(NetExpr*expr, unsigned wid) const
{
/* If the expression is a const, then replace it with a new
const. This is a more efficient result. */
if (NetEConst*tmp = dynamic_cast<NetEConst*>(expr)) {
tmp->cast_signed(signed_flag_);
if (wid > tmp->expr_width()) {
tmp = new NetEConst(verinum(tmp->value(), wid));
tmp->set_line(*this);
delete expr;
}
return tmp;
if (debug_elaborate) {
cerr << get_fileline() << ": PECallFunction::cast_to_width_: "
<< "cast to " << wid
<< " bits " << (signed_flag_?"signed":"unsigned")
<< " from expr_width()=" << expr->expr_width() << endl;
}
if (debug_elaborate)
cerr << get_fileline() << ": debug: cast to " << wid
<< " bits " << (signed_flag_?"signed":"unsigned") << endl;
NetESelect*tmp = new NetESelect(expr, 0, wid);
tmp->cast_signed(signed_flag_);
tmp->set_line(*this);
return tmp;
return cast_to_width(expr, wid, signed_flag_, *this);
}
/*
@@ -1377,7 +1431,7 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope,
PExpr*expr = parms_[0];
ivl_assert(*this, expr);
NetExpr*sub = expr->elaborate_expr(des, scope, expr_width_, flags);
NetExpr*sub = expr->elaborate_expr(des, scope, expr->expr_width(), flags);
return cast_to_width_(sub, expr_wid);
}
@@ -1392,6 +1446,10 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope,
return 0;
}
if (debug_elaborate) {
cerr << get_fileline() << ": PECallFunction::elaborate_sfunc_: "
<< name << " expression is the argument cast to expr_wid=" << expr_wid << endl;
}
PExpr*expr = parms_[0];
NetExpr*sub = expr->elaborate_expr(des, scope, expr_width_, flags);
@@ -1516,7 +1574,7 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope,
if (missing_parms > 0) {
cerr << get_fileline() << ": error: The function " << name
<< " has been called with empty parameters." << endl;
<< " has been called with missing/empty parameters." << endl;
cerr << get_fileline() << ": : Verilog doesn't allow "
<< "passing empty parameters to functions." << endl;
des->errors += 1;
@@ -1525,10 +1583,7 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope,
if (missing_parms || parm_errors)
return 0;
NetExpr*tmp = pad_to_width(fun, expr_wid, *this);
tmp->cast_signed(signed_flag_);
return tmp;
return pad_to_width(fun, expr_wid, signed_flag_, *this);
}
NetExpr* PECallFunction::elaborate_access_func_(Design*des, NetScope*scope,
@@ -1585,10 +1640,7 @@ NetExpr* PECallFunction::elaborate_access_func_(Design*des, NetScope*scope,
NetExpr*tmp = new NetEAccess(branch, nature);
tmp->set_line(*this);
tmp = pad_to_width(tmp, expr_wid, *this);
tmp->cast_signed(signed_flag_);
return tmp;
return pad_to_width(tmp, expr_wid, signed_flag_, *this);
}
/*
@@ -2108,6 +2160,14 @@ NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope,
return elaborate_base_(des, scope, dscope, expr_wid, flags);
}
NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope,
ivl_type_t type, unsigned flags) const
{
const netdarray_t*darray = dynamic_cast<const netdarray_t*>(type);
assert(darray);
return elaborate_expr(des, scope, darray->element_type()->packed_width(), flags);
}
NetExpr* PECallFunction::elaborate_base_(Design*des, NetScope*scope, NetScope*dscope,
unsigned expr_wid, unsigned flags) const
{
@@ -2189,10 +2249,10 @@ NetExpr* PECallFunction::elaborate_base_(Design*des, NetScope*scope, NetScope*ds
NetEUFunc*func = new NetEUFunc(scope, dscope, eres, parms, need_const);
func->set_line(*this);
NetExpr*tmp = pad_to_width(func, expr_wid, *this);
tmp->cast_signed(signed_flag_);
if(res->darray_type())
return func;
return tmp;
return pad_to_width(func, expr_wid, signed_flag_, *this);
}
cerr << get_fileline() << ": internal error: Unable to locate "
@@ -2221,6 +2281,21 @@ unsigned PECallFunction::elaborate_arguments_(Design*des, NetScope*scope,
const unsigned parm_count = parms.size() - parm_off;
const unsigned actual_count = parms_.size();
/* The parser can't distinguish between a function call with
no arguments and a function call with one empty argument,
and always supplies one empty argument. Handle the no
argument case here. */
if ((parm_count == 0) && (actual_count == 1) && (parms_[0] == 0))
return 0;
if (actual_count > parm_count) {
cerr << get_fileline() << ": error: "
<< "Too many arguments (" << actual_count
<< ", expecting " << parm_count << ")"
<< " in call to function." << endl;
des->errors += 1;
}
for (unsigned idx = 0 ; idx < parm_count ; idx += 1) {
unsigned pidx = idx + parm_off;
PExpr*tmp = (idx < actual_count) ? parms_[idx] : 0;
@@ -2251,7 +2326,7 @@ unsigned PECallFunction::elaborate_arguments_(Design*des, NetScope*scope,
} else if (def->port_defe(pidx)) {
if (! gn_system_verilog()) {
cerr << get_fileline() << ": internal error: "
<<"Found (and using) default function argument "
<< "Found (and using) default function argument "
<< "requires SystemVerilog." << endl;
des->errors += 1;
}
@@ -2265,7 +2340,7 @@ unsigned PECallFunction::elaborate_arguments_(Design*des, NetScope*scope,
if (missing_parms > 0) {
cerr << get_fileline() << ": error: The function " << path_
<< " has been called with empty parameters." << endl;
<< " has been called with missing/empty parameters." << endl;
cerr << get_fileline() << ": : Verilog doesn't allow "
<< "passing empty parameters to functions." << endl;
parm_errors += 1;
@@ -2414,22 +2489,54 @@ NetExpr* PECallFunction::elaborate_expr_method_(Design*des, NetScope*scope,
unsigned PECastSize::test_width(Design*des, NetScope*scope, width_mode_t&)
{
expr_width_ = size_;
ivl_assert(*this, size_);
ivl_assert(*this, base_);
NetExpr*size_ex = elab_and_eval(des, scope, size_, -1, true);
NetEConst*size_ce = dynamic_cast<NetEConst*>(size_ex);
expr_width_ = size_ce ? size_ce->value().as_ulong() : 0;
delete size_ex;
if (expr_width_ == 0) {
cerr << get_fileline() << ": error: Cast size expression "
"must be constant and greater than zero." << endl;
des->errors += 1;
return 0;
}
width_mode_t tmp_mode = PExpr::SIZED;
base_->test_width(des, scope, tmp_mode);
return size_;
if (!type_is_vectorable(base_->expr_type())) {
cerr << get_fileline() << ": error: Cast base expression "
"must be a vector type." << endl;
des->errors += 1;
return 0;
}
expr_type_ = base_->expr_type();
min_width_ = expr_width_;
signed_flag_ = base_->has_sign();
return expr_width_;
}
NetExpr* PECastSize::elaborate_expr(Design*des, NetScope*scope,
unsigned, unsigned) const
unsigned expr_wid, unsigned flags) const
{
NetExpr*sub = base_->elaborate_expr(des, scope, base_->expr_width(), NO_FLAGS);
NetESelect*sel = new NetESelect(sub, 0, size_);
sel->set_line(*this);
flags &= ~SYS_TASK_ARG; // don't propagate the SYS_TASK_ARG flag
return sel;
ivl_assert(*this, size_);
ivl_assert(*this, base_);
NetExpr*sub = base_->elaborate_expr(des, scope, base_->expr_width(), flags);
// Perform the cast. The extension method (zero/sign), if needed,
// depends on the type of the base expression.
NetExpr*tmp = cast_to_width(sub, expr_width_, base_->has_sign(), *this);
// Pad up to the expression width. The extension method (zero/sign)
// depends on the type of enclosing expression.
return pad_to_width(tmp, expr_wid, signed_flag_, *this);
}
unsigned PECastType::test_width(Design*des, NetScope*scope, width_mode_t&wid)
@@ -2452,11 +2559,44 @@ unsigned PECastType::test_width(Design*des, NetScope*scope, width_mode_t&wid)
expr_width_ = t->packed_width();
}
signed_flag_= t->get_signed();
signed_flag_ = t->get_signed();
min_width_ = expr_width_;
return expr_width_;
}
NetExpr* PECastType::elaborate_expr(Design*des, NetScope*scope,
ivl_type_t type, unsigned) const
{
const netdarray_t*darray = NULL;
const netvector_t*vector = NULL;
// Casting array of vectors to dynamic array type
if((darray = dynamic_cast<const netdarray_t*>(type)) &&
(vector = dynamic_cast<const netvector_t*>(darray->element_type()))) {
PExpr::width_mode_t mode = PExpr::SIZED;
unsigned use_wid = base_->test_width(des, scope, mode);
NetExpr*base = base_->elaborate_expr(des, scope, use_wid, NO_FLAGS);
assert(vector->packed_width() > 0);
assert(base->expr_width() > 0);
// Find rounded up length that can fit the whole casted array of vectors
int len = base->expr_width() + vector->packed_width() - 1;
if(base->expr_width() > vector->packed_width()) {
len /= vector->packed_width();
} else {
len /= base->expr_width();
}
// Number of words in the created dynamic array
NetEConst*len_expr = new NetEConst(verinum(len));
return new NetENew(type, len_expr, base);
}
// Fallback
return elaborate_expr(des, scope, (unsigned) 0, 0);
}
NetExpr* PECastType::elaborate_expr(Design*des, NetScope*scope,
unsigned, unsigned) const
{
@@ -2500,17 +2640,15 @@ NetExpr* PECastType::elaborate_expr(Design*des, NetScope*scope,
if((base_->expr_type() != IVL_VT_BOOL) &&
(base_->expr_type() != IVL_VT_LOGIC)) {
cerr << get_fileline() << ": cannot be casted to string." << endl;
cerr << get_fileline() << ": cannot be cast to a string." << endl;
ivl_assert(*this, false);
}
return expr;
}
cerr << get_fileline() << ": sorry: I don't know how to cast expression." << endl;
ivl_assert(*this, false);
return expr;
cerr << get_fileline() << ": sorry: This cast operation is not yet supported." << endl;
return 0;
}
unsigned PEConcat::test_width(Design*des, NetScope*scope, width_mode_t&)
@@ -2702,17 +2840,16 @@ NetExpr* PEConcat::elaborate_expr(Design*des, NetScope*scope,
concat->set(idx, parms[off+idx]);
}
if (wid_sum == 0 && concat_depth < 2) {
cerr << get_fileline() << ": error: Concatenation may not "
<< "have zero width in this context." << endl;
if (wid_sum == 0) {
cerr << get_fileline() << ": error: Concatenation/replication "
<< "may not have zero width in this context." << endl;
des->errors += 1;
concat_depth -= 1;
delete concat;
return 0;
}
NetExpr*tmp = pad_to_width(concat, expr_wid, *this);
tmp->cast_signed(signed_flag_);
NetExpr*tmp = pad_to_width(concat, expr_wid, signed_flag_, *this);
concat_depth -= 1;
return tmp;
@@ -2752,6 +2889,25 @@ NetExpr* PEFNumber::elaborate_expr(Design*, NetScope*, unsigned, unsigned) const
bool PEIdent::calculate_packed_indices_(Design*des, NetScope*scope, NetNet*net,
list<long>&prefix_indices) const
{
unsigned dimensions = net->unpacked_dimensions() + net->packed_dimensions();
switch (net->data_type()) {
case IVL_VT_STRING:
case IVL_VT_DARRAY:
case IVL_VT_QUEUE:
dimensions += 1;
default:
break;
}
if (path_.back().index.size() > dimensions) {
cerr << get_fileline() << ": error: the number of indices ("
<< path_.back().index.size()
<< ") is greater than the number of dimensions ("
<< dimensions
<< ")." << endl;
des->errors += 1;
return false;
}
list<index_component_t> index;
index = path_.back().index;
ivl_assert(*this, index.size() >= net->unpacked_dimensions());
@@ -2780,7 +2936,7 @@ bool PEIdent::calculate_bits_(Design*des, NetScope*scope,
NetEConst*msb_c = dynamic_cast<NetEConst*>(msb_ex);
if (msb_c == 0) {
cerr << index_tail.msb->get_fileline() << ": error: "
"Bit select expressionsmust be constant."
"Bit select expressions must be constant."
<< endl;
cerr << index_tail.msb->get_fileline() << ": : "
"This msb expression violates the rule: "
@@ -3610,10 +3766,7 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
if (!tmp) return 0;
tmp = pad_to_width(tmp, expr_wid, *this);
tmp->cast_signed(signed_flag_);
return tmp;
return pad_to_width(tmp, expr_wid, signed_flag_, *this);
}
// If the identifier names a signal (a register or wire)
@@ -3649,10 +3802,7 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
<< ", tmp=" << *tmp << endl;
}
tmp = pad_to_width(tmp, expr_wid, *this);
tmp->cast_signed(signed_flag_);
return tmp;
return pad_to_width(tmp, expr_wid, signed_flag_, *this);
}
// If the identifier is a named event
@@ -3699,7 +3849,7 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
}
// Maybe this is a method attached to an enumeration name? If
// this is system verilog, then test to see if the name is
// this is SystemVerilog, then test to see if the name is
// really a method attached to an object.
if (gn_system_verilog() && found_in==0 && path_.size() >= 2) {
pform_name_t use_path = path_;
@@ -3752,9 +3902,7 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
member_comp);
if (!tmp) return 0;
tmp = pad_to_width(tmp, expr_wid, *this);
tmp->cast_signed(signed_flag_);
return tmp;
return pad_to_width(tmp, expr_wid, signed_flag_, *this);
}
if (net->class_type() != 0) {
@@ -4333,7 +4481,7 @@ NetExpr* PEIdent::elaborate_expr_param_(Design*des,
<< "Elaborate parameter <" << path_
<< "> as enumeration constant." << *etmp << endl;
tmp = etmp->dup_expr();
tmp = pad_to_width(tmp, expr_wid, *this);
tmp = pad_to_width(tmp, expr_wid, signed_flag_, *this);
} else {
perm_string name = peek_tail_name(path_);
@@ -4508,7 +4656,8 @@ NetExpr* PEIdent::elaborate_expr_net_part_(Design*des, NetScope*scope,
{
list<long> prefix_indices;
bool rc = calculate_packed_indices_(des, scope, net->sig(), prefix_indices);
ivl_assert(*this, rc);
if (!rc)
return 0;
long msv, lsv;
bool parts_defined_flag;
@@ -4648,7 +4797,8 @@ NetExpr* PEIdent::elaborate_expr_net_idx_up_(Design*des, NetScope*scope,
{
list<long>prefix_indices;
bool rc = calculate_packed_indices_(des, scope, net->sig(), prefix_indices);
ivl_assert(*this, rc);
if (!rc)
return 0;
NetExpr*base = calculate_up_do_base_(des, scope, need_const);
@@ -4750,7 +4900,8 @@ NetExpr* PEIdent::elaborate_expr_net_idx_do_(Design*des, NetScope*scope,
{
list<long>prefix_indices;
bool rc = calculate_packed_indices_(des, scope, net->sig(), prefix_indices);
ivl_assert(*this, rc);
if (!rc)
return 0;
NetExpr*base = calculate_up_do_base_(des, scope, need_const);
@@ -4838,7 +4989,8 @@ NetExpr* PEIdent::elaborate_expr_net_bit_(Design*des, NetScope*scope,
{
list<long>prefix_indices;
bool rc = calculate_packed_indices_(des, scope, net->sig(), prefix_indices);
ivl_assert(*this, rc);
if (!rc)
return 0;
const name_component_t&name_tail = path_.back();
ivl_assert(*this, !name_tail.index.empty());
@@ -4848,6 +5000,8 @@ NetExpr* PEIdent::elaborate_expr_net_bit_(Design*des, NetScope*scope,
ivl_assert(*this, index_tail.lsb == 0);
NetExpr*mux = elab_and_eval(des, scope, index_tail.msb, -1, need_const);
if (!mux)
return 0;
if (const netdarray_t*darray = net->sig()->darray_type()) {
// Special case: This is a select of a dynamic
@@ -5395,10 +5549,23 @@ unsigned PENumber::test_width(Design*, NetScope*, width_mode_t&mode)
expr_width_ = integer_width;
mode = UNSIZED;
} else if (mode < LOSSLESS) {
mode = LOSSLESS;
if (expr_width_ < integer_width) {
expr_width_ = integer_width;
if (mode < UNSIZED)
mode = UNSIZED;
} else {
mode = LOSSLESS;
}
}
}
if (debug_elaborate) {
cerr << get_fileline() << ": PENumber::test_width: "
<< "Value=" << *value_
<< ", width=" << expr_width_
<< ", output mode=" << width_mode_name(mode) << endl;
}
return expr_width_;
}
@@ -5510,7 +5677,6 @@ unsigned PETernary::test_width(Design*des, NetScope*scope, width_mode_t&mode)
} else if (tru_type == IVL_VT_LOGIC || fal_type == IVL_VT_LOGIC) {
expr_type_ = IVL_VT_LOGIC;
} else {
ivl_assert(*this, tru_type == fal_type);
expr_type_ = tru_type;
}
if (expr_type_ == IVL_VT_REAL) {
@@ -5906,7 +6072,7 @@ NetExpr* PEUnary::elaborate_expr(Design*des, NetScope*scope,
}
tmp->set_line(*this);
}
tmp = pad_to_width(tmp, expr_wid, *this);
tmp = pad_to_width(tmp, expr_wid, signed_flag_, *this);
break;
case '&': // Reduction AND
@@ -5924,7 +6090,7 @@ NetExpr* PEUnary::elaborate_expr(Design*des, NetScope*scope,
}
tmp = new NetEUReduce(op_, ip);
tmp->set_line(*this);
tmp = pad_to_width(tmp, expr_wid, *this);
tmp = pad_to_width(tmp, expr_wid, signed_flag_, *this);
break;
case '~':
+73 -32
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2000-2014 Stephen Williams (steve@icarus.com)
* Copyright (c) 2000-2016 Stephen Williams (steve@icarus.com)
* Copyright CERN 2012-2013 / Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
@@ -138,6 +138,9 @@ NetAssign_* PEConcat::elaborate_lval(Design*des,
continue;
}
/* A concatenation is always unsigned. */
tmp->set_signed(false);
/* Link the new l-value to the previous one. */
NetAssign_*last = tmp;
while (last->more)
@@ -157,7 +160,7 @@ NetAssign_*PEIdent::scan_lname_for_nested_members_(Design*des, NetScope*scope,
return 0;
pform_name_t use_path = cur_path;
perm_string tmp_name = peek_tail_name(use_path);
name_component_t tail = use_path.back();
use_path.pop_back();
NetNet* reg = 0;
@@ -171,18 +174,32 @@ NetAssign_*PEIdent::scan_lname_for_nested_members_(Design*des, NetScope*scope,
return 0;
tmp = new NetAssign_(tmp);
tmp->set_property(tmp_name);
tmp->set_property(tail.name);
return tmp;
}
if (reg->struct_type()) {
if (reg->struct_type() && reg->struct_type()->packed()) {
NetAssign_*tmp = new NetAssign_(reg);
elaborate_lval_net_packed_member_(des, scope, tmp, tail);
return tmp;
}
#if 0
if (reg->struct_type() && reg->struct_type()->packed()) {
cerr << get_fileline() << ": sorry: "
<< "I don't know what to do with struct " << use_path << endl;
<< "I don't know what to do with packed struct " << use_path
<< " with member " << tail << "." << endl;
return 0;
}
#endif
if (reg->struct_type() && !reg->struct_type()->packed()) {
cerr << get_fileline() << ": sorry: "
<< "I don't know what to do with unpacked struct " << use_path
<< " with member " << tail << "." << endl;
return 0;
}
if (reg->class_type()) {
return elaborate_lval_net_class_member_(des, scope, reg, tmp_name);
return elaborate_lval_net_class_member_(des, scope, reg, tail.name);
}
return 0;
@@ -202,6 +219,11 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
NetEvent* eve = 0;
perm_string method_name;
if (debug_elaborate) {
cerr << get_fileline() << ": PEIdent::elaborate_lval: "
<< "Elaborate l-value ident expression: " << *this << endl;
}
/* Try to detect the special case that we are in a method and
the identifier is a member of the class. */
if (NetAssign_*tmp = elaborate_lval_method_class_member_(des, scope))
@@ -263,17 +285,18 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
if (debug_elaborate) {
cerr << get_fileline() << ": PEIdent::elaborate_lval: "
<< "Lval reg = " << reg->name() << endl;
<< "Found l-value as reg."
<< " unpacked_dimensions()=" << reg->unpacked_dimensions() << endl;
}
// We are processing the tail of a string of names. For
// example, the verilog may be "a.b.c", so we are processing
// example, the Verilog may be "a.b.c", so we are processing
// "c" at this point. (Note that if method_name is not nil,
// then this is "a.b.c.method" and "a.b.c" is a struct or class.)
const name_component_t&name_tail = path_.back();
// Use the last index to determine what kind of select
// (bit/part/etc) we are processing. For example, the verilog
// (bit/part/etc) we are processing. For example, the Verilog
// may be "a.b.c[1][2][<index>]". All but the last index must
// be simple expressions, only the <index> may be a part
// select etc., so look at it to determine how we will be
@@ -310,7 +333,8 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
if (reg->struct_type() && !method_name.nil()) {
NetAssign_*lv = new NetAssign_(reg);
elaborate_lval_net_packed_member_(des, use_scope, lv, method_name);
name_component_t tmp_name (method_name);
elaborate_lval_net_packed_member_(des, use_scope, lv, tmp_name);
return lv;
}
@@ -378,6 +402,7 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
/* No select expressions. */
NetAssign_*lv = new NetAssign_(reg);
lv->set_signed(reg->get_signed());
return lv;
}
@@ -464,7 +489,7 @@ NetAssign_* PEIdent::elaborate_lval_method_class_member_(Design*des,
if (debug_elaborate) {
cerr << get_fileline() << ": PEIdent::elaborate_lval_method_class_member_: "
<< "Found initialzers for property " << class_type->get_prop_name(pidx) << endl;
<< "Found initializers for property " << class_type->get_prop_name(pidx) << endl;
}
}
}
@@ -509,6 +534,11 @@ NetAssign_* PEIdent::elaborate_lval_net_word_(Design*des,
const name_component_t&name_tail = path_.back();
ivl_assert(*this, !name_tail.index.empty());
if (debug_elaborate) {
cerr << get_fileline() << ": PEIdent::elaborate_lval_net_word_: "
<< "Handle as n-dimensional array." << endl;
}
if (name_tail.index.size() < reg->unpacked_dimensions()) {
cerr << get_fileline() << ": error: Array " << reg->name()
<< " needs " << reg->unpacked_dimensions() << " indices,"
@@ -576,6 +606,11 @@ NetAssign_* PEIdent::elaborate_lval_net_word_(Design*des,
canon_index = new NetEConst(verinum(verinum::Vx));
canon_index->set_line(*this);
if (debug_elaborate) {
cerr << get_fileline() << ": PEIdent::elaborate_lval_net_word_: "
<< "canon_index=" << *canon_index << endl;
}
if (reg->type()==NetNet::UNRESOLVED_WIRE) {
cerr << get_fileline() << ": error: "
<< "Unable to assign words of unresolved wire array." << endl;
@@ -656,20 +691,24 @@ bool PEIdent::elaborate_lval_net_bit_(Design*des,
unsigned long lwid;
bool rcl = reg->sb_to_slice(prefix_indices, lsb, loff, lwid);
ivl_assert(*this, rcl);
cerr << get_fileline() << ": warning: L-value packed array "
<< "select of " << reg->name();
if (reg->unpacked_dimensions() > 0) cerr << "[]";
cerr << " has an undefined index." << endl;
if (warn_ob_select) {
cerr << get_fileline()
<< ": warning: L-value packed array select of "
<< reg->name();
if (reg->unpacked_dimensions() > 0) cerr << "[]";
cerr << " has an undefined index." << endl;
}
lv->set_part(new NetEConst(verinum(verinum::Vx)), lwid);
return true;
// The index is undefined and this is a bit select.
} else {
cerr << get_fileline() << ": warning: L-value bit select of "
<< reg->name();
if (reg->unpacked_dimensions() > 0) cerr << "[]";
cerr << " has an undefined index." << endl;
if (warn_ob_select) {
cerr << get_fileline()
<< ": warning: L-value bit select of "
<< reg->name();
if (reg->unpacked_dimensions() > 0) cerr << "[]";
cerr << " has an undefined index." << endl;
}
lv->set_part(new NetEConst(verinum(verinum::Vx)), 1);
return true;
}
@@ -766,12 +805,10 @@ bool PEIdent::elaborate_lval_net_bit_(Design*des,
// Constant bit select that does something useful.
long loff = reg->sb_to_idx(prefix_indices,lsb);
if (loff < 0 || loff >= (long)reg->vector_width()) {
cerr << get_fileline() << ": error: bit select "
if (warn_ob_select && (loff < 0 || loff >= (long)reg->vector_width())) {
cerr << get_fileline() << ": warning: bit select "
<< reg->name() << "[" <<lsb<<"]"
<< " is out of range." << endl;
des->errors += 1;
return 0;
}
if (reg->type()==NetNet::UNRESOLVED_WIRE) {
@@ -837,10 +874,13 @@ bool PEIdent::elaborate_lval_net_part_(Design*des,
ivl_assert(*this, reg);
if (! parts_defined_flag) {
cerr << get_fileline() << ": warning: L-value part select of "
<< reg->name();
if (reg->unpacked_dimensions() > 0) cerr << "[]";
cerr << " has an undefined index." << endl;
if (warn_ob_select) {
cerr << get_fileline()
<< ": warning: L-value part select of "
<< reg->name();
if (reg->unpacked_dimensions() > 0) cerr << "[]";
cerr << " has an undefined index." << endl;
}
// Use a width of two here so we can distinguish between an
// undefined bit or part select.
lv->set_part(new NetEConst(verinum(verinum::Vx)), 2);
@@ -903,11 +943,11 @@ bool PEIdent::elaborate_lval_net_part_(Design*des,
}
/* If the part select extends beyond the extremes of the
variable, then report an error. Note that loff is
variable, then output a warning. Note that loff is
converted to normalized form so is relative the
variable pins. */
if (loff < 0 || moff >= (long)reg->vector_width()) {
if (warn_ob_select && (loff < 0 || moff >= (long)reg->vector_width())) {
cerr << get_fileline() << ": warning: Part select "
<< reg->name() << "[" << msb<<":"<<lsb<<"]"
<< " is out of range." << endl;
@@ -1099,8 +1139,9 @@ NetAssign_* PEIdent::elaborate_lval_net_class_member_(Design*des, NetScope*scope
bool PEIdent::elaborate_lval_net_packed_member_(Design*des, NetScope*scope,
NetAssign_*lv,
const perm_string&member_name) const
const name_component_t&member_comp) const
{
const perm_string&member_name = member_comp.name;
NetNet*reg = lv->sig();
ivl_assert(*this, reg);
+57 -30
View File
@@ -328,39 +328,66 @@ bool PEIdent::eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
return false;
}
long lidx_tmp = sig->sb_to_idx(prefix_indices, lsb);
long midx_tmp = sig->sb_to_idx(prefix_indices, msb);
/* Detect reversed indices of a part select. */
if (lidx_tmp > midx_tmp) {
cerr << get_fileline() << ": error: Part select "
<< sig->name() << "[" << msb << ":"
<< lsb << "] indices reversed." << endl;
cerr << get_fileline() << ": : Did you mean "
<< sig->name() << "[" << lsb << ":"
<< msb << "]?" << endl;
long tmp = midx_tmp;
midx_tmp = lidx_tmp;
lidx_tmp = tmp;
des->errors += 1;
}
if (prefix_indices.size()+1 < sig->packed_dims().size()) {
// Here we have a slice that doesn't have enough indices
// to get to a single slice. For example:
// wire [9:0][5:1] foo
// ... foo[4:3] ...
// Make this work by finding the indexed slices and
// creating a generated slice that spans the whole
// range.
long loff, moff;
unsigned long lwid, mwid;
bool lrc;
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);
ivl_assert(*this, lwid == mwid);
/* Warn about a part select that is out of range. */
if (midx_tmp >= (long)sig->vector_width() || lidx_tmp < 0) {
cerr << get_fileline() << ": warning: Part select "
<< sig->name();
if (sig->unpacked_dimensions() > 0) {
cerr << "[]";
if (moff > loff) {
lidx = loff;
midx = moff + mwid - 1;
} else {
lidx = moff;
midx = loff + lwid - 1;
}
cerr << "[" << msb << ":" << lsb
<< "] is out of range." << endl;
}
/* This is completely out side the signal so just skip it. */
if (lidx_tmp >= (long)sig->vector_width() || midx_tmp < 0) {
return false;
}
} else {
long lidx_tmp = sig->sb_to_idx(prefix_indices, lsb);
long midx_tmp = sig->sb_to_idx(prefix_indices, msb);
midx = midx_tmp;
lidx = lidx_tmp;
/* Detect reversed indices of a part select. */
if (lidx_tmp > midx_tmp) {
cerr << get_fileline() << ": error: Part select "
<< sig->name() << "[" << msb << ":"
<< lsb << "] indices reversed." << endl;
cerr << get_fileline() << ": : Did you mean "
<< sig->name() << "[" << lsb << ":"
<< msb << "]?" << endl;
long tmp = midx_tmp;
midx_tmp = lidx_tmp;
lidx_tmp = tmp;
des->errors += 1;
}
/* Warn about a part select that is out of range. */
if (midx_tmp >= (long)sig->vector_width() || lidx_tmp < 0) {
cerr << get_fileline() << ": warning: Part select "
<< sig->name();
if (sig->unpacked_dimensions() > 0) {
cerr << "[]";
}
cerr << "[" << msb << ":" << lsb
<< "] is out of range." << endl;
}
/* This is completely out side the signal so just skip it. */
if (lidx_tmp >= (long)sig->vector_width() || midx_tmp < 0) {
return false;
}
midx = midx_tmp;
lidx = lidx_tmp;
}
break;
}
+27 -12
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2000-2014 Stephen Williams (steve@icarus.com)
* Copyright (c) 2000-2016 Stephen Williams (steve@icarus.com)
* Copyright CERN 2013 / Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
@@ -54,6 +54,15 @@
# include <cassert>
# include "ivl_assert.h"
void set_scope_timescale(Design*des, NetScope*scope, PScope*pscope)
{
scope->time_unit(pscope->time_unit);
scope->time_precision(pscope->time_precision);
scope->time_from_timescale(pscope->time_from_timescale);
des->set_precision(pscope->time_precision);
}
typedef map<perm_string,LexicalScope::param_expr_t>::const_iterator mparm_it_t;
static void collect_parm_item_(Design*des, NetScope*scope, perm_string name,
@@ -523,6 +532,7 @@ static void elaborate_scope_class(Design*des, NetScope*scope, PClass*pclass)
class_scope->set_class_def(use_class);
use_class->set_class_scope(class_scope);
use_class->set_definition_scope(scope);
set_scope_timescale(des, class_scope, pclass);
// Collect the properties, elaborate them, and add them to the
// elaborated class definition.
@@ -654,8 +664,10 @@ static void elaborate_scope_task(Design*des, NetScope*scope, PTask*task)
task_scope->is_auto(task->is_auto());
task_scope->set_line(task);
if (scope==0)
if (scope==0) {
set_scope_timescale(des, task_scope, task);
des->add_root_task(task_scope, task);
}
if (debug_scopes) {
cerr << task->get_fileline() << ": elaborate_scope_task: "
@@ -719,8 +731,10 @@ static void elaborate_scope_func(Design*des, NetScope*scope, PFunction*task)
task_scope->is_auto(task->is_auto());
task_scope->set_line(task);
if (scope==0)
if (scope==0) {
set_scope_timescale(des, task_scope, task);
des->add_root_task(task_scope, task);
}
if (debug_scopes) {
cerr << task->get_fileline() << ": elaborate_scope_func: "
@@ -793,7 +807,7 @@ void elaborate_rootscope_tasks(Design*des)
}
cerr << cur->second->get_fileline() << ": internal error: "
<< "elabortae_rootscope_tasks does not understand "
<< "elaborate_rootscope_tasks does not understand "
<< "this object," << endl;
des->errors += 1;
}
@@ -1742,18 +1756,15 @@ void PGModule::elaborate_scope_mod_instances_(Design*des, Module*mod, NetScope*s
// scope searches will continue into the parent scope.
NetScope*my_scope = new NetScope(sc, use_name, NetScope::MODULE,
bound_type_? true : false,
mod->program_block);
mod->program_block,
mod->is_interface);
my_scope->set_line(get_file(), mod->get_file(),
get_lineno(), mod->get_lineno());
my_scope->set_module_name(mod->mod_name());
instances[idx] = my_scope;
// Set time units and precision.
my_scope->time_unit(mod->time_unit);
my_scope->time_precision(mod->time_precision);
my_scope->time_from_timescale(mod->time_from_timescale);
des->set_precision(mod->time_precision);
set_scope_timescale(des, my_scope, mod);
// Look for module parameter replacements. The "replace" map
// maps parameter name to replacement expression that is
@@ -1792,8 +1803,12 @@ void PGModule::elaborate_scope_mod_instances_(Design*des, Module*mod, NetScope*s
// so the mapping into the replace list is much easier.
if (parms_) {
assert(overrides_ == 0);
for (unsigned jdx = 0 ; jdx < nparms_ ; jdx += 1)
replace[parms_[jdx].name] = parms_[jdx].parm;
for (unsigned jdx = 0 ; jdx < nparms_ ; jdx += 1) {
// No expression means that the parameter is not
// replaced.
if (parms_[jdx].parm)
replace[parms_[jdx].name] = parms_[jdx].parm;
}
}
+60 -20
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2000-2014 Stephen Williams (steve@icarus.com)
* Copyright (c) 2000-2016 Stephen Williams (steve@icarus.com)
* Copyright CERN 2012 / Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
@@ -715,16 +715,23 @@ void PTaskFunc::elaborate_sig_ports_(Design*des, NetScope*scope,
continue;
}
// If the port has a default expression that can be used
// as a value when the caller doesn't bind, then
// elaborate that expression here. This expression
// should evaluate down do a constant.
// If the port has a default expression, elaborate
// that expression here.
if (ports_->at(idx).defe != 0) {
tmp_def = elab_and_eval(des, scope, ports_->at(idx).defe, -1, true);
if (tmp_def==0) {
cerr << get_fileline() << ": error: Unable to evaluate "
<< *ports_->at(idx).defe
<< " as a port default (constant) expression." << endl;
if (tmp->port_type() == NetNet::PINPUT) {
tmp_def = elab_and_eval(des, scope, ports_->at(idx).defe,
-1, scope->need_const_func());
if (tmp_def == 0) {
cerr << get_fileline()
<< ": error: Unable to evaluate "
<< *ports_->at(idx).defe
<< " as a port default expression." << endl;
des->errors += 1;
}
} else {
cerr << get_fileline() << ": sorry: Default arguments "
"for subroutine output or inout ports are not "
"yet supported." << endl;
des->errors += 1;
}
}
@@ -909,6 +916,11 @@ bool test_ranges_eeq(const vector<netrange_t>&lef, const vector<netrange_t>&rig)
*/
NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
{
// This sets the vector or array dimension size that will
// cause a warning. For now, these warnings are permanently
// enabled.
const long warn_dimension_size = 1 << 30;
NetNet::Type wtype = type_;
bool is_implicit_scalar = false;
if (wtype == NetNet::IMPLICIT) {
@@ -964,6 +976,23 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
}
if (port_set_ || net_set_) {
if (warn_implicit_dimensions
&& port_set_ && net_set_
&& net_.empty() && !port_.empty()) {
cerr << get_fileline() << ": warning: "
<< "var/net declaration of " << basename()
<< " inherits dimensions from port declaration." << endl;
}
if (warn_implicit_dimensions
&& port_set_ && net_set_
&& port_.empty() && !net_.empty()) {
cerr << get_fileline() << ": warning: "
<< "Port declaration of " << basename()
<< " inherits dimensions from var/net." << endl;
}
bool bad_range = false;
vector<netrange_t> plist, nlist;
/* If they exist get the port definition MSB and LSB */
@@ -1042,7 +1071,11 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
packed_dimensions = nlist;
wid = netrange_width(packed_dimensions);
if (wid > warn_dimension_size) {
cerr << get_fileline() << ": warning: Vector size "
"is greater than " << warn_dimension_size
<< "." << endl;
}
}
unsigned nattrib = 0;
@@ -1063,6 +1096,7 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
// put all the packed dimensions there.
if (use_lidx==0 && use_ridx==0) {
netvector_t*vec = new netvector_t(packed_dimensions, data_type_);
vec->set_signed(get_signed());
packed_dimensions.clear();
ivl_assert(*this, netdarray==0);
netdarray = new netdarray_t(vec);
@@ -1073,6 +1107,7 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
// declaration, which is the dimensions [null:<nil>].
if (use_ridx==0 && dynamic_cast<PENull*>(use_lidx)) {
netvector_t*vec = new netvector_t(packed_dimensions, data_type_);
vec->set_signed(get_signed());
packed_dimensions.clear();
ivl_assert(*this, netdarray==0);
netdarray = new netqueue_t(vec);
@@ -1114,6 +1149,11 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
index_l = lval.as_long();
index_r = rval.as_long();
}
if (abs(index_r - index_l) > warn_dimension_size) {
cerr << get_fileline() << ": warning: Array dimension "
"is greater than " << warn_dimension_size
<< "." << endl;
}
unpacked_dimensions.push_back(netrange_t(index_l, index_r));
}
@@ -1145,6 +1185,14 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
NetLogic*pull = 0;
if (wtype == NetNet::SUPPLY0 || wtype == NetNet::SUPPLY1) {
if (debug_elaborate) {
cerr << get_fileline() << ": debug: "
<< "Generate a SUPPLY pull for the ";
if (wtype == NetNet::SUPPLY0) cerr << "supply0";
else cerr << "supply1";
cerr << " net." << endl;
}
NetLogic::TYPE pull_type = (wtype==NetNet::SUPPLY1)
? NetLogic::PULLUP
: NetLogic::PULLDOWN;
@@ -1155,14 +1203,6 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
pull->pin(0).drive1(IVL_DR_SUPPLY);
des->add_node(pull);
wtype = NetNet::WIRE;
if (debug_elaborate) {
cerr << get_fileline() << ": debug: "
<< "Generate a SUPPLY pull for the ";
if (wtype == NetNet::SUPPLY0) cerr << "supply0";
else cerr << "supply1";
cerr << " net." << endl;
}
}
@@ -1194,7 +1234,7 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
cerr << " in scope " << scope_path(scope) << endl;
}
sig = new NetNet(scope, name_, wtype, use_type);
sig = new NetNet(scope, name_, wtype, unpacked_dimensions, use_type);
} else if (enum_type_t*enum_type = dynamic_cast<enum_type_t*>(set_data_type_)) {
list<named_pexpr_t>::const_iterator sample_name = enum_type->names->begin();
+61 -36
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012-2014 Stephen Williams (steve@icarus.com)
* Copyright (c) 2012-2016 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
@@ -17,11 +17,13 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
# include "PExpr.h"
# include "pform_types.h"
# include "netlist.h"
# include "netclass.h"
# include "netdarray.h"
# include "netenum.h"
# include "netqueue.h"
# include "netparray.h"
# include "netscalar.h"
# include "netstruct.h"
@@ -32,6 +34,44 @@
using namespace std;
/*
* Some types have a list of ranges that need to be elaborated. This
* function elaborates the ranges referenced by "dims" into the vector
* "ranges".
*/
static void elaborate_array_ranges(Design*des, NetScope*scope,
vector<netrange_t>&ranges,
const list<pform_range_t>*dims)
{
if (dims == 0)
return;
for (list<pform_range_t>::const_iterator cur = dims->begin()
; cur != dims->end() ; ++ cur) {
NetExpr*me = elab_and_eval(des, scope, cur->first, 0, true);
NetExpr*le = elab_and_eval(des, scope, cur->second, 0, true);
/* If elaboration failed for either expression, we
should have already reported the error, so just
skip the following evaluation to recover. */
long mnum = 0, lnum = 0;
if ( me && ! eval_as_long(mnum, me) ) {
assert(0);
des->errors += 1;
}
if ( le && ! eval_as_long(lnum, le) ) {
assert(0);
des->errors += 1;
}
ranges.push_back(netrange_t(mnum, lnum));
}
}
/*
* Elaborations of types may vary depending on the scope that it is
* done in, so keep a per-scope cache of the results.
@@ -43,8 +83,8 @@ ivl_type_s* data_type_t::elaborate_type(Design*des, NetScope*scope)
use_definitions = des;
map<Definitions*,ivl_type_s*>::iterator pos = cache_type_elaborate_.lower_bound(use_definitions);
if (pos->first == use_definitions)
return pos->second;
if (pos != cache_type_elaborate_.end() && pos->first == use_definitions)
return pos->second;
ivl_type_s*tmp = elaborate_type_raw(des, scope);
cache_type_elaborate_.insert(pos, pair<NetScope*,ivl_type_s*>(scope, tmp));
@@ -120,33 +160,7 @@ ivl_type_s* enum_type_t::elaborate_type_raw(Design*des, NetScope*scope) const
ivl_type_s* vector_type_t::elaborate_type_raw(Design*des, NetScope*scope) const
{
vector<netrange_t> packed;
if (pdims.get()) {
for (list<pform_range_t>::const_iterator cur = pdims->begin()
; cur != pdims->end() ; ++ cur) {
NetExpr*me = elab_and_eval(des, scope, cur->first, 0, true);
NetExpr*le = elab_and_eval(des, scope, cur->second, 0, true);
/* If elaboration failed for either expression, we
should have already reported the error, so just
skip the following evaluation to recover. */
long mnum = 0, lnum = 0;
if ( me && ! eval_as_long(mnum, me) ) {
assert(0);
des->errors += 1;
}
if ( le && ! eval_as_long(lnum, le) ) {
assert(0);
des->errors += 1;
}
packed.push_back(netrange_t(mnum, lnum));
}
}
elaborate_array_ranges(des, scope, packed, pdims.get());
netvector_t*tmp = new netvector_t(packed, base_type);
tmp->set_signed(signed_flag);
@@ -171,13 +185,14 @@ ivl_type_s* string_type_t::elaborate_type_raw(Design*, NetScope*) const
return &netstring_t::type_string;
}
ivl_type_s* parray_type_t::elaborate_type_raw(Design*des, NetScope*) const
ivl_type_s* parray_type_t::elaborate_type_raw(Design*des, NetScope*scope) const
{
cerr << get_fileline() << " : sorry: "
<< "Packed arrays are not currently supported in this context."
<< endl;
des->errors += 1;
return 0;
vector<netrange_t>packed;
elaborate_array_ranges(des, scope, packed, dims.get());
ivl_type_t etype = base_type->elaborate_type(des, scope);
return new netparray_t(packed, etype);
}
netstruct_t* struct_type_t::elaborate_type_raw(Design*des, NetScope*scope) const
@@ -232,6 +247,16 @@ ivl_type_s* uarray_type_t::elaborate_type_raw(Design*des, NetScope*scope) const
return res;
}
// Special case: if the dimension is null:nil. this is a queue.
if (cur->second==0 && dynamic_cast<PENull*>(cur->first)) {
cerr << get_fileline() << ": sorry: "
<< "SV queues inside classes are not yet supported." << endl;
des->errors += 1;
ivl_type_s*res = new netqueue_t(btype);
return res;
}
vector<netrange_t> dimensions;
bool bad_range = evaluate_ranges(des, scope, dimensions, *dims);
+301 -102
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998-2014 Stephen Williams (steve@icarus.com)
* Copyright (c) 1998-2016 Stephen Williams (steve@icarus.com)
* Copyright CERN 2013 / Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
@@ -36,6 +36,7 @@
# include "PEvent.h"
# include "PGenerate.h"
# include "PPackage.h"
# include "PScope.h"
# include "PSpec.h"
# include "netlist.h"
# include "netenum.h"
@@ -50,6 +51,9 @@
# include "ivl_assert.h"
// Implemented in elab_scope.cc
extern void set_scope_timescale(Design*des, NetScope*scope, PScope*pscope);
void PGate::elaborate(Design*, NetScope*) const
{
cerr << "internal error: what kind of gate? " <<
@@ -787,7 +791,7 @@ void PGBuiltin::elaborate(Design*des, NetScope*scope) const
if (check_delay_count(des)) return;
NetExpr* rise_time, *fall_time, *decay_time;
eval_delays(des, scope, rise_time, fall_time, decay_time);
eval_delays(des, scope, rise_time, fall_time, decay_time, true);
struct attrib_list_t*attrib_list;
unsigned attrib_list_n = 0;
@@ -1287,15 +1291,18 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
for (unsigned idx = 0 ; idx < pins.size() ; idx += 1) {
bool unconnected_port = false;
perm_string port_name = rmod->get_port_name(idx);
// Skip unconnected module ports. This happens when a
// null parameter is passed in.
if (pins[idx] == 0) {
if (pins_fromwc[idx]) {
cerr << get_fileline() << ": error: Wildcard named port " <<
"connection (.*) did not find a matching identifier " <<
"for port '" << rmod->ports[idx]->name << "'." << endl;
cerr << get_fileline() << ": error: Wildcard named "
"port connection (.*) did not find a matching "
"identifier for port " << (idx+1) << " ("
<< port_name << ")." << endl;
des->errors += 1;
return;
}
@@ -1330,22 +1337,22 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
break;
}
// Print a waring for an unconnected input.
// Print a warning for an unconnected input.
if (warn_portbinding) {
cerr << get_fileline() << ": warning: "
<< "Instantiating module "
<< rmod->mod_name()
<< " with dangling input port '"
<< rmod->ports[idx]->name;
<< " with dangling input port "
<< (idx+1) << " (" << port_name;
switch (rmod->uc_drive) {
case Module::UCD_PULL0:
cerr << "' (pulled low)." << endl;
cerr << ") pulled low." << endl;
break;
case Module::UCD_PULL1:
cerr << "' (pulled high)." << endl;
cerr << ") pulled high." << endl;
break;
case Module::UCD_NONE:
cerr << "' (floating)." << endl;
cerr << ") floating." << endl;
break;
}
}
@@ -1361,8 +1368,8 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
if (debug_elaborate) {
cerr << get_fileline() << ": debug: " << get_name()
<< ": Port " << (idx+1) << " has " << prts.size()
<< " sub-ports." << endl;
<< ": Port " << (idx+1) << " (" << port_name
<< ") has " << prts.size() << " sub-ports." << endl;
}
// Count the internal vector bits of the port.
@@ -1394,7 +1401,7 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
prt_vector_width += port_width;
ptype = PortType::merged(netnet->port_type(), ptype);
}
inst_scope->add_module_port_info(idx, rmod->get_port_name(idx), ptype, prt_vector_width );
inst_scope->add_module_port_info(idx, port_name, ptype, prt_vector_width );
}
// If I find that the port is unconnected inside the
@@ -1418,6 +1425,16 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
<< prts[0]->name() << " is coerced to inout." << endl;
}
if (!prts.empty() && (prts[0]->port_type() == NetNet::POUTPUT)
&& (prts[0]->type() != NetNet::REG)
&& prts[0]->pin(0).nexus()->has_floating_input()
&& pins[idx]->is_collapsible_net(des, scope)) {
prts[0]->port_type(NetNet::PINOUT);
cerr << pins[idx]->get_fileline() << ": warning: output port "
<< prts[0]->name() << " is coerced to inout." << endl;
}
// Elaborate the expression that connects to the
// module[s] port. sig is the thing outside the module
// that connects to the port.
@@ -1454,8 +1471,9 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
NetExpr*tmp_expr = elab_and_eval(des, scope, pins[idx], -1);
if (tmp_expr == 0) {
cerr << pins[idx]->get_fileline()
<< ": internal error: Port expression "
<< "too complicated for elaboration." << endl;
<< ": error: Failed to elaborate port expression."
<< endl;
des->errors += 1;
continue;
}
@@ -1541,8 +1559,8 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
cerr << pins[idx]->get_fileline() << ": error: "
<< "Inout port expression must support "
<< "continuous assignment." << endl;
cerr << pins[idx]->get_fileline() << ": : "
<< "Port " << rmod->ports[idx]->name << " of "
cerr << pins[idx]->get_fileline() << ": : Port "
<< (idx+1) << " (" << port_name << ") of "
<< rmod->mod_name() << " is connected to "
<< *pins[idx] << endl;
des->errors += 1;
@@ -1555,9 +1573,9 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
!prts.empty() && (prts[0]->data_type() != IVL_VT_REAL )) {
cerr << pins[idx]->get_fileline() << ": error: "
<< "Cannot automatically connect bit based "
"inout port " << rmod->ports[idx]->name
<< " of module " << rmod->mod_name() << " to real "
"signal " << sig->name() << "." << endl;
"inout port " << (idx+1) << " (" << port_name
<< ") of module " << rmod->mod_name()
<< " to real signal " << sig->name() << "." << endl;
des->errors += 1;
continue;
}
@@ -1566,9 +1584,8 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
if (!prts.empty() && (prts[0]->data_type() == IVL_VT_REAL )) {
cerr << pins[idx]->get_fileline() << ": error: "
<< "No support for connecting real inout ports ("
"port "
<< rmod->ports[idx]->name << " of module "
<< rmod->mod_name() << ")." << endl;
"port " << (idx+1) << " (" << port_name
<< ") of module " << rmod->mod_name() << ")." << endl;
des->errors += 1;
continue;
}
@@ -1581,7 +1598,7 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
// Special case: If the output port is an unpacked
// array, then there should be no sub-ports and
// the passed pexxpression is processed
// the passed port expression is processed
// differently. Note that we are calling it the
// "r-value" expression, but since this is an
// output port, we assign to it from the internal object.
@@ -1611,8 +1628,8 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
cerr << pins[idx]->get_fileline() << ": error: "
<< "Output port expression must support "
<< "continuous assignment." << endl;
cerr << pins[idx]->get_fileline() << ": : "
<< "Port " << rmod->ports[idx]->name << " of "
cerr << pins[idx]->get_fileline() << ": : Port "
<< (idx+1) << " (" << port_name << ") of "
<< rmod->mod_name() << " is connected to "
<< *pins[idx] << endl;
des->errors += 1;
@@ -1687,8 +1704,8 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
instance.size() != 1) {
cerr << pins[idx]->get_fileline() << ": error: "
<< "An arrayed instance of " << rmod->mod_name()
<< " cannot have a real port ("
<< rmod->ports[idx]->name << ") connected to a "
<< " cannot have a real port (port " << (idx+1)
<< " : " << port_name << ") connected to a "
"real signal (" << sig->name() << ")." << endl;
des->errors += 1;
continue;
@@ -1721,8 +1738,9 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
if (debug_elaborate) {
cerr << get_fileline() << ": debug: " << get_name()
<< ": Port " << (idx+1) << " has vector width of "
<< prts_vector_width << "." << endl;
<< ": Port " << (idx+1) << " (" << port_name
<< ") has vector width of " << prts_vector_width
<< "." << endl;
}
// Check that the parts have matching pin counts. If
@@ -1730,11 +1748,8 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
// based, but users count parameter positions from 1.
if ((instance.size() == 1)
&& (prts_vector_width != sig->vector_width())) {
const char *tmp3 = rmod->ports[idx]->name.str();
bool as_signed = false;
if (tmp3 == 0) tmp3 = "???";
switch (prts[0]->port_type()) {
case NetNet::POUTPUT:
as_signed = prts[0]->get_signed();
@@ -1754,7 +1769,7 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
}
cerr << get_fileline() << ": warning: Port " << (idx+1)
<< " (" << tmp3 << ") of "
<< " (" << port_name << ") of "
<< type_ << " expects " << prts_vector_width <<
" bits, got " << sig->vector_width() << "." << endl;
@@ -1999,7 +2014,7 @@ void PGModule::elaborate_udp_(Design*des, PUdp*udp, NetScope*scope) const
PDelays tmp_del;
tmp_del.set_delays(overrides_, false);
tmp_del.eval_delays(des, scope, rise_expr, fall_expr,
decay_expr);
decay_expr, true);
}
}
@@ -2282,11 +2297,18 @@ NetAssign_* PAssign_::elaborate_lval(Design*des, NetScope*scope) const
PExpr::width_mode_t mode = PExpr::SIZED;
rval_->test_width(des, scope, mode);
// Create a L-value that matches the function return type.
NetNet*tmp;
netvector_t*tmp_vec = new netvector_t(rval_->expr_type(),
rval_->expr_width()-1, 0,
rval_->has_sign());
NetNet*tmp = new NetNet(scope, scope->local_symbol(),
NetNet::REG, tmp_vec);
if(rval_->expr_type() == IVL_VT_DARRAY) {
netdarray_t*darray = new netdarray_t(tmp_vec);
tmp = new NetNet(scope, scope->local_symbol(), NetNet::REG, darray);
} else {
tmp = new NetNet(scope, scope->local_symbol(), NetNet::REG, tmp_vec);
}
tmp->set_file(rval_->get_file());
tmp->set_lineno(rval_->get_lineno());
NetAssign_*lv = new NetAssign_(tmp);
@@ -2317,7 +2339,8 @@ NetExpr* PAssign_::elaborate_rval_(Design*des, NetScope*scope,
NetExpr* PAssign_::elaborate_rval_(Design*des, NetScope*scope,
ivl_type_t lv_net_type,
ivl_variable_type_t lv_type,
unsigned lv_width) const
unsigned lv_width,
bool force_unsigned) const
{
ivl_assert(*this, rval_);
@@ -2326,7 +2349,7 @@ NetExpr* PAssign_::elaborate_rval_(Design*des, NetScope*scope,
// should look into fixing calls to this method to pass a
// net_type instead of the separate lv_width/lv_type values.
NetExpr*rv = elaborate_rval_expr(des, scope, lv_net_type, lv_type, lv_width,
rval(), is_constant_);
rval(), is_constant_, force_unsigned);
if (!is_constant_ || !rv) return rv;
@@ -2444,10 +2467,35 @@ NetProc* PAssign::elaborate_compressed_(Design*des, NetScope*scope) const
NetAssign_*lv = elaborate_lval(des, scope);
if (lv == 0) return 0;
NetExpr*rv = elaborate_rval_(des, scope, 0, lv->expr_type(), count_lval_width(lv));
// Compressed assignments should behave identically to the
// equivalent uncompressed assignments. This means we need
// to take the type of the LHS into account when determining
// the type of the RHS expression.
bool force_unsigned;
switch (op_) {
case 'l':
case 'r':
case 'R':
// The right-hand operand of shift operations is
// self-determined.
force_unsigned = false;
break;
default:
force_unsigned = !lv->get_signed();
break;
}
NetExpr*rv = elaborate_rval_(des, scope, 0, lv->expr_type(),
count_lval_width(lv), force_unsigned);
if (rv == 0) return 0;
NetAssign*cur = new NetAssign(lv, op_, rv);
// The ivl_target API doesn't support signalling the type
// of a lval, so convert arithmetic shifts into logical
// shifts now if the lval is unsigned.
char op = op_;
if ((op == 'R') && !lv->get_signed())
op = 'r';
NetAssign*cur = new NetAssign(lv, op, rv);
cur->set_line(*this);
return cur;
@@ -2669,11 +2717,16 @@ NetProc* PAssign::elaborate(Design*des, NetScope*scope) const
return bl;
}
if (lv->enumeration() &&
! lv->enumeration()->matches(rv->enumeration())) {
cerr << get_fileline() << ": error: "
<< "Enumeration type mismatch in assignment." << endl;
des->errors += 1;
if (lv->enumeration()) {
if (! rv->enumeration()) {
cerr << get_fileline() << ": error: "
"This assignment requires an explicit cast." << endl;
des->errors += 1;
} else if (! lv->enumeration()->matches(rv->enumeration())) {
cerr << get_fileline() << ": error: "
"Enumeration type mismatch in assignment." << endl;
des->errors += 1;
}
}
NetAssign*cur = new NetAssign(lv, rv);
@@ -2860,14 +2913,27 @@ NetProc* PBlock::elaborate(Design*des, NetScope*scope) const
des->errors += 1;
return 0;
}
assert(nscope);
elaborate_behaviors_(des, nscope);
}
NetBlock*cur = new NetBlock(type, nscope);
if (nscope) {
// Handle any variable initialization statements in this scope.
// For automatic scopes these statements need to be executed
// each time the block is entered, so add them to the main
// block. For static scopes, put them in a separate process
// that will be executed at the start of simulation.
if (nscope->is_auto()) {
for (unsigned idx = 0; idx < var_inits.size(); idx += 1) {
NetProc*tmp = var_inits[idx]->elaborate(des, nscope);
if (tmp) cur->append(tmp);
}
} else {
elaborate_var_inits_(des, nscope);
}
}
if (nscope == 0)
nscope = scope;
@@ -3720,7 +3786,7 @@ NetProc* PCallTask::elaborate_build_call_(Design*des, NetScope*scope,
NetExpr*rv = 0;
if (parms_idx<parms_.size() && parms_[parms_idx]) {
if (parms_idx < parms_.size() && parms_[parms_idx]) {
rv = elaborate_rval_expr(des, scope, port->net_type(),
lv_type, wid, parms_ [parms_idx]);
if (NetEEvent*evt = dynamic_cast<NetEEvent*> (rv)) {
@@ -3735,7 +3801,7 @@ NetProc* PCallTask::elaborate_build_call_(Design*des, NetScope*scope,
if (! gn_system_verilog()) {
cerr << get_fileline() << ": internal error: "
<< "Found (and using) default task expression "
<< " requires SystemVerilog." << endl;
"requires SystemVerilog." << endl;
des->errors += 1;
}
rv = def->port_defe(idx);
@@ -3770,7 +3836,9 @@ NetProc* PCallTask::elaborate_build_call_(Design*des, NetScope*scope,
expression that can be a target to a procedural
assignment, including a memory word. */
for (unsigned idx = 0 ; idx < parm_count ; idx += 1) {
for (unsigned idx = use_this?1:0 ; idx < parm_count ; idx += 1) {
size_t parms_idx = use_this? idx-1 : idx;
NetNet*port = def->port(idx);
@@ -3782,20 +3850,24 @@ NetProc* PCallTask::elaborate_build_call_(Design*des, NetScope*scope,
/* Elaborate an l-value version of the port expression
for output and inout ports. If the expression does
not exist then quietly skip it, but if the expression
is not a valid l-value print an error message. Note
that the elaborate_lval method already printed a
detailed message. */
NetAssign_*lv;
if (parms_[idx]) {
lv = parms_[idx]->elaborate_lval(des, scope, false, false);
not exist or is not a valid l-value print an error
message. Note that the elaborate_lval method already
printed a detailed message for the latter case. */
NetAssign_*lv = 0;
if (parms_idx < parms_.size() && parms_[parms_idx]) {
lv = parms_[parms_idx]->elaborate_lval(des, scope, false, false);
if (lv == 0) {
cerr << parms_[idx]->get_fileline() << ": error: "
cerr << parms_[parms_idx]->get_fileline() << ": error: "
<< "I give up on task port " << (idx+1)
<< " expression: " << *parms_[idx] << endl;
<< " expression: " << *parms_[parms_idx] << endl;
}
} else {
lv = 0;
} else if (port->port_type() == NetNet::POUTPUT) {
// Output ports were skipped earlier, so
// report the error now.
cerr << get_fileline() << ": error: "
<< "Missing argument " << (idx+1)
<< " of call to task." << endl;
des->errors += 1;
}
if (lv == 0)
@@ -4027,9 +4099,18 @@ NetProc* PDisable::elaborate(Design*des, NetScope*scope) const
*/
NetProc* PDoWhile::elaborate(Design*des, NetScope*scope) const
{
NetExpr*tmp = elab_and_eval(des, scope, cond_, -1);
tmp->set_line(*this);
NetDoWhile*loop = new NetDoWhile(tmp, statement_->elaborate(des, scope));
NetExpr*ce = elab_and_eval(des, scope, cond_, -1);
NetProc*sub;
if (statement_)
sub = statement_->elaborate(des, scope);
else
sub = new NetBlock(NetBlock::SEQU, 0);
if (ce == 0 || sub == 0) {
delete ce;
delete sub;
return 0;
}
NetDoWhile*loop = new NetDoWhile(ce, sub);
loop->set_line(*this);
return loop;
}
@@ -4560,7 +4641,11 @@ NetProc* PEventStatement::elaborate(Design*des, NetScope*scope) const
*/
NetProc* PForever::elaborate(Design*des, NetScope*scope) const
{
NetProc*stat = statement_->elaborate(des, scope);
NetProc*stat;
if (statement_)
stat = statement_->elaborate(des, scope);
else
stat = new NetBlock(NetBlock::SEQU, 0);
if (stat == 0) return 0;
NetForever*proc = new NetForever(stat);
@@ -4766,7 +4851,11 @@ NetProc* PForeach::elaborate(Design*des, NetScope*scope) const
/* Elaborate the statement that is contained in the foreach
loop. */
NetProc*sub = statement_->elaborate(des, scope);
NetProc*sub;
if (statement_)
sub = statement_->elaborate(des, scope);
else
sub = new NetBlock(NetBlock::SEQU, 0);
/* Make a step statement: idx += 1 */
NetAssign_*idx_lv = new NetAssign_(idx_sig);
@@ -4797,7 +4886,11 @@ NetProc* PForeach::elaborate_static_array_(Design*des, NetScope*scope,
ivl_assert(*this, index_vars_.size() > 0);
ivl_assert(*this, dims.size() == index_vars_.size());
NetProc*sub = statement_->elaborate(des, scope);
NetProc*sub;
if (statement_)
sub = statement_->elaborate(des, scope);
else
sub = new NetBlock(NetBlock::SEQU, 0);
NetForLoop*stmt = 0;
for (int idx_idx = index_vars_.size()-1 ; idx_idx >= 0 ; idx_idx -= 1) {
@@ -4882,7 +4975,7 @@ NetProc* PForStatement::elaborate(Design*des, NetScope*scope) const
sig->data_type(), sig->vector_width(),
expr1_);
if (debug_elaborate) {
if (debug_elaborate && initial_expr) {
cerr << get_fileline() << ": debug: FOR initial assign: "
<< sig->name() << " = " << *initial_expr << endl;
}
@@ -4891,36 +4984,35 @@ NetProc* PForStatement::elaborate(Design*des, NetScope*scope) const
loop. If there is an error, this will return 0 and I should
skip the append. No need to worry, the error has been
reported so it's OK that the netlist is bogus. */
NetProc*sub = statement_->elaborate(des, scope);
NetProc*sub;
if (statement_)
sub = statement_->elaborate(des, scope);
else
sub = new NetBlock(NetBlock::SEQU, 0);
/* Now elaborate the for_step statement. I really should do
some error checking here to make sure the step statement
really does step the variable. */
if (debug_elaborate) {
cerr << get_fileline() << ": debug: Elaborate for_step statement "
<< sig->name() << " = " << *initial_expr << endl;
}
NetProc*step = step_->elaborate(des, scope);
/* Elaborate the condition expression. Try to evaluate it too,
in case it is a constant. This is an interesting case
worthy of a warning. */
NetExpr*ce = elab_and_eval(des, scope, cond_, -1);
if (ce == 0) {
delete sub;
delete step;
return 0;
}
if (dynamic_cast<NetEConst*>(ce)) {
cerr << get_fileline() << ": warning: condition expression "
"of for-loop is constant." << endl;
}
/* Error recovery - if we failed to elaborate any of the loop
expressions, give up now. */
if (initial_expr == 0 || ce == 0 || step == 0 || sub == 0) {
delete initial_expr;
delete ce;
delete step;
delete sub;
return 0;
}
/* All done, build up the loop. */
NetForLoop*loop = new NetForLoop(sig, initial_expr, ce, sub, step);
@@ -4965,7 +5057,6 @@ void PFunction::elaborate(Design*des, NetScope*scope) const
des->errors += 1;
return;
}
assert(def);
ivl_assert(*this, statement_);
@@ -4978,6 +5069,31 @@ void PFunction::elaborate(Design*des, NetScope*scope) const
return;
}
// Handle any variable initialization statements in this scope.
// For automatic functions, these statements need to be executed
// each time the function is called, so insert them at the start
// of the elaborated definition. For static functions, put them
// in a separate process that will be executed before the start
// of simulation.
if (is_auto_) {
// Get the NetBlock of the statement. If it is not a
// NetBlock then create one to wrap the initialization
// statements and the original statement.
NetBlock*blk = dynamic_cast<NetBlock*> (st);
if ((blk == 0) && (var_inits.size() > 0)) {
blk = new NetBlock(NetBlock::SEQU, scope);
blk->set_line(*this);
blk->append(st);
st = blk;
}
for (unsigned idx = var_inits.size(); idx > 0; idx -= 1) {
NetProc*tmp = var_inits[idx-1]->elaborate(des, scope);
if (tmp) blk->prepend(tmp);
}
} else {
elaborate_var_inits_(des, scope);
}
def->set_proc(st);
}
@@ -5013,8 +5129,16 @@ NetProc* PRepeat::elaborate(Design*des, NetScope*scope) const
des->errors += 1;
return 0;
}
// If the expression is real, convert to an integer. 64 bits
// should be more enough for any real use case.
if (expr->expr_type() == IVL_VT_REAL)
expr = cast_to_int4(expr, 64);
NetProc*stat = statement_->elaborate(des, scope);
NetProc*stat;
if (statement_)
stat = statement_->elaborate(des, scope);
else
stat = new NetBlock(NetBlock::SEQU, 0);
if (stat == 0) return 0;
// If the expression is a constant, handle certain special
@@ -5132,11 +5256,6 @@ NetProc* PReturn::elaborate(Design*des, NetScope*scope) const
void PTask::elaborate(Design*des, NetScope*task) const
{
// Elaborate any processes that are part of this scope that
// aren't the definition itself. This can happen, for example,
// with variable initialization statements in this scope.
elaborate_behaviors_(des, task);
NetTaskDef*def = task->task_def();
assert(def);
@@ -5155,6 +5274,31 @@ void PTask::elaborate(Design*des, NetScope*task) const
}
}
// Handle any variable initialization statements in this scope.
// For automatic tasks , these statements need to be executed
// each time the task is called, so insert them at the start
// of the elaborated definition. For static tasks, put them
// in a separate process that will be executed before the start
// of simulation.
if (is_auto_) {
// Get the NetBlock of the statement. If it is not a
// NetBlock then create one to wrap the initialization
// statements and the original statement.
NetBlock*blk = dynamic_cast<NetBlock*> (st);
if ((blk == 0) && (var_inits.size() > 0)) {
blk = new NetBlock(NetBlock::SEQU, task);
blk->set_line(*this);
blk->append(st);
st = blk;
}
for (unsigned idx = var_inits.size(); idx > 0; idx -= 1) {
NetProc*tmp = var_inits[idx-1]->elaborate(des, task);
if (tmp) blk->prepend(tmp);
}
} else {
elaborate_var_inits_(des, task);
}
def->set_proc(st);
}
@@ -5193,9 +5337,18 @@ NetProc* PTrigger::elaborate(Design*des, NetScope*scope) const
*/
NetProc* PWhile::elaborate(Design*des, NetScope*scope) const
{
NetExpr*tmp = elab_and_eval(des, scope, cond_, -1);
tmp->set_line(*this);
NetWhile*loop = new NetWhile(tmp, statement_->elaborate(des, scope));
NetExpr*ce = elab_and_eval(des, scope, cond_, -1);
NetProc*sub;
if (statement_)
sub = statement_->elaborate(des, scope);
else
sub = new NetBlock(NetBlock::SEQU, 0);
if (ce == 0 || sub == 0) {
delete ce;
delete sub;
return 0;
}
NetWhile*loop = new NetWhile(ce, sub);
loop->set_line(*this);
return loop;
}
@@ -5602,6 +5755,10 @@ bool Module::elaborate(Design*des, NetScope*scope) const
(*gt)->elaborate(des, scope);
}
// Elaborate the variable initialization statements, making a
// single initial process out of them.
result_flag &= elaborate_var_inits_(des, scope);
// Elaborate the behaviors, making processes out of them. This
// involves scanning the PProcess* list, creating a NetProcTop
// for each process.
@@ -5679,6 +5836,9 @@ bool PGenerate::elaborate(Design*des, NetScope*container) const
"generate " << scheme_type
<< " elaborating in scope " << scope_path(container)
<< "." << endl;
cerr << get_fileline() << ": PGenerate::elaborate: "
"generate scope_name=" << scope_name
<< ", id_number=" << id_number << endl;
}
// Handle the special case that this is a CASE scheme. In this
@@ -5713,6 +5873,7 @@ bool PGenerate::elaborate(Design*des, NetScope*container) const
// scheme defined in the Verilog-2005 standard.
const char*name = scope_name.str();
if (name[0] == '$') {
if (!scope->auto_name("genblk", '0', name + 4)) {
cerr << get_fileline() << ": warning: Couldn't build"
<< " unique name for unnamed generate block"
@@ -5788,6 +5949,8 @@ bool PGenerate::elaborate_(Design*des, NetScope*scope) const
for (gates_it_t cur = gates.begin() ; cur != gates.end() ; ++ cur )
(*cur)->elaborate(des, scope);
elaborate_var_inits_(des, scope);
typedef list<PProcess*>::const_iterator proc_it_t;
for (proc_it_t cur = behaviors.begin(); cur != behaviors.end(); ++ cur )
(*cur)->elaborate(des, scope);
@@ -5823,6 +5986,44 @@ bool PScope::elaborate_behaviors_(Design*des, NetScope*scope) const
return result_flag;
}
bool LexicalScope::elaborate_var_inits_(Design*des, NetScope*scope) const
{
if (var_inits.size() == 0)
return true;
NetProc*proc = 0;
if (var_inits.size() == 1) {
proc = var_inits[0]->elaborate(des, scope);
} else {
NetBlock*blk = new NetBlock(NetBlock::SEQU, 0);
bool flag = true;
for (unsigned idx = 0; idx < var_inits.size(); idx += 1) {
NetProc*tmp = var_inits[idx]->elaborate(des, scope);
if (tmp)
blk->append(tmp);
else
flag = false;
}
if (flag) proc = blk;
}
if (proc == 0)
return false;
NetProcTop*top = new NetProcTop(scope, IVL_PR_INITIAL, proc);
if (const LineInfo*li = dynamic_cast<const LineInfo*>(this)) {
top->set_line(*li);
}
if (gn_system_verilog()) {
top->attribute(perm_string::literal("_ivl_schedule_init"),
verinum(1));
}
des->add_process(top);
scope->set_var_init(proc);
return true;
}
class elaborate_package_t : public elaborator_work_item_t {
public:
elaborate_package_t(Design*d, NetScope*scope, PPackage*p)
@@ -6056,6 +6257,7 @@ Design* elaborate(list<perm_string>roots)
ivl_assert(*pac->second, pac->first == pac->second->pscope_name());
NetScope*scope = des->make_package_scope(pac->first);
scope->set_line(pac->second);
set_scope_timescale(des, scope, pac->second);
elaborator_work_item_t*es = new elaborate_package_t(des, scope, pac->second);
des->elaboration_work_list.push_back(es);
@@ -6086,16 +6288,13 @@ Design* elaborate(list<perm_string>roots)
// Make the root scope. This makes a NetScope object and
// pushes it into the list of root scopes in the Design.
NetScope*scope = des->make_root_scope(*root, rmod->program_block);
NetScope*scope = des->make_root_scope(*root, rmod->program_block,
rmod->is_interface);
// Collect some basic properties of this scope from the
// Module definition.
scope->set_line(rmod);
scope->time_unit(rmod->time_unit);
scope->time_precision(rmod->time_precision);
scope->time_from_timescale(rmod->time_from_timescale);
des->set_precision(rmod->time_precision);
set_scope_timescale(des, scope, rmod);
// Save this scope, along with its definition, in the
// "root_elems" list for later passes.
+6 -2
View File
@@ -507,7 +507,6 @@ int Design::emit(struct target_t*tgt) const
for (map<NetScope*,PTaskFunc*>::const_iterator scope = root_tasks_.begin()
; scope != root_tasks_.end() ; ++ scope) {
scope->first->emit_scope(tgt);
scope->first->emit_defs(tgt);
}
// enumerate package scopes
@@ -521,7 +520,6 @@ int Design::emit(struct target_t*tgt) const
const NetScope*use_scope = cur->second->class_scope();
cur->second->emit_scope(tgt);
tgt->class_type(use_scope, cur->second);
cur->second->emit_defs(tgt);
}
// enumerate root scopes
@@ -548,6 +546,12 @@ int Design::emit(struct target_t*tgt) const
// emit task and function definitions
bool tasks_rc = true;
for (map<NetScope*,PTaskFunc*>::const_iterator scope = root_tasks_.begin()
; scope != root_tasks_.end() ; ++ scope)
tasks_rc &= scope->first->emit_defs(tgt);
for (map<perm_string,netclass_t*>::const_iterator cur = classes_.begin()
; cur != classes_.end() ; ++cur)
tasks_rc &= cur->second->emit_defs(tgt);
for (map<perm_string,NetScope*>::const_iterator scope = packages_.begin()
; scope != packages_.end() ; ++ scope )
tasks_rc &= scope->second->emit_defs(tgt);
+14 -3
View File
@@ -697,7 +697,9 @@ NetEConst* NetEBComp::eval_eqeqeq_(bool ne_flag, const NetExpr*le, const NetExpr
// If the left value is longer check it against the pad bit.
if (res == verinum::V1) {
verinum::V pad = verinum::V0;
if (is_signed) pad = rv.get(rv.len()-1);
if (is_signed)
pad = rv.get(rv.len()-1);
for (unsigned idx = cnt ; idx < lv.len() ; idx += 1)
if (lv.get(idx) != pad) {
res = verinum::V0;
@@ -708,12 +710,15 @@ NetEConst* NetEBComp::eval_eqeqeq_(bool ne_flag, const NetExpr*le, const NetExpr
// If the right value is longer check it against the pad bit.
if (res == verinum::V1) {
verinum::V pad = verinum::V0;
if (is_signed) pad = lv.get(lv.len()-1);
if (is_signed)
pad = lv.get(lv.len()-1);
for (unsigned idx = cnt ; idx < rv.len() ; idx += 1) {
if (rv.get(idx) != pad)
if (rv.get(idx) != pad) {
res = verinum::V0;
break;
}
}
}
if (ne_flag) {
@@ -2009,6 +2014,12 @@ static bool check_dimension(const NetExpr*dim_expr, long &dim)
static bool get_array_info(const NetExpr*arg, long dim,
long &left, long &right, bool&defer)
{
if (const NetEConstParam*param = dynamic_cast<const NetEConstParam*>(arg)) {
assert(dim == 1);
left = param->expr_width() - 1;
right = 0;
return false;
}
/* The argument must be a signal that has enough dimensions. */
const NetESignal*esig = dynamic_cast<const NetESignal*>(arg);
if (esig == 0) return true;
+20 -8
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1999-2013 Stephen Williams (steve@icarus.com)
* Copyright (c) 1999-2015 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
@@ -1138,18 +1138,29 @@ NetNet* NetESelect::synthesize(Design *des, NetScope*scope, NetExpr*root)
if (sub->vector_width() == expr_width())
return sub;
// The vector_width is not exactly right, so the source is
// probably asking for padding. Create nodes to do sign
// extension or 0 extension, depending on the has_sign() mode
// of the expression.
netvector_t*net_vec = new netvector_t(expr_type(), expr_width()-1, 0);
net_vec->set_signed(has_sign());
NetNet*net = new NetNet(scope, scope->local_symbol(),
NetNet::IMPLICIT, net_vec);
net->set_line(*this);
net->local_flag(true);
if (has_sign()) {
// It may still happen that the expression is wider than the selection,
// and there was no part select created earlier (size casting).
if(expr_width() < sub->vector_width()) {
NetPartSelect*sel = new NetPartSelect(sub, 0, expr_width(),
NetPartSelect::VP, has_sign());
sel->set_line(*this);
des->add_node(sel);
connect(net->pin(0), sel->pin(0));
// The vector_width is not exactly right, so the source is
// probably asking for padding. Create nodes to do sign
// extension or 0 extension, depending on the has_sign() mode
// of the expression.
} else if (has_sign()) {
NetSignExtend*pad = new NetSignExtend(scope,
scope->local_symbol(),
expr_width());
@@ -1166,7 +1177,6 @@ NetNet* NetESelect::synthesize(Design *des, NetScope*scope, NetExpr*root)
cat->set_line(*this);
des->add_node(cat);
assert(expr_width() > sub->vector_width());
unsigned pad_width = expr_width() - sub->vector_width();
verinum pad((uint64_t)0, pad_width);
NetConst*con = new NetConst(scope, scope->local_symbol(),
@@ -1278,6 +1288,8 @@ NetNet* NetESignal::synthesize(Design*des, NetScope*scope, NetExpr*root)
net_->vector_width()-1, 0);
NetNet*tmp = new NetNet(scope, scope->local_symbol(),
NetNet::IMPLICIT, tmp_vec);
tmp->set_line(*this);
tmp->local_flag(true);
verinum tmp_val ((uint64_t)scope->genvar_tmp_val, net_->vector_width());
NetConst*tmp_const = new NetConst(scope, scope->local_symbol(), tmp_val);
tmp_const->set_line(*this);
+39 -47
View File
@@ -1,10 +1,10 @@
.TH iverilog-vpi 1 "April 17th, 2009" "" "Version %M.%m.%n %E"
.TH iverilog-vpi 1 "Jan 29th, 2017" "" "Version %M.%n%E"
.SH NAME
iverilog-vpi - Compile front end for VPI modules
.SH SYNOPSIS
.B iverilog-vpi
[\-\-name=\fIname\fP]
[options]
\fIsourcefile\fP...
.SH DESCRIPTION
@@ -15,9 +15,9 @@ list of C or C++ source files, and generates as output a linked VPI
module. See the \fBvvp\fP(1) man page for a description of how the
linked module is loaded by a simulation.
The output is named after the first source file. For example, if the
first source file is named \fIfoo.c\fP, the output becomes
\fIfoo.vpi\fP.
By default the output is named after the first source file. For
example, if the first source file is named \fIfoo.c\fP, the output
becomes \fIfoo.vpi\fP.
.SH OPTIONS
\fIiverilog\-vpi\fP accepts the following options:
@@ -26,10 +26,15 @@ first source file is named \fIfoo.c\fP, the output becomes
Include the named library in the link of the VPI module. This allows
VPI modules to further reference external libraries.
.TP 8
.B -L\fIdirectory\fP
Add \fIdirectory\fP to the list of directories that will be searched
for library files.
.TP 8
.B -I\fIdirectory\fP
Add \fIdirectory\fP to the list of directories that will be search for
header files.
Add \fIdirectory\fP to the list of directories that will be searched
for header files.
.TP 8
.B -D\fIdefine\fP
@@ -41,46 +46,38 @@ Normally, the output VPI module will be named after the first source
file passed to the command. This flag sets the name (without the .vpi
suffix) of the output vpi module.
.TP 8
.B --install-dir
This flag causes the program to print the install directory for VPI
modules, then exit. It is a convenience for makefiles or automated
plug-in installers.
.TP 8
.B --cflags, --ldflags and --ldlibs
These flags provide compile time information.
.SH "PC-ONLY OPTIONS"
The PC port of \fIiverilog\-vpi\fP includes two special flags needed to
support the more intractable development environment. These flags help
the program locate parts that it needs.
When built as a native Windows program (using the MinGW toolchain),
by default \fIiverilog\-vpi\fP will attempt to locate the MinGW tools
needed to compile a VPI module on the system path (as set by the PATH
environment variable). As an alternative, the user may specify the
location of the MinGW tools via the following option.
.TP 8
.B -mingw=\fIpath\fP
Tell the program the root of the Mingw compiler tool suite. The
Tell the program the root of the MinGW compiler tool suite. The
\fBvvp\fP runtime is compiled with this compiler, and this is the
compiler that \fIiverilog\-vpi\fP expects to use to compile your source
code. This is normally not needed, and if you do use it, it is only
needed once. The compiler will save the \fIpath\fP in the registry for
use later.
compiler that \fIiverilog\-vpi\fP expects to use to compile your
source code. If this option accompanies a list of files, it will
apply to the current build only. If this option is provided on its
own, \fIiverilog\-vpi\fP will save the \fIpath\fP in the registry
and use that path in preference to the system path for subsequent
operations, avoiding the need to specify it on the command line
every time.
.SH "INFORMATIONAL OPTIONS"
\fIiverilog\-vpi\fP includes additional flags to let Makefile gurus
peek at the configuration of the \fIiverilog\fP installation. This way,
Makefiles can be written that handle complex VPI builds natively, and
without hard-coding values that depend on the system and installation.
If used at all, these options must be used one at a time, and without
any other options or directives.
.TP 8
.B -ivl=\fIpath\fP
Set for the use during compilation the root if the Icarus Verilog
install. This is the place where you installed Icarus Verilog when you
ran the installer. This flag is also only needed once, and the path is
stored in the registry for future use.
.SH "UNIX-ONLY OPTIONS"
The UNIX version of \fIiverilog\-vpi\fP includes additional flags to
let Makefile gurus peek at the configuration of the \fIiverilog\fP
installation. This way, Makefiles can be written that handle complex VPI
builds natively, and without hard-coding values that depend on the
system and installation. If used at all, these options must be
used one at a time, and without any other options or directives.
.B --install-dir
Print the install directory for VPI modules.
.TP 8
.B --cflags
@@ -95,11 +92,6 @@ Print the linker flags (LDFLAGS) needed to link a VPI module.
.B --ldlibs
Print the libraries (LDLIBS) needed to link a VPI module.
.TP 8
.B -m32
On 64bit systems that support it (and support vvp32) this flag
requests a 32bit vpi binary instead of the default 64bit binary.
.P
Example GNU makefile that takes advantage of these flags:
.IP "" 4
@@ -123,12 +115,12 @@ Steve Williams ([email protected])
.SH SEE ALSO
iverilog(1), vvp(1),
.BR "<http://www.icarus.com/eda/verilog/>",
.BR "<http://www.mingw.org>",
.BR "<http://iverilog.icarus.com/>",
.BR "<http://mingw-w64.yaxm.org/>",
.SH COPYRIGHT
.nf
Copyright \(co 2002\-2009 Stephen Williams
Copyright \(co 2002\-2017 Stephen Williams
This document can be freely redistributed according to the terms of the
GNU General Public License version 2.0
+5 -1
View File
@@ -35,6 +35,7 @@ CCSRC=
CXSRC=
OBJ=
LIB=
LIBDIR=
OUT=
INCOPT=
DEFS=
@@ -81,6 +82,9 @@ do
-l*) LIB="$LIB $parm"
;;
-L*) LIBDIR="$LIBDIR $parm"
;;
-I*) INCOPT="$INCOPT $parm"
;;
@@ -148,4 +152,4 @@ then
fi
echo "Making $OUT from $OBJ..."
exec $LD -o $OUT $LDFLAGS $OBJ $LIB $LDLIBS
exec $LD -o $OUT $LDFLAGS $LIBDIR $OBJ $LIB $LDLIBS
+1
View File
@@ -125,6 +125,7 @@ ivl_lpm_enable
ivl_lpm_file
ivl_lpm_lineno
ivl_lpm_name
ivl_lpm_negedge
ivl_lpm_q
ivl_lpm_scope
ivl_lpm_select
+2
View File
@@ -26,6 +26,7 @@
# include <stdio.h>
#endif
#if defined(__GNUC__)
/*
* Define a safer version of malloc().
*/
@@ -82,5 +83,6 @@
} \
__ivl_rtn; \
})
#endif
#endif /* IVL_ivl_alloc_H */
+17 -8
View File
@@ -1,7 +1,7 @@
#ifndef IVL_ivl_target_H
#define IVL_ivl_target_H
/*
* Copyright (c) 2000-2014 Stephen Williams (steve@icarus.com)
* Copyright (c) 2000-2015 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
@@ -41,6 +41,12 @@
# define __attribute__(x)
#endif
#if defined(__cplusplus) && defined(_MSC_VER)
# define ENUM_UNSIGNED_INT : unsigned int
#else
# define ENUM_UNSIGNED_INT
#endif
_BEGIN_DECL
/*
@@ -201,7 +207,7 @@ typedef enum ivl_dis_domain_e {
IVL_DIS_CONTINUOUS = 2
} ivl_dis_domain_t;
typedef enum ivl_drive_e {
typedef enum ivl_drive_e ENUM_UNSIGNED_INT {
IVL_DR_HiZ = 0,
IVL_DR_SMALL = 1,
IVL_DR_MEDIUM = 2,
@@ -243,7 +249,7 @@ typedef enum ivl_expr_type_e {
IVL_EX_UNARY = 14
} ivl_expr_type_t;
typedef enum ivl_select_type_e {
typedef enum ivl_select_type_e ENUM_UNSIGNED_INT {
IVL_SEL_OTHER = 0,
IVL_SEL_IDX_UP = 1,
IVL_SEL_IDX_DOWN = 2
@@ -300,7 +306,7 @@ typedef enum ivl_lpm_type_e {
IVL_LPM_CONCAT = 16,
IVL_LPM_CONCATZ = 36, /* Transparent concat */
IVL_LPM_CMP_EEQ= 18, /* Case EQ (===) */
IVL_LPM_CMP_EQX= 37, /* Windcard EQ (==?) */
IVL_LPM_CMP_EQX= 37, /* Wildcard EQ (==?) */
IVL_LPM_CMP_EQZ= 38, /* casez EQ */
IVL_LPM_CMP_EQ = 10,
IVL_LPM_CMP_GE = 1,
@@ -345,7 +351,7 @@ typedef enum ivl_path_edge_e {
/* Processes are initial, always, or final blocks with a statement. This is
the type of the ivl_process_t object. */
typedef enum ivl_process_type_e {
typedef enum ivl_process_type_e ENUM_UNSIGNED_INT {
IVL_PR_INITIAL = 0,
IVL_PR_ALWAYS = 1,
IVL_PR_FINAL = 2
@@ -431,7 +437,7 @@ typedef enum ivl_sfunc_as_task_e {
/* This is the type of a variable, and also used as the type for an
expression. */
typedef enum ivl_variable_type_e {
typedef enum ivl_variable_type_e ENUM_UNSIGNED_INT {
IVL_VT_VOID = 0, /* Not used */
IVL_VT_NO_TYPE = 1, /* Place holder for missing/unknown type. */
IVL_VT_REAL = 2,
@@ -1285,8 +1291,8 @@ extern unsigned ivl_lpm_lineno(ivl_lpm_t net);
* magnitude compare, the signedness does matter. In any case, the
* result of the compare is always unsigned.
*
* The EQX and EQZ nodes are windcard compares, where xz bits (EQX) or
* z bits (EQZ) in the data(1) operand are treated as windcards. no
* The EQX and EQZ nodes are wildcard compares, where xz bits (EQX) or
* z bits (EQZ) in the data(1) operand are treated as wildcards. no
* bits in the data(0) operand are wild. This matches the
* SystemVerilog convention for the ==? operator.
*
@@ -1418,6 +1424,7 @@ extern ivl_signal_t ivl_lpm_array(ivl_lpm_t net);
/* IVL_LPM_PART IVL_LPM_SUBSTITUTE */
extern unsigned ivl_lpm_base(ivl_lpm_t net);
/* IVL_LPM_FF */
extern unsigned ivl_lpm_negedge(ivl_lpm_t net);
extern ivl_nexus_t ivl_lpm_clk(ivl_lpm_t net);
/* IVL_LPM_UFUNC */
extern ivl_scope_t ivl_lpm_define(ivl_lpm_t net);
@@ -2342,4 +2349,6 @@ typedef const char* (*target_query_f) (const char*key);
_END_DECL
#undef ENUM_UNSIGNED_INT
#endif /* IVL_ivl_target_H */
+1 -1
View File
@@ -95,7 +95,7 @@ keys, with their corresponding values, are:
This is exactly the same as the "-Dname=<value>" described above.
I:<dir>
This is exctly the same as "-I<dir>".
This is exactly the same as "-I<dir>".
relative include:<flag>
The <flag> can be "true" or "false". This enables "relative
+240 -356
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -1,5 +1,5 @@
const char COPYRIGHT[] =
"Copyright (c) 1999-2011 Stephen Williams ([email protected])";
"Copyright (c) 1999-2011,2015 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 -14
View File
@@ -4,7 +4,7 @@
%{
/*
* Copyright (c) 1998-2014 Stephen Williams ([email protected])
* Copyright (c) 1998-2015 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
@@ -432,18 +432,28 @@ TU [munpf]
return SYSTEM_IDENTIFIER; }
\'[sS]?[dD][ \t]*[0-9][0-9_]* { yylval.number = make_unsized_dec(yytext);
return BASED_NUMBER; }
\'[sS]?[dD][ \t]*[xzXZ?]_* { yylval.number = make_undef_highz_dec(yytext);
return BASED_NUMBER; }
\'[sS]?[bB][ \t]*[0-1xzXZ_\?]+ { yylval.number = make_unsized_binary(yytext);
return BASED_NUMBER; }
\'[sS]?[oO][ \t]*[0-7xzXZ_\?]+ { yylval.number = make_unsized_octal(yytext);
return BASED_NUMBER; }
\'[sS]?[hH][ \t]*[0-9a-fA-FxzXZ_\?]+ { yylval.number = make_unsized_hex(yytext);
return BASED_NUMBER; }
\'[sS]?[dD][ \t]*[0-9][0-9_]* {
yylval.number = make_unsized_dec(yytext);
return BASED_NUMBER;
}
\'[sS]?[dD][ \t]*[xzXZ?]_* {
yylval.number = make_undef_highz_dec(yytext);
return BASED_NUMBER;
}
\'[sS]?[bB][ \t]*[0-1xzXZ?][0-1xzXZ?_]* {
yylval.number = make_unsized_binary(yytext);
return BASED_NUMBER;
}
\'[sS]?[oO][ \t]*[0-7xzXZ?][0-7xzXZ?_]* {
yylval.number = make_unsized_octal(yytext);
return BASED_NUMBER;
}
\'[sS]?[hH][ \t]*[0-9a-fA-FxzXZ?][0-9a-fA-FxzXZ?_]* {
yylval.number = make_unsized_hex(yytext);
return BASED_NUMBER;
}
\'[01xzXZ] {
if (generation_flag < GN_VER2005_SV) {
if (!gn_system_verilog()) {
cerr << yylloc.text << ":" << yylloc.first_line << ": warning: "
<< "Using SystemVerilog 'N bit vector. Use at least "
<< "-g2005-sv to remove this warning." << endl;
@@ -469,7 +479,7 @@ TU [munpf]
/* This rule handles scaled time values for SystemVerilog. */
[0-9][0-9_]*(\.[0-9][0-9_]*)?{TU}?s {
if(generation_flag & (GN_VER2005_SV | GN_VER2009 | GN_VER2012)) {
if (gn_system_verilog()) {
yylval.text = strdupnew(yytext);
return TIME_LITERAL;
} else REJECT; }
@@ -847,7 +857,7 @@ verinum*make_unsized_binary(const char*txt)
ptr += 1;
}
assert((tolower(*ptr) == 'b') || (generation_flag >= GN_VER2005_SV));
assert((tolower(*ptr) == 'b') || gn_system_verilog());
if (tolower(*ptr) == 'b') {
ptr += 1;
} else {
+5
View File
@@ -27,6 +27,11 @@ LineInfo::LineInfo()
{
}
LineInfo::LineInfo(const LineInfo&that) :
file_(that.file_), lineno_(that.lineno_)
{
}
LineInfo::~LineInfo()
{
}
+1
View File
@@ -36,6 +36,7 @@ using namespace std;
class LineInfo {
public:
LineInfo();
LineInfo(const LineInfo&that);
virtual ~LineInfo();
// Get a fully formatted file/lineno
+1 -1
View File
@@ -36,7 +36,7 @@ double acc_fetch_paramval(handle object)
fprintf(pli_trace, "acc_fetch_paramval(%s) --> \"%s\"\n",
vpi_get_str(vpiName, object), val.value.str);
}
return (double) (long)val.value.str;
return (double) (intptr_t)val.value.str;
default:
vpi_printf("XXXX: parameter %s has type %d\n",
+1 -1
View File
@@ -115,7 +115,7 @@ PLI_INT32 tf_getlongtime(PLI_INT32 *high)
}
/*
* This function is not defined in the IEE standard, but is provided for
* This function is not defined in the IEEE standard, but is provided for
* compatibility with other simulators. On platforms that support this,
* make it a weak symbol just in case the user has defined their own
* function for this.
+20 -6
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2000-2013 Stephen Williams (steve@icarus.com)
* Copyright (c) 2000-2015 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
@@ -45,6 +45,14 @@ bool Nexus::drivers_constant() const
return false;
}
/* If we are connected to a tran, there may be a driver
on the other side of the tran. We could try checking
for this, but for now, be pessimistic. */
if (dynamic_cast<const NetTran*>(cur->get_obj())) {
driven_ = VAR;
return false;
}
Link::DIR cur_dir = cur->get_dir();
if (cur_dir == Link::INPUT)
continue;
@@ -267,11 +275,17 @@ vector<bool> Nexus::driven_mask(void) const
}
const NetPartSelect*obj_ps = dynamic_cast<const NetPartSelect*>(obj);
if (obj_ps && obj_ps->dir()==NetPartSelect::VP)
continue;
if (obj_ps && cur->get_pin()!=1)
continue;
if (obj_ps) {
if(obj_ps) {
if (obj_ps->dir()==NetPartSelect::VP) {
if(cur->get_pin() != 0)
continue;
for (size_t idx = 0 ; idx < mask.size() ; idx += 1)
mask[idx] = true;
return mask;
} else {
if (cur->get_pin() != 1)
continue;
}
for (unsigned idx = 0 ; idx < obj_ps->width() ; idx += 1) {
size_t bit = idx + obj_ps->base();
ivl_assert(*obj, bit < mask.size());
+14 -2
View File
@@ -1,5 +1,5 @@
const char COPYRIGHT[] =
"Copyright (c) 1998-2014 Stephen Williams ([email protected])";
"Copyright (c) 1998-2015 Stephen Williams ([email protected])";
/*
* This source code is free software; you can redistribute it
@@ -108,6 +108,7 @@ bool gn_assertions_flag = true;
bool gn_io_range_error_flag = true;
bool gn_strict_ca_eval_flag = false;
bool gn_strict_expr_width_flag = false;
bool gn_shared_loop_index_flag = false;
bool gn_verilog_ams_flag = false;
/*
@@ -153,6 +154,7 @@ FILE *depend_file = NULL;
* These are the warning enable flags.
*/
bool warn_implicit = false;
bool warn_implicit_dimensions = false;
bool warn_timescale = false;
bool warn_portbinding = false;
bool warn_inf_loop = false;
@@ -343,6 +345,12 @@ static void process_generation_flag(const char*gen)
} else if (strcmp(gen,"no-strict-expr-width") == 0) {
gn_strict_expr_width_flag = false;
} else if (strcmp(gen,"shared-loop-index") == 0) {
gn_shared_loop_index_flag = true;
} else if (strcmp(gen,"no-shared-loop-index") == 0) {
gn_shared_loop_index_flag = false;
} else {
}
}
@@ -678,6 +686,9 @@ static void read_iconfig_file(const char*ipath)
case 'i':
warn_implicit = true;
break;
case 'd':
warn_implicit_dimensions = true;
break;
case 'l':
warn_inf_loop = true;
break;
@@ -859,6 +870,7 @@ int main(int argc, char*argv[])
# if defined(HAVE_TIMES)
times_flag = true;
# endif
flags["VVP_EXTRA_ARGS"] = strdup(" -v");
break;
case 'V':
version_flag = true;
@@ -1106,7 +1118,7 @@ int main(int argc, char*argv[])
/* Decide if we are going to allow system functions to be called
* as tasks. */
if (generation_flag >= GN_VER2005_SV) {
if (gn_system_verilog()) {
def_sfunc_as_task = IVL_SFUNC_AS_TASK_WARNING;
}
+3 -281
View File
@@ -1,282 +1,4 @@
Please NOTE:
Please see the Icarus Verilog Wiki for instruction on building and installing
Icarus Verilog as a native Windows application using the MinGW tools:
These directions are slightly outdated and need to be updated.
The plan is to rewrite all this using the latest MinGW at
some time in the not too distant future (CR Aug. 2009)
MINGW PORT OF ICARUS VERILOG
Copyright 2006 Stephen Williams <[email protected]>
Icarus Verilog source can be compiled with the mingw C/C++ compilers
to get a Windows binary that does not require the POSIX compatibility
cruft of the Cygwin.dll library. The resulting program can be run with
or without Cygwin, so this is the preferred Windows distribution form.
The configure scripts automatically detect that the compilers in use
are the mingw compilers and will configure the Makefiles appropriately.
The mingw patch doesn't contain tools beyond the compiler, but there
is the "msys" package that the makers of Mingw publish that has enough
extra tools to get most everything else working. There are a few extra
packages needed beyond mingw and msys, and the following instructions
explain how to get them and install them.
* Some Preliminary Comments -- PLEASE READ ME --
The Windows port of Icarus Verilog is the most difficult of all the
ports. The Windows system off the shelf is completely stripped, devoid
of any support for software development. Everything needed to compile
Icarus Verilog must be collected from various sources and stitched
together by hand. Normal human beings with a basic understanding of
software development can do this, but some patience (and access to the
Internet) is required. You may choose to print these instructions. FOR
BEST RESULTS, FOLLOW THESE INSTRUCTIONS CAREFULLY.
NOTE that if you have Cygwin installed, it is best to not use a cygwin
window to do the build, as the Cygwin tools will intermix with the
mingw tools such that it is hard to be sure you are using the right
compiler. Thus, it is recommended that these steps be *not* done in a
Cygwin window. Use an MSYS window instead, and be careful that your
msys/mingw tools are not masked by paths that point to Cygwin binaries.
I have no plans to intentionally support MSVC++ compilation. Don't ask.
* Summary of Prerequisites
This is a brief list of prerequisite packages, along with the URL
where each can be found. In most cases, the specific version is not
critical, but these are the versions I use.
msys-1.0 <http://www.mingw/org>
msysDTK-1.0 <http://www.mingw.org>
Mingw32-5.x <http://www.mingw.org>
... including the sub-packages binutils, gcc-core and gcc-g++
if you are given the option.
readline-5.0-1 <http://gnuwin32.sourceforge.net>
bzip2-1.0.3 <http://gnuwin32.sourceforge.net>
zlib-1.2.3 <http://gnuwin32.sourceforge.net>
gperf-3.0.1 <http://gnuwin32.sourceforge.net>
bison-2.1 <http://gnuwin32.sourceforge.net>
flex-2.5.4a <http://gnuwin32.sourceforge.net>
The above table lists the packages required. It is convenient to
install them in the above order. Many of these packages are also
collected into the directory:
<ftp://icarus.com/pub/eda/verilog/win32-build-parts>
Incidentally, besides Mingw32, none of these packages are needed after
installation of Icarus Verilog is complete. These are only needed to
build the compiler. The Mingw32 package can be used to compile VPI
modules if you choose.
* Install MSYS and msysDTK
The msys package is available from the mingw download site. This is
not the compiler but a collection of *nix tools ported to Windows and
wrapped in a convenient installer. The msys package is all the various
basic tools (shells, file utils, etc) and the msysDTK is extra
developer tools other than the compiler.
Download the msys-1.x.x.exe and msysdtc-1.x.x.exe binaries. These are
self-installing packages. Install msys first, and then msysDTC. Most
likely, you want to install them in c:/msys. (The msysDTK is installed
in the same location, as it is an add-on.)
This install should be easy and reliable.
The installation will leave an "msys" icon on your desktop and in the
mingw sub-menu of your Start menu. This icon brings up a shell window
(a command line) that has paths all set up for executing msys and
mingw commands. This is what you will want to use while executing
commands below.
* Install Mingw32
The obvious step 2, then, is install the mingw compilers. These can be
found at the web page <http://www.mingw.org>. The Mingw-5.x.x package
is a convenient remote installer. Download this program and run
it. The installer will ask which components you want to install. You
need only the base C compiler and the C++ compiler. (You may install
other languages if you wish.)
When I install Mingw32 (using the installer) I typically set a
destination directory of d:\mingw or the like. You will be using
that path later.
NOTES:
If you intend to compile VPI modules for Icarus Verilog, you
need Mingw32, even if you are using a precompiled binary. VPI
modules only require Mingw32, and none of the other libraries.
Finally, as part of installing the mingw32 compilers, remember to add
the mingw/bin directory to your path. You will need that to be able to
find the compilers later.
* Install GnuWin32 Packages
The GnuWin32 project is a collections of open source programs and
libraries ported to Windows. These also work well with the Mingw
compiler, and in fact Icarus Verilog uses a few pieces from this
collection.
You will need these gnuwin32 packages to compile Icarus Verilog:
<http://gnuwin32.sourceforge.net>
bzip2-1.0.3.exe
zlib-1.2.3.exe
gperf-3.0.1.exe
bison-2.1.exe
flex-2.5.4a.exe
readline-5.0-1.exe
I suggest creating a common directory for holding all your gnuwin32
packages. I use C:\gnuwin32. The download page at the gnuwin32 site
has a "setup" link for each of these packages. Click the setup to
download the installer for each of the desired programs, then execute
the downloaded .exe files to invoke the installer. Install into the
c:\gunwin32 directory.
NOTES:
You need the binaries and the developer files, but you do not
need the source to these packages. The installer gives you the
choice.
After you are done installing the gnuwin32 tools, you should add the
c:\gnuwin32\bin directory (assuming you installed in c:\gnuwin32) to
your Windows path. The msys shell will pick up your Windows path.
* Unpack Icarus Verilog source
Unpack the compressed tar file (.tar.gz) of the source with a command
like this:
$ gunzip -d verilog-xxxxxxxx.tar.gz | tar xvf -
This will create a directory "verilog-xxxxxxxx" that contains all the
source for Icarus Verilog. Descend into that directory, as that is
where we will work from now on.
$ cd verilog-xxxxxxxx
NOTES:
The exact name of the file will vary according to the
snapshot. The 20030303 name is only an example.
Unpack the source into a directory that has no spaces. The
makefiles included in the source get confused by white space in
directory names.
* Preconfigure Icarus Verilog (Not normally needed)
Under certain cases, you may need to "preconfigure" the Icarus Verilog
source tree. You should only need to do this if you are getting the
Icarus Verilog source tree from git, or you are using an existing
source tree that you've patched to cause configure.in files to change.
NOTE: If you are building from a fresh, bundled source tree that
you downloaded from an FTP site, then SKIP THIS STEP. Go on to
the "Configure Icarus Verilog" step below.
First, remove any autom4te.cache directories that may exist in your
source tree. These can make a mess of autoconf runs. Then, generate
configure scripts with this command:
$ sh autoconf.sh
This script will run the "autoconf" command (part of the msysDTK) to
generate all the necessary "configure" scripts. This will take a few
minutes. This should go smoothly.
* Configure Icarus Verilog
Now we are all set to configure and compile Icarus Verilog. Choose a
destination path where you will want to install the binaries. I chose
on my system the directory "D:\iverilog". This choice is not
permanent, so don't get too much angst over it. Just choose a name
without white space.
Now, configure the source to make the makefiles and configuration
details. Run these commands:
$ CPPFLAGS="-Ic:/gnuwin32/include
$ LDFLAGS="-Lc:/gnuwin32/lib
$ export CPPFLAGS LDFLAGS
$ ./configure --prefix=c:/iverilog
NOTES:
The CPPFLAGS and LDFLAGS variables tell configure where
the gnuwin32 packages are. The configure program will
write these values into the Makefiles, so you only need to
keep these variables long enough for the configure program
to work.
Your PATH variable was set in the previous step.
Use forward slashes as directory characters. All the various
tools prefer the forward slash.
Substitute your chosen directory for the prefix. This will cause the
makefiles to build and the source code to configure. The configure
program will detect that this is a mingw environment and set things up
to build properly.
(For a prefix, use the drive letter notation; the mingw compiled parts
require it, and the Cygwin tools should be able to handle it. You may
need to check or upgrade your Cygwin installation if this causes
problems for you.)
* Compile Icarus Verilog
This, believe it or not, should be the easy part:
$ make
It could take a while. Now is a good time to go get some coffee or
take a tea break.
* Install Icarus Verilog
If the compile ran OK, then next you install Icarus Verilog in the
directory you have chosen. When you are ready, install like this:
$ make install
This is part of what the configure program did for you. The Makefiles
now know to put the files under the D:\iverilog directory (or whatever
directory you chose) and away you go.
You may find that you need to put some of the prerequisite DLLs into
the d:\iverilog\bin directory. These include:
c:\mingw\bin\mingw10.dll
c:\gnuwin32\bin\readline.dll
c:\gnuwin32\bin\history.dll
c:\gnuwin32\bin\bzip2.dll
c:\gnuwin32\bin\zlib.dll
If you already have these in your Windows path (i.e. your system32
directory) then you do not need to copy them into the iverilog
directory. However, prepackaged Icarus Verilog binaries include these
files.
* Running Icarus Verilog
Finally, put the C:\iverilog\bin directory in your Windows path, and
you should be able to run the iverilog and vvp commands to your
heart's content.
Currently, the iverilog.exe uses the path to itself to locate the
libraries and modules associated with itself. In other words, if you
execute the C:\iverilog\bin\iverilog.exe program, it will locate its
subparts in the C:\iverilog directory and subdirectories below
that. This means you can move the Icarus Verilog installation by
simply moving the root directory and all its contents.
The vvp.pdf and iverilog.pdf files document the main commands. View
these with Acrobat reader, or any other viewer capable of displaying
PDF format files.
http://iverilog.wikia.com/wiki/Installation_Guide#Compiling_on_MS_Windows_.28MinGW.29
+6
View File
@@ -43,6 +43,8 @@ NetAssign_::NetAssign_(NetAssign_*n)
: nest_(n), sig_(0), word_(0), base_(0), sel_type_(IVL_SEL_OTHER)
{
more = 0;
signed_ = false;
turn_sig_to_wire_on_release_ = false;
}
NetAssign_::NetAssign_(NetNet*s)
@@ -51,6 +53,7 @@ NetAssign_::NetAssign_(NetNet*s)
lwid_ = sig_->vector_width();
sig_->incr_lref();
more = 0;
signed_ = false;
turn_sig_to_wire_on_release_ = false;
}
@@ -135,6 +138,9 @@ ivl_variable_type_t NetAssign_::expr_type() const
return darray->element_base_type();
}
if (sig_ && sig_->data_type()==IVL_VT_STRING && base_!=0)
return IVL_VT_BOOL;
if (ntype) return ntype->base_type();
ivl_assert(*this, sig_);
+19 -12
View File
@@ -101,11 +101,12 @@ uint64_t Design::scale_to_precision(uint64_t val,
return val;
}
NetScope* Design::make_root_scope(perm_string root, bool program_block)
NetScope* Design::make_root_scope(perm_string root, bool program_block,
bool is_interface)
{
NetScope *root_scope_;
root_scope_ = new NetScope(0, hname_t(root), NetScope::MODULE,
false, program_block);
false, program_block, is_interface);
/* This relies on the fact that the basename return value is
permallocated. */
root_scope_->set_module_name(root_scope_->basename());
@@ -527,6 +528,20 @@ void NetScope::evaluate_parameter_logic_(Design*des, param_ref_t cur)
des->errors += 1;
return;
}
// If the parameter has type or range information, then
// make sure the type is set right. Note that if the
// parameter doesn't have an explicit type or range,
// then it will get the signedness from the expression itself.
if (cur->second.type != IVL_VT_NO_TYPE) {
expr->cast_signed(cur->second.signed_flag);
} else if (cur->second.signed_flag) {
expr->cast_signed(true);
}
if (!range_flag && !expr->has_width()) {
expr = pad_to_width(expr, integer_width, *expr);
}
break;
default:
@@ -536,17 +551,8 @@ void NetScope::evaluate_parameter_logic_(Design*des, param_ref_t cur)
des->errors += 1;
return;
}
(*cur).second.val = expr;
/* If the parameter has type or range information, then make
sure the type is set right. Note that if the parameter
doesn't have an explicit type or range, then it will get
the signedness from the expression itself. */
if ((*cur).second.type != IVL_VT_NO_TYPE) {
(*cur).second.val->cast_signed((*cur).second.signed_flag);
} else if ((*cur).second.signed_flag) {
(*cur).second.val->cast_signed(true);
}
cur->second.val = expr;
// If there are no value ranges to test the value against,
// then we are done.
@@ -841,6 +847,7 @@ NetFuncDef* Design::find_function(NetScope*scope, const pform_name_t&name)
// the function's signals have been elaborated. If this is
// the case, elaborate them now.
if (func->elab_stage() < 2) {
func->need_const_func(true);
const PFunction*pfunc = func->func_pform();
assert(pfunc);
pfunc->elaborate_sig(this, func);
+149 -5
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012-2013 Stephen Williams (steve@icarus.com)
* Copyright (c) 2012-2016 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
@@ -88,6 +88,10 @@ NetExpr* NetFuncDef::evaluate_function(const LineInfo&loc, const std::vector<Net
// fills in the context_map with local variables held by the scope.
scope()->evaluate_function_find_locals(loc, context_map);
// Execute any variable initialization statements.
if (const NetProc*init_proc = scope()->var_init())
init_proc->evaluate_function(loc, context_map);
if (debug_eval_tree && proc_==0) {
cerr << loc.get_fileline() << ": NetFuncDef::evaluate_function: "
<< "Function " << scope_path(scope())
@@ -209,6 +213,98 @@ bool NetProc::evaluate_function(const LineInfo&,
return false;
}
void NetAssign::eval_func_lval_op_real_(const LineInfo&loc,
verireal&lv, verireal&rv) const
{
switch (op_) {
case '+':
lv = lv + rv;
break;
case '-':
lv = lv - rv;
break;
case '*':
lv = lv * rv;
break;
case '/':
lv = lv / rv;
break;
case '%':
lv = lv % rv;
break;
default:
cerr << "Illegal assignment operator: "
<< human_readable_op(op_) << endl;
ivl_assert(loc, 0);
}
}
void NetAssign::eval_func_lval_op_(const LineInfo&loc,
verinum&lv, verinum&rv) const
{
unsigned lv_width = lv.len();
bool lv_sign = lv.has_sign();
switch (op_) {
case 'l':
case 'R':
// The left operand is self-determined.
break;
case 'r':
// The left operand is self-determined, but we need to
// cast it to unsigned to get a logical shift.
lv.has_sign(false);
break;
default:
// The left operand must be cast to the expression type/size
lv.has_sign(rv.has_sign());
lv = cast_to_width(lv, rv.len());
}
switch (op_) {
case '+':
lv = lv + rv;
break;
case '-':
lv = lv - rv;
break;
case '*':
lv = lv * rv;
break;
case '/':
lv = lv / rv;
break;
case '%':
lv = lv % rv;
break;
case '&':
for (unsigned idx = 0 ; idx < lv.len() ; idx += 1)
lv.set(idx, lv[idx] & rv[idx]);
break;
case '|':
for (unsigned idx = 0 ; idx < lv.len() ; idx += 1)
lv.set(idx, lv[idx] | rv[idx]);
break;
case '^':
for (unsigned idx = 0 ; idx < lv.len() ; idx += 1)
lv.set(idx, lv[idx] ^ rv[idx]);
break;
case 'l':
lv = lv << rv.as_unsigned();
break;
case 'r':
lv = lv >> rv.as_unsigned();
break;
case 'R':
lv = lv >> rv.as_unsigned();
break;
default:
cerr << "Illegal assignment operator: "
<< human_readable_op(op_) << endl;
ivl_assert(loc, 0);
}
lv = cast_to_width(lv, lv_width);
lv.has_sign(lv_sign);
}
bool NetAssign::eval_func_lval_(const LineInfo&loc,
map<perm_string,LocalVar>&context_map,
const NetAssign_*lval, NetExpr*rval_result) const
@@ -269,18 +365,55 @@ bool NetAssign::eval_func_lval_(const LineInfo&loc,
ivl_assert(loc, base + lval->lwidth() <= old_lval->expr_width());
NetEConst*lval_const = dynamic_cast<NetEConst*>(old_lval);
ivl_assert(loc, lval_const);
verinum lval_v = lval_const->value();
NetEConst*rval_const = dynamic_cast<NetEConst*>(rval_result);
verinum rval_v = cast_to_width(rval_const->value(), lval->lwidth());
ivl_assert(loc, rval_const);
verinum rval_v = rval_const->value();
for (unsigned idx = 0 ; idx < rval_v.len() ; idx += 1)
lval_v.set(idx+base, rval_v[idx]);
verinum lpart(verinum::Vx, lval->lwidth());
if (op_) {
for (unsigned idx = 0 ; idx < lpart.len() ; idx += 1)
lpart.set(idx, lval_v[base+idx]);
eval_func_lval_op_(loc, lpart, rval_v);
} else {
lpart = cast_to_width(rval_v, lval->lwidth());
}
for (unsigned idx = 0 ; idx < lpart.len() ; idx += 1)
lval_v.set(idx+base, lpart[idx]);
delete base_result;
delete rval_result;
rval_result = new NetEConst(lval_v);
} else {
rval_result = fix_assign_value(lval->sig(), rval_result);
if (op_ == 0) {
rval_result = fix_assign_value(lval->sig(), rval_result);
} else if (dynamic_cast<NetECReal*>(rval_result)) {
NetECReal*lval_const = dynamic_cast<NetECReal*>(old_lval);
ivl_assert(loc, lval_const);
verireal lval_r = lval_const->value();
NetECReal*rval_const = dynamic_cast<NetECReal*>(rval_result);
ivl_assert(loc, rval_const);
verireal rval_r = rval_const->value();
eval_func_lval_op_real_(loc, lval_r, rval_r);
delete rval_result;
rval_result = new NetECReal(lval_r);
} else {
NetEConst*lval_const = dynamic_cast<NetEConst*>(old_lval);
ivl_assert(loc, lval_const);
verinum lval_v = lval_const->value();
NetEConst*rval_const = dynamic_cast<NetEConst*>(rval_result);
ivl_assert(loc, rval_const);
verinum rval_v = rval_const->value();
eval_func_lval_op_(loc, lval_v, rval_v);
delete rval_result;
rval_result = new NetEConst(lval_v);
}
}
if (old_lval)
@@ -318,6 +451,13 @@ bool NetAssign::evaluate_function(const LineInfo&loc,
NetEConst*rval_const = dynamic_cast<NetEConst*>(rval_result);
ivl_assert(*this, rval_const);
if (op_) {
cerr << get_fileline() << ": sorry: Assignment operators "
"inside a constant function are not currently "
"supported if the LHS is a concatenation." << endl;
return false;
}
verinum rval_full = rval_const->value();
delete rval_result;
@@ -369,6 +509,10 @@ bool NetBlock::evaluate_function(const LineInfo&loc,
// Now collect the new locals.
subscope_->evaluate_function_find_locals(loc, local_context_map);
use_local_context_map = true;
// Execute any variable initialization statements.
if (const NetProc*init_proc = subscope_->var_init())
init_proc->evaluate_function(loc, local_context_map);
}
// Now use the local context map if there is any local
+14
View File
@@ -311,6 +311,20 @@ void Nexus::count_io(unsigned&inp, unsigned&out) const
}
}
bool Nexus::has_floating_input() const
{
bool found_input = false;
for (const Link*cur = first_nlink() ; cur ; cur = cur->next_nlink()) {
if (cur->get_dir() == Link::OUTPUT)
return false;
if (cur->get_dir() == Link::INPUT)
found_input = true;
}
return found_input;
}
bool Nexus::drivers_present() const
{
for (const Link*cur = first_nlink() ; cur ; cur = cur->next_nlink()) {
+21 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2013 Stephen Williams (steve@icarus.com)
* Copyright (c) 2002-2016 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
@@ -404,6 +404,17 @@ NexusSet* NetDoWhile::nex_input(bool rem_out)
return result;
}
NexusSet* NetEvWait::nex_input(bool rem_out)
{
NexusSet*result;
if (statement_)
result = statement_->nex_input(rem_out);
else
result = new NexusSet;
return result;
}
NexusSet* NetForce::nex_input(bool)
{
cerr << get_fileline() << ": internal warning: NetForce::nex_input()"
@@ -427,6 +438,15 @@ NexusSet* NetForLoop::nex_input(bool rem_out)
result->add(*tmp);
delete tmp;
if (gn_shared_loop_index_flag) {
tmp = new NexusSet();
for (unsigned idx = 0 ; idx < index_->pin_count() ; idx += 1)
tmp->add(index_->pin(idx).nexus(), 0, index_->vector_width());
result->rem(*tmp);
delete tmp;
}
return result;
}
+11
View File
@@ -56,6 +56,17 @@ void NetBlock::append(NetProc*cur)
}
}
void NetBlock::prepend(NetProc*cur)
{
if (last_ == 0) {
last_ = cur;
cur->next_ = cur;
} else {
cur->next_ = last_->next_;
last_->next_ = cur;
}
}
const NetProc* NetBlock::proc_first() const
{
if (last_ == 0)
+28 -20
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2000-2014 Stephen Williams (steve@icarus.com)
* Copyright (c) 2000-2017 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
@@ -110,8 +110,10 @@ void Definitions::add_class(netclass_t*net_class)
* in question.
*/
NetScope::NetScope(NetScope*up, const hname_t&n, NetScope::TYPE t, bool nest, bool prog)
: type_(t), name_(n), nested_module_(nest), program_block_(prog), up_(up)
NetScope::NetScope(NetScope*up, const hname_t&n, NetScope::TYPE t, bool nest,
bool program, bool interface)
: type_(t), name_(n), nested_module_(nest), program_block_(program),
is_interface_(interface), up_(up)
{
events_ = 0;
lcounter_ = 0;
@@ -137,6 +139,7 @@ NetScope::NetScope(NetScope*up, const hname_t&n, NetScope::TYPE t, bool nest, bo
time_from_timescale_ = false;
}
var_init_ = 0;
switch (t) {
case NetScope::TASK:
task_ = 0;
@@ -262,19 +265,20 @@ bool NetScope::auto_name(const char*prefix, char pad, const char* suffix)
assert(self != up_->children_.end());
assert(self->second == this);
char tmp[32];
int pad_pos = strlen(prefix);
int max_pos = sizeof(tmp) - strlen(suffix) - 1;
strncpy(tmp, prefix, sizeof(tmp));
tmp[31] = 0;
// This is to keep the pad attempts from being stuck in some
// sort of infinite loop. This should not be a practical
// limit, but an extreme one.
const size_t max_pad_attempts = 32 + strlen(prefix);
string use_prefix = prefix;
// Try a variety of potential new names. Make sure the new
// name is not in the parent scope. Keep looking until we are
// sure we have a unique name, or we run out of names to try.
while (pad_pos <= max_pos) {
while (use_prefix.size() <= max_pad_attempts) {
// Try this name...
strcat(tmp + pad_pos, suffix);
hname_t new_name(lex_strings.make(tmp));
string tmp = use_prefix + suffix;
hname_t new_name(lex_strings.make(tmp.c_str()), name_.peek_numbers());
if (!up_->child(new_name)) {
// Ah, this name is unique. Rename myself, and
// change my name in the parent scope.
@@ -283,7 +287,9 @@ bool NetScope::auto_name(const char*prefix, char pad, const char* suffix)
up_->children_[name_] = this;
return true;
}
tmp[pad_pos++] = pad;
// Name collides, so try a different name.
use_prefix = use_prefix + pad;
}
return false;
}
@@ -294,16 +300,16 @@ bool NetScope::auto_name(const char*prefix, char pad, const char* suffix)
*/
bool NetScope::replace_parameter(perm_string key, PExpr*val, NetScope*scope)
{
bool flag = false;
if (parameters.find(key) == parameters.end())
return false;
if (parameters.find(key) != parameters.end()) {
param_expr_t&ref = parameters[key];
ref.val_expr = val;
ref.val_scope = scope;
flag = true;
}
param_expr_t&ref = parameters[key];
if (ref.local_flag)
return false;
return flag;
ref.val_expr = val;
ref.val_scope = scope;
return true;
}
bool NetScope::make_parameter_unannotatable(perm_string key)
@@ -372,6 +378,8 @@ NetScope::param_ref_t NetScope::find_parameter(perm_string key)
// To get here the parameter must already exist, so we should
// never get here.
assert(0);
// But return something to avoid a compiler warning.
return idx;
}
NetScope::TYPE NetScope::type() const
+4 -1
View File
@@ -1,7 +1,7 @@
#ifndef IVL_netdarray_H
#define IVL_netdarray_H
/*
* Copyright (c) 2012-2014 Stephen Williams (steve@icarus.com)
* Copyright (c) 2012-2015 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
@@ -33,6 +33,9 @@ class netdarray_t : public netarray_t {
// IVL_VT_DARRAY for dynamic arrays?
ivl_variable_type_t base_type() const;
// A dynamic array may have a type that is signed.
inline bool get_signed() const { return element_type()->get_signed(); }
// This is the base_type() of the element of the array. We
// need this in some cases in order to get the base type of
// the element, and not the IVL_VT_DARRAY of the array itself.
+17 -6
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998-2013 Stephen Williams (steve@icarus.com)
* Copyright (c) 1998-2015 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
@@ -557,7 +557,7 @@ void NetNet::calculate_slice_widths_from_packed_dims_(void)
ivl_assert(*this, ! slice_wids_.empty());
slice_wids_[0] = netrange_width(slice_dims_);
vector<netrange_t>::const_iterator cur = slice_dims_.begin();
for (size_t idx = 1 ; idx < slice_wids_.size() ; idx += 1) {
for (size_t idx = 1 ; idx < slice_wids_.size() ; idx += 1, cur++) {
slice_wids_[idx] = slice_wids_[idx-1] / cur->width();
}
}
@@ -1153,8 +1153,8 @@ unsigned NetReplicate::repeat() const
* ...
*/
NetFF::NetFF(NetScope*s, perm_string n, unsigned width__)
: NetNode(s, n, 8), width_(width__)
NetFF::NetFF(NetScope*s, perm_string n, bool negedge__, unsigned width__)
: NetNode(s, n, 8), negedge_(negedge__), width_(width__)
{
pin_Clock().set_dir(Link::INPUT);
pin_Enable().set_dir(Link::INPUT);
@@ -1170,6 +1170,11 @@ NetFF::~NetFF()
{
}
bool NetFF::is_negedge() const
{
return negedge_;
}
unsigned NetFF::width() const
{
return width_;
@@ -2738,10 +2743,11 @@ DelayType NetCase::delay_type() const
for (unsigned idx = 0; idx < nstmts; idx += 1) {
if (!expr(idx)) def_stmt = true;
DelayType dt = stat(idx) ? stat(idx)->delay_type() : NO_DELAY;
if (idx == 0) {
result = stat(idx)->delay_type();
result = dt;
} else {
result = combine_delays(result, stat(idx)->delay_type());
result = combine_delays(result, dt);
}
}
@@ -2764,6 +2770,7 @@ DelayType NetCondit::delay_type() const
*/
DelayType NetDoWhile::delay_type() const
{
ivl_assert(*this, proc_);
return proc_->delay_type();
}
@@ -2774,11 +2781,13 @@ DelayType NetEvWait::delay_type() const
DelayType NetForever::delay_type() const
{
ivl_assert(*this, statement_);
return statement_->delay_type();
}
DelayType NetForLoop::delay_type() const
{
ivl_assert(*this, statement_);
return get_loop_delay_type(condition_, statement_);
}
@@ -2801,6 +2810,7 @@ DelayType NetPDelay::delay_type() const
DelayType NetRepeat::delay_type() const
{
ivl_assert(*this, statement_);
return get_loop_delay_type(expr_, statement_);
}
@@ -2816,5 +2826,6 @@ DelayType NetUTask::delay_type() const
DelayType NetWhile::delay_type() const
{
ivl_assert(*this, proc_);
return get_loop_delay_type(cond_, proc_);
}
+60 -14
View File
@@ -1,7 +1,7 @@
#ifndef IVL_netlist_H
#define IVL_netlist_H
/*
* Copyright (c) 1998-2014 Stephen Williams (steve@icarus.com)
* Copyright (c) 1998-2015 Stephen Williams (steve@icarus.com)
* Copyright CERN 2013 / Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
@@ -90,6 +90,12 @@ class netvector_t;
struct target;
struct functor_t;
#if defined(__cplusplus) && defined(_MSC_VER)
# define ENUM_UNSIGNED_INT : unsigned int
#else
# define ENUM_UNSIGNED_INT
#endif
ostream& operator << (ostream&o, ivl_variable_type_t val);
extern void join_island(NetPins*obj);
@@ -102,8 +108,7 @@ class Link {
friend class NexusSet;
public:
enum DIR { PASSIVE, INPUT, OUTPUT };
enum DIR ENUM_UNSIGNED_INT { PASSIVE, INPUT, OUTPUT };
private: // Only NetPins can create/delete Link objects
Link();
~Link();
@@ -383,6 +388,10 @@ class Nexus {
is a variable, but also if this is a net with a force. */
bool assign_lval() const;
/* This method returns true if there are any inputs
attached to this nexus but no drivers. */
bool has_floating_input() const;
/* This method returns true if there are any drivers
(including variables) attached to this nexus. */
bool drivers_present() const;
@@ -619,7 +628,7 @@ class NetDelaySrc : public NetObj {
class PortType
{
public:
enum Enum { NOT_A_PORT, PIMPLICIT, PINPUT, POUTPUT, PINOUT, PREF };
enum Enum ENUM_UNSIGNED_INT { NOT_A_PORT, PIMPLICIT, PINPUT, POUTPUT, PINOUT, PREF };
/*
* Merge Port types (used to construct a sane combined port-type
@@ -647,7 +656,7 @@ struct PortInfo
class NetNet : public NetObj, public PortType {
public:
enum Type { NONE, IMPLICIT, IMPLICIT_REG, INTEGER, WIRE, TRI, TRI1,
enum Type ENUM_UNSIGNED_INT { NONE, IMPLICIT, IMPLICIT_REG, INTEGER, WIRE, TRI, TRI1,
SUPPLY0, SUPPLY1, WAND, TRIAND, TRI0, WOR, TRIOR, REG,
UNRESOLVED_WIRE };
@@ -708,7 +717,7 @@ class NetNet : public NetObj, public PortType {
/* This method returns a reference to the packed dimensions
for the vector. These are arranged as a list where the
first range in the list (front) is the left-most range in
the verilog declaration. These packed dims are compressed
the Verilog declaration. These packed dims are compressed
to represent the dimensions of all the subtypes. */
const std::vector<netrange_t>& packed_dims() const { return slice_dims_; }
@@ -765,7 +774,7 @@ class NetNet : public NetObj, public PortType {
unsigned peek_eref() const;
// Assignment statements count their lrefs here. And by
// asignment statements, we mean BEHAVIORAL assignments.
// assignment statements, we mean BEHAVIORAL assignments.
void incr_lref();
void decr_lref();
unsigned peek_lref() const { return lref_count_; }
@@ -918,7 +927,8 @@ class NetScope : public Definitions, public Attrib {
/* Create a new scope, and attach it to the given parent. The
name is expected to have been permallocated. */
NetScope(NetScope*up, const hname_t&name, TYPE t, bool nest=false, bool prog=false);
NetScope(NetScope*up, const hname_t&name, TYPE t, bool nest=false,
bool program=false, bool interface=false);
~NetScope();
/* Rename the scope using the name generated by inserting as
@@ -1008,11 +1018,19 @@ class NetScope : public Definitions, public Attrib {
// Nested modules have slightly different scope search rules.
inline bool nested_module() const { return nested_module_; }
// Program blocks have elaboration constraints.
// Program blocks and interfaces have elaboration constraints.
inline bool program_block() const { return program_block_; }
inline bool is_interface() const { return is_interface_; }
TYPE type() const;
void print_type(ostream&) const;
// This provides a link to the variable initialisation process
// for use when evaluating a constant function. Note this is
// only used for static functions - the variable initialization
// for automatic functions is included in the function definition.
void set_var_init(const NetProc*proc) { var_init_ = proc; }
const NetProc* var_init() const { return var_init_; }
void set_task_def(NetTaskDef*);
void set_func_def(NetFuncDef*);
void set_class_def(netclass_t*);
@@ -1221,6 +1239,8 @@ class NetScope : public Definitions, public Attrib {
bool nested_module_;
// True if the scope is a program block
bool program_block_;
// True if the scope is an interface
bool is_interface_;
perm_string file_;
perm_string def_file_;
@@ -1241,6 +1261,8 @@ class NetScope : public Definitions, public Attrib {
vector<PortInfo> ports_;
const NetProc*var_init_;
union {
NetTaskDef*task_;
NetFuncDef*func_;
@@ -1618,9 +1640,10 @@ class NetModulo : public NetNode {
class NetFF : public NetNode {
public:
NetFF(NetScope*s, perm_string n, unsigned vector_width);
NetFF(NetScope*s, perm_string n, bool negedge, unsigned vector_width);
~NetFF();
bool is_negedge() const;
unsigned width() const;
Link& pin_Clock();
@@ -1652,6 +1675,7 @@ class NetFF : public NetNode {
virtual void functor_node(Design*des, functor_t*fun);
private:
bool negedge_;
unsigned width_;
verinum aset_value_;
verinum sset_value_;
@@ -2041,7 +2065,7 @@ class NetEConst : public NetExpr {
/* This method allows the constant value to be converted
to an unsized value. This is used after evaluating a
unsized constant expression. */
virtual void trim();
void trim();
virtual void expr_scan(struct expr_scan_t*) const;
virtual void dump(ostream&) const;
@@ -2212,7 +2236,7 @@ class NetPartSelect : public NetNode {
*
* wire [7:0] foo = NetSubstitute(bar, bat, off);
*
* meaus that bar is a vector the same width as foo, bat is a narrower
* means that bar is a vector the same width as foo, bat is a narrower
* vector. The off is a constant offset into the bar vector. This
* looks something like this:
*
@@ -2283,7 +2307,7 @@ class NetBUFZ : public NetNode {
*
* 0 -- Output (always returns 0 or 1)
* 1 -- Input
* 2 -- Input (windcard input for EQX and EQZ variants)
* 2 -- Input (wildcard input for EQX and EQZ variants)
*/
class NetCaseCmp : public NetNode {
@@ -2614,8 +2638,10 @@ class NetProc : public virtual LineInfo {
// picked off by e.g. condit statements as set/reset inputs to
// the flipflop being generated.
virtual bool synth_sync(Design*des, NetScope*scope,
bool&ff_negedge,
NetNet*ff_clock, NetBus&ff_ce,
NetBus&ff_aclr, NetBus&ff_aset,
vector<verinum>&ff_aset_value,
NexusSet&nex_map, NetBus&nex_out,
const std::vector<NetEvProbe*>&events);
@@ -2719,6 +2745,12 @@ class NetAssign_ {
void set_property(const perm_string&name);
inline perm_string get_property(void) const { return member_; }
// Determine if the assigned object is signed or unsigned.
// This is used when determining the expression type for
// a compressed assignment statement.
bool get_signed() const { return signed_; }
void set_signed(bool flag) { signed_ = flag; }
// Get the width of the r-value that this node expects. This
// method accounts for the presence of the mux, so it is not
// necessarily the same as the pin_count().
@@ -2769,6 +2801,7 @@ class NetAssign_ {
// member/property if signal is a class.
perm_string member_;
bool signed_;
bool turn_sig_to_wire_on_release_;
// indexed part select base
NetExpr*base_;
@@ -2836,6 +2869,8 @@ class NetAssign : public NetAssignBase {
map<perm_string,LocalVar>&ctx) const;
private:
void eval_func_lval_op_real_(const LineInfo&loc, verireal&lv, verireal&rv) const;
void eval_func_lval_op_(const LineInfo&loc, verinum&lv, verinum&rv) const;
bool eval_func_lval_(const LineInfo&loc, map<perm_string,LocalVar>&ctx,
const NetAssign_*lval, NetExpr*rval_result) const;
@@ -2882,6 +2917,7 @@ class NetBlock : public NetProc {
NetScope* subscope() const { return subscope_; }
void append(NetProc*);
void prepend(NetProc*);
const NetProc*proc_first() const;
const NetProc*proc_next(const NetProc*cur) const;
@@ -2895,8 +2931,10 @@ class NetBlock : public NetProc {
NetBus&accumulated_nex_out);
bool synth_sync(Design*des, NetScope*scope,
bool&ff_negedge,
NetNet*ff_clk, NetBus&ff_ce,
NetBus&ff_aclr,NetBus&ff_aset,
vector<verinum>&ff_aset_value,
NexusSet&nex_map, NetBus&nex_out,
const std::vector<NetEvProbe*>&events);
@@ -3036,8 +3074,10 @@ class NetCondit : public NetProc {
NetBus&accumulated_nex_out);
bool synth_sync(Design*des, NetScope*scope,
bool&ff_negedge,
NetNet*ff_clk, NetBus&ff_ce,
NetBus&ff_aclr,NetBus&ff_aset,
vector<verinum>&ff_aset_value,
NexusSet&nex_map, NetBus&nex_out,
const std::vector<NetEvProbe*>&events);
@@ -3306,6 +3346,7 @@ class NetEvWait : public NetProc {
// process? This method checks.
virtual bool is_synchronous();
virtual NexusSet* nex_input(bool rem_out = true);
virtual void nex_output(NexusSet&out);
virtual bool synth_async(Design*des, NetScope*scope,
@@ -3313,8 +3354,10 @@ class NetEvWait : public NetProc {
NetBus&accumulated_nex_out);
virtual bool synth_sync(Design*des, NetScope*scope,
bool&ff_negedge,
NetNet*ff_clk, NetBus&ff_ce,
NetBus&ff_aclr,NetBus&ff_aset,
vector<verinum>&ff_aset_value,
NexusSet&nex_map, NetBus&nex_out,
const std::vector<NetEvProbe*>&events);
@@ -4650,6 +4693,7 @@ class NetECast : public NetEUnary {
virtual NetNet* synthesize(Design*, NetScope*scope, NetExpr*root);
virtual NetECast* dup_expr() const;
virtual ivl_variable_type_t expr_type() const;
virtual void dump(ostream&) const;
private:
virtual NetExpr* eval_arguments_(const NetExpr*ex) const;
@@ -4746,7 +4790,8 @@ class Design : public Definitions {
const char* get_flag(const string&key) const;
NetScope* make_root_scope(perm_string name, bool program_block);
NetScope* make_root_scope(perm_string name, bool program_block,
bool is_interface);
NetScope* find_root_scope();
std::list<NetScope*> find_root_scopes() const;
@@ -4989,4 +5034,5 @@ inline unsigned Link::get_pin() const
return pin_;
}
#undef ENUM_UNSIGNED_INT
#endif /* IVL_netlist_H */
+125 -24
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2014 Stephen Williams (steve@icarus.com)
* Copyright (c) 2001-2016 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
@@ -203,7 +203,7 @@ static NetExpr* make_add_expr(NetExpr*expr, long val)
}
verinum val_v (val, expr->expr_width());
val_v.has_sign(true);
val_v.has_sign(expr->has_sign());
NetEConst*val_c = new NetEConst(val_v);
val_c->set_line(*expr);
@@ -236,7 +236,7 @@ static NetExpr* make_add_expr(const LineInfo*loc, NetExpr*expr1, NetExpr*expr2)
static NetExpr* make_sub_expr(long val, NetExpr*expr)
{
verinum val_v (val, expr->expr_width());
val_v.has_sign(true);
val_v.has_sign(expr->has_sign());
NetEConst*val_c = new NetEConst(val_v);
val_c->set_line(*expr);
@@ -248,21 +248,50 @@ static NetExpr* make_sub_expr(long val, NetExpr*expr)
return res;
}
static NetExpr* make_mult_expr(NetExpr*expr, unsigned long val)
/*
* Subtract a signed constant from an existing expression.
*/
static NetExpr* make_sub_expr(NetExpr*expr, long val)
{
verinum val_v (val, expr->expr_width());
val_v.has_sign(true);
val_v.has_sign(expr->has_sign());
NetEConst*val_c = new NetEConst(val_v);
val_c->set_line(*expr);
NetEBMult*res = new NetEBMult('*', expr, val_c, expr->expr_width(),
NetEBAdd*res = new NetEBAdd('-', expr, val_c, expr->expr_width(),
expr->has_sign());
res->set_line(*expr);
return res;
}
/*
* Multiply an existing expression by a signed positive number.
* This does a lossless multiply, so the arguments will need to be
* sized to match the output size.
*/
static NetExpr* make_mult_expr(NetExpr*expr, unsigned long val)
{
const unsigned val_wid = ceil(log2((double)val)) ;
unsigned use_wid = expr->expr_width() + val_wid;
verinum val_v (val, use_wid);
val_v.has_sign(expr->has_sign());
NetEConst*val_c = new NetEConst(val_v);
val_c->set_line(*expr);
// We know by definitions that the expr argument needs to be
// padded to be the right argument width for this lossless multiply.
expr = pad_to_width(expr, use_wid, *expr);
NetEBMult*res = new NetEBMult('*', expr, val_c, use_wid, expr->has_sign());
res->set_line(*expr);
return res;
}
/*
* This routine is used to calculate the number of bits needed to
* contain the given number.
@@ -424,17 +453,41 @@ NetExpr *normalize_variable_slice_base(const list<long>&indices, NetExpr*base,
-- pcur;
}
long sb;
if (pcur->get_msb() >= pcur->get_lsb())
sb = pcur->get_lsb();
else
sb = pcur->get_msb();
long sb = min(pcur->get_lsb(), pcur->get_msb());
long loff;
reg->sb_to_slice(indices, sb, loff, lwid);
base = make_mult_expr(base, lwid);
base = make_add_expr(base, loff);
unsigned min_wid = base->expr_width();
if ((sb < 0) && !base->has_sign()) min_wid += 1;
if (min_wid < num_bits(pcur->get_lsb())) min_wid = pcur->get_lsb();
if (min_wid < num_bits(pcur->get_msb())) min_wid = pcur->get_msb();
base = pad_to_width(base, min_wid, *base);
if ((sb < 0) && !base->has_sign()) {
NetESelect *tmp = new NetESelect(base, 0 , min_wid);
tmp->set_line(*base);
tmp->cast_signed(true);
base = tmp;
}
if (pcur->get_msb() >= pcur->get_lsb()) {
if (pcur->get_lsb() != 0)
base = make_sub_expr(base, pcur->get_lsb());
base = make_mult_expr(base, lwid);
min_wid = base->expr_width();
if (min_wid < num_bits(loff)) min_wid = num_bits(loff);
if (loff != 0) min_wid += 1;
base = pad_to_width(base, min_wid, *base);
base = make_add_expr(base, loff);
} else {
if (pcur->get_msb() != 0)
base = make_sub_expr(base, pcur->get_msb());
base = make_mult_expr(base, lwid);
min_wid = base->expr_width();
if (min_wid < num_bits(loff)) min_wid = num_bits(loff);
if (loff != 0) min_wid += 1;
base = pad_to_width(base, min_wid, *base);
base = make_sub_expr(loff, base);
}
return base;
}
@@ -490,7 +543,7 @@ void indices_to_expressions(Design*des, NetScope*scope,
}
ivl_assert(*loc, cur->msb);
NetExpr*word_index = elab_and_eval(des, scope, cur->msb, -1, need_const);
NetExpr*word_index = elab_and_eval_lossless(des, scope, cur->msb, -2, need_const);
if (word_index == 0)
flags.invalid = true;
@@ -680,7 +733,8 @@ NetExpr* make_canonical_index(Design*des, NetScope*scope,
indices_flags flags;
indices_to_expressions(des, scope, loc,
src, src.size(),
need_const, flags,
need_const,
flags,
indices_expr, indices_const);
if (flags.undefined) {
@@ -790,13 +844,17 @@ NetExpr* condition_reduce(NetExpr*expr)
return cmp;
}
NetExpr* elab_and_eval(Design*des, NetScope*scope, PExpr*pe,
int context_width, bool need_const, bool annotatable,
ivl_variable_type_t cast_type)
static NetExpr* do_elab_and_eval(Design*des, NetScope*scope, PExpr*pe,
int context_width, bool need_const,
bool annotatable, bool force_expand,
ivl_variable_type_t cast_type,
bool force_unsigned)
{
PExpr::width_mode_t mode = PExpr::SIZED;
if ((context_width == -2) && !gn_strict_expr_width_flag)
mode = PExpr::EXPAND;
if (force_expand)
mode = PExpr::EXPAND;
pe->test_width(des, scope, mode);
@@ -810,13 +868,20 @@ NetExpr* elab_and_eval(Design*des, NetScope*scope, PExpr*pe,
if ((pe->expr_type() != IVL_VT_REAL) && (expr_width < pos_context_width))
expr_width = pos_context_width;
// If this is the RHS of a compressed assignment, the LHS also
// affects the expression type (signed/unsigned).
if (force_unsigned)
pe->cast_signed(false);
if (debug_elaborate) {
cerr << pe->get_fileline() << ": elab_and_eval: test_width of "
<< *pe << endl;
cerr << pe->get_fileline() << ": : "
<< "returns type=" << pe->expr_type()
<< ", width=" << expr_width
<< ", context_width=" << context_width
<< ", signed=" << pe->has_sign()
<< ", force_expand=" << force_expand
<< ", expr_width=" << expr_width
<< ", mode=" << PExpr::width_mode_name(mode) << endl;
cerr << pe->get_fileline() << ": : "
<< "cast_type=" << cast_type << endl;
@@ -824,6 +889,7 @@ NetExpr* elab_and_eval(Design*des, NetScope*scope, PExpr*pe,
// If we can get the same result using a smaller expression
// width, do so.
unsigned min_width = pe->min_width();
if ((min_width != UINT_MAX) && (pe->expr_type() != IVL_VT_REAL)
&& (pos_context_width > 0) && (expr_width > pos_context_width)) {
@@ -850,6 +916,11 @@ NetExpr* elab_and_eval(Design*des, NetScope*scope, PExpr*pe,
if (annotatable)
flags |= PExpr::ANNOTATABLE;
if (debug_elaborate) {
cerr << pe->get_fileline() << ": elab_and_eval: "
<< "Calculated width is " << expr_width << "." << endl;
}
NetExpr*tmp = pe->elaborate_expr(des, scope, expr_width, flags);
if (tmp == 0) return 0;
@@ -869,6 +940,13 @@ NetExpr* elab_and_eval(Design*des, NetScope*scope, PExpr*pe,
}
}
// If the context_width sent is is actually the minimum width,
// then raise the context_width to be big enough for the
// lossless expression.
if (force_expand && context_width > 0) {
context_width = max(context_width, (int)expr_width);
}
eval_expr(tmp, context_width);
if (NetEConst*ce = dynamic_cast<NetEConst*>(tmp)) {
@@ -879,6 +957,29 @@ NetExpr* elab_and_eval(Design*des, NetScope*scope, PExpr*pe,
return tmp;
}
NetExpr* elab_and_eval(Design*des, NetScope*scope, PExpr*pe,
int context_width, bool need_const, bool annotatable,
ivl_variable_type_t cast_type, bool force_unsigned)
{
return do_elab_and_eval(des, scope, pe, context_width,
need_const, annotatable, false,
cast_type, force_unsigned);
}
/*
* This variant of elab_and_eval does the expression losslessly, no
* matter what the generation of Verilog. This is in support of
* certain special contexts, notably index expressions.
*/
NetExpr* elab_and_eval_lossless(Design*des, NetScope*scope, PExpr*pe,
int context_width, bool need_const, bool annotatable,
ivl_variable_type_t cast_type)
{
return do_elab_and_eval(des, scope, pe, context_width,
need_const, annotatable, true,
cast_type, false);
}
NetExpr* elab_and_eval(Design*des, NetScope*scope, PExpr*pe,
ivl_type_t lv_net_type, bool need_const)
{
@@ -929,7 +1030,7 @@ NetExpr* elab_sys_task_arg(Design*des, NetScope*scope, perm_string name,
// determine the exact width required to hold the result.
// But leave literal numbers exactly as the user supplied
// them.
if ((mode >= PExpr::LOSSLESS) && !dynamic_cast<PENumber*>(pe))
if ((mode >= PExpr::LOSSLESS) && !dynamic_cast<PENumber*>(pe) && tmp->expr_width()>32)
ce->trim();
}
@@ -1342,8 +1443,8 @@ bool evaluate_index_prefix(Design*des, NetScope*scope,
{
list<index_component_t>::const_iterator icur = indices.begin();
for (size_t idx = 0 ; (idx+1) < indices.size() ; idx += 1, ++icur) {
assert(icur != indices.end());
assert(icur->sel == index_component_t::SEL_BIT);
ivl_assert(*(icur->msb), icur != indices.end());
ivl_assert(*(icur->msb), icur->sel == index_component_t::SEL_BIT);
NetExpr*texpr = elab_and_eval(des, scope, icur->msb, -1, true);
long tmp;
@@ -1354,7 +1455,7 @@ bool evaluate_index_prefix(Design*des, NetScope*scope,
return false;
}
prefix_indices .push_back(tmp);
prefix_indices.push_back(tmp);
delete texpr;
}
+35 -7
View File
@@ -1,7 +1,7 @@
#ifndef IVL_netmisc_H
#define IVL_netmisc_H
/*
* Copyright (c) 1999-2014 Stephen Williams (steve@icarus.com)
* Copyright (c) 1999-2016 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
@@ -60,12 +60,32 @@ inline NetScope* symbol_search(const LineInfo*li,
}
/*
* This function transforms an expression by padding the high bits
* with V0 until the expression has the desired width. This may mean
* not transforming the expression at all, if it is already wide
* enough.
* This function transforms an expression by either zero or sign extending
* the high bits until the expression has the desired width. This may mean
* not transforming the expression at all, if it is already wide enough.
* The extension method and the returned expression type is determined by
* signed_flag.
*/
extern NetExpr*pad_to_width(NetExpr*expr, unsigned wid, const LineInfo&info);
extern NetExpr*pad_to_width(NetExpr*expr, unsigned wid, bool signed_flag,
const LineInfo&info);
/*
* This version determines the extension method from the base expression type.
*/
inline NetExpr*pad_to_width(NetExpr*expr, unsigned wid, const LineInfo&info)
{
return pad_to_width(expr, wid, expr->has_sign(), info);
}
/*
* This function transforms an expression by either zero or sign extending
* or discarding the high bits until the expression has the desired width.
* This may mean not transforming the expression at all, if it is already
* the correct width. The extension method (if needed) and the returned
* expression type is determined by signed_flag.
*/
extern NetExpr*cast_to_width(NetExpr*expr, unsigned wid, bool signed_flag,
const LineInfo&info);
extern NetNet*pad_to_width(Design*des, NetNet*n, unsigned w,
const LineInfo&info);
@@ -255,6 +275,13 @@ extern unsigned count_lval_width(const class NetAssign_*first);
class PExpr;
extern NetExpr* elab_and_eval(Design*des, NetScope*scope,
PExpr*pe, int context_width,
bool need_const =false,
bool annotatable =false,
ivl_variable_type_t cast_type =IVL_VT_NO_TYPE,
bool force_unsigned =false);
extern NetExpr* elab_and_eval_lossless(Design*des, NetScope*scope,
PExpr*pe, int context_width,
bool need_const =false,
bool annotatable =false,
@@ -291,7 +318,8 @@ extern NetExpr* elaborate_rval_expr(Design*des, NetScope*scope,
ivl_type_t lv_net_type,
ivl_variable_type_t lv_type,
unsigned lv_width, PExpr*expr,
bool need_const =false);
bool need_const =false,
bool force_unsigned =false);
extern bool evaluate_ranges(Design*des, NetScope*scope,
std::vector<netrange_t>&llist,
+6
View File
@@ -34,6 +34,12 @@ netparray_t::~netparray_t()
* The packed width of a packed array is the packed width of the
* element times the dimension width of the array itself.
*/
bool netparray_t::packed(void) const
{
return true;
}
long netparray_t::packed_width(void) const
{
long cur_width = element_type()->packed_width();
+1
View File
@@ -64,6 +64,7 @@ class netparray_t : public netsarray_t {
public:
// Virtual methods from the ivl_type_s type...
bool packed(void) const;
long packed_width(void) const;
std::vector<netrange_t> slice_dimensions() const;
+4 -1
View File
@@ -1,7 +1,7 @@
#ifndef IVL__netqueue_H
#define IVL__netqueue_H
/*
* Copyright (c) 2014 Stephen Williams (steve@icarus.com)
* Copyright (c) 2014-2015 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
@@ -38,6 +38,9 @@ class netqueue_t : public netdarray_t {
// IVL_VT_QUEUE for queues.
ivl_variable_type_t base_type() const;
// A queue may have a type that is signed.
inline bool get_signed() const { return element_type()->get_signed(); }
std::ostream& debug_dump(std::ostream&) const;
private:
+3 -4
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012-2013 Stephen Williams (steve@icarus.com)
* Copyright (c) 2012-2016 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
@@ -141,19 +141,18 @@ bool prefix_to_slice(const std::vector<netrange_t>&dims,
// Now similarly go through the prefix numbers, working
// through the dimensions until we run out. Accumulate a
// growing slice width (acc_wid) that is used to caculate the
// growing slice width (acc_wid) that is used to calculate the
// growing offset (acc_off).
list<long>::const_iterator icur = prefix.end();
do {
-- icur;
acc_wid *= pcur->width();
-- pcur;
if (pcur->get_msb() >= pcur->get_lsb())
acc_off += (*icur - pcur->get_lsb()) * acc_wid;
else
acc_off += (pcur->get_lsb() - *icur) * acc_wid;
-- pcur;
} while (icur != prefix.begin());
// Got our final offset.
+1 -1
View File
@@ -94,7 +94,7 @@ class netrange_t {
inline netrange_t() : msb_(LONG_MAX), lsb_(LONG_MAX) { }
// Create a properly defined netrange
inline netrange_t(long m, long l) : msb_(m), lsb_(l) { }
// Copy constructure.
// Copy constructor.
inline netrange_t(const netrange_t&that)
: msb_(that.msb_), lsb_(that.lsb_) { }
+32 -11
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1999-2011 Stephen Williams (steve@icarus.com)
* Copyright (c) 1999-2016 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,21 +24,20 @@
# include "netmisc.h"
/*
* This function transforms an expression by padding the high bits
* with V0 until the expression has the desired width. This may mean
* not transforming the expression at all, if it is already wide
* enough.
*/
NetExpr*pad_to_width(NetExpr*expr, unsigned wid, const LineInfo&info)
NetExpr*pad_to_width(NetExpr*expr, unsigned wid, bool signed_flag,
const LineInfo&info)
{
if (wid <= expr->expr_width())
if (wid <= expr->expr_width()) {
expr->cast_signed(signed_flag);
return expr;
}
/* If the expression is a const, then replace it with a wider
const. This is a more efficient result. */
if (NetEConst*tmp = dynamic_cast<NetEConst*>(expr)) {
verinum oval = pad_to_width(tmp->value(), wid);
verinum oval = tmp->value();
oval.has_sign(signed_flag);
oval = pad_to_width(oval, wid);
tmp = new NetEConst(oval);
tmp->set_line(info);
delete expr;
@@ -46,8 +45,30 @@ NetExpr*pad_to_width(NetExpr*expr, unsigned wid, const LineInfo&info)
}
NetESelect*tmp = new NetESelect(expr, 0, wid);
tmp->cast_signed(signed_flag);
tmp->set_line(info);
tmp->cast_signed(expr->has_sign());
return tmp;
}
NetExpr*cast_to_width(NetExpr*expr, unsigned wid, bool signed_flag,
const LineInfo&info)
{
/* If the expression is a const, then replace it with a new
const. This is a more efficient result. */
if (NetEConst*tmp = dynamic_cast<NetEConst*>(expr)) {
tmp->cast_signed(signed_flag);
if (wid != tmp->expr_width()) {
tmp = new NetEConst(verinum(tmp->value(), wid));
tmp->set_line(info);
delete expr;
}
return tmp;
}
NetESelect*tmp = new NetESelect(expr, 0, wid);
tmp->cast_signed(signed_flag);
tmp->set_line(info);
return tmp;
}
+578 -217
View File
File diff suppressed because it is too large Load Diff
+538 -186
View File
File diff suppressed because it is too large Load Diff
+55 -22
View File
@@ -1,7 +1,7 @@
#ifndef IVL_pform_H
#define IVL_pform_H
/*
* Copyright (c) 1998-2014 Stephen Williams (steve@icarus.com)
* Copyright (c) 1998-2016 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
@@ -136,6 +136,10 @@ extern void pform_set_default_nettype(NetNet::Type net,
used to reject statements that cannot exist in program blocks. */
extern bool pform_in_program_block(void);
/* Return true if currently processing an interface. This can be
used to reject statements that cannot exist in interfaces. */
extern bool pform_in_interface(void);
/*
* Look for the given wire in the current lexical scope. If the wire
* (including variables of any type) cannot be found in the current
@@ -152,23 +156,33 @@ extern PWire* pform_get_make_wire_in_scope(perm_string name, NetNet::Type net_ty
* are to apply to the scope of that module. The endmodule causes the
* pform to close up and finish the named module.
*
* The program_flag indicates that the module is actually a program
* block. This has implications during parse and during
* The program_block flag indicates that the module is actually a program
* block. The is_interface flag indicates that the module is actually
* an interface. These flags have implications during parse and during
* elaboration/code generation.
*/
extern void pform_startmodule(const struct vlltype&loc, const char*name,
bool program_block, list<named_pexpr_t>*attr);
bool program_block, bool is_interface,
LexicalScope::lifetime_t lifetime,
list<named_pexpr_t>*attr);
extern void pform_check_timeunit_prec();
extern void pform_module_set_ports(vector<Module::port_t*>*);
/* This function is used to support the port definition in a
port_definition_list. In this case, we have everything needed to
define the port, all in one place. */
/* These functions are used when we have a complete port definition, either
in an ansi style or non-ansi style declaration. In this case, we have
everything needed to define the port, all in one place. */
extern void pform_module_define_port(const struct vlltype&li,
perm_string name,
NetNet::PortType,
NetNet::Type type,
data_type_t*vtype,
list<named_pexpr_t>*attr,
bool keep_attr =false);
extern void pform_module_define_port(const struct vlltype&li,
list<pform_port_t>*ports,
NetNet::PortType,
NetNet::Type type,
data_type_t*vtype,
list<named_pexpr_t>*attr);
extern Module::port_t* pform_module_port_reference(perm_string name,
@@ -180,7 +194,8 @@ extern void pform_endmodule(const char*, bool inside_celldefine,
extern void pform_start_class_declaration(const struct vlltype&loc,
class_type_t*type,
data_type_t*base_type,
std::list<PExpr*>*base_exprs);
std::list<PExpr*>*base_exprs,
LexicalScope::lifetime_t lifetime);
extern void pform_class_property(const struct vlltype&loc,
property_qualifier_t pq,
data_type_t*data_type,
@@ -205,7 +220,8 @@ extern void pform_make_udp(perm_string name,
* Package related functions.
*/
extern void pform_start_package_declaration(const struct vlltype&loc,
const char*type);
const char*type,
LexicalScope::lifetime_t lifetime);
extern void pform_end_package_declaration(const struct vlltype&loc);
extern void pform_package_import(const struct vlltype&loc,
PPackage*pkg, const char*ident);
@@ -213,6 +229,15 @@ extern void pform_package_import(const struct vlltype&loc,
extern PExpr* pform_package_ident(const struct vlltype&loc,
PPackage*pkg, pform_name_t*ident);
/*
* Interface related functions.
*/
extern void pform_start_modport_item(const struct vlltype&loc, const char*name);
extern void pform_end_modport_item(const struct vlltype&loc);
extern void pform_add_modport_port(const struct vlltype&loc,
NetNet::PortType port_type,
perm_string name, PExpr*expr);
/*
* This creates an identifier aware of names that may have been
* imported from other packages.
@@ -231,13 +256,20 @@ extern void pform_pop_scope();
*/
extern LexicalScope* pform_peek_scope();
extern PClass* pform_push_class_scope(const struct vlltype&loc, perm_string name);
extern PClass* pform_push_class_scope(const struct vlltype&loc, perm_string name,
LexicalScope::lifetime_t lifetime);
extern PFunction*pform_push_constructor_scope(const struct vlltype&loc);
extern PPackage* pform_push_package_scope(const struct vlltype&loc, perm_string name);
extern PPackage* pform_push_package_scope(const struct vlltype&loc, perm_string name,
LexicalScope::lifetime_t lifetime);
extern PTask*pform_push_task_scope(const struct vlltype&loc, char*name,
bool is_auto);
LexicalScope::lifetime_t lifetime);
extern PFunction*pform_push_function_scope(const struct vlltype&loc, const char*name,
bool is_auto);
LexicalScope::lifetime_t lifetime);
extern PBlock*pform_push_block_scope(char*name, PBlock::BL_TYPE tt);
extern void pform_put_behavior_in_scope(AProcess*proc);
@@ -272,7 +304,8 @@ extern void pform_endgenerate();
*/
extern PGenerate* pform_parent_generate(void);
extern void pform_set_typedef(perm_string name, data_type_t*data_type);
extern void pform_set_typedef(perm_string name, data_type_t*data_type,
std::list<pform_range_t>*unp_ranges);
/*
* This function makes a PECallFunction of the named function. Decide
@@ -335,17 +368,17 @@ extern void pform_makewire(const struct vlltype&li,
list<perm_string>*names,
list<named_pexpr_t>*attr);
extern void pform_make_reginit(const struct vlltype&li,
perm_string name, PExpr*expr);
extern void pform_make_var_init(const struct vlltype&li,
perm_string name, PExpr*expr);
/* Look up the names of the wires, and set the port type,
i.e. input, output or inout. If the wire does not exist, create
it. The second form takes a single name. */
/* This function is used when we have an incomplete port definition in
a non-ansi style declaration. Look up the names of the wires, and set
the port type, i.e. input, output or inout, and, if specified, the
range and signedness. If the wire does not exist, create it. */
extern void pform_set_port_type(const struct vlltype&li,
list<perm_string>*names,
list<pform_range_t>*range,
bool signed_flag,
list<pform_port_t>*ports,
NetNet::PortType,
data_type_t*dt,
list<named_pexpr_t>*attr);
extern void pform_set_reg_idx(perm_string name,
+51 -10
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998-2014 Stephen Williams (steve@icarus.com)
* Copyright (c) 1998-2016 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
@@ -318,7 +318,7 @@ void PECallFunction::dump(ostream &out) const
void PECastSize::dump(ostream &out) const
{
out << size_ << "'(";
out << *size_ << "'(";
base_->dump(out);
out << ")";
}
@@ -789,6 +789,8 @@ void PBlock::dump(ostream&out, unsigned ind) const
dump_events_(out, ind+2);
dump_wires_(out, ind+2);
dump_var_inits_(out, ind+2);
}
for (unsigned idx = 0 ; idx < list_.size() ; idx += 1) {
@@ -926,7 +928,10 @@ void PDisable::dump(ostream&out, unsigned ind) const
void PDoWhile::dump(ostream&out, unsigned ind) const
{
out << setw(ind) << "" << "do" << endl;
statement_->dump(out, ind+3);
if (statement_)
statement_->dump(out, ind+3);
else
out << setw(ind+3) << "" << "/* NOOP */" << endl;
out << setw(ind) << "" << "while (" << *cond_ << ");" << endl;
}
@@ -989,13 +994,19 @@ void PForeach::dump(ostream&fd, unsigned ind) const
}
fd << "] /* " << get_fileline() << " */" << endl;
statement_->dump(fd, ind+3);
if (statement_)
statement_->dump(fd, ind+3);
else
fd << setw(ind+3) << "" << "/* NOOP */" << endl;
}
void PForever::dump(ostream&out, unsigned ind) const
{
out << setw(ind) << "" << "forever /* " << get_fileline() << " */" << endl;
statement_->dump(out, ind+3);
if (statement_)
statement_->dump(out, ind+3);
else
out << setw(ind+3) << "" << "/* NOOP */" << endl;
}
void PForStatement::dump(ostream&out, unsigned ind) const
@@ -1003,7 +1014,10 @@ void PForStatement::dump(ostream&out, unsigned ind) const
out << setw(ind) << "" << "for (" << *name1_ << " = " << *expr1_
<< "; " << *cond_ << "; <for_step>)" << endl;
step_->dump(out, ind+6);
statement_->dump(out, ind+3);
if (statement_)
statement_->dump(out, ind+3);
else
out << setw(ind+3) << "" << "/* NOOP */" << endl;
}
void PFunction::dump(ostream&out, unsigned ind) const
@@ -1030,6 +1044,8 @@ void PFunction::dump(ostream&out, unsigned ind) const
dump_wires_(out, ind+2);
dump_var_inits_(out, ind+2);
if (statement_)
statement_->dump(out, ind+2);
else
@@ -1045,7 +1061,10 @@ void PRelease::dump(ostream&out, unsigned ind) const
void PRepeat::dump(ostream&out, unsigned ind) const
{
out << setw(ind) << "" << "repeat (" << *expr_ << ")" << endl;
statement_->dump(out, ind+3);
if (statement_)
statement_->dump(out, ind+3);
else
out << setw(ind+3) << "" << "/* NOOP */" << endl;
}
void PReturn::dump(ostream&fd, unsigned ind) const
@@ -1072,6 +1091,8 @@ void PTask::dump(ostream&out, unsigned ind) const
dump_wires_(out, ind+2);
dump_var_inits_(out, ind+2);
if (statement_)
statement_->dump(out, ind+2);
else
@@ -1126,7 +1147,10 @@ void PTrigger::dump(ostream&out, unsigned ind) const
void PWhile::dump(ostream&out, unsigned ind) const
{
out << setw(ind) << "" << "while (" << *cond_ << ")" << endl;
statement_->dump(out, ind+3);
if (statement_)
statement_->dump(out, ind+3);
else
out << setw(ind+3) << "" << "/* NOOP */" << endl;
}
void PProcess::dump(ostream&out, unsigned ind) const
@@ -1136,7 +1160,10 @@ void PProcess::dump(ostream&out, unsigned ind) const
dump_attributes_map(out, attributes, ind+2);
statement_->dump(out, ind+2);
if (statement_)
statement_->dump(out, ind+2);
else
out << setw(ind+2) << "" << "/* NOOP */" << endl;
}
void AProcess::dump(ostream&out, unsigned ind) const
@@ -1157,7 +1184,10 @@ void AProcess::dump(ostream&out, unsigned ind) const
dump_attributes_map(out, attributes, ind+2);
statement_->dump(out, ind+2);
if (statement_)
statement_->dump(out, ind+2);
else
out << setw(ind+2) << "" << "/* NOOP */" << endl;
}
void PSpecPath::dump(std::ostream&out, unsigned ind) const
@@ -1269,6 +1299,8 @@ void PGenerate::dump(ostream&out, unsigned indent) const
(*idx)->dump(out, indent+2);
}
dump_var_inits_(out, indent+2);
for (list<PProcess*>::const_iterator idx = behaviors.begin()
; idx != behaviors.end() ; ++ idx ) {
(*idx)->dump(out, indent+2);
@@ -1408,6 +1440,14 @@ void LexicalScope::dump_wires_(ostream&out, unsigned indent) const
}
}
void LexicalScope::dump_var_inits_(ostream&out, unsigned indent) const
{
// Iterate through and display all the register initializations.
for (unsigned idx = 0; idx < var_inits.size(); idx += 1) {
var_inits[idx]->dump(out, indent);
}
}
void PScopeExtra::dump_classes_(ostream&out, unsigned indent) const
{
// Dump the task definitions.
@@ -1564,6 +1604,7 @@ void Module::dump(ostream&out) const
(*gate)->dump(out);
}
dump_var_inits_(out, 4);
for (list<PProcess*>::const_iterator behav = behaviors.begin()
; behav != behaviors.end() ; ++ behav ) {
+4 -3
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012 Stephen Williams (steve@icarus.com)
* Copyright (c) 2012-2016 Stephen Williams (steve@icarus.com)
* Copyright CERN 2013 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
@@ -35,12 +35,13 @@ map<perm_string,PPackage*> pform_packages;
static PPackage*pform_cur_package = 0;
void pform_start_package_declaration(const struct vlltype&loc, const char*name)
void pform_start_package_declaration(const struct vlltype&loc, const char*name,
LexicalScope::lifetime_t lifetime)
{
ivl_assert(loc, pform_cur_package == 0);
perm_string use_name = lex_strings.make(name);
PPackage*pkg_scope = pform_push_package_scope(loc, use_name);
PPackage*pkg_scope = pform_push_package_scope(loc, use_name, lifetime);
FILE_NAME(pkg_scope, loc);
pform_cur_package = pkg_scope;
}
+10 -5
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012-2014 Stephen Williams (steve@icarus.com)
* Copyright (c) 2012-2016 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
@@ -36,9 +36,13 @@ static PClass*pform_cur_class = 0;
* if present, are the "exprs" that would be passed to a chained
* constructor.
*/
void pform_start_class_declaration(const struct vlltype&loc, class_type_t*type, data_type_t*base_type, list<PExpr*>*base_exprs)
void pform_start_class_declaration(const struct vlltype&loc,
class_type_t*type,
data_type_t*base_type,
list<PExpr*>*base_exprs,
LexicalScope::lifetime_t lifetime)
{
PClass*class_scope = pform_push_class_scope(loc, type->name);
PClass*class_scope = pform_push_class_scope(loc, type->name, lifetime);
class_scope->type = type;
assert(pform_cur_class == 0);
pform_cur_class = class_scope;
@@ -75,6 +79,7 @@ void pform_class_property(const struct vlltype&loc,
if (! curp->index.empty()) {
list<pform_range_t>*pd = new list<pform_range_t> (curp->index);
use_type = new uarray_type_t(use_type, pd);
FILE_NAME(use_type, loc);
}
pform_cur_class->type->properties[curp->name]
@@ -127,7 +132,7 @@ void pform_set_constructor_return(PFunction*net)
PFunction*pform_push_constructor_scope(const struct vlltype&loc)
{
assert(pform_cur_class);
PFunction*func = pform_push_function_scope(loc, "new", true);
PFunction*func = pform_push_function_scope(loc, "new", LexicalScope::AUTOMATIC);
return func;
}
@@ -138,7 +143,7 @@ void pform_end_class_declaration(const struct vlltype&loc)
// If there were initializer statements, then collect them
// into an implicit constructor function.
if (! pform_cur_class->type->initialize.empty()) {
PFunction*func = pform_push_function_scope(loc, "new@", true);
PFunction*func = pform_push_function_scope(loc, "new@", LexicalScope::AUTOMATIC);
func->set_ports(0);
pform_set_constructor_return(func);
pform_set_this_class(loc, func);
+2 -2
View File
@@ -79,8 +79,8 @@ static void pform_set_struct_type(struct_type_t*struct_type, perm_string name, N
return;
}
// For now, can only handle packed structs.
ivl_assert(*struct_type, 0);
// For now, can only handle packed structs. The parser generates
// a "sorry" message, so no need to do anything here.
}
void pform_set_struct_type(struct_type_t*struct_type, list<perm_string>*names, NetNet::Type net_type, list<named_pexpr_t>*attr)
+17 -2
View File
@@ -1,7 +1,7 @@
#ifndef IVL_pform_types_H
#define IVL_pform_types_H
/*
* Copyright (c) 2007-2014 Stephen Williams (steve@icarus.com)
* Copyright (c) 2007-2016 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
@@ -50,7 +50,7 @@ typedef named<verinum> named_number_t;
typedef named<PExpr*> named_pexpr_t;
/*
* The pform_range_t holds variable diimensions for type
* The pform_range_t holds variable dimensions for type
* declarations. The two expressions are interpreted as the first and
* last values of the range. For example:
*
@@ -72,6 +72,21 @@ typedef named<PExpr*> named_pexpr_t;
*/
typedef std::pair<PExpr*,PExpr*> pform_range_t;
/*
* The pform_port_t holds the name and optional unpacked dimensions
* and initialization expression for a single port in a list of port
* declarations.
*/
struct pform_port_t {
pform_port_t(perm_string n, list<pform_range_t>*ud, PExpr*e)
: name(n), udims(ud), expr(e) { }
~pform_port_t() { }
perm_string name;
list<pform_range_t>*udims;
PExpr*expr;
};
/*
* Semantic NOTES:
* - The SEL_BIT is a single expression. This might me a bit select
+11 -7
View File
@@ -4,22 +4,26 @@
# the number for a snapshot and the path to a temporary directory.
# for example:
#
# sh scripts/MAKE_RELEASE.sh 0.9.1 ~/tmp
# sh scripts/MAKE_RELEASE.sh 10.1 ~/tmp
#
# The above assumes that there is a tag "v0_9_1" at the point
# The above assumes that there is a tag "v10_1" at the point
# to be released. (The tag has the "v", but the argument to this
# script does not have the "v"). This script extracts based on the
# tag, uses the temporary directory to stage intermediate results,
# and finally creates a file called verilog-0.9.1.tar.gz that
# and finally creates a file called verilog-10.1.tar.gz that
# contains the release ready to go.
#
# The complete steps to make a release x.y.z generally are:
# The complete steps to make a release x.y generally are:
#
# git tag -a v0_9_1
# Edit version_base.h to suit.
#
# Edit verilog.spec to suit.
#
# git tag -a v10_1
# (Make the tag in the local git repository.)
#
# sh scripts/MAKE_RELEASE.sh 0.9.1 ~/tmp
# (Make the snapshot bundle verilog-0.9.1.tar.gz)
# sh scripts/MAKE_RELEASE.sh 10.1 ~/tmp
# (Make the snapshot bundle verilog-10.1.tar.gz)
#
# git push --tags
# (Publish the tag to the repository.)
+1 -1
View File
@@ -15,7 +15,7 @@ iwidth:32
sys_func:vpi/system.sft
sys_func:vpi/v2005_math.sft
sys_func:vpi/va_math.sft
warnings:ailnpstv
warnings:adfilnpstv
debug:eval_tree
debug:elaborate
debug:emit
+1 -1
View File
@@ -9,6 +9,6 @@
#
# NOTE: DO NOT INSTALL THIS FILE.
./ivl -v -Ctgt-stub/stub.conf -C./scripts/devel-stub.conf -Pa.pf -Na.net -fDLL=tgt-stub/stub.tgt foo.vl |& tee foo.log
./ivl -v -Ctgt-stub/stub.conf -C./scripts/devel-stub.conf -Pa.pf -Na.net -fDLL=tgt-stub/stub.tgt foo.vl | tee foo.log 2>&1
echo "*** ivl command completed"
+1 -1
View File
@@ -88,7 +88,7 @@ static bool symbol_search(const LineInfo*li, Design*des, NetScope*scope,
return false;
// The prefix is found to be a scope, so switch to that
// scope, set the hier_path to turn of upwards searches,
// scope, set the hier_path to turn off upwards searches,
// and continue our search for the tail.
if (recurse.is_scope()) {
scope = recurse.scope;
+3 -7
View File
@@ -1,7 +1,7 @@
%{
/*
* Copyright (c) 2000-2014 Stephen Williams ([email protected])
* Copyright (c) 2000-2015 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
@@ -121,11 +121,6 @@ static void hookup_DFF_CE(NetFF*ff, NetESignal*d, NetEvProbe*pclk,
connect(ff->pin_Clock(), pclk->pin(0));
if (ce) connect(ff->pin_Enable(), ce->pin(0));
ff->attribute(perm_string::literal("LPM_FFType"), verinum("DFF"));
if (pclk->edge() == NetEvProbe::NEGEDGE)
ff->attribute(perm_string::literal("Clock:LPM_Polarity"), verinum("INVERT"));
/* This lval_ represents a reg that is a WIRE in the
synthesized results. This function signals the destructor
to change the REG that this l-value refers to into a
@@ -165,7 +160,8 @@ static void make_DFF_CE(Design*des, NetProcTop*top,
if (a->sig()) {
// cerr << "new NetFF named " << a->name() << endl;
NetFF*ff = new NetFF(top->scope(), a->name(),
bool negedge = pclk->edge() == NetEvProbe::NEGEDGE;
NetFF*ff = new NetFF(top->scope(), a->name(), negedge,
a->sig()->vector_width());
hookup_DFF_CE(ff, d, pclk, ce, a, rval_pinoffset);
des->add_node(ff);
+257 -60
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2014 Stephen Williams (steve@icarus.com)
* Copyright (c) 2002-2016 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -34,8 +34,10 @@ bool NetProc::synth_async(Design*, NetScope*, NexusSet&, NetBus&, NetBus&)
}
bool NetProc::synth_sync(Design*des, NetScope*scope,
bool& /* ff_negedge */,
NetNet* /* ff_clk */, NetBus& /* ff_ce */,
NetBus& /* ff_aclr*/, NetBus& /* ff_aset*/,
vector<verinum>& /*ff_aset_value*/,
NexusSet&nex_map, NetBus&nex_out,
const vector<NetEvProbe*>&events)
{
@@ -70,9 +72,45 @@ bool NetAssignBase::synth_async(Design*des, NetScope*scope,
NexusSet&nex_map, NetBus&nex_out,
NetBus&accumulated_nex_out)
{
/* If the lval is a concatenation, synthesise each part
separately. */
if (lval_->more ) {
/* Temporarily set the lval_ and rval_ fields for each
part in turn and recurse. Restore them when done. */
NetAssign_*full_lval = lval_;
NetExpr*full_rval = rval_;
unsigned offset = 0;
bool flag = true;
while (lval_) {
unsigned width = lval_->lwidth();
NetEConst*base = new NetEConst(verinum(offset));
base->set_line(*this);
rval_ = new NetESelect(full_rval->dup_expr(), base, width);
rval_->set_line(*this);
eval_expr(rval_, width);
NetAssign_*more = lval_->more;
lval_->more = 0;
if (!synth_async(des, scope, nex_map, nex_out, accumulated_nex_out))
flag = false;
lval_ = lval_->more = more;
offset += width;
}
lval_ = full_lval;
rval_ = full_rval;
return flag;
}
NetNet*rsig = rval_->synthesize(des, scope, rval_);
assert(rsig);
if (lval_->word() && ! dynamic_cast<NetEConst*>(lval_->word())) {
cerr << get_fileline() << ": sorry: assignment to variable "
"location in memory is not currently supported in "
"synthesis." << endl;
des->errors += 1;
return false;
}
NetNet*lsig = lval_->sig();
if (!lsig) {
cerr << get_fileline() << ": error: "
@@ -82,15 +120,6 @@ bool NetAssignBase::synth_async(Design*des, NetScope*scope,
des->errors += 1;
return false;
}
if (lval_->more) {
cerr << get_fileline() << ": sorry: "
<< "NetAssignBase::synth_async does not support an "
<< "L-value concatenation ";
dump_lval(cerr);
cerr << endl;
des->errors += 1;
return false;
}
if (debug_synth2) {
cerr << get_fileline() << ": NetAssignBase::synth_async: "
@@ -136,6 +165,7 @@ bool NetAssignBase::synth_async(Design*des, NetScope*scope,
NetNet*tmp = new NetNet(scope, scope->local_symbol(),
NetNet::WIRE, NetNet::not_an_array, tmp_type);
tmp->local_flag(true);
tmp->set_line(*this);
NetPartSelect*ps = new NetPartSelect(tmp, base_off, lval_->lwidth(), NetPartSelect::PV);
ps->set_line(*this);
@@ -166,7 +196,8 @@ bool NetAssignBase::synth_async(Design*des, NetScope*scope,
NetNet*tmp = new NetNet(scope, scope->local_symbol(),
NetNet::WIRE, NetNet::not_an_array, tmp_type);
//tmp->local_flag(true);
tmp->local_flag(true);
tmp->set_line(*this);
ivl_assert(*this, accumulated_nex_out.pin_count()==1);
NetNet*use_lsig = lsig;
@@ -185,7 +216,6 @@ bool NetAssignBase::synth_async(Design*des, NetScope*scope,
<< " Found no use_sig, resorting to lsig." << endl;
}
}
NetSubstitute*ps = new NetSubstitute(use_lsig, rsig,
tmp->vector_width(),
base_off);
@@ -196,6 +226,8 @@ bool NetAssignBase::synth_async(Design*des, NetScope*scope,
rsig = tmp;
}
rsig = crop_to_width(des, rsig, lsig->vector_width());
if (nex_out.pin_count() > 1) {
NexusSet tmp_set;
nex_output(tmp_set);
@@ -338,6 +370,103 @@ bool NetBlock::synth_async(Design*des, NetScope*scope,
return flag;
}
/*
* This function is used to fix up a MUX selector to be no longer than
* it needs to be. The general idea is that if the selector needs to
* be only N bits, but is actually M bits, we translate it to this:
*
* osig = { |esig[M-1:N-1], esig[N-2:0] }
*
* This obviously implies that (N >= 2) and (M >= N). In the code
* below, N is sel_need, and M is sel_got (= esig->vector_width()).
*/
static NetNet* mux_selector_reduce_width(Design*des, NetScope*scope,
const LineInfo&loc,
NetNet*esig, unsigned sel_need)
{
const unsigned sel_got = esig->vector_width();
ivl_assert(*esig, sel_got >= sel_need);
// If the actual width matches the desired width (M==N) then
// osig is esig itself. We're done.
if (sel_got == sel_need)
return esig;
if (debug_synth2) {
cerr << loc.get_fileline() << ": mux_selector_reduce_width: "
<< "Reduce selector width=" << sel_got
<< " to " << sel_need << " bits." << endl;
}
ivl_assert(*esig, sel_need >= 2);
// This is the output signal, osig.
ivl_variable_type_t osig_data_type = IVL_VT_LOGIC;
netvector_t*osig_vec = new netvector_t(osig_data_type, sel_need-1, 0);
NetNet*osig = new NetNet(scope, scope->local_symbol(),
NetNet::TRI, osig_vec);
osig->local_flag(true);
osig->set_line(loc);
// Create the concat: osig = {...,...}
NetConcat*osig_cat = new NetConcat(scope, scope->local_symbol(),
sel_need, 2, true);
osig_cat->set_line(loc);
des->add_node(osig_cat);
connect(osig_cat->pin(0), osig->pin(0));
// Create the part select esig[N-2:0]...
NetPartSelect*ps0 = new NetPartSelect(esig, 0, sel_need-1,
NetPartSelect::VP);
ps0->set_line(loc);
des->add_node(ps0);
connect(ps0->pin(1), esig->pin(0));
netvector_t*ps0_vec = new netvector_t(osig_data_type, sel_need-2, 0);
NetNet*ps0_sig = new NetNet(scope, scope->local_symbol(),
NetNet::TRI, ps0_vec);
ps0_sig->local_flag(true);
ps0_sig->set_line(loc);
connect(ps0_sig->pin(0), ps0->pin(0));
// osig = {..., esig[N-2:0]}
connect(osig_cat->pin(1), ps0_sig->pin(0));
// Create the part select esig[M-1:N-1]
NetPartSelect*ps1 = new NetPartSelect(esig, sel_need-1,
sel_got-sel_need,
NetPartSelect::VP);
ps1->set_line(loc);
des->add_node(ps1);
connect(ps1->pin(1), esig->pin(0));
netvector_t*ps1_vec = new netvector_t(osig_data_type, sel_got-sel_need-1, 0);
NetNet*ps1_sig = new NetNet(scope, scope->local_symbol(),
NetNet::TRI, ps1_vec);
ps1_sig->local_flag(true);
ps1_sig->set_line(loc);
connect(ps1_sig->pin(0), ps1->pin(0));
// Create the reduction OR: | esig[M-1:N-1]
NetUReduce*ered = new NetUReduce(scope, scope->local_symbol(),
NetUReduce::OR, sel_got-sel_need);
ered->set_line(loc);
des->add_node(ered);
connect(ered->pin(1), ps1_sig->pin(0));
NetNet*ered_sig = new NetNet(scope, scope->local_symbol(),
NetNet::TRI, &netvector_t::scalar_logic);
ered_sig->local_flag(true);
ered_sig->set_line(loc);
connect(ered->pin(0), ered_sig->pin(0));
// osig = { |esig[M-1:N-1], esig[N-2:0] }
connect(osig_cat->pin(2), ered_sig->pin(0));
return osig;
}
bool NetCase::synth_async(Design*des, NetScope*scope,
NexusSet&nex_map, NetBus&nex_out,
NetBus&accumulated_nex_out)
@@ -352,12 +481,22 @@ bool NetCase::synth_async(Design*des, NetScope*scope,
if (dynamic_cast<NetEConst*> (expr_))
return synth_async_casez_(des, scope, nex_map, nex_out, accumulated_nex_out);
if (debug_synth2) {
cerr << get_fileline() << ": NetCase::synth_async: "
<< "Selector expression: " << *expr_ << endl;
}
/* Synthesize the select expression. */
NetNet*esig = expr_->synthesize(des, scope, expr_);
unsigned sel_width = esig->vector_width();
ivl_assert(*this, sel_width > 0);
if (debug_synth2) {
cerr << get_fileline() << ": NetCase::synth_async: "
<< "selector width (sel_width) = " << sel_width << endl;
}
ivl_assert(*this, nex_map.size() == nex_out.pin_count());
vector<unsigned> mux_width (nex_out.pin_count());
@@ -384,6 +523,7 @@ bool NetCase::synth_async(Design*des, NetScope*scope,
index of the mux value, and the statement is bound to that
index. */
unsigned long max_guard_value = 0;
map<unsigned long,NetProc*>statement_map;
NetProc*statement_default = 0;
@@ -416,10 +556,49 @@ bool NetCase::synth_async(Design*des, NetScope*scope,
continue;
}
if (sel_idx > max_guard_value)
max_guard_value = sel_idx;
ivl_assert(*this, items_[item].statement);
statement_map[sel_idx] = items_[item].statement;
}
// The minimum selector width is the number of inputs that
// are selected, rounded up to the nearest power of 2.
unsigned sel_need = max(ceil(log2(max_guard_value + 1)), 1.0);
// If the sel_width can select more than just the explicit
// guard values, and there is a default statement, then adjust
// the sel_need to allow for the implicit selections.
if (statement_default && (sel_width > sel_need))
sel_need += 1;
// The mux size is always an exact power of 2.
if (sel_need >= 8*sizeof(unsigned)) {
cerr << get_fileline() << ": sorry: mux select width of "
<< sel_need << " bits is too large for synthesis." << endl;
des->errors += 1;
return false;
}
unsigned mux_size = 1U << sel_need;
if (debug_synth2) {
cerr << get_fileline() << ": NetCase::synth_async: "
<< "Adjusted mux_size is " << mux_size
<< " (max_guard_value=" << max_guard_value
<< ", sel_need=" << sel_need
<< ", sel_width=" << sel_width << ")." << endl;
}
if (sel_width > sel_need) {
if (debug_synth2) {
cerr << get_fileline() << ": NetCase::synth_async: "
<< "Selector is " << sel_width << " bits, "
<< "need only " << sel_need << " bits." << endl;
}
esig = mux_selector_reduce_width(des, scope, *this, esig, sel_need);
}
if (!statement_default && (statement_map.size() != ((size_t)1 << sel_width))) {
cerr << get_fileline() << ": sorry: Latch inferred from "
<< "incomplete case statement. This is not supported "
@@ -428,15 +607,6 @@ bool NetCase::synth_async(Design*des, NetScope*scope,
return false;
}
if (sel_width >= 8*sizeof(unsigned)) {
cerr << get_fileline() << ": sorry: mux select width of "
<< sel_width << " bits is too large for synthesis." << endl;
des->errors += 1;
return false;
}
unsigned mux_size = 1U << sel_width;
/* If there is a default clause, synthesize it once and we'll
link it in wherever it is needed. */
NetBus default_bus (scope, nex_map.size());
@@ -464,7 +634,7 @@ bool NetCase::synth_async(Design*des, NetScope*scope,
vector<NetMux*> mux (mux_width.size());
for (size_t mdx = 0 ; mdx < mux_width.size() ; mdx += 1) {
mux[mdx] = new NetMux(scope, scope->local_symbol(),
mux_width[mdx], mux_size, sel_width);
mux_width[mdx], mux_size, sel_need);
des->add_node(mux[mdx]);
// The select signal is already synthesized, and is
@@ -614,7 +784,7 @@ bool NetCase::synth_async_casez_(Design*des, NetScope*scope,
netvector_t*condit_type = new netvector_t(IVL_VT_LOGIC, 0, 0);
NetCaseCmp::kind_t case_kind;
NetCaseCmp::kind_t case_kind = NetCaseCmp::EEQ;
switch (type()) {
case NetCase::EQ:
case_kind = NetCaseCmp::EEQ;
@@ -650,8 +820,8 @@ bool NetCase::synth_async_casez_(Design*des, NetScope*scope,
sel_width, case_kind);
des->add_node(condit_dev);
condit_dev->set_line(*this);
// Note that the expression that may have windcards must
// go in the pin(2) input. This is the definiton of the
// Note that the expression that may have wildcards must
// go in the pin(2) input. This is the definition of the
// NetCaseCmp statement.
connect(condit_dev->pin(1), esig->pin(0));
connect(condit_dev->pin(2), guard->pin(0));
@@ -697,6 +867,7 @@ bool NetCase::synth_async_casez_(Design*des, NetScope*scope,
NetNet*tmp = new NetNet(scope, scope->local_symbol(),
NetNet::TRI, tmp_vec);
tmp->local_flag(true);
tmp->set_line(*this);
ivl_assert(*this, tmp->vector_width() != 0);
connect(mux_cur->pin_Result(), tmp->pin(0));
@@ -973,6 +1144,7 @@ bool NetCondit::synth_async(Design*des, NetScope*scope,
NetNet*otmp = new NetNet(scope, scope->local_symbol(),
NetNet::WIRE, NetNet::not_an_array, tmp_type);
otmp->local_flag(true);
otmp->set_line(*this);
connect(mux->pin_Result(),otmp->pin(0));
connect(mux->pin_Sel(), ssig->pin(0));
@@ -983,6 +1155,8 @@ bool NetCondit::synth_async(Design*des, NetScope*scope,
tmp_type = new netvector_t(mux_data_type, mux_width-1,0);
NetNet*tmp = new NetNet(scope, scope->local_symbol(),
NetNet::WIRE, NetNet::not_an_array, tmp_type);
tmp->local_flag(true);
tmp->set_line(*this);
connect(mux->pin_Data(1), tmp->pin(0));
}
@@ -990,6 +1164,8 @@ bool NetCondit::synth_async(Design*des, NetScope*scope,
tmp_type = new netvector_t(mux_data_type, mux_width-1,0);
NetNet*tmp = new NetNet(scope, scope->local_symbol(),
NetNet::WIRE, NetNet::not_an_array, tmp_type);
tmp->local_flag(true);
tmp->set_line(*this);
connect(mux->pin_Data(0), tmp->pin(0));
}
@@ -1000,6 +1176,8 @@ bool NetCondit::synth_async(Design*des, NetScope*scope,
tmp_type = new netvector_t(mux_data_type, mux_lwidth-1,0);
NetNet*tmp = new NetNet(scope, scope->local_symbol(),
NetNet::WIRE, NetNet::not_an_array, tmp_type);
tmp->local_flag(true);
tmp->set_line(*this);
NetPartSelect*ps = new NetPartSelect(tmp, mux_off, mux_width, NetPartSelect::PV);
des->add_node(ps);
connect(ps->pin(0), otmp->pin(0));
@@ -1027,8 +1205,14 @@ bool NetCondit::synth_async(Design*des, NetScope*scope,
<< endl;
}
vector<bool>mask = statement_input.pin(idx).nexus()->driven_mask();
for (size_t bit = mux_off ; bit < mux_off+mux_width ; bit += 1) {
ivl_assert(*this, mask[bit]==false);
// If the mask is empty then there are no bits in the
// nexus to check yet.
if (! mask.empty()) {
for (size_t bit = mux_off;
bit < mux_off+mux_width;
bit += 1) {
ivl_assert(*this, mask[bit]==false);
}
}
connect(nex_out.pin(idx), statement_input.pin(idx));
}
@@ -1176,6 +1360,7 @@ bool NetProcTop::synth_async(Design*des)
NetNet*tmp_sig = new NetNet(scope(), scope()->local_symbol(),
NetNet::WIRE, NetNet::not_an_array, tmp_type);
tmp_sig->local_flag(true);
tmp_sig->set_line(*this);
NetPartSelect*tmp = new NetPartSelect(tmp_sig, item.base,
item.wid, NetPartSelect::PV);
@@ -1209,8 +1394,10 @@ bool NetProcTop::synth_async(Design*des)
* the statements may each infer different reset and enable signals.
*/
bool NetBlock::synth_sync(Design*des, NetScope*scope,
bool&ff_negedge,
NetNet*ff_clk, NetBus&ff_ce,
NetBus&ff_aclr,NetBus&ff_aset,
vector<verinum>&ff_aset_value,
NexusSet&nex_map, NetBus&nex_out,
const vector<NetEvProbe*>&events_in)
{
@@ -1234,6 +1421,16 @@ bool NetBlock::synth_sync(Design*des, NetScope*scope,
are used to collect the outputs from the substatement
for the inputs of the FF bank. */
NetBus tmp_out (scope, tmp_set.size());
for (unsigned idx = 0 ; idx < tmp_out.pin_count() ; idx += 1) {
unsigned ptr = nex_map.find_nexus(tmp_set[idx]);
ivl_assert(*this, ptr < nex_out.pin_count());
if (nex_out.pin(ptr).is_linked()) {
cerr << get_fileline() << ": sorry: multiple statements "
"assigning to the same flip-flop are not yet "
"supported in synthesis." << endl;
return false;
}
}
/* Create a temporary ff_ce (FF clock-enable) that
accounts for the subset of outputs that this
@@ -1253,8 +1450,9 @@ bool NetBlock::synth_sync(Design*des, NetScope*scope,
subset of the statement. The tmp_map is the output
nexa that we expect, and the tmp_out is where we want
those outputs connected. */
bool ok_flag = cur->synth_sync(des, scope, ff_clk, tmp_ce,
ff_aclr, ff_aset,
bool ok_flag = cur->synth_sync(des, scope,
ff_negedge, ff_clk, tmp_ce,
ff_aclr, ff_aset, ff_aset_value,
tmp_set, tmp_out, events_in);
flag = flag && ok_flag;
@@ -1290,8 +1488,10 @@ bool NetBlock::synth_sync(Design*des, NetScope*scope,
* expression is connected to an event, or not.
*/
bool NetCondit::synth_sync(Design*des, NetScope*scope,
bool&ff_negedge,
NetNet*ff_clk, NetBus&ff_ce,
NetBus&ff_aclr,NetBus&ff_aset,
vector<verinum>&ff_aset_value,
NexusSet&nex_map, NetBus&nex_out,
const vector<NetEvProbe*>&events_in)
{
@@ -1338,25 +1538,13 @@ bool NetCondit::synth_sync(Design*des, NetScope*scope,
for (unsigned pin = 0 ; pin < tmp_out.pin_count() ; pin += 1) {
Nexus*rst_nex = tmp_out.pin(pin).nexus();
vector<bool> rst_mask = rst_nex->driven_mask();
if (debug_synth2) {
cerr << get_fileline() << ": NetCondit::synth_sync: "
<< "nex_out pin=" << pin
<< ", rst_mask.size()==" << rst_mask.size()
<< ", rst_nex->vector_width()=" << rst_nex->vector_width()
<< endl;
}
for (size_t bit = 0 ; bit < rst_mask.size() ; bit += 1) {
if (rst_mask[bit]==false) {
cerr << get_fileline() << ": sorry: "
<< "Asynchronous LOAD not implemented." << endl;
return false;
}
if (! rst_nex->drivers_constant()) {
cerr << get_fileline() << ": sorry: "
<< "Asynchronous LOAD not implemented." << endl;
return false;
}
verinum rst_drv = rst_nex->driven_vector();
ivl_assert(*this, rst_drv.len()==rst_mask.size());
verinum zero (verinum::V0, rst_drv.len());
verinum ones (verinum::V1, rst_drv.len());
@@ -1368,22 +1556,20 @@ bool NetCondit::synth_sync(Design*des, NetScope*scope,
ivl_assert(*this, rst->pin_count()==1);
connect(ff_aclr.pin(pin), rst->pin(0));
} else if (rst_drv==ones) {
} else {
// Don't yet support multiple asynchronous set inputs.
ivl_assert(*this, ! ff_aset.pin(pin).is_linked());
ivl_assert(*this, rst->pin_count()==1);
connect(ff_aset.pin(pin), rst->pin(0));
} else {
cerr << get_fileline() << ": sorry: "
<< "Forgot how to implement asynchronous scramble (set to x/z)." << endl;
return false;
if (rst_drv!=ones)
ff_aset_value[pin] = rst_drv;
}
}
return else_->synth_sync(des, scope, ff_clk, ff_ce,
ff_aclr, ff_aset,
return else_->synth_sync(des, scope,
ff_negedge, ff_clk, ff_ce,
ff_aclr, ff_aset, ff_aset_value,
nex_map, nex_out, vector<NetEvProbe*>(0));
}
@@ -1538,14 +1724,19 @@ bool NetCondit::synth_sync(Design*des, NetScope*scope,
}
}
bool flag = if_->synth_sync(des, scope, ff_clk, ff_ce, ff_aclr, ff_aset, nex_map, nex_out, events_in);
bool flag = if_->synth_sync(des, scope,
ff_negedge, ff_clk, ff_ce,
ff_aclr, ff_aset, ff_aset_value,
nex_map, nex_out, events_in);
return flag;
}
bool NetEvWait::synth_sync(Design*des, NetScope*scope,
bool&ff_negedge,
NetNet*ff_clk, NetBus&ff_ce,
NetBus&ff_aclr,NetBus&ff_aset,
vector<verinum>&ff_aset_value,
NexusSet&nex_map, NetBus&nex_out,
const vector<NetEvProbe*>&events_in)
{
@@ -1615,8 +1806,7 @@ bool NetEvWait::synth_sync(Design*des, NetScope*scope,
connect(ff_clk->pin(0), pclk->pin(0));
if (pclk->edge() == NetEvProbe::NEGEDGE) {
perm_string polarity = perm_string::literal("Clock:LPM_Polarity");
ff_clk->attribute(polarity, verinum("INVERT"));
ff_negedge = true;
if (debug_synth2) {
cerr << get_fileline() << ": debug: "
@@ -1626,8 +1816,9 @@ bool NetEvWait::synth_sync(Design*des, NetScope*scope,
}
/* Synthesize the input to the DFF. */
bool flag = statement_->synth_sync(des, scope, ff_clk, ff_ce,
ff_aclr, ff_aset,
bool flag = statement_->synth_sync(des, scope,
ff_negedge, ff_clk, ff_ce,
ff_aclr, ff_aset, ff_aset_value,
nex_map, nex_out, events);
return flag;
@@ -1648,6 +1839,7 @@ bool NetProcTop::synth_sync(Design*des)
NexusSet nex_set;
statement_->nex_output(nex_set);
vector<verinum> aset_value(nex_set.size());
/* Make a model FF that will connect to the first item in the
set, and will also take the initial connection of clocks
@@ -1657,6 +1849,7 @@ bool NetProcTop::synth_sync(Design*des)
NetNet*clock = new NetNet(scope(), scope()->local_symbol(),
NetNet::TRI, &netvector_t::scalar_logic);
clock->local_flag(true);
clock->set_line(*this);
#if 0
NetNet*ce = new NetNet(scope(), scope()->local_symbol(),
@@ -1681,7 +1874,10 @@ bool NetProcTop::synth_sync(Design*des)
// Connect the input later.
/* Synthesize the input to the DFF. */
bool flag = statement_->synth_sync(des, scope(), clock, ce, aclr, aset,
bool negedge = false;
bool flag = statement_->synth_sync(des, scope(),
negedge, clock, ce,
aclr, aset, aset_value,
nex_set, nex_d,
vector<NetEvProbe*>());
if (! flag) {
@@ -1700,9 +1896,10 @@ bool NetProcTop::synth_sync(Design*des)
}
NetFF*ff2 = new NetFF(scope(), scope()->local_symbol(),
nex_set[idx].wid);
negedge, nex_set[idx].wid);
des->add_node(ff2);
ff2->set_line(*this);
ff2->aset_value(aset_value[idx]);
NetNet*tmp = nex_d.pin(idx).nexus()->pick_any_net();
tmp->set_line(*this);
+13 -8
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2000-2014 Stephen Williams (steve@icarus.com)
* Copyright (c) 2000-2015 Stephen Williams (steve@icarus.com)
* Copyright CERN 2013 / Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
@@ -171,13 +171,6 @@ extern "C" unsigned ivl_expr_lineno(ivl_expr_t net)
return net->lineno;
}
inline static const char *basename(ivl_scope_t scope, const char *inst)
{
inst += strlen(ivl_scope_name(scope));
assert(*inst == '.');
return inst+1;
}
extern "C" ivl_variable_type_t ivl_const_type(ivl_net_const_t net)
{
assert(net);
@@ -1090,6 +1083,18 @@ extern "C" unsigned ivl_lpm_base(ivl_lpm_t net)
}
}
extern "C" unsigned ivl_lpm_negedge(ivl_lpm_t net)
{
assert(net);
switch (net->type) {
case IVL_LPM_FF:
return net->u_.ff.negedge_flag;
default:
assert(0);
return 0;
}
}
extern "C" ivl_nexus_t ivl_lpm_clk(ivl_lpm_t net)
{
assert(net);
+2 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2000-2011 Stephen Williams (steve@icarus.com)
* Copyright (c) 2000-2015 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
@@ -364,6 +364,7 @@ void dll_target::expr_last(const NetELast*net)
esig->value_ = IVL_VT_DARRAY;
esig->net_type= sig->net_type;
esig->width_ = 1;
esig->signed_ = sig->net_type->get_signed()? 1 : 0;
FILE_NAME(esig, net);
esig->u_.signal_.word = 0;
esig->u_.signal_.sig = sig;
+16 -17
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2000-2014 Stephen Williams (steve@icarus.com)
* Copyright (c) 2000-2015 Stephen Williams (steve@icarus.com)
* Copyright CERN 2013 / Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
@@ -151,13 +151,6 @@ void ivl_net_const_s::operator delete(void*, size_t)
static StringHeapLex net_const_strings;
inline static const char *basename(ivl_scope_t scope, const char *inst)
{
inst += strlen(ivl_scope_name(scope));
assert(*inst == '.');
return inst+1;
}
static perm_string make_scope_name(const hname_t&name)
{
if (! name.has_numbers())
@@ -1057,20 +1050,17 @@ void dll_target::logic(const NetLogic*net)
obj->npins_ = net->pin_count();
obj->pins_ = new ivl_nexus_t[obj->npins_];
ivl_nexus_ptr_t out_ptr = 0;
for (unsigned idx = 0 ; idx < obj->npins_ ; idx += 1) {
const Nexus*nex = net->pin(idx).nexus();
assert(nex->t_cookie());
obj->pins_[idx] = nex->t_cookie();
ivl_nexus_ptr_t tmp = nexus_log_add(obj->pins_[idx], obj, idx);
if (idx == 0)
out_ptr = tmp;
if (idx == 0) {
tmp->drive0 = net->pin(0).drive0();
tmp->drive1 = net->pin(0).drive1();
}
}
out_ptr->drive0 = net->pin(0).drive0();
out_ptr->drive1 = net->pin(0).drive1();
assert(net->scope());
ivl_scope_t scop = find_scope(des_, net->scope());
assert(scop);
@@ -1941,6 +1931,9 @@ void dll_target::lpm_ff(const NetFF*net)
const Nexus*nex;
/* Set the clock polarity. */
obj->u_.ff.negedge_flag = net->is_negedge();
/* Set the clk signal to point to the nexus, and the nexus to
point back to this device. */
nex = net->pin_Clock().nexus();
@@ -1979,7 +1972,10 @@ void dll_target::lpm_ff(const NetFF*net)
nexus_lpm_add(obj->u_.ff.aset, obj, 0, IVL_DR_HiZ, IVL_DR_HiZ);
verinum tmp = net->aset_value();
obj->u_.ff.aset_value = expr_from_value_(tmp);
if (tmp.len() > 0)
obj->u_.ff.aset_value = expr_from_value_(tmp);
else
obj->u_.ff.aset_value = 0;
} else {
obj->u_.ff.aset = 0;
@@ -2004,7 +2000,10 @@ void dll_target::lpm_ff(const NetFF*net)
nexus_lpm_add(obj->u_.ff.sset, obj, 0, IVL_DR_HiZ, IVL_DR_HiZ);
verinum tmp = net->sset_value();
obj->u_.ff.sset_value = expr_from_value_(tmp);
if (tmp.len() > 0)
obj->u_.ff.sset_value = expr_from_value_(tmp);
else
obj->u_.ff.sset_value = 0;
} else {
obj->u_.ff.sset = 0;
+2 -1
View File
@@ -1,7 +1,7 @@
#ifndef IVL_t_dll_H
#define IVL_t_dll_H
/*
* Copyright (c) 2000-2014 Stephen Williams (steve@icarus.com)
* Copyright (c) 2000-2015 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
@@ -370,6 +370,7 @@ struct ivl_lpm_s {
union {
struct ivl_lpm_ff_s {
unsigned negedge_flag :1;
ivl_nexus_t clk;
ivl_nexus_t we;
ivl_nexus_t aclr;
+1 -1
View File
@@ -35,7 +35,7 @@ using namespace std;
static const char*version_string =
"Icarus Verilog BLIF Code Generator " VERSION " (" VERSION_TAG ")\n\n"
"Copyright (c) 2013 Stephen Williams ([email protected])\n\n"
"Copyright (c) 2013,2015 Stephen Williams ([email protected])\n\n"
" This program is free software; you can redistribute it and/or modify\n"
" it under the terms of the GNU General Public License as published by\n"
" the Free Software Foundation; either version 2 of the License, or\n"
+1 -1
View File
@@ -51,7 +51,7 @@ static int print_lpm_cmp_gt_s(FILE*fd, ivl_lpm_t net)
return 0;
}
fprintf(stderr, "%s:%u: sorry: blif: Signed agnitude compare not implemented yet\n",
fprintf(stderr, "%s:%u: sorry: blif: Signed magnitude compare not implemented yet\n",
ivl_lpm_file(net), ivl_lpm_lineno(net));
return 1;
+2 -2
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2000-2014 Stephen Williams (steve@icarus.com)
* Copyright (c) 2000-2015 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
@@ -30,7 +30,7 @@
static const char*version_string =
"Icarus Verilog NULL Code Generator " VERSION " (" VERSION_TAG ")\n\n"
"Copyright (c) 2000-2014 Stephen Williams ([email protected])\n\n"
"Copyright (c) 2000-2015 Stephen Williams ([email protected])\n\n"
" This program is free software; you can redistribute it and/or modify\n"
" it under the terms of the GNU General Public License as published by\n"
" the Free Software Foundation; either version 2 of the License, or\n"
+6 -3
View File
@@ -82,12 +82,15 @@ pcb_config.h: stamp-pcb_config-h
$(CXX) $(CPPFLAGS) $(CXXFLAGS) @DEPENDENCY_FLAG@ -c $< -o $*.o
mv $*.d dep
fp_lex.o: fp_lex.cc fp.h
fp_lex.cc: $(srcdir)/fp.lex
$(LEX) -s -ofp_lex.cc $(srcdir)/fp.lex
fp.cc fp.h: $(srcdir)/fp.y
$(YACC) --verbose -t -d -o fp.cc $(srcdir)/fp.y
mv fp.cc.h fp.h 2>/dev/null || mv fp.hh fp.h
fp.cc: $(srcdir)/fp.y
$(YACC) --verbose -t -p fp -d -o $@ $<
fp.h: fp.cc
mv fp.cc.h $@ 2>/dev/null || mv fp.hh $@
ifeq (@WIN32@,yes)
TGTLDFLAGS=-L.. -livl
-1
View File
@@ -1,5 +1,4 @@
%name-prefix="fp"
%pure-parser
%parse-param {const char*file_path}
+2 -2
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2014 Stephen Williams (steve@icarus.com)
* Copyright (c) 2014,2015 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -34,7 +34,7 @@ using namespace std;
static const char*version_string =
"Icarus Verilog SIZER Statistics Generator " VERSION " (" VERSION_TAG ")\n\n"
"Copyright (c) 2014 Stephen Williams ([email protected])\n\n"
"Copyright (c) 2014,2015 Stephen Williams ([email protected])\n\n"
" This program is free software; you can redistribute it and/or modify\n"
" it under the terms of the GNU General Public License as published by\n"
" the Free Software Foundation; either version 2 of the License, or\n"
+19 -6
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013 Stephen Williams (steve@icarus.com)
* Copyright (c) 2013-2015 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
@@ -25,13 +25,26 @@
void show_constant(ivl_net_const_t net)
{
unsigned idx;
const char*bits = ivl_const_bits(net);
assert(net);
fprintf(out, "constant ");
for (idx = 0 ; idx < ivl_const_width(net) ; idx += 1)
fprintf(out, "%c", bits[idx]);
switch (ivl_const_type(net)) {
case IVL_VT_BOOL:
case IVL_VT_LOGIC:
{
const char*bits = ivl_const_bits(net);
unsigned idx;
assert(bits);
for (idx = 0 ; idx < ivl_const_width(net) ; idx += 1)
fprintf(out, "%c", bits[idx]);
}
break;
case IVL_VT_REAL:
fprintf(out, "%f", ivl_const_real(net));
break;
default:
fprintf(out, "<unsupported type>");
break;
}
fprintf(out, " at %s:%u\n", ivl_const_file(net), ivl_const_lineno(net));
}
+2 -2
View File
@@ -2,7 +2,7 @@
// are not used here.
// target_design()
unusedFunction:stub.c:1770
unusedFunction:stub.c:1774
// target_query()
unusedFunction:stub.c:1834
unusedFunction:stub.c:1844

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