Compare commits

..
363 Commits
Author SHA1 Message Date
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
227 changed files with 9925 additions and 4940 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 \
+5 -3
View File
@@ -94,13 +94,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 -2
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-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
@@ -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;
@@ -125,6 +135,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.
+8 -3
View File
@@ -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);
@@ -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 */
+1 -1
View File
@@ -41,7 +41,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>;
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
+4
View File
@@ -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;
+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
+9 -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;
@@ -1889,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 ([email protected])
* 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();
+17 -6
View File
@@ -1,4 +1,4 @@
.TH iverilog 1 "February 26th, 2014" "" "Version %M.%m.%n %E"
.TH iverilog 1 "Aug 7th, 2015" "" "Version %M.%n%E"
.SH NAME
iverilog - Icarus Verilog compiler
@@ -30,7 +30,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.
@@ -213,6 +213,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 +292,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
@@ -514,14 +525,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\-2015 Stephen Williams
This document can be freely redistributed according to the terms of the
GNU General Public License version 2.0
+15 -11
View File
@@ -1,5 +1,5 @@
/*
* 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
@@ -496,6 +496,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 +507,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 +542,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 +578,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);
}
}
@@ -1044,19 +1057,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" : "");
+117 -24
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1999-2014 Stephen Williams (steve@icarus.com)
* Copyright (c) 1999-2015 Stephen Williams (steve@icarus.com)
* Copyright CERN 2013 / Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
@@ -657,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;
}
@@ -785,8 +788,11 @@ 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: "
@@ -1072,7 +1078,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];
@@ -1094,6 +1100,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_;
@@ -1324,7 +1335,7 @@ unsigned PECallFunction::test_width_method_(Design*des, NetScope*scope,
if (net == 0)
return 0;
// Look fonr built in string attributes.
// Look for built in string attributes.
if (net->data_type()==IVL_VT_STRING) {
if (method_name == "len") {
@@ -1407,7 +1418,7 @@ NetExpr*PECallFunction::cast_to_width_(NetExpr*expr, unsigned wid) const
const. This is a more efficient result. */
if (NetEConst*tmp = dynamic_cast<NetEConst*>(expr)) {
tmp->cast_signed(signed_flag_);
if (wid > tmp->expr_width()) {
if (wid != tmp->expr_width()) {
tmp = new NetEConst(verinum(tmp->value(), wid));
tmp->set_line(*this);
delete expr;
@@ -1443,7 +1454,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);
}
@@ -1586,7 +1597,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;
@@ -2178,6 +2189,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
{
@@ -2259,6 +2278,9 @@ NetExpr* PECallFunction::elaborate_base_(Design*des, NetScope*scope, NetScope*ds
NetEUFunc*func = new NetEUFunc(scope, dscope, eres, parms, need_const);
func->set_line(*this);
if(res->darray_type())
return func;
NetExpr*tmp = pad_to_width(func, expr_wid, *this);
tmp->cast_signed(signed_flag_);
@@ -2291,6 +2313,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;
@@ -2321,7 +2358,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;
}
@@ -2335,7 +2372,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;
@@ -2522,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
{
@@ -2772,9 +2842,9 @@ 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;
@@ -2822,6 +2892,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());
@@ -2850,7 +2939,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: "
@@ -3416,7 +3505,7 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
indices_flags idx_flags;
indices_to_expressions(des, scope, this,
use_comp.index, net->unpacked_dimensions(),
need_const, net->unpacked_count(),
need_const,
idx_flags,
unpacked_indices,
unpacked_indices_const);
@@ -3769,7 +3858,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_;
@@ -4489,7 +4578,7 @@ NetExpr* PEIdent::elaborate_expr_net_word_(Design*des, NetScope*scope,
indices_flags idx_flags;
indices_to_expressions(des, scope, this,
name_tail.index, net->unpacked_dimensions(),
need_const, net->unpacked_count(),
need_const,
idx_flags,
unpacked_indices,
unpacked_indices_const);
@@ -4578,7 +4667,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;
@@ -4718,7 +4808,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);
@@ -4820,7 +4911,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);
@@ -4908,7 +5000,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());
+25 -11
View File
@@ -157,7 +157,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 +171,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;
@@ -316,7 +330,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;
}
@@ -470,7 +485,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;
}
}
}
@@ -528,8 +543,6 @@ NetAssign_* PEIdent::elaborate_lval_net_word_(Design*des,
return 0;
}
unsigned array_need_words = reg->unpacked_count();
// Make sure there are enough indices to address an array element.
const index_component_t&index_head = name_tail.index.front();
if (index_head.sel == index_component_t::SEL_PART) {
@@ -547,7 +560,7 @@ NetAssign_* PEIdent::elaborate_lval_net_word_(Design*des,
indices_flags flags;
indices_to_expressions(des, scope, this,
name_tail.index, reg->unpacked_dimensions(),
false, array_need_words,
false,
flags,
unpacked_indices,
unpacked_indices_const);
@@ -1117,8 +1130,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);
+1 -1
View File
@@ -630,7 +630,7 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
indices_flags flags;
indices_to_expressions(des, scope, this,
path_tail.index, sig->unpacked_dimensions(),
true, sig->unpacked_count(),
true,
flags,
unpacked_indices,
unpacked_indices_const);
+17 -26
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
@@ -201,16 +201,15 @@ static void elaborate_scope_enumeration(Design*des, NetScope*scope,
verinum one_value ((uint64_t)1, enum_width);
one_value.has_sign(enum_type->signed_flag);
// Find the maximum allowed enumeration value.
verinum min_value (0);
verinum max_value (0);
if (enum_type->signed_flag) {
min_value = -pow(verinum(2), verinum(enum_width-1));
max_value = pow(verinum(2), verinum(enum_width-1)) - one_value;
} else {
max_value = pow(verinum(2), verinum(enum_width)) - one_value;
}
min_value.has_sign(true);
max_value.has_sign(enum_type->signed_flag);
// Variable to indicate when a defined value wraps.
bool implicit_wrapped = false;
// Process the enumeration definition.
for (list<named_pexpr_t>::const_iterator cur = enum_type->names->begin()
; cur != enum_type->names->end() ; ++ cur, name_idx += 1) {
@@ -229,6 +228,8 @@ static void elaborate_scope_enumeration(Design*des, NetScope*scope,
continue;
}
cur_value = val_const->value();
// Clear the implicit wrapped flag if a parameter is given.
implicit_wrapped = false;
// A 2-state value can not have a constant with X/Z bits.
if (enum_type->base_type==IVL_VT_BOOL &&
@@ -335,24 +336,8 @@ static void elaborate_scope_enumeration(Design*des, NetScope*scope,
continue;
}
// Cast any undefined bits to zero so the comparisons below
// return just true (1) or false (0).
verinum two_state_value = cur_value;
two_state_value.cast_to_int2();
// The enumeration value must fit into the enumeration bits.
if (!cur_value.is_defined()) {
if (cur_value.len() > (unsigned long)use_enum->packed_width()) {
cerr << use_enum->get_fileline()
<< ": error: Enumeration name " << cur->name
<< " value=" << cur_value
<< " is too wide for enumeration base type." << endl;
des->errors += 1;
}
} else if ((two_state_value > max_value) ||
(cur_value.has_sign() && (two_state_value < min_value))) {
// Check to see if an implicitly wrapped value is used.
if (implicit_wrapped) {
cerr << use_enum->get_fileline()
<< ": error: Enumeration name " << cur->name
<< " has an inferred value that overflowed." << endl;
@@ -385,6 +370,7 @@ static void elaborate_scope_enumeration(Design*des, NetScope*scope,
// In case the next name has an implicit value,
// increment the current value by one.
if (cur_value.is_defined()) {
if (cur_value == max_value) implicit_wrapped = true;
cur_value = cur_value + one_value;
}
}
@@ -807,7 +793,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;
}
@@ -1756,7 +1742,8 @@ 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());
@@ -1806,8 +1793,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;
}
}
+52 -12
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 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));
}
@@ -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();
+48 -35
View File
@@ -32,6 +32,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 +81,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 +158,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 +183,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
+127 -73
View File
@@ -1,5 +1,5 @@
/*
* 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
@@ -1287,15 +1287,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 +1333,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 +1364,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 +1397,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
@@ -1454,8 +1457,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 +1545,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 +1559,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 +1570,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 +1584,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 +1614,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 +1690,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 +1724,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 +1734,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 +1755,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;
@@ -2282,11 +2283,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);
@@ -3720,7 +3728,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 +3743,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);
@@ -3782,20 +3790,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]) {
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 (idx < parms_.size() && parms_[idx]) {
lv = parms_[idx]->elaborate_lval(des, scope, false, false);
if (lv == 0) {
cerr << parms_[idx]->get_fileline() << ": error: "
<< "I give up on task port " << (idx+1)
<< " expression: " << *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 +4039,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 +4581,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 +4791,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 +4826,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 +4915,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 +4924,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);
@@ -5013,8 +5045,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
@@ -5193,9 +5233,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;
}
@@ -5679,6 +5728,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 +5765,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"
@@ -6086,7 +6139,8 @@ 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.
+6
View File
@@ -2009,6 +2009,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);
+34 -47
View File
@@ -1,10 +1,10 @@
.TH iverilog-vpi 1 "April 17th, 2009" "" "Version %M.%m.%n %E"
.TH iverilog-vpi 1 "May 10th, 2015" "" "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:
@@ -28,8 +28,8 @@ VPI modules to further reference external libraries.
.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 +41,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 +87,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 +110,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\-2015 Stephen Williams
This document can be freely redistributed according to the terms of the
GNU General Public License version 2.0
+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
+200 -320
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
+21 -11
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,16 +432,26 @@ 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) {
cerr << yylloc.text << ":" << yylloc.first_line << ": warning: "
+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());
+6 -1
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
@@ -153,6 +153,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;
@@ -678,6 +679,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 +863,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;
+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
+4 -2
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());
@@ -846,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);
+18 -11
View File
@@ -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;
@@ -262,19 +264,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 +286,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;
}
@@ -372,6 +377,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.
+16 -5
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
@@ -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_);
}
+33 -12
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();
@@ -619,7 +624,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 +652,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 };
@@ -765,7 +770,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 +923,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,8 +1014,9 @@ 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;
@@ -1221,6 +1228,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_;
@@ -1618,9 +1627,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 +1662,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_;
@@ -2212,7 +2223,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 +2294,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 +2625,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);
@@ -2895,8 +2908,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 +3051,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);
@@ -3313,8 +3330,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);
@@ -4747,7 +4766,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;
@@ -4990,4 +5010,5 @@ inline unsigned Link::get_pin() const
return pin_;
}
#undef ENUM_UNSIGNED_INT
#endif /* IVL_netlist_H */
+3 -5
View File
@@ -480,8 +480,6 @@ void indices_to_expressions(Design*des, NetScope*scope,
const list<index_component_t>&src, unsigned count,
// True if the expression MUST be constant.
bool need_const,
// Total words in target array
unsigned need_addr,
// These are the outputs.
indices_flags&flags,
list<NetExpr*>&indices, list<long>&indices_const)
@@ -692,7 +690,7 @@ NetExpr* make_canonical_index(Design*des, NetScope*scope,
indices_flags flags;
indices_to_expressions(des, scope, loc,
src, src.size(),
need_const, stype->static_dimensions().size(),
need_const,
flags,
indices_expr, indices_const);
@@ -893,7 +891,7 @@ static NetExpr* do_elab_and_eval(Design*des, NetScope*scope, PExpr*pe,
}
}
// If the context_width sent is is actually the minimim width,
// 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) {
@@ -1428,7 +1426,7 @@ NetExpr*collapse_array_exprs(Design*des, NetScope*scope,
indices_flags flags;
indices_to_expressions(des, scope, loc, indices,
net->packed_dimensions(),
false, net->unpacked_count(), flags, exprs, exprs_const);
false, flags, exprs, exprs_const);
ivl_assert(*loc, exprs.size() == net->packed_dimensions());
// Special Case: there is only 1 packed dimension, so the
-2
View File
@@ -181,8 +181,6 @@ extern void indices_to_expressions(Design*des, NetScope*scope,
const list<index_component_t>&src, unsigned count,
// True if the expression MUST be constant.
bool need_const,
// Total array size, for sizing expressions
unsigned need_addr,
// These are the outputs.
indices_flags&flags,
list<NetExpr*>&indices,list<long>&indices_const);
+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:
+1 -1
View File
@@ -141,7 +141,7 @@ 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 {
+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_) { }
+313 -102
View File
@@ -1,7 +1,7 @@
%{
/*
* Copyright (c) 1998-2014 Stephen Williams ([email protected])
* Copyright (c) 1998-2015 Stephen Williams ([email protected])
* Copyright CERN 2012-2013 / Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
@@ -49,6 +49,16 @@ static struct {
data_type_t* data_type;
} port_declaration_context = {NetNet::NONE, NetNet::NOT_A_PORT, 0};
/* Modport port declaration lists use this structure for context. */
enum modport_port_type_t { MP_NONE, MP_SIMPLE, MP_TF, MP_CLOCKING };
static struct {
modport_port_type_t type;
union {
NetNet::PortType direction;
bool is_import;
};
} last_modport_port = { MP_NONE, {NetNet::NOT_A_PORT}};
/* The task and function rules need to briefly hold the pointer to the
task/function that is currently in progress. */
static PTask* current_task = 0;
@@ -549,6 +559,7 @@ static void current_function_set_statement(const YYLTYPE&loc, vector<Statement*>
%type <flag> from_exclude block_item_decls_opt
%type <number> number pos_neg_number
%type <flag> signing unsigned_signed_opt signed_unsigned_opt
%type <flag> import_export
%type <flag> K_automatic_opt K_packed_opt K_reg_opt K_static_opt K_virtual_opt
%type <flag> udp_reg_opt edge_operator
%type <drive> drive_strength drive_strength_opt dr_strength0 dr_strength1
@@ -562,8 +573,8 @@ static void current_function_set_statement(const YYLTYPE&loc, vector<Statement*>
%type <statement> udp_initial udp_init_opt
%type <expr> udp_initial_expr_opt
%type <text> register_variable net_variable endlabel_opt class_declaration_endlabel_opt
%type <perm_strings> register_variable_list net_variable_list
%type <text> register_variable net_variable event_variable endlabel_opt class_declaration_endlabel_opt
%type <perm_strings> register_variable_list net_variable_list event_variable_list
%type <perm_strings> list_of_identifiers loop_variables
%type <port_list> list_of_port_identifiers
@@ -583,7 +594,7 @@ static void current_function_set_statement(const YYLTYPE&loc, vector<Statement*>
%type <tf_ports> task_item task_item_list task_item_list_opt
%type <tf_ports> tf_port_declaration tf_port_item tf_port_list tf_port_list_opt
%type <named_pexpr> port_name parameter_value_byname
%type <named_pexpr> modport_simple_port port_name parameter_value_byname
%type <named_pexprs> port_name_list parameter_value_byname_list
%type <named_pexpr> attribute
@@ -739,7 +750,7 @@ class_identifier
perm_string name = lex_strings.make($1);
class_type_t*tmp = new class_type_t(name);
FILE_NAME(tmp, @1);
pform_set_typedef(name, tmp);
pform_set_typedef(name, tmp, NULL);
delete[]$1;
$$ = tmp;
}
@@ -1033,7 +1044,11 @@ data_type /* IEEE1800-2005: A.2.2.1 */
$$ = tmp;
}
| struct_data_type
{ $$ = $1; }
{ if (!$1->packed_flag) {
yyerror(@1, "sorry: Unpacked structs not supported.");
}
$$ = $1;
}
| enum_data_type
{ $$ = $1; }
| atom2_type signed_unsigned_opt
@@ -1051,7 +1066,7 @@ data_type /* IEEE1800-2005: A.2.2.1 */
| K_time
{ list<pform_range_t>*pd = make_range_from_width(64);
vector_type_t*tmp = new vector_type_t(IVL_VT_LOGIC, false, pd);
tmp->reg_flag = true;
tmp->reg_flag = !gn_system_verilog();
$$ = tmp;
}
| TYPE_IDENTIFIER dimensions_opt
@@ -1117,8 +1132,8 @@ data_type_or_implicit_or_void
statements may go. This may be a bad idea, but it is legacy now. */
/* NOTE 2: The "module" rule of the description combines the
module_declaration and program_declaration rules from the
standard description. */
module_declaration, program_declaration, and interface_declaration
rules from the standard description. */
description /* IEEE1800-2005: A.1.2 */
: module
@@ -1142,7 +1157,7 @@ description_list
;
/* This implements the [ : INDENTIFIER ] part of the constructure
/* This implements the [ : IDENTIFIER ] part of the constructor
rule documented in IEEE1800-2005: A.1.8 */
endnew_opt : ':' K_new | ;
@@ -1270,6 +1285,11 @@ function_declaration /* IEEE1800-2005: A.2.6 */
;
import_export /* IEEE1800-2012: A.2.9 */
: K_import { $$ = true; }
| K_export { $$ = false; }
;
implicit_class_handle /* IEEE1800-2005: A.8.4 */
: K_this { $$ = pform_create_this(); }
| K_super { $$ = pform_create_super(); }
@@ -1546,6 +1566,115 @@ method_qualifier_opt
|
;
modport_declaration /* IEEE1800-2012: A.2.9 */
: K_modport
{ if (!pform_in_interface())
yyerror(@1, "error: modport declarations are only allowed "
"in interfaces.");
}
modport_item_list ';'
modport_item_list
: modport_item
| modport_item_list ',' modport_item
;
modport_item
: IDENTIFIER
{ pform_start_modport_item(@1, $1); }
'(' modport_ports_list ')'
{ pform_end_modport_item(@1); }
;
/* The modport_ports_list is a LALR(2) grammar. When the parser sees a
',' it needs to look ahead to the next token to decide whether it is
a continuation of the preceding modport_ports_declaration, or the
start of a new modport_ports_declaration. bison only supports LALR(1),
so we have to handcraft a mini parser for this part of the syntax.
last_modport_port holds the state for this mini parser.*/
modport_ports_list
: modport_ports_declaration
| modport_ports_list ',' modport_ports_declaration
| modport_ports_list ',' modport_simple_port
{ if (last_modport_port.type == MP_SIMPLE) {
pform_add_modport_port(@3, last_modport_port.direction,
$3->name, $3->parm);
} else {
yyerror(@3, "error: modport expression not allowed here.");
}
delete $3;
}
| modport_ports_list ',' modport_tf_port
{ if (last_modport_port.type != MP_TF)
yyerror(@3, "error: task/function declaration not allowed here.");
}
| modport_ports_list ',' IDENTIFIER
{ if (last_modport_port.type == MP_SIMPLE) {
pform_add_modport_port(@3, last_modport_port.direction,
lex_strings.make($3), 0);
} else if (last_modport_port.type != MP_TF) {
yyerror(@3, "error: list of identifiers not allowed here.");
}
delete[] $3;
}
| modport_ports_list ','
{ yyerror(@2, "error: NULL port declarations are not allowed"); }
;
modport_ports_declaration
: attribute_list_opt port_direction IDENTIFIER
{ last_modport_port.type = MP_SIMPLE;
last_modport_port.direction = $2;
pform_add_modport_port(@3, $2, lex_strings.make($3), 0);
delete[] $3;
delete $1;
}
| attribute_list_opt port_direction modport_simple_port
{ last_modport_port.type = MP_SIMPLE;
last_modport_port.direction = $2;
pform_add_modport_port(@3, $2, $3->name, $3->parm);
delete $3;
delete $1;
}
| attribute_list_opt import_export IDENTIFIER
{ last_modport_port.type = MP_TF;
last_modport_port.is_import = $2;
yyerror(@3, "sorry: modport task/function ports are not yet supported.");
delete[] $3;
delete $1;
}
| attribute_list_opt import_export modport_tf_port
{ last_modport_port.type = MP_TF;
last_modport_port.is_import = $2;
yyerror(@3, "sorry: modport task/function ports are not yet supported.");
delete $1;
}
| attribute_list_opt K_clocking IDENTIFIER
{ last_modport_port.type = MP_CLOCKING;
last_modport_port.direction = NetNet::NOT_A_PORT;
yyerror(@3, "sorry: modport clocking declaration is not yet supported.");
delete[] $3;
delete $1;
}
;
modport_simple_port
: '.' IDENTIFIER '(' expression ')'
{ named_pexpr_t*tmp = new named_pexpr_t;
tmp->name = lex_strings.make($2);
tmp->parm = $4;
delete[]$2;
$$ = tmp;
}
;
modport_tf_port
: K_task IDENTIFIER
| K_task IDENTIFIER '(' tf_port_list_opt ')'
| K_function data_type_or_implicit_or_void IDENTIFIER
| K_function data_type_or_implicit_or_void IDENTIFIER '(' tf_port_list_opt ')'
;
non_integer_type /* IEEE1800-2005: A.2.2.1 */
: K_real { $$ = real_type_t::REAL; }
@@ -1667,7 +1796,7 @@ property_expr /* IEEE1800-2012 A.2.10 */
/* The property_qualifier rule is as literally described in the LRM,
but the use is usually as { property_qualifier }, which is
implemented bt the property_qualifier_opt rule below. */
implemented by the property_qualifier_opt rule below. */
property_qualifier /* IEEE1800-2005 A.1.8 */
: class_item_qualifier
@@ -1972,7 +2101,7 @@ tf_port_item /* IEEE1800-2005: A.2.7 */
} else {
// Otherwise, the decorations for this identifier
// indicate the type. Save the type for any right
// context thta may come later.
// context that may come later.
port_declaration_context.port_type = use_port_type;
if ($2 == 0) {
$2 = new vector_type_t(IVL_VT_LOGIC, false, 0);
@@ -1990,7 +2119,7 @@ tf_port_item /* IEEE1800-2005: A.2.7 */
assert(tmp->size()==1);
tmp->front().defe = $5;
}
}
}
/* Rules to match error cases... */
@@ -2004,8 +2133,14 @@ tf_port_item /* IEEE1800-2005: A.2.7 */
/* This rule matches the [ = <expression> ] part of the tf_port_item rules. */
tf_port_item_expr_opt
: '=' expression { $$ = $2; }
| { $$ = 0; }
: '=' expression
{ if (! gn_system_verilog()) {
yyerror(@1, "error: Task/function default arguments require "
"SystemVerilog.");
}
$$ = $2;
}
| { $$ = 0; }
;
tf_port_list /* IEEE1800-2005: A.2.7 */
@@ -2186,8 +2321,8 @@ block_item_decl
{ if ($2) pform_set_data_type(@2, $2, $3, NetNet::REG, attributes_in_context);
}
| K_event list_of_identifiers ';'
{ pform_make_events($2, @1.text, @1.first_line);
| K_event event_variable_list ';'
{ if ($2) pform_make_events($2, @1.text, @1.first_line);
}
| K_parameter param_type parameter_assign_list ';'
@@ -2233,9 +2368,9 @@ block_item_decls_opt
/* Type declarations are parsed here. The rule actions call pform
functions that add the declaration to the current lexical scope. */
type_declaration
: K_typedef data_type IDENTIFIER ';'
: K_typedef data_type IDENTIFIER dimensions_opt ';'
{ perm_string name = lex_strings.make($3);
pform_set_typedef(name, $2);
pform_set_typedef(name, $2, $4);
delete[]$3;
}
@@ -2248,7 +2383,7 @@ type_declaration
yyerror(@3, "error: Typedef identifier \"%s\" is already a type name.", $3.text);
} else {
pform_set_typedef(name, $2);
pform_set_typedef(name, $2, NULL);
}
delete[]$3.text;
}
@@ -2261,7 +2396,7 @@ type_declaration
perm_string name = lex_strings.make($3);
class_type_t*tmp = new class_type_t(name);
FILE_NAME(tmp, @3);
pform_set_typedef(name, tmp);
pform_set_typedef(name, tmp, NULL);
delete[]$3;
}
| K_typedef K_enum IDENTIFIER ';'
@@ -2276,7 +2411,7 @@ type_declaration
perm_string name = lex_strings.make($2);
class_type_t*tmp = new class_type_t(name);
FILE_NAME(tmp, @2);
pform_set_typedef(name, tmp);
pform_set_typedef(name, tmp, NULL);
delete[]$2;
}
@@ -2323,34 +2458,34 @@ enum_data_type
enum_type->range.reset(make_range_from_width(integer_width));
$$ = enum_type;
}
| K_enum K_logic unsigned_signed_opt dimensions '{' enum_name_list '}'
| K_enum K_logic unsigned_signed_opt dimensions_opt '{' enum_name_list '}'
{ enum_type_t*enum_type = new enum_type_t;
FILE_NAME(enum_type, @1);
enum_type->names .reset($6);
enum_type->base_type = IVL_VT_LOGIC;
enum_type->signed_flag = $3;
enum_type->integer_flag = false;
enum_type->range.reset($4);
enum_type->range.reset($4 ? $4 : make_range_from_width(1));
$$ = enum_type;
}
| K_enum K_reg unsigned_signed_opt dimensions '{' enum_name_list '}'
| K_enum K_reg unsigned_signed_opt dimensions_opt '{' enum_name_list '}'
{ enum_type_t*enum_type = new enum_type_t;
FILE_NAME(enum_type, @1);
enum_type->names .reset($6);
enum_type->base_type = IVL_VT_LOGIC;
enum_type->signed_flag = $3;
enum_type->integer_flag = false;
enum_type->range.reset($4);
enum_type->range.reset($4 ? $4 : make_range_from_width(1));
$$ = enum_type;
}
| K_enum K_bit unsigned_signed_opt dimensions '{' enum_name_list '}'
| K_enum K_bit unsigned_signed_opt dimensions_opt '{' enum_name_list '}'
{ enum_type_t*enum_type = new enum_type_t;
FILE_NAME(enum_type, @1);
enum_type->names .reset($6);
enum_type->base_type = IVL_VT_BOOL;
enum_type->signed_flag = $3;
enum_type->integer_flag = false;
enum_type->range.reset($4);
enum_type->range.reset($4 ? $4 : make_range_from_width(1));
$$ = enum_type;
}
;
@@ -3210,6 +3345,22 @@ expr_primary
FILE_NAME(tmp, @1);
$$ = tmp;
}
| TIME_LITERAL
{ int unit;
based_size = 0;
$$ = 0;
if ($1 == 0 || !get_time_unit($1, unit))
yyerror(@1, "internal error: delay.");
else {
double p = pow(10.0, (double)(unit - pform_get_timeunit()));
double time = atof($1) * p;
verireal *v = new verireal(time);
$$ = new PEFNumber(v);
FILE_NAME($$, @1);
}
}
| SYSTEM_IDENTIFIER
{ perm_string tn = lex_strings.make($1);
PECallFunction*tmp = new PECallFunction(tn);
@@ -3244,7 +3395,7 @@ expr_primary
/* An identifier followed by an expression list in parentheses is a
function call. If a system identifier, then a system function
call. It can also be a call to a class method (functino). */
call. It can also be a call to a class method (function). */
| hierarchy_identifier '(' expression_list_with_nuls ')'
{ list<PExpr*>*expr_list = $3;
@@ -4018,6 +4169,9 @@ port_declaration
use_type = NetNet::IMPLICIT_REG;
} else if (dynamic_cast<struct_type_t*> ($4)) {
use_type = NetNet::IMPLICIT_REG;
} else if (enum_type_t*etype = dynamic_cast<enum_type_t*> ($4)) {
if(etype->base_type == IVL_VT_LOGIC)
use_type = NetNet::IMPLICIT_REG;
}
}
ptmp = pform_module_port_reference(name, @2.text, @2.first_line);
@@ -4213,13 +4367,13 @@ local_timeunit_prec_decl2
}
;
/* This is the global structure of a module. A module in a start
/* This is the global structure of a module. A module is a start
section, with optional ports, then an optional list of module
items, and finally an end marker. */
module
: attribute_list_opt module_start IDENTIFIER
{ pform_startmodule(@2, $3, $2==K_program, $1); }
{ pform_startmodule(@2, $3, $2==K_program, $2==K_interface, $1); }
module_package_import_list_opt
module_parameter_port_list_opt
module_port_list_opt
@@ -4258,6 +4412,9 @@ module
case K_program:
yyerror(@14, "error: program not closed by endprogram.");
break;
case K_interface:
yyerror(@14, "error: interface not closed by endinterface.");
break;
default:
break;
}
@@ -4283,6 +4440,10 @@ module
yyerror(@16, "error: End label doesn't match "
"program name.");
break;
case K_interface:
yyerror(@16, "error: End label doesn't match "
"interface name.");
break;
default:
break;
}
@@ -4297,19 +4458,21 @@ module
}
;
/* Modules start with module/macromodule or program keyword, and end
with the endmodule or endprogram keyword. The syntax for modules
and programs is almost identical, so let semantics sort out the
differences. */
/* Modules start with a module/macromodule, program, or interface
keyword, and end with a endmodule, endprogram, or endinterface
keyword. The syntax for modules programs, and interfaces is
almost identical, so let semantics sort out the differences. */
module_start
: K_module { $$ = K_module; }
| K_macromodule { $$ = K_module; }
| K_program { $$ = K_program; }
| K_interface { $$ = K_interface; }
;
module_end
: K_endmodule { $$ = K_module; }
| K_endprogram { $$ = K_program; }
: K_endmodule { $$ = K_module; }
| K_endprogram { $$ = K_program; }
| K_endinterface { $$ = K_interface; }
;
endlabel_opt
@@ -4395,8 +4558,8 @@ module_item
}
pform_makewire(@2, $4, str_strength, $5, $2, data_type);
if ($1) {
yyerror(@2, "sorry: Attributes not supported "
"on net declaration assignments.");
yywarn(@2, "Attributes are not supported on net declaration "
"assignments and will be discarded.");
delete $1;
}
}
@@ -4412,8 +4575,8 @@ module_item
}
pform_makewire(@2, 0, $4, $5, $2, data_type);
if ($1) {
yyerror(@2, "sorry: Attributes not supported "
"on net declaration assignments.");
yywarn(@2, "Attributes are not supported on net declaration "
"assignments and will be discarded.");
delete $1;
}
}
@@ -4422,8 +4585,8 @@ module_item
{ real_type_t*data_type = new real_type_t(real_type_t::REAL);
pform_makewire(@2, 0, str_strength, $3, NetNet::WIRE, data_type);
if ($1) {
yyerror(@2, "sorry: Attributes not supported "
"on net declaration assignments.");
yywarn(@2, "Attributes are not supported on net declaration "
"assignments and will be discarded.");
delete $1;
}
}
@@ -4505,7 +4668,12 @@ module_item
/* */
| K_defparam defparam_assign_list ';'
| K_defparam
{ if (pform_in_interface())
yyerror(@1, "error: Parameter overrides are not allowed "
"in interfaces.");
}
defparam_assign_list ';'
/* Most gate types have an optional drive strength and optional
two/three-value delay. These rules handle the different cases.
@@ -4614,7 +4782,7 @@ module_item
generate/endgenerate regions do not nest. Generate schemes nest,
but generate regions do not. */
| K_generate module_item_list_opt K_endgenerate
| K_generate generate_item_list_opt K_endgenerate
{ // Test for bad nesting. I understand it, but it is illegal.
if (pform_parent_generate()) {
cerr << @1 << ": error: Generate/endgenerate regions cannot nest." << endl;
@@ -4651,44 +4819,32 @@ module_item
K_endcase
{ pform_endgenerate(); }
/* Handle some anachronistic syntax cases. */
| K_generate K_begin module_item_list_opt K_end K_endgenerate
{ /* Detect and warn about anachronistic begin/end use */
if (generation_flag > GN_VER2001 && warn_anachronisms) {
warn_count += 1;
cerr << @2 << ": warning: Anachronistic use of begin/end to surround generate schemes." << endl;
}
}
| K_generate K_begin ':' IDENTIFIER {
pform_start_generate_nblock(@2, $4);
} module_item_list_opt K_end K_endgenerate
{ /* Detect and warn about anachronistic named begin/end use */
if (generation_flag > GN_VER2001 && warn_anachronisms) {
warn_count += 1;
cerr << @2 << ": warning: Anachronistic use of named begin/end to surround generate schemes." << endl;
}
pform_endgenerate();
}
| modport_declaration
| package_import_declaration
/* 1364-2001 and later allow specparam declarations outside specify blocks. */
| attribute_list_opt K_specparam specparam_decl ';'
| attribute_list_opt K_specparam
{ if (pform_in_interface())
yyerror(@1, "error: specparam declarations are not allowed "
"in interfaces.");
}
specparam_decl ';'
/* specify blocks are parsed but ignored. */
| K_specify K_endspecify
{ /* empty lists are legal syntax. */ }
| K_specify
{ if (pform_in_interface())
yyerror(@1, "error: specify blocks are not allowed "
"in interfaces.");
}
specify_item_list_opt K_endspecify
| K_specify specify_item_list K_endspecify
{
}
| K_specify error K_endspecify
{ yyerror(@1, "error: syntax error in specify block");
yyerrok;
}
| K_specify error K_endspecify
{ yyerror(@1, "error: syntax error in specify block");
yyerrok;
}
/* These rules match various errors that the user can type into
module items. These rules try to catch them at a point where a
@@ -4747,6 +4903,16 @@ module_item
{ pform_set_timeprecision($2, true, true); }
;
module_item_list
: module_item_list module_item
| module_item
;
module_item_list_opt
: module_item_list
|
;
generate_if : K_if '(' expression ')' { pform_start_generate_if(@1, $3); } ;
generate_case_items
@@ -4761,15 +4927,37 @@ generate_case_item
{ pform_endgenerate(); }
;
module_item_list
: module_item_list module_item
| module_item
;
generate_item
: module_item
/* Handle some anachronistic syntax cases. */
| K_begin generate_item_list_opt K_end
{ /* Detect and warn about anachronistic begin/end use */
if (generation_flag > GN_VER2001 && warn_anachronisms) {
warn_count += 1;
cerr << @1 << ": warning: Anachronistic use of begin/end to surround generate schemes." << endl;
}
}
| K_begin ':' IDENTIFIER {
pform_start_generate_nblock(@1, $3);
} generate_item_list_opt K_end
{ /* Detect and warn about anachronistic named begin/end use */
if (generation_flag > GN_VER2001 && warn_anachronisms) {
warn_count += 1;
cerr << @1 << ": warning: Anachronistic use of named begin/end to surround generate schemes." << endl;
}
pform_endgenerate();
}
;
module_item_list_opt
: module_item_list
|
;
generate_item_list
: generate_item_list generate_item
| generate_item
;
generate_item_list_opt
: generate_item_list
|
;
/* A generate block is the thing within a generate scheme. It may be
a single module item, an anonymous block of module items, or a
@@ -4778,24 +4966,24 @@ module_item_list_opt
only need to take note here of the scope name, if any. */
generate_block
: module_item
| K_begin module_item_list_opt K_end
| K_begin ':' IDENTIFIER module_item_list_opt K_end endlabel_opt
{ pform_generate_block_name($3);
if ($6) {
if (strcmp($3,$6) != 0) {
yyerror(@6, "error: End label doesn't match "
"begin name");
}
if (! gn_system_verilog()) {
yyerror(@6, "error: Begin end labels require "
"SystemVerilog.");
}
delete[]$6;
}
delete[]$3;
}
;
: module_item
| K_begin generate_item_list_opt K_end
| K_begin ':' IDENTIFIER generate_item_list_opt K_end endlabel_opt
{ pform_generate_block_name($3);
if ($6) {
if (strcmp($3,$6) != 0) {
yyerror(@6, "error: End label doesn't match "
"begin name");
}
if (! gn_system_verilog()) {
yyerror(@6, "error: Begin end labels require "
"SystemVerilog.");
}
delete[]$6;
}
delete[]$3;
}
;
generate_block_opt : generate_block | ';' ;
@@ -5338,6 +5526,23 @@ net_variable_list
}
;
event_variable
: IDENTIFIER dimensions_opt
{ if ($2) {
yyerror(@2, "sorry: event arrays are not supported.");
delete $2;
}
$$ = $1;
}
;
event_variable_list
: event_variable
{ $$ = list_from_identifier($1); }
| event_variable_list ',' event_variable
{ $$ = list_from_identifier($1, $3); }
;
specify_item
: K_specparam specparam_decl ';'
| specify_simple_path_decl ';'
@@ -5450,6 +5655,12 @@ specify_item_list
| specify_item_list specify_item
;
specify_item_list_opt
: /* empty */
{ }
| specify_item_list
{ }
specify_edge_path_decl
: specify_edge_path '=' '(' delay_value_list ')'
{ $$ = pform_assign_path_delay($1, $4); }
@@ -5926,7 +6137,7 @@ statement_item /* This is roughly statement_item in the LRM */
{ yyerror(@1, "error: Malformed conditional expression.");
$$ = $5;
}
/* SytemVerilog adds the compressed_statement */
/* SystemVerilog adds the compressed_statement */
| compressed_statement ';'
{ $$ = $1; }
@@ -6566,7 +6777,7 @@ udp_primitive
presence is significant. This is a fairly common pattern so
collect those rules here. */
K_automatic_opt: K_automatic { $$ = true; } | { $$ = false;} ;
K_automatic_opt: K_automatic { $$ = true; } | { $$ = false; } ;
K_packed_opt : K_packed { $$ = true; } | { $$ = false; } ;
K_reg_opt : K_reg { $$ = true; } | { $$ = false; } ;
K_static_opt : K_static { $$ = true; } | { $$ = false; } ;
+205 -55
View File
@@ -1,5 +1,5 @@
/*
* 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
@@ -29,6 +29,7 @@
# include "PPackage.h"
# include "PUdp.h"
# include "PGenerate.h"
# include "PModport.h"
# include "PSpec.h"
# include "discipline.h"
# include <list>
@@ -265,6 +266,10 @@ static unsigned scope_generate_counter = 1;
always within a module. */
static PGenerate*pform_cur_generate = 0;
/* This tracks the current modport list being processed. This is
always within an interface. */
static PModport*pform_cur_modport = 0;
static NetNet::Type pform_default_nettype = NetNet::WIRE;
/*
@@ -534,6 +539,15 @@ bool pform_in_program_block()
return false;
}
bool pform_in_interface()
{
if (pform_cur_module.empty())
return false;
if (pform_cur_module.front()->is_interface)
return true;
return false;
}
static bool pform_at_module_level()
{
return (lexical_scope == pform_cur_module.front())
@@ -579,8 +593,11 @@ PWire*pform_get_make_wire_in_scope(perm_string name, NetNet::Type net_type, NetN
return cur;
}
void pform_set_typedef(perm_string name, data_type_t*data_type)
void pform_set_typedef(perm_string name, data_type_t*data_type, std::list<pform_range_t>*unp_ranges)
{
if(unp_ranges)
data_type = new uarray_type_t(data_type, unp_ranges);
// If we are in a lexical scope (i.e. a package or module)
// then put the typedef into that scope. Otherwise, put it
// into the $root scope.
@@ -1062,6 +1079,12 @@ verinum* pform_verinum_with_size(verinum*siz, verinum*val,
assert(siz->is_defined());
unsigned long size = siz->as_ulong();
if (size == 0) {
cerr << file << ":" << lineno << ": error: Sized numeric constant "
"must have a size greater than zero." << endl;
error_count += 1;
}
verinum::V pad;
switch (val->get(val->len()-1)) {
@@ -1107,7 +1130,8 @@ verinum* pform_verinum_with_size(verinum*siz, verinum*val,
}
void pform_startmodule(const struct vlltype&loc, const char*name,
bool program_block, list<named_pexpr_t>*attr)
bool program_block, bool is_interface,
list<named_pexpr_t>*attr)
{
if (! pform_cur_module.empty() && !gn_system_verilog()) {
cerr << loc << ": error: Module definition " << name
@@ -1115,15 +1139,25 @@ void pform_startmodule(const struct vlltype&loc, const char*name,
error_count += 1;
}
if (gn_system_verilog() && ! pform_cur_module.empty() &&
pform_cur_module.front()->program_block) {
cerr << loc << ": error: Program blocks cannot contain nested modules/program blocks." << endl;
error_count += 1;
if (gn_system_verilog() && ! pform_cur_module.empty()) {
if (pform_cur_module.front()->program_block) {
cerr << loc << ": error: module, program, or interface "
"declarations are not allowed in program "
"blocks." << endl;
error_count += 1;
}
if (pform_cur_module.front()->is_interface
&& !(program_block || is_interface)) {
cerr << loc << ": error: module declarations are not "
"allowed in interfaces." << endl;
error_count += 1;
}
}
perm_string lex_name = lex_strings.make(name);
Module*cur_module = new Module(lexical_scope, lex_name);
cur_module->program_block = program_block;
cur_module->is_interface = is_interface;
/* Set the local time unit/precision to the global value. */
cur_module->time_unit = pform_time_unit;
cur_module->time_precision = pform_time_prec;
@@ -1914,7 +1948,6 @@ static void pform_set_net_range(list<perm_string>*names,
pform_set_net_range(txt, net_type, range, signed_flag, dt, SR_NET, attr);
}
delete names;
}
/*
@@ -2001,8 +2034,13 @@ void pform_makegates(const struct vlltype&loc,
{
assert(! pform_cur_module.empty());
if (pform_cur_module.front()->program_block) {
cerr << loc << ": error: Gates and switches may not be instantiated"
<< " in program blocks." << endl;
cerr << loc << ": error: Gates and switches may not be instantiated in "
<< "program blocks." << endl;
error_count += 1;
}
if (pform_cur_module.front()->is_interface) {
cerr << loc << ": error: Gates and switches may not be instantiated in "
<< "interfaces." << endl;
error_count += 1;
}
@@ -2117,8 +2155,13 @@ void pform_make_modgates(const struct vlltype&loc,
{
assert(! pform_cur_module.empty());
if (pform_cur_module.front()->program_block) {
cerr << loc << ": error: Module instantiations are not allowed"
<< " in program blocks." << endl;
cerr << loc << ": error: Module instantiations are not allowed in "
<< "program blocks." << endl;
error_count += 1;
}
if (pform_cur_module.front()->is_interface) {
cerr << loc << ": error: Module instantiations are not allowed in "
<< "interfaces." << endl;
error_count += 1;
}
@@ -2317,6 +2360,11 @@ void pform_module_define_port(const struct vlltype&li,
signed_flag = false;
prange = 0;
} else if (enum_type_t*enum_type = dynamic_cast<enum_type_t*>(vtype)) {
data_type = enum_type->base_type;
signed_flag = enum_type->signed_flag;
prange = enum_type->range.get();
} else if (vtype) {
VLerror(li, "sorry: Given type %s not supported here (%s:%d).",
typeid(*vtype).name(), __FILE__, __LINE__);
@@ -2374,7 +2422,11 @@ static PWire* pform_get_or_make_wire(const vlltype&li, perm_string name,
ivl_variable_type_t dtype)
{
PWire*cur = pform_get_wire_in_scope(name);
if (cur) {
// If the wire already exists but isn't yet fully defined,
// carry on adding details.
if (cur && (cur->get_data_type() == IVL_VT_NO_TYPE ||
cur->get_wire_type() == NetNet::IMPLICIT) ) {
// If this is not implicit ("implicit" meaning we don't
// know what the type is yet) then set the type now.
if (type != NetNet::IMPLICIT) {
@@ -2392,6 +2444,18 @@ static PWire* pform_get_or_make_wire(const vlltype&li, perm_string name,
return cur;
}
// If the wire already exists and is fully defined, this
// must be a redeclaration. Start again with a new wire.
if (cur) {
LineInfo tloc;
FILE_NAME(&tloc, li);
cerr << tloc.get_fileline() << ": error: duplicate declaration "
"for net or variable '" << name << "' in '"
<< pform_cur_module.front()->mod_name() << "'." << endl;
error_count += 1;
delete cur;
}
cur = new PWire(name, type, ptype, dtype);
FILE_NAME(cur, li.text, li.first_line);
@@ -2527,6 +2591,15 @@ void pform_makewire(const struct vlltype&li,
NetNet::Type type,
data_type_t*data_type)
{
if ((lexical_scope == 0) && (generation_flag < GN_VER2005_SV)) {
VLerror(li, "error: variable declarations must be contained within a module.");
return;
}
if (lexical_scope == 0) {
VLerror(li, "sorry: variable declarations in the $root scope are not yet supported.");
return;
}
list<perm_string>*names = new list<perm_string>;
for (list<decl_assignment_t*>::iterator cur = assign_list->begin()
@@ -2613,7 +2686,10 @@ vector<pform_tf_port_t>*pform_make_task_ports(const struct vlltype&loc,
}
curw->set_signed(signed_flag);
if (isint) assert(curw->set_wire_type(NetNet::INTEGER));
if (isint) {
bool flag = curw->set_wire_type(NetNet::INTEGER);
assert(flag);
}
/* If there is a range involved, it needs to be set. */
if (range) {
@@ -2624,7 +2700,6 @@ vector<pform_tf_port_t>*pform_make_task_ports(const struct vlltype&loc,
}
delete range;
delete names;
return res;
}
@@ -2653,7 +2728,6 @@ static vector<pform_tf_port_t>*do_make_task_ports(const struct vlltype&loc,
res->push_back(pform_tf_port_t(curw));
}
delete names;
return res;
}
@@ -2662,35 +2736,54 @@ vector<pform_tf_port_t>*pform_make_task_ports(const struct vlltype&loc,
data_type_t*vtype,
list<perm_string>*names)
{
vector<pform_tf_port_t>*ret = NULL;
std::list<pform_range_t>*unpacked_dims = NULL;
if (uarray_type_t*uarray = dynamic_cast<uarray_type_t*> (vtype)) {
unpacked_dims = uarray->dims.get();
vtype = uarray->base_type;
}
if (atom2_type_t*atype = dynamic_cast<atom2_type_t*> (vtype)) {
list<pform_range_t>*range_tmp = make_range_from_width(atype->type_code);
return pform_make_task_ports(loc, pt, IVL_VT_BOOL,
ret = pform_make_task_ports(loc, pt, IVL_VT_BOOL,
atype->signed_flag,
range_tmp, names);
}
if (vector_type_t*vec_type = dynamic_cast<vector_type_t*> (vtype)) {
return pform_make_task_ports(loc, pt, vec_type->base_type,
ret = pform_make_task_ports(loc, pt, vec_type->base_type,
vec_type->signed_flag,
copy_range(vec_type->pdims.get()),
names, vec_type->integer_flag);
}
if (/*real_type_t*real_type = */ dynamic_cast<real_type_t*> (vtype)) {
return pform_make_task_ports(loc, pt, IVL_VT_REAL,
ret = pform_make_task_ports(loc, pt, IVL_VT_REAL,
true, 0, names);
}
if (dynamic_cast<string_type_t*> (vtype)) {
return pform_make_task_ports(loc, pt, IVL_VT_STRING,
ret = pform_make_task_ports(loc, pt, IVL_VT_STRING,
false, 0, names);
}
if (class_type_t*class_type = dynamic_cast<class_type_t*> (vtype)) {
return do_make_task_ports(loc, pt, IVL_VT_CLASS, class_type, names);
ret = do_make_task_ports(loc, pt, IVL_VT_CLASS, class_type, names);
}
return do_make_task_ports(loc, pt, IVL_VT_NO_TYPE, vtype, names);
ret = do_make_task_ports(loc, pt, IVL_VT_NO_TYPE, vtype, names);
if (unpacked_dims) {
for (list<perm_string>::iterator cur = names->begin()
; cur != names->end() ; ++ cur ) {
PWire*wire = pform_get_wire_in_scope(*cur);
wire->set_unpacked_idx(*unpacked_dims);
}
}
delete names;
return ret;
}
/*
@@ -2803,6 +2896,14 @@ void pform_set_parameter(const struct vlltype&loc,
LexicalScope::range_t*value_range)
{
LexicalScope*scope = lexical_scope;
if ((scope == 0) && (generation_flag < GN_VER2005_SV)) {
VLerror(loc, "error: parameter declarations must be contained within a module.");
return;
}
if (scope == 0) {
VLerror(loc, "sorry: parameter declarations in the $root scope are not yet supported.");
return;
}
if (scope == pform_cur_generate) {
VLerror("parameter declarations are not permitted in generate blocks");
return;
@@ -2826,8 +2927,8 @@ void pform_set_parameter(const struct vlltype&loc,
error_count += 1;
}
// Only a Module scope has specparams.
if ((scope == pform_cur_module.front()) &&
(dynamic_cast<Module*> (scope)) &&
if ((dynamic_cast<Module*> (scope)) &&
(scope == pform_cur_module.front()) &&
(pform_cur_module.front()->specparams.find(name) !=
pform_cur_module.front()->specparams.end())) {
LineInfo tloc;
@@ -2860,8 +2961,8 @@ void pform_set_parameter(const struct vlltype&loc,
parm.range = value_range;
// Only a Module keeps the position of the parameter.
if ((scope == pform_cur_module.front()) &&
(dynamic_cast<Module*> (scope)))
if ((dynamic_cast<Module*> (scope)) &&
(scope == pform_cur_module.front()))
pform_cur_module.front()->param_names.push_back(name);
}
@@ -2870,7 +2971,14 @@ void pform_set_localparam(const struct vlltype&loc,
bool signed_flag, list<pform_range_t>*range, PExpr*expr)
{
LexicalScope*scope = lexical_scope;
ivl_assert(loc, scope);
if ((scope == 0) && (generation_flag < GN_VER2005_SV)) {
VLerror(loc, "error: localparam declarations must be contained within a module.");
return;
}
if (scope == 0) {
VLerror(loc, "sorry: localparam declarations in the $root scope are not yet supported.");
return;
}
// Check if the localparam name is already in the dictionary.
if (scope->localparams.find(name) != scope->localparams.end()) {
@@ -3136,7 +3244,6 @@ static void pform_set_integer_2atom(uint64_t width, bool signed_flag, list<perm_
perm_string txt = *cur;
pform_set_integer_2atom(width, signed_flag, txt, net_type, attr);
}
delete names;
}
template <class T> static void pform_set2_data_type(const struct vlltype&li, T*data_type, perm_string name, NetNet::Type net_type, list<named_pexpr_t>*attr)
@@ -3160,18 +3267,12 @@ template <class T> static void pform_set2_data_type(const struct vlltype&li, T*d
}
}
static void pform_set_enum(const struct vlltype&li, enum_type_t*enum_type,
static void pform_set_enum(enum_type_t*enum_type,
perm_string name, NetNet::Type net_type,
std::list<named_pexpr_t>*attr)
{
PWire*cur = pform_get_make_wire_in_scope(name, net_type, NetNet::NOT_A_PORT, enum_type->base_type);
// A NULL is returned for a duplicate enumeration.
if (! cur) {
cerr << li.get_fileline() << ": error: Found duplicate "
<< "enumeration named " << name << "." << endl;
error_count += 1;
return;
}
assert(cur);
cur->set_signed(enum_type->signed_flag);
@@ -3209,10 +3310,9 @@ static void pform_set_enum(const struct vlltype&li, enum_type_t*enum_type,
for (list<perm_string>::iterator cur = names->begin()
; cur != names->end() ; ++ cur) {
perm_string txt = *cur;
pform_set_enum(li, enum_type, txt, net_type, attr);
pform_set_enum(enum_type, txt, net_type, attr);
}
delete names;
}
/*
@@ -3221,58 +3321,68 @@ static void pform_set_enum(const struct vlltype&li, enum_type_t*enum_type,
*/
void pform_set_data_type(const struct vlltype&li, data_type_t*data_type, list<perm_string>*names, NetNet::Type net_type, list<named_pexpr_t>*attr)
{
const std::list<pform_range_t>*unpacked_dims = NULL;
if (data_type == 0) {
VLerror(li, "internal error: data_type==0.");
assert(0);
}
if(uarray_type_t*uarray_type = dynamic_cast<uarray_type_t*> (data_type)) {
unpacked_dims = uarray_type->dims.get();
data_type = uarray_type->base_type;
}
if (atom2_type_t*atom2_type = dynamic_cast<atom2_type_t*> (data_type)) {
pform_set_integer_2atom(atom2_type->type_code, atom2_type->signed_flag, names, net_type, attr);
return;
}
if (struct_type_t*struct_type = dynamic_cast<struct_type_t*> (data_type)) {
else if (struct_type_t*struct_type = dynamic_cast<struct_type_t*> (data_type)) {
pform_set_struct_type(struct_type, names, net_type, attr);
return;
}
if (enum_type_t*enum_type = dynamic_cast<enum_type_t*> (data_type)) {
else if (enum_type_t*enum_type = dynamic_cast<enum_type_t*> (data_type)) {
pform_set_enum(li, enum_type, names, net_type, attr);
return;
}
if (vector_type_t*vec_type = dynamic_cast<vector_type_t*> (data_type)) {
else if (vector_type_t*vec_type = dynamic_cast<vector_type_t*> (data_type)) {
if (net_type==NetNet::REG && vec_type->integer_flag)
net_type=NetNet::INTEGER;
pform_set_net_range(names, vec_type->pdims.get(),
vec_type->signed_flag,
vec_type->base_type, net_type, attr);
return;
}
if (/*real_type_t*real_type =*/ dynamic_cast<real_type_t*> (data_type)) {
else if (/*real_type_t*real_type =*/ dynamic_cast<real_type_t*> (data_type)) {
pform_set_net_range(names, 0, true, IVL_VT_REAL, net_type, attr);
return;
}
if (class_type_t*class_type = dynamic_cast<class_type_t*> (data_type)) {
else if (class_type_t*class_type = dynamic_cast<class_type_t*> (data_type)) {
pform_set_class_type(class_type, names, net_type, attr);
return;
}
if (parray_type_t*array_type = dynamic_cast<parray_type_t*> (data_type)) {
else if (parray_type_t*array_type = dynamic_cast<parray_type_t*> (data_type)) {
pform_set2_data_type(li, array_type, names, net_type, attr);
return;
}
if (string_type_t*string_type = dynamic_cast<string_type_t*> (data_type)) {
else if (string_type_t*string_type = dynamic_cast<string_type_t*> (data_type)) {
pform_set_string_type(string_type, names, net_type, attr);
return;
} else {
VLerror(li, "internal error: Unexpected data_type.");
assert(0);
}
VLerror(li, "internal error: Unexpected data_type.");
assert(0);
if(unpacked_dims) {
for (list<perm_string>::iterator cur = names->begin()
; cur != names->end() ; ++ cur ) {
PWire*wire = pform_get_wire_in_scope(*cur);
wire->set_unpacked_idx(*unpacked_dims);
}
}
delete names;
}
vector<PWire*>* pform_make_udp_input_ports(list<perm_string>*names)
@@ -3326,6 +3436,46 @@ PProcess* pform_make_behavior(ivl_process_type_t type, Statement*st,
return pp;
}
void pform_start_modport_item(const struct vlltype&loc, const char*name)
{
Module*scope = pform_cur_module.front();
ivl_assert(loc, scope && scope->is_interface);
ivl_assert(loc, pform_cur_modport == 0);
perm_string use_name = lex_strings.make(name);
pform_cur_modport = new PModport(use_name);
FILE_NAME(pform_cur_modport, loc);
if (scope->modports.find(use_name) != scope->modports.end()) {
cerr << loc << ": error: duplicate declaration for modport '"
<< name << "' in '" << scope->mod_name() << "'." << endl;
error_count += 1;
}
scope->modports[use_name] = pform_cur_modport;
delete[] name;
}
void pform_end_modport_item(const struct vlltype&loc)
{
ivl_assert(loc, pform_cur_modport);
pform_cur_modport = 0;
}
void pform_add_modport_port(const struct vlltype&loc,
NetNet::PortType port_type,
perm_string name, PExpr*expr)
{
ivl_assert(loc, pform_cur_modport);
if (pform_cur_modport->simple_ports.find(name)
!= pform_cur_modport->simple_ports.end()) {
cerr << loc << ": error: duplicate declaration of port '"
<< name << "' in modport list '"
<< pform_cur_modport->name() << "'." << endl;
error_count += 1;
}
pform_cur_modport->simple_ports[name] = make_pair(port_type, expr);
}
FILE*vl_input = 0;
extern void reset_lexor();
+21 -5
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-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
@@ -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,12 +156,14 @@ 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,
list<named_pexpr_t>*attr);
extern void pform_check_timeunit_prec();
extern void pform_module_set_ports(vector<Module::port_t*>*);
@@ -213,6 +219,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.
@@ -272,7 +287,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
+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)
+1 -1
View File
@@ -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:
*
+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
@@ -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);
+122 -57
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);
@@ -531,18 +563,24 @@ bool NetCase::synth_async(Design*des, NetScope*scope,
statement_map[sel_idx] = items_[item].statement;
}
// The mux_size is the number of inputs that are selected.
unsigned mux_size = max_guard_value + 1;
unsigned sel_need = ceil(log2(mux_size));
// The minimum selector width is the number of inputs that
// are selected, rounded up to the nearest power of 2.
unsigned sel_need = ceil(log2(max_guard_value + 1));
// If the sel_width can select more than just the explicit
// guard values, and there is a default statement, then adjust
// the mux size to allow for the implicit selections.
if (statement_default && (sel_width > sel_need)) {
// the sel_need to allow for the implicit selections.
if (statement_default && (sel_width > sel_need))
sel_need += 1;
ivl_assert(*this, sel_need < sizeof mux_size);
mux_size = 1<<sel_need;
// 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: "
@@ -746,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;
@@ -782,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));
@@ -829,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));
@@ -1105,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));
@@ -1115,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));
}
@@ -1122,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));
}
@@ -1132,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));
@@ -1159,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));
}
@@ -1308,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);
@@ -1341,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)
{
@@ -1366,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
@@ -1385,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;
@@ -1422,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)
{
@@ -1470,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());
@@ -1500,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));
}
@@ -1670,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)
{
@@ -1747,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: "
@@ -1758,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;
@@ -1780,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
@@ -1789,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(),
@@ -1813,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) {
@@ -1832,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
+6 -5
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
@@ -36,7 +36,7 @@
static const char*version_string =
"Icarus Verilog STUB 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"
@@ -380,7 +380,7 @@ static void show_lpm_divide(ivl_lpm_t net)
*/
static void show_lpm_cmp_eeq(ivl_lpm_t net)
{
const char*str;
const char*str = 0;
switch (ivl_lpm_type(net)) {
case IVL_LPM_CMP_EEQ:
str = "EEQ";
@@ -497,10 +497,11 @@ static void show_lpm_concat(ivl_lpm_t net)
static void show_lpm_ff(ivl_lpm_t net)
{
ivl_nexus_t nex;
char*edge = ivl_lpm_negedge(net) ? "negedge" : "posedge";
unsigned width = ivl_lpm_width(net);
fprintf(out, " LPM_FF %s: <width=%u>\n",
ivl_lpm_basename(net), width);
fprintf(out, " LPM_FF %s: <polarity=%s> <width=%u>\n",
ivl_lpm_basename(net), edge, width);
nex = ivl_lpm_clk(net);
fprintf(out, " clk: %p\n", nex);
+56 -14
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2011-2014 Cary R. (cygcary@yahoo.com)
* Copyright (C) 2011-2015 Cary R. (cygcary@yahoo.com)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -1245,7 +1245,43 @@ static void emit_posedge_dff_prim(void)
fprintf(vlog_out, "endprimitive\n");
}
static void emit_negedge_dff_prim(void)
{
fprintf(vlog_out, "\n");
fprintf(vlog_out, "/* Icarus generated UDP to represent a synthesized "
"negative edge D-FF. */\n");
fprintf(vlog_out, "primitive IVL_negedge_DFF "
"(q, clk, en, d, clr, set);\n");
fprintf(vlog_out, "%*coutput q;\n", indent_incr, ' ');
fprintf(vlog_out, "%*cinput clk, en, d, clr, set;\n", indent_incr, ' ');
fprintf(vlog_out, "%*creg q;\n", indent_incr, ' ');
fprintf(vlog_out, "%*ctable\n", indent_incr, ' ');
fprintf(vlog_out, "%*cf 1 0 0 0 : ? : 0 ;\n", 2*indent_incr, ' ');
fprintf(vlog_out, "%*cf 1 1 0 0 : ? : 1 ;\n", 2*indent_incr, ' ');
fprintf(vlog_out, "%*cn 1 0 0 0 : 0 : - ;\n", 2*indent_incr, ' ');
fprintf(vlog_out, "%*cn 1 1 0 0 : 1 : - ;\n", 2*indent_incr, ' ');
fprintf(vlog_out, "%*cn x 0 0 0 : 0 : - ;\n", 2*indent_incr, ' ');
fprintf(vlog_out, "%*cn x 1 0 0 : 1 : - ;\n", 2*indent_incr, ' ');
fprintf(vlog_out, "%*cp ? ? 0 0 : ? : - ;\n", 2*indent_incr, ' ');
fprintf(vlog_out, "%*c* 0 ? 0 0 : ? : - ;\n", 2*indent_incr, ' ');
fprintf(vlog_out, "%*c? * ? ? ? : ? : - ;\n", 2*indent_incr, ' ');
fprintf(vlog_out, "%*c? ? * ? ? : ? : - ;\n", 2*indent_incr, ' ');
fprintf(vlog_out, "%*c? ? ? * ? : ? : - ;\n", 2*indent_incr, ' ');
fprintf(vlog_out, "%*c? ? ? ? * : ? : - ;\n", 2*indent_incr, ' ');
fprintf(vlog_out, "%*c? ? ? 0 1 : ? : 1 ;\n", 2*indent_incr, ' ');
fprintf(vlog_out, "%*c? ? ? 0 x : 1 : - ;\n", 2*indent_incr, ' ');
fprintf(vlog_out, "%*c? ? ? 0 x : 0 : x ;\n", 2*indent_incr, ' ');
fprintf(vlog_out, "%*c? ? ? 1 ? : ? : 0 ;\n", 2*indent_incr, ' ');
fprintf(vlog_out, "%*c? ? ? x 0 : 0 : - ;\n", 2*indent_incr, ' ');
fprintf(vlog_out, "%*c? ? ? x 0 : 1 : x ;\n", 2*indent_incr, ' ');
fprintf(vlog_out, "%*c? ? ? x x : ? : x ;\n", 2*indent_incr, ' ');
fprintf(vlog_out, "%*c? ? ? x 1 : ? : x ;\n", 2*indent_incr, ' ');
fprintf(vlog_out, "%*cendtable\n", indent_incr, ' ');
fprintf(vlog_out, "endprimitive\n");
}
static unsigned need_posedge_dff_prim = 0;
static unsigned need_negedge_dff_prim = 0;
/*
* Synthesis creates a D-FF LPM object. To allow this to be simulated as
@@ -1263,14 +1299,14 @@ void emit_icarus_generated_udps()
{
/* Emit the copyright information and LGPL note and then emit any
* needed primitives. */
if (need_posedge_dff_prim) {
if (need_posedge_dff_prim || need_negedge_dff_prim) {
fprintf(vlog_out,
"\n"
"/*\n"
" * This is the copyright information for the following primitive(s)\n"
" * (library elements).\n"
" *\n"
" * Copyright (C) 2011 Cary R. ([email protected])\n"
" * Copyright (C) 2011-2015 Cary R. ([email protected])\n"
" *\n"
" * This library is free software; you can redistribute it and/or\n"
" * modify it under the terms of the GNU Lesser General Public\n"
@@ -1290,13 +1326,12 @@ void emit_icarus_generated_udps()
"NOTE: vlog95: Adding LGPL 2.1 primitive(s) at the end of the output file.\n");
}
if (need_posedge_dff_prim) emit_posedge_dff_prim();
if (need_negedge_dff_prim) emit_negedge_dff_prim();
}
static void emit_lpm_ff(ivl_scope_t scope, ivl_lpm_t lpm)
{
// HERE: No support for lpm attributes and hence polarity information.
// ivl_attribute_t clock_pol = find_lpm_attr(lpm, "Clock:LPM_Polarity");
ivl_attribute_t clock_pol = 0;
unsigned negedge = ivl_lpm_negedge(lpm);
ivl_expr_t aset_expr = ivl_lpm_aset_value(lpm);
ivl_expr_t sset_expr = ivl_lpm_sset_value(lpm);
ivl_nexus_t nex;
@@ -1305,7 +1340,13 @@ static void emit_lpm_ff(ivl_scope_t scope, ivl_lpm_t lpm)
const char *sset_bits = 0;
/* For now we only support a width of 1 for these bits. */
if (aset_expr) {
assert(ivl_expr_width(aset_expr) == 1);
if (ivl_expr_width(aset_expr) != 1) {
fprintf(stderr, "%s:%u: vlog95 sorry: FF LPMs with "
"multi-bit asynchronous set values are not "
"currently translated.\n",
ivl_lpm_file(lpm), ivl_lpm_lineno(lpm));
vlog_errors += 1;
}
aset_bits = ivl_expr_bits(aset_expr);
}
if (sset_expr) {
@@ -1314,9 +1355,7 @@ static void emit_lpm_ff(ivl_scope_t scope, ivl_lpm_t lpm)
}
fprintf(vlog_out, "%*c", indent, ' ');
/* If there is a clock polarity attribute then we have a negative
* edge D-FF. */
if (clock_pol) {
if (negedge) {
fprintf(vlog_out, "IVL_negedge_DFF");
} else {
fprintf(vlog_out, "IVL_posedge_DFF");
@@ -1368,7 +1407,7 @@ static void emit_lpm_ff(ivl_scope_t scope, ivl_lpm_t lpm)
}
nex = ivl_lpm_sync_set(lpm);
if (nex) {
if (! sset_bits || (sset_bits && (sset_bits[0] == '1'))) {
if (! sset_bits || (sset_bits[0] == '1')) {
emit_nexus_as_ca(scope, nex, 0, 0);
if (have_data) fprintf(vlog_out, " | ");
} else {
@@ -1404,7 +1443,10 @@ static void emit_lpm_ff(ivl_scope_t scope, ivl_lpm_t lpm)
else fprintf(vlog_out, "1'b0");
fprintf(vlog_out, ");\n");
/* We need to emit a primitive for this instance. */
need_posedge_dff_prim = 1;
if (negedge)
need_negedge_dff_prim = 1;
else
need_posedge_dff_prim = 1;
}
static ivl_signal_t get_output_from_nexus(ivl_scope_t scope, ivl_nexus_t nex,
@@ -1900,7 +1942,7 @@ void emit_signal_net_const_as_ca(ivl_scope_t scope, ivl_signal_t sig)
{
ivl_nexus_t nex = ivl_signal_nex(sig, 0);
unsigned idx, count = ivl_nexus_ptrs(nex);
unsigned long emitted = (unsigned long) ivl_nexus_get_private(nex);
unsigned long emitted = (uintptr_t) ivl_nexus_get_private(nex);
for (idx = 0; idx < count; idx += 1) {
ivl_nexus_ptr_t nex_ptr = ivl_nexus_ptr(nex, idx);
ivl_net_const_t net_const = ivl_nexus_ptr_con(nex_ptr);
@@ -1930,7 +1972,7 @@ void emit_signal_net_const_as_ca(ivl_scope_t scope, ivl_signal_t sig)
fprintf(vlog_out, "\n");
/* Increment the emitted constant count by one. */
ivl_nexus_set_private(nex,
(void *) ((unsigned long) ivl_nexus_get_private(nex) + 1U));
(void *) ((uintptr_t) ivl_nexus_get_private(nex) + 1U));
return;
}
/* We must find the constant in the nexus. */
+13 -3
View File
@@ -78,6 +78,7 @@ static void emit_bits(const char *bits, unsigned nbits, unsigned is_signed)
{
unsigned has_undef = 0;
assert(nbits > 0);
/* Check for an undefined bit. */
for (int idx = (int)nbits-1; idx >= 0; idx -= 1) {
if ((bits[idx] != '0') && (bits[idx] != '1')) {
@@ -91,8 +92,14 @@ static void emit_bits(const char *bits, unsigned nbits, unsigned is_signed)
/* Emit as a binary constant. */
if (has_undef || (nbits < 2)) {
int start = nbits - 1;
char sbit = bits[start];
/* Trim extra leading bits. */
if (! is_signed && (sbit == '1')) sbit = ' ';
while (start && (sbit == bits[start-1])) start -= 1;
/* Print the trimmed value. */
fprintf(vlog_out, "b");
for (int idx = (int)nbits-1; idx >= 0; idx -= 1) {
for (int idx = start; idx >= 0; idx -= 1) {
fprintf(vlog_out, "%c", bits[idx]);
}
/* Emit as a hex constant. */
@@ -152,9 +159,12 @@ void emit_number(const char *bits, unsigned nbits, unsigned is_signed,
vlog_errors += 1;
return;
} else if (rtype == -2) {
fprintf(vlog_out, "'bz");
fprintf(vlog_out, "%u'bz", nbits);
} else if (rtype == -3) {
fprintf(vlog_out, "'bx");
/* If this is a 32-bit wide constant then generate the
* undefined with integers to get a signed value. */
if (nbits == 32) fprintf(vlog_out, "1/0");
else fprintf(vlog_out, "%u'bx", nbits);
} else {
fprintf(vlog_out, "%"PRId32, value);
}
+6 -3
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2010-2014 Cary R. (cygcary@yahoo.com)
* Copyright (C) 2010-2015 Cary R. (cygcary@yahoo.com)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -432,10 +432,13 @@ static void emit_sig_type(ivl_signal_t sig)
}
/* Check to see if we have a variable (reg) or a net. */
if (type == IVL_SIT_REG) {
/* The variable data type will be declared later, so here
we just want to declare the range and whether or not it
is signed. */
if (ivl_signal_integer(sig)) {
fprintf(vlog_out, " integer");
/* nothing to do */
} else if (ivl_signal_data_type(sig) == IVL_VT_REAL) {
fprintf(vlog_out, " real");
/* nothing to do */
} else {
int msb, lsb;
get_sig_msb_lsb(sig, &msb, &lsb);
+1 -1
View File
@@ -942,7 +942,7 @@ static void emit_stmt_block_named(ivl_scope_t scope, ivl_statement_t stmt)
static void emit_stmt_case(ivl_scope_t scope, ivl_statement_t stmt)
{
const char *case_type;
const char *case_type = 0;
unsigned idx, default_case, count = ivl_stmt_case_count(stmt);
switch (ivl_statement_type(stmt)) {
case IVL_ST_CASE:
+2 -2
View File
@@ -30,7 +30,7 @@
static const char*version_string =
"Icarus Verilog VLOG95 Code Generator " VERSION " (" VERSION_TAG ")\n\n"
"Copyright (C) 2010-2013 Cary R. ([email protected])\n\n"
"Copyright (C) 2010-2015 Cary R. ([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"
@@ -208,7 +208,7 @@ int target_design(ivl_design_t des)
assert(indent == 0);
fprintf(vlog_out, "endmodule /* ivl_root_scope */\n");
}
/* Emit the rest of the scope objets. */
/* Emit the rest of the scope objects. */
for (idx = 0; idx < nroots; idx += 1) emit_scope(roots[idx], 0);
free_emitted_scope_list();
+2 -2
View File
@@ -3,7 +3,7 @@ THE VVP TARGET
SYMBOL NAME CONVENTIONS
There are some naming conventions that the vp target uses for
There are some naming conventions that the vvp target uses for
generating symbol names.
* wires and regs
@@ -30,4 +30,4 @@ the drivers are first fed into a resolver (or a tree of resolvers) to
form a single output that is the nexus.
The nexus, then, feeds its output to the inputs of other gates, or to
the .net objects in the design.
the .net objects in the design.
+2 -2
View File
@@ -2,7 +2,7 @@
// are not used here.
// target_design()
unusedFunction:vvp.c:89
unusedFunction:vvp.c:149
// target_query()
unusedFunction:vvp.c:184
unusedFunction:vvp.c:246
+12 -16
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2012 Stephen Williams (steve@icarus.com)
* Copyright (c) 2001-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
@@ -26,10 +26,6 @@
# include <assert.h>
# include "ivl_alloc.h"
#ifdef __MINGW32__ /* MinGW has inconsistent %p output. */
#define snprintf _snprintf
#endif
static ivl_signal_type_t signal_type_of_nexus(ivl_nexus_t nex)
{
unsigned idx;
@@ -703,11 +699,12 @@ static void draw_net_input_x(ivl_nexus_t nex,
/* If the nexus has no drivers, then send a constant HiZ or
0.0 into the net. */
if (ndrivers == 0) {
unsigned wid = width_of_nexus(nex);
/* For real nets put 0.0. */
if (signal_data_type_of_nexus(nex) == IVL_VT_REAL) {
nex_private = draw_Cr_to_string(0.0);
} else {
unsigned jdx, wid = width_of_nexus(nex);
unsigned jdx;
char*tmp = malloc(wid + 5);
nex_private = tmp;
strcpy(tmp, "C4<");
@@ -731,18 +728,17 @@ static void draw_net_input_x(ivl_nexus_t nex,
}
*tmp++ = '>';
*tmp = 0;
/* Create an "open" driver to hold the HiZ. We
need to do this so that .nets have something to
hang onto. */
char buf[64];
snprintf(buf, sizeof buf, "o%p", nex);
fprintf(vvp_out, "%s .functor BUFZ %u, %s; HiZ drive\n",
buf, wid, nex_private);
nex_private = realloc(nex_private, strlen(buf)+1);
strcpy(nex_private, buf);
}
/* Create an "open" driver to hold the HiZ or 0.0. We need
to do this so that .nets have something to hang onto. */
char buf[64];
snprintf(buf, sizeof buf, "o%p", nex);
fprintf(vvp_out, "%s .functor BUFZ %u, %s; HiZ drive\n",
buf, wid, nex_private);
nex_private = realloc(nex_private, strlen(buf)+1);
strcpy(nex_private, buf);
if (island) {
char*tmp2 = draw_island_port(island, island_input_flag, nex, nex_data, nex_private);
free(nex_private);
+46 -37
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2005-2011 Stephen Williams (steve@icarus.com)
* Copyright (c) 2005-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
@@ -36,7 +36,6 @@ static void function_argument_logic(ivl_signal_t port, ivl_expr_t expr)
if (ewidth < pwidth)
fprintf(vvp_out, " %%pad/u %u;\n", pwidth);
fprintf(vvp_out, " %%store/vec4 v%p_0, 0, %u;\n", port, pwidth);
}
static void function_argument_real(ivl_signal_t port, ivl_expr_t expr)
@@ -45,54 +44,57 @@ static void function_argument_real(ivl_signal_t port, ivl_expr_t expr)
assert(ivl_signal_dimensions(port) == 0);
draw_eval_real(expr);
fprintf(vvp_out, " %%store/real v%p_0;\n", port);
}
static void function_argument_bool(ivl_signal_t port, ivl_expr_t expr)
{
/* For now, treat bit2 variables as bit4 variables. */
function_argument_logic(port, expr);
}
static void function_argument_class(ivl_signal_t port, ivl_expr_t expr)
{
draw_eval_object(expr);
fprintf(vvp_out, " %%store/obj v%p_0;\n", port);
}
static void function_argument_darray(ivl_signal_t port, ivl_expr_t expr)
{
draw_eval_object(expr);
fprintf(vvp_out, " %%store/obj v%p_0;\n", port);
}
static void function_argument_string(ivl_signal_t port, ivl_expr_t expr)
{
draw_eval_string(expr);
fprintf(vvp_out, " %%store/str v%p_0;\n", port);
}
static void draw_function_argument(ivl_signal_t port, ivl_expr_t expr)
static void draw_eval_function_argument(ivl_signal_t port, ivl_expr_t expr)
{
ivl_variable_type_t dtype = ivl_signal_data_type(port);
switch (dtype) {
case IVL_VT_BOOL:
/* For now, treat bit2 variables as bit4 variables. */
case IVL_VT_LOGIC:
function_argument_logic(port, expr);
break;
case IVL_VT_REAL:
function_argument_real(port, expr);
break;
case IVL_VT_BOOL:
function_argument_bool(port, expr);
break;
case IVL_VT_CLASS:
function_argument_class(port, expr);
vvp_errors += draw_eval_object(expr);
break;
case IVL_VT_STRING:
function_argument_string(port, expr);
draw_eval_string(expr);
break;
case IVL_VT_DARRAY:
function_argument_darray(port, expr);
vvp_errors += draw_eval_object(expr);
break;
default:
fprintf(stderr, "XXXX function argument %s type=%d?!\n",
ivl_signal_basename(port), dtype);
assert(0);
}
}
static void draw_send_function_argument(ivl_signal_t port)
{
ivl_variable_type_t dtype = ivl_signal_data_type(port);
switch (dtype) {
case IVL_VT_BOOL:
/* For now, treat bit2 variables as bit4 variables. */
case IVL_VT_LOGIC:
fprintf(vvp_out, " %%store/vec4 v%p_0, 0, %u;\n",
port, ivl_signal_width(port));
break;
case IVL_VT_REAL:
fprintf(vvp_out, " %%store/real v%p_0;\n", port);
break;
case IVL_VT_CLASS:
fprintf(vvp_out, " %%store/obj v%p_0;\n", port);
break;
case IVL_VT_STRING:
fprintf(vvp_out, " %%store/str v%p_0;\n", port);
break;
case IVL_VT_DARRAY:
fprintf(vvp_out, " %%store/obj v%p_0;\n", port);
break;
default:
fprintf(stderr, "XXXX function argument %s type=%d?!\n",
@@ -111,13 +113,20 @@ static void draw_ufunc_preamble(ivl_expr_t expr)
fprintf(vvp_out, " %%alloc S_%p;\n", def);
}
/* evaluate the expressions and send the results to the
function ports. */
/* Evaluate the expressions and send the results to the
function ports. Do this in two passes - evaluate,
then send - this avoids the function input variables
being overwritten if the same (non-automatic) function
is called in one of the expressions. */
assert(ivl_expr_parms(expr) == (ivl_scope_ports(def)-1));
for (idx = 0 ; idx < ivl_expr_parms(expr) ; idx += 1) {
ivl_signal_t port = ivl_scope_port(def, idx+1);
draw_function_argument(port, ivl_expr_parm(expr, idx));
draw_eval_function_argument(port, ivl_expr_parm(expr, idx));
}
for (idx = ivl_expr_parms(expr) ; idx > 0 ; idx -= 1) {
ivl_signal_t port = ivl_scope_port(def, idx);
draw_send_function_argument(port);
}
/* Call the function */
-4
View File
@@ -23,10 +23,6 @@
# include <assert.h>
# include "ivl_alloc.h"
#ifdef __MINGW32__ /* MinGW has inconsistent %p output. */
#define snprintf _snprintf
#endif
struct args_info {
char*text;
/* True ('s' or 'u' if this argument is a calculated vec4. */
+3 -3
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2014 Stephen Williams (steve@icarus.com)
* Copyright (c) 2014-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
@@ -76,8 +76,8 @@ static int draw_condition_binary_compare(ivl_expr_t expr)
%cmp instruction. */
if (ivl_expr_width(le)==use_wid && test_immediate_vec4_ok(le)) {
ivl_expr_t tmp = le;
re = le;
le = tmp;
le = re;
re = tmp;
}
draw_eval_vec4(le);
+27 -12
View File
@@ -1,5 +1,5 @@
/*
* 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
@@ -28,7 +28,6 @@ static int eval_darray_new(ivl_expr_t ex)
ivl_expr_t size_expr = ivl_expr_oper1(ex);
ivl_expr_t init_expr = ivl_expr_oper2(ex);
draw_eval_expr_into_integer(size_expr, size_reg);
clr_word(size_reg);
// The new function has a net_type that contains the details
// of the type.
@@ -39,6 +38,7 @@ static int eval_darray_new(ivl_expr_t ex)
assert(element_type);
switch (ivl_type_base(element_type)) {
int msb, lsb, wid;
case IVL_VT_REAL:
// REAL objects are not packable.
assert(ivl_type_packed_dimensions(element_type) == 0);
@@ -53,19 +53,30 @@ static int eval_darray_new(ivl_expr_t ex)
// bool objects are vectorable, but for now only support
// a single dimensions.
assert(ivl_type_packed_dimensions(element_type) == 1);
int msb = ivl_type_packed_msb(element_type, 0);
int lsb = ivl_type_packed_lsb(element_type, 0);
int wid = msb>=lsb? msb - lsb : lsb - msb;
msb = ivl_type_packed_msb(element_type, 0);
lsb = ivl_type_packed_lsb(element_type, 0);
wid = msb>=lsb? msb - lsb : lsb - msb;
wid += 1;
fprintf(vvp_out, " %%new/darray %u, \"%sb%d\";\n", size_reg,
ivl_type_signed(element_type) ? "s" : "", wid);
break;
case IVL_VT_LOGIC:
// logic objects are vectorable, but for now only support
// a single dimensions.
assert(ivl_type_packed_dimensions(element_type) == 1);
msb = ivl_type_packed_msb(element_type, 0);
lsb = ivl_type_packed_lsb(element_type, 0);
wid = msb>=lsb? msb - lsb : lsb - msb;
wid += 1;
fprintf(vvp_out, " %%new/darray %u, \"%sv%d\";\n", size_reg,
ivl_type_signed(element_type) ? "s" : "", wid);
break;
default:
assert(0);
break;
}
clr_word(size_reg);
if (init_expr && ivl_expr_type(init_expr)==IVL_EX_ARRAY_PATTERN) {
unsigned idx;
@@ -109,12 +120,15 @@ static int eval_darray_new(ivl_expr_t ex)
unsigned wid;
switch (ivl_type_base(element_type)) {
case IVL_VT_BOOL:
case IVL_VT_LOGIC:
wid = width_of_packed_type(element_type);
draw_eval_vec4(init_expr);
resize_vec4_wid(init_expr, wid);
for (idx = 0 ; idx < cnt ; idx += 1) {
fprintf(vvp_out, " %%ix/load 3, %ld, 0;\n", idx);
draw_eval_vec4(init_expr);
fprintf(vvp_out, " %%parti/%c %u, %ld, 6;\n",
ivl_expr_signed(init_expr) ? 's' : 'u', wid, idx * wid);
fprintf(vvp_out, " %%ix/load 3, %ld, 0;\n", cnt - idx - 1);
fprintf(vvp_out, " %%set/dar/obj/vec4 3;\n");
fprintf(vvp_out, " %%pop/vec4 1;\n");
}
break;
case IVL_VT_REAL:
@@ -187,11 +201,12 @@ static int eval_object_property(ivl_expr_t expr)
static int eval_object_shallowcopy(ivl_expr_t ex)
{
int errors = 0;
ivl_expr_t dest = ivl_expr_oper1(ex);
ivl_expr_t src = ivl_expr_oper2(ex);
draw_eval_object(dest);
draw_eval_object(src);
errors += draw_eval_object(dest);
errors += draw_eval_object(src);
/* The %scopy opcode pops the top of the object stack as the
source object, and shallow-copies it to the new top, the
@@ -199,7 +214,7 @@ static int eval_object_shallowcopy(ivl_expr_t ex)
the stack. */
fprintf(vvp_out, " %%scopy;\n");
return 0;
return errors;
}
static int eval_object_signal(ivl_expr_t expr)
+33 -15
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
@@ -415,7 +415,7 @@ static void draw_binary_vec4_land(ivl_expr_t expr)
fprintf(vvp_out, " %%or/r;\n");
/* Now push the right expression. Again, reduce to a single
bit if necessasry. */
bit if necessary. */
draw_eval_vec4(re);
if (ivl_expr_width(re) > 1)
fprintf(vvp_out, " %%or/r;\n");
@@ -615,7 +615,7 @@ static void draw_binary_vec4_lor(ivl_expr_t expr)
fprintf(vvp_out, " %%or/r;\n");
/* Now push the right expression. Again, reduce to a single
bit if necessasry. */
bit if necessary. */
draw_eval_vec4(re);
if (ivl_expr_width(re) > 1)
fprintf(vvp_out, " %%or/r;\n");
@@ -643,16 +643,16 @@ static void draw_binary_vec4_lrs(ivl_expr_t expr)
// the stack and replace it with the result of the shift.
switch (ivl_expr_opcode(expr)) {
case 'l': /* << */
fprintf(vvp_out, " %%shiftl %u;\n", use_index_reg);
fprintf(vvp_out, " %%shiftl %d;\n", use_index_reg);
break;
case 'r': /* >> */
fprintf(vvp_out, " %%shiftr %u;\n", use_index_reg);
fprintf(vvp_out, " %%shiftr %d;\n", use_index_reg);
break;
case 'R': /* >>> */
if (ivl_expr_signed(le))
fprintf(vvp_out, " %%shiftr/s %u;\n", use_index_reg);
fprintf(vvp_out, " %%shiftr/s %d;\n", use_index_reg);
else
fprintf(vvp_out, " %%shiftr %u;\n", use_index_reg);
fprintf(vvp_out, " %%shiftr %d;\n", use_index_reg);
break;
default:
assert(0);
@@ -790,10 +790,10 @@ static void draw_concat_number_vec4(ivl_expr_t expr, int as_concati)
if (accum) {
if (count_pushi) {
fprintf(vvp_out, " %%concati/vec4 %lu, %lu, %u;\n",
fprintf(vvp_out, " %%concati/vec4 %lu, %lu, %d;\n",
val0, valx, accum);
} else {
fprintf(vvp_out, " %%pushi/vec4 %lu, %lu, %u;\n",
fprintf(vvp_out, " %%pushi/vec4 %lu, %lu, %d;\n",
val0, valx, accum);
}
}
@@ -807,16 +807,27 @@ static void draw_concat_vec4(ivl_expr_t expr)
/* This is the number of expressions that go into the
concatenation. */
unsigned num_sube = ivl_expr_parms(expr);
unsigned sub_idx;
unsigned sub_idx = 0;
ivl_expr_t sube;
assert(num_sube > 0);
/* Start with the most-significant bits. */
draw_eval_vec4(ivl_expr_parm(expr, 0));
sube = ivl_expr_parm(expr, sub_idx);
draw_eval_vec4(sube);
/* Evaluate, but skip any zero replication expressions at the
* head of this concatenation. */
while ((ivl_expr_type(sube) == IVL_EX_CONCAT) &&
(ivl_expr_repeat(sube) == 0)) {
fprintf(vvp_out, " %%pop/vec4 1; skip zero replication\n");
sub_idx += 1;
sube = ivl_expr_parm(expr, sub_idx);
draw_eval_vec4(sube);
}
for (sub_idx = 1 ; sub_idx < num_sube ; sub_idx += 1) {
for ( sub_idx += 1 ; sub_idx < num_sube ; sub_idx += 1) {
/* Concatenate progressively lower parts. */
ivl_expr_t sube = ivl_expr_parm(expr, sub_idx);
sube = ivl_expr_parm(expr, sub_idx);
/* Special case: The next expression is a NUMBER that
can be concatenated using %concati/vec4
@@ -827,6 +838,13 @@ static void draw_concat_vec4(ivl_expr_t expr)
}
draw_eval_vec4(sube);
/* Evaluate, but skip any zero replication expressions in the
* rest of this concatenation. */
if ((ivl_expr_type(sube) == IVL_EX_CONCAT) &&
(ivl_expr_repeat(sube) == 0)) {
fprintf(vvp_out, " %%pop/vec4 1; skip zero replication\n");
continue;
}
fprintf(vvp_out, " %%concat/vec4; draw_concat_vec4\n");
}
@@ -934,7 +952,7 @@ static void draw_select_pad_vec4(ivl_expr_t expr)
}
/*
* This function handles the speical case of a call to the internal
* This function handles the special case of a call to the internal
* functions $ivl_darray_method$pop_back et al. The first (and only)
* argument is the signal that represents a dynamic queue. Generate a
* %qpop instruction to pop a value and push it to the vec4 stack.
@@ -1014,7 +1032,7 @@ static void draw_string_vec4(ivl_expr_t expr)
for (unsigned idx = 0 ; idx < wid ; idx += 8) {
tmp <<= 8;
tmp |= *p;
tmp |= (unsigned long)*p;
p += 1;
tmp_wid += 8;
if (tmp_wid == 32) {
-4
View File
@@ -23,10 +23,6 @@
# include <assert.h>
# include "ivl_alloc.h"
#ifdef __MINGW32__ /* MinGW has inconsistent %p output. */
#define snprintf _snprintf
#endif
static ivl_signal_t find_path_source_port(ivl_delaypath_t path)
{
unsigned idx;
+33 -16
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2011-2014 Stephen Williams (steve@icarus.com)
* Copyright (c) 2011-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
@@ -22,11 +22,6 @@
# include <assert.h>
# include <stdlib.h>
#ifdef __MINGW32__ /* MinGW has inconsistent %p output. */
#define snprintf _snprintf
#endif
/*
* These functions handle the blocking assignment. Use the %set
* instruction to perform the actual assignment, and calculate any
@@ -143,7 +138,7 @@ static void get_vec_from_lval_slice(ivl_lval_t lval, struct vec_slice_info*slice
draw_eval_vec4(part_off_ex);
fprintf(vvp_out, " %%flag_mov %u, 4;\n", slice->u_.part_select_dynamic.x_flag);
fprintf(vvp_out, " %%dup/vec4;\n");
fprintf(vvp_out, " %%ix/vec4 %u;\n", slice->u_.part_select_dynamic.word_idx_reg);
fprintf(vvp_out, " %%ix/vec4 %d;\n", slice->u_.part_select_dynamic.word_idx_reg);
fprintf(vvp_out, " %%part/u %u;\n", wid);
} else if (ivl_signal_dimensions(sig) > 0 && word_ix == 0) {
@@ -167,7 +162,7 @@ static void get_vec_from_lval_slice(ivl_lval_t lval, struct vec_slice_info*slice
slice->u_.memory_word_dynamic.x_flag = allocate_flag();
draw_eval_expr_into_integer(word_ix, slice->u_.memory_word_dynamic.word_idx_reg);
fprintf(vvp_out, " %%flag_mov %d, 4;\n", slice->u_.memory_word_dynamic.x_flag);
fprintf(vvp_out, " %%flag_mov %u, 4;\n", slice->u_.memory_word_dynamic.x_flag);
fprintf(vvp_out, " %%load/vec4a v%p, %d;\n", sig, slice->u_.memory_word_dynamic.word_idx_reg);
} else {
@@ -263,7 +258,7 @@ static void put_vec_to_lval_slice(ivl_lval_t lval, struct vec_slice_info*slice,
break;
case SLICE_MEMORY_WORD_DYNAMIC:
fprintf(vvp_out, " %%flag_mov 4, %d;\n", slice->u_.memory_word_dynamic.x_flag);
fprintf(vvp_out, " %%flag_mov 4, %u;\n", slice->u_.memory_word_dynamic.x_flag);
fprintf(vvp_out, " %%store/vec4a v%p, %d, 0;\n", sig, slice->u_.memory_word_dynamic.word_idx_reg);
clr_word(slice->u_.memory_word_dynamic.word_idx_reg);
clr_flag(slice->u_.memory_word_dynamic.x_flag);
@@ -381,7 +376,7 @@ static void store_vec4_to_lval(ivl_statement_t net)
/* Note that flag4 is set by the eval above. */
assert(lsig);
if (ivl_signal_type(lsig)==IVL_SIT_UWIRE) {
fprintf(vvp_out, " %%force/vec4/off v%p_0, %u;\n",
fprintf(vvp_out, " %%force/vec4/off v%p_0, %d;\n",
lsig, offset_index);
} else {
fprintf(vvp_out, " %%store/vec4 v%p_0, %d, %u;\n",
@@ -397,7 +392,7 @@ static void store_vec4_to_lval(ivl_statement_t net)
assert(!lsig);
ivl_type_t sub_type = draw_lval_expr(nest);
assert(ivl_type_base(sub_type) == IVL_VT_CLASS);
fprintf(vvp_out, " %%store/prop/v %u, %u;\n",
fprintf(vvp_out, " %%store/prop/v %d, %u;\n",
ivl_lval_property_idx(lval), lwid);
fprintf(vvp_out, " %%pop/obj 1, 0;\n");
@@ -444,11 +439,34 @@ static int show_stmt_assign_vector(ivl_statement_t net)
fprintf(vvp_out, " %%cvt/vr %u;\n", wid);
} else if (ivl_expr_value(rval) == IVL_VT_STRING) {
/* Special case: vector to string casting */
/* Special case: string to vector casting */
ivl_lval_t lval = ivl_stmt_lval(net, 0);
fprintf(vvp_out, " %%vpi_call %u %u \"$ivl_string_method$to_vec\", v%p_0, v%p_0 {0 0 0};\n",
ivl_file_table_index(ivl_stmt_file(net)), ivl_stmt_lineno(net),
ivl_expr_signal(rval), ivl_lval_sig(lval));
if (slices) free(slices);
return 0;
} else if (ivl_expr_value(rval) == IVL_VT_DARRAY) {
/* Special case: dynamic array to vector casting */
ivl_lval_t lval = ivl_stmt_lval(net, 0);
void*rval_addr = NULL;
/* Even more special case: function call returning dynamic array */
if(ivl_expr_type(rval) == IVL_EX_UFUNC) {
rval_addr = ivl_scope_port(ivl_expr_def(rval), 0);
draw_ufunc_object(rval);
/* We do not need to store the result, it is going to be
converted to vector quite soon. */
fprintf(vvp_out, " %%pop/obj 1, 0; drop the result\n");
} else {
rval_addr = ivl_expr_signal(rval);
}
fprintf(vvp_out, " %%vpi_call %u %u \"$ivl_darray_method$to_vec\", v%p_0, v%p_0 {0 0 0};\n",
ivl_file_table_index(ivl_stmt_file(net)), ivl_stmt_lineno(net),
rval_addr, ivl_lval_sig(lval));
if (slices) free(slices);
return 0;
} else {
@@ -532,8 +550,7 @@ static int show_stmt_assign_vector(ivl_statement_t net)
break;
}
if (slices)
free(slices);
if (slices) free(slices);
return 0;
}
@@ -868,7 +885,7 @@ static int show_stmt_assign_sig_cobject(ivl_statement_t net)
expression to the assignment is of an entire
array object. */
fprintf(vvp_out, " %%load/obj v%p_0;\n", sig);
draw_eval_object(rval);
errors += draw_eval_object(rval);
fprintf(vvp_out, " %%store/prop/obj %d, %d; IVL_VT_DARRAY\n", prop_idx, idx);
fprintf(vvp_out, " %%pop/obj 1, 0;\n");
@@ -882,7 +899,7 @@ static int show_stmt_assign_sig_cobject(ivl_statement_t net)
/* The property is a class object. */
fprintf(vvp_out, " %%load/obj v%p_0;\n", sig);
draw_eval_object(rval);
errors += draw_eval_object(rval);
if (idx_expr) draw_eval_expr_into_integer(idx_expr, idx);
fprintf(vvp_out, " %%store/prop/obj %d, %d; IVL_VT_CLASS\n", prop_idx, idx);
fprintf(vvp_out, " %%pop/obj 1, 0;\n");
+6 -3
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2011 Stephen Williams (steve@icarus.com)
* Copyright (c) 2001-2014 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
@@ -28,7 +28,7 @@
static const char*version_string =
"Icarus Verilog VVP Code Generator " VERSION " (" VERSION_TAG ")\n\n"
"Copyright (c) 2001-2011 Stephen Williams ([email protected])\n\n"
"Copyright (c) 2001-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"
@@ -59,7 +59,10 @@ __inline__ static void draw_execute_header(ivl_design_t des)
{
const char*cp = ivl_design_flag(des, "VVP_EXECUTABLE");
if (cp) {
fprintf(vvp_out, "#! %s\n", cp);
const char *extra_args = ivl_design_flag(des, "VVP_EXTRA_ARGS");
if (!extra_args)
extra_args = "";
fprintf(vvp_out, "#! %s%s\n", cp, extra_args);
#if !defined(__MINGW32__)
fchmod(fileno(vvp_out), 0755);
#endif
+2 -7
View File
@@ -23,11 +23,6 @@
# include "ivl_target.h"
# include <stdio.h>
#ifdef __MINGW32__ /* MinGW has inconsistent %p output. */
#define snprintf _snprintf
#endif
extern int debug_draw;
/*
@@ -242,13 +237,13 @@ extern void draw_eval_real(ivl_expr_t ex);
extern int draw_eval_bool64(ivl_expr_t ex);
/*
* The draw_eval_string functio evaluates the expression as a string,
* The draw_eval_string function evaluates the expression as a string,
* and pushes the string onto the string stack.
*/
extern void draw_eval_string(ivl_expr_t ex);
/*
* The draw_eval_string functio evaluates the expression as an object,
* The draw_eval_string function evaluates the expression as an object,
* and pushes the object onto the object stack.
*/
extern int draw_eval_object(ivl_expr_t ex);
+47 -34
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2014 Stephen Williams (steve@icarus.com)
* Copyright (c) 2001-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
@@ -21,10 +21,7 @@
# include <string.h>
# include <assert.h>
# include <stdlib.h>
#ifdef __MINGW32__ /* MinGW has inconsistent %p output. */
#define snprintf _snprintf
#endif
# include <stdbool.h>
static int show_statement(ivl_statement_t net, ivl_scope_t sscope);
@@ -114,14 +111,12 @@ static void assign_to_array_word(ivl_signal_t lsig, ivl_expr_t word_ix,
ivl_expr_t part_off_ex,
unsigned nevents)
{
unsigned skip_assign = transient_id++;
int word_ix_reg = 3;
int part_off_reg = 0;
int delay_index;
unsigned long part_off = 0;
int error_flag = allocate_flag();
fprintf(vvp_out, " %%flag_set/imm %d, 0;\n", error_flag);
/* Figure the constant part offset, if possible. If we can do
so, then forget about the expression and use the calculated
@@ -143,11 +138,13 @@ static void assign_to_array_word(ivl_signal_t lsig, ivl_expr_t word_ix,
/* Calculate array word index into word index register */
draw_eval_expr_into_integer(word_ix, word_ix_reg);
fprintf(vvp_out, " %%flag_or %d, 4;\n", error_flag);
if (part_off_ex) {
part_off_reg = allocate_word();
/* Save the index calculation error flag to a global. */
fprintf(vvp_out, " %%flag_mov %d, 4;\n", error_flag);
draw_eval_expr_into_integer(part_off_ex, part_off_reg);
/* Add the error state of the part select to the global. */
fprintf(vvp_out, " %%flag_or %d, 4;\n", error_flag);
} else if (part_off != 0) {
@@ -158,26 +155,35 @@ static void assign_to_array_word(ivl_signal_t lsig, ivl_expr_t word_ix,
part_off_reg, part_off);
}
/* Calculated delay... */
if (dexp != 0) {
/* Calculated delay... */
delay_index = allocate_word();
/* If needed save the index calculation error flag. */
if (! part_off_ex) {
fprintf(vvp_out, " %%flag_mov %d, 4;\n", error_flag);
}
draw_eval_expr_into_integer(dexp, delay_index);
fprintf(vvp_out, " %%flag_mov 4, %d;\n", error_flag);
if (word_ix_reg != 3) {
fprintf(vvp_out, " %%ix/mov 3, %u;\n", word_ix_reg);
fprintf(vvp_out, " %%ix/mov 3, %d;\n", word_ix_reg);
clr_word(word_ix_reg);
}
/* Restore the error state since an undefined delay is okay. */
fprintf(vvp_out, " %%flag_mov 4, %d;\n", error_flag);
fprintf(vvp_out, " %%assign/vec4/a/d v%p, %d, %d;\n",
lsig, part_off_reg, delay_index);
clr_word(delay_index);
/* Event control delay... */
} else if (nevents != 0) {
/* Event control delay... */
/* If needed use the global error state. */
if (part_off_ex) {
fprintf(vvp_out, " %%flag_mov 4, %d;\n", error_flag);
}
fprintf(vvp_out, " %%assign/vec4/a/e v%p, %d;\n", lsig, part_off_reg);
/* Constant delay... */
} else {
/* Constant delay... */
unsigned long low_d = delay % UINT64_C(0x100000000);
unsigned long hig_d = delay / UINT64_C(0x100000000);
@@ -185,15 +191,18 @@ static void assign_to_array_word(ivl_signal_t lsig, ivl_expr_t word_ix,
fprintf(vvp_out, " %%ix/load %d, %lu, %lu; Constant delay\n",
delay_index, low_d, hig_d);
if (word_ix_reg != 3) {
fprintf(vvp_out, " %%ix/mov 3, %u;\n", word_ix_reg);
fprintf(vvp_out, " %%ix/mov 3, %d;\n", word_ix_reg);
clr_word(word_ix_reg);
}
fprintf(vvp_out, " %%assign/vec4/a/d v%p, %d, %u;\n",
/* If needed use the global error state. */
if (part_off_ex) {
fprintf(vvp_out, " %%flag_mov 4, %d;\n", error_flag);
}
fprintf(vvp_out, " %%assign/vec4/a/d v%p, %d, %d;\n",
lsig, part_off_reg, delay_index);
clr_word(delay_index);
}
fprintf(vvp_out, "t_%u ;\n", skip_assign);
if (nevents != 0) fprintf(vvp_out, " %%evctl/c;\n");
clr_flag(error_flag);
@@ -662,7 +671,7 @@ static int show_stmt_case(ivl_statement_t net, ivl_scope_t sscope)
/* Duplicate the case expression so that the cmp
instructions below do not completely erase the
value. Do this in fromt of each compare. */
value. Do this in front of each compare. */
fprintf(vvp_out, " %%dup/vec4;\n");
draw_eval_vec4(cex);
@@ -758,7 +767,7 @@ static int show_stmt_case_r(ivl_statement_t net, ivl_scope_t sscope)
continue;
}
/* The referene value... */
/* The reference value... */
fprintf(vvp_out, " %%dup/real;\n");
/* The guard value... */
draw_eval_real(cex);
@@ -1043,7 +1052,14 @@ static void force_link_rval(ivl_statement_t net, ivl_expr_t rval)
if ((rword_idx = ivl_expr_oper1(rval)) != 0) {
assert(ivl_signal_dimensions(rsig) != 0);
assert(number_is_immediate(rword_idx, IMM_WID, 0));
if (!number_is_immediate(rword_idx, IMM_WID, 0)) {
fprintf(stderr, "%s:%u: tgt-vvp sorry: procedural continuous "
"assignments are not yet fully supported. The RHS of "
"this assignment will only be evaluated once, at the "
"time the assignment statement is executed.\n",
ivl_stmt_file(net), ivl_stmt_lineno(net));
return;
}
/* An out-of-range or undefined index will have been
converted to a canonical offset of 1'bx. Skip the
assignment in this case. */
@@ -1321,7 +1337,7 @@ static int show_stmt_do_while(ivl_statement_t net, ivl_scope_t sscope)
the result. If the expression evaluates to true, then
branch to the top label. */
int use_flag = draw_eval_condition(ivl_stmt_cond_expr(net));
fprintf(vvp_out, " %%jmp/1 T_%u.%u, %u;\n",
fprintf(vvp_out, " %%jmp/1 T_%u.%u, %d;\n",
thread_count, top_label, use_flag);
clr_flag(use_flag);
@@ -1665,7 +1681,7 @@ static int show_stmt_while(ivl_statement_t net, ivl_scope_t sscope)
the result. If the expression evaluates to false, then
branch to the out label. */
int use_flag = draw_eval_condition(ivl_stmt_cond_expr(net));
fprintf(vvp_out, " %%jmp/0xz T_%u.%u, %u;\n",
fprintf(vvp_out, " %%jmp/0xz T_%u.%u, %d;\n",
thread_count, out_label, use_flag);
clr_flag(use_flag);
@@ -1696,19 +1712,16 @@ static int show_delete_method(ivl_statement_t net)
return 0;
}
static int show_push_frontback_method(ivl_statement_t net)
static int show_push_frontback_method(ivl_statement_t net, bool is_front)
{
const char*stmt_name = ivl_stmt_name(net);
show_stmt_file_line(net, "queue: push_back");
const char*type_code = "?";
if (strcmp(stmt_name,"$ivl_queue_method$push_front") == 0)
const char*type_code;
if (is_front) {
show_stmt_file_line(net, "queue: push_front");
type_code = "qf";
else if (strcmp(stmt_name,"$ivl_queue_method$push_back") == 0)
} else {
show_stmt_file_line(net, "queue: push_back");
type_code = "qb";
else
type_code = "??";
}
unsigned parm_count = ivl_stmt_parm_count(net);
if (parm_count != 2)
@@ -1750,10 +1763,10 @@ static int show_system_task_call(ivl_statement_t net)
return show_delete_method(net);
if (strcmp(stmt_name,"$ivl_queue_method$push_front") == 0)
return show_push_frontback_method(net);
return show_push_frontback_method(net, true);
if (strcmp(stmt_name,"$ivl_queue_method$push_back") == 0)
return show_push_frontback_method(net);
return show_push_frontback_method(net, false);
show_stmt_file_line(net, "System task call.");
@@ -2308,7 +2321,7 @@ int draw_process(ivl_process_t net, void*x)
fprintf(vvp_out, " .scope S_%p;\n", scope);
/* Generate the entry label. Just give the thread a number so
that we ar certain the label is unique. */
that we are certain the label is unique. */
fprintf(vvp_out, "T_%u ;\n", thread_count);
/* Draw the contents of the thread. */

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