Compare commits

...
763 Commits
Author SHA1 Message Date
steve 2e279b61dd Update to 0.7 release. 2002-12-14 18:20:14 +00:00
steve 8ab909a765 Add vpi_handle_by_name to the VPI interface,
and bump the vpithunk magic number.
2002-12-11 23:55:22 +00:00
steve cca07fa42d Account for bison 1.35 and stack manipulations. 2002-12-10 05:49:51 +00:00
steve 5b81798205 install iverilog-vpi as a script. 2002-12-10 05:45:44 +00:00
steve a8a82df47d Prepare for 20021207 snapshot 2002-12-08 03:06:30 +00:00
steve e62e1d89b6 Named event triggers can take hierarchical names. 2002-12-07 02:49:24 +00:00
steve c032186133 Reword some error messages for clarity. 2002-12-06 03:08:19 +00:00
steve b89e138404 precalculate r-values of nb assignments and task arguments. 2002-12-05 04:15:14 +00:00
steve 9f80ed32b6 Support bit select in constant expressions. 2002-12-05 02:14:33 +00:00
steve c16a4a3950 distclean target. 2002-12-04 03:33:38 +00:00
steve 90fa90a508 Mingw32 compatible temp file management. 2002-12-04 03:26:59 +00:00
steve aaa734690f Use O_EXCL when opening temp files. 2002-12-04 02:29:36 +00:00
steve 88da7804c4 Improve the bad character error message. 2002-12-04 02:07:00 +00:00
steve 8604f922a5 specify delay can take an unbracketed simple value. 2002-11-26 03:56:10 +00:00
steve 807a758f7c Do not set width if width is already OK. 2002-11-26 03:35:13 +00:00
steve ef55086543 Support put of vpiStringVal to signals. 2002-11-25 23:33:45 +00:00
steve 2001903c89 Cygwin doesnot need driver-vpi sibdirectory. 2002-11-24 02:27:28 +00:00
steve 751e4e4c79 Fix instanceRef spelling. 2002-11-24 02:26:14 +00:00
steve 9d91b5db4c Document the Windows specific flags. 2002-11-23 00:51:53 +00:00
steve 9a3c9507ed Handle wide AND/NOR devices with Virtex carry logic. 2002-11-22 05:46:06 +00:00
steve d71d52bfe9 Implement bufif1 as BUFT 2002-11-22 01:45:40 +00:00
steve 8e30bc9f9e Careful of left operands to shift that are constant. 2002-11-22 00:01:50 +00:00
steve 412518d1ca Precalculate indices to l-value arrays. 2002-11-21 23:27:51 +00:00
steve 03afbf157b %set/x0 instruction to support bounds checking. 2002-11-21 22:43:13 +00:00
steve 00b2d467e4 Allow right values of right shift to shift in. 2002-11-21 22:42:48 +00:00
steve 856829d299 Fix const test of msb in assignment l-values. 2002-11-21 18:15:40 +00:00
steve 2fafe6866f Better handling of select width of shifters. 2002-11-21 18:08:09 +00:00
steve b9188ad0ca PATHPULSE specparam assignment syntax. 2002-11-21 17:40:11 +00:00
steve 0ccb9139c9 Magnitude compare to 0. 2002-11-17 23:37:55 +00:00
steve 18e402ddc8 Close old file if $dumpfile is called again. 2002-11-17 22:28:42 +00:00
steve b82d3165da Update version strings in spec flie. 2002-11-17 18:38:03 +00:00
steve 91580d1fcc Generate unique labels for force functors. 2002-11-17 18:31:09 +00:00
steve 35d7384903 Handle default: case in net_inputs for NetCase. 2002-11-16 05:45:41 +00:00
steve 4539632f34 Add vpiScope iterate on vpiScope objects. 2002-11-15 22:14:12 +00:00
steve 0651f246b2 Save vpiFullName results. 2002-11-14 22:43:58 +00:00
steve 6d0dee9341 Add version resources to the Windows binary. 2002-11-13 17:25:10 +00:00
steve c692f1708c Allow -mingw and -ivl flags to stand alone. 2002-11-13 17:03:49 +00:00
steve d91733d32c Spell the iverilog-vpi target correctly. 2002-11-13 16:57:25 +00:00
steve cd7378ff3f Do not truncate high bits of right shift. 2002-11-13 03:03:08 +00:00
steve c98ce4a029 Add Windows version of iverilog-vpi. 2002-11-13 01:50:11 +00:00
steve d035a7e92c spelling error. 2002-11-13 01:49:43 +00:00
steve 6db6359363 Update Solaris packaging to to realities. 2002-11-11 15:49:03 +00:00
steve 5c07a29e46 Install sqrt-virtex.v under Windows. 2002-11-11 01:12:41 +00:00
steve 42d9094e9b Snapshot 20021109 2002-11-09 23:41:15 +00:00
steve 1742231eba Handle nested-if chip enables. 2002-11-09 23:29:29 +00:00
steve 3178f886b7 XNF target uses only legacy functors. 2002-11-09 23:29:02 +00:00
steve cbc4a0ab52 Detect synthesis conflicts blocks statements share outputs. 2002-11-09 20:22:57 +00:00
steve cfd8cbf850 Port expressions for output ports are lnets, not nets. 2002-11-09 19:20:48 +00:00
steve 013b18b3dc leading underscore test for Windows more robust. 2002-11-09 06:03:57 +00:00
steve db9f20b21a Macos install notes. 2002-11-09 06:03:38 +00:00
steve f611260089 display octal escapes properly. 2002-11-09 06:01:11 +00:00
steve e34e3a4875 spelling in a comment. 2002-11-09 02:22:07 +00:00
steve aa8869a3c7 Postpone parameter width check to evaluation. 2002-11-09 01:40:19 +00:00
steve 588931fcf2 Add dup_expr for user defined function calls. 2002-11-09 00:25:27 +00:00
steve 07e49e215e Use the vectorized %assign where appropriate. 2002-11-08 05:00:31 +00:00
steve 1b84893ccb Add the %assign/v0 instruction. 2002-11-08 04:59:57 +00:00
steve 6445bb6915 Handle comments in suppressed code. 2002-11-08 00:04:16 +00:00
steve db899bd1b5 Use Vector %set to set constants in variables. 2002-11-07 05:19:55 +00:00
steve c6dcc38fe0 Vectorize load from REG variables. 2002-11-07 03:12:17 +00:00
steve b0a7909162 functor_set takes bit and strength, not 2 strengths. 2002-11-07 03:11:43 +00:00
steve d7ae85a13a Add vector set and load instructions. 2002-11-07 02:32:39 +00:00
steve 46ee38b466 Concatenation can evaluate sub-expressions in place. 2002-11-06 05:41:37 +00:00
steve bc6a958a50 More reliable iverilog.conf install dependency. 2002-11-06 03:42:40 +00:00
steve 0e751ad975 More forgiving about assignment rval width mismatch. 2002-11-06 03:22:28 +00:00
steve de94d09706 No need to keep excess width from an
unsigned constant value, if it can
 be trimmed safely.
2002-11-06 02:25:13 +00:00
steve 2f88a631df Run output with the vvp command. 2002-11-05 03:49:21 +00:00
steve 4e5dd49a37 Fix mask calculate when MOV_b is right on the word boundary. 2002-11-05 03:46:44 +00:00
steve 8463dcc878 ignore parse.output 2002-11-05 02:19:37 +00:00
steve 18bc2f65b3 Misspelled name. 2002-11-05 02:18:53 +00:00
steve b4e8ea5a0c Install shared objects as programs, not data. 2002-11-05 02:14:41 +00:00
steve 06a8087cb5 Do not need _leading underscore on Windows. 2002-11-05 02:14:16 +00:00
steve a9dfef0f55 Fix the call to FormatMessage under Windows. 2002-11-05 02:12:35 +00:00
steve e4540c3d0d Better error message for load failure on Windows. 2002-11-05 02:11:56 +00:00
steve 0cc8396244 Cast for gcc convenience. 2002-11-03 22:44:19 +00:00
steve 946693ad4d New output files from new bison. 2002-11-03 20:50:33 +00:00
steve f014d4c533 Update instructions, now that Cygwin handles X:/path strings. 2002-11-03 20:49:57 +00:00
steve 6a1e3f7e27 Slightly more verbose load fail message. 2002-11-03 20:47:23 +00:00
steve 7ad66b0725 Support old/new bison yylloc. 2002-11-03 20:36:53 +00:00
steve 0341c0c727 Error message for mising code generator type. 2002-11-03 20:36:10 +00:00
steve 20c8550139 Compiler error wrt ptrdiff_t. 2002-11-03 20:33:43 +00:00
steve 39aa90ce59 Snapshot 20021102 2002-11-03 02:12:00 +00:00
steve 6c67a64fc3 Get VectorVals from constant values. 2002-11-03 02:07:24 +00:00
steve 86032c0aa5 Allow named events to be referenced by
hierarchical names.
2002-11-02 03:27:51 +00:00
steve f243f694b4 Detect memories without work index in l-value. 2002-11-02 01:10:49 +00:00
steve 276ae3e228 Add the sqrt-virtex example. 2002-11-01 03:29:43 +00:00
steve fe6756eb07 Fix bottom bit of ADD/SUB device. 2002-11-01 02:36:34 +00:00
steve 539e494bc0 Give nets better names, if available. 2002-11-01 02:36:22 +00:00
steve 1298656c22 Fix up left shift to pass compile,
fix up ADD/SUB to generate missing pieces,
 Add the asynch set/reset to DFF devices.
2002-10-30 03:58:45 +00:00
steve c66d319d9c UPdate to 20021027 snapshot. 2002-10-28 02:26:41 +00:00
steve ae27165ffe Add Virtex code generators for left shift,
subtraction, and GE comparators.
2002-10-28 02:05:56 +00:00
steve 32f1ca6f8b draw lpm ff with aset_expr taken into account. 2002-10-23 04:39:35 +00:00
steve 9ce2806710 Fix synth2 handling of aset/aclr signals where
flip-flops are split by begin-end blocks.
2002-10-23 01:45:24 +00:00
steve 3d4593d4d5 Synthesizer support for synchronous begin-end blocks. 2002-10-21 01:42:08 +00:00
steve df5ae54ec7 Handle conditional error cases better. 2002-10-20 19:19:37 +00:00
steve fbee1b424d Properly set or clear expression lookaside for binary expressions. 2002-10-20 02:55:37 +00:00
steve 555017b525 Snapshot 20021019 2002-10-19 23:38:49 +00:00
steve 1e170ee005 bourne shell compatibility. 2002-10-19 23:18:52 +00:00
steve 43501809b1 Redo the parameter vector support to allow
parameter names in range expressions.
2002-10-19 22:59:49 +00:00
steve c0c67a101a Fix spelling of the scalared keyword. 2002-10-13 05:01:44 +00:00
steve 1eb714e097 More verbose eval_const assert message. 2002-10-13 05:01:07 +00:00
steve 54a8e12856 Fix symbol underscore needs for Mac OS X. 2002-10-03 18:03:35 +00:00
steve 6203f05ef9 Add pal target enable help message. 2002-10-03 17:57:54 +00:00
steve 703ad04067 Allow expression lookaside map to spam statements. 2002-09-27 20:24:42 +00:00
steve 778e96330d Add thread expression lookaside map. 2002-09-27 16:33:34 +00:00
steve e3eb89fb12 Remove excess debug messages. 2002-09-26 03:42:10 +00:00
steve 166621bcb3 Generate vvp code for asynch set/reset of NetFF. 2002-09-26 03:18:04 +00:00
steve 879a5a4cbe Synthesize async set/reset is certain cases. 2002-09-26 01:13:14 +00:00
steve 9faabfe995 Fix missing endifs within supressed ifdefs. 2002-09-25 02:23:08 +00:00
steve 6f23fa61ac Allow results in register bits 47 in certain cases. 2002-09-24 04:20:32 +00:00
steve 30b6cf7821 Include user specified libraries on the link line. 2002-09-24 01:50:53 +00:00
steve 6258011210 More detailed check of process edge events. 2002-09-24 00:58:35 +00:00
steve 7557a46382 Remove some now useless asserts. 2002-09-21 23:47:30 +00:00
steve a0a91f358c Snapshot 20020921 2002-09-21 21:29:09 +00:00
steve 0128286966 Allow constant bit selects out of range. 2002-09-21 21:28:18 +00:00
steve acd5e86e04 Fix disable in arbitrary fork/join situations. 2002-09-21 04:55:00 +00:00
steve ab94b0a636 disable threads with children. 2002-09-20 03:59:34 +00:00
steve de6d696667 Add support for cbAfterDelay. 2002-09-20 02:42:11 +00:00
steve 63946c4cfb More careful cd command. 2002-09-20 02:41:36 +00:00
steve 475b603d15 Relax position constrations of ifdef and friends. 2002-09-19 20:33:27 +00:00
steve 096956cda9 Fix multiple source on the command line. 2002-09-18 23:25:18 +00:00
steve 3d3116d48b Add support for binary NOR operator. 2002-09-18 04:29:55 +00:00
steve 616360d751 Spelling errors. 2002-09-18 04:08:45 +00:00
steve 7a5c30d297 printf size warning. 2002-09-18 03:34:07 +00:00
steve 9c5ab36a8b Fix switch case warnings. 2002-09-18 03:33:10 +00:00
steve 466656b167 Allow forward references of memories. 2002-09-18 02:55:18 +00:00
steve 5d6567cb02 Generate vvp code for structural flip-flops. 2002-09-17 05:37:45 +00:00
steve c44c123ef5 Connect output of block to net_out, instead of statement outputs. 2002-09-17 04:40:28 +00:00
steve 4ecbf56e2b Account for part select in l-value. 2002-09-17 04:39:20 +00:00
steve ed9a2c4b3f Proper initialization of the memories table. 2002-09-17 00:42:22 +00:00
steve 90751b9250 Reject multiple probes on synchronous logic. 2002-09-16 21:55:06 +00:00
steve 7d8011669d snapshot 20020915 2002-09-16 03:48:56 +00:00
steve eb81062d85 Add to synth2 support for synthesis of
synchronous logic. This includes DFF enables
 modeled by if/then/else.
2002-09-16 00:30:33 +00:00
steve 8fbacc966e compile error. 2002-09-16 00:28:51 +00:00
steve 75801a12e3 Display FF enables. 2002-09-16 00:28:25 +00:00
steve 9f1ce170e6 Generate code for 8:1 muxes msing F5 and F6 muxes. 2002-09-15 21:52:19 +00:00
steve 327c8826f4 Generate Virtex code for 4:1 mux slices. 2002-09-14 05:19:19 +00:00
steve fb0383d2bd single bit optimization for != in expressions,
and expand ++ and != results if needed.
2002-09-13 04:09:51 +00:00
steve 28725d0d74 Optimize ==1 when in context where x vs z doesnt matter. 2002-09-13 03:12:50 +00:00
steve dac99b9374 Add support for binary nand operator. 2002-09-12 15:49:43 +00:00
steve 1573477caf Account for buffer overrun in memory word names. 2002-09-12 15:13:07 +00:00
steve 70a7513781 Support $ in preprocessor identifiers. 2002-09-11 19:42:37 +00:00
steve 0277035496 Fix wrecked rbuf in vpi_get_str of signals and memories. 2002-09-11 16:06:57 +00:00
steve 33f462fdf6 Actually set strength pointer when getting strength val. 2002-09-10 02:27:11 +00:00
steve 639b9f346f Snapshot 20020907 2002-09-08 01:39:23 +00:00
steve 447fee6f43 Fix padding of operand of unary minus. 2002-09-08 01:37:13 +00:00
steve c9212a9a09 Implement vpi_remove_cb for cbValueChange. 2002-09-07 04:54:51 +00:00
steve ea21fab379 Add support for %v is the display system task.
Change the encoding of H and L outputs from
 the bufif devices so that they are logic x.
2002-09-06 04:56:28 +00:00
steve 4d090b64bd List tran devices as unsupported. 2002-09-04 16:19:39 +00:00
steve 7e1e44e87a Properly cast signedness of parameters with ranges. 2002-09-01 03:01:48 +00:00
steve 0a2a9dcd94 Fix leaking vthread bits in ?: eval. 2002-09-01 01:42:34 +00:00
steve c9b4b66af2 Watch for x indices in l-value of non-blocking assignments. 2002-09-01 00:19:35 +00:00
steve 7b6678b2a1 Fix reverse bit ordered bit select in continuous assignment. 2002-08-31 03:48:50 +00:00
steve e79f62c5fa Generate x out for x select on wide muxes. 2002-08-29 03:04:01 +00:00
steve 60046cc790 update for 20020828 snapshot. 2002-08-28 20:30:53 +00:00
steve 3fca25181a Evaluate nonblocking assign r-values. 2002-08-28 18:54:36 +00:00
steve cbca31555d Add the %subi instruction, and use it where possible. 2002-08-28 18:38:07 +00:00
steve d5aa700b4b Generate %load/nx for indexed load of nets. 2002-08-28 17:15:35 +00:00
steve 1db8319bce Add the %load/nx opcode to index vpi nets. 2002-08-28 17:15:06 +00:00
steve aa390f2a91 Fix l-value indexing of memories and vectors so that
an unknown (x) index causes so cell to be addresses.

 Fix tangling of label identifiers in the fork-join
 code generator.
2002-08-27 05:39:57 +00:00
steve bd9e66d333 Missing declaration of ivl_memory_scope. 2002-08-24 05:03:40 +00:00
steve c34e318f8c Fix = vs == error. 2002-08-24 05:02:58 +00:00
steve 4fc858b676 Fix missing semi-colon warning. 2002-08-24 05:02:37 +00:00
steve ac8b582b3d Rewire time formatting to handle all cases. 2002-08-24 02:02:44 +00:00
steve 6f748d3d4f Macro arguments not supported. 2002-08-24 00:52:49 +00:00
steve 2854a524f0 Watch signed comparisons, that lead to infinite loops. 2002-08-22 23:34:52 +00:00
steve 985c34bfd9 Fix behavioral eval of x?a:b expressions. 2002-08-22 03:38:40 +00:00
steve 63f97d8ec6 Carry mux output delays. 2002-08-21 02:28:03 +00:00
steve d2ac85e2c7 Copy gate delays when doing gate delay substitutions. 2002-08-20 04:12:22 +00:00
steve 1b42f6232f Support parameters with defined ranges. 2002-08-20 04:11:53 +00:00
steve 4de141ab1d Support parameters with defined ranges. 2002-08-19 02:39:16 +00:00
steve 8ab2ec6f86 Allow release to handle removal of target net. 2002-08-19 00:06:11 +00:00
steve 2fad8d4cff Detect temporaries in sequential block synthesis. 2002-08-18 22:07:16 +00:00
steve d94b0fe3c8 Terminate if the functors signal errors. 2002-08-18 22:06:29 +00:00
steve 98956ef88f Snapshot 20020817 2002-08-18 01:07:05 +00:00
steve ac21d96bd8 x in index values leads to 0. 2002-08-18 01:05:50 +00:00
steve c794aa02b8 Fix intermix of node functors and node delete. 2002-08-16 05:18:27 +00:00
steve dd564ab321 add dumpvars_compiletf to check first argument. 2002-08-15 02:12:20 +00:00
steve c0046e845e Handle special case of empty system task argument list. 2002-08-15 02:11:54 +00:00
steve 640767b748 Constants can self-size themselves in unsized contexts. 2002-08-14 03:57:27 +00:00
steve d4eaede435 Do not elide named blocks. 2002-08-13 05:35:00 +00:00
steve 52bf4e613f conditional ident string using autoconfig. 2002-08-12 01:34:58 +00:00
steve 9533a8dbdf Escape the backslash in the windows file name. 2002-08-12 01:27:48 +00:00
steve 774f78cd3e Autoconfig ident support. 2002-08-12 00:27:10 +00:00
steve aca1dcf848 Add missing Log and Ident strings. 2002-08-11 23:47:04 +00:00
steve d24cd015b6 Remove VVM option. 2002-08-11 23:39:33 +00:00
steve 4d41525a91 No longer any nead for -rdynamic flag 2002-08-10 22:36:59 +00:00
steve b170a85fef Kill links to vvm. 2002-08-10 22:27:13 +00:00
steve 90c6bc3a61 Add attributes documentation. 2002-08-10 22:27:00 +00:00
steve a4f6217a2f Missing symbols for mingw. 2002-08-10 22:23:22 +00:00
steve faff19af7b vvp.pdf comes from the man page. 2002-08-10 22:12:01 +00:00
steve bc86bd4efa Remove useless error messages. 2002-08-10 22:07:38 +00:00
steve b4b18f3f30 Observe attributes to control synthesis. 2002-08-10 22:07:08 +00:00
steve 1bcacf06d4 The default attribute value is 1. 2002-08-10 21:59:39 +00:00
steve 27178cedda Allow vpiIntegerVar as parameter to $value$plusarg 2002-08-10 17:00:31 +00:00
steve 6151d796a2 More unsupported items in the list. 2002-08-10 16:57:27 +00:00
steve 6ace9659e0 Get local StringHeap.h 2002-08-07 02:36:10 +00:00
steve 14942b4b43 Dead code. 2002-08-07 02:17:14 +00:00
steve 9ede67ea63 List net delays as unsupported. 2002-08-07 02:07:12 +00:00
steve cc74d2a6b0 Add force to nets. 2002-08-07 00:54:39 +00:00
steve ea779ac7dd Documentation, and excessive inlines. 2002-08-07 00:54:20 +00:00
steve 693e9e5ad0 Store only the base name of memories. 2002-08-05 04:18:45 +00:00
steve a1bc8ca6ca Snapshot 20020804 2002-08-04 22:47:23 +00:00
steve 4e753a2c15 dll uses StringHeap for named items. 2002-08-04 19:13:16 +00:00
steve 89314d4772 Do not use hierarchical names of memories to
generate vvp labels. -tdll target does not
 used hierarchical name string to look up the
 memory objects in the design.
2002-08-04 18:28:14 +00:00
steve 41f7ecacfc Eliminate use of ivl_signal_name for signal labels. 2002-08-03 22:30:48 +00:00
steve dd8da912f5 Fix suffix parsing of library index. 2002-08-03 22:30:00 +00:00
steve 65ad911a2a Grammer fixes. 2002-08-02 01:52:02 +00:00
steve 37331d1c1b Add port name to pin size error message. 2002-07-31 23:55:38 +00:00
steve db2c842d15 Account for the tail readonly callbacks. 2002-07-31 03:22:44 +00:00
steve c0e22a6533 Set vpi_mode_flag to represent cpReadOnlySync actions. 2002-07-31 03:22:23 +00:00
steve bb87c368b8 Asynchronous synthesis of sequential blocks. 2002-07-29 00:00:28 +00:00
steve 76665b9404 Fix NetBlock destructor to delete substatements. 2002-07-28 23:58:44 +00:00
steve a265ba2162 dump NOT gates. 2002-07-28 23:57:22 +00:00
steve 461a0fa2fb $attribute deprecation note. 2002-07-26 02:08:02 +00:00
steve e51bbcb85a Add monitoron and monitoroff system tasks. 2002-07-25 03:35:51 +00:00
steve 58ec62c895 Rewrite find_similar_event to support doing
all event matching and replacement in one
 shot, saving time in the scans.
2002-07-24 16:24:45 +00:00
steve 843e1f9c44 Save event matching for nodangle. 2002-07-24 16:22:59 +00:00
steve 45382144c3 Verbose messages. 2002-07-24 16:21:52 +00:00
steve e2f537628f integral type/ptrdiff_t warning. 2002-07-23 15:11:41 +00:00
steve 91baa938e2 Fix display of no arguments. 2002-07-23 02:41:15 +00:00
steve 7fcaeacd65 Careful not to overrun vector buffer. 2002-07-23 02:36:34 +00:00
steve 2478d6f5d3 Set ivl_target delays for case compare logic. 2002-07-22 21:07:40 +00:00
steve fbc1f6fb81 Initialize the lcounter_ to 0. 2002-07-22 21:07:08 +00:00
steve 57aee7ca26 Add vpi_chk_error and vpi_control functions. 2002-07-19 01:57:26 +00:00
steve 2fcfe9f2c3 vpi_iterate returns 0 on error. 2002-07-19 01:12:50 +00:00
steve 2df2619029 Support put of wide vpiVectorVal to signal. 2002-07-19 00:36:36 +00:00
steve 9260d0d245 New e-mail address for Yasuhisa Kato 2002-07-18 02:18:30 +00:00
steve 15becdaee4 Need driver for sure in assign feedback and other cases. 2002-07-18 02:06:37 +00:00
steve 80c9db3c88 Careful with assign to self. 2002-07-18 00:24:22 +00:00
steve c5d03d3a25 Fix uninitialized thread pointer in named event. 2002-07-17 18:30:01 +00:00
steve 9e1570dc80 Implementation of vpi_handle_by_name, and
add the vpiVariables iterator.
2002-07-17 05:13:43 +00:00
steve 68da84e84a Allow wide rvalues assigned to narrow nex_out. 2002-07-16 04:40:48 +00:00
steve 18ba73382e Fix check for select size. 2002-07-16 03:15:11 +00:00
steve dabbfdb80a Fix dangling pointer in pop_scope. 2002-07-15 03:57:30 +00:00
steve 4eea8720a0 Improve temporary file name guess. 2002-07-15 00:33:50 +00:00
steve 41239078a9 Fix initialization of symbol table string heap. 2002-07-15 00:21:42 +00:00
steve e375078dda Infinite loop in nex_input of NetBlock objects. 2002-07-14 23:47:58 +00:00
steve da6b4c447f No longer need the .exe on generated files. 2002-07-14 23:32:31 +00:00
steve b72c0a0089 Do temp file creation by hand. 2002-07-14 23:11:35 +00:00
steve fbaf8f91bb Fix vpiScope iterator. 2002-07-14 02:52:05 +00:00
steve 329e943e4e Use result buf for event and scope names. 2002-07-12 18:23:30 +00:00
steve 31bd3e6056 Use all bits of ?: condit expression. 2002-07-12 18:10:45 +00:00
steve 15b94050ce Remember to scan IntegerVars. 2002-07-12 17:09:21 +00:00
steve c610699227 Eliminate use of vpiInternalScope. 2002-07-12 17:08:13 +00:00
steve f0d2e20342 Scan scope objects before subscopes. 2002-07-12 17:02:38 +00:00
steve 26a80005d6 Fix typo. 2002-07-12 16:30:44 +00:00
steve 5cf033a6ad Remove vvm files from spec file. 2002-07-12 04:05:50 +00:00
steve e41ee7632d Document the IVERILOG_DUMPER variable. 2002-07-12 02:35:35 +00:00
steve 66a86433e7 Make types array static, not on stack. 2002-07-12 02:10:20 +00:00
steve 2354a90e9f Eliminate use of vpiInternalScope. 2002-07-12 02:08:10 +00:00
steve b7aaf51fbd vpiIntegerVars can have callbacks. 2002-07-12 02:07:36 +00:00
steve 5a885165b2 vpi_iterate return null if there is nothing to iterate. 2002-07-12 02:04:44 +00:00
steve a748604418 Library dir case insensitivity includes the suffix. 2002-07-10 04:34:18 +00:00
steve e1a4e27173 Dynamic resizevpi result buf in more places. 2002-07-09 03:24:37 +00:00
steve 2b06a293b6 Fix split of root btree node. 2002-07-09 03:20:51 +00:00
steve 472f98affe Generate code for wide muxes. 2002-07-08 04:04:07 +00:00
steve 8114523be2 Asynchronous synthesis of case statements. 2002-07-07 22:32:15 +00:00
steve 33ee1da817 Smart synthesis of binary AND expressions. 2002-07-07 22:31:39 +00:00
steve 301040a67a Avoid emitting to vvp local net symbols. 2002-07-05 21:26:17 +00:00
steve 54b96ea7bd Count different types of functors. 2002-07-05 20:08:44 +00:00
steve d0dfe2e7e7 Allow set of output name. 2002-07-05 17:17:20 +00:00
steve fd8ceac170 Names of vpi objects allocated as vpip_strings. 2002-07-05 17:14:15 +00:00
steve a05d8c2823 Symbol table uses more efficient key string allocator,
and remove all the symbol tables after compile is done.
2002-07-05 04:40:59 +00:00
steve 626f418ab0 Track opcode memory space. 2002-07-05 03:46:43 +00:00
steve 5792220dcb Remove the vpi object symbol table after compile. 2002-07-05 02:50:57 +00:00
steve 29d5d44f03 More detailed Mac OS X instructions. 2002-07-04 16:37:59 +00:00
steve b2762f63a2 Fix s_vpi_vecval array byte size. 2002-07-04 16:37:07 +00:00
steve 7d97f8a964 initial statements are not asynchronous. 2002-07-04 00:24:16 +00:00
steve d3e63088d8 Dynamic size result buffer for _str and _get_value functions. 2002-07-03 23:39:57 +00:00
steve dddaa0ebcf More configure information in iverilog-vpi. 2002-07-03 23:20:12 +00:00
steve ccbb1e5f5a don't pollute name space
fix vecval for Z/X cases
2002-07-03 23:16:27 +00:00
steve 3f1cd14f6c Fix scope search for events. 2002-07-03 05:34:59 +00:00
steve 70abb2ce5c Clear drive cache on link or unlink. 2002-07-03 03:08:47 +00:00
steve 3f80bead1b vpiName, vpiFullName support in memory types,
length checks for *_get_str() buffers,
 temporary buffers for *_get_str() data,
 dynamic storage for vpi_get_data() in memory types
 shared with signal white space
2002-07-03 02:09:38 +00:00
steve 93bb4283b8 Change the signal to a net when assignments go away. 2002-07-02 03:02:57 +00:00
steve 5b5b31286b Include synth2 in synthesis targets. 2002-07-02 03:02:02 +00:00
steve c5bde6560c Limit word writing to vector limits. 2002-07-01 15:36:12 +00:00
steve cb4eb6236c Ignore generated pdf and ps files. 2002-07-01 03:54:08 +00:00
steve d5e9e13555 synth_asych of if/else requires redirecting the target
if sub-statements. Use NetNet objects to manage the
 situation.
2002-07-01 00:54:21 +00:00
steve 3595b6d186 Carry can propagate to the otp in addi. 2002-07-01 00:52:47 +00:00
steve 210010a390 Get vpiVectorVal for memories. 2002-06-30 04:35:47 +00:00
steve 99b3cc4464 vpiVectorVal of very wide signals. 2002-06-30 02:52:36 +00:00
steve 9b6b081e38 Add structure for asynchronous logic synthesis. 2002-06-30 02:21:31 +00:00
steve b54ee3b1cd Fix mishandling of incorect defparam error message. 2002-06-25 02:39:34 +00:00
steve 9fc4e1eddd Cache calculated driven value. 2002-06-25 01:33:22 +00:00
steve 73cca6ec39 include malloc.h only when available. 2002-06-25 01:33:01 +00:00
steve 58c2e12507 Make link_drive_constant cache its results in
the Nexus, to improve cprop performance.
2002-06-24 01:49:38 +00:00
steve 6dd80611a1 Export ivl_signal_integer fro windows. 2002-06-23 20:41:19 +00:00
steve c2132039d2 Variable substitution in command files. 2002-06-23 20:10:51 +00:00
steve d8d07eb129 trivial performance boost. 2002-06-23 18:23:09 +00:00
steve f9768cd579 spelling error. 2002-06-23 18:22:43 +00:00
steve b6a15b2f4d Wide unary minus in continuous assignments. 2002-06-22 04:22:40 +00:00
steve 5eca5d9948 Carry integerness throughout the compilation. 2002-06-21 04:59:35 +00:00
steve f4a4ee00d0 Add support for special integer vectors. 2002-06-21 04:58:55 +00:00
steve cd94019733 Remove NetTmp and add NetSubnet class. 2002-06-19 04:20:03 +00:00
steve d7fb47268f Shuffle link_drivers_constant for speed. 2002-06-19 04:18:46 +00:00
steve b4b5ac9944 Normalize run-time index expressions for bit selects 2002-06-16 20:39:12 +00:00
steve df0b81d94d Generate runtime code to normalize indices. 2002-06-16 19:19:16 +00:00
steve 067d09720c Rounding error. 2002-06-15 02:35:49 +00:00
steve 870c35eece sign extend signed vectors vpiIntVal. 2002-06-14 22:05:28 +00:00
steve a82c178fd9 Fix expression width for repeat concatenations. 2002-06-14 21:38:41 +00:00
steve 809bd18e66 Uninstall removed ivl from libdir. 2002-06-14 04:17:12 +00:00
steve 4f0ffa2258 Compiler portability. 2002-06-14 03:25:51 +00:00
steve f45b17973c Add acc_fetch_argc/argv/version (mruff) 2002-06-11 15:19:12 +00:00
steve 0bbea355c2 More specify syntax. 2002-06-11 13:58:04 +00:00
steve 2be3507422 Stub value change callbacks for consts and modules. 2002-06-11 03:47:34 +00:00
steve d6c946f390 Spelling patch (Larry Doolittle) 2002-06-11 03:34:33 +00:00
steve 96b6eb6b30 Get tf_asynchon/off name right. 2002-06-11 03:29:14 +00:00
steve 9cef973d9b Add NetRamDq synthsesis from memory l-values. 2002-06-08 23:42:46 +00:00
steve 88722a2831 Add tf_putlongp and tf_putp. 2002-06-07 16:21:12 +00:00
steve d6b5c67313 Add a bunch of acc/tf functions. (mruff) 2002-06-07 02:58:58 +00:00
steve 4fed9d6532 Simply give up on constants with indices. 2002-06-07 02:57:54 +00:00
steve 28e0616543 Use standard name for iostream. 2002-06-06 18:57:18 +00:00
steve 6173e6b78a Better error for identifier index eval. 2002-06-06 18:57:04 +00:00
steve b5018cd994 distclean rm some generated makefiles. 2002-06-06 18:48:02 +00:00
steve f19a7c617d improved uninstall target. 2002-06-05 18:52:14 +00:00
steve 53d8cdd9f8 Add support for memory words in l-value of
non-blocking assignments, and remove the special
 NetAssignMem_ and NetAssignMemNB classes.
2002-06-05 03:44:25 +00:00
steve 4bac5c06ba Dump l-value memory indices. 2002-06-05 03:43:14 +00:00
steve 91a755d0e8 Add support for memory words in l-value of
blocking assignments, and remove the special
 NetAssignMem class.
2002-06-04 05:38:43 +00:00
steve 8cae7a4d44 Add misctf support to libveriuser 2002-06-04 01:42:58 +00:00
steve 11d1c45e45 Add asynchon and asynchoff 2002-06-04 01:40:03 +00:00
steve 5454a15b94 Fix return type of tf_getinstance. 2002-06-03 21:52:59 +00:00
steve 3ad0ec77ce Add verinum != operator. 2002-06-03 04:04:24 +00:00
steve 3966e852ac Ignore memories and named events. 2002-06-03 03:56:06 +00:00
steve 83bfa9345f compile warnings. 2002-06-03 03:55:14 +00:00
steve 7d1d3847d8 Better typing for veriusertfs table. 2002-06-03 00:08:42 +00:00
steve a91c4f66ce Check for null pointers from users. 2002-06-02 19:05:50 +00:00
steve ca2486ea61 Add acc_handle_tfarg and acc_next_topmode 2002-06-02 19:03:29 +00:00
steve 24a2487c18 Generate %cmpi/u where appropriate. 2002-06-02 18:57:17 +00:00
steve d68153dea3 Add %cmpi/u instruction. 2002-06-02 18:55:58 +00:00
steve 89329fc0cc Add tf_getinstance function. 2002-06-02 18:54:59 +00:00
steve cba5a22714 Generate %muli instructions when possible. 2002-05-31 20:04:57 +00:00
steve 1ce50993f0 Add the %muli instruction. 2002-05-31 20:04:22 +00:00
steve 2c0c934ad5 Add tf_getlongtime (mruff) 2002-05-31 18:25:51 +00:00
steve b6db8b63ec Check for and don't dereference null pointers,
Avoid copy of static objects.
 (mruff)
2002-05-31 18:21:39 +00:00
steve f1ab9e63fa Add support for $timeformat. 2002-05-31 04:26:54 +00:00
steve 12c574d5c9 Call padding reserved. 2002-05-31 04:26:44 +00:00
steve af6f0c800f Slight improvement in %mov performance. 2002-05-31 04:09:58 +00:00
steve 48f65cef40 Word oriented bit storage. 2002-05-31 00:05:49 +00:00
steve b5a1d116fa Add the veriusertf_register funciton. 2002-05-30 02:37:26 +00:00
steve b9339d3c60 Add tf_nump from mruff. 2002-05-30 02:12:17 +00:00
steve 0838dd24a4 Add tf_error and tf_warning from mruff 2002-05-30 02:10:08 +00:00
steve 9537fd7f0b Implement acc_product_version. 2002-05-30 02:06:05 +00:00
steve 95876feb46 Use addi with wide immediate values. 2002-05-30 01:57:23 +00:00
steve 19d817503d Offset lvalue index expressions. 2002-05-29 22:05:54 +00:00
steve b6b364a09d Add %addi, which is faster to simulate. 2002-05-29 16:29:34 +00:00
steve f704d4d3ff Use binary search to speed up deep lookups. 2002-05-29 05:37:35 +00:00
steve 450b9ab85c Callbacks can happen during calltf functions. 2002-05-28 22:55:20 +00:00
steve a1774bd3bd ivl indexes the search path for libraries, and
supports case insensitive module-to-file lookup.
2002-05-28 20:46:51 +00:00
steve 5aa69516bb ivl indexes the search path for libraries, and
supports case insensitive module-to-file lookup.
2002-05-28 20:40:37 +00:00
steve c594dcec52 Add new iverilog-vpi man page. 2002-05-28 05:21:30 +00:00
steve 8126384726 ignore generated iverilog-vpi files. 2002-05-28 05:21:13 +00:00
steve 96e6a9b02f Update to new capabilities. 2002-05-28 05:20:41 +00:00
steve d44ff4fd91 Pass library paths through -Cfile instead of command line. 2002-05-28 02:25:03 +00:00
steve 9a4ee873e1 Add the ivl -C flag for bulk configuration
from the driver, and use that to run library
 modules through the preprocessor.
2002-05-28 00:50:39 +00:00
steve 597ed1681a Predefine __ICARUS__ 2002-05-27 23:14:06 +00:00
steve bcd49b94dd Able to disable thread self. 2002-05-27 00:53:10 +00:00
steve 422754f36f Support carrying the scope of named begin-end
blocks down to the code generator, and have
 the vvp code generator use that to support disable.
2002-05-27 00:08:45 +00:00
steve bfad382fd1 Carry Verilog 2001 attributes with processes,
all the way through to the ivl_target API.

 Divide signal reference counts between rval
 and lval references.
2002-05-26 01:39:02 +00:00
steve 8941a594ee include iostream for gcc 3.1 2002-05-25 16:51:37 +00:00
steve 6bd8ab46d5 Eval ^ and &0 expressions. 2002-05-25 16:43:47 +00:00
steve 57f2ad6d15 Better padding of constants. 2002-05-25 16:43:22 +00:00
steve 33efeca0da Only match plusargs. 2002-05-24 21:46:21 +00:00
steve be1888ed5f Implement mc_scan_plusargs. 2002-05-24 20:29:07 +00:00
steve 6ede18d41c support GCC __attributes__ for printf formats. 2002-05-24 19:05:30 +00:00
steve d63e994ea5 Detect long division by zero. 2002-05-24 04:55:13 +00:00
steve 700887d657 Verilog 2001 attriubtes on nets/wires. 2002-05-24 04:36:23 +00:00
steve 42674be38b Support language generation flag -g. 2002-05-24 01:13:00 +00:00
steve fde7cd8f10 Add support for $bits (SystemVerilog) 2002-05-24 00:44:54 +00:00
steve 7ce713356e Define SIZEOF_UNSIGNED_LONG_LONG 2002-05-24 00:43:16 +00:00
steve 6511fc610b Add the acc_user.h header file. 2002-05-23 03:46:42 +00:00
steve 8dd4f77f3f Add the io_printf function to libveriuser. 2002-05-23 03:35:42 +00:00
steve 004bfad348 Link the veriuser library. 2002-05-23 03:35:05 +00:00
steve ff90a5735d Export the vpi_vprintf function. 2002-05-23 03:34:46 +00:00
steve e6c0629626 Add language support for Verilog-2001 attribute
syntax. Hook this support into existing $attribute
 handling, and add number and void value types.

 Add to the ivl_target API new functions for access
 of complex attributes attached to gates.
2002-05-23 03:08:50 +00:00
steve 01efffedfc Ignore Named events in vcd signal scan. 2002-05-23 01:07:26 +00:00
steve 74c219f171 Add ranges and signed to port list declarations. 2002-05-20 02:06:01 +00:00
steve bf10c5762a Parse port_declaration_lists from the 2001 Standard. 2002-05-19 23:37:28 +00:00
steve ca9abaf0c5 Start the libveriuser library. 2002-05-19 05:21:00 +00:00
steve cfab250671 Add callbacks for vpiNamedEvent objects. 2002-05-19 05:18:16 +00:00
steve b1c0f7306d Add vpi support for named events.
Add vpi_mode_flag to track the mode of the
 vpi engine. This is for error checking.
2002-05-18 02:34:11 +00:00
steve a156d8b8ce Add vpiIndex update. 2002-05-17 16:13:08 +00:00
steve a7b7781fe9 Rewire vpiMemory and vpiMemoryWord handles to
support proper iteration of words, and the
 vpiIndex value.
2002-05-17 04:12:19 +00:00
steve 21fe6afe8d null terminate the reversed decimal string 2002-05-17 04:05:38 +00:00
steve 48da46986b Support set by string for reg objects. 2002-05-15 04:48:46 +00:00
steve 8d6239301f Count compile errors. 2002-05-15 01:25:25 +00:00
steve 2e6807493f Make clean should remove iverilog-vpi. 2002-05-15 01:25:07 +00:00
steve 94cef20e49 task calls and forks push the thread event in the queue. 2002-05-12 23:44:41 +00:00
steve c787a36af2 Accept errors in memory index expression. 2002-05-12 19:16:58 +00:00
steve da0c4c7565 Get thread vectors by vpiIntVal. 2002-05-12 00:32:21 +00:00
steve 9c28f085d8 Set and get memory words by string value. 2002-05-11 04:39:35 +00:00
steve e9af0c7485 Support scope iterate over vpiNet,vpiReg/vpiMemory. 2002-05-10 16:00:57 +00:00
steve be54bfdc21 ignore vpiMemory objects in vcd dumper. 2002-05-10 16:00:16 +00:00
steve c6a6f4bc79 Allow for C++ source files. 2002-05-10 03:54:46 +00:00
steve 88ae1b7b3c Handle null time and calltf pointers. 2002-05-09 03:34:31 +00:00
steve f5d3b78653 Use else clause instead of ! to preface wait events. 2002-05-07 05:06:07 +00:00
steve 68f1316eba Fix uninitialized memory accesses. 2002-05-07 04:15:43 +00:00
steve e70e04d6e8 Handle x case of unary ! properly. 2002-05-07 03:49:58 +00:00
steve a3eb6868ea Allow parameters in concatenation of widths are defined. 2002-05-06 02:30:27 +00:00
steve 186759c95e Do not need mangle.o unless vvm us used. 2002-05-06 00:50:38 +00:00
steve 8667b9a35d Put off evaluation of concatenation repeat expresions
until after parameters are defined. This allows parms
 to be used in repeat expresions.

 Add the builtin $signed system function.
2002-05-05 21:11:49 +00:00
steve 00defb0265 Credit for Mike Ruff amd Mike Runyan. 2002-05-04 03:19:35 +00:00
steve 822a085d97 Properly free vpi callback objects. 2002-05-04 03:17:29 +00:00
steve f23aec7f14 Add simulator event callbacks. 2002-05-04 03:03:17 +00:00
steve fb457128bf Add vpiModule iterator to vpiScope objects. 2002-05-03 15:44:11 +00:00
steve d126a414bd Spelling errors. 2002-04-30 04:26:42 +00:00
steve 844fe3b9bc Trim leading nulls from string forms. 2002-04-27 23:26:24 +00:00
steve 271855377f Support drawing vpiBinaryConst in hex. 2002-04-27 22:36:39 +00:00
steve 84020b16e3 Preserve stringiness string part select and concatenation. 2002-04-27 05:03:46 +00:00
steve c6035ab06e If the verinum is already right, no need to reset it. 2002-04-27 04:49:27 +00:00
steve d94a40ecd9 Display string verinums as strings. 2002-04-27 04:48:43 +00:00
steve c3be17ccae Dump parametres for system functions. 2002-04-27 04:20:52 +00:00
steve 10dc978778 Fixup eval of signed constants. 2002-04-27 03:17:15 +00:00
steve 7f8f0eb65a Support selecting bits from parameters. 2002-04-27 02:38:04 +00:00
steve c7107dc973 Evaluate constant bit select of constants. 2002-04-25 05:04:31 +00:00
steve 74eb544962 Dump bit select expressions. 2002-04-25 05:03:11 +00:00
steve 0696e3d558 Agressively evalutate case expressions. 2002-04-24 17:40:48 +00:00
steve 714ca3542d Fix compile time eval of signed <= signed. 2002-04-24 02:47:02 +00:00
steve 7e27217dac add -Wno- arguments to the driver. 2002-04-24 02:02:31 +00:00
steve 4a7e14786c Tail size was wrong. 2002-04-23 05:18:05 +00:00
steve 1ddb736f4c Handle bitsel muxes of odd shaped outputs. 2002-04-23 05:06:31 +00:00
steve 9ef49379f4 Add support for non-constant bit select. 2002-04-23 03:53:59 +00:00
steve 96213fe0ac Keep delays applied to BUFZ devices. 2002-04-22 03:15:25 +00:00
steve d482da4803 Reduce the while loop expression if needed. 2002-04-22 02:41:30 +00:00
steve 4502da608d Dump the while loop expression. 2002-04-22 02:40:32 +00:00
steve 0976fd393b Do not allow implicit wires in sensitivity lists. 2002-04-22 00:53:39 +00:00
steve 5882c6a481 Redo handling of assignment internal delays.
Leave it possible for them to be calculated
 at run time.
2002-04-21 22:31:02 +00:00
steve 52ea13819a Add the assign/d instruction for computed delays. 2002-04-21 22:29:49 +00:00
steve 048d044fdc Functions really do work. 2002-04-21 22:29:19 +00:00
steve 9dda15a186 implement nex_input for behavioral statements. 2002-04-21 17:43:12 +00:00
steve b094bbdcf4 Add support for conbinational events by finding
the inputs to expressions and some statements.
 Get case and assignment statements working.
2002-04-21 04:59:07 +00:00
steve eb708c1540 Support specified times in cbReadOnlySync, and
add support for cbReadWriteSync.
 Keep simulation time in a 64bit number.
2002-04-20 04:33:23 +00:00
steve 47a3b1f744 the command is gtkwave. 2002-04-20 02:42:58 +00:00
steve 76b5d7e9e1 Fix first_file test for timescale warning. 2002-04-18 18:38:37 +00:00
steve 0071c9b0aa More examples. 2002-04-18 03:25:16 +00:00
steve 0ab42597d9 Timescale warnings. 2002-04-15 00:04:22 +00:00
steve 95ccc1e904 lexor support for huge decimal numbers. 2002-04-14 21:42:01 +00:00
steve ea44866b2f Evaluate logical not at elaboration time. 2002-04-14 21:16:48 +00:00
steve 6d4c6b56f6 Fix constant evaluation of unary 2002-04-14 19:28:47 +00:00
steve f03ec88c2a Handle empty true case of conditional statements. 2002-04-14 19:19:21 +00:00
steve e630ecdb0d Ternary expressions can be signed. 2002-04-14 19:02:34 +00:00
steve eb27dc8db3 Support signed integer division. 2002-04-14 18:41:34 +00:00
steve 5cf7355c91 Precalculate unary - if possible. 2002-04-14 03:55:25 +00:00
steve 84bf0cee59 Vector constants to vpi_call can have sign. 2002-04-14 03:54:40 +00:00
steve a18662ed13 Allow signed constant vectors for call_vpi parameters. 2002-04-14 03:53:20 +00:00
steve 3275d1f252 Support signed expressions through to VPI. 2002-04-14 02:56:19 +00:00
steve b14a0b885a Fix bug removing pairs of ones in XOR. 2002-04-14 02:51:37 +00:00
steve e95a902b3d Show unary subexpressions. 2002-04-14 02:44:53 +00:00
steve 6733f7625b Detect missing indices to memories (PR#421) 2002-04-13 02:33:17 +00:00
steve f7f61a8696 Detect mismatches in reg as module items and ports. 2002-04-12 02:57:08 +00:00
steve e1a6bb10de Formally define extended arguments to vvp. 2002-04-12 02:44:02 +00:00
steve 07bee5ca72 Add $plusargs system functions. 2002-04-07 04:37:53 +00:00
steve fa97ba0d9a Set vpip_cur_task while calling compileft 2002-04-07 02:34:10 +00:00
steve bc95b02854 make install for iverilog-vpi 2002-04-07 00:50:13 +00:00
steve 1893e7c8e5 Add the iverilog-vpi command. 2002-04-07 00:47:10 +00:00
steve 0c04e2976b minor cleanup of formatting. 2002-04-07 00:46:21 +00:00
steve ac4fbb3e41 allow runtime selection of VCD vs LXT. 2002-04-06 21:33:29 +00:00
steve c98c24b9ff cbValueChange automatically replays. 2002-04-06 20:25:45 +00:00
steve 284c6fd85d Add dependency generation. 2002-04-04 05:26:13 +00:00
steve 3c8551ce90 Update for gcc 3.0 2002-03-31 04:07:40 +00:00
steve 65159a2733 Update for newer bison. 2002-03-31 04:06:49 +00:00
steve 007d702223 Notes about scheduling 2002-03-31 01:54:13 +00:00
steve 362b2aa604 vpip_bits_to_dec_str takes a bit array in a specific format. 2002-03-18 05:33:24 +00:00
steve de252965ac Add the .ufunc statement. 2002-03-18 00:19:34 +00:00
steve 7349a6beaf Generate port information in the .ufunc statement. 2002-03-18 00:18:50 +00:00
steve 828ca0ef9d Add API to support user defined function. 2002-03-17 19:30:20 +00:00
steve f5049c2f14 Do not push values through logic gates. 2002-03-17 05:48:49 +00:00
steve f77c7f3d18 Clean up edge detection code. 2002-03-17 03:24:34 +00:00
steve f75fb3cd95 Force the push flags to be explicit. 2002-03-17 03:23:10 +00:00
steve 8b9c26598a Patch to allow user to set place for temporary files. 2002-03-15 23:27:42 +00:00
steve 53600d3361 Pass the %f flag for the -tpal target. 2002-03-09 22:31:48 +00:00
steve 0dc5e5e29d Add LXT dumper support. (Anthony Bybell) 2002-03-09 21:54:48 +00:00
steve eae9153b40 Parse multiline definitions. 2002-03-09 06:37:49 +00:00
steve 3d646aa92c Constant expressions are not l-values for task ports. 2002-03-09 04:02:26 +00:00
steve b7c2bd4f72 Add the NetUserFunc netlist node. 2002-03-09 02:10:22 +00:00
steve b0a489fb7f Debug code for write to constants. 2002-03-08 05:41:45 +00:00
steve 01b9d5e023 Better linker error messages. 2002-03-05 05:31:52 +00:00
steve 6fa9415482 Initialize all the codes tables. 2002-03-01 05:43:59 +00:00
steve c159ff3134 Add cleanup to verbose messages. 2002-03-01 05:43:14 +00:00
steve efa5338e3b out-of-memory asserts. 2002-03-01 05:42:50 +00:00
steve 6dcf880482 carriage return is white space. 2002-02-27 05:46:33 +00:00
steve b5fbb82ba1 Make vvm optional, normally off. 2002-02-16 03:18:53 +00:00
steve ba8465abd2 Support pragma comments. 2002-02-15 05:20:58 +00:00
steve 0964dd99c5 Add writememb (Tom Verbeure) 2002-02-06 04:50:22 +00:00
steve a6a78f5776 Detect and skip suppressed values in display 2002-02-06 04:50:04 +00:00
steve 23f73390a4 support x and z in memory word binary values. 2002-02-06 04:49:24 +00:00
steve d55a890fdd get bin or hex string values of memory words. 2002-02-06 04:48:34 +00:00
steve 84de8f2b93 Add fpga.tgt to the file list. 2002-02-04 01:31:02 +00:00
steve 08dac488c1 Release 0.6 updates. 2002-02-04 00:48:30 +00:00
steve f2cff31b6e Clean up warnings. 2002-02-04 00:41:34 +00:00
steve 7c3f5c9fae Support print of version number. 2002-02-03 07:05:36 +00:00
steve aa16e82102 Fix parameter bit select check for magic constants. 2002-02-03 05:53:00 +00:00
steve ddd3566d50 Add CVS tokens. 2002-02-03 05:51:31 +00:00
steve ec82af0c74 Use Larrys bits-to-decimal-string code. 2002-02-03 01:01:51 +00:00
steve 78bb3d6f09 Comments about xor evaluation. 2002-02-03 00:06:28 +00:00
steve 54dab22042 event find_similar should not find self. 2002-02-02 06:13:38 +00:00
steve 9756cb6382 Propagate sign in unary minus. 2002-02-01 05:09:14 +00:00
steve 9fa0f95003 Full support for $readmem ranges (Tom Verbeure) 2002-01-31 04:28:17 +00:00
steve a624021a2e Detect duplicate port declarations. 2002-01-31 04:10:15 +00:00
steve 928df5caf7 include config.h to eliminate warnings. 2002-01-29 22:36:31 +00:00
steve 5796524f06 Add ne_expr.cc 2002-01-28 01:39:45 +00:00
steve b761a105b3 release candidate 0.6 2002-01-28 01:33:54 +00:00
steve 364ffc9024 Add support for bit select of parameters.
This leads to a NetESelect node and the
 vvp code generator to support that.
2002-01-28 00:52:41 +00:00
steve 712080f7e0 Detect scalar/vector declarion mismatch. 2002-01-26 05:28:28 +00:00
steve b906f4c0a1 Handle x in l-value of set/x 2002-01-26 02:08:07 +00:00
steve d48bb4d744 Tell check target where to find system.vpi. 2002-01-25 03:25:16 +00:00
steve d67ad166cd Support display of strings with umber formats. (Tom Verbeure) 2002-01-25 03:24:19 +00:00
steve 4e286ea86b Add the vpiLeft.. and vpiRightRange constants 2002-01-24 04:19:39 +00:00
steve a9be4e009f Spelling in comment. 2002-01-24 04:17:46 +00:00
steve 2f05d4b227 bison 1.31 doesnot include stdio.h 2002-01-24 03:57:45 +00:00
steve 0b68639f7d elaborate deassign lval as done for assign. 2002-01-23 05:56:22 +00:00
steve 5f09e01a44 No implicit declaration in assign l-values. 2002-01-23 05:23:17 +00:00
steve 6a98764b3b Load modules with RTLD_LAZY 2002-01-23 04:54:37 +00:00
steve 853c1f4387 Detect incorrect function ports. 2002-01-23 03:35:17 +00:00
steve b99c5aa394 Update for 0.6 release 2002-01-23 02:43:14 +00:00
steve 349be0f169 Precalculate constant results of memory index expressions. 2002-01-22 01:40:04 +00:00
steve 4f28f6a770 Better calcuation of dec string width (Larry Doolittle) 2002-01-22 00:18:10 +00:00
steve fcf64c0c38 More space efficient use of constant strings (Larry Doolittle) 2002-01-22 00:06:56 +00:00
steve da8d59757e return calculated oval from UDP (Stephan Boettcher) 2002-01-20 23:27:51 +00:00
steve a02cfe0f1b Evaluate case guards, if possible. 2002-01-19 20:09:56 +00:00
steve f3255121a2 Spelling fixes. 2002-01-19 19:22:39 +00:00
steve 608555ce7e Pass back target errors processing conditionals. 2002-01-19 19:02:08 +00:00
steve ec8b6e126e Default widths pad out as per the standard,
add $displayb/o/h et al., and some better
 error messages for incorrect formats.
2002-01-15 03:23:34 +00:00
steve a697157257 Support DesSTrVal for binary constants. 2002-01-15 03:21:18 +00:00
steve ec070ee65b Support vpiSize and vpiSigned for time objects. 2002-01-15 03:06:29 +00:00
steve 02f5ccd5d9 Handle constants with drive strength z 2002-01-12 17:49:41 +00:00
steve 361d4f2147 Drive strengths for continuous assignments. 2002-01-12 04:03:39 +00:00
steve c09a148cd9 Make BUFZ device strengths available. 2002-01-12 04:03:09 +00:00
steve b274dada85 Support the BUFZ logic device. 2002-01-12 04:02:16 +00:00
steve c6a937e2e7 The stime system function is 32bits. 2002-01-11 05:25:45 +00:00
steve 5840368f2d Handle certain special cases of stime. 2002-01-11 05:23:05 +00:00
steve dee52dd2d0 Magic stime object support. 2002-01-11 05:21:47 +00:00
steve a0e3b3386d Add the stime system function. 2002-01-11 05:20:59 +00:00
steve 6535b48c1c Add the %c format, and some warning messages. 2002-01-11 04:48:01 +00:00
steve 4d3611c5f1 odd width thread vectors as strings. 2002-01-10 01:54:04 +00:00
steve 77c4c88a4c String prints of non-round vectors (PR378) 2002-01-09 03:29:12 +00:00
steve 4291866b9f Add vpi_get_vlog_info support. 2002-01-09 03:15:23 +00:00
steve 8aef782411 Make lexor_keyword.cc for distributions. 2002-01-07 04:59:21 +00:00
steve 0aa033ddf3 Support scope for functors. (Stephan Boettcher) 2002-01-06 17:50:50 +00:00
steve edba542c7a Feedback output, not propagated output. (Stephan Boettcher) 2002-01-06 17:35:01 +00:00
steve 0e5289b022 Print a useful message for failed include file. 2002-01-06 04:51:31 +00:00
steve 6be3be0f16 Constant values have drive strengths. 2002-01-06 03:15:43 +00:00
steve 03d188fc52 Support weak functor inputs. 2002-01-06 03:15:13 +00:00
steve 6e1e658922 VPI access to root module scopes. 2002-01-06 00:48:39 +00:00
steve a87575a76e make check uses vvp instead of vvm. 2002-01-05 04:36:43 +00:00
steve 336624c7b9 include malloc.h only when available. 2002-01-05 04:36:06 +00:00
steve 71660fbaa5 Implement vpi_mcd_printf. 2002-01-04 02:26:36 +00:00
steve dd79885f6d Add structural modulus support down to vvp. 2002-01-03 04:19:01 +00:00
steve 51ffeb7c06 Use my own cfltype to defend against bison 1.30. 2002-01-02 02:39:34 +00:00
steve 912749342c Parse combinational event delay. 2001-12-31 05:23:13 +00:00
steve 4bb91c4f98 Elaborate multiply nets with constant operands ad NetConst. 2001-12-31 04:23:59 +00:00
steve 400580179f Get sense of 1-bit == operator right. 2001-12-31 01:56:08 +00:00
steve c9d6b5431d Remove test print 2001-12-31 00:39:20 +00:00
steve 51db00fb44 Support $signed cast of expressions. 2001-12-31 00:08:14 +00:00
steve e20acfc9f9 Include s indicator in dump of signed numbers. 2001-12-31 00:02:33 +00:00
steve a3fe753826 Account for negatives in cmp/s 2001-12-31 00:01:16 +00:00
steve 03aebd7525 Support elaborate_net for PEString objects. 2001-12-30 21:32:03 +00:00
steve fd5c0cfa28 Support vpiStringVal in vhtread vectors. 2001-12-30 21:31:38 +00:00
steve 357a0ff23e Detect bison and flex in configure.in 2001-12-30 17:20:33 +00:00
steve 1a22f37d92 Synthesize reduction logic. 2001-12-30 17:06:52 +00:00
steve a5890b914f Properly handle empty target in positionla parameter override. 2001-12-30 04:47:57 +00:00
steve b397b10104 Evaluate constant unary minus. 2001-12-30 00:39:25 +00:00
steve 5de8e0555c push events through event/or lists. 2001-12-29 23:59:06 +00:00
steve 91b01cd67e constant eval of arithmetic with x and z. 2001-12-29 22:10:10 +00:00
steve 9c6b17c887 Allow escaped $ in identifiers. 2001-12-29 20:41:30 +00:00
steve 000d187c94 Do not delete delay expressions of UDP instances. 2001-12-29 20:19:31 +00:00
steve 989e9d4d94 Newline can terminate escaped names. 2001-12-29 19:00:13 +00:00
steve 40ef704cc3 Evaluate constant right shifts. 2001-12-29 00:43:55 +00:00
steve 7c9fe0c173 clarify bufif output strenghts. 2001-12-19 23:43:03 +00:00
steve dddbeb957a Comments about MUX synthesis. 2001-12-18 05:34:02 +00:00
steve fd0cb30a4d Improved functor debug dumps. 2001-12-18 05:32:11 +00:00
steve 125c631091 Remove result length restrictions for vpi_get_value. 2001-12-18 05:31:54 +00:00
steve 443dc7853f Include config.h for namespace declaration. 2001-12-18 04:52:45 +00:00
steve a5400d7212 Support all 3 TRI net types. 2001-12-15 02:13:33 +00:00
steve da09d4c6e6 The IVL_SIT_WIRE type does not exist, it is a
synonym for IVL_SIT_TRI.
2001-12-15 02:13:17 +00:00
steve ace6b0a767 Give tri0 and tri1 their proper strengths. 2001-12-15 02:11:51 +00:00
steve 7d494fd3d5 Support tri0 and tri1 resolvers. 2001-12-15 01:54:38 +00:00
steve cd1524e6ca Generate notif functors. 2001-12-14 06:03:34 +00:00
steve a0526cdd32 Arrange bufif to support notif as well. 2001-12-14 06:03:17 +00:00
steve 4dd5f97a96 Parse and handle drive strengths of gates to vvp. 2001-12-14 02:05:13 +00:00
steve 1ca6fe5519 Support strength syntax on functors. 2001-12-14 02:04:49 +00:00
steve 6b2c604124 Better variable names for functor chunks. 2001-12-14 01:59:28 +00:00
steve e42775ea7f support toupper and tolower of file names. 2001-12-08 04:13:07 +00:00
steve a8c4729cf5 vpi_put_value of vpiIntVal for memory words. 2001-12-07 23:23:05 +00:00
steve c200c0c20e Support integer for function return value. 2001-12-07 05:03:13 +00:00
steve 4b174fd996 Forgot to evaluate UDP delays. 2001-12-06 05:04:49 +00:00
steve dbf5509f4f Support delays on UDP instances. 2001-12-06 04:44:11 +00:00
steve ec4f8c80d5 Support functor delays for gates and UDP devices.
(Stephan Boettcher)
2001-12-06 03:31:24 +00:00
steve c8319bcc02 Add ivl_logic_delay function to ivl_target. 2001-12-06 03:11:00 +00:00
steve 7bf480be9a Some bison versions choose different output names. 2001-12-06 02:55:24 +00:00
steve 2d3e85d941 Make sure fork labels are globally unique. 2001-12-05 05:41:20 +00:00
steve ab6c8cb4b8 Parser and pform use hierarchical names as hname_t
objects instead of encoded strings.
2001-12-03 04:47:14 +00:00
steve 33c7c47f73 Handle index identifiers in simple paths. 2001-12-01 02:42:39 +00:00
steve 64d7b1cee5 Support addresses in readmemh. 2001-12-01 02:40:10 +00:00
steve 0cebef872a Better synthesys of DFF w/ complex l-values. (Larry Doolittle) 2001-11-30 01:22:21 +00:00
steve 65f835f3eb Properly parse net_decl assignments with delays. 2001-11-29 17:37:51 +00:00
steve 8309c1f673 Preserve the text after ifdefs in the output. 2001-11-29 02:26:25 +00:00
steve e85347bf8b Handle part selects in l-values of DFF devices. 2001-11-29 01:58:18 +00:00
steve 86a4512848 Restore -Fxnfio to -txnf target. 2001-11-29 01:06:51 +00:00
steve 82831ea9a5 Use NetScope instead of string for scope path. 2001-11-22 06:20:59 +00:00
steve 98c145c3b6 Ignore foo and a.out. 2001-11-22 06:20:32 +00:00
steve a50fe36ef8 Ignore foo and a.out. 2001-11-22 04:44:23 +00:00
steve 7cbd710f7b Remove diag print. 2001-11-21 02:59:27 +00:00
steve 39ef2b7605 Pass list of file to ivlpp via temporary file. 2001-11-21 02:20:34 +00:00
steve da4901bb17 Close library files after parsing. 2001-11-20 23:36:34 +00:00
steve f28f5e01e5 Unary reduction operators are all 1-bit results. 2001-11-19 04:26:46 +00:00
steve e00aedd99b Handle padding out of logical values. 2001-11-19 04:25:46 +00:00
steve 9d1a81ce2c Handle division and modulus by zero while
evaluating run-time constants.
2001-11-19 02:54:12 +00:00
steve cfed3933fa Port close cropping behavior from mcrgb
Move window array reset to libmc.
2001-11-19 01:54:14 +00:00
steve 659624c71f Print typename is fallback expression node dump. 2001-11-19 01:46:38 +00:00
steve 6e0b77a8da Generate force code for variable l-values. 2001-11-18 01:28:18 +00:00
steve 54bb59ae99 Support compile on MacosX 10.1.1 (Timothy J. Wood) 2001-11-17 17:57:58 +00:00
steve cac941b272 More spelling. 2001-11-17 17:45:37 +00:00
steve 0be48388c2 Add support for +libext+ in command files. 2001-11-16 05:07:19 +00:00
steve d8970752b6 include stdlib.h for portability. 2001-11-16 04:22:27 +00:00
steve 08f0f5a1f7 DLL target support for force and release. 2001-11-14 03:28:49 +00:00
steve f8162be8c3 Describe +incdir and +define. 2001-11-14 03:28:15 +00:00
steve f50074de50 The +incdir+ plusarg can take multiple directores,
and add initial support for +define+ in the command file.
2001-11-13 03:30:26 +00:00
steve 9866fd01bd Support +incdir in command files, and ignore other
+args flags. Also ignore -a and -v flags.
2001-11-12 18:47:32 +00:00
steve d1ad10c90f More sophisticated command file parser. 2001-11-12 01:26:36 +00:00
steve 0045d7d1bf Remov XNF dead wood. 2001-11-11 00:10:05 +00:00
steve 4a74ae1795 Runtime support for functor delays. (Stephan Boettcher) 2001-11-10 18:07:11 +00:00
steve 4d0b840c26 Coerse input to inout when assigned to. 2001-11-10 02:08:49 +00:00
steve 0c7335a77d Spelling errors. 2001-11-09 03:43:26 +00:00
steve 7e8a538c20 Support $writememh 2001-11-09 03:39:21 +00:00
steve aca5afa95c Support vpiIntVal from memory. 2001-11-09 03:39:07 +00:00
steve 7793a49854 Remove string paths from PExpr elaboration. 2001-11-08 05:15:50 +00:00
steve 6bfbcbdcf7 elaborate_lnet uses scope instead of string path. 2001-11-07 04:26:46 +00:00
steve bf72f39fe9 eval_const uses scope instead of a string path. 2001-11-07 04:01:59 +00:00
steve fa23dafdae Use functor pointers where vvp_ipoint_t is unneeded. 2001-11-07 03:34:41 +00:00
steve 9572ddd7e8 Support more real arithmetic in delay constants. 2001-11-06 06:11:55 +00:00
steve 1ff36dc892 shift expressions can have definite widths. 2001-11-06 04:32:37 +00:00
steve bf9a8f5021 Code rearrange. (Stephan Boettcher) 2001-11-06 03:07:21 +00:00
steve 0c4bea473c Parse specparam parsepulse assignments. 2001-11-06 02:52:19 +00:00
steve 649428962e Pad limited r-values in continuous assignments. 2001-11-04 23:12:29 +00:00
steve cc5ddc0b6b MacOSX 10.1 updates. 2001-11-04 05:03:21 +00:00
steve b624b6002e Parse more [gosh darn] specify syntax. 2001-11-03 04:09:10 +00:00
steve af35736e04 initialize scope for %m in $fdisplay. 2001-11-02 05:56:47 +00:00
steve 58b5b583a7 Comment the scope type parser. 2001-11-02 05:43:11 +00:00
steve 9e385e6947 Implement split_node for symbol table (hendrik) 2001-11-02 04:48:03 +00:00
steve 560c003e03 make fork label into complete statemnt. 2001-11-01 19:31:40 +00:00
steve 1d045eea0d Catch ports that have no direction. 2001-11-01 05:21:26 +00:00
steve 7a0e73ef3d Handle procedural constant functor pointers. 2001-11-01 04:42:39 +00:00
steve 5d20dd63ec Generate code for deassign and cassign. 2001-11-01 04:26:57 +00:00
steve ab9a853d52 ivl_target support for cassign. 2001-11-01 04:25:31 +00:00
steve 82c0a2ebac Add force/cassign/release/deassign support. (Stephan Boettcher) 2001-11-01 03:00:19 +00:00
steve 75e78e86d3 ivl_target support for assign/deassign. 2001-10-31 05:24:52 +00:00
steve a75326e2e0 Rewrite the functor type to have fewer functor modes,
and use objects to manage the different types.
 (Stephan Boettcher)
2001-10-31 04:27:46 +00:00
steve b3e430c751 Give up if roots are missing. 2001-10-31 03:22:31 +00:00
steve faa3a62259 detect module ports not declared within the module. 2001-10-31 03:11:15 +00:00
steve 438605fad5 Account for new scope type syntax on scope. 2001-10-31 03:07:11 +00:00
steve 9505b586bf Generate IEEE1364-2000 line directives. 2001-10-30 21:53:27 +00:00
steve 40e7bc2450 line number in line directive is for the *next* line. 2001-10-30 21:46:56 +00:00
steve a9aaca1ffa Add ifndef support. 2001-10-30 20:48:55 +00:00
steve ce61d12f60 Stubs for assign/deassign for t-dll. 2001-10-30 02:52:07 +00:00
steve 874bab10e4 NetObj constructor finally requires a scope. 2001-10-28 01:14:53 +00:00
steve 21194c909a Propagate functor push, to make assign better. 2001-10-27 03:43:56 +00:00
steve 96a50d635d Minor rework of summation carry propagation (Stephan Boettcher) 2001-10-27 03:22:26 +00:00
steve 8c9e0bafa9 more specify syntax (Stehpan Boettcher) 2001-10-26 03:22:56 +00:00
steve b3bb79992a const/non-const warnings. (Stephan Boettcher) 2001-10-26 02:29:10 +00:00
steve 4e92501864 VPI support for callback to return values. 2001-10-25 04:19:53 +00:00
steve d83fb10774 The ! expression returns 0 to x and z values. 2001-10-24 05:06:54 +00:00
steve 5a6cca33a0 Write resolvers before the .functor (PR#300) 2001-10-24 03:43:45 +00:00
steve b2f6953259 npmos outputs have 3bit strengths, not 2. 2001-10-24 03:18:52 +00:00
steve b1f1f74920 Support bit selects of non-0 lsb for vectors. 2001-10-23 04:22:41 +00:00
steve 2adea8de48 Fix carry between works for %add instruction. 2001-10-23 03:49:13 +00:00
steve 859318becd The -s flag can now be repeated on the iverilog command. 2001-10-23 00:37:29 +00:00
steve 55fb219503 document the -y flag. 2001-10-23 00:36:54 +00:00
steve b01316ce12 Better error message for mising root module. 2001-10-22 23:26:37 +00:00
steve 1921e19635 fix constant overrun in | operands. 2001-10-22 15:31:21 +00:00
steve 990df42407 Handle activating tasks in another root. 2001-10-22 02:05:20 +00:00
steve 924b4e0062 unused idx warning. 2001-10-22 02:04:37 +00:00
steve 0e43dfb285 Remove useless code for drawing .var inputs. 2001-10-22 00:04:51 +00:00
steve 46621d3c83 wrong variable for clk input to memory. 2001-10-21 23:38:16 +00:00
steve fa95f7ff3b Kill const-nonconst warning. 2001-10-21 23:37:49 +00:00
steve e45546e6f3 Install pdf version of the man pages. 2001-10-21 21:59:49 +00:00
steve d79d48ffeb clean up API for restarting parser. 2001-10-21 20:18:56 +00:00
steve 467ecf5b33 Error messages for missing UDP port declarations. 2001-10-21 01:55:24 +00:00
steve 9f3e64e11a Module types in pform are char* instead of string. 2001-10-21 00:42:47 +00:00
steve 56954356db Catch and X division by 0. 2001-10-20 23:20:32 +00:00
steve 6466d02eda Add automatic module libraries. 2001-10-20 23:02:39 +00:00
steve 7a149a6943 Scope/module names are char* instead of string. 2001-10-20 05:21:51 +00:00
steve acf3a4ec16 Print memory usage information if requested (Stephan Boettcher) 2001-10-20 01:03:42 +00:00
steve 5c4b87675f Evaluate constant == when operands differ in width. 2001-10-20 00:11:24 +00:00
steve 83d3a60d5c Add trailing ; to fork-join out labels. 2001-10-19 23:52:36 +00:00
steve 3e4eb17b15 Another go at getting link of ivl.exe right. 2001-10-19 23:15:01 +00:00
steve 1075b28f26 export the ivl_design_roots function. 2001-10-19 23:14:46 +00:00
steve 943527c526 Fix memory fault with -c flag. 2001-10-19 23:10:08 +00:00
steve d350620315 Support multiple root modules (Philip Blundell) 2001-10-19 21:53:24 +00:00
steve 6fc556cefc Method to get the type_ member 2001-10-19 01:55:32 +00:00
steve 73283768a5 Support rnpmos devices. (Philip Blundell) 2001-10-18 17:30:25 +00:00
steve ce7d64f427 Evaluate string expressions (Philip Blundell) 2001-10-18 16:41:49 +00:00
steve 84b70be7ee Include HAVE_SYS_WAIT in config.h (PR#306) 2001-10-18 16:16:23 +00:00
steve 3924c51097 Support vpiVectorVal for signals. (Philip Blundell) 2001-10-18 04:52:31 +00:00
steve 4bb1bd4315 Get Division error into the division method! 2001-10-16 03:10:20 +00:00
steve 0164ad78be Catch division by zero in .arith/div. 2001-10-16 03:06:18 +00:00
steve 36e1eab3f4 Add arith/div object. 2001-10-16 02:47:37 +00:00
steve 177fa4062b Support IVL_LPM_DIVIDE for structural divide. 2001-10-16 02:19:26 +00:00
steve 821c68696d Generate %div instructions for binary /. 2001-10-16 01:27:17 +00:00
steve a3217db7b2 Add %div support (Anthony Bybell) 2001-10-16 01:26:54 +00:00
steve 42dab181cd Carry the type of the scope (Stephan Boettcher) 2001-10-15 02:58:27 +00:00
steve 98d71de50f sign warning. 2001-10-15 02:55:03 +00:00
steve c596e1cda1 Include scope information in VCD output. 2001-10-15 01:50:23 +00:00
steve 706f2ffc89 Support getting scope of scope, and scope of signals. 2001-10-15 01:49:50 +00:00
steve a7054a91e5 libiberty is needed for mingw, and useable under cygwin. 2001-10-14 19:54:05 +00:00
steve ad44b411fb Try appending .vpi to module names with directories. 2001-10-14 18:42:46 +00:00
steve f7fa2f1f4d More coverage of $dump related commands. 2001-10-14 18:32:06 +00:00
steve 2fcab15704 Forgot to propagate carry. 2001-10-14 17:36:18 +00:00
steve cfbad49d33 Very wide multiplication (Anthony Bybell) 2001-10-14 16:36:43 +00:00
steve 9dbcb32808 vvm support for pullup/down gates (PR#288) 2001-10-14 03:50:53 +00:00
steve 1b69bb5d2f Handle mode-42 functor init. 2001-10-14 03:41:58 +00:00
steve 2326672b3a Handle constant bits in arithmetic expressions. 2001-10-14 03:24:35 +00:00
steve 393a76d57a threshold of $width is optional. 2001-10-14 02:03:51 +00:00
steve 4b3b41cd79 Propogate strength-only changes from resolver. 2001-10-14 01:45:11 +00:00
steve eab5793dda Account for non-0 start address for memories (Stephan Boettcher) 2001-10-14 01:36:12 +00:00
steve 6cf2ddf541 M42 implementation of mode 2 (Stephan Boettcher) 2001-10-12 03:00:08 +00:00
steve ad6bbe539f functor lookup includes vpi signal search. 2001-10-12 02:53:47 +00:00
steve f12864f69e Propagate initial value of UDP. 2001-10-11 18:29:21 +00:00
steve b61c89c104 npmos devices pass strength. 2001-10-11 18:20:51 +00:00
steve 0def3c9983 Initialize attributes for bufz devices. 2001-10-11 00:13:19 +00:00
steve 9e5dc17c1d Detect execv failures. 2001-10-11 00:12:49 +00:00
steve 36d36d99f3 Generate BUF devices for bufz logic. 2001-10-11 00:12:28 +00:00
steve de985ac3fd Document the behavioral reduction or. 2001-10-10 04:48:12 +00:00
steve 245905aeda Support vectors as operands to logical and. 2001-10-10 04:47:43 +00:00
steve ac6caaf29e More make install details. 2001-10-09 23:05:10 +00:00
steve 3734b5e7f1 spec reference events can be identifiers. 2001-10-09 18:11:58 +00:00
steve 789efb9832 Collect functor reference handling into a single function. (Stephan Boettcher) 2001-10-09 16:57:47 +00:00
steve c7bc35ad75 get CFLAGS from configure 2001-10-09 16:50:17 +00:00
steve 5071ce8575 handle nmos and pmos devices. 2001-10-09 02:28:44 +00:00
steve 64ff74df37 Add the PMOS and NMOS functor types. 2001-10-09 02:28:16 +00:00
steve 181066311b Tasks can have sub-scopes. 2001-10-09 02:01:04 +00:00
steve 20ad433f8c Fix pr283: signal values before enddefinitions in vcd. (Stephan Boettcher) 2001-10-08 23:33:00 +00:00
steve 494b5ff1ee parameter names do not have defined size. 2001-10-07 03:38:08 +00:00
steve cbd501b865 Fix some Cygwin DLL handling. (Venkat Iyer) 2001-09-30 16:45:10 +00:00
steve 41384a0e41 Reduce VCD output by removing duplicates. (Stephan Boettcher) 2001-09-30 05:18:46 +00:00
steve 3854e12024 Fencepost error in memory writes. (Stephan Boettcher) 2001-09-29 20:55:42 +00:00
steve ff55af1e9e Check address is in range for set. (Stephan Boettcher) 2001-09-29 04:45:20 +00:00
steve bdf643ddb1 Generate code for unary minus (PR#272) 2001-09-29 04:37:44 +00:00
steve d46465845c Fix the size of unsized constant operants to compare (PR#274) 2001-09-29 01:53:22 +00:00
steve dd75595082 Handle short l-values to concatenation. 2001-09-20 03:46:38 +00:00
steve a73cfbc2b5 MacOS X compile time changes. (Timothy Wood) 2001-09-20 03:21:01 +00:00
steve 21c844363a Change UDP output only if table matches. 2001-09-19 04:10:40 +00:00
steve 3109906514 Detect C name mangling for dlsym. 2001-09-17 22:26:33 +00:00
steve 606eb2b3cd Support the cellref attribute. 2001-09-16 22:26:47 +00:00
steve e99059e001 Support attributes to logic gates. 2001-09-16 22:19:42 +00:00
steve cefbb635c1 Suppor the PAD attribute on signals. 2001-09-16 01:48:16 +00:00
steve b2b8b89cd8 Make configure detect malloc.h 2001-09-15 18:27:04 +00:00
steve 92760f2c5f Support != in virtex code generator. 2001-09-15 05:06:04 +00:00
steve 176be94be9 dead code. 2001-09-14 04:20:49 +00:00
steve 9fda809fa6 Add XOR and XNOR gates. 2001-09-14 04:17:20 +00:00
steve 3c8d598eed Elaborate == to NetCompare instead of XNOR and AND
gates. This allows code generators to generate
 better code in certain cases.
2001-09-14 04:16:52 +00:00
steve f2068e83d4 Generate code for identity comparators. 2001-09-14 04:15:46 +00:00
steve 5976e7078c Xilinx uses GROUND and VCC as pin names for the
GND and VCC devices.

 Connect the top end of the EQ chain to the MUXCY
 instead of to the LUT. The MUXCY has the real output.
2001-09-12 04:35:25 +00:00
steve da9a84ed84 Use carry mux to implement wide identity compare,
Place property item in correct place in LUT cell list.
2001-09-11 05:52:31 +00:00
steve 03b635604a initial structural memory propagation (Stephan Boettcher) 2001-09-11 01:54:58 +00:00
steve 167f94bdbf Add 4 wide identity compare. 2001-09-10 03:48:34 +00:00
steve 4507351d48 Virtex support for mux devices and adders
with carry chains. Also, make Virtex specific
 implementations of primitive logic.
2001-09-09 22:23:28 +00:00
steve 0253f92e7e pin down some enumerated constants. 2001-09-09 22:21:57 +00:00
steve 432d4efc9b Connect right ANEB pin when doing NE comparator. 2001-09-09 16:49:04 +00:00
steve 749c3eb5a7 No code for unlinked constants. 2001-09-08 01:23:21 +00:00
steve e933b56507 extend xz from the top character, not the second-from-top. 2001-09-08 01:22:55 +00:00
steve 0c5ce9dfec Redo of_SUBU in a more obvious algorithm, that
is not significantly slower. Also, clean up the
 implementation of %mov from a constant.

 Fix initial clearing of vector by vector_to_array
2001-09-07 23:29:28 +00:00
steve acde444439 Separate the virtex and generic-edif code generators. 2001-09-06 04:28:39 +00:00
362 changed files with 42007 additions and 14783 deletions
+5
View File
@@ -2,9 +2,14 @@ lexor_keyword.cc
parse.h
parse.cc
parse.cc.output
parse.output
syn-rules.cc
syn-rules.cc.output
syn-rules.output
lexor.cc
iverilog-vpi
iverilog-vpi.pdf
iverilog-vpi.ps
ivl
ivl.exp
dep
+33 -12
View File
@@ -16,8 +16,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: Attrib.cc,v 1.2 2001/07/25 03:10:48 steve Exp $"
#ifdef HAVE_CVS_IDENT
#ident "$Id: Attrib.cc,v 1.5 2002/08/12 01:34:58 steve Exp $"
#endif
# include "config.h"
@@ -36,14 +36,15 @@ Attrib::~Attrib()
delete[] list_;
}
void Attrib::set_attributes(const map<string,string>&attr)
#if 0
void Attrib::copy_attributes(const map<string,verinum>&attr)
{
assert(list_ == 0);
nlist_ = attr.size();
list_ = new cell_[nlist_];
map<string,string>::const_iterator idx;
map<string,verinum>::const_iterator idx;
unsigned jdx;
for (idx = attr.begin(), jdx = 0 ; idx != attr.end() ; idx ++, jdx++) {
struct cell_*tmp = list_ + jdx;
@@ -51,8 +52,9 @@ void Attrib::set_attributes(const map<string,string>&attr)
tmp->val = (*idx).second;
}
}
#endif
string Attrib::attribute(const string&key) const
const verinum& Attrib::attribute(const string&key) const
{
for (unsigned idx = 0 ; idx < nlist_ ; idx += 1) {
@@ -60,10 +62,11 @@ string Attrib::attribute(const string&key) const
return list_[idx].val;
}
return "";
static const verinum null;
return null;
}
void Attrib::attribute(const string&key, const string&value)
void Attrib::attribute(const string&key, const verinum&value)
{
unsigned idx;
@@ -92,7 +95,7 @@ bool Attrib::has_compat_attributes(const Attrib&that) const
for (idx = 0 ; idx < that.nlist_ ; idx += 1) {
string tmp = attribute(that.list_[idx].key);
verinum tmp = attribute(that.list_[idx].key);
if (tmp != that.list_[idx].val)
return false;
}
@@ -100,18 +103,18 @@ bool Attrib::has_compat_attributes(const Attrib&that) const
return true;
}
unsigned Attrib::size() const
unsigned Attrib::attr_cnt() const
{
return nlist_;
}
string Attrib::key(unsigned idx) const
const char* Attrib::attr_key(unsigned idx) const
{
assert(idx < nlist_);
return list_[idx].key;
return list_[idx].key.c_str();
}
string Attrib::value(unsigned idx) const
const verinum& Attrib::attr_value(unsigned idx) const
{
assert(idx < nlist_);
return list_[idx].val;
@@ -120,6 +123,24 @@ string Attrib::value(unsigned idx) const
/*
* $Log: Attrib.cc,v $
* Revision 1.5 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.4 2002/05/26 01:39:02 steve
* Carry Verilog 2001 attributes with processes,
* all the way through to the ivl_target API.
*
* Divide signal reference counts between rval
* and lval references.
*
* Revision 1.3 2002/05/23 03:08:50 steve
* Add language support for Verilog-2001 attribute
* syntax. Hook this support into existing $attribute
* handling, and add number and void value types.
*
* Add to the ivl_target API new functions for access
* of complex attributes attached to gates.
*
* Revision 1.2 2001/07/25 03:10:48 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
+29 -11
View File
@@ -18,12 +18,12 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: Attrib.h,v 1.1 2000/12/04 17:37:03 steve Exp $"
#ifdef HAVE_CVS_IDENT
#ident "$Id: Attrib.h,v 1.4 2002/08/12 01:34:58 steve Exp $"
#endif
# include <string>
# include <map>
# include "verinum.h"
/*
* This class keeps a map of key/value pairs. The map can be set from
@@ -35,21 +35,21 @@ class Attrib {
Attrib();
~Attrib();
void set_attributes(const map<string,string>&attr);
string attribute(const string&key) const;
void attribute(const string&key, const string&value);
const verinum&attribute(const string&key) const;
void attribute(const string&key, const verinum&value);
bool has_compat_attributes(const Attrib&that) const;
/* Provide a means of iterating over the entries in the map. */
unsigned size() const;
string key(unsigned idx) const;
string value(unsigned idx) const;
unsigned attr_cnt() const;
const char* attr_key(unsigned idx) const;
const verinum& attr_value(unsigned idx) const;
private:
struct cell_ {
string key;
string val;
string key;
verinum val;
};
unsigned nlist_;
@@ -62,6 +62,24 @@ class Attrib {
/*
* $Log: Attrib.h,v $
* Revision 1.4 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.3 2002/05/26 01:39:02 steve
* Carry Verilog 2001 attributes with processes,
* all the way through to the ivl_target API.
*
* Divide signal reference counts between rval
* and lval references.
*
* Revision 1.2 2002/05/23 03:08:50 steve
* Add language support for Verilog-2001 attribute
* syntax. Hook this support into existing $attribute
* handling, and add number and void value types.
*
* Add to the ivl_target API new functions for access
* of complex attributes attached to gates.
*
* Revision 1.1 2000/12/04 17:37:03 steve
* Add Attrib class for holding NetObj attributes.
*
+279
View File
@@ -0,0 +1,279 @@
/*
* Copyright (c) 2001 Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: HName.cc,v 1.5 2002/11/02 03:27:52 steve Exp $"
#endif
# include "config.h"
# include "HName.h"
# include <iostream>
# include <string.h>
# include <stdlib.h>
#ifdef HAVE_MALLOC_H
# include <malloc.h>
#endif
hname_t::hname_t()
{
item_ = 0;
count_ = 0;
}
hname_t::hname_t(const char*text)
{
item_ = strdup(text);
count_ = 1;
}
hname_t::hname_t(const hname_t&that)
{
count_ = that.count_;
switch (count_) {
case 0:
item_ = 0;
break;
case 1:
item_ = strdup(that.item_);
break;
default:
array_ = new char*[count_];
for (unsigned idx = 0 ; idx < count_ ; idx += 1)
array_[idx] = strdup(that.array_[idx]);
break;
}
}
hname_t::~hname_t()
{
switch (count_) {
case 0:
break;
case 1:
free(item_);
break;
default:
for (unsigned idx = 0 ; idx < count_ ; idx += 1)
free(array_[idx]);
delete[]array_;
break;
}
}
unsigned hname_t::component_count() const
{
return count_;
}
void hname_t::append(const char*text)
{
char**tmp;
switch (count_) {
case 0:
count_ = 1;
item_ = strdup(text);
break;
case 1:
count_ = 2;
tmp = new char*[2];
tmp[0] = item_;
tmp[1] = strdup(text);
array_ = tmp;
break;
default:
tmp = new char*[count_+1];
for (unsigned idx = 0 ; idx < count_ ; idx += 1)
tmp[idx] = array_[idx];
delete[]array_;
array_ = tmp;
array_[count_] = strdup(text);
count_ += 1;
}
}
void hname_t::prepend(const char*text)
{
char**tmp;
switch (count_) {
case 0:
count_ = 1;
item_ = strdup(text);
break;
case 1:
count_ = 2;
tmp = new char*[2];
tmp[0] = strdup(text);
tmp[1] = item_;
array_ = tmp;
break;
default:
tmp = new char*[count_+1];
tmp[0] = strdup(text);
for (unsigned idx = 0 ; idx < count_ ; idx += 1)
tmp[idx+1] = array_[idx];
delete[]array_;
array_ = tmp;
count_ += 1;
}
}
char* hname_t::remove_tail_name()
{
if (count_ == 0)
return 0;
if (count_ == 1) {
char*tmp = item_;
count_ = 0;
item_ = 0;
return tmp;
}
if (count_ == 2) {
char*tmp1 = array_[0];
char*tmp2 = array_[1];
delete[]array_;
count_ = 1;
item_ = tmp1;
return tmp2;
}
char*tmpo = array_[count_-1];
char**tmpa = new char*[count_-1];
for (unsigned idx = 0 ; idx < count_-1 ; idx += 1)
tmpa[idx] = array_[idx];
delete[]array_;
array_ = tmpa;
count_ -= 1;
return tmpo;
}
const char* hname_t::peek_name(unsigned idx) const
{
if (idx >= count_)
return 0;
if (count_ == 1)
return item_;
return array_[idx];
}
const char* hname_t::peek_tail_name() const
{
switch (count_) {
case 0:
return 0;
case 1:
return item_;
default:
return array_[count_-1];
}
}
bool operator < (const hname_t&l, const hname_t&r)
{
unsigned idx = 0;
const char*lc = l.peek_name(idx);
const char*rc = r.peek_name(idx);
while (lc && rc) {
int cmp = strcmp(lc, rc);
if (cmp < 0)
return true;
if (cmp > 0)
return false;
idx += 1;
lc = l.peek_name(idx);
rc = r.peek_name(idx);
}
if (lc && !rc)
return false;
if (rc && !lc)
return true;
// Must be ==
return false;
}
bool operator == (const hname_t&l, const hname_t&r)
{
unsigned idx = 0;
const char*lc = l.peek_name(idx);
const char*rc = r.peek_name(idx);
while (lc && rc) {
int cmp = strcmp(lc, rc);
if (cmp != 0)
return false;
idx += 1;
lc = l.peek_name(idx);
rc = r.peek_name(idx);
}
if (lc || rc)
return false;
// Must be ==
return true;
}
ostream& operator<< (ostream&out, const hname_t&that)
{
switch (that.count_) {
case 0:
out << "";
return out;
case 1:
out << that.item_;
return out;
default:
out << that.array_[0];
for (unsigned idx = 1 ; idx < that.count_ ; idx += 1)
out << "." << that.array_[idx];
return out;
}
}
/*
* $Log: HName.cc,v $
* Revision 1.5 2002/11/02 03:27:52 steve
* Allow named events to be referenced by
* hierarchical names.
*
* Revision 1.4 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.3 2002/01/05 04:36:06 steve
* include malloc.h only when available.
*
* Revision 1.2 2001/12/18 04:52:45 steve
* Include config.h for namespace declaration.
*
* Revision 1.1 2001/12/03 04:47:14 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
*
*/
+101
View File
@@ -0,0 +1,101 @@
#ifndef __HName_H
#define __HName_H
/*
* Copyright (c) 2001 Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: HName.h,v 1.4 2002/11/02 03:27:51 steve Exp $"
#endif
# include <iostream>
#ifdef __GNUC__
#if __GNUC__ > 2
using namespace std;
#endif
#endif
/*
* This class represents a Verilog hierarchical name. A hierarchical
* name is an ordered list of simple names.
*/
class hname_t {
public:
hname_t ();
explicit hname_t (const char*text);
hname_t (const hname_t&that);
~hname_t();
// This method adds a name to the end of the hierarchical
// path. This becomes a new base name.
void append(const char*text);
// This method adds a name to the *front* of the hierarchical
// path. The base name remains the same, unless this is the
// only component.
void prepend(const char*text);
// This method removes the tail name from the hierarchy, and
// returns a pointer to that tail name. That tail name now
// must be removed by the caller.
char* remove_tail_name();
// Return the given component in the hierarchical name. If the
// idx is too large, return 0.
const char*peek_name(unsigned idx) const;
const char*peek_tail_name() const;
// Return the number of components in the hierarchical
// name. If this is a simple name, this will return 1.
unsigned component_count() const;
friend ostream& operator<< (ostream&, const hname_t&);
private:
union {
char**array_;
char* item_;
};
unsigned count_;
private: // not implemented
hname_t& operator= (const hname_t&);
};
extern bool operator < (const hname_t&, const hname_t&);
extern bool operator == (const hname_t&, const hname_t&);
/*
* $Log: HName.h,v $
* Revision 1.4 2002/11/02 03:27:51 steve
* Allow named events to be referenced by
* hierarchical names.
*
* Revision 1.3 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.2 2002/06/14 03:25:51 steve
* Compiler portability.
*
* Revision 1.1 2001/12/03 04:47:14 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
*
*/
#endif
+5 -2
View File
@@ -16,8 +16,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: LineInfo.cc,v 1.2 2001/07/25 03:10:48 steve Exp $"
#ifdef HAVE_CVS_IDENT
#ident "$Id: LineInfo.cc,v 1.3 2002/08/12 01:34:58 steve Exp $"
#endif
# include "config.h"
@@ -44,6 +44,9 @@ void LineInfo::set_line(const LineInfo&that)
/*
* $Log: LineInfo.cc,v $
* Revision 1.3 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.2 2001/07/25 03:10:48 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
+5 -2
View File
@@ -18,8 +18,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: LineInfo.h,v 1.5 2000/11/30 17:31:42 steve Exp $"
#ifdef HAVE_CVS_IDENT
#ident "$Id: LineInfo.h,v 1.6 2002/08/12 01:34:58 steve Exp $"
#endif
# include <string>
@@ -52,6 +52,9 @@ class LineInfo {
/*
* $Log: LineInfo.h,v $
* Revision 1.6 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.5 2000/11/30 17:31:42 steve
* Change LineInfo to store const C strings.
*
+108 -40
View File
@@ -16,12 +16,16 @@
# 59 Temple Place - Suite 330
# Boston, MA 02111-1307, USA
#
#ident "$Id: Makefile.in,v 1.103 2001/08/10 00:40:00 steve Exp $"
#ident "$Id: Makefile.in,v 1.140 2002/12/10 05:45:44 steve Exp $"
#
#
SHELL = /bin/sh
VERSION = 0.5
# This version string is only used in the version message printed
# by the compiler. It reflects the assigned version number for the
# product as a whole. Most components also print the CVS Name: token
# in order to get a more automatic version stamp as well.
VERSION = 0.7
prefix = @prefix@
exec_prefix = @exec_prefix@
@@ -34,9 +38,11 @@ VPATH = $(srcdir)
bindir = @bindir@
libdir = @libdir@
includedir = $(prefix)/include
mandir = @mandir@
dllib=@DLLIB@
rdynamic=@rdynamic@
strip_dynamic=@strip_dynamic@
CC = @CC@
CXX = @CXX@
@@ -45,6 +51,8 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
STRIP = @STRIP@
LEX = @LEX@
YACC = @YACC@
CPPFLAGS = @CPPFLAGS@ @DEFS@
CXXFLAGS = @CXXFLAGS@ -I. -I$(srcdir)
@@ -59,13 +67,11 @@ ifeq ('@HAVE_IPAL@','yes')
TARGETS += tgt-pal
endif
all: ivl@EXEEXT@ libvpi.a
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) all); done
cd vvm ; $(MAKE) all
for dir in $(SUBDIRS) ; do (cd $$dir ; $(MAKE) all); done
cd vpi ; $(MAKE) all
cd ivlpp ; $(MAKE) all
cd driver ; $(MAKE) all
cd driver ; $(MAKE) VERSION=$(VERSION) all
cd tgt-verilog ; $(MAKE) all
cd tgt-stub ; $(MAKE) all
for tgt in $(TARGETS); do (cd $$tgt ; $(MAKE) all); done
@@ -76,19 +82,24 @@ ifeq (@WIN32@,yes)
all: dosify.exe
dosify.exe: dosify.c
$(CC) -o dosify.exe dosify.c
ifeq (@MINGW32@,yes)
SUBDIRS += driver-vpi
endif
else
all: iverilog-vpi
endif
# This rule rules the compiler in the trivial hello.vl program to make
# sure the basics were compiled properly.
check: all
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) check); done
driver/iverilog -Ccheck.conf -ocheck -tvvm-check -B./ivlpp examples/hello.vl
$(CXX) -o check $(rdynamic) -fno-exceptions -I$(srcdir) -I$(srcdir)/vvm -I$(srcdir)/vpip -Lvvm -Lvpip check.cc -lvvm -lvpip $(dllib)
./check | grep 'Hello, World'
driver/iverilog -Ccheck.conf -ocheck.vvp -tvvp-check -B./ivlpp $(srcdir)/examples/hello.vl
vvp/vvp -M./vpi ./check.vvp | grep 'Hello, World'
clean:
rm -f *.o parse.cc parse.cc.output parse.h dep/*.d lexor.cc lexor_keyword.cc ivl@EXEEXT@ libivl.a libvpi.a
cd vvm ; $(MAKE) clean
rm -f *.o parse.cc parse.cc.output parse.h dep/*.d lexor.cc lexor_keyword.cc ivl@EXEEXT@ libivl.a libvpi.a iverilog-vpi
cd vpi ; $(MAKE) clean
cd driver ; $(MAKE) clean
cd ivlpp ; $(MAKE) clean
@@ -100,29 +111,30 @@ clean:
distclean: clean
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) distclean); done
for tgt in $(TARGETS); do (cd $$tgt ; $(MAKE) distclean); done
rm -f vvm/Makefile
rm -f vpi/Makefile
rm -f ivlpp/Makefile
rm -f driver/Makefile
rm -f config.status config.cache config.log
rm -f Makefile
rm -f tgt-pal/Makefile tgt-stub/Makefile tgt-verilog/Makefile
TT = t-dll.o t-dll-api.o t-dll-expr.o t-dll-proc.o t-vvm.o t-xnf.o
FF = nodangle.o synth.o syn-rules.o xnfio.o
TT = t-dll.o t-dll-api.o t-dll-expr.o t-dll-proc.o t-xnf.o
FF = cprop.o nodangle.o synth.o synth2.o syn-rules.o xnfio.o
O = main.o cprop.o design_dump.o dup_expr.o elaborate.o elab_expr.o \
O = main.o async.o design_dump.o dup_expr.o elaborate.o elab_expr.o \
elab_lval.o elab_net.o elab_anet.o elab_pexpr.o elab_scope.o \
elab_sig.o emit.o eval.o eval_rconst.o \
elab_sig.o emit.o eval.o eval_attrib.o eval_rconst.o \
eval_tree.o expr_synth.o functor.o lexor.o lexor_keyword.o link_const.o \
mangle.o netlist.o netmisc.o net_assign.o \
net_design.o net_event.o net_force.o net_link.o net_modulo.o net_proc.o \
net_scope.o net_udp.o pad_to_width.o \
load_module.o netlist.o netmisc.o net_assign.o \
net_design.o net_event.o net_expr.o net_force.o net_func.o \
net_link.o net_modulo.o net_nex_input.o net_nex_output.o \
net_proc.o net_scope.o net_udp.o pad_to_width.o \
parse.o parse_misc.o pform.o pform_dump.o \
set_width.o \
verinum.o verireal.o target.o targets.o util.o \
Attrib.o LineInfo.o Module.o PDelays.o PEvent.o \
set_width.o sync.o \
verinum.o verireal.o target.o targets.o \
Attrib.o HName.o LineInfo.o Module.o PDelays.o PEvent.o \
PExpr.o PGate.o \
PTask.o PFunction.o PWire.o Statement.o \
PTask.o PFunction.o PWire.o Statement.o StringHeap.o \
$(FF) $(TT)
Makefile: Makefile.in config.h.in config.status
@@ -132,6 +144,7 @@ Makefile: Makefile.in config.h.in config.status
libvpi.a: vpithunk.o
rm -f $@
ar cvq $@ vpithunk.o
ranlib $@
# The vpithunk.c file (that makes up the libvpi.a library) needs to
# be make with PIC flags, because shared objects load it.
@@ -142,12 +155,14 @@ vpithunk.o: vpithunk.c
ifeq (@WIN32@,yes)
# Under Windows (mingw) I need to make the ivl.exe in two steps.
# The first step makes an ivl.exe that dlltool can use to make an
# export and import library, and the last link makes a, ivl.exe
# that really exports the things that the import library imports.
ivl@EXEEXT@: $O ivl.def
$(CXX) -o ivl@EXEEXT@ $O $(dllib) @EXTRALIBS@
dlltool --dllname ivl@EXEEXT@ --def ivl.def \
--output-lib libivl.a --output-exp ivl.exp
# $(CXX) -o ivl@EXEEXT@ -Wl,--base-file,ivl.base ivl.exp $O $(dllib)
# dlltool --dllname ivl@EXEEXT@ --base-file ivl.base \
# --output-exp ivl.exp --def ivl.def
$(CXX) -o ivl@EXEEXT@ ivl.exp $O $(dllib) @EXTRALIBS@
else
ivl@EXEEXT@: $O
@@ -155,9 +170,18 @@ ivl@EXEEXT@: $O
endif
ifeq (@WIN32@,yes)
else
iverilog-vpi: iverilog-vpi.sh
sed -e 's;@SHARED@;@shared@;' -e 's;@PIC@;@PICFLAG@;' \
-e 's;@INCLUDEDIR@;@includedir@;' -e 's;@LIBDIR@;@libdir@;' $< > $@
chmod +x $@
endif
%.o: %.cc
@[ -d dep ] || mkdir dep
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -MD -c $< -o $*.o
$(CXX) @ident_support@ $(CPPFLAGS) $(CXXFLAGS) -MD -c $< -o $*.o
mv $*.d dep/$*.d
@@ -166,40 +190,62 @@ lexor.o: lexor.cc parse.h
parse.o: parse.cc
parse.h parse.cc: $(srcdir)/parse.y
bison --verbose -t -p VL -d -o parse.cc $(srcdir)/parse.y
mv parse.cc.h parse.h
$(YACC) --verbose -t -p VL -d -o parse.cc $(srcdir)/parse.y
mv parse.cc.h parse.h || mv parse.hh parse.h
syn-rules.cc: $(srcdir)/syn-rules.y
bison --verbose -p syn_ -o syn-rules.cc $(srcdir)/syn-rules.y
$(YACC) --verbose -p syn_ -o syn-rules.cc $(srcdir)/syn-rules.y
lexor.cc: $(srcdir)/lexor.lex
flex -PVL -s -olexor.cc $(srcdir)/lexor.lex
$(LEX) -PVL -s -olexor.cc $(srcdir)/lexor.lex
lexor_keyword.o: lexor_keyword.cc
lexor_keyword.cc: lexor_keyword.gperf
gperf -o -i 7 -C -k 1-3,$$ -L ANSI-C -H keyword_hash -N check_identifier -t $(srcdir)/lexor_keyword.gperf > lexor_keyword.cc || (rm -f lexor_keyword.cc ; false)
iverilog-vpi.ps: $(srcdir)/iverilog-vpi.man
man -t $(srcdir)/iverilog-vpi.man > iverilog-vpi.ps
iverilog-vpi.pdf: iverilog-vpi.ps
ps2pdf iverilog-vpi.ps iverilog-vpi.pdf
ifeq (@WIN32@,yes)
WIN32_INSTALL = $(prefix)/hello.vl $(prefix)/sqrt.vl $(prefix)/QUICK_START.txt
INSTALL_DOC = $(prefix)/iverilog-vpi.pdf
INSTALL_DOCDIR =
all: iverilog-vpi.pdf
else
INSTALL_DOC = $(mandir)/man1/iverilog-vpi.1
INSTALL_DOCDIR = $(mandir)/man1
endif
install: all installdirs $(libdir)/ivl/ivl@EXEEXT@ $(libdir)/ivl/iverilog.conf $(includedir)/ivl_target.h $(includedir)/vpi_user.h $(libdir)/libvpi.a $(WIN32_INSTALL)
cd vvm ; $(MAKE) install
ifeq (@WIN32@,yes)
WIN32_INSTALL = $(prefix)/hello.vl $(prefix)/sqrt.vl $(prefix)/sqrt-virtex.v $(prefix)/QUICK_START.txt
else
WIN32_INSTALL = $(bindir)/iverilog-vpi
endif
install: all installdirs $(libdir)/ivl/ivl@EXEEXT@ $(libdir)/ivl/iverilog.conf $(includedir)/ivl_target.h $(includedir)/vpi_user.h $(includedir)/acc_user.h $(includedir)/veriuser.h $(libdir)/libvpi.a $(WIN32_INSTALL) $(INSTALL_DOC)
cd vpi ; $(MAKE) install
cd ivlpp ; $(MAKE) install
cd driver ; $(MAKE) install
for tgt in $(SUBDIRS); do (cd $$tgt ; $(MAKE) install); done
for tgt in $(TARGETS); do (cd $$tgt ; $(MAKE) install); done
$(bindir)/iverilog-vpi: ./iverilog-vpi
$(INSTALL_SCRIPT) ./iverilog-vpi $(bindir)/iverilog-vpi
$(libdir)/libvpi.a : ./libvpi.a
$(INSTALL_DATA) libvpi.a $(libdir)/libvpi.a
$(libdir)/ivl/ivl@EXEEXT@: ./ivl@EXEEXT@
$(INSTALL_PROGRAM) ./ivl@EXEEXT@ $(libdir)/ivl/ivl@EXEEXT@
$(STRIP) $(libdir)/ivl/ivl@EXEEXT@
$(STRIP) $(strip_dynamic) $(libdir)/ivl/ivl@EXEEXT@
$(libdir)/ivl/iverilog.conf: $(srcdir)/iverilog.conf
# Install iverilog.conf whenever ivl.exe is installed. This
# forces iverilog.conf to be treated similarly, in spite of
# dates in the source bundle.
$(libdir)/ivl/iverilog.conf: $(libdir)/ivl/ivl@EXEEXT@
$(INSTALL_DATA) $(srcdir)/iverilog.conf $(libdir)/ivl/iverilog.conf
$(includedir)/ivl_target.h: $(srcdir)/ivl_target.h
@@ -208,6 +254,18 @@ $(includedir)/ivl_target.h: $(srcdir)/ivl_target.h
$(includedir)/vpi_user.h: $(srcdir)/vpi_user.h
$(INSTALL_DATA) $(srcdir)/vpi_user.h $(includedir)/vpi_user.h
$(includedir)/acc_user.h: $(srcdir)/acc_user.h
$(INSTALL_DATA) $(srcdir)/acc_user.h $(includedir)/acc_user.h
$(includedir)/veriuser.h: $(srcdir)/veriuser.h
$(INSTALL_DATA) $(srcdir)/veriuser.h $(includedir)/veriuser.h
$(mandir)/man1/iverilog-vpi.1: $(srcdir)/iverilog-vpi.man
$(INSTALL_DATA) $(srcdir)/iverilog-vpi.man $(mandir)/man1/iverilog-vpi.1
$(prefix)/iverilog-vpi.pdf: iverilog-vpi.pdf
$(INSTALL_DATA) iverilog-vpi.pdf $(prefix)/iverilog-vpi.pdf
# In windows installations, put a few examples and the quick_start
# into the destination directory.
ifeq (@WIN32@,yes)
@@ -219,24 +277,34 @@ $(prefix)/sqrt.vl: $(srcdir)/examples/sqrt.vl
./dosify.exe $(srcdir)/examples/sqrt.vl tmp.vl
mv tmp.vl $(prefix)/sqrt.vl
$(prefix)/sqrt-virtex.v: $(srcdir)/examples/sqrt-virtex.v
./dosify.exe $(srcdir)/examples/sqrt-virtex.v tmp.vl
mv tmp.vl $(prefix)/sqrt-virtex.v
$(prefix)/QUICK_START.txt: $(srcdir)/QUICK_START.txt
./dosify.exe $(srcdir)/QUICK_START.txt tmp.txt
mv tmp.txt $(prefix)/QUICK_START.txt
endif
installdirs: mkinstalldirs
$(srcdir)/mkinstalldirs $(bindir) $(includedir) $(libdir)/ivl
$(srcdir)/mkinstalldirs $(bindir) $(includedir) $(libdir)/ivl \
$(mandir) $(mandir)/man1
uninstall:
rm -f $(libdir)/ivl/ivl@EXEEXT@
rm -f $(libdir)/ivl/iverilog.conf
rm -f $(libdir)/ivl/ivl
-rmdir $(libdir)/ivl
rm -f $(libdir)/libvpi.a
rm -f $(bindir)/verilog
rm -f $(bindir)/iverilog-vpi
rm -f $(bindir)/gverilog@EXEEXT@
rm -f $(includedir)/ivl_target.h
rm -f $(includedir)/vpi_user.h
rm -f $(includedir)/acc_user.h
rm -f $(includedir)/veriuser.h
rm -f $(mandir)/man1/iverilog-vpi.1
cd driver ; $(MAKE) uninstall
cd vpi ; $(MAKE) uninstall
cd vvm ; $(MAKE) uninstall
cd ivlpp ; $(MAKE) uninstall
for tgt in $(SUBDIRS); do (cd $$tgt ; $(MAKE) uninstall); done
for tgt in $(TARGETS); do (cd $$tgt ; $(MAKE) uninstall); done
+32 -17
View File
@@ -16,8 +16,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: Module.cc,v 1.15 2001/07/25 03:10:48 steve Exp $"
#ifdef HAVE_CVS_IDENT
#ident "$Id: Module.cc,v 1.19 2002/08/12 01:34:58 steve Exp $"
#endif
# include "config.h"
@@ -27,12 +27,14 @@
# include "PWire.h"
# include <assert.h>
Module::Module(const string&name, const svector<Module::port_t*>*pp)
: name_(name)
Module::Module(const char*name)
: name_(strdup(name))
{
if (pp)
ports_ = *pp;
}
Module::~Module()
{
free(name_);
}
void Module::add_gate(PGate*gate)
@@ -52,7 +54,7 @@ void Module::add_function(const string &name, PFunction *func)
PWire* Module::add_wire(PWire*wire)
{
PWire*&ep = wires_[wire->name()];
PWire*&ep = wires_[wire->path()];
if (ep) return ep;
assert(ep == 0);
@@ -67,7 +69,7 @@ void Module::add_behavior(PProcess*b)
unsigned Module::port_count() const
{
return ports_.count();
return ports.count();
}
/*
@@ -77,11 +79,11 @@ unsigned Module::port_count() const
*/
const svector<PEIdent*>& Module::get_port(unsigned idx) const
{
assert(idx < ports_.count());
assert(idx < ports.count());
static svector<PEIdent*> zero;
if (ports_[idx])
return ports_[idx]->expr;
if (ports[idx])
return ports[idx]->expr;
else
return zero;
}
@@ -89,17 +91,17 @@ const svector<PEIdent*>& Module::get_port(unsigned idx) const
unsigned Module::find_port(const string&name) const
{
assert(name != "");
for (unsigned idx = 0 ; idx < ports_.count() ; idx += 1)
if (ports_[idx]->name == name)
for (unsigned idx = 0 ; idx < ports.count() ; idx += 1)
if (ports[idx]->name == name)
return idx;
return ports_.count();
return ports.count();
}
PWire* Module::get_wire(const string&name) const
PWire* Module::get_wire(const hname_t&name) const
{
map<string,PWire*>::const_iterator obj = wires_.find(name);
map<hname_t,PWire*>::const_iterator obj = wires_.find(name);
if (obj == wires_.end())
return 0;
else
@@ -119,7 +121,7 @@ PGate* Module::get_gate(const string&name)
return 0;
}
const map<string,PWire*>& Module::get_wires() const
const map<hname_t,PWire*>& Module::get_wires() const
{
return wires_;
}
@@ -137,6 +139,19 @@ const list<PProcess*>& Module::get_behaviors() const
/*
* $Log: Module.cc,v $
* Revision 1.19 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.18 2002/05/19 23:37:28 steve
* Parse port_declaration_lists from the 2001 Standard.
*
* Revision 1.17 2001/12/03 04:47:14 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
*
* Revision 1.16 2001/10/20 05:21:51 steve
* Scope/module names are char* instead of string.
*
* Revision 1.15 2001/07/25 03:10:48 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
+44 -16
View File
@@ -18,14 +18,16 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: Module.h,v 1.21 2000/11/05 06:05:59 steve Exp $"
#ifdef HAVE_CVS_IDENT
#ident "$Id: Module.h,v 1.27 2002/08/19 02:39:16 steve Exp $"
#endif
# include <list>
# include <map>
# include "svector.h"
# include "HName.h"
# include "named.h"
# include "LineInfo.h"
# include <string>
class PEvent;
class PExpr;
@@ -44,7 +46,7 @@ class NetScope;
* therefore the handle for grasping the described circuit.
*/
class Module {
class Module : public LineInfo {
/* The module ports are in general a vector of port_t
objects. Each port has a name and an ordered list of
@@ -58,20 +60,27 @@ class Module {
};
public:
explicit Module(const string&name, const svector<port_t*>*);
explicit Module(const char*name);
~Module();
/* The module has parameters that are evaluated when the
module is elaborated. During parsing, I put the parameters
into this map. */
map<string,PExpr*>parameters;
map<string,PExpr*>localparams;
struct param_expr_t {
PExpr*expr;
PExpr*msb;
PExpr*lsb;
bool signed_flag;
};
map<string,param_expr_t>parameters;
map<string,param_expr_t>localparams;
/* The module also has defparam assignments which don't create
new parameters within the module, but may be used to set
values within this module (when instantiated) or in other
instantiated modules. */
map<string,PExpr*>defparms;
map<hname_t,PExpr*>defparms;
/* Parameters may be overridden at instantiation time;
the overrides do not contain explicit parameter names,
@@ -81,6 +90,10 @@ class Module {
a parameter-index to its name. */
list<string> param_names;
/* This is an array of port descriptors, which is in turn a
named array of PEident pointers. */
svector<port_t*> ports;
/* Keep a table of named events declared in the module. */
map<string,PEvent*>events;
@@ -88,7 +101,7 @@ class Module {
set by the `timescale directive. */
int time_unit, time_precision;
const string&get_name() const { return name_; }
const char*mod_name() const { return name_; }
void add_gate(PGate*gate);
@@ -107,10 +120,10 @@ class Module {
// Find a wire by name. This is used for connecting gates to
// existing wires, etc.
PWire* get_wire(const string&name) const;
PWire* get_wire(const hname_t&name) const;
PGate* get_gate(const string&name);
const map<string,PWire*>& get_wires() const;
const map<hname_t,PWire*>& get_wires() const;
const list<PGate*>& get_gates() const;
const list<PProcess*>& get_behaviors() const;
@@ -122,13 +135,9 @@ class Module {
bool elaborate_sig(Design*, NetScope*scope) const;
private:
const string name_;
char* name_;
/* This is an array of port descriptors, which is in turn a
named array of PEident pointers. */
svector<port_t*> ports_;
map<string,PWire*> wires_;
map<hname_t,PWire*> wires_;
list<PGate*> gates_;
list<PProcess*> behaviors_;
map<string,PTask*> tasks_;
@@ -142,6 +151,25 @@ class Module {
/*
* $Log: Module.h,v $
* Revision 1.27 2002/08/19 02:39:16 steve
* Support parameters with defined ranges.
*
* Revision 1.26 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.25 2002/05/19 23:37:28 steve
* Parse port_declaration_lists from the 2001 Standard.
*
* Revision 1.24 2001/12/03 04:47:14 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
*
* Revision 1.23 2001/10/31 03:11:15 steve
* detect module ports not declared within the module.
*
* Revision 1.22 2001/10/20 05:21:51 steve
* Scope/module names are char* instead of string.
*
* Revision 1.21 2000/11/05 06:05:59 steve
* Handle connectsion to internally unconnected modules (PR#38)
*
+25 -8
View File
@@ -16,8 +16,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: PDelays.cc,v 1.5 2001/07/25 03:10:48 steve Exp $"
#ifdef HAVE_CVS_IDENT
#ident "$Id: PDelays.cc,v 1.9 2002/08/12 01:34:58 steve Exp $"
#endif
# include "config.h"
@@ -30,14 +30,17 @@
PDelays::PDelays()
{
delete_flag_ = true;
for (unsigned idx = 0 ; idx < 3 ; idx += 1)
delay_[idx] = 0;
}
PDelays::~PDelays()
{
for (unsigned idx = 0 ; idx < 3 ; idx += 1)
delete delay_[idx];
if (delete_flag_) {
for (unsigned idx = 0 ; idx < 3 ; idx += 1)
delete delay_[idx];
}
}
void PDelays::set_delay(PExpr*del)
@@ -45,15 +48,18 @@ void PDelays::set_delay(PExpr*del)
assert(del);
assert(delay_[0] == 0);
delay_[0] = del;
delete_flag_ = true;
}
void PDelays::set_delays(const svector<PExpr*>*del)
void PDelays::set_delays(const svector<PExpr*>*del, bool df)
{
assert(del);
assert(del->count() <= 3);
for (unsigned idx = 0 ; idx < del->count() ; idx += 1)
delay_[idx] = (*del)[idx];
delete_flag_ = df;
}
static unsigned long calculate_val(Design*des, const NetScope*scope,
@@ -69,7 +75,7 @@ static unsigned long calculate_val(Design*des, const NetScope*scope,
delete dr;
} else {
verinum*dv = expr->eval_const(des, scope->name());
verinum*dv = expr->eval_const(des, scope);
if (dv == 0) {
cerr << expr->get_line() << ": sorry: non-constant "
<< "delays not supported here: " << *expr << endl;
@@ -86,12 +92,11 @@ static unsigned long calculate_val(Design*des, const NetScope*scope,
return val;
}
void PDelays::eval_delays(Design*des, const string&path,
void PDelays::eval_delays(Design*des, NetScope*scope,
unsigned long&rise_time,
unsigned long&fall_time,
unsigned long&decay_time) const
{
NetScope*scope = des->find_scope(path);
assert(scope);
int shift = scope->time_unit() - des->get_precision();
@@ -126,6 +131,18 @@ void PDelays::eval_delays(Design*des, const string&path,
/*
* $Log: PDelays.cc,v $
* Revision 1.9 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.8 2001/12/29 20:19:31 steve
* Do not delete delay expressions of UDP instances.
*
* Revision 1.7 2001/11/22 06:20:59 steve
* Use NetScope instead of string for scope path.
*
* Revision 1.6 2001/11/07 04:01:59 steve
* eval_const uses scope instead of a string path.
*
* Revision 1.5 2001/07/25 03:10:48 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
+27 -9
View File
@@ -1,7 +1,7 @@
#ifndef __PDelays_H
#define __PDelays_H
/*
* Copyright (c) 1999 Stephen Williams ([email protected])
* Copyright (c) 1999-2002 Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -18,20 +18,22 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: PDelays.h,v 1.3 2001/01/16 02:44:17 steve Exp $"
#ifdef HAVE_CVS_IDENT
#ident "$Id: PDelays.h,v 1.7 2002/08/12 01:34:58 steve Exp $"
#endif
# include "svector.h"
# include <string>
# include <iostream>
#ifdef HAVE_IOSFWD
# include <iosfwd>
#else
class ostream;
#ifdef __GNUC__
#if __GNUC__ > 2
using namespace std;
#endif
#endif
class Design;
class NetScope;
class PExpr;
/*
@@ -44,10 +46,13 @@ class PDelays {
PDelays();
~PDelays();
/* Set the delay expressions. If the delete_flag is true, then
this object takes ownership of the expressions, and will
delete it in the destructor. */
void set_delay(PExpr*);
void set_delays(const svector<PExpr*>*del);
void set_delays(const svector<PExpr*>*del, bool delete_flag=true);
void eval_delays(Design*des, const string&path,
void eval_delays(Design*des, NetScope*scope,
unsigned long&rise_time,
unsigned long&fall_time,
unsigned long&decay_time) const;
@@ -56,6 +61,7 @@ class PDelays {
private:
PExpr* delay_[3];
bool delete_flag_;
private: // not implemented
PDelays(const PDelays&);
@@ -66,6 +72,18 @@ ostream& operator << (ostream&o, const PDelays&);
/*
* $Log: PDelays.h,v $
* Revision 1.7 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.6 2002/06/14 03:25:51 steve
* Compiler portability.
*
* Revision 1.5 2001/12/29 20:19:31 steve
* Do not delete delay expressions of UDP instances.
*
* Revision 1.4 2001/11/22 06:20:59 steve
* Use NetScope instead of string for scope path.
*
* Revision 1.3 2001/01/16 02:44:17 steve
* Use the iosfwd header if available.
*
+5 -2
View File
@@ -16,8 +16,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: PEvent.cc,v 1.2 2001/07/25 03:10:48 steve Exp $"
#ifdef HAVE_CVS_IDENT
#ident "$Id: PEvent.cc,v 1.3 2002/08/12 01:34:58 steve Exp $"
#endif
# include "config.h"
@@ -40,6 +40,9 @@ string PEvent::name() const
/*
* $Log: PEvent.cc,v $
* Revision 1.3 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.2 2001/07/25 03:10:48 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
+11 -3
View File
@@ -18,8 +18,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: PEvent.h,v 1.4 2001/01/16 02:44:18 steve Exp $"
#ifdef HAVE_CVS_IDENT
#ident "$Id: PEvent.h,v 1.6 2002/08/12 01:34:58 steve Exp $"
#endif
# include "LineInfo.h"
@@ -30,7 +30,8 @@ class NetScope;
/*
* The PEvent class represents event objects. These are things that
* are declared in Verilog as ``event foo;''
* are declared in Verilog as ``event foo;'' The name passed to the
* constructure is the "foo" part of the declaration.
*/
class PEvent : public LineInfo {
@@ -52,6 +53,13 @@ class PEvent : public LineInfo {
/*
* $Log: PEvent.h,v $
* Revision 1.6 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.5 2001/12/03 04:47:14 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
*
* Revision 1.4 2001/01/16 02:44:18 steve
* Use the iosfwd header if available.
*
+55 -29
View File
@@ -16,8 +16,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: PExpr.cc,v 1.24 2001/07/25 03:10:48 steve Exp $"
#ifdef HAVE_CVS_IDENT
#ident "$Id: PExpr.cc,v 1.32 2002/11/09 19:20:48 steve Exp $"
#endif
# include "config.h"
@@ -46,37 +46,34 @@ bool PExpr::is_constant(Module*) const
return false;
}
NetNet* PExpr::elaborate_net(Design*des, const string&path, unsigned,
unsigned long,
unsigned long,
unsigned long,
Link::strength_t,
Link::strength_t) const
{
cerr << get_line() << ": error: Unable to elaborate `"
<< *this << "' as gates." << endl;
return 0;
}
NetNet* PExpr::elaborate_lnet(Design*des, const string&path) const
NetNet* PExpr::elaborate_lnet(Design*des, NetScope*, bool) const
{
cerr << get_line() << ": error: expression not valid in assign l-value: "
<< *this << endl;
return 0;
}
PEBinary::PEBinary(char op, PExpr*l, PExpr*r)
: op_(op), left_(l), right_(r)
{
}
PEBinary::~PEBinary()
{
}
bool PEBinary::is_constant(Module*mod) const
{
return left_->is_constant(mod) && right_->is_constant(mod);
}
PECallFunction::PECallFunction(const char*n, const svector<PExpr *> &parms)
: name_(n), parms_(parms)
PECallFunction::PECallFunction(const hname_t&n, const svector<PExpr *> &parms)
: path_(n), parms_(parms)
{
}
PECallFunction::PECallFunction(const char*n)
: name_(n)
PECallFunction::PECallFunction(const hname_t&n)
: path_(n)
{
}
@@ -142,8 +139,8 @@ bool PEFNumber::is_constant(Module*) const
return true;
}
PEIdent::PEIdent(const string&s)
: text_(s), msb_(0), lsb_(0), idx_(0)
PEIdent::PEIdent(const hname_t&s)
: path_(s), msb_(0), lsb_(0), idx_(0)
{
}
@@ -151,9 +148,9 @@ PEIdent::~PEIdent()
{
}
string PEIdent::name() const
const hname_t& PEIdent::path() const
{
return text_;
return path_;
}
/*
@@ -162,14 +159,17 @@ string PEIdent::name() const
*/
bool PEIdent::is_constant(Module*mod) const
{
map<string,PExpr*>::const_iterator cur;
if (mod == 0) return false;
cur = mod->parameters.find(text_);
if (cur != mod->parameters.end()) return true;
{ map<string,Module::param_expr_t>::const_iterator cur;
cur = mod->parameters.find(path_.peek_name(0));
if (cur != mod->parameters.end()) return true;
}
cur = mod->localparams.find(text_);
if (cur != mod->localparams.end()) return true;
{ map<string,Module::param_expr_t>::const_iterator cur;
cur = mod->localparams.find(path_.peek_name(0));
if (cur != mod->localparams.end()) return true;
}
return false;
}
@@ -204,13 +204,14 @@ bool PENumber::is_constant(Module*) const
return true;
}
PEString::PEString(const string&s)
PEString::PEString(char*s)
: text_(s)
{
}
PEString::~PEString()
{
delete[]text_;
}
string PEString::value() const
@@ -255,6 +256,31 @@ bool PEUnary::is_constant(Module*m) const
/*
* $Log: PExpr.cc,v $
* Revision 1.32 2002/11/09 19:20:48 steve
* Port expressions for output ports are lnets, not nets.
*
* Revision 1.31 2002/08/19 02:39:16 steve
* Support parameters with defined ranges.
*
* Revision 1.30 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.29 2001/12/30 21:32:03 steve
* Support elaborate_net for PEString objects.
*
* Revision 1.28 2001/12/03 04:47:14 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
*
* Revision 1.27 2001/11/08 05:15:50 steve
* Remove string paths from PExpr elaboration.
*
* Revision 1.26 2001/11/07 04:26:46 steve
* elaborate_lnet uses scope instead of string path.
*
* Revision 1.25 2001/11/06 06:11:55 steve
* Support more real arithmetic in delay constants.
*
* Revision 1.24 2001/07/25 03:10:48 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
+143 -230
View File
@@ -18,8 +18,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: PExpr.h,v 1.48 2001/01/14 23:04:55 steve Exp $"
#ifdef HAVE_CVS_IDENT
#ident "$Id: PExpr.h,v 1.63 2002/11/09 19:20:48 steve Exp $"
#endif
# include <string>
@@ -51,8 +51,11 @@ class PExpr : public LineInfo {
virtual void dump(ostream&) const;
// Procedural elaboration of the expression.
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope) const;
// Procedural elaboration of the expression. Set thie
// bare_memory_ok flag if the result is allowed to be a
// NetEMemory without an index.
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
bool sys_task_arg =false) const;
// Elaborate expressions that are the r-value of parameter
// assignments. This elaboration follows the restrictions of
@@ -62,7 +65,7 @@ class PExpr : public LineInfo {
// This method elaborate the expression as gates, for use in a
// continuous assign or other wholly structural context.
virtual NetNet* elaborate_net(Design*des, const string&path,
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
unsigned lwidth,
unsigned long rise,
unsigned long fall,
@@ -77,7 +80,8 @@ class PExpr : public LineInfo {
// This method elaborates the expression as gates, but
// restricted for use as l-values of continuous assignments.
virtual NetNet* elaborate_lnet(Design*des, const string&path) const;
virtual NetNet* elaborate_lnet(Design*des, NetScope*scope,
bool implicit_net_ok =false) const;
// Expressions that can be in the l-value of procedural
// assignments can be elaborated with this method.
@@ -86,7 +90,7 @@ class PExpr : public LineInfo {
// This attempts to evaluate a constant expression, and return
// a verinum as a result. If the expression cannot be
// evaluated, return 0.
virtual verinum* eval_const(const Design*des, const string&path) const;
virtual verinum* eval_const(const Design*des, const NetScope*sc) const;
// This attempts to evaluate a constant expression as a
// decimal floating point. This is used when calculating delay
@@ -123,15 +127,17 @@ class PEConcat : public PExpr {
// continuous assignments.
virtual NetNet* elaborate_anet(Design*des, NetScope*scope) const;
virtual NetNet* elaborate_lnet(Design*des, const string&path) const;
virtual NetNet* elaborate_net(Design*des, const string&path,
virtual NetNet* elaborate_lnet(Design*des, NetScope*scope,
bool implicit_net_ok =false) const;
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
unsigned width,
unsigned long rise,
unsigned long fall,
unsigned long decay,
Link::strength_t drive0,
Link::strength_t drive1) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
bool sys_task_arg =false) const;
virtual NetEConcat*elaborate_pexpr(Design*des, NetScope*) const;
virtual NetAssign_* elaborate_lval(Design*des, NetScope*scope) const;
virtual bool is_constant(Module*) const;
@@ -182,7 +188,7 @@ class PEFNumber : public PExpr {
/* The eval_const method as applied to a floating point number
gets the *integer* value of the number. This accounts for
any rounding that is needed to get the value. */
virtual verinum* eval_const(const Design*des, const string&path) const;
virtual verinum* eval_const(const Design*des, const NetScope*sc) const;
/* This method returns the full floating point value. */
virtual verireal* eval_rconst(const Design*, const NetScope*) const;
@@ -190,7 +196,8 @@ class PEFNumber : public PExpr {
/* A PEFNumber is a constant, so this returns true. */
virtual bool is_constant(Module*) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
bool sys_task_arg =false) const;
virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
virtual void dump(ostream&) const;
@@ -202,7 +209,7 @@ class PEFNumber : public PExpr {
class PEIdent : public PExpr {
public:
explicit PEIdent(const string&s);
explicit PEIdent(const hname_t&s);
~PEIdent();
virtual void dump(ostream&) const;
@@ -211,13 +218,14 @@ class PEIdent : public PExpr {
virtual NetNet* elaborate_anet(Design*des, NetScope*scope) const;
// Identifiers are allowed (with restrictions) is assign l-values.
virtual NetNet* elaborate_lnet(Design*des, const string&path) const;
virtual NetNet* elaborate_lnet(Design*des, NetScope*scope,
bool implicit_net_ok =false) const;
// Identifiers are also allowed as procedural assignment l-values.
virtual NetAssign_* elaborate_lval(Design*des, NetScope*scope) const;
// Structural r-values are OK.
virtual NetNet* elaborate_net(Design*des, const string&path,
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
unsigned lwidth,
unsigned long rise,
unsigned long fall,
@@ -225,7 +233,8 @@ class PEIdent : public PExpr {
Link::strength_t drive0,
Link::strength_t drive1) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
bool sys_task_arg =false) const;
virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
// Elaborate the PEIdent as a port to a module. This method
@@ -233,12 +242,13 @@ class PEIdent : public PExpr {
NetNet* elaborate_port(Design*des, NetScope*sc) const;
virtual bool is_constant(Module*) const;
verinum* eval_const(const Design*des, const string&path) const;
verinum* eval_const(const Design*des, const NetScope*sc) const;
verireal*eval_rconst(const Design*des, const NetScope*sc) const;
string name() const;
const hname_t& path() const;
private:
string text_;
hname_t path_;
public:
// Use these to support bit- and part-select operators.
@@ -249,11 +259,24 @@ class PEIdent : public PExpr {
// expression.
PExpr*idx_;
NetNet* elaborate_net_ram_(Design*des, const string&path,
NetNet* elaborate_net_ram_(Design*des, NetScope*scope,
NetMemory*mem, unsigned lwidth,
unsigned long rise,
unsigned long fall,
unsigned long decay) const;
NetNet* elaborate_net_bitmux_(Design*des, NetScope*scope,
NetNet*sig,
unsigned long rise,
unsigned long fall,
unsigned long decay,
Link::strength_t drive0,
Link::strength_t drive1) const;
private:
NetAssign_* elaborate_mem_lval_(Design*des, NetScope*scope,
NetMemory*mem) const;
};
class PENumber : public PExpr {
@@ -265,16 +288,20 @@ class PENumber : public PExpr {
const verinum& value() const;
virtual void dump(ostream&) const;
virtual NetNet* elaborate_net(Design*des, const string&path,
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
unsigned lwidth,
unsigned long rise,
unsigned long fall,
unsigned long decay,
Link::strength_t drive0,
Link::strength_t drive1) const;
virtual NetEConst*elaborate_expr(Design*des, NetScope*) const;
virtual NetEConst*elaborate_expr(Design*des, NetScope*,
bool sys_task_arg =false) const;
virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
virtual verinum* eval_const(const Design*des, const string&path) const;
virtual NetAssign_* elaborate_lval(Design*des, NetScope*scope) const;
virtual verinum* eval_const(const Design*des, const NetScope*sc) const;
virtual verireal*eval_rconst(const Design*, const NetScope*) const;
virtual bool is_the_same(const PExpr*that) const;
virtual bool is_constant(Module*) const;
@@ -283,21 +310,37 @@ class PENumber : public PExpr {
verinum*const value_;
};
/*
* This represents a string constant in an expression.
*
* The s parameter to the PEString constructor is a C string that this
* class instance will take for its own. The caller should not delete
* the string, the destructor will do it.
*/
class PEString : public PExpr {
public:
explicit PEString(const string&s);
explicit PEString(char*s);
~PEString();
string value() const;
virtual void dump(ostream&) const;
virtual NetEConst*elaborate_expr(Design*des, NetScope*) const;
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
unsigned width,
unsigned long rise,
unsigned long fall,
unsigned long decay,
Link::strength_t drive0,
Link::strength_t drive1) const;
virtual NetEConst*elaborate_expr(Design*des, NetScope*,
bool sys_task_arg =false) const;
virtual NetEConst*elaborate_pexpr(Design*des, NetScope*sc) const;
verinum* PEString::eval_const(const Design*, const NetScope*) const;
virtual bool is_constant(Module*) const;
private:
const string text_;
char*text_;
};
class PEUnary : public PExpr {
@@ -307,16 +350,17 @@ class PEUnary : public PExpr {
~PEUnary();
virtual void dump(ostream&out) const;
virtual NetNet* elaborate_net(Design*des, const string&path,
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
unsigned width,
unsigned long rise,
unsigned long fall,
unsigned long decay,
Link::strength_t drive0,
Link::strength_t drive1) const;
virtual NetEUnary*elaborate_expr(Design*des, NetScope*) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
bool sys_task_arg =false) const;
virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
virtual verinum* eval_const(const Design*des, const string&path) const;
virtual verinum* eval_const(const Design*des, const NetScope*sc) const;
virtual bool is_constant(Module*) const;
@@ -328,22 +372,24 @@ class PEUnary : public PExpr {
class PEBinary : public PExpr {
public:
explicit PEBinary(char op, PExpr*l, PExpr*r)
: op_(op), left_(l), right_(r) { }
explicit PEBinary(char op, PExpr*l, PExpr*r);
~PEBinary();
virtual bool is_constant(Module*) const;
virtual void dump(ostream&out) const;
virtual NetNet* elaborate_net(Design*des, const string&path,
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
unsigned width,
unsigned long rise,
unsigned long fall,
unsigned long decay,
Link::strength_t drive0,
Link::strength_t drive1) const;
virtual NetEBinary*elaborate_expr(Design*des, NetScope*) const;
virtual NetEBinary*elaborate_expr(Design*des, NetScope*,
bool sys_task_arg =false) const;
virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
virtual verinum* eval_const(const Design*des, const string&path) const;
virtual verinum* eval_const(const Design*des, const NetScope*sc) const;
virtual verireal*eval_rconst(const Design*des, const NetScope*sc) const;
private:
char op_;
@@ -352,42 +398,42 @@ class PEBinary : public PExpr {
NetEBinary*elaborate_expr_base_(Design*, NetExpr*lp, NetExpr*rp) const;
NetNet* elaborate_net_add_(Design*des, const string&path,
NetNet* elaborate_net_add_(Design*des, NetScope*scope,
unsigned lwidth,
unsigned long rise,
unsigned long fall,
unsigned long decay) const;
NetNet* elaborate_net_bit_(Design*des, const string&path,
NetNet* elaborate_net_bit_(Design*des, NetScope*scope,
unsigned lwidth,
unsigned long rise,
unsigned long fall,
unsigned long decay) const;
NetNet* elaborate_net_cmp_(Design*des, const string&path,
NetNet* elaborate_net_cmp_(Design*des, NetScope*scope,
unsigned lwidth,
unsigned long rise,
unsigned long fall,
unsigned long decay) const;
NetNet* elaborate_net_div_(Design*des, const string&path,
NetNet* elaborate_net_div_(Design*des, NetScope*scope,
unsigned lwidth,
unsigned long rise,
unsigned long fall,
unsigned long decay) const;
NetNet* elaborate_net_mod_(Design*des, const string&path,
NetNet* elaborate_net_mod_(Design*des, NetScope*scope,
unsigned lwidth,
unsigned long rise,
unsigned long fall,
unsigned long decay) const;
NetNet* elaborate_net_log_(Design*des, const string&path,
NetNet* elaborate_net_log_(Design*des, NetScope*scope,
unsigned lwidth,
unsigned long rise,
unsigned long fall,
unsigned long decay) const;
NetNet* elaborate_net_mul_(Design*des, const string&path,
NetNet* elaborate_net_mul_(Design*des, NetScope*scope,
unsigned lwidth,
unsigned long rise,
unsigned long fall,
unsigned long decay) const;
NetNet* elaborate_net_shift_(Design*des, const string&path,
NetNet* elaborate_net_shift_(Design*des, NetScope*scope,
unsigned lwidth,
unsigned long rise,
unsigned long fall,
@@ -407,16 +453,17 @@ class PETernary : public PExpr {
virtual bool is_constant(Module*) const;
virtual void dump(ostream&out) const;
virtual NetNet* elaborate_net(Design*des, const string&path,
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
unsigned width,
unsigned long rise,
unsigned long fall,
unsigned long decay,
Link::strength_t drive0,
Link::strength_t drive1) const;
virtual NetETernary*elaborate_expr(Design*des, NetScope*) const;
virtual NetETernary*elaborate_expr(Design*des, NetScope*,
bool sys_task_arg =false) const;
virtual NetETernary*elaborate_pexpr(Design*des, NetScope*sc) const;
virtual verinum* eval_const(const Design*des, const string&path) const;
virtual verinum* eval_const(const Design*des, const NetScope*sc) const;
private:
PExpr*expr_;
@@ -426,219 +473,85 @@ class PETernary : public PExpr {
/*
* This class represents a parsed call to a function, including calls
* to system functions.
* to system functions. The parameters in the parms list are the
* expressions that are passed as input to the ports of the function.
*/
class PECallFunction : public PExpr {
public:
explicit PECallFunction(const char*n, const svector<PExpr *> &parms);
explicit PECallFunction(const char*n);
explicit PECallFunction(const hname_t&n, const svector<PExpr *> &parms);
explicit PECallFunction(const hname_t&n);
~PECallFunction();
virtual void dump(ostream &) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope) const;
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
unsigned width,
unsigned long rise,
unsigned long fall,
unsigned long decay,
Link::strength_t drive0,
Link::strength_t drive1) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
bool sys_task_arg =false) const;
private:
string name_;
hname_t path_;
svector<PExpr *> parms_;
bool check_call_matches_definition_(Design*des, NetScope*dscope) const;
NetExpr* elaborate_sfunc_(Design*des, NetScope*scope) const;
};
/*
* $Log: PExpr.h,v $
* Revision 1.48 2001/01/14 23:04:55 steve
* Generalize the evaluation of floating point delays, and
* get it working with delay assignment statements.
* Revision 1.63 2002/11/09 19:20:48 steve
* Port expressions for output ports are lnets, not nets.
*
* Allow parameters to be referenced by hierarchical name.
* Revision 1.62 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.47 2000/12/16 19:03:30 steve
* Evaluate <= and ?: in parameter expressions (PR#81)
* Revision 1.61 2002/06/04 05:38:43 steve
* Add support for memory words in l-value of
* blocking assignments, and remove the special
* NetAssignMem class.
*
* Revision 1.46 2000/12/10 22:01:35 steve
* Support decimal constants in behavioral delays.
* Revision 1.60 2002/05/23 03:08:51 steve
* Add language support for Verilog-2001 attribute
* syntax. Hook this support into existing $attribute
* handling, and add number and void value types.
*
* Revision 1.45 2000/12/06 06:31:09 steve
* Check lvalue of procedural continuous assign (PR#29)
* Add to the ivl_target API new functions for access
* of complex attributes attached to gates.
*
* Revision 1.44 2000/09/17 21:26:15 steve
* Add support for modulus (Eric Aardoom)
* Revision 1.59 2002/04/23 03:53:59 steve
* Add support for non-constant bit select.
*
* Revision 1.43 2000/09/09 15:21:26 steve
* move lval elaboration to PExpr virtual methods.
* Revision 1.58 2002/04/14 03:55:25 steve
* Precalculate unary - if possible.
*
* Revision 1.42 2000/09/07 22:38:13 steve
* Support unary + and - in constants.
* Revision 1.57 2002/04/13 02:33:17 steve
* Detect missing indices to memories (PR#421)
*
* Revision 1.41 2000/06/30 15:50:20 steve
* Allow unary operators in constant expressions.
* Revision 1.56 2002/03/09 04:02:26 steve
* Constant expressions are not l-values for task ports.
*
* Revision 1.40 2000/06/13 05:22:16 steve
* Support concatenation in parameter expressions.
* Revision 1.55 2002/03/09 02:10:22 steve
* Add the NetUserFunc netlist node.
*
* Revision 1.39 2000/06/01 02:31:39 steve
* Parameters can be strings.
* Revision 1.54 2001/12/30 21:32:03 steve
* Support elaborate_net for PEString objects.
*
* Revision 1.38 2000/05/16 04:05:15 steve
* Module ports are really special PEIdent
* expressions, because a name can be used
* many places in the port list.
* Revision 1.53 2001/12/03 04:47:14 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
*
* Revision 1.37 2000/05/07 04:37:56 steve
* Carry strength values from Verilog source to the
* pform and netlist for gates.
* Revision 1.52 2001/11/08 05:15:50 steve
* Remove string paths from PExpr elaboration.
*
* Change vvm constants to use the driver_t to drive
* a constant value. This works better if there are
* multiple drivers on a signal.
*
* Revision 1.36 2000/05/04 03:37:58 steve
* Add infrastructure for system functions, move
* $time to that structure and add $random.
*
* Revision 1.35 2000/04/12 04:23:57 steve
* Named events really should be expressed with PEIdent
* objects in the pform,
*
* Handle named events within the mix of net events
* and edges. As a unified lot they get caught together.
* wait statements are broken into more complex statements
* that include a conditional.
*
* Do not generate NetPEvent or NetNEvent objects in
* elaboration. NetEvent, NetEvWait and NetEvProbe
* take over those functions in the netlist.
*
* Revision 1.34 2000/04/01 21:40:22 steve
* Add support for integer division.
*
* Revision 1.33 2000/04/01 19:31:57 steve
* Named events as far as the pform.
*
* Revision 1.32 2000/03/12 18:22:11 steve
* Binary and unary operators in parameter expressions.
*
* Revision 1.31 2000/03/12 04:35:22 steve
* Allow parameter identifiers in parameter expressions.
*
* Revision 1.30 2000/03/08 04:36:53 steve
* Redesign the implementation of scopes and parameters.
* I now generate the scopes and notice the parameters
* in a separate pass over the pform. Once the scopes
* are generated, I can process overrides and evalutate
* paremeters before elaboration begins.
*
* Revision 1.29 2000/02/23 02:56:53 steve
* Macintosh compilers do not support ident.
*
* Revision 1.28 2000/02/16 03:58:27 steve
* Fix up width matching in structural bitwise operators.
*
* Revision 1.27 2000/01/13 03:35:35 steve
* Multiplication all the way to simulation.
*
* Revision 1.26 1999/12/16 03:46:39 steve
* Structural logical or.
*
* Revision 1.25 1999/11/21 00:13:08 steve
* Support memories in continuous assignments.
*
* Revision 1.24 1999/11/14 20:24:28 steve
* Add support for the LPM_CLSHIFT device.
*
* Revision 1.23 1999/11/05 21:45:19 steve
* Fix NetConst being set to zero width, and clean
* up elaborate_set_cmp_ for NetEBinary.
*
* Revision 1.22 1999/10/31 20:08:24 steve
* Include subtraction in LPM_ADD_SUB device.
*
* Revision 1.21 1999/10/31 04:11:27 steve
* Add to netlist links pin name and instance number,
* and arrange in vvm for pin connections by name
* and instance number.
*
* Revision 1.20 1999/09/25 02:57:29 steve
* Parse system function calls.
*
* Revision 1.19 1999/09/15 04:17:52 steve
* separate assign lval elaboration for error checking.
*
* Revision 1.18 1999/08/31 22:38:29 steve
* Elaborate and emit to vvm procedural functions.
*
* Revision 1.17 1999/08/01 21:18:55 steve
* elaborate rise/fall/decay for continuous assign.
*
* Revision 1.16 1999/07/31 19:14:47 steve
* Add functions up to elaboration (Ed Carter)
*
* Revision 1.15 1999/07/22 02:05:20 steve
* is_constant method for PEConcat.
*
* Revision 1.14 1999/07/17 19:50:59 steve
* netlist support for ternary operator.
*
* Revision 1.13 1999/06/16 03:13:29 steve
* More syntax parse with sorry stubs.
*
* Revision 1.12 1999/06/15 02:50:02 steve
* Add lexical support for real numbers.
*
* Revision 1.11 1999/06/10 04:03:52 steve
* Add support for the Ternary operator,
* Add support for repeat concatenation,
* Correct some seg faults cause by elaboration
* errors,
* Parse the casex anc casez statements.
*
* Revision 1.10 1999/06/09 03:00:05 steve
* Add support for procedural concatenation expression.
*
* Revision 1.9 1999/05/16 05:08:42 steve
* Redo constant expression detection to happen
* after parsing.
*
* Parse more operators and expressions.
*
* Revision 1.8 1999/05/10 00:16:57 steve
* Parse and elaborate the concatenate operator
* in structural contexts, Replace vector<PExpr*>
* and list<PExpr*> with svector<PExpr*>, evaluate
* constant expressions with parameters, handle
* memories as lvalues.
*
* Parse task declarations, integer types.
*
* Revision 1.7 1999/05/01 02:57:52 steve
* Handle much more complex event expressions.
*
* Revision 1.6 1999/04/29 02:16:26 steve
* Parse OR of event expressions.
*
* Revision 1.5 1999/04/19 01:59:36 steve
* Add memories to the parse and elaboration phases.
*
* Revision 1.4 1998/11/11 00:01:51 steve
* Check net ranges in declarations.
*
* Revision 1.3 1998/11/09 18:55:33 steve
* Add procedural while loops,
* Parse procedural for loops,
* Add procedural wait statements,
* Add constant nodes,
* Add XNOR logic gate,
* Make vvm output look a bit prettier.
*
* Revision 1.2 1998/11/07 17:05:05 steve
* Handle procedural conditional, and some
* of the conditional expressions.
*
* Elaborate signals and identifiers differently,
* allowing the netlist to hold signal information.
*
* Revision 1.1 1998/11/03 23:28:54 steve
* Introduce verilog to CVS.
* Revision 1.51 2001/11/07 04:26:46 steve
* elaborate_lnet uses scope instead of string path.
*
* Revision 1.50 2001/11/07 04:01:59 steve
* eval_const uses scope instead of a string path.
*/
#endif
+5 -2
View File
@@ -16,8 +16,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: PFunction.cc,v 1.5 2001/07/25 03:10:48 steve Exp $"
#ifdef HAVE_CVS_IDENT
#ident "$Id: PFunction.cc,v 1.6 2002/08/12 01:34:58 steve Exp $"
#endif
# include "config.h"
@@ -54,6 +54,9 @@ void PFunction::set_output(PWire*o)
/*
* $Log: PFunction.cc,v $
* Revision 1.6 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.5 2001/07/25 03:10:48 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
+32 -8
View File
@@ -16,8 +16,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: PGate.cc,v 1.10 2001/07/25 03:10:48 steve Exp $"
#ifdef HAVE_CVS_IDENT
#ident "$Id: PGate.cc,v 1.14 2002/08/12 01:34:58 steve Exp $"
#endif
# include "config.h"
@@ -90,12 +90,12 @@ void PGate::elaborate_scope(Design*, NetScope*) const
* parameters. This method understands how to handle the different
* numbers of expressions.
*/
void PGate::eval_delays(Design*des, const string&path,
void PGate::eval_delays(Design*des, NetScope*scope,
unsigned long&rise_time,
unsigned long&fall_time,
unsigned long&decay_time) const
{
delay_.eval_delays(des, path, rise_time, fall_time, decay_time);
delay_.eval_delays(des, scope, rise_time, fall_time, decay_time);
}
PGAssign::PGAssign(svector<PExpr*>*pins)
@@ -142,17 +142,24 @@ void PGBuiltin::set_range(PExpr*msb, PExpr*lsb)
lsb_ = lsb;
}
PGModule::PGModule(const string&type, const string&name, svector<PExpr*>*pins)
: PGate(name, pins), type_(type), overrides_(0), pins_(0),
PGModule::PGModule(const char*type, const string&name, svector<PExpr*>*pins)
: PGate(name, pins), overrides_(0), pins_(0),
npins_(0), parms_(0), nparms_(0), msb_(0), lsb_(0)
{
type_ = strdup(type);
}
PGModule::PGModule(const string&type, const string&name,
PGModule::PGModule(const char*type, const string&name,
named<PExpr*>*pins, unsigned npins)
: PGate(name, 0), type_(type), overrides_(0), pins_(pins),
: PGate(name, 0), overrides_(0), pins_(pins),
npins_(npins), parms_(0), nparms_(0), msb_(0), lsb_(0)
{
type_ = strdup(type);
}
PGModule::~PGModule()
{
free(type_);
}
void PGModule::set_parameters(svector<PExpr*>*o)
@@ -178,8 +185,25 @@ void PGModule::set_range(PExpr*msb, PExpr*lsb)
lsb_ = lsb;
}
const char* PGModule::get_type()
{
return type_;
}
/*
* $Log: PGate.cc,v $
* Revision 1.14 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.13 2001/11/22 06:20:59 steve
* Use NetScope instead of string for scope path.
*
* Revision 1.12 2001/10/21 00:42:47 steve
* Module types in pform are char* instead of string.
*
* Revision 1.11 2001/10/19 01:55:32 steve
* Method to get the type_ member
*
* Revision 1.10 2001/07/25 03:10:48 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
+37 -13
View File
@@ -18,8 +18,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: PGate.h,v 1.19 2001/04/22 23:09:45 steve Exp $"
#ifdef HAVE_CVS_IDENT
#ident "$Id: PGate.h,v 1.24 2002/08/12 01:34:58 steve Exp $"
#endif
# include "svector.h"
@@ -65,7 +65,7 @@ class PGate : public LineInfo {
const string& get_name() const { return name_; }
void eval_delays(Design*des, const string&path,
void eval_delays(Design*des, NetScope*scope,
unsigned long&rise_time,
unsigned long&fall_time,
unsigned long&decay_time) const;
@@ -79,10 +79,10 @@ class PGate : public LineInfo {
void strength0(strength_t);
void strength1(strength_t);
map<string,string> attributes;
map<string,PExpr*> attributes;
virtual void dump(ostream&out) const;
virtual void elaborate(Design*des, const string&path) const;
virtual void elaborate(Design*des, NetScope*scope) const;
virtual void elaborate_scope(Design*des, NetScope*sc) const;
virtual bool elaborate_sig(Design*des, NetScope*scope) const;
@@ -116,7 +116,7 @@ class PGAssign : public PGate {
~PGAssign();
void dump(ostream&out) const;
virtual void elaborate(Design*des, const string&path) const;
virtual void elaborate(Design*des, NetScope*scope) const;
private:
};
@@ -153,7 +153,7 @@ class PGBuiltin : public PGate {
void set_range(PExpr*msb, PExpr*lsb);
virtual void dump(ostream&out) const;
virtual void elaborate(Design*, const string&path) const;
virtual void elaborate(Design*, NetScope*scope) const;
private:
Type type_;
@@ -173,15 +173,17 @@ class PGModule : public PGate {
public:
// If the binding of ports is by position, this constructor
// builds everything all at once.
explicit PGModule(const string&type, const string&name,
explicit PGModule(const char*type, const string&name,
svector<PExpr*>*pins);
// If the binding of ports is by name, this constructor takes
// the bindings and stores them for later elaboration.
explicit PGModule(const string&type, const string&name,
explicit PGModule(const char*type, const string&name,
named<PExpr*>*pins, unsigned npins);
~PGModule();
// Parameter overrides can come as an ordered list, or a set
// of named expressions.
void set_parameters(svector<PExpr*>*o);
@@ -192,12 +194,14 @@ class PGModule : public PGate {
void set_range(PExpr*msb, PExpr*lsb);
virtual void dump(ostream&out) const;
virtual void elaborate(Design*, const string&path) const;
virtual void elaborate(Design*, NetScope*scope) const;
virtual void elaborate_scope(Design*des, NetScope*sc) const;
virtual bool elaborate_sig(Design*des, NetScope*scope) const;
const char* get_type();
private:
string type_;
char* type_;
svector<PExpr*>*overrides_;
named<PExpr*>*pins_;
unsigned npins_;
@@ -210,14 +214,34 @@ class PGModule : public PGate {
PExpr*msb_;
PExpr*lsb_;
void elaborate_mod_(Design*, Module*mod, const string&path) const;
void elaborate_udp_(Design*, PUdp *udp, const string&path) const;
void elaborate_mod_(Design*, Module*mod, NetScope*scope) const;
void elaborate_udp_(Design*, PUdp *udp, NetScope*scope) const;
void elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const;
bool elaborate_sig_mod_(Design*des, NetScope*scope, Module*mod) const;
};
/*
* $Log: PGate.h,v $
* Revision 1.24 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.23 2002/05/23 03:08:51 steve
* Add language support for Verilog-2001 attribute
* syntax. Hook this support into existing $attribute
* handling, and add number and void value types.
*
* Add to the ivl_target API new functions for access
* of complex attributes attached to gates.
*
* Revision 1.22 2001/11/22 06:20:59 steve
* Use NetScope instead of string for scope path.
*
* Revision 1.21 2001/10/21 00:42:47 steve
* Module types in pform are char* instead of string.
*
* Revision 1.20 2001/10/19 01:55:32 steve
* Method to get the type_ member
*
* Revision 1.19 2001/04/22 23:09:45 steve
* More UDP consolidation from Stephan Boettcher.
*
+5 -2
View File
@@ -16,8 +16,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: PTask.cc,v 1.6 2001/07/25 03:10:48 steve Exp $"
#ifdef HAVE_CVS_IDENT
#ident "$Id: PTask.cc,v 1.7 2002/08/12 01:34:58 steve Exp $"
#endif
# include "config.h"
@@ -48,6 +48,9 @@ void PTask::set_statement(Statement*s)
/*
* $Log: PTask.cc,v $
* Revision 1.7 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.6 2001/07/25 03:10:48 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
+9 -3
View File
@@ -18,8 +18,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: PTask.h,v 1.10 2001/01/13 22:20:08 steve Exp $"
#ifdef HAVE_CVS_IDENT
#ident "$Id: PTask.h,v 1.12 2002/08/12 01:34:58 steve Exp $"
#endif
# include "LineInfo.h"
@@ -52,7 +52,7 @@ class PTask : public LineInfo {
void elaborate_sig(Design*des, NetScope*scope) const;
// Elaborate the statement to finish off the task definition.
void elaborate(Design*des, const string&path) const;
void elaborate(Design*des, NetScope*scope) const;
void dump(ostream&, unsigned) const;
@@ -98,6 +98,12 @@ class PFunction : public LineInfo {
/*
* $Log: PTask.h,v $
* Revision 1.12 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.11 2001/11/22 06:20:59 steve
* Use NetScope instead of string for scope path.
*
* Revision 1.10 2001/01/13 22:20:08 steve
* Parse parameters within nested scopes.
*
+16 -3
View File
@@ -18,8 +18,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: PUdp.h,v 1.5 2001/04/22 23:09:45 steve Exp $"
#ifdef HAVE_CVS_IDENT
#ident "$Id: PUdp.h,v 1.7 2002/08/12 01:34:58 steve Exp $"
#endif
# include <map>
@@ -27,6 +27,8 @@
# include <string>
# include "verinum.h"
class PExpr;
svector<string>::svector<string>(unsigned size)
: nitems_(size), items_(new string[size])
{
@@ -68,7 +70,7 @@ class PUdp {
verinum::V initial;
map<string,string> attributes;
map<string,PExpr*> attributes;
void dump(ostream&out) const;
@@ -82,6 +84,17 @@ class PUdp {
/*
* $Log: PUdp.h,v $
* Revision 1.7 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.6 2002/05/23 03:08:51 steve
* Add language support for Verilog-2001 attribute
* syntax. Hook this support into existing $attribute
* handling, and add number and void value types.
*
* Add to the ivl_target API new functions for access
* of complex attributes attached to gates.
*
* Revision 1.5 2001/04/22 23:09:45 steve
* More UDP consolidation from Stephan Boettcher.
*
+48 -5
View File
@@ -16,18 +16,34 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: PWire.cc,v 1.6 2001/07/25 03:10:48 steve Exp $"
#ifdef HAVE_CVS_IDENT
#ident "$Id: PWire.cc,v 1.10 2002/08/12 01:34:58 steve Exp $"
#endif
# include "config.h"
# include "PWire.h"
# include <assert.h>
PWire::PWire(const string&n, NetNet::Type t, NetNet::PortType pt)
: name_(n), type_(t), port_type_(pt), signed_(false), lidx_(0), ridx_(0)
PWire::PWire(const hname_t&n, NetNet::Type t, NetNet::PortType pt)
: hname_(n), type_(t), port_type_(pt), signed_(false), isint_(false),
lidx_(0), ridx_(0)
{
if (t == NetNet::INTEGER) {
type_ = NetNet::REG;
signed_ = true;
isint_ = true;
}
}
PWire::PWire(char*n, NetNet::Type t, NetNet::PortType pt)
: hname_(n), type_(t), port_type_(pt), signed_(false), isint_(false),
lidx_(0), ridx_(0)
{
if (t == NetNet::INTEGER) {
type_ = NetNet::REG;
signed_ = true;
isint_ = true;
}
}
NetNet::Type PWire::get_wire_type() const
@@ -35,6 +51,11 @@ NetNet::Type PWire::get_wire_type() const
return type_;
}
const hname_t& PWire::path() const
{
return hname_;
}
bool PWire::set_wire_type(NetNet::Type t)
{
assert(t != NetNet::IMPLICIT);
@@ -47,6 +68,10 @@ bool PWire::set_wire_type(NetNet::Type t)
if (t == NetNet::REG) { type_ = t; return true; }
return false;
case NetNet::REG:
if (t == NetNet::INTEGER) {
isint_ = true;
return true;
}
if (t == NetNet::REG) return true;
return false;
default:
@@ -93,6 +118,11 @@ bool PWire::get_signed() const
return signed_;
}
bool PWire::get_isint() const
{
return isint_;
}
void PWire::set_range(PExpr*m, PExpr*l)
{
msb_ = svector<PExpr*>(msb_,m);
@@ -110,6 +140,19 @@ void PWire::set_memory_idx(PExpr*ldx, PExpr*rdx)
/*
* $Log: PWire.cc,v $
* Revision 1.10 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.9 2002/06/21 04:59:35 steve
* Carry integerness throughout the compilation.
*
* Revision 1.8 2002/01/26 05:28:28 steve
* Detect scalar/vector declarion mismatch.
*
* Revision 1.7 2001/12/03 04:47:14 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
*
* Revision 1.6 2001/07/25 03:10:48 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
+34 -7
View File
@@ -18,8 +18,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: PWire.h,v 1.10 2001/01/16 02:44:18 steve Exp $"
#ifdef HAVE_CVS_IDENT
#ident "$Id: PWire.h,v 1.14 2002/08/12 01:34:58 steve Exp $"
#endif
# include "netlist.h"
@@ -40,14 +40,21 @@ class Design;
* Wires include nets, registers and ports. A net or register becomes
* a port by declaration, so ports are not seperate. The module
* identifies a port by keeping it in its port list.
*
* The hname parameter to the constructor is a hierarchical name. It
* is an array of strings starting with the root, running towards
* the base name, and terminated by a null pointer. The environment
* allocates the memory for me.
*/
class PWire : public LineInfo {
public:
PWire(const string&n, NetNet::Type t, NetNet::PortType pt);
PWire(const hname_t&hname, NetNet::Type t, NetNet::PortType pt);
PWire(char*name, NetNet::Type t, NetNet::PortType pt);
const string&name() const { return name_; }
// Return a hierarchical name.
//const string name() const;
const hname_t&path() const;
NetNet::Type get_wire_type() const;
bool set_wire_type(NetNet::Type);
@@ -57,12 +64,13 @@ class PWire : public LineInfo {
void set_signed(bool flag);
bool get_signed() const;
bool get_isint() const;
void set_range(PExpr*msb, PExpr*lsb);
void set_memory_idx(PExpr*ldx, PExpr*rdx);
map<string,string> attributes;
map<string,PExpr*> attributes;
// Write myself to the specified stream.
void dump(ostream&out) const;
@@ -70,10 +78,11 @@ class PWire : public LineInfo {
void elaborate_sig(Design*, NetScope*scope) const;
private:
string name_;
hname_t hname_;
NetNet::Type type_;
NetNet::PortType port_type_;
bool signed_;
bool isint_; // original type of integer
// These members hold expressions for the bit width of the
// wire. If they do not exist, the wire is 1 bit wide.
@@ -92,6 +101,24 @@ class PWire : public LineInfo {
/*
* $Log: PWire.h,v $
* Revision 1.14 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.13 2002/06/21 04:59:35 steve
* Carry integerness throughout the compilation.
*
* Revision 1.12 2002/05/23 03:08:51 steve
* Add language support for Verilog-2001 attribute
* syntax. Hook this support into existing $attribute
* handling, and add number and void value types.
*
* Add to the ivl_target API new functions for access
* of complex attributes attached to gates.
*
* Revision 1.11 2001/12/03 04:47:14 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
*
* Revision 1.10 2001/01/16 02:44:18 steve
* Use the iosfwd header if available.
*
+147 -130
View File
@@ -12,14 +12,13 @@ home page at <http://www.icarus.com/eda/verilog>.
Icarus Verilog is not aimed at being a simulator in the traditional
sense, but a compiler that generates code employed by back-end
tools. These back-end tools currently include a simulator written in
C++ called VVM, another faster simulator called VVP and an XNF (Xilinx
Netlist Format) generator. See "vvm.txt" and "xnf.txt" for further
details on these back-end processors. In the future, backends are
expected for EDIF/LPM, structural Verilog, VHDL, etc.
tools. These back-end tools currently include a simulator engine
called VVP, an XNF (Xilinx Netlist Format) generator and an EDIF fpga
netlist generator. In the future, backends are expected for EDIF/LPM,
structural Verilog, VHDL, etc.
For instructions on how to run Icarus Verilog, see the ``iverilog''
man page.
For instructions on how to run Icarus Verilog,
see the ``iverilog'' man page.
2.0 Building/Installing Icarus Verilog From Source
@@ -30,6 +29,8 @@ system and C/C++ compilation should be able to build the source
distribution with little effort. Some actual programming skills are
not required, but helpful in case of problems.
If you are building for Windows, see the mingw.txt file.
2.1 Compile Time Prerequisites
You need the following software to compile Icarus Verilog from source
@@ -38,7 +39,7 @@ on a UNIX-like system:
- GNU Make
The Makefiles use some GNU extensions, so a basic POSIX
make will not work. Linux systems typically come with a
satisfactory make. BSD based systems (i.e. NetBSD, FreeBSD)
satisfactory make. BSD based systems (i.e., NetBSD, FreeBSD)
typically have GNU make as the gmake program.
- ISO C++ Compiler
@@ -73,7 +74,7 @@ configure script that modify its behavior:
--without-ipal
This turns off support for Icarus PAL, whether ipal
libaries are installed or not.
libraries are installed or not.
--prefix=<root>
The default is /usr/local, which causes the tool suite to
@@ -81,8 +82,9 @@ configure script that modify its behavior:
/usr/local/share/ivl, etc.
I recommend that if you are configuring for precompiled
binaries, use --prefix=/usr. On Solaris systems, it is
common to use --prefix=/opt.
binaries, use --prefix=/usr. On Solaris systems, it is
common to use --prefix=/opt. You can configure for a non-root
install with --prefix=$HOME.
2.3 (Optional) Testing
@@ -91,7 +93,7 @@ To run a simple test before installation, execute
make check
The commands printed by this run might help you in running Icarus
Verilog on your own verilog sources before the package is installed
Verilog on your own Verilog sources before the package is installed
by root.
2.4 Installation
@@ -127,7 +129,7 @@ only sees a single input file. See ivlpp/ivlpp.txt for details.
3.2 Parse
The verilog compiler starts by parsing the verilog source file. The
The Verilog compiler starts by parsing the Verilog source file. The
output of the parse in a list of Module objects in PFORM. The pform
(see pform.h) is mostly a direct reflection of the compilation
step. There may be dangling references, and it is not yet clear which
@@ -150,10 +152,10 @@ The elaborate() function performs the elaboration.
One can see a human readable version of the final, elaborated and
optimized netlist by using the ``-N <path>'' flag to the compiler. If
elaboration succeeds, the final netlist (i.e. after optimizations but
elaboration succeeds, the final netlist (i.e., after optimizations but
before code generation) will be dumped into the file named <path>.
Elaboration is actually performed it two steps: scopes and parameters
Elaboration is actually performed in two steps: scopes and parameters
first, followed by the structural and behavioral elaboration.
3.3.1 Scope Elaboration
@@ -182,19 +184,19 @@ simply passing through the pform.
This is actually a collection of processing steps that perform
optimizations that do not depend on the target technology. Examples of
some useful transformations would be,
some useful transformations are
- eliminate null effect circuitry,
- eliminate null effect circuitry
- combinational reduction
- Constant propagation
- constant propagation
The actual functions performed are specified on the ivl command line by
the -F flags (See below).
the -F flags (see below).
3.5 Code Generation
This step takes the design netlist and uses it to drive the code
generator. (See target.h.) This may require transforming the
generator (see target.h). This may require transforming the
design to suit the technology.
The emit() method of the Design class performs this step. It runs
@@ -206,7 +208,10 @@ command line.
3.6 ATTRIBUTES
The parser accepts as an extension to Verilog the $attribute module
NOTE: The $attribute syntax will soon be deprecated in favor of the
Verilog-2001 attribute syntax, which is cleaner and standardized.
The parser accepts, as an extension to Verilog, the $attribute module
item. The syntax of the $attribute item is:
$attribute (<identifier>, <key>, <value>);
@@ -234,6 +239,11 @@ between processing steps. Processing steps that are aware of others
may place attributes on netlist objects to communicate information to
later steps.
Icarus Verilog also accepts the Verilog 2001 syntax for
attributes. They have the same general meaning as with the $attribute
syntax, but they are attached to objects by position instead of by
name. Also, the key is a Verilog identifier instead of a string.
4.0 Running iverilog
The preferred way to invoke the compiler is with the iverilog(1)
@@ -241,93 +251,8 @@ command. This program invokes the preprocessor (ivlpp) and the
compiler (ivl) with the proper command line options to get the job
done in a friendly way. See the iverilog(1) man page for usage details.
4.1 Running IVL Directly (not recommended)
NOTE: The preferred method of running Icarus Verilog is the
iverilog command described above. The instructions below may
change at any time without notice.
The ivl command is the compiler driver, that invokes the parser,
optimization functions and the code generator, but not the preprocessor.
Usage: ivl <options>... file
ivl -h
ivl -V
-F <name>
Use this flag to request an optimization function be applied
to the netlist before it is sent to the target output
stage. Any number of -F options may be given, to specify a
variety of processing steps. The steps will be applied in
order, with the output of one uses as the input to the next.
The function is specified by name. Use the "ivl -h" command to
get a list of configured function names.
-h
Print usage information, and exit.
-m <module>
Cause a named VPI module to be included in the module
list. This parameter appends the named module to the end of
the VPI_MODULE_LIST. This is an ordered list of modules to be
loaded into the simulation at runtime.
This list can also be set with -fVPI_MODULE_LIST=<list> which
sets the list completely. Then, -m after this will append
module names to the list sp specified. The default list
includes "system".
-N <file>
Dump the elaborated netlist to the named file. The netlist is
the folly elaborated netlist, after all the function modules
are applied and right before the output generator is
called. This is an aid for debugging the compiler, and the
output generator in particular.
-o <file>
Normally, the generated result is sent to standard
output. Use the -o flag to specify an output file for the
generated result.
-P <file>
Write the PForm of the parsed input to the specified file.
The pform is the compiler's understanding of the input after
parsing and before elaboration. This is an aid for debugging
the compiler.
-p <assign>
Use this flag to set a parameter value. The format of the
assignment is <key>=<value> where key is any string up to the
first '=', and <value> is the rest of the option. If the '='
is omitted, then the key is assigned the empty string.
The useful keys are defined by the functions and the target in
use. These assignments are specifically useful for passing
target specific information to the target back-end, or
options/parameters to optimization functions, if any are defined.
-s <module>
Normally, ivl will elaborate the only module in the source
file. If there are multiple modules, use this option to select
the module to be used as the top-level module.
-T [min|typ|max]
Normally, ivl will select typ values from min:type:max
expressions and print a warning. This flag tells the compiler
exactly which value to choose, and suppresses the warning.
-t <name>
Select the output format for the compiled result. Use the
"ivl -h" command to get a list of configured targets.
-v Print progress indications, and (if supported by the system)
executions times in ivl precessing steps.
-V
Print version and copyright information for ivl, and exit.
4.2 EXAMPLES
4.1 EXAMPLES
Example: Compiling "hello.vl"
@@ -344,7 +269,7 @@ endmodule
--------------------------------------------------------------
Insure that "iverilog" is on your search path, and the vpi library
Ensure that "iverilog" is on your search path, and the vpi library
is available.
To compile the program:
@@ -365,25 +290,12 @@ by the compiler. See the iverilog(1) man page.
Icarus Verilog is in development - as such it still only supports a
(growing) subset of Verilog. Below is a description of some of the
currently unsupported verilog features. This list is not exhaustive,
currently unsupported Verilog features. This list is not exhaustive,
and does not account for errors in the compiler. See the Icarus
Verilog web page for the current state of support for Verilog, and in
particular, browse the bug report database for reported unsupported
constructs.
- block disable not supported, i.e.:
begin : foo
[...]
disable foo; // sorry
[...]
end
- Functions in structural contexts are not supported.
assign foo = user_function(a,b); // sorry
always @(a or b) foo = user_function(a,b); // OK
- real data types not supported. This includes real and
realtime. However, floating point constants in delay expressions
are supported so that `timescale works properly.
@@ -395,6 +307,105 @@ constructs.
- trireg is not supported. tri0 and tri1 are supported.
- tran primitives, i.e. tran, tranif1, tranif0, rtran, rtranif1
and rtranif0 are not supported.
- Module instance arrays are not supported, although gate instance
arrays do work.
- Net delays, of the form "wire #N foo;" do not work. Delays in
every other context do work properly, including the V2001 form
"wire #5 foo = bar;"
- Event controls inside non-blocking assignments are not supported.
i.e.: a <= @(posedge clk) b;
- Lists of named events of the form @(event_1 or event_2) are not
supported. Named events are otherwise supported, and lists of
other kinds of events are also supported.
- Macro arguments are not supported. `define macros are supported,
but they cannot take arguments.
5.1 Nonstandard Constructs or Behaviors
Icarus Verilog includes some features that are not part of the
IEEE1364 standard, but have well defined meaning, and also sometimes
gives nonstandard (but extended) meanings to some features of the
language that are defined.
$sizeof(<expr>)
$bits(<expr>)
The $bits system function returns the size in bits of the
expression that is its argument. The result of this
function is undefined if the argument doesn't have a
self-determined size.
The $sizeof function is deprecated in favor of $bits, which is
the same thing, but included in the SystemVerilog definition.
Builtin system functions
Certain of the system functions have well defined meanings, so
can theoretically be evaluated at compile time, instead of
using runtime VPI code. Doing so means that VPI cannot
override the definitions of functions handled in this
manner. On the other hand, this makes them synthesizeable, and
also allows for more aggressive constant propagation. The
functions handled in this manner are:
$bits
$signed
$sizeof
$unsigned
Implementations of these system functions in VPI modules will
be ignored.
Preprocessing Library Modules
Icarus Verilog does preprocess modules that are loaded from
libraries via the -y mechanism. However, the only macros
defined during compilation of that file are those that it
defines itself (or includes) or that are defined on the
command line or command file.
Specifically, macros defined in the non-library source files
are not remembered when the library module is loaded. This is
intentional. If it were otherwise, then compilation results
might vary depending on the order that libraries are loaded,
and that is too unpredictable.
It is said that some commercial compilers do allow macro
definitions to span library modules. That's just plain weird.
Width in %t Time Formats
Standard Verilog does not allow width fields in the %t formats
of display strings. For example, this is illegal:
$display("Time is %0t", %time);
Standard Verilog instead relies on the $timeformat to
completely specify the format.
Icarus Verilog allows the programmer to specify the field
with. The "%t" format in Icarus Verilog works exactly as it
does in standard Verilog. However, if the programmer chooses
to specify a minimum width (i.e., "%5t"), then for that display
Icarus Verilog will override the $timeformat minimum width and
use the explicit minimum width.
vpiScope iterator on vpiScope objects.
In the VPI, the normal way to iterate over vpiScope objects
contained within a vpiScope object, is the vpiInternalScope
iterator. Icarus Verilog adds support for the vpiScope
iterator of a vpiScope object, that iterates over *everything*
the is contained in the current scope. This is useful in cases
where one wants to iterate over all the objects in a scope
without iterating over all the contained types explicitly.
6.0 CREDITS
@@ -411,15 +422,18 @@ Verilog guidance, and especially testing from many people, including
Guy Hutchison <[email protected]>
Ales Hvezda <[email protected]>
Venkat Iyer <[email protected]>
Yasuhisa Kato <ykato@mac.com>
Yasuhisa Kato <kato@y.email.ne.jp>
James Lee <[email protected]>
Peter Monta <[email protected]>
Daniel H. Nelsen <[email protected]>
Stefan Petersen <[email protected]>
Michael Ruff <[email protected]>
Mike Runyan <[email protected]>
Jason Schonberg <[email protected]>
Stuart Sutherland <[email protected]>
Stephen Tell <[email protected]>
Stefan Theide <[email protected]>
Tom Verbeure
Steve Wilson <[email protected]>
and others. Testers in particular include a larger community of people
@@ -445,7 +459,10 @@ removed from the list) send e-mail to me.
Hamish Moffatt <[email protected]>
Macintosh -- MacO/S
Yasuhisa Kato <ykato@mac.com>
Yasuhisa Kato <kato@y.email.ne.jp>
Mac O/S X
Timothy J. Wood <[email protected]>
NetBSD/*
Dan McMahill <[email protected]>
@@ -465,10 +482,10 @@ just the systems where precompiled binaries are publicly available.
6.2 TEST SUITE MANAGER
Steve Wilson <stevew@home.com> or <[email protected]> has taken on
the large task of managing the test suite. He has maintained the
regression test scripts, the driver list, received submissions from
myself and others, and has written a great many tests on his own. Any
compiler writer, for any language, will tell you that the test suite
is at least as important as the compiler code itself.
Steve Wilson <stevew@ka6s.com> has taken on the large task of managing
the test suite. He has maintained the regression test scripts, the
driver list, received submissions from myself and others, and has
written a great many tests on his own. Any compiler writer, for any
language, will tell you that the test suite is at least as important
as the compiler code itself.
+60 -108
View File
@@ -16,8 +16,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: Statement.cc,v 1.23 2001/07/25 03:10:48 steve Exp $"
#ifdef HAVE_CVS_IDENT
#ident "$Id: Statement.cc,v 1.28 2002/08/12 01:34:58 steve Exp $"
#endif
# include "config.h"
@@ -32,17 +32,19 @@ Statement::~Statement()
PAssign_::PAssign_(PExpr*lval, PExpr*ex)
: event_(0), lval_(lval), rval_(ex)
{
delay_ = 0;
}
PAssign_::PAssign_(PExpr*lval, PExpr*de, PExpr*ex)
: event_(0), lval_(lval), rval_(ex)
{
if (de) delay_.set_delay(de);
delay_ = de;
}
PAssign_::PAssign_(PExpr*lval, PEventStatement*ev, PExpr*ex)
: event_(ev), lval_(lval), rval_(ex)
{
delay_ = 0;
}
PAssign_::~PAssign_()
@@ -105,11 +107,20 @@ PBlock::~PBlock()
delete list_[idx];
}
PCallTask::PCallTask(const string&n, const svector<PExpr*>&p)
: name_(n), parms_(p)
PCallTask::PCallTask(const hname_t&n, const svector<PExpr*>&p)
: path_(n), parms_(p)
{
}
PCallTask::~PCallTask()
{
}
const hname_t& PCallTask::path() const
{
return path_;
}
PCase::PCase(NetCase::TYPE t, PExpr*ex, svector<PCase::Item*>*l)
: type_(t), expr_(ex), items_(l)
{
@@ -167,7 +178,7 @@ PDelayStatement::~PDelayStatement()
{
}
PDisable::PDisable(const string&sc)
PDisable::PDisable(const hname_t&sc)
: scope_(sc)
{
}
@@ -179,6 +190,7 @@ PDisable::~PDisable()
PEventStatement::PEventStatement(const svector<PEEvent*>&ee)
: expr_(ee), statement_(0)
{
assert(expr_.count() > 0);
}
@@ -188,6 +200,11 @@ PEventStatement::PEventStatement(PEEvent*ee)
expr_[0] = ee;
}
PEventStatement::PEventStatement(void)
: statement_(0)
{
}
PEventStatement::~PEventStatement()
{
// delete the events and the statement?
@@ -219,6 +236,17 @@ PForever::~PForever()
delete statement_;
}
PForStatement::PForStatement(PExpr*n1, PExpr*e1, PExpr*cond,
PExpr*n2, PExpr*e2, Statement*st)
: name1_(n1), expr1_(e1), cond_(cond), name2_(n2), expr2_(e2),
statement_(st)
{
}
PForStatement::~PForStatement()
{
}
PProcess::~PProcess()
{
delete statement_;
@@ -245,7 +273,7 @@ PRepeat::~PRepeat()
delete statement_;
}
PTrigger::PTrigger(const string&e)
PTrigger::PTrigger(const hname_t&e)
: event_(e)
{
}
@@ -254,6 +282,11 @@ PTrigger::~PTrigger()
{
}
PWhile::PWhile(PExpr*e1, Statement*st)
: cond_(e1), statement_(st)
{
}
PWhile::~PWhile()
{
delete cond_;
@@ -262,109 +295,28 @@ PWhile::~PWhile()
/*
* $Log: Statement.cc,v $
* Revision 1.28 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.27 2002/04/21 22:31:02 steve
* Redo handling of assignment internal delays.
* Leave it possible for them to be calculated
* at run time.
*
* Revision 1.26 2002/04/21 04:59:07 steve
* Add support for conbinational events by finding
* the inputs to expressions and some statements.
* Get case and assignment statements working.
*
* Revision 1.25 2001/12/03 04:47:14 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
*
* Revision 1.24 2001/11/22 06:20:59 steve
* Use NetScope instead of string for scope path.
*
* Revision 1.23 2001/07/25 03:10:48 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
*
* Revision 1.22 2000/07/26 05:08:07 steve
* Parse disable statements to pform.
*
* Revision 1.21 2000/05/11 23:37:26 steve
* Add support for procedural continuous assignment.
*
* Revision 1.20 2000/04/22 04:20:19 steve
* Add support for force assignment.
*
* Revision 1.19 2000/04/12 04:23:57 steve
* Named events really should be expressed with PEIdent
* objects in the pform,
*
* Handle named events within the mix of net events
* and edges. As a unified lot they get caught together.
* wait statements are broken into more complex statements
* that include a conditional.
*
* Do not generate NetPEvent or NetNEvent objects in
* elaboration. NetEvent, NetEvWait and NetEvProbe
* take over those functions in the netlist.
*
* Revision 1.18 2000/04/01 19:31:57 steve
* Named events as far as the pform.
*
* Revision 1.17 2000/02/23 02:56:54 steve
* Macintosh compilers do not support ident.
*
* Revision 1.16 1999/09/29 18:36:02 steve
* Full case support
*
* Revision 1.15 1999/09/22 02:00:48 steve
* assignment with blocking event delay.
*
* Revision 1.14 1999/09/04 19:11:46 steve
* Add support for delayed non-blocking assignments.
*
* Revision 1.13 1999/09/02 01:59:27 steve
* Parse non-blocking assignment delays.
*
* Revision 1.12 1999/07/12 00:59:36 steve
* procedural blocking assignment delays.
*
* Revision 1.11 1999/06/24 04:24:18 steve
* Handle expression widths for EEE and NEE operators,
* add named blocks and scope handling,
* add registers declared in named blocks.
*
* Revision 1.10 1999/06/19 21:06:16 steve
* Elaborate and supprort to vvm the forever
* and repeat statements.
*
* Revision 1.9 1999/06/15 05:38:39 steve
* Support case expression lists.
*
* Revision 1.8 1999/06/13 23:51:16 steve
* l-value part select for procedural assignments.
*
* Revision 1.7 1999/06/06 20:45:38 steve
* Add parse and elaboration of non-blocking assignments,
* Replace list<PCase::Item*> with an svector version,
* Add integer support.
*
* Revision 1.6 1999/05/10 00:16:58 steve
* Parse and elaborate the concatenate operator
* in structural contexts, Replace vector<PExpr*>
* and list<PExpr*> with svector<PExpr*>, evaluate
* constant expressions with parameters, handle
* memories as lvalues.
*
* Parse task declarations, integer types.
*
* Revision 1.5 1999/02/03 04:20:11 steve
* Parse and elaborate the Verilog CASE statement.
*
* Revision 1.4 1999/01/25 05:45:56 steve
* Add the LineInfo class to carry the source file
* location of things. PGate, Statement and PProcess.
*
* elaborate handles module parameter mismatches,
* missing or incorrect lvalues for procedural
* assignment, and errors are propogated to the
* top of the elaboration call tree.
*
* Attach line numbers to processes, gates and
* assignment statements.
*
* Revision 1.3 1998/11/11 03:13:04 steve
* Handle while loops.
*
* Revision 1.2 1998/11/07 17:05:05 steve
* Handle procedural conditional, and some
* of the conditional expressions.
*
* Elaborate signals and identifiers differently,
* allowing the netlist to hold signal information.
*
* Revision 1.1 1998/11/03 23:28:55 steve
* Introduce verilog to CVS.
*
*/
+75 -142
View File
@@ -18,14 +18,15 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: Statement.h,v 1.29 2000/09/09 15:21:26 steve Exp $"
#ifdef HAVE_CVS_IDENT
#ident "$Id: Statement.h,v 1.36 2002/08/12 01:34:58 steve Exp $"
#endif
# include <string>
# include "svector.h"
# include "PDelays.h"
# include "PExpr.h"
# include "HName.h"
# include "LineInfo.h"
class PExpr;
class Statement;
@@ -55,6 +56,8 @@ class PProcess : public LineInfo {
Type type() const { return type_; }
Statement*statement() { return statement_; }
map<string,PExpr*> attributes;
virtual void dump(ostream&out, unsigned ind) const;
private:
@@ -74,7 +77,7 @@ class Statement : public LineInfo {
virtual ~Statement() =0;
virtual void dump(ostream&out, unsigned ind) const;
virtual NetProc* elaborate(Design*des, const string&path) const;
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
virtual void elaborate_scope(Design*des, NetScope*scope) const;
};
@@ -96,7 +99,7 @@ class PAssign_ : public Statement {
protected:
NetAssign_* elaborate_lval(Design*, NetScope*scope) const;
PDelays delay_;
PExpr* delay_;
PEventStatement*event_;
private:
@@ -113,11 +116,9 @@ class PAssign : public PAssign_ {
~PAssign();
virtual void dump(ostream&out, unsigned ind) const;
virtual NetProc* elaborate(Design*des, const string&path) const;
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
private:
NetProc*assign_to_memory_(class NetMemory*, PExpr*,
Design*des, const string&path) const;
};
class PAssignNB : public PAssign_ {
@@ -128,11 +129,11 @@ class PAssignNB : public PAssign_ {
~PAssignNB();
virtual void dump(ostream&out, unsigned ind) const;
virtual NetProc* elaborate(Design*des, const string&path) const;
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
private:
NetProc*assign_to_memory_(class NetMemory*, PExpr*,
Design*des, const string&path) const;
Design*des, NetScope*scope) const;
};
/*
@@ -154,11 +155,9 @@ class PBlock : public Statement {
BL_TYPE bl_type() const { return bl_type_; }
//unsigned size() const { return list_.count(); }
//const Statement*stat(unsigned idx) const { return list_[idx]; }
virtual void dump(ostream&out, unsigned ind) const;
virtual NetProc* elaborate(Design*des, const string&path) const;
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
virtual void elaborate_scope(Design*des, NetScope*scope) const;
private:
@@ -170,9 +169,10 @@ class PBlock : public Statement {
class PCallTask : public Statement {
public:
explicit PCallTask(const string&n, const svector<PExpr*>&parms);
explicit PCallTask(const hname_t&n, const svector<PExpr*>&parms);
~PCallTask();
string name() const { return name_; }
const hname_t& path() const;
unsigned nparms() const { return parms_.count(); }
@@ -187,13 +187,13 @@ class PCallTask : public Statement {
}
virtual void dump(ostream&out, unsigned ind) const;
virtual NetProc* elaborate(Design*des, const string&path) const;
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
private:
NetProc* elaborate_sys(Design*des, const string&path) const;
NetProc* elaborate_usr(Design*des, const string&path) const;
NetProc* elaborate_sys(Design*des, NetScope*scope) const;
NetProc* elaborate_usr(Design*des, NetScope*scope) const;
const string name_;
hname_t path_;
svector<PExpr*> parms_;
};
@@ -208,7 +208,7 @@ class PCase : public Statement {
PCase(NetCase::TYPE, PExpr*ex, svector<Item*>*);
~PCase();
virtual NetProc* elaborate(Design*des, const string&path) const;
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
virtual void elaborate_scope(Design*des, NetScope*scope) const;
virtual void dump(ostream&out, unsigned ind) const;
@@ -229,7 +229,7 @@ class PCAssign : public Statement {
explicit PCAssign(PExpr*l, PExpr*r);
~PCAssign();
virtual NetCAssign* elaborate(Design*des, const string&path) const;
virtual NetCAssign* elaborate(Design*des, NetScope*scope) const;
virtual void dump(ostream&out, unsigned ind) const;
private:
@@ -243,7 +243,7 @@ class PCondit : public Statement {
PCondit(PExpr*ex, Statement*i, Statement*e);
~PCondit();
virtual NetProc* elaborate(Design*des, const string&path) const;
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
virtual void elaborate_scope(Design*des, NetScope*scope) const;
virtual void dump(ostream&out, unsigned ind) const;
@@ -263,7 +263,7 @@ class PDeassign : public Statement {
explicit PDeassign(PExpr*l);
~PDeassign();
virtual NetDeassign* elaborate(Design*des, const string&path) const;
virtual NetDeassign* elaborate(Design*des, NetScope*scope) const;
virtual void dump(ostream&out, unsigned ind) const;
private:
@@ -277,7 +277,7 @@ class PDelayStatement : public Statement {
~PDelayStatement();
virtual void dump(ostream&out, unsigned ind) const;
virtual NetProc* elaborate(Design*des, const string&path) const;
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
virtual void elaborate_scope(Design*des, NetScope*scope) const;
private:
@@ -292,14 +292,14 @@ class PDelayStatement : public Statement {
class PDisable : public Statement {
public:
explicit PDisable(const string&sc);
explicit PDisable(const hname_t&sc);
~PDisable();
virtual void dump(ostream&out, unsigned ind) const;
virtual NetProc* elaborate(Design*des, const string&path) const;
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
private:
string scope_;
hname_t scope_;
};
/*
@@ -308,6 +308,7 @@ class PDisable : public Statement {
*
* @name <statement>;
* @(expr) <statement>;
* @* <statement>;
*/
class PEventStatement : public Statement {
@@ -315,18 +316,20 @@ class PEventStatement : public Statement {
explicit PEventStatement(const svector<PEEvent*>&ee);
explicit PEventStatement(PEEvent*ee);
// Make an @* statement.
explicit PEventStatement(void);
~PEventStatement();
void set_statement(Statement*st);
virtual void dump(ostream&out, unsigned ind) const;
virtual NetProc* elaborate(Design*des, const string&path) const;
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
virtual void elaborate_scope(Design*des, NetScope*scope) const;
// This method is used to elaborate, but attach a previously
// elaborated statement to the event.
NetProc* elaborate_st(Design*des, const string&path, NetProc*st) const;
NetProc* elaborate_st(Design*des, NetScope*scope, NetProc*st) const;
private:
svector<PEEvent*>expr_;
@@ -339,7 +342,7 @@ class PForce : public Statement {
explicit PForce(PExpr*l, PExpr*r);
~PForce();
virtual NetProc* elaborate(Design*des, const string&path) const;
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
virtual void dump(ostream&out, unsigned ind) const;
private:
@@ -352,7 +355,7 @@ class PForever : public Statement {
explicit PForever(Statement*s);
~PForever();
virtual NetProc* elaborate(Design*des, const string&path) const;
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
virtual void elaborate_scope(Design*des, NetScope*scope) const;
virtual void dump(ostream&out, unsigned ind) const;
@@ -364,12 +367,10 @@ class PForStatement : public Statement {
public:
PForStatement(PExpr*n1, PExpr*e1, PExpr*cond,
PExpr*n2, PExpr*e2, Statement*st)
: name1_(n1), expr1_(e1), cond_(cond), name2_(n2), expr2_(e2),
statement_(st)
{ }
PExpr*n2, PExpr*e2, Statement*st);
~PForStatement();
virtual NetProc* elaborate(Design*des, const string&path) const;
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
virtual void elaborate_scope(Design*des, NetScope*scope) const;
virtual void dump(ostream&out, unsigned ind) const;
@@ -396,7 +397,7 @@ class PRepeat : public Statement {
explicit PRepeat(PExpr*expr, Statement*s);
~PRepeat();
virtual NetProc* elaborate(Design*des, const string&path) const;
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
virtual void elaborate_scope(Design*des, NetScope*scope) const;
virtual void dump(ostream&out, unsigned ind) const;
@@ -411,7 +412,7 @@ class PRelease : public Statement {
explicit PRelease(PExpr*l);
~PRelease();
virtual NetProc* elaborate(Design*des, const string&path) const;
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
virtual void dump(ostream&out, unsigned ind) const;
private:
@@ -425,24 +426,23 @@ class PRelease : public Statement {
class PTrigger : public Statement {
public:
explicit PTrigger(const string&ev);
explicit PTrigger(const hname_t&ev);
~PTrigger();
virtual NetProc* elaborate(Design*des, const string&path) const;
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
virtual void dump(ostream&out, unsigned ind) const;
private:
string event_;
hname_t event_;
};
class PWhile : public Statement {
public:
PWhile(PExpr*e1, Statement*st)
: cond_(e1), statement_(st) { }
PWhile(PExpr*e1, Statement*st);
~PWhile();
virtual NetProc* elaborate(Design*des, const string&path) const;
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
virtual void elaborate_scope(Design*des, NetScope*scope) const;
virtual void dump(ostream&out, unsigned ind) const;
@@ -453,6 +453,38 @@ class PWhile : public Statement {
/*
* $Log: Statement.h,v $
* Revision 1.36 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.35 2002/06/04 05:38:44 steve
* Add support for memory words in l-value of
* blocking assignments, and remove the special
* NetAssignMem class.
*
* Revision 1.34 2002/05/26 01:39:02 steve
* Carry Verilog 2001 attributes with processes,
* all the way through to the ivl_target API.
*
* Divide signal reference counts between rval
* and lval references.
*
* Revision 1.33 2002/04/21 22:31:02 steve
* Redo handling of assignment internal delays.
* Leave it possible for them to be calculated
* at run time.
*
* Revision 1.32 2002/04/21 04:59:07 steve
* Add support for conbinational events by finding
* the inputs to expressions and some statements.
* Get case and assignment statements working.
*
* Revision 1.31 2001/12/03 04:47:14 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
*
* Revision 1.30 2001/11/22 06:20:59 steve
* Use NetScope instead of string for scope path.
*
* Revision 1.29 2000/09/09 15:21:26 steve
* move lval elaboration to PExpr virtual methods.
*
@@ -480,104 +512,5 @@ class PWhile : public Statement {
* Do not generate NetPEvent or NetNEvent objects in
* elaboration. NetEvent, NetEvWait and NetEvProbe
* take over those functions in the netlist.
*
* Revision 1.23 2000/04/01 19:31:57 steve
* Named events as far as the pform.
*
* Revision 1.22 2000/03/11 03:25:51 steve
* Locate scopes in statements.
*
* Revision 1.21 2000/02/23 02:56:54 steve
* Macintosh compilers do not support ident.
*
* Revision 1.20 1999/09/29 18:36:02 steve
* Full case support
*
* Revision 1.19 1999/09/22 02:00:48 steve
* assignment with blocking event delay.
*
* Revision 1.18 1999/09/15 01:55:06 steve
* Elaborate non-blocking assignment to memories.
*
* Revision 1.17 1999/09/04 19:11:46 steve
* Add support for delayed non-blocking assignments.
*
* Revision 1.16 1999/09/02 01:59:27 steve
* Parse non-blocking assignment delays.
*
* Revision 1.15 1999/07/12 00:59:36 steve
* procedural blocking assignment delays.
*
* Revision 1.14 1999/07/03 02:12:51 steve
* Elaborate user defined tasks.
*
* Revision 1.13 1999/06/24 04:24:18 steve
* Handle expression widths for EEE and NEE operators,
* add named blocks and scope handling,
* add registers declared in named blocks.
*
* Revision 1.12 1999/06/19 21:06:16 steve
* Elaborate and supprort to vvm the forever
* and repeat statements.
*
* Revision 1.11 1999/06/15 05:38:39 steve
* Support case expression lists.
*
* Revision 1.10 1999/06/13 23:51:16 steve
* l-value part select for procedural assignments.
*
* Revision 1.9 1999/06/06 20:45:38 steve
* Add parse and elaboration of non-blocking assignments,
* Replace list<PCase::Item*> with an svector version,
* Add integer support.
*
* Revision 1.8 1999/05/10 00:16:58 steve
* Parse and elaborate the concatenate operator
* in structural contexts, Replace vector<PExpr*>
* and list<PExpr*> with svector<PExpr*>, evaluate
* constant expressions with parameters, handle
* memories as lvalues.
*
* Parse task declarations, integer types.
*
* Revision 1.7 1999/04/29 02:16:26 steve
* Parse OR of event expressions.
*
* Revision 1.6 1999/02/03 04:20:11 steve
* Parse and elaborate the Verilog CASE statement.
*
* Revision 1.5 1999/01/25 05:45:56 steve
* Add the LineInfo class to carry the source file
* location of things. PGate, Statement and PProcess.
*
* elaborate handles module parameter mismatches,
* missing or incorrect lvalues for procedural
* assignment, and errors are propogated to the
* top of the elaboration call tree.
*
* Attach line numbers to processes, gates and
* assignment statements.
*
* Revision 1.4 1998/11/11 03:13:04 steve
* Handle while loops.
*
* Revision 1.3 1998/11/09 18:55:33 steve
* Add procedural while loops,
* Parse procedural for loops,
* Add procedural wait statements,
* Add constant nodes,
* Add XNOR logic gate,
* Make vvm output look a bit prettier.
*
* Revision 1.2 1998/11/07 17:05:05 steve
* Handle procedural conditional, and some
* of the conditional expressions.
*
* Elaborate signals and identifiers differently,
* allowing the netlist to hold signal information.
*
* Revision 1.1 1998/11/03 23:28:56 steve
* Introduce verilog to CVS.
*
*/
#endif
+77
View File
@@ -0,0 +1,77 @@
/*
* Copyright (c) 2002 Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
* ---
* You should also have recieved a copy of the Picture Elements
* Binary Software License offer along with the source. This offer
* allows you to obtain the right to redistribute the software in
* binary (compiled) form. If you have not received it, contact
* Picture Elements, Inc., 777 Panoramic Way, Berkeley, CA 94704.
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: StringHeap.cc,v 1.2 2002/08/12 01:34:58 steve Exp $"
#endif
# include "StringHeap.h"
#ifdef HAVE_MALLOC_H
# include <malloc.h>
#endif
# include <stdlib.h>
# include <string.h>
# include <assert.h>
StringHeap::StringHeap()
{
cell_base_ = 0;
cell_ptr_ = HEAPCELL;
}
StringHeap::~StringHeap()
{
// This is a planned memory leak. The string heap is indended
// to hold permanently-allocated strings.
}
const char* StringHeap::add(const char*text)
{
unsigned len = strlen(text);
assert((len+1) <= HEAPCELL);
unsigned rem = HEAPCELL - cell_ptr_;
if (rem < (len+1)) {
cell_base_ = (char*)malloc(HEAPCELL);
cell_ptr_ = 0;
}
char*res = cell_base_ + cell_ptr_;
memcpy(res, text, len);
cell_ptr_ += len;
cell_base_[cell_ptr_++] = 0;
return res;
}
/*
* $Log: StringHeap.cc,v $
* Revision 1.2 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.1 2002/08/04 19:13:16 steve
* dll uses StringHeap for named items.
*
*/
+53
View File
@@ -0,0 +1,53 @@
#ifndef __StringHeap_H
#define __StringHeap_H
/*
* Copyright (c) 2002 Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: StringHeap.h,v 1.2 2002/08/12 01:34:58 steve Exp $"
#endif
class StringHeap {
public:
StringHeap();
~StringHeap();
const char*add(const char*);
private:
enum { HEAPCELL = 0x10000 };
char*cell_base_;
unsigned cell_ptr_;
private: // not implemented
StringHeap(const StringHeap&);
StringHeap& operator= (const StringHeap&);
};
/*
* $Log: StringHeap.h,v $
* Revision 1.2 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.1 2002/08/04 19:13:16 steve
* dll uses StringHeap for named items.
*
*/
#endif
+159
View File
@@ -0,0 +1,159 @@
#ifndef __acc_user_H
#define __acc_user_H
/*
* Copyright (c) 2002 Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: acc_user.h,v 1.6 2002/08/12 01:34:58 steve Exp $"
#endif
/*
* This header file contains the definitions and declarations needed
* by an Icarus Verilog user using acc_ routines.
*
* NOTE: Icarus Verilog does not support acc_ routines. This is just a
* stub. The functions that are implemented here are actually
* implemented using VPI routines.
*/
#ifdef __cplusplus
# define EXTERN_C_START extern "C" {
# define EXTERN_C_END }
#else
# define EXTERN_C_START
# define EXTERN_C_END
# define bool int
#endif
EXTERN_C_START
/*
* This is a declaration of the "handle" type that is compatible with
* the vpiHandle from vpi_user.h.
*/
typedef struct __vpiHandle *handle;
/* OBJECT TYPES */
#define accScope 21
#define accScalar 300
#define accVector 302
/* type VALUES FOR t_setval_delay STRUCTURE */
#define accNoDelay 0
#define accInertialDelay 1
#define accTransportDelay 2
#define accPureTransportDelay 3
#define accForceFlag 4
#define accReleaseFlag 5
/* type VALUES FOR t_setval_value STRUCTURE */
#define accBinStrVal 1
#define accOctStrVal 2
#define accDecStrVal 3
#define accHexStrVal 4
#define accScalarVal 5
#define accIntVal 6
#define accRealVal 7
#define accStringVal 8
#define accVectorVal 9
/* type VALUES FOR t_acc_time STRUCTURE */
#define accTime 1
#define accSimTime 2
#define accRealTime 3
typedef struct t_acc_time {
int type;
int low, high;
double real;
} s_acc_time, *p_acc_time;
typedef struct t_setval_delay {
s_acc_time time;
int model;
} s_setval_delay, *p_setval_delay;
typedef struct t_acc_vecval {
int aval;
int bval;
} s_acc_vecval, *p_acc_vecval;
typedef struct t_setval_value {
int format;
union {
char*str;
int scalar;
int integer;
double real;
p_acc_vecval vector;
} value;
} s_setval_value, *p_setval_value, s_acc_value, *p_acc_value;
extern int acc_error_flag;
extern int acc_initialize(void);
extern void acc_close(void);
extern int acc_fetch_argc(void);
extern char**acc_fetch_argv(void);
extern char* acc_fetch_fullname(handle obj);
extern int acc_fetch_tfarg_int(int n);
extern char* acc_fetch_tfarg_str(int n);
extern handle acc_handle_tfarg(int n);
extern handle acc_next_topmod(handle prev_topmod);
extern int acc_object_of_type(handle object, int type);
extern char*acc_product_version(void);
extern int acc_set_value(handle obj, p_setval_value value,
p_setval_delay delay);
extern char* acc_version(void);
EXTERN_C_END
/*
* $Log: acc_user.h,v $
* Revision 1.6 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.5 2002/06/11 15:19:12 steve
* Add acc_fetch_argc/argv/version (mruff)
*
* Revision 1.4 2002/06/07 02:58:58 steve
* Add a bunch of acc/tf functions. (mruff)
*
* Revision 1.3 2002/06/02 19:03:29 steve
* Add acc_handle_tfarg and acc_next_topmode
*
* Revision 1.2 2002/05/30 02:06:05 steve
* Implement acc_product_version.
*
* Revision 1.1 2002/05/23 03:46:42 steve
* Add the acc_user.h header file.
*
*/
#endif
+97
View File
@@ -0,0 +1,97 @@
/*
* Copyright (c) 2002 Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: async.cc,v 1.4 2002/08/18 22:07:16 steve Exp $"
#endif
# include "config.h"
# include "functor.h"
# include "netlist.h"
# include <assert.h>
bool NetAssign::is_asynchronous()
{
return true;
}
bool NetCondit::is_asynchronous()
{
return false;
}
bool NetEvWait::is_asynchronous()
{
/* The "sense" set contains the set of Nexa that are in the
sensitivity list. We also presume here that the list is
only LEVEL sensitive. */
NexusSet*sense = new NexusSet;
for (unsigned idx = 0 ; idx < nevents_ ; idx += 1) {
NexusSet*tmp = event(idx)->nex_async_();
if (tmp == 0) {
delete sense;
return false;
}
sense->add(*tmp);
delete tmp;
}
NexusSet*inputs = statement_->nex_input();
if (! sense->contains(*inputs)) {
delete sense;
delete inputs;
return false;
}
delete sense;
delete inputs;
return true;
}
bool NetProc::is_asynchronous()
{
return false;
}
bool NetProcTop::is_asynchronous()
{
if (type_ == NetProcTop::KINITIAL)
return false;
return statement_->is_asynchronous();
}
/*
* $Log: async.cc,v $
* Revision 1.4 2002/08/18 22:07:16 steve
* Detect temporaries in sequential block synthesis.
*
* Revision 1.3 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.2 2002/07/04 00:24:16 steve
* initial statements are not asynchronous.
*
* Revision 1.1 2002/06/30 02:21:31 steve
* Add structure for asynchronous logic synthesis.
*
*/
+49
View File
@@ -0,0 +1,49 @@
ATTRIBUTES TO CONTROL SYNTHESIS
The following is a summary of Verilog attributes that Icarus Verilog
understands within Verilog source files to control synthesis
behavior. This section documents generic synthesis attributes. For
target specific attributes, see target specific documentation.
These attributes only effect the behavior of the synthesizer. For
example, the ivl_combinational will not generate an error message
if the Verilog is being compiled for simulation. (It may generate a
warning.)
* Attributes for "always" and "initial" statements
(* ivl_combinational *)
This attribute tells the compiler that the statement models
combinational logic. If the compiler finds that it cannot make
combinational logic out of a marked always statement, it will
report an error.
This attribute can be used to prevent accidentally inferring
latches or flip-flops where the user intended combinational
logic.
(* ivl_synthesis_on *)
This attribute tells the compiler that the marked always statement
is synthesizeable. The compiler will attempt to synthesize the
code in the marked "always" statement. If it cannot in any way
synthesize it, then it will report an error.
(* ivl_synthesis_off *)
If this value is attached to an "always" statement, then the
compiler will *not* synthesize the "always" statment. This can be
used, for example, to mark embedded test bench code.
* Attributes for signals (wire/reg/integer/tri/etc.)
[ none defined yet ]
* Other Attributes
[ none defined yet ]
+5 -2
View File
@@ -9,8 +9,11 @@
echo "Autoconf in root..."
autoconf
for dir in vpip vvp tgt-vvp tgt-fpga
for dir in vpip vvp tgt-vvp tgt-fpga libveriuser
do
echo "Autoconf in $dir..."
( cd $dir ; autoconf )
( cd ./$dir ; autoconf )
done
echo "Precompiling lexor_keyword.gperf"
gperf -o -i 7 -C -k 1-3,\$ -L ANSI-C -H keyword_hash -N check_identifier -t ./lexor_keyword.gperf > lexor_keyword.cc
+3
View File
@@ -4,3 +4,6 @@
[-tvvm-check]
<ivl>./ivl %W %[s-s%s] %[N-N%N] %[T-T%T] -tvvm -Fcprop -Fnodangle -fVPI_MODULE_PATH=vpi %f %m -o%o.cc -- -
[-tvvp-check]
<ivl>./ivl %W %[s-s%s] %[N-N%N] %[T-T%T] -tdll -fDLL=./tgt-vvp/vvp.tgt -Fcprop -Fnodangle -fVPI_MODULE_PATH=vpi %f %m -o%o -- -
+47 -13
View File
@@ -18,10 +18,12 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: compiler.h,v 1.5 2000/10/31 17:49:02 steve Exp $"
#ifdef HAVE_CVS_IDENT
#ident "$Id: compiler.h,v 1.13 2002/08/12 01:34:58 steve Exp $"
#endif
# include <list>
/*
* This defines constants and defaults for the compiler in general.
*/
@@ -65,24 +67,56 @@
/* Implicit definitions of wires. */
extern bool warn_implicit;
extern bool error_implicit;
/* inherit timescales accross files. */
extern bool warn_timescale;
/* This is true if verbose output is requested. */
extern bool verbose_flag;
/* This is an ordered list of library suffixxes to search. */
extern list<const char*>library_suff;
extern int build_library_index(const char*path, bool key_case_sensitive);
/* This is the generation of Verilog that the compiler is asked to
support. */
enum generation_t {
GN_VER1995 = 1,
GN_VER2001 = 2,
GN_SYSVER30 = 3,
GN_DEFAULT = 3
};
extern generation_t generation_flag;
/* This is the string to use to invoke the preprocessor. */
extern char*ivlpp_string;
/*
* $Log: compiler.h,v $
* Revision 1.5 2000/10/31 17:49:02 steve
* Support time variables.
* Revision 1.13 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.4 2000/08/20 04:13:56 steve
* Add ivl_target support for logic gates, and
* make the interface more accessible.
* Revision 1.12 2002/05/28 20:40:37 steve
* ivl indexes the search path for libraries, and
* supports case insensitive module-to-file lookup.
*
* Revision 1.3 2000/03/17 21:50:25 steve
* Switch to control warnings.
* Revision 1.11 2002/05/28 00:50:39 steve
* Add the ivl -C flag for bulk configuration
* from the driver, and use that to run library
* modules through the preprocessor.
*
* Revision 1.2 2000/02/23 02:56:54 steve
* Macintosh compilers do not support ident.
* Revision 1.10 2002/05/24 01:13:00 steve
* Support language generation flag -g.
*
* Revision 1.1 1999/06/06 20:42:48 steve
* Make compiler width a compile time constant.
* Revision 1.9 2002/04/22 00:53:39 steve
* Do not allow implicit wires in sensitivity lists.
*
* Revision 1.8 2002/04/15 00:04:22 steve
* Timescale warnings.
*
* Revision 1.7 2001/11/16 05:07:19 steve
* Add support for +libext+ in command files.
*/
#endif
+15 -1
View File
@@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: config.h.in,v 1.1 2001/07/25 03:10:48 steve Exp $"
#ident "$Id: config.h.in,v 1.5 2002/08/11 23:39:33 steve Exp $"
#endif
#if defined(__cplusplus)
@@ -37,13 +37,27 @@
# undef HAVE_TIMES
# undef HAVE_IOSFWD
# undef HAVE_GETOPT_H
# undef HAVE_MALLOC_H
# undef HAVE_DLFCN_H
# undef HAVE_DL_H
# undef HAVE_FCHMOD
# undef HAVE_LIBREADLINE
# undef HAVE_SYS_WAIT_H
/*
* $Log: config.h.in,v $
* Revision 1.5 2002/08/11 23:39:33 steve
* Remove VVM option.
*
* Revision 1.4 2002/02/16 03:18:53 steve
* Make vvm optional, normally off.
*
* Revision 1.3 2001/10/18 16:16:23 steve
* Include HAVE_SYS_WAIT in config.h (PR#306)
*
* Revision 1.2 2001/09/15 18:27:04 steve
* Make configure detect malloc.h
*
* Revision 1.1 2001/07/25 03:10:48 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
+126 -73
View File
@@ -14,9 +14,25 @@ then
exit 1
fi
AC_CHECK_PROGS(LEX,flex,none)
if test "$LEX" = "none"
then
echo "*** Error: No suitable flex found. ***"
echo " Please install the 'flex' package."
exit 1
fi
AC_CHECK_PROGS(YACC,bison,none)
if test "$YACC" = "none"
then
echo "*** Error: No suitable bison found. ***"
echo " Please install the 'bison' package."
exit 1
fi
AC_LANG_CPLUSPLUS
AC_CHECK_HEADERS(getopt.h iosfwd sys/wait.h)
AC_CHECK_HEADERS(getopt.h malloc.h iosfwd sys/wait.h)
AC_MSG_CHECKING(for sys/times)
AC_TRY_LINK(
@@ -30,7 +46,8 @@ do_times=no
AC_MSG_RESULT($do_times)
AC_CHECK_HEADER(ipal.h, HAVE_IPAL=yes, HAVE_IPAL=)
AC_ARG_WITH(ipal,enable PAL target,
AC_ARG_WITH(ipal,
[ --with-ipal enable PAL target],
if test "$with_ipal" = no; then
echo Disabling ipal support
HAVE_IPAL=
@@ -58,66 +75,6 @@ AC_LANG_C
AC_CANONICAL_HOST
# $host
#######################
## test for underscores. The vpi module loader in vvm needs to know this
## in order to know the name of the start symbol for the .vpi module.
#######################
AC_CYGWIN
AC_EXEEXT
AC_MINGW32
WIN32=no
AC_MSG_CHECKING("Checking for windows")
if test "$CYGWIN" = "yes" -o "$MINGW32" = "yes"
then
WIN32=yes
fi
AC_SUBST(WIN32)
AC_MSG_RESULT($WIN32)
AC_SUBST(EXEEXT)
AC_MSG_CHECKING("for leading and/or trailing underscores")
cat << EOF > underscore.c
void underscore(void){}
EOF
$CC -shared -c underscore.c > /dev/null 2>&1
CC_LEADING_UNDERSCORE=no
CC_TRAILING_UNDERSCORE=no
output=`nm underscore.o|grep _underscore 2>&1`
if test ! -z "$output" -a -z "$CYGWIN" -a -z "$MINGW32"; then
CC_LEADING_UNDERSCORE=yes
AC_DEFINE(NEED_LU)
fi
output=`nm underscore.o|grep underscore_ 2>&1`
if test ! -z "$output"; then
CC_TRAILING_UNDERSCORE=yes
AC_DEFINE(NEED_TU)
fi
if test "$CC_LEADING_UNDERSCORE" = yes; then
AC_DEFINE(WLU)
fi
if test "$CC_TRAILING_UNDERSCORE" = yes; then
AC_DEFINE(WTU)
fi
rm underscore.c underscore.o
AC_MSG_RESULT("$CC_LEADING_UNDERSCORE $CC_TRAILING_UNDERSCORE")
#######################
## end of test for underscores
#######################
# The -fPIC flag is used to tell the compiler to make position
# independent code. It is needed when making shared objects.
@@ -138,20 +95,25 @@ AC_SUBST(PICFLAG)
AC_MSG_RESULT($PICFLAG)
# mingw needs to link with libiberty.a
# mingw needs to link with libiberty.a, cygwin can tolerate it
AC_MSG_CHECKING("for extra libs needed")
EXTRALIBS=
case "${host}" in
*-*-cygwin*)
if test $ac_cv_mingw32 = yes; then
EXTRALIBS="-liberty"
fi
EXTRALIBS="-liberty"
;;
esac
AC_SUBST(EXTRALIBS)
AC_MSG_RESULT($EXTRALIBS)
# Darwin requires -no-cpp-precomp
case "${host}" in
*-*-darwin*)
CPPFLAGS="-no-cpp-precomp"
CFLAGS="-no-cpp-precomp"
;;
esac
# The -rdynamic flag is used by iverilog when compiling the target,
# to know how to export symbols of the main program to loadable modules
@@ -176,32 +138,123 @@ case "${host}" in
*-*-hpux*)
rdynamic="-E"
;;
*-*-darwin*)
rdynamic="-Wl,-all_load"
strip_dynamic="-SX"
;;
esac
AC_SUBST(rdynamic)
AC_MSG_RESULT($rdynamic)
AC_SUBST(strip_dynamic)
AC_MSG_RESULT($strip_dynamic)
AC_MSG_CHECKING("for shared library link flag")
shared=-shared
case "${host}" in
*-*-cygwin*)
shared="-mdll -Wl,--enable-auto-image-base"
if test $ac_cv_mingw32 = yes; then
shared="-shared -Wl,--enable-auto-image-base"
fi
shared="-shared -Wl,--enable-auto-image-base"
;;
*-*-hpux*)
shared="-b"
;;
*-*-darwin1.[0123])
shared="-bundle -undefined suppress"
;;
*-*-darwin*)
shared="-bundle -undefined suppress -flat_namespace"
;;
esac
AC_SUBST(shared)
AC_MSG_RESULT($shared)
#######################
## test for underscores. The vpi module loader needs to know this
## in order to know the name of the start symbol for the .vpi module.
#######################
AC_CONFIG_SUBDIRS(vpip vvp tgt-vvp tgt-fpga)
AC_CYGWIN
AC_EXEEXT
AC_MINGW32
AC_OUTPUT(Makefile vpi/Makefile ivlpp/Makefile vvm/Makefile driver/Makefile tgt-null/Makefile tgt-stub/Makefile tgt-verilog/Makefile tgt-pal/Makefile)
WIN32=no
AC_MSG_CHECKING("Checking for windows")
if test "$CYGWIN" = "yes" -o "$MINGW32" = "yes"
then
WIN32=yes
fi
AC_SUBST(MINGW32)
AC_SUBST(WIN32)
AC_MSG_RESULT($WIN32)
AC_SUBST(EXEEXT)
AC_MSG_CHECKING("for leading and/or trailing underscores")
cat << EOF > underscore.c
void underscore(void){}
EOF
$CC $shared -c underscore.c > /dev/null 2>&1
CC_LEADING_UNDERSCORE=no
CC_TRAILING_UNDERSCORE=no
output=`nm underscore.o|grep _underscore 2>&1`
if test ! -z "$output" -a "$CYGWIN" != "yes" -a "$MINGW32" != "yes"; then
CC_LEADING_UNDERSCORE=yes
AC_DEFINE(NEED_LU)
fi
output=`nm underscore.o|grep underscore_ 2>&1`
if test ! -z "$output"; then
CC_TRAILING_UNDERSCORE=yes
AC_DEFINE(NEED_TU)
fi
if test "$CC_LEADING_UNDERSCORE" = yes; then
AC_DEFINE(WLU)
fi
if test "$CC_TRAILING_UNDERSCORE" = yes; then
AC_DEFINE(WTU)
fi
rm underscore.c underscore.o
AC_MSG_RESULT("$CC_LEADING_UNDERSCORE $CC_TRAILING_UNDERSCORE")
#######################
## end of test for underscores
#######################
AC_MSG_CHECKING("for ident support in C compiler")
ident_support='-DHAVE_CVS_IDENT=1'
case "${host}" in
*-*-cygwin*)
ident_support=
;;
*-*-darwin*)
ident_support=
;;
*-*-machten*)
ident_support=
;;
esac
AC_SUBST(ident_support)
AC_MSG_RESULT($ident_support)
AC_CONFIG_SUBDIRS(vvp tgt-vvp tgt-fpga libveriuser)
AC_OUTPUT(Makefile vpi/Makefile ivlpp/Makefile driver/Makefile driver-vpi/Makefile tgt-null/Makefile tgt-stub/Makefile tgt-verilog/Makefile tgt-pal/Makefile)
+156 -61
View File
@@ -16,8 +16,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: cprop.cc,v 1.29 2001/07/25 03:10:48 steve Exp $"
#ifdef HAVE_CVS_IDENT
#ident "$Id: cprop.cc,v 1.39 2002/08/20 04:12:22 steve Exp $"
#endif
# include "config.h"
@@ -56,7 +56,7 @@ void cprop_functor::signal(Design*des, NetNet*obj)
void cprop_functor::lpm_add_sub(Design*des, NetAddSub*obj)
{
// For now, only additions are handled.
if (obj->attribute("LPM_Direction") != "ADD")
if (obj->attribute("LPM_Direction") != verinum("ADD"))
return;
// If the low bit on the A side is 0, then eliminate it from
@@ -64,8 +64,8 @@ void cprop_functor::lpm_add_sub(Design*des, NetAddSub*obj)
// result. Don't reduce the adder smaller then a 1-bit
// adder. These will be eliminated later.
while ((obj->width() > 1)
&& link_drivers_constant(obj->pin_DataA(0))
&& (driven_value(obj->pin_DataA(0)) == verinum::V0)) {
&& obj->pin_DataA(0).nexus()->drivers_constant()
&& (obj->pin_DataA(0).nexus()->driven_value() == verinum::V0)) {
NetAddSub*tmp = 0;
tmp = new NetAddSub(obj->scope(), obj->name(), obj->width()-1);
@@ -89,8 +89,8 @@ void cprop_functor::lpm_add_sub(Design*des, NetAddSub*obj)
// Now do the same thing on the B side.
while ((obj->width() > 1)
&& link_drivers_constant(obj->pin_DataB(0))
&& (driven_value(obj->pin_DataB(0)) == verinum::V0)) {
&& obj->pin_DataB(0).nexus()->drivers_constant()
&& (obj->pin_DataB(0).nexus()->driven_value() == verinum::V0)) {
NetAddSub*tmp = 0;
tmp = new NetAddSub(obj->scope(), obj->name(), obj->width()-1);
@@ -153,21 +153,22 @@ void cprop_functor::lpm_compare(Design*des, NetCompare*obj)
void cprop_functor::lpm_compare_eq_(Design*des, NetCompare*obj)
{
NetScope*scope = obj->scope();
/* First, look for the case where constant bits on matching A
and B inputs are different. This this is so, the device can
be completely eliminated and replaced with a constant 0. */
for (unsigned idx = 0 ; idx < obj->width() ; idx += 1) {
if (! link_drivers_constant(obj->pin_DataA(idx)))
if (! obj->pin_DataA(idx).nexus()->drivers_constant())
continue;
if (! link_drivers_constant(obj->pin_DataB(idx)))
if (! obj->pin_DataB(idx).nexus()->drivers_constant())
continue;
if (driven_value(obj->pin_DataA(idx)) ==
driven_value(obj->pin_DataB(idx)))
if (obj->pin_DataA(idx).nexus()->driven_value() ==
obj->pin_DataB(idx).nexus()->driven_value())
continue;
NetConst*zero = new NetConst(obj->name(), verinum::V0);
NetConst*zero = new NetConst(scope, obj->name(), verinum::V0);
connect(zero->pin(0), obj->pin_AEB());
delete obj;
des->add_node(zero);
@@ -180,11 +181,11 @@ void cprop_functor::lpm_compare_eq_(Design*des, NetCompare*obj)
unsigned top = obj->width();
for (unsigned idx = 0 ; idx < top ; ) {
if (! link_drivers_constant(obj->pin_DataA(idx))) {
if (! obj->pin_DataA(idx).nexus()->drivers_constant()) {
idx += 1;
continue;
}
if (! link_drivers_constant(obj->pin_DataB(idx))) {
if (! obj->pin_DataB(idx).nexus()->drivers_constant()) {
idx += 1;
continue;
}
@@ -204,7 +205,7 @@ void cprop_functor::lpm_compare_eq_(Design*des, NetCompare*obj)
/* If we wound up disconnecting all the inputs, then remove
the device and replace it with a constant. */
if (top == 0) {
NetConst*one = new NetConst(obj->name(), verinum::V1);
NetConst*one = new NetConst(scope, obj->name(), verinum::V1);
connect(one->pin(0), obj->pin_AEB());
delete obj;
des->add_node(one);
@@ -215,8 +216,8 @@ void cprop_functor::lpm_compare_eq_(Design*des, NetCompare*obj)
/* If there is only one bit left, then replace the comparator
with a simple XOR gate. */
if (top == 1) {
NetLogic*tmp = new NetLogic(obj->scope(), obj->name(), 3,
NetLogic::XOR);
NetLogic*tmp = new NetLogic(scope, obj->name(), 3,
NetLogic::XNOR);
connect(tmp->pin(0), obj->pin_AEB());
connect(tmp->pin(1), obj->pin_DataA(0));
connect(tmp->pin(2), obj->pin_DataB(0));
@@ -230,7 +231,7 @@ void cprop_functor::lpm_compare_eq_(Design*des, NetCompare*obj)
if (top == obj->width())
return;
NetCompare*tmp = new NetCompare(obj->scope(), obj->name(), top);
NetCompare*tmp = new NetCompare(scope, obj->name(), top);
connect(tmp->pin_AEB(), obj->pin_AEB());
for (unsigned idx = 0 ; idx < top ; idx += 1) {
connect(tmp->pin_DataA(idx), obj->pin_DataA(idx));
@@ -295,6 +296,8 @@ void cprop_functor::lpm_ff(Design*des, NetFF*obj)
void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
{
NetScope*scope = obj->scope();
switch (obj->type()) {
case NetLogic::NAND:
@@ -307,12 +310,12 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
on the output of an AND gate. */
while (idx < top) {
if (! link_drivers_constant(obj->pin(idx))) {
if (! obj->pin(idx).nexus()->drivers_constant()) {
idx += 1;
continue;
}
if (driven_value(obj->pin(idx)) == verinum::V1) {
if (obj->pin(idx).nexus()->driven_value()==verinum::V1) {
obj->pin(idx).unlink();
top -= 1;
if (idx < top) {
@@ -323,7 +326,7 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
continue;
}
if (driven_value(obj->pin(idx)) != verinum::V0) {
if (obj->pin(idx).nexus()->driven_value() != verinum::V0) {
idx += 1;
xs += 1;
continue;
@@ -336,15 +339,19 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
NetConst*tmp;
switch (obj->type()) {
case NetLogic::AND:
tmp = new NetConst(obj->name(), verinum::V0);
tmp = new NetConst(scope, obj->name(), verinum::V0);
break;
case NetLogic::NAND:
tmp = new NetConst(obj->name(), verinum::V1);
tmp = new NetConst(scope, obj->name(), verinum::V1);
break;
default:
assert(0);
}
tmp->rise_time(obj->rise_time());
tmp->fall_time(obj->fall_time());
tmp->decay_time(obj->decay_time());
des->add_node(tmp);
tmp->pin(0).drive0(obj->pin(0).drive0());
tmp->pin(0).drive1(obj->pin(0).drive1());
@@ -361,15 +368,19 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
NetConst*tmp;
switch (obj->type()) {
case NetLogic::AND:
tmp = new NetConst(obj->name(), verinum::V1);
tmp = new NetConst(scope, obj->name(), verinum::V1);
break;
case NetLogic::NAND:
tmp = new NetConst(obj->name(), verinum::V0);
tmp = new NetConst(scope, obj->name(), verinum::V0);
break;
default:
assert(0);
}
tmp->rise_time(obj->rise_time());
tmp->fall_time(obj->fall_time());
tmp->decay_time(obj->decay_time());
des->add_node(tmp);
tmp->pin(0).drive0(obj->pin(0).drive0());
tmp->pin(0).drive1(obj->pin(0).drive1());
@@ -384,7 +395,7 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
gate with a Vx. */
if (xs == (top-1)) {
NetConst*tmp;
tmp = new NetConst(obj->name(), verinum::Vx);
tmp = new NetConst(scope, obj->name(), verinum::Vx);
des->add_node(tmp);
tmp->pin(0).drive0(obj->pin(0).drive0());
tmp->pin(0).drive1(obj->pin(0).drive1());
@@ -401,18 +412,23 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
NetLogic*tmp;
switch (obj->type()) {
case NetLogic::AND:
tmp = new NetLogic(obj->scope(),
tmp = new NetLogic(scope,
obj->name(), 2,
NetLogic::BUF);
break;
case NetLogic::NAND:
tmp = new NetLogic(obj->scope(),
tmp = new NetLogic(scope,
obj->name(), 2,
NetLogic::NOT);
break;
default:
assert(0);
}
tmp->rise_time(obj->rise_time());
tmp->fall_time(obj->fall_time());
tmp->decay_time(obj->decay_time());
des->add_node(tmp);
tmp->pin(0).drive0(obj->pin(0).drive0());
tmp->pin(0).drive1(obj->pin(0).drive1());
@@ -424,12 +440,16 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
}
/* Finally, this cleans up the gate by creating a
new [N]OR gate that has the right number of
new [N]AND gate that has the right number of
inputs, connected in the right place. */
if (top < obj->pin_count()) {
NetLogic*tmp = new NetLogic(obj->scope(),
NetLogic*tmp = new NetLogic(scope,
obj->name(), top,
obj->type());
tmp->rise_time(obj->rise_time());
tmp->fall_time(obj->fall_time());
tmp->decay_time(obj->decay_time());
des->add_node(tmp);
tmp->pin(0).drive0(obj->pin(0).drive0());
tmp->pin(0).drive1(obj->pin(0).drive1());
@@ -454,12 +474,12 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
on the output of an OR gate. */
while (idx < top) {
if (! link_drivers_constant(obj->pin(idx))) {
if (! obj->pin(idx).nexus()->drivers_constant()) {
idx += 1;
continue;
}
if (driven_value(obj->pin(idx)) == verinum::V0) {
if (obj->pin(idx).nexus()->driven_value() == verinum::V0) {
obj->pin(idx).unlink();
top -= 1;
if (idx < top) {
@@ -470,7 +490,7 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
continue;
}
if (driven_value(obj->pin(idx)) != verinum::V1) {
if (obj->pin(idx).nexus()->driven_value() != verinum::V1) {
idx += 1;
continue;
}
@@ -482,15 +502,19 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
NetConst*tmp;
switch (obj->type()) {
case NetLogic::OR:
tmp = new NetConst(obj->name(), verinum::V1);
tmp = new NetConst(scope, obj->name(), verinum::V1);
break;
case NetLogic::NOR:
tmp = new NetConst(obj->name(), verinum::V0);
tmp = new NetConst(scope, obj->name(), verinum::V0);
break;
default:
assert(0);
}
tmp->rise_time(obj->rise_time());
tmp->fall_time(obj->fall_time());
tmp->decay_time(obj->decay_time());
des->add_node(tmp);
tmp->pin(0).drive0(obj->pin(0).drive0());
tmp->pin(0).drive1(obj->pin(0).drive1());
@@ -507,15 +531,19 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
NetConst*tmp;
switch (obj->type()) {
case NetLogic::OR:
tmp = new NetConst(obj->name(), verinum::V0);
tmp = new NetConst(scope, obj->name(), verinum::V0);
break;
case NetLogic::NOR:
tmp = new NetConst(obj->name(), verinum::V1);
tmp = new NetConst(scope, obj->name(), verinum::V1);
break;
default:
assert(0);
}
tmp->rise_time(obj->rise_time());
tmp->fall_time(obj->fall_time());
tmp->decay_time(obj->decay_time());
des->add_node(tmp);
tmp->pin(0).drive0(obj->pin(0).drive0());
tmp->pin(0).drive1(obj->pin(0).drive1());
@@ -532,18 +560,22 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
NetLogic*tmp;
switch (obj->type()) {
case NetLogic::OR:
tmp = new NetLogic(obj->scope(),
tmp = new NetLogic(scope,
obj->name(), 2,
NetLogic::BUF);
break;
case NetLogic::NOR:
tmp = new NetLogic(obj->scope(),
tmp = new NetLogic(scope,
obj->name(), 2,
NetLogic::NOT);
break;
default:
assert(0);
}
tmp->rise_time(obj->rise_time());
tmp->fall_time(obj->fall_time());
tmp->decay_time(obj->decay_time());
des->add_node(tmp);
tmp->pin(0).drive0(obj->pin(0).drive0());
tmp->pin(0).drive1(obj->pin(0).drive1());
@@ -558,9 +590,13 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
new [N]OR gate that has the right number of
inputs, connected in the right place. */
if (top < obj->pin_count()) {
NetLogic*tmp = new NetLogic(obj->scope(),
NetLogic*tmp = new NetLogic(scope,
obj->name(), top,
obj->type());
tmp->rise_time(obj->rise_time());
tmp->fall_time(obj->fall_time());
tmp->decay_time(obj->decay_time());
des->add_node(tmp);
tmp->pin(0).drive0(obj->pin(0).drive0());
tmp->pin(0).drive1(obj->pin(0).drive1());
@@ -580,14 +616,17 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
unsigned idx = 1;
/* Eliminate all the 0 inputs. They have no effect
on the output of an XOR gate. */
on the output of an XOR gate. The eliminate works
by unlinking the current input and relinking the
last input to this position. It's like bubbling
all the 0 inputs to the end. */
while (idx < top) {
if (! link_drivers_constant(obj->pin(idx))) {
if (! obj->pin(idx).nexus()->drivers_constant()) {
idx += 1;
continue;
}
if (driven_value(obj->pin(idx)) == verinum::V0) {
if (obj->pin(idx).nexus()->driven_value() == verinum::V0) {
obj->pin(idx).unlink();
top -= 1;
if (idx < top) {
@@ -612,12 +651,12 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
unsigned one = 0, ones = 0;
idx = 1;
while (idx < top) {
if (! link_drivers_constant(obj->pin(idx))) {
if (! obj->pin(idx).nexus()->drivers_constant()) {
idx += 1;
continue;
}
if (driven_value(obj->pin(idx)) == verinum::V1) {
if (obj->pin(idx).nexus()->driven_value() == verinum::V1) {
if (one == 0) {
one = idx;
ones += 1;
@@ -625,6 +664,8 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
continue;
}
/* Here we found two constant V1
inputs. Unlink both. */
obj->pin(idx).unlink();
top -= 1;
if (idx < top) {
@@ -639,8 +680,11 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
obj->pin(top).unlink();
}
/* Reset ones counter and one index,
start looking for the next pair. */
assert(ones == 1);
ones = 0;
one = 0;
continue;
}
@@ -648,12 +692,16 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
}
/* If all the inputs were eliminated, then replace
the gate with a constant 0 and I am done. */
the gate with a constant value and I am done. */
if (top == 1) {
verinum::V out = obj->type()==NetLogic::XNOR
? verinum::V1
: verinum::V0;
NetConst*tmp = new NetConst(obj->name(), out);
NetConst*tmp = new NetConst(scope, obj->name(), out);
tmp->rise_time(obj->rise_time());
tmp->fall_time(obj->fall_time());
tmp->decay_time(obj->decay_time());
des->add_node(tmp);
tmp->pin(0).drive0(obj->pin(0).drive0());
@@ -671,9 +719,9 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
if ((top == 3) && (ones == 1)) {
unsigned save;
if (! link_drivers_constant(obj->pin(1)))
if (! obj->pin(1).nexus()->drivers_constant())
save = 1;
else if (driven_value(obj->pin(1)) != verinum::V1)
else if (obj->pin(1).nexus()->driven_value() != verinum::V1)
save = 1;
else
save = 2;
@@ -681,14 +729,18 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
NetLogic*tmp;
if (obj->type() == NetLogic::XOR)
tmp = new NetLogic(obj->scope(),
tmp = new NetLogic(scope,
obj->name(), 2,
NetLogic::NOT);
else
tmp = new NetLogic(obj->scope(),
tmp = new NetLogic(scope,
obj->name(), 2,
NetLogic::BUF);
tmp->rise_time(obj->rise_time());
tmp->fall_time(obj->fall_time());
tmp->decay_time(obj->decay_time());
des->add_node(tmp);
tmp->pin(0).drive0(obj->pin(0).drive0());
tmp->pin(0).drive1(obj->pin(0).drive1());
@@ -706,14 +758,18 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
NetLogic*tmp;
if (obj->type() == NetLogic::XOR)
tmp = new NetLogic(obj->scope(),
tmp = new NetLogic(scope,
obj->name(), 2,
NetLogic::BUF);
else
tmp = new NetLogic(obj->scope(),
tmp = new NetLogic(scope,
obj->name(), 2,
NetLogic::NOT);
tmp->rise_time(obj->rise_time());
tmp->fall_time(obj->fall_time());
tmp->decay_time(obj->decay_time());
des->add_node(tmp);
tmp->pin(0).drive0(obj->pin(0).drive0());
tmp->pin(0).drive1(obj->pin(0).drive1());
@@ -728,7 +784,7 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
new XOR gate that has the right number of
inputs, connected in the right place. */
if (top < obj->pin_count()) {
NetLogic*tmp = new NetLogic(obj->scope(),
NetLogic*tmp = new NetLogic(scope,
obj->name(), top,
obj->type());
des->add_node(tmp);
@@ -766,12 +822,12 @@ void cprop_functor::lpm_mux(Design*des, NetMux*obj)
connected to the select input. */
bool flag = true;
for (unsigned idx = 0 ; idx < obj->width() ; idx += 1) {
if (! link_drivers_constant(obj->pin_Data(idx, 0))) {
if (! obj->pin_Data(idx, 0).nexus()->drivers_constant()) {
flag = false;
break;
}
if (driven_value(obj->pin_Data(idx, 0)) != verinum::Vz) {
if (obj->pin_Data(idx, 0).nexus()->driven_value() != verinum::Vz) {
flag = false;
break;
}
@@ -798,12 +854,12 @@ void cprop_functor::lpm_mux(Design*des, NetMux*obj)
NetMux with an array of BUFIF0 devices. */
flag = true;
for (unsigned idx = 0 ; idx < obj->width() ; idx += 1) {
if (! link_drivers_constant(obj->pin_Data(idx, 1))) {
if (! obj->pin_Data(idx, 1).nexus()->drivers_constant()) {
flag = false;
break;
}
if (driven_value(obj->pin_Data(idx, 1)) != verinum::Vz) {
if (obj->pin_Data(idx, 1).nexus()->driven_value() != verinum::Vz) {
flag = false;
break;
}
@@ -884,7 +940,7 @@ void cprop_dc_functor::lpm_const(Design*des, NetConst*obj)
return;
// Look for signals that have NetESignal nodes attached to
// them. If I find any, this this constant is used by a
// them. If I find any, then this constant is used by a
// behavioral expression somewhere.
for (unsigned idx = 0 ; idx < obj->pin_count() ; idx += 1) {
Nexus*nex = obj->pin(idx).nexus();
@@ -904,7 +960,7 @@ void cprop_dc_functor::lpm_const(Design*des, NetConst*obj)
// If the net has an eref, then there is an
// expression somewhere that reads this signal. So
// the constant does get read.
if (tmp->get_eref() > 0)
if (tmp->peek_eref() > 0)
return;
// If the net is a port of the root module, then
@@ -917,7 +973,6 @@ void cprop_dc_functor::lpm_const(Design*des, NetConst*obj)
}
}
// Done. Delete me.
delete obj;
}
@@ -939,6 +994,46 @@ void cprop(Design*des)
/*
* $Log: cprop.cc,v $
* Revision 1.39 2002/08/20 04:12:22 steve
* Copy gate delays when doing gate delay substitutions.
*
* Revision 1.38 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.37 2002/06/25 01:33:22 steve
* Cache calculated driven value.
*
* Revision 1.36 2002/06/24 01:49:38 steve
* Make link_drive_constant cache its results in
* the Nexus, to improve cprop performance.
*
* Revision 1.35 2002/05/26 01:39:02 steve
* Carry Verilog 2001 attributes with processes,
* all the way through to the ivl_target API.
*
* Divide signal reference counts between rval
* and lval references.
*
* Revision 1.34 2002/05/23 03:08:51 steve
* Add language support for Verilog-2001 attribute
* syntax. Hook this support into existing $attribute
* handling, and add number and void value types.
*
* Add to the ivl_target API new functions for access
* of complex attributes attached to gates.
*
* Revision 1.33 2002/04/14 02:51:37 steve
* Fix bug removing pairs of ones in XOR.
*
* Revision 1.32 2002/02/03 00:06:28 steve
* Comments about xor evaluation.
*
* Revision 1.31 2001/12/31 01:56:08 steve
* Get sense of 1-bit == operator right.
*
* Revision 1.30 2001/10/28 01:14:53 steve
* NetObj constructor finally requires a scope.
*
* Revision 1.29 2001/07/25 03:10:48 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
+2 -26
View File
@@ -6,41 +6,17 @@ To build using cygwin:
Prerequisites:
o Latest net release (1.1.4) of cygwin (sources.redhat.com/cygwin)
o autoconf version 2.13 (or later) from cygutils (cygutils.netpedia.net)
o cvs (1.10.8 or later) also from cygutils
Procedure:
o Get the source code - see the main icarus verilog page for how to
do this
o cd to the verilog directory
o autoconf
o autoconf.sh
o ./configure
o make
o make install
That's all that's needed. But there're two common problems during
the make phase. All steps are in the verilog directory.
1.
If gcc dies saying virtual memory exhausted while compiling parse.c
then recompile with -O1 or without -O flag and do these steps to
continue
o make CXXFLAGS='' parse.o
o make
2.
If gcc dies in the vpi directory while compiling vpi_systask.c with the
error, conflicting types for `_cygwin_dll_entry', then fix the line in
/usr/include/cygwin/cygwin_dll.h. Change the line:
int WINAPI _cygwin_dll_entry (HANDLE h, DWORD reason, void *ptr); \
to
int WINAPI _cygwin_dll_entry (HINSTANCE h, DWORD reason, void *ptr); \
Note the change from HANDLE to HINSTANCE. Then do
o make
That's all that's needed.
To build your own extensions - just include vpi_user.h and link with
a command like this:
+148 -40
View File
@@ -16,8 +16,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: design_dump.cc,v 1.117 2001/08/25 23:50:02 steve Exp $"
#ifdef HAVE_CVS_IDENT
#ident "$Id: design_dump.cc,v 1.135 2002/10/23 01:47:17 steve Exp $"
#endif
# include "config.h"
@@ -93,7 +93,7 @@ void NetNet::dump_net(ostream&o, unsigned ind) const
o << " inout";
break;
}
o << " (eref=" << get_eref() << ")";
o << " (eref=" << peek_eref() << ", lref=" << peek_lref() << ")";
if (scope())
o << " scope=" << scope()->name();
o << " #(" << rise_time() << "," << fall_time() << "," <<
@@ -117,6 +117,13 @@ void NetNet::dump_net(ostream&o, unsigned ind) const
dump_obj_attr(o, ind+4);
}
void NetSubnet::dump_net(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "** " << name() << " is a NetSubnet **"
<< endl;
NetNet::dump_net(o, ind);
}
void NetMemory::dump(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << name_ << "[" << width_ << "] " <<
@@ -174,9 +181,9 @@ void NetObj::dump_node_pins(ostream&o, unsigned ind) const
void NetObj::dump_obj_attr(ostream&o, unsigned ind) const
{
unsigned idx;
for (idx = 0 ; idx < attributes_.size() ; idx += 1) {
o << setw(ind) << "" << attributes_.key(idx) << " = \"" <<
attributes_.value(idx) << "\"" << endl;
for (idx = 0 ; idx < attr_cnt() ; idx += 1) {
o << setw(ind) << "" << attr_key(idx) << " = \"" <<
attr_value(idx) << "\"" << endl;
}
}
@@ -264,7 +271,8 @@ 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()? scope()->name() : "") << endl;
<< " scope=" << (scope()? scope()->name() : "")
<< " aset_value=" << aset_value_ << endl;
dump_node_pins(o, ind+4);
dump_obj_attr(o, ind+4);
@@ -353,6 +361,14 @@ void NetRamDq::dump_node(ostream&o, unsigned ind) const
dump_obj_attr(o, ind+4);
}
void NetUserFunc::dump_node(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << def_->name() << "(";
o << ")" << endl;
dump_node_pins(o, ind+4);
dump_obj_attr(o, ind+4);
}
void NetTaskDef::dump(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "task " << name_ << ";" << endl;
@@ -405,6 +421,11 @@ void NetProcTop::dump(ostream&o, unsigned ind) const
break;
}
for (unsigned idx = 0 ; idx < attr_cnt() ; idx += 1) {
o << setw(ind+2) << "" << "(* " << attr_key(idx) << " = "
<< attr_value(idx) << " *)" << endl;
}
statement_->dump(o, ind+2);
}
@@ -418,6 +439,14 @@ void NetAssign_::dump_lval(ostream&o) const
} else {
o << "[" << (loff_+lwid_-1) << ":" << loff_ << "]";
}
} else if (mem_) {
// Is there an obvious way to flag memories in the dump
// as different from the _real_ bit mux case?
// o << "**memory**";
o << mem_->name() << "[";
if (bmux_) o << *bmux_;
else o << "**oops**";
o << "]";
} else {
o << "";
}
@@ -464,30 +493,13 @@ void NetAssignNB::dump(ostream&o, unsigned ind) const
}
void NetAssignMem::dump(ostream&o, unsigned ind) const
{
o << setw(ind) << "";
o << "/* " << get_line() << " */" << endl;
o << setw(ind) << "";
o << memory()->name() << "[" << *index() << "] = ";
rval()->dump(o);
o << ";" << endl;
}
void NetAssignMemNB::dump(ostream&o, unsigned ind) const
{
o << setw(ind) << "";
o << "/* " << get_line() << " */" << endl;
o << setw(ind) << "";
o << memory()->name() << "[" << *index() << "] <= ";
rval()->dump(o);
o << ";" << endl;
}
/* Dump a block statement */
void NetBlock::dump(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << type_ << endl;
o << setw(ind) << "" << type_;
if (subscope_)
o << " : " << subscope_->name();
o << endl;
if (last_) {
const NetProc*cur = last_;
@@ -647,8 +659,12 @@ void NetPDelay::dump(ostream&o, unsigned ind) const
void NetRelease::dump(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "release " << lval_->name() << "; "
<< "/* " << get_line() << " */" << endl;
if (lval_)
o << setw(ind) << "" << "release " << lval_->name() << "; "
<< "/* " << get_line() << " */" << endl;
else
o << setw(ind) << "" << "release (null); "
<< "/* " << get_line() << " */" << endl;
}
void NetRepeat::dump(ostream&o, unsigned ind) const
@@ -684,23 +700,32 @@ void NetScope::dump(ostream&o) const
/* Dump the parameters for this scope. */
{
map<string,NetExpr*>::const_iterator pp;
map<string,param_expr_t>::const_iterator pp;
for (pp = parameters_.begin()
; pp != parameters_.end() ; pp ++) {
o << " parameter " << (*pp).first << " = " <<
*(*pp).second << ";" << endl;
o << " parameter ";
if ((*pp).second.signed_flag)
o << "signed ";
if ((*pp).second.msb)
o << "[" << *(*pp).second.msb
<< ":" << *(*pp).second.lsb << "] ";
o << (*pp).first << " = " <<
*(*pp).second.expr << ";" << endl;
}
for (pp = localparams_.begin()
; pp != localparams_.end() ; pp ++) {
o << " localparam " << (*pp).first << " = " <<
*(*pp).second << ";" << endl;
*(*pp).second.expr << ";" << endl;
}
}
/* Dump the saved defparam assignments here. */
{
map<string,NetExpr*>::const_iterator pp;
map<hname_t,NetExpr*>::const_iterator pp;
for (pp = defparams.begin()
; pp != defparams.end() ; pp ++ ) {
o << " defparam " << (*pp).first << " = " <<
@@ -786,7 +811,7 @@ void NetProc::dump(ostream&o, unsigned ind) const
/* Dump an expression that noone wrote a dump method for. */
void NetExpr::dump(ostream&o) const
{
o << "(?)";
o << "(?" << typeid(*this).name() << "?)";
}
void NetEBinary::dump(ostream&o) const
@@ -842,8 +867,12 @@ void NetEBinary::dump(ostream&o) const
void NetEConcat::dump(ostream&o) const
{
if (repeat_ != 1)
o << repeat_;
if (repeat_calculated_) {
if (repeat_value_ != 1)
o << repeat_value_;
} else if (repeat_) {
o << "<" << *repeat_ << ">";
}
if (parms_[0])
o << "{" << *parms_[0];
@@ -884,6 +913,8 @@ void NetESFunc::dump(ostream&o) const
void NetESignal::dump(ostream&o) const
{
if (has_sign())
o << "+";
o << name() << "[" << msi_<<":"<<lsi_ << "]";
}
@@ -904,7 +935,10 @@ void NetEMemory::dump(ostream&o) const
void NetEParam::dump(ostream&o) const
{
o << "<" << scope_->name() << "." << name_ << ">";
if (scope_ != 0)
o << "<" << scope_->name() << "." << name_ << ">";
else
o << "<" << name_ << ">";
}
void NetETernary::dump(ostream&o) const
@@ -945,7 +979,9 @@ void Design::dump(ostream&o) const
{
o << "DESIGN TIME PRECISION: 10e" << get_precision() << endl;
o << "SCOPES:" << endl;
root_scope_->dump(o);
for (list<NetScope*>::const_iterator scope = root_scopes_.begin();
scope != root_scopes_.end(); scope++)
(*scope)->dump(o);
o << "ELABORATED NODES:" << endl;
@@ -968,6 +1004,78 @@ void Design::dump(ostream&o) const
/*
* $Log: design_dump.cc,v $
* Revision 1.135 2002/10/23 01:47:17 steve
* Fix synth2 handling of aset/aclr signals where
* flip-flops are split by begin-end blocks.
*
* Revision 1.134 2002/10/19 22:59:49 steve
* Redo the parameter vector support to allow
* parameter names in range expressions.
*
* Revision 1.133 2002/08/19 00:06:11 steve
* Allow release to handle removal of target net.
*
* Revision 1.132 2002/08/13 05:35:00 steve
* Do not elide named blocks.
*
* Revision 1.131 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.130 2002/08/04 18:28:14 steve
* Do not use hierarchical names of memories to
* generate vvp labels. -tdll target does not
* used hierarchical name string to look up the
* memory objects in the design.
*
* Revision 1.129 2002/06/19 04:20:03 steve
* Remove NetTmp and add NetSubnet class.
*
* Revision 1.128 2002/06/14 21:38:41 steve
* Fix expression width for repeat concatenations.
*
* Revision 1.127 2002/06/08 23:42:46 steve
* Add NetRamDq synthsesis from memory l-values.
*
* Revision 1.126 2002/06/05 03:44:25 steve
* Add support for memory words in l-value of
* non-blocking assignments, and remove the special
* NetAssignMem_ and NetAssignMemNB classes.
*
* Revision 1.125 2002/06/04 05:38:44 steve
* Add support for memory words in l-value of
* blocking assignments, and remove the special
* NetAssignMem class.
*
* Revision 1.124 2002/05/26 01:39:02 steve
* Carry Verilog 2001 attributes with processes,
* all the way through to the ivl_target API.
*
* Divide signal reference counts between rval
* and lval references.
*
* Revision 1.123 2002/05/05 21:11:49 steve
* Put off evaluation of concatenation repeat expresions
* until after parameters are defined. This allows parms
* to be used in repeat expresions.
*
* Add the builtin $signed system function.
*
* Revision 1.122 2002/03/09 02:10:22 steve
* Add the NetUserFunc netlist node.
*
* Revision 1.121 2001/12/31 00:03:05 steve
* Include s indicator in dump of signed numbers.
*
* Revision 1.120 2001/12/03 04:47:14 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
*
* Revision 1.119 2001/11/19 01:46:38 steve
* Print typename is fallback expression node dump.
*
* Revision 1.118 2001/10/19 21:53:24 steve
* Support multiple root modules (Philip Blundell)
*
* Revision 1.117 2001/08/25 23:50:02 steve
* Change the NetAssign_ class to refer to the signal
* instead of link into the netlist. This is faster
+9 -2
View File
@@ -15,9 +15,10 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
* $Id: dosify.c,v 1.1 2001/08/03 17:06:47 steve Exp $
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: dosify.c,v 1.3 2002/08/12 01:34:58 steve Exp $"
#endif
/*
* This is a simple program to make a dosified copy of the
@@ -68,6 +69,12 @@ int main(int argc, char*argv[])
/*
* $Log: dosify.c,v $
* Revision 1.3 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.2 2002/08/11 23:47:04 steve
* Add missing Log and Ident strings.
*
* Revision 1.1 2001/08/03 17:06:47 steve
* Add install of examples for Windows.
*
+2
View File
@@ -0,0 +1,2 @@
Makefile
iverilog-vpi.exe
+82
View File
@@ -0,0 +1,82 @@
#
# This source code is free software; you can redistribute it
# and/or modify it in source code form under the terms of the GNU
# Library General Public License as published by the Free Software
# Foundation; either version 2 of the License, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Library General Public License for more details.
#
# You should have received a copy of the GNU Library General Public
# License along with this program; if not, write to the Free
# Software Foundation, Inc.,
# 59 Temple Place - Suite 330
# Boston, MA 02111-1307, USA
#
#ident "$Id: Makefile.in,v 1.5 2002/12/08 03:06:30 steve Exp $"
#
#
SHELL = /bin/sh
VERSION = 0.7
prefix = @prefix@
exec_prefix = @exec_prefix@
srcdir = @srcdir@
VPATH = $(srcdir)
bindir = $(exec_prefix)/bin
libdir = $(exec_prefix)/lib
includedir = $(prefix)/include
mandir = @mandir@
dllib=@DLLIB@
CC = @CC@
CXX = @CXX@
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
CPPFLAGS = @CPPFLAGS@ @DEFS@
CFLAGS = @CFLAGS@ -I. -I$(srcdir)/.. -DVERSION='"$(VERSION)"'
CXXFLAGS = @CXXFLAGS@ -I. -I$(srcdir)/..
LDFLAGS = @LDFLAGS@
all: iverilog-vpi@EXEEXT@
clean:
rm -f *.o
rm -f iverilog-vpi@EXEEXT@
distclean: clean
rm -f Makefile
O = main.o res.o
iverilog-vpi@EXEEXT@: $O
$(CC) $(LDFLAGS) $O -o iverilog-vpi@EXEEXT@ @EXTRALIBS@
main.o: main.c
$(CC) $(CFLAGS) -c $(srcdir)/main.c
# Windows specific...
res.o: res.rc
windres -i res.rc -o res.o
#
install: all installdirs $(bindir)/iverilog-vpi@EXEEXT@
$(bindir)/iverilog-vpi@EXEEXT@: ./iverilog-vpi@EXEEXT@
$(INSTALL_PROGRAM) ./iverilog-vpi@EXEEXT@ $(bindir)/iverilog-vpi@EXEEXT@
installdirs: ../mkinstalldirs
$(srcdir)/../mkinstalldirs $(bindir)
uninstall:
rm -f $(bindir)/iverilog-vpi@EXEEXT@
+565
View File
@@ -0,0 +1,565 @@
/*
* Copyright (c) 2002 Gus Baldauf (gus@picturel.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
/*
* iverilog-vpi.c
*
* this program provides the functionality of iverilog-vpi.sh under Win32
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <windows.h>
/* Macros used for compiling and linking */
#define IVERILOG_VPI_CC "gcc" /* no .exe extension */
#define IVERILOG_VPI_CXX "gcc" /* no .exe extension */
#define IVERILOG_VPI_CFLAGS "-O" /* -I appended later */
#define IVERILOG_VPI_LD "gcc" /* no .exe extension */
#define IVERILOG_VPI_LDFLAGS "-shared -Wl,--enable-auto-image-base"
#define IVERILOG_VPI_LDLIBS "-lveriuser -lvpi" /* -L prepended later */
/* pointers to global strings */
static struct global_strings {
char *pCCSRC; /* list of C source files */
char *pCXSRC; /* list of C++ source files */
char *pOBJ; /* list of object files */
char *pLIB; /* list of library files */
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 */
} gstr;
static void deInitDynString(char *str)
{
free(str);
}
/* when finished, free allocated memory and return error code */
static void myExit(int exitVal)
{
deInitDynString(gstr.pCCSRC);
deInitDynString(gstr.pCXSRC);
deInitDynString(gstr.pOBJ);
deInitDynString(gstr.pLIB);
deInitDynString(gstr.pOUT);
deInitDynString(gstr.pMINGW);
deInitDynString(gstr.pIVL);
deInitDynString(gstr.pCFLAGS);
deInitDynString(gstr.pLDLIBS);
deInitDynString(gstr.pNewPath);
exit(exitVal);
}
/* display usage summary and exit */
static void usage()
{
fprintf(stderr,"usage: iverilog-vpi [--name=name] [-llibrary] [-mingw=dir] [-ivl=dir] sourcefile...\n");
fprintf(stderr," or iverilog-vpi -mingw=dir\n");
fprintf(stderr," or iverilog-vpi -ivl=dir\n");
myExit(1);
}
static void initDynString(char **str)
{
*str = (char *) malloc(1);
if (!*str) {
fprintf(stderr,"error: out of memory\n");
myExit(4);
}
*str[0] = 0;
}
/* initialize dynamic memory buffers */
static void init()
{
initDynString(&gstr.pCCSRC);
initDynString(&gstr.pCXSRC);
initDynString(&gstr.pOBJ);
initDynString(&gstr.pLIB);
initDynString(&gstr.pOUT);
initDynString(&gstr.pMINGW);
initDynString(&gstr.pIVL);
initDynString(&gstr.pCFLAGS);
initDynString(&gstr.pLDLIBS);
initDynString(&gstr.pNewPath);
}
/* return true if "str" is terminated with with "end", case insensitive */
static int endsIn (char *end, char *str)
{
char *ext;
if (strlen(end) >= strlen(str))
return 0;
ext = str + (strlen(str) - strlen(end));
return stricmp(end,ext) ? 0 : 1;
}
/* return true if "str" begins with "prefix", case insensitive */
static int startsWith (char *prefix, char *str)
{
if (strlen(prefix) >= strlen(str))
return 0;
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)
{
*ptr = (char *) realloc(*ptr,strlen(*ptr)+(count?count:strlen(app))+1);
if (*ptr == NULL) {
fprintf(stderr,"error: out of memory\n");
myExit(4);
}
if (count)
strncat(*ptr,app,count);
else
strcat(*ptr,app);
}
/* append "app" to "ptr", allocating memory as needed */
static void append (char **ptr, char *app)
{
appendn(ptr,app,0);
}
/* if the string does not end with a backslash, add one */
static void appendBackSlash(char **str)
{
if ((*str)[strlen(*str)-1] != '\\')
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)
{
*ptr = (char *) realloc(*ptr,(count?count:strlen(str))+1);
if (*ptr == NULL) {
fprintf(stderr,"error: out of memory\n");
myExit(4);
}
if (count) {
strncpy(*ptr,str,count);
(*ptr)[count] = 0;
}
else
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);
}
/* get a copy of a Icarus Verilog registry string key */
static int GetRegistryKey(char *key, char **value)
{
long lrv;
HKEY hkKey;
char *regKeyBuffer;
DWORD regKeyType, regKeySize;
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);
if ((lrv != ERROR_SUCCESS) || (regKeyType != REG_SZ) || (!regKeySize)) {
lrv = RegCloseKey(hkKey);
return 0;
}
regKeyBuffer = (char *) malloc(regKeySize+1);
if (!regKeyBuffer) {
lrv = RegCloseKey(hkKey);
fprintf(stderr,"error: out of memory\n");
myExit(4);
}
regKeyBuffer[regKeySize] = 0; /* makes sure there is a trailing NULL */
lrv = RegQueryValueEx(hkKey,key,NULL,&regKeyType,regKeyBuffer,&regKeySize);
if ((lrv != ERROR_SUCCESS) || (regKeyType != REG_SZ) || (!regKeySize)) {
lrv = RegCloseKey(hkKey);
free(regKeyBuffer);
return 0;
}
RegCloseKey(hkKey);
assign(value,regKeyBuffer);
free(regKeyBuffer);
return 1;
}
/* store a copy of a Icarus Verilog registry string key */
static void SetRegistryKey(char *key, char *value)
{
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;
RegSetValueEx(hkKey,key,0,REG_SZ,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);
}
/* parse the command line, assign results to global variable strings */
static int parse(int argc, char *argv[])
{
int idx, srcFileCnt=0;
char dot_c_ext[] = ".c";
char dot_cc_ext[] = ".cc";
char dot_o_ext[] = ".o";
char name_option[] = "--name=";
char lib_option[] = "-l";
char mingw_option[] = "-mingw=";
char ivl_option[] = "-ivl=";
if (argc == 1)
return 0;
for (idx=1; idx<argc; ++idx) {
if (endsIn(dot_c_ext,argv[idx])) { /* check for C source files */
++srcFileCnt;
append(&gstr.pCCSRC,argv[idx]);
append(&gstr.pCCSRC," ");
if (!*gstr.pOUT)
assignn(&gstr.pOUT,argv[idx],strlen(argv[idx])-strlen(dot_c_ext));
}
else if (endsIn(dot_cc_ext,argv[idx])) { /* check for C++ source files */
++srcFileCnt;
append(&gstr.pCXSRC,argv[idx]);
append(&gstr.pCXSRC," ");
if (!*gstr.pOUT)
assignn(&gstr.pOUT,argv[idx],strlen(argv[idx])-strlen(dot_cc_ext));
}
else if (endsIn(dot_o_ext,argv[idx])) { /* check for compiled object files */
++srcFileCnt;
append(&gstr.pOBJ,argv[idx]);
append(&gstr.pOBJ," ");
if (!*gstr.pOUT)
assignn(&gstr.pOUT,argv[idx],strlen(argv[idx])-strlen(dot_o_ext));
}
else if (startsWith(name_option,argv[idx])) { /* check for --name option */
assignn(&gstr.pOUT,argv[idx]+sizeof(name_option)-1,strlen(argv[idx])-(sizeof(name_option)-1));
}
else if (startsWith(lib_option,argv[idx])) { /* check for -l option */
append(&gstr.pLIB,argv[idx]);
append(&gstr.pLIB," ");
}
else if (startsWith(mingw_option,argv[idx])) /* check for -mingw option */
assignn(&gstr.pMINGW,argv[idx]+sizeof(mingw_option)-1,strlen(argv[idx])-(sizeof(mingw_option)-1));
else if (startsWith(ivl_option,argv[idx])) /* check for -ivl option */
assignn(&gstr.pIVL,argv[idx]+sizeof(ivl_option)-1,strlen(argv[idx])-(sizeof(ivl_option)-1));
else
return 0; /* different from iverilog-vpi.sh, we don't ignore accept arguments */
}
if (0 == srcFileCnt)
assign(&gstr.pOUT,""); /* in case they used --name with no source files */
if (!*gstr.pOUT) { /* normally it's an error if there are no *.c,*.cc,*.o files */
if (!*gstr.pMINGW && !*gstr.pIVL) /* unless they are just setting the IVL or MinGW registry entries */
usage();
}
else {
append(&gstr.pOUT,".vpi"); /* the result file should have a .vpi extension */
append(&gstr.pOUT," ");
}
return 1;
}
/* do minimal check that the MinGW root directory looks valid */
static void checkMingwDir(char *root)
{
int irv;
struct _stat stat_buf;
char *path;
initDynString(&path);
assign(&path,gstr.pMINGW);
appendBackSlash(&path);
append(&path,"bin\\" IVERILOG_VPI_CC ".exe");
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);
appendBackSlash(&path);
append(&path,"bin\\vvp.exe");
irv = _stat(path,&stat_buf);
deInitDynString(path);
if (irv) {
fprintf(stderr,"error: %s does not appear to be the valid root directory of\n",root);
fprintf(stderr," Icarus Verilog. Use the -ivl option of iverilog-vpi.exe to\n");
fprintf(stderr," 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);
}
}
/* see if we can find mingw root */
#define IVL_REGKEY_MINGW "MingwDir"
static void setup_mingw_environment()
{
char *pOldPATH = getenv("PATH"); /* get current 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);
}
assign(&gstr.pNewPath,"PATH="); /* create new path */
append(&gstr.pNewPath,gstr.pMINGW);
appendBackSlash(&gstr.pNewPath);
append(&gstr.pNewPath,"bin;");
append(&gstr.pNewPath,pOldPATH);
_putenv(gstr.pNewPath); /* place new path in environment variable */
}
/* see if we can find iverilog root */
#define IVL_REGKEY_IVL "InstallDir"
static void setup_ivl_environment()
{
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.exe 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);
}
/* build up the CFLAGS option string */
assign(&gstr.pCFLAGS,IVERILOG_VPI_CFLAGS);
append(&gstr.pCFLAGS," -I");
append(&gstr.pCFLAGS,gstr.pIVL);
appendBackSlash(&gstr.pCFLAGS);
append(&gstr.pCFLAGS,"include");
/* build up the LDFLAGS option string */
assign(&gstr.pLDLIBS,"-L");
append(&gstr.pLDLIBS,gstr.pIVL);
appendBackSlash(&gstr.pLDLIBS);
append(&gstr.pLDLIBS,"lib ");
append(&gstr.pLDLIBS,IVERILOG_VPI_LDLIBS);
}
/* compile source modules */
static void compile(char *pSource, char **pObject, char *ext, int *compile_errors, char *compiler)
{
char *ptr1 = pSource;
char *ptr2 = strchr(pSource,' ');
char *buf=0,*src=0,*obj=0;
while (ptr2) {
int len = ptr2 - ptr1;
assignn(&src,ptr1,len);
assignn(&obj,ptr1,len-strlen(ext)); /* strip off the extension */
append (&obj,".o");
assign (&buf,compiler);
append (&buf," -c -o ");
append (&buf,obj);
append (&buf," ");
append (&buf,gstr.pCFLAGS);
append (&buf," ");
append (&buf,src);
append (pObject,obj);
append (pObject," ");
printf("%s\n",buf);
if (system(buf))
++*compile_errors;
ptr1 = ptr2 + 1; /* advance to next token */
ptr2 = strchr(ptr1,' ');
}
free(buf);
free(src);
free(obj);
}
/* using the global strings, compile and link */
static void compile_and_link()
{
char *buf=0;
int iRet, compile_errors = 0;
/* print out the mingw and ivl directories to help the user debug problems */
printf("info: %s will be used as the MinGW root directory.\n",gstr.pMINGW);
checkMingwDir(gstr.pMINGW);
printf("info: %s will be used as the Icarus Verilog root directory.\n",gstr.pIVL);
checkIvlDir(gstr.pIVL);
/* compile */
compile(gstr.pCCSRC,&gstr.pOBJ,".c" ,&compile_errors,IVERILOG_VPI_CC ); /* compile the C source files */
compile(gstr.pCXSRC,&gstr.pOBJ,".cc",&compile_errors,IVERILOG_VPI_CXX); /* compile the C++ source files */
if (compile_errors) {
fprintf(stderr,"iverilog-vpi: Some %d files failed to compile.\n",compile_errors);
myExit(2);
}
/* link */
assign(&buf,IVERILOG_VPI_LD);
append(&buf," -o ");
append(&buf,gstr.pOUT); /* has a trailing space */
append(&buf,IVERILOG_VPI_LDFLAGS);
append(&buf," ");
append(&buf,gstr.pOBJ) /* has a trailing space */;
append(&buf,gstr.pLIB); /* has a trailing space */
append(&buf,gstr.pLDLIBS);
printf("%s\n",buf);
iRet = system(buf);
free(buf);
if (iRet)
myExit(3);
}
/* program execution starts here */
int main(int argc, char *argv[])
{
init();
if (!parse(argc,argv))
usage();
setup_mingw_environment();
setup_ivl_environment();
if (*gstr.pOUT) /* are there any *.c,*.cc,*.o files specified */
compile_and_link();
myExit(0);
}
+38
View File
@@ -0,0 +1,38 @@
// LANGUAGE ENGLISH
LANGUAGE 9, 4
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
1 VERSIONINFO
FILEVERSION 2002,11,13,0
PRODUCTVERSION 0,7,0,0
FILEFLAGSMASK 0x3fL
FILEFLAGS 0x2L
FILEOS 0x40004L
FILETYPE 0x2L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "CompanyName", "Icarus Verilog\0"
VALUE "FileDescription", "Icarus Veriog VPI Tool\0"
VALUE "FileVersion", "2002, 11, 13, 0\0"
VALUE "InternalName", "iverilog-vpi\0"
VALUE "LegalCopyright", "Copyright 2002 Gus Baldauf\0"
VALUE "OriginalFilename", "iverilog-vpi.exe\0"
VALUE "ProductName", "Icarus Verilog\0"
VALUE "ProductVersion", "0, 7, 0, 0\0"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END
+9
View File
@@ -1,6 +1,15 @@
a.out
Makefile
parse.c
parse.h
parse.output
lexor.c
cfparse.c
cfparse.h
cfparse.output
cflexor.c
foo.*
iverilog
iverilog.ps
iverilog.pdf
tmp.pdf
+34 -11
View File
@@ -3,9 +3,7 @@
# and/or modify it in source code form under the terms of the GNU
# Library General Public License as published by the Free Software
# Foundation; either version 2 of the License, or (at your option)
# any later version. In order to redistribute the software in
# binary form, you will need a Picture Elements Binary Software
# License.
# 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
@@ -18,12 +16,12 @@
# 59 Temple Place - Suite 330
# Boston, MA 02111-1307, USA
#
#ident "$Id: Makefile.in,v 1.6 2001/08/10 00:39:42 steve Exp $"
#ident "$Id: Makefile.in,v 1.16 2002/12/08 03:06:30 steve Exp $"
#
#
SHELL = /bin/sh
VERSION = 0.0
VERSION = 0.7
prefix = @prefix@
exec_prefix = @exec_prefix@
@@ -37,7 +35,6 @@ includedir = $(prefix)/include
mandir = @mandir@
dllib=@DLLIB@
rdynamic=@rdynamic@
CC = @CC@
CXX = @CXX@
@@ -46,7 +43,7 @@ INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
CPPFLAGS = @CPPFLAGS@ @DEFS@
CFLAGS = @CFLAGS@ -I. -I$(srcdir)/..
CFLAGS = @CFLAGS@ -I. -I$(srcdir)/.. -DVERSION='"$(VERSION)"'
CXXFLAGS = @CXXFLAGS@ -I. -I$(srcdir)/..
LDFLAGS = @LDFLAGS@
@@ -54,8 +51,9 @@ all: iverilog@EXEEXT@
clean:
rm -f *.o lexor.c parse.c parse.h parse.output
rm -f cflexor.c cfparse.c cfparse.h cfparse.output
O = main.o build_string.o lexor.o parse.o
O = main.o build_string.o lexor.o parse.o substit.o cflexor.o cfparse.o
iverilog@EXEEXT@: $O
$(CC) $(LDFLAGS) $O -o iverilog@EXEEXT@ @EXTRALIBS@
@@ -66,16 +64,38 @@ lexor.c: lexor.lex
parse.h parse.c: parse.y
bison --verbose -t -d -o parse.c $(srcdir)/parse.y
cflexor.c: cflexor.lex
flex -s -Pcf -ocflexor.c $(srcdir)/cflexor.lex
cfparse.h cfparse.c: cfparse.y
bison --verbose -t -d -o cfparse.c --name-prefix=cf $(srcdir)/cfparse.y
main.o: main.c globals.h
$(CC) $(CFLAGS) -c -DCXX='"@CXX@"' -DIVL_ROOT='"@libdir@/ivl"' -DIVL_INC='"@includedir@"' -DIVL_LIB='"@libdir@"' -DRDYNAMIC=\"$(rdynamic)\" -DDLLIB='"@DLLIB@"' -DEXEEXT='"@EXEEXT@"' $(srcdir)/main.c
$(CC) $(CFLAGS) -c -DCXX='"@CXX@"' -DIVL_ROOT='"@libdir@/ivl"' -DIVL_INC='"@includedir@"' -DIVL_LIB='"@libdir@"' -DDLLIB='"@DLLIB@"' $(srcdir)/main.c
build_string.o: build_string.c globals.h
lexor.o: lexor.c parse.h globals.h
parse.o: parse.c globals.h
cflexor.o: cflexor.c cfparse.h cfparse_misc.h globals.h
cfparse.o: cfparse.c globals.h cfparse_misc.h
iverilog.ps: $(srcdir)/iverilog.man
man -t $(srcdir)/iverilog.man > iverilog.ps
install: all installdirs $(bindir)/iverilog@EXEEXT@ $(mandir)/man1/iverilog.1
iverilog.pdf: iverilog.ps
ps2pdf iverilog.ps iverilog.pdf
ifeq (@WIN32@,yes)
INSTALL_DOC = $(prefix)/iverilog.pdf
INSTALL_DOCDIR =
all: iverilog.pdf
else
INSTALL_DOC = $(mandir)/man1/iverilog.1
INSTALL_DOCDIR = $(mandir)/man1
endif
install: all installdirs $(bindir)/iverilog@EXEEXT@ $(INSTALL_DOC)
$(bindir)/iverilog@EXEEXT@: ./iverilog@EXEEXT@
$(INSTALL_PROGRAM) ./iverilog@EXEEXT@ $(bindir)/iverilog@EXEEXT@
@@ -83,8 +103,11 @@ $(bindir)/iverilog@EXEEXT@: ./iverilog@EXEEXT@
$(mandir)/man1/iverilog.1: $(srcdir)/iverilog.man
$(INSTALL_DATA) $(srcdir)/iverilog.man $(mandir)/man1/iverilog.1
$(prefix)/iverilog.pdf: iverilog.pdf
$(INSTALL_DATA) iverilog.pdf $(prefix)/iverilog.pdf
installdirs: ../mkinstalldirs
$(srcdir)/../mkinstalldirs $(bindir) $(mandir)/man1
$(srcdir)/../mkinstalldirs $(bindir) $(INSTALL_DOCDIR)
uninstall:
rm -f $(bindir)/iverilog@EXEEXT@
+46 -2
View File
@@ -16,8 +16,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: build_string.c,v 1.4 2001/07/25 03:10:50 steve Exp $"
#ifdef HAVE_CVS_IDENT
#ident "$Id: build_string.c,v 1.11 2002/08/12 01:35:01 steve Exp $"
#endif
# include "config.h"
@@ -54,6 +54,7 @@ int build_string(char*output, size_t olen, const char*pattern)
if (((*pattern == 's') && start)
|| ((*pattern == 'v') && verbose_flag)
|| ((*pattern == 'M') && depfile)
|| ((*pattern == 'N') && npath)
|| ((*pattern == 'T') && mtm)) {
int rc = build_string(output, olen,
@@ -71,6 +72,18 @@ int build_string(char*output, size_t olen, const char*pattern)
olen -= strlen(base);
break;
case 'C':
strcpy(output, iconfig_path);
output += strlen(iconfig_path);
olen -= strlen(iconfig_path);
break;
case 'g':
strcpy(output, generation);
output += strlen(generation);
olen -= strlen(generation);
break;
case 'f':
if (f_list) {
strcpy(output, f_list);
@@ -87,6 +100,14 @@ int build_string(char*output, size_t olen, const char*pattern)
}
break;
case 'M':
if (depfile) {
strcpy(output, depfile);
output += strlen(depfile);
olen -= strlen(depfile);
}
break;
case 'N':
if (npath) {
strcpy(output, npath);
@@ -144,6 +165,29 @@ int build_string(char*output, size_t olen, const char*pattern)
/*
* $Log: build_string.c,v $
* Revision 1.11 2002/08/12 01:35:01 steve
* conditional ident string using autoconfig.
*
* Revision 1.10 2002/05/28 02:25:03 steve
* Pass library paths through -Cfile instead of command line.
*
* Revision 1.9 2002/05/28 00:50:39 steve
* Add the ivl -C flag for bulk configuration
* from the driver, and use that to run library
* modules through the preprocessor.
*
* Revision 1.8 2002/05/24 01:13:00 steve
* Support language generation flag -g.
*
* Revision 1.7 2002/04/04 05:26:13 steve
* Add dependency generation.
*
* Revision 1.6 2001/11/16 05:07:19 steve
* Add support for +libext+ in command files.
*
* Revision 1.5 2001/10/20 23:02:40 steve
* Add automatic module libraries.
*
* Revision 1.4 2001/07/25 03:10:50 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
+137
View File
@@ -0,0 +1,137 @@
%{
/*
* Copyright (c) 2001 Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: cflexor.lex,v 1.6 2002/05/28 20:40:37 steve Exp $"
#endif
# include "cfparse.h"
# include "cfparse_misc.h"
# include "globals.h"
# include <string.h>
/*
* Lexical location information is passed in the yylloc variable to th
* parser. The file names, strings, are kept in a list so that I can
* re-use them. The set_file_name function will return a pointer to
* the name as it exists in the list (and delete the passed string.)
* If the name is new, it will be added to the list.
*/
YYLTYPE yylloc;
static int comment_enter;
%}
%x CCOMMENT
%x LCOMMENT
%x PLUS_ARGS
%%
/* Accept C++ style comments. */
"//".* { comment_enter = YY_START; BEGIN(LCOMMENT); }
<LCOMMENT>. { yymore(); }
<LCOMMENT>\n { yylloc.first_line += 1; BEGIN(comment_enter); }
/* Accept C style comments. */
"/*" { comment_enter = YY_START; BEGIN(CCOMMENT); }
<CCOMMENT>. { yymore(); }
<CCOMMENT>\n { yylloc.first_line += 1; yymore(); }
<CCOMMENT>"*/" { BEGIN(comment_enter); }
/* Accept shell type comments. */
^"#".* { ; }
/* Skip white space. */
[ \t\f\r] { ; }
/* Skip line ends, but also count the line. */
\n { yylloc.first_line += 1; }
"+define+" { BEGIN(PLUS_ARGS); return TOK_DEFINE; }
"+incdir+" { BEGIN(PLUS_ARGS); return TOK_INCDIR; }
"+libdir+" { BEGIN(PLUS_ARGS); return TOK_LIBDIR; }
"+libdir-nocase+" { BEGIN(PLUS_ARGS); return TOK_LIBDIR_NOCASE; }
"+libext+" { BEGIN(PLUS_ARGS); return TOK_LIBEXT; }
/* If it is not any known plus-flag, return the generic form. */
"+"[^\n \t\b\f\r+]* {
cflval.text = strdup(yytext);
BEGIN(PLUS_ARGS);
return TOK_PLUSWORD; }
/* Once in PLUS_ARGS mode, words are delimited by +
characters. White space and line end terminate PLUS_ARGS mode,
but + terminates only the word. */
<PLUS_ARGS>[^\n \t\b\f\r+]* {
cflval.text = strdup(yytext);
return TOK_PLUSARG; }
/* Within plusargs, this is a delimiter. */
<PLUS_ARGS>"+" { }
/* White space end plus_args mode. */
<PLUS_ARGS>[ \t\b\f\r] { BEGIN(0); }
<PLUS_ARGS>\n {
yylloc.first_line += 1;
BEGIN(0); }
/* Notice the -a flag. */
"-a" { return TOK_Da; }
/* Notice the -v flag. */
"-v" { return TOK_Dv; }
/* Notice the -y flag. */
"-y" { return TOK_Dy; }
/* This rule matches paths and strings that may be file names. This
is a little bit tricky, as we don't want to mistake a comment for
a string word. */
"/"[^\*\/].* { cflval.text = strdup(yytext);
return TOK_STRING; }
[^/\n \t\b\r+-].* { cflval.text = strdup(yytext);
return TOK_STRING; }
/* Fallback match. */
. { return yytext[0]; }
%%
int yywrap()
{
return 1;
}
void cfreset(FILE*fd, const char*path)
{
yyin = fd;
yyrestart(fd);
yylloc.first_line = 1;
yylloc.text = (char*)path;
}
+210
View File
@@ -0,0 +1,210 @@
%{
/*
* Copyright (c) 20001 Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: cfparse.y,v 1.8 2002/06/23 20:10:51 steve Exp $"
#endif
# include "globals.h"
# include "cfparse_misc.h"
# include <ctype.h>
/*
* This flag is set to 0, 1 or 2 if file names are to be translated to
* uppercase(1) or lowercase(2).
*/
static int setcase_filename_flag = 0;
static void translate_file_name(char*text)
{
switch (setcase_filename_flag) {
case 0:
break;
case 1:
while (*text) {
*text = toupper(*text);
text += 1;
}
break;
case 2:
while (*text) {
*text = tolower(*text);
text += 1;
}
break;
}
}
%}
%union {
char*text;
};
%token TOK_Da TOK_Dv TOK_Dy
%token TOK_DEFINE TOK_INCDIR TOK_LIBDIR TOK_LIBDIR_NOCASE TOK_LIBEXT
%token <text> TOK_PLUSARG TOK_PLUSWORD TOK_STRING
%%
start
:
| item_list
;
item_list
: item_list item
| item
;
item
/* Absent any other matching, a token string is taken to be the name
of a source file. Add the file to the file list. */
: TOK_STRING
{ char*tmp = substitutions($1);
translate_file_name(tmp);
process_file_name(tmp);
free($1);
free(tmp);
}
/* The -a flag is completely ignored. */
| TOK_Da { }
/* The -v <libfile> flag is ignored, and the <libfile> is processed
as an ordinary source file. */
| TOK_Dv TOK_STRING
{ char*tmp = substitutions($2);
translate_file_name(tmp);
process_file_name(tmp);
fprintf(stderr, "%s:%u: Ignoring -v in front of %s\n",
@1.text, @1.first_line, $2);
free($2);
free(tmp);
}
/* This rule matches "-y <path>" sequences. This does the same thing
as -y on the command line, so add the path to the library
directory list. */
| TOK_Dy TOK_STRING
{ char*tmp = substitutions($2);
process_library_switch(tmp);
free($2);
free(tmp);
}
| TOK_LIBDIR TOK_PLUSARG
{ char*tmp = substitutions($2);
process_library_switch(tmp);
free($2);
free(tmp);
}
| TOK_LIBDIR_NOCASE TOK_PLUSARG
{ char*tmp = substitutions($2);
process_library_nocase_switch(tmp);
free($2);
free(tmp);
}
| TOK_DEFINE TOK_PLUSARG
{ process_define($2);
free($2);
}
/* The +incdir token introduces a list of +<path> arguments that are
the include directories to search. */
| TOK_INCDIR inc_args
/* The +libext token introduces a list of +<ext> arguments that
become individual -Y flags to ivl. */
| TOK_LIBEXT libext_args
/* The +<word> tokens that are not otherwise matched, are
ignored. The skip_args rule arranges for all the argument words
to be consumed. */
| TOK_PLUSWORD skip_args
{ fprintf(stderr, "%s:%u: Ignoring %s\n",
@1.text, @1.first_line, $1);
free($1);
}
| TOK_PLUSWORD
{ if (strcmp($1, "+toupper-filenames") == 0) {
setcase_filename_flag = 1;
} else if (strcmp($1, "+tolower-filenames") == 0) {
setcase_filename_flag = 2;
} else {
fprintf(stderr, "%s:%u: Ignoring %s\n",
@1.text, @1.first_line, $1);
}
free($1);
}
;
/* inc_args are +incdir+ arguments in order. */
inc_args
: inc_args inc_arg
| inc_arg
;
inc_arg : TOK_PLUSARG
{ char*tmp = substitutions($1);
process_include_dir(tmp);
free($1);
free(tmp);
}
;
/* inc_args are +incdir+ arguments in order. */
libext_args
: libext_args libext_arg
| libext_arg
;
libext_arg : TOK_PLUSARG
{ process_library2_switch($1);
free($1);
}
;
/* skip_args are arguments to a +word flag that is not otherwise
parsed. This rule matches them and releases the strings, so that
they can be safely ignored. */
skip_args
: skip_args skip_arg
| skip_arg
;
skip_arg : TOK_PLUSARG
{ free($1);
}
;
%%
int yyerror(const char*msg)
{
}
+57
View File
@@ -0,0 +1,57 @@
#ifndef __cfparse_misc_H
#define __cfparse_misc_H
/*
* Copyright (c) 2001 Picture Elements, Inc.
* Stephen Williams (steve@picturel.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: cfparse_misc.h,v 1.4 2002/08/12 01:35:01 steve Exp $"
#endif
/*
* The vlltype supports the passing of detailed source file location
* information between the lexical analyzer and the parser. Defining
* YYLTYPE compels the lexor to use this type and not something other.
*/
struct cfltype {
unsigned first_line;
unsigned first_column;
unsigned last_line;
unsigned last_column;
const char*text;
};
# define YYLTYPE struct cfltype
extern YYLTYPE yylloc;
/*
* $Log: cfparse_misc.h,v $
* Revision 1.4 2002/08/12 01:35:01 steve
* conditional ident string using autoconfig.
*
* Revision 1.3 2002/01/02 02:39:34 steve
* Use my own cfltype to defend against bison 1.30.
*
* Revision 1.2 2001/11/12 18:47:32 steve
* Support +incdir in command files, and ignore other
* +args flags. Also ignore -a and -v flags.
*
* Revision 1.1 2001/11/12 01:26:36 steve
* More sophisticated command file parser.
*
*/
#endif
+75 -4
View File
@@ -18,8 +18,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: globals.h,v 1.4 2001/07/03 04:09:25 steve Exp $"
#ifdef HAVE_CVS_IDENT
#ident "$Id: globals.h,v 1.16 2002/08/12 01:35:01 steve Exp $"
#endif
# include <stddef.h>
@@ -27,6 +27,9 @@
/* This is the base (i.e. -B<value>) of the Icarus Verilog files. */
extern const char*base;
/* This is the path to the iconfig file sent to ivl. */
extern char* iconfig_path;
/* This is a list of all the -f<key>=<value> options from the
command line, concatenated together. */
extern char*f_list;
@@ -36,14 +39,17 @@ extern char*mod_list;
/* This is the optional -Tmin|typ|max setting. */
extern const char*mtm;
/* Ths is the optional -M<dependfile> value, if one was supplied. */
extern const char*depfile;
/* Ths is the optional -N<path> value, if one was supplied. */
extern const char*npath;
/* This is the name of the output file that the user selected. */
extern const char*opath;
/* This pointer is set if there was a -s<value> parameter. */
extern const char*start;
/* This pointer is set if there were -s<value> parameters. */
extern char*start;
/* This flag is true if the -S flag was used on the command line. */
extern int synth_flag;
@@ -51,17 +57,82 @@ extern int synth_flag;
/* This is the name of the selected target. */
extern const char*targ;
/* This is the language generation flag. */
extern const char*generation;
/* Perform variable substitutions on the string. */
extern char* substitutions(const char*str);
/* Add the name to the list of source files. */
extern void process_file_name(const char*name);
/* Add the name to the list of library directories. */
extern void process_library_switch(const char*name);
extern void process_library_nocase_switch(const char*name);
extern void process_library2_switch(const char*name);
/* Add a new include file search directory */
extern void process_include_dir(const char*name);
/* Add a new -D define. */
extern void process_define(const char*name);
/* -v */
extern int verbose_flag;
extern char warning_flags[];
/* -y and -Y flags from the command line. */
extern char* library_flags;
extern char* library_flags2;
extern const char*lookup_pattern(const char*key);
extern int build_string(char*out, size_t olen, const char*pattern);
/*
* $Log: globals.h,v $
* Revision 1.16 2002/08/12 01:35:01 steve
* conditional ident string using autoconfig.
*
* Revision 1.15 2002/06/23 20:10:51 steve
* Variable substitution in command files.
*
* Revision 1.14 2002/05/28 20:40:37 steve
* ivl indexes the search path for libraries, and
* supports case insensitive module-to-file lookup.
*
* Revision 1.13 2002/05/28 00:50:40 steve
* Add the ivl -C flag for bulk configuration
* from the driver, and use that to run library
* modules through the preprocessor.
*
* Revision 1.12 2002/05/24 01:13:00 steve
* Support language generation flag -g.
*
* Revision 1.11 2002/04/04 05:26:13 steve
* Add dependency generation.
*
* Revision 1.10 2001/11/16 05:07:19 steve
* Add support for +libext+ in command files.
*
* Revision 1.9 2001/11/13 03:30:26 steve
* The +incdir+ plusarg can take multiple directores,
* and add initial support for +define+ in the command file.
*
* Revision 1.8 2001/11/12 18:47:32 steve
* Support +incdir in command files, and ignore other
* +args flags. Also ignore -a and -v flags.
*
* Revision 1.7 2001/11/12 01:26:36 steve
* More sophisticated command file parser.
*
* Revision 1.6 2001/10/23 00:37:30 steve
* The -s flag can now be repeated on the iverilog command.
*
* Revision 1.5 2001/10/20 23:02:40 steve
* Add automatic module libraries.
*
* Revision 1.4 2001/07/03 04:09:25 steve
* Generate verbuse status messages (Stephan Boettcher)
*
+151 -31
View File
@@ -1,19 +1,20 @@
.TH iverilog 1 "$Date: 2001/08/31 17:28:10 $" Version "$Date: 2001/08/31 17:28:10 $"
.TH iverilog 1 "$Date: 2002/06/23 20:10:51 $" Version "$Date: 2002/06/23 20:10:51 $"
.SH NAME
iverilog - Icarus Verilog compiler
.SH SYNOPSIS
.B iverilog
[-ESv] [-Cpath] [-ccmdfile] [-Dmacro[=defn]] [-pflag=value] [-Iincludepath] [-mmodule] [-Nfile] [-ooutputfilename] [-stopmodule] [-ttype] [-Tmin/typ/max] [-Wclass] sourcefile
[-ESVv] [-Cpath] [-ccmdfile] [-g1|-g2|-g3.0] [-Dmacro[=defn]] [-pflag=value]
[-Iincludedir] [-mmodule] [-Mfile] [-Nfile] [-ooutputfilename]
[-stopmodule] [-ttype] [-Tmin/typ/max] [-Wclass] [-ypath] sourcefile
.SH DESCRIPTION
.PP
\fIiverilog\fP is a compiler that translates Verilog source code into
executable programs for simulation, or other netlist formats for
further processing. The currently supported targets are \fIvvm\fP (for
executable simulation) and \fIvvp\fP for simulation, and \fIxnf\fP for
synthesis. Other target types are added as code generators are
implemented.
further processing. The currently supported targets are \fIvvp\fP for
simulation, and \fIxnf\fP and \fIfpga\fP for synthesis. Other target
types are added as code generators are implemented.
.SH OPTIONS
.l
@@ -21,7 +22,7 @@ implemented.
.TP 8
.B -B\fIbase\fP
The \fIiverilog\fP program uses external programs to preprocess and
compile the verilog source. Normally, the path used to locate these
compile the Verilog source. Normally, the path used to locate these
tools is built into the \fIiverilog\fP program. However, the \fB-B\fP
switch allows the user to select a different set of programs. The path
given is used to locate \fIivlpp\fP, \fIivl\fP and the VPI modules.
@@ -30,9 +31,7 @@ given is used to locate \fIivlpp\fP, \fIivl\fP and the VPI modules.
This flag specifies an input file that contains a list of Verilog
source files. This is similar to the \fIcommand file\fP of other
Verilog simulators, in that it is a file that contains the file names
instead of taking them on the command line. The command file may
contain C-style comments (/*-*/) or shell-style comments (# to the end
of the line.)
instead of taking them on the command line. See \fBCommand Files\fP below.
.TP 8
.B -C\fIpath\fP
This flag selects the driver configuration file to use. Normally, the
@@ -54,14 +53,30 @@ Defines macro \fImacro\fP as \fIdefn\fP.
Preprocess the Verilog source, but do not compile it. The output file
is the Verilog input, but with file inclusions and macro references
expanded and removed. This is useful, for example, to preprocess
verilog source for use by other compilers.
Verilog source for use by other compilers.
.TP 8
.B -g1\fI|\fP-g2\fI|\fP-g3.0
Select the Verilog language \fIgeneration\fP to support in the
compiler. This selects between \fIIEEE1364-1995\fP(1),
\fIIEEE1364-2001\fP(2), or \fISystemVerilog 3.0\fP(3.0). Normally,
Icarus Verilog defaults to the latest known generation of the
language. This flag is most useful to restrict the language to a set
supported by tools of specific generations, for compatibility with
other tools.
.TP 8
.B -I\fIincludedir\fP
Append directory \fIincludepdir\fP to list of directories searched
Append directory \fIincludedir\fP to list of directories searched
for Verilog include files. The \fB-I\fP switch may be used many times
to specify several directories to search, the directories are searched
in the order they appear on the command line.
.TP 8
.B -M\fIpath\fP
Write into the file specified by path a list of files that contribute
to the compilation of the design. This includes files that are
included by include directives and files that are automatically loaded
by library support. The output is one file name per line, with no
leading or trailing space.
.TP 8
.B -m\fImodule\fP
Add this module to the list of VPI modules to be loaded by the
simulation. Many modules can be specified, and all will be loaded, in
@@ -92,9 +107,10 @@ netlist format, the \fB-S\fP switch is unnecessary and has no effect.
.TP 8
.B -s \fItopmodule\fP
Specify the top level module to elaborate. Icarus Verilog will by default
choose the only module that has no ports. However, this simplistic
heuristic is often not sufficient, and sometimes not what is wanted
anyhow.
choose modules that are not instantiated in any other modules, but
sometimes that is not sufficient, or instantiates too many modules. If
the user specifies one or more root modules with \fB-s\fP flags, then
they will be used as root modules instead.
.TP 8
.B -T\fImin|typ|max\fP
Use this switch to select min, typ or max times from min:typ:max
@@ -110,13 +126,36 @@ Use this switch to specify the target output format. See the
.B -v
Turn on verbose messages. This will print the command lines that are
executed to perform the actual compilation, along with version
information from the various components.
information from the various components, as well as the version of the
product as a whole.
.TP 8
.B -V
Print the version of the compiler, and exit.
.TP 8
.B -W\fIclass\fP
Turn on different classes of warnings. See the \fBWARNING TYPES\fP
section below for desctriptions of the different warning groups. If
section below for descriptions of the different warning groups. If
multiple \fB-W\fP switches are used, the warning set is the union of
all the requested classes.
.TP 8
.B -y\fIlibdir\fP
Append the directory to the library module search path. When the
compiler finds an undefined module, it looks in these directories for
files with the right name.
.SH MODULE LIBRARIES
The Icarus Verilog compiler supports module libraries as directories
that contain Verilog source files. During elaboration, the compiler
notices the instantiation of undefined module types. If the user
specifies library search directories, the compiler will search the
directory for files with the name of the missing module type. If it
finds such a file, it loads it as a Verilog source file, they tries
again to elaborate the module.
Library module files should contain only a single module, but this is
not a requirement. Library modules may reference other modules in the
library or in the main design.
.SH TARGETS
@@ -129,31 +168,27 @@ desired target.
The null target causes no code to be generated. It is useful for
checking the syntax of the Verilog source.
.TP 8
.B vvm
The target is an executable program that uses the vvm simulation
runtime. The compiler actually generates C++ code, then compiles and
links that code to make the output executable.
.TP 8
.B vvp
This is the default. The vvp target generates code for the vvp
runtime. The output is a complete program that simulates the design
(like with vvm) but must be run by the \fivvp\fP command. This target
is much faster then the \fBvvm\fP target, but not quite as complete.
but must be run by the \fBvvp\fP command.
.TP 8
.B xnf
This is the Xilinx Netlist Format used by many tools for placing
devices in FPGAs or other programmable devices. The Icarus Verilog XNF
code generator can generate complete designs or XNF macros that can be
imported into larger designs by other tools.
imported into larger designs by other tools. (This target is obsolete,
use the \fBfpga\fP target instead.)
.TP 8
.B fpga
This is a variant of the XNF code generator that supports a wider
variety of target devices. It is intented as a future replacement for
the existing \fBxnf\fP target, but for now is still experimental.
This is a synthesis target that supports a variety of fpga devices,
mostly by EDIF format output.
.SH "WARNING TYPES"
These are the types of warnings that can be selected by the \fB-W\fP
switch.
switch. All the warning types (other then \fBall\fP) can also be
prefixed with \fBno-\fP to turn off that warning. This is most useful
after a \fB-Wall\fP argument to suppress isolated warning types.
.TP 8
.B all
@@ -162,9 +197,94 @@ This enables all supported warning categories.
.TP 8
.B implicit
This enables warnings for creation of implicit declarations. For
example, if a scaler wire X is used but not declared in the Verilog
example, if a scalar wire X is used but not declared in the Verilog
source, this will print a warning at its first use.
.TP 8
.B timescale
This enables warnings for inconsistent use of the timescale
directive. It detects if some modules have no timescale, or if modules
inherit timescale from another file. Both probably mean that
timescales are inconsistent, and simulation timing can be confusing
and dependent on compilation order.
.SH "COMMAND FILES"
The command file allows the user to place source file names and
certain command line switches into a text file instead of on a long
command line. Command files can include C or C++ style comments, as
well as # comments, if the # starts the line.
.TP 8
.I "file name"
A simple file name or file path is taken to be the name of a Verilog
source file. The path starts with the first non-white-space
character. Variables are substitued in file names.
.TP 8
.B -y\ \fIlibdir\fP
A \fB-y\fP token prefixes a library directory in the command file,
exactly like it does on the command line. The parameter to the \fB-y\fP
flag may be on the same line or the next non-comment line.
Variables in the \fIlibdir\fP are substituted.
.TP 8
.B +incdir+\fIincludedir\fP
The \fB+incdir+\fP token in command files gives directories to search
for include files in much the same way that \fB-I\fP flags work on the
command line. The difference is that multiple \fI+includedir\fP
directories are valid parameters to a single \fB+incdir+\fP token,
although you may also have multiple \fB+incdir+\fP lines.
Variables in the \fIincludedir\fP are substituted.
.TP 8
.B +libext+\fIext\fP
The \fB+libext\fP token in command files fives file extensions to try
when looking for a library file. This is useful in conjunction with
\fB-y\fP flags to list suffixes to try in each directory before moving
on to the next library directory.
.TP 8
.B +libdir+\fIdir\fP
This is another way to specify library directories. See the -y flag.
.TP 8
.B +libdir-nocase+\fIdir\fP
This is like the \fB+libdir\fP statement, but file names inside the
directories declared here are case insensitive. The missing module
name in a lookup need not match the file name case, as long as the
letters are correct. For example, "foo" matches "Foo.v" but not
"bar.v".
.TP 8
.B +define+\fINAME\fP=\fIvalue\fP
The \fB+define+\fP token is the same as the \fB-D\fP option on the
command line. The value part of the token is optional.
.TP 8
.B +toupper-filename\fP
This token causes file names after this in the command file to be
translated to uppercase. This helps with situations where a directory
has passed through a DOS machine, and in the process the file names
become munged.
.TP 8
.B +tolower-filename\fP
This is similar to the \fB+toupper-filename\fP hack described above.
.SH "VARIABLES IN COMMAND FILES"
In certain cases, iverilog supports variables in command files. These
are strings of the form "$(\fIvarname\fP)", where \fIvarname\fP is the
name of the environment variable to read. The entire string is
replaced with the contents of that variable. Variables are only
substitued in contexts that explicitly support them, including file
and directory strings.
Variable values come from the operating system environment, and not
from preprocessor defines elsewhere in the file or the command line.
.SH EXAMPLES
These examples assume that you have a Verilog source file called hello.v in
the current directory
@@ -196,7 +316,7 @@ vvp(1),
.SH COPYRIGHT
.nf
Copyright \(co 2000 Stephen Williams
Copyright \(co 2002 Stephen Williams
This document can be freely redistributed according to the terms of the
GNU General Public License version 2.0
+396 -260
View File
@@ -16,16 +16,17 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ident "$Id: main.c,v 1.21 2001/07/25 03:10:50 steve Exp $"
#ident "$Id: main.c,v 1.49 2002/12/04 03:26:59 steve Exp $"
# include "config.h"
const char HELP[] =
"Usage: iverilog [-ESv] [-B base] [-C path] [-c cmdfile]\n"
" [-D macro[=defn]] [-I includedir] [-m module]\n"
"Usage: iverilog [-ESvV] [-B base] [-C path] [-c cmdfile] [-g1|-g2|-g3.0]\n"
" [-D macro[=defn]] [-I includedir] [-M depfile] [-m module]\n"
" [-N file] [-o filename] [-p flag=value]\n"
" [-s topmodule] [-t target] [-T min|typ|max]\n"
" [-W class] source_file(s)\n"
" [-W class] [-y dir] [-Y suf] source_file(s)\n"
"See man page for details.";
#define MAXSIZE 4096
@@ -43,6 +44,7 @@ const char HELP[] =
#ifdef __MINGW32__
#include <windows.h>
#include <libiberty.h>
#endif
#if HAVE_GETOPT_H
@@ -67,10 +69,6 @@ extern const char*optarg;
# define IVL_ROOT "."
#endif
#ifndef RDYNAMIC
# define RDYNAMIC "-rdynamic"
#endif
# include "globals.h"
#ifdef __MINGW32__
@@ -79,12 +77,16 @@ const char sep = '\\';
const char sep = '/';
#endif
extern void cfreset(FILE*fd, const char*path);
const char*base = 0;
const char*mtm = 0;
const char*opath = "a.out" EXEEXT;
const char*opath = "a.out";
const char*npath = 0;
const char*targ = "vvp";
const char*start = 0;
const char*depfile = 0;
const char*generation = "-g3.0";
char warning_flags[16] = "";
@@ -92,13 +94,23 @@ char*inc_list = 0;
char*def_list = 0;
char*mod_list = 0;
char*command_filename = 0;
char*start = 0;
char*f_list = 0;
/* These are used to collect the list of file names that will be
passed to ivlpp. Keep the list in a file because it can be a long
list. */
char*source_path = 0;
FILE*source_file = 0;
unsigned source_count = 0;
char*iconfig_path = 0;
FILE*iconfig_file = 0;
int synth_flag = 0;
int verbose_flag = 0;
int command_file = 0;
int inside_c_comment = 0;
FILE *fp;
@@ -107,6 +119,72 @@ char tmp[MAXSIZE];
static char ivl_root[MAXSIZE];
#ifdef __MINGW32__
# include <io.h>
# include <fcntl.h>
static FILE*fopen_safe(const char*path)
{
FILE*file = 0;
int fd;
fd = _open(path, _O_WRONLY|_O_CREAT|_O_EXCL, 0700);
if (fd != -1)
file = _fdopen(fd, "w");
return file;
}
#else
# include <fcntl.h>
static FILE*fopen_safe(const char*path)
{
FILE*file = 0;
int fd;
fd = open(path, O_WRONLY|O_CREAT|O_EXCL, 0700);
if (fd != -1)
file = fdopen(fd, "w");
return file;
}
#endif
static const char*my_tempfile(const char*str, FILE**fout)
{
FILE*file;
int retry;
static char pathbuf[8192];
const char*tmpdir = getenv("TMP");
if (tmpdir == 0)
tmpdir = getenv("TMPDIR");
if (tmpdir == 0)
tmpdir = getenv("TEMP");
#ifdef __MINGW32__
if (tmpdir == 0)
tmpdir = "C:\\TEMP";
#else
if (tmpdir == 0)
tmpdir = "/tmp";
#endif
assert(tmpdir);
assert((strlen(tmpdir) + strlen(str)) < sizeof pathbuf - 10);
srand(getpid());
retry = 100;
file = NULL;
while ((retry > 0) && (file == NULL)) {
unsigned code = rand();
sprintf(pathbuf, "%s%c%s%04x", tmpdir, sep, str, code);
file = fopen_safe(pathbuf);
retry -= 1;
}
*fout = file;
return pathbuf;
}
/*
* This is the default target type. It looks up the bits that are
* needed to run the command from the configuration file (which is
@@ -146,7 +224,14 @@ static int t_default(char*cmd, unsigned ncmd)
rc = system(cmd);
remove(source_path);
remove(iconfig_path);
if (rc != 0) {
if (rc == 127) {
fprintf(stderr, "Failed to execute: %s\n", cmd);
return 1;
}
if (WIFEXITED(rc))
return WEXITSTATUS(rc);
@@ -157,169 +242,6 @@ static int t_default(char*cmd, unsigned ncmd)
return 0;
}
/*
* This function handles the vvm target. After preprocessing, run the
* ivl translator to get C++, then run g++ to make an executable
* program out of that.
*/
static int t_vvm(char*cmd, unsigned ncmd)
{
int rc;
const char*pattern = lookup_pattern("<ivl>");
if (pattern == 0) {
fprintf(stderr, "No such target: %s\n", targ);
return -1;
}
tmp[0] = ' ';
tmp[1] = '|';
tmp[2] = ' ';
rc = build_string(tmp+3, sizeof tmp - 3, pattern);
cmd = realloc(cmd, ncmd+3+rc+1);
#ifdef __MINGW32__
{
char *t;
for (t = tmp; *t; t++)
{
if (*t == '/') *t = '\\';
}
}
#endif
strcpy(cmd+ncmd, tmp);
if (verbose_flag)
printf("translate: %s\n", cmd);
rc = system(cmd);
if (rc != 0) {
if (WIFEXITED(rc)) {
fprintf(stderr, "errors translating Verilog program.\n");
return WEXITSTATUS(rc);
} else {
fprintf(stderr, "Command signaled: %s\n", cmd);
return -1;
}
}
#if defined(__MINGW32__)
/* In the Windows world, the path to headers and libraries
for vvm is relative the ivl_root, which is in something like:
d:\iverilog\lib\ivl <-- ivl_root
d:\iverilog\include <-- vvm headers
d:\iverilog\lib <-- vvm libraries
So we make up all the ugly references that are the g++
command line to compile a .cc file generated by vvm. */
sprintf(tmp, "%s " RDYNAMIC " -s -fno-exceptions -o %s "
"-I%s\\..\\..\\include -L%s\\.. %s.cc -lvvm -lvpip %s",
CXX, opath, ivl_root, ivl_root, opath, DLLIB);
#else
/* In the UNIX universe, life is easy. The configure script
has figured everything out and wrote it into the Makefile,
which passes it on as the IVL_INC and IVL_LIB defines. */
sprintf(tmp, "%s " RDYNAMIC " -s -fno-exceptions -o %s -I%s "
"-L%s %s.cc -lvvm -lvpip %s", CXX, opath, IVL_INC,
IVL_LIB, opath, DLLIB);
#endif
if (verbose_flag)
printf("compile: %s\n", tmp);
rc = system(tmp);
if (rc != 0) {
if (WIFEXITED(rc)) {
fprintf(stderr, "errors compiling translated program.\n");
return WEXITSTATUS(rc);
} else {
fprintf(stderr, "Command signaled: %s\n", tmp);
return -1;
}
}
sprintf(tmp, "%s.cc", opath);
unlink(tmp);
return 0;
}
static int t_xnf(char*cmd, unsigned ncmd)
{
int rc;
sprintf(tmp, " | %s%civl %s -o %s -txnf -Fcprop -Fsynth -Fsyn-rules "
"-Fnodangle -Fxnfio", base, sep,warning_flags, opath);
rc = strlen(tmp);
cmd = realloc(cmd, ncmd+rc+1);
#ifdef __MINGW32__
{
char *t;
for (t = tmp; *t; t++)
{
if (*t == '/') *t = '\\';
}
}
#endif
strcpy(cmd+ncmd, tmp);
ncmd += rc;
if (f_list) {
rc = strlen(f_list);
cmd = realloc(cmd, ncmd+rc+1);
strcpy(cmd+ncmd, f_list);
ncmd += rc;
}
if (mtm) {
sprintf(tmp, " -T%s", mtm);
rc = strlen(tmp);
cmd = realloc(cmd, ncmd+rc+1);
strcpy(cmd+ncmd, tmp);
ncmd += rc;
}
if (npath) {
sprintf(tmp, " -N%s", npath);
rc = strlen(tmp);
cmd = realloc(cmd, ncmd+rc+1);
strcpy(cmd+ncmd, tmp);
ncmd += rc;
}
if (start) {
sprintf(tmp, " -s%s", start);
rc = strlen(tmp);
cmd = realloc(cmd, ncmd+rc+1);
strcpy(cmd+ncmd, tmp);
ncmd += rc;
}
sprintf(tmp, " -- -");
rc = strlen(tmp);
cmd = realloc(cmd, ncmd+rc+1);
strcpy(cmd+ncmd, tmp);
ncmd += rc;
if (verbose_flag)
printf("translate: %s\n", cmd);
rc = system(cmd);
if (rc != 0) {
if (WIFEXITED(rc)) {
fprintf(stderr, "errors translating Verilog program.\n");
return WEXITSTATUS(rc);
}
fprintf(stderr, "Command signaled: %s\n", cmd);
return -1;
}
return 0;
}
static void process_warning_switch(const char*name)
{
@@ -327,21 +249,112 @@ static void process_warning_switch(const char*name)
strcpy(warning_flags, "-W");
if (strcmp(name,"all") == 0) {
strcat(warning_flags, "i");
strcat(warning_flags, "it");
} else if (strcmp(name,"implicit") == 0) {
if (! strchr(warning_flags+2, 'i'))
strcat(warning_flags, "i");
} else if (strcmp(name,"timescale") == 0) {
if (! strchr(warning_flags+2, 't'))
strcat(warning_flags, "t");
} else if (strcmp(name,"no-implicit") == 0) {
char*cp = strchr(warning_flags+2, 'i');
if (cp) while (*cp) {
cp[0] = cp[1];
cp += 1;
}
} else if (strcmp(name,"no-timescale") == 0) {
char*cp = strchr(warning_flags+2, 't');
if (cp) while (*cp) {
cp[0] = cp[1];
cp += 1;
}
}
}
void process_library_switch(const char *name)
{
fprintf(iconfig_file, "-y:%s\n", name);
}
void process_library_nocase_switch(const char *name)
{
fprintf(iconfig_file, "-yl:%s\n", name);
}
void process_library2_switch(const char *name)
{
fprintf(iconfig_file, "-Y:%s\n", name);
}
void process_include_dir(const char *name)
{
if (inc_list == 0) {
inc_list = malloc(strlen(" -I")+strlen(name)+1);
strcpy(inc_list, " -I");
strcat(inc_list, name);
} else {
inc_list = realloc(inc_list, strlen(inc_list)
+ strlen(" -I")
+ strlen(name) + 1);
strcat(inc_list, " -I");
strcat(inc_list, name);
}
}
void process_define(const char*name)
{
if (def_list == 0) {
def_list = malloc(strlen(" -D")+strlen(name)+1);
strcpy(def_list, " -D");
strcat(def_list, name);
} else {
def_list = realloc(def_list, strlen(def_list)
+ strlen(" -D")
+ strlen(name) + 1);
strcat(def_list, " -D");
strcat(def_list, name);
}
}
void process_file_name(const char*name)
{
fprintf(source_file, "%s\n", name);
source_count += 1;
}
int process_generation(const char*name)
{
if (strcmp(name,"1") == 0)
generation = "-g1";
else if (strcmp(name,"2") == 0)
generation = "-g2";
else if (strcmp(name,"3.0") == 0)
generation = "-g3.0";
else {
fprintf(stderr, "Unknown/Unsupported Language generation "
"%s\n", name);
fprintf(stderr, "Supported generations are:\n");
fprintf(stderr, " 1 -- IEEE1364-1995 (Verilog 1)\n"
" 2 -- IEEE1364-2001 (Verilog 2001)\n"
" 3.0 -- SystemVerilog 3.0\n");
return 1;
}
return 0;
}
int main(int argc, char **argv)
{
const char*config_path = 0;
char*cmd;
unsigned ncmd;
int e_flag = 0;
int opt, idx;
int version_flag = 0;
int opt, idx, rc;
char*cp;
#ifdef __MINGW32__
@@ -373,6 +386,7 @@ int main(int argc, char **argv)
base = ivl_root;
}
#else
/* In a UNIX environment, the IVL_ROOT from the Makefile is
dependable. It points to the $prefix/lib/ivl directory,
@@ -381,7 +395,29 @@ int main(int argc, char **argv)
base = ivl_root;
#endif
while ((opt = getopt(argc, argv, "B:C:c:D:Ef:hI:m:N::o:p:Ss:T:t:vW:")) != EOF) {
/* Create a temporary file for communicating input parameters
to the preprocessor. */
source_path = strdup(my_tempfile("ivrlg", &source_file));
if (NULL == source_file) {
fprintf(stderr, "%s: Error opening temporary file %s\n",
argv[0], source_path);
fprintf(stderr, "%s: Please check TMP or TMPDIR.\n", argv[0]);
return 1;
}
/* Create another temporary file for passing configuration
information to ivl. */
iconfig_path = strdup(my_tempfile("ivrlh", &iconfig_file));
if (NULL == iconfig_file) {
fprintf(stderr, "%s: Error opening temporary file %s\n",
argv[0], iconfig_path);
fprintf(stderr, "%s: Please check TMP or TMPDIR.\n", argv[0]);
fclose(source_file);
remove(source_path);
return 1;
}
while ((opt = getopt(argc, argv, "B:C:c:D:Ef:g:hI:M:m:N::o:p:Ss:T:t:vVW:y:Y:")) != EOF) {
switch (opt) {
case 'B':
@@ -392,20 +428,10 @@ int main(int argc, char **argv)
break;
case 'c':
command_filename = malloc(strlen(optarg)+1);
strcat(command_filename, optarg);
strcpy(command_filename, optarg);
break;
case 'D':
if (def_list == 0) {
def_list = malloc(strlen(" -D")+strlen(optarg)+1);
strcpy(def_list, " -D");
strcat(def_list, optarg);
} else {
def_list = realloc(def_list, strlen(def_list)
+ strlen(" -D")
+ strlen(optarg) + 1);
strcat(def_list, " -D");
strcat(def_list, optarg);
}
process_define(optarg);
break;
case 'E':
e_flag = 1;
@@ -426,23 +452,23 @@ int main(int argc, char **argv)
}
break;
case 'g':
rc = process_generation(optarg);
if (rc != 0)
return -1;
break;
case 'h':
fprintf(stderr, "%s\n", HELP);
return 1;
case 'I':
if (inc_list == 0) {
inc_list = malloc(strlen(" -I")+strlen(optarg)+1);
strcpy(inc_list, " -I");
strcat(inc_list, optarg);
} else {
inc_list = realloc(inc_list, strlen(inc_list)
+ strlen(" -I")
+ strlen(optarg) + 1);
strcat(inc_list, " -I");
strcat(inc_list, optarg);
}
process_include_dir(optarg);
break;
case 'M':
depfile = optarg;
break;
case 'm':
if (mod_list == 0) {
mod_list = malloc(strlen(" -m")+strlen(optarg)+1);
@@ -469,7 +495,18 @@ int main(int argc, char **argv)
synth_flag = 1;
break;
case 's':
start = optarg;
if (start) {
static const char *s = " -s ";
size_t l = strlen(start);
start = realloc(start, l + strlen(optarg) + strlen(s) + 1);
strcpy(start + l, s);
strcpy(start + l + strlen(s), optarg);
} else {
static const char *s = "-s ";
start = malloc(strlen(optarg) + strlen(s) + 1);
strcpy(start, s);
strcpy(start + strlen(s), optarg);
}
break;
case 'T':
if (strcmp(optarg,"min") == 0) {
@@ -490,16 +527,61 @@ int main(int argc, char **argv)
case 'v':
verbose_flag = 1;
break;
case 'V':
version_flag = 1;
break;
case 'W':
process_warning_switch(optarg);
break;
case 'y':
process_library_switch(optarg);
break;
case 'Y':
process_library2_switch(optarg);
break;
case '?':
default:
return 1;
}
}
if ((optind == argc) && !command_filename) {
if (version_flag || verbose_flag) {
printf("Icarus Verilog version " VERSION "\n");
printf("Copyright 1998-2002 Stephen Williams\n");
printf("$Name: $\n");
if (version_flag)
return 0;
}
if (command_filename) {
int rc;
if (( fp = fopen(command_filename, "r")) == NULL ) {
fprintf(stderr, "%s: Can't open %s\n",
argv[0], command_filename);
return 1;
}
cfreset(fp, command_filename);
rc = cfparse();
if (rc != 0) {
fprintf(stderr, "%s: error reading command file\n",
command_filename);
return 1;
}
}
/* Finally, process all the remaining words on the command
line as file names. */
for (idx = optind ; idx < argc ; idx += 1)
process_file_name(argv[idx]);
fclose(source_file);
source_file = 0;
if (source_count == 0) {
fprintf(stderr, "%s: No input files.\n", argv[0]);
fprintf(stderr, "%s\n", HELP);
return 1;
@@ -526,9 +608,9 @@ int main(int argc, char **argv)
/* Start building the preprocess command line. */
sprintf(tmp, "%s%civlpp %s%s", base,sep,
sprintf(tmp, "%s%civlpp %s%s -D__ICARUS__=1 -f%s ", base,sep,
verbose_flag?" -v":"",
e_flag?"":" -L");
e_flag?"":" -L", source_path);
ncmd = strlen(tmp);
cmd = malloc(ncmd + 1);
@@ -546,55 +628,11 @@ int main(int argc, char **argv)
ncmd += strlen(def_list);
}
/* If user supplied a command file, retain its contents -- this
process supersedes command line source files. */
if (command_filename != 0) {
if (( fp = fopen(command_filename, "r")) == NULL ) {
fprintf(stderr, "%s: Can't open %s\n",
argv[0], command_filename);
return 1;
} else {
/* Process file and skip over commented-out lines.
Skips over c-like comment as well as '//' or
'#' lines. */
sprintf(tmp, "");
while (fgets(line, MAXSIZE, fp) != NULL) {
if ( strstr(line, "*/") != NULL ) {
inside_c_comment = 0;
continue;
}
if (inside_c_comment || (strstr(line, "/*") != NULL)) {
inside_c_comment = 1;
continue;
}
if ( (line[0] != '/' || line[1] != '/')
&& line[0] != '#' ) {
strcat (tmp, " ");
strncat (tmp, line, (strlen(line)-1));
}
}
fclose(fp);
}
cmd = realloc(cmd, ncmd+strlen(tmp)+1);
strcpy(cmd+ncmd, tmp);
ncmd += strlen(tmp);
} else {
/* Add all verilog source files to the preprocess
command line. */
for (idx = optind ; idx < argc ; idx += 1) {
sprintf(tmp, " %s", argv[idx]);
cmd = realloc(cmd, ncmd+strlen(tmp)+1);
strcpy(cmd+ncmd, tmp);
ncmd += strlen(tmp);
}
if (depfile) {
cmd = realloc(cmd, ncmd + strlen(depfile) + 5);
strcat(cmd, " -M ");
strcat(cmd, depfile);
ncmd += strlen(depfile) + 4;
}
/* If the -E flag was given on the command line, then all we
@@ -613,6 +651,10 @@ int main(int argc, char **argv)
printf("preprocess: %s\n", cmd);
rc = system(cmd);
remove(source_path);
fclose(iconfig_file);
remove(iconfig_path);
if (rc != 0) {
if (WIFEXITED(rc)) {
fprintf(stderr, "errors preprocessing Verilog program.\n");
@@ -626,19 +668,113 @@ int main(int argc, char **argv)
return 0;
}
if (strcmp(targ,"vvm") == 0)
return t_vvm(cmd, ncmd);
else if (strcmp(targ,"xnf") == 0)
return t_xnf(cmd, ncmd);
else {
return t_default(cmd, ncmd);
}
/* Write the preprocessor command needed to preprocess a
single file. This may be used to preprocess library
files. */
fprintf(iconfig_file, "ivlpp:%s%civlpp -D__ICARUS__ -L %s %s\n",
base, sep,
inc_list? inc_list : "",
def_list? def_list : "");
/* Done writing to the iconfig file. Close it now. */
fclose(iconfig_file);
return t_default(cmd, ncmd);
return 0;
}
/*
* $Log: main.c,v $
* Revision 1.49 2002/12/04 03:26:59 steve
* Mingw32 compatible temp file management.
*
* Revision 1.48 2002/12/04 02:29:36 steve
* Use O_EXCL when opening temp files.
*
* Revision 1.47 2002/08/12 01:27:48 steve
* Escape the backslash in the windows file name.
*
* Revision 1.46 2002/08/10 22:36:59 steve
* No longer any nead for -rdynamic flag
*
* Revision 1.45 2002/08/10 22:27:13 steve
* Kill links to vvm.
*
* Revision 1.44 2002/07/15 00:33:50 steve
* Improve temporary file name guess.
*
* Revision 1.43 2002/07/14 23:32:31 steve
* No longer need the .exe on generated files.
*
* Revision 1.42 2002/07/14 23:11:35 steve
* Do temp file creation by hand.
*
* Revision 1.41 2002/05/28 20:40:37 steve
* ivl indexes the search path for libraries, and
* supports case insensitive module-to-file lookup.
*
* Revision 1.40 2002/05/28 02:25:03 steve
* Pass library paths through -Cfile instead of command line.
*
* Revision 1.39 2002/05/28 00:50:40 steve
* Add the ivl -C flag for bulk configuration
* from the driver, and use that to run library
* modules through the preprocessor.
*
* Revision 1.38 2002/05/27 23:14:06 steve
* Predefine __ICARUS__
*
* Revision 1.37 2002/05/24 01:13:00 steve
* Support language generation flag -g.
*
* Revision 1.36 2002/04/24 02:02:31 steve
* add -Wno- arguments to the driver.
*
* Revision 1.35 2002/04/15 00:04:23 steve
* Timescale warnings.
*
* Revision 1.34 2002/04/04 05:26:13 steve
* Add dependency generation.
*
* Revision 1.33 2002/03/15 23:27:42 steve
* Patch to allow user to set place for temporary files.
*
* Revision 1.32 2002/02/03 07:05:37 steve
* Support print of version number.
*
* Revision 1.31 2001/11/21 02:20:34 steve
* Pass list of file to ivlpp via temporary file.
*
* Revision 1.30 2001/11/16 05:07:19 steve
* Add support for +libext+ in command files.
*
* Revision 1.29 2001/11/13 03:30:26 steve
* The +incdir+ plusarg can take multiple directores,
* and add initial support for +define+ in the command file.
*
* Revision 1.28 2001/11/12 18:47:32 steve
* Support +incdir in command files, and ignore other
* +args flags. Also ignore -a and -v flags.
*
* Revision 1.27 2001/11/12 01:26:36 steve
* More sophisticated command file parser.
*
* Revision 1.26 2001/11/11 00:10:05 steve
* Remov XNF dead wood.
*
* Revision 1.25 2001/10/23 00:37:30 steve
* The -s flag can now be repeated on the iverilog command.
*
* Revision 1.24 2001/10/20 23:02:40 steve
* Add automatic module libraries.
*
* Revision 1.23 2001/10/19 23:10:08 steve
* Fix memory fault with -c flag.
*
* Revision 1.22 2001/10/11 00:12:49 steve
* Detect execv failures.
*
* Revision 1.21 2001/07/25 03:10:50 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
+5 -2
View File
@@ -18,13 +18,16 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: parse.y,v 1.3 2001/07/25 03:10:50 steve Exp $"
#ident "$Id: parse.y,v 1.5 2002/03/31 04:07:16 steve Exp $"
#endif
# include "config.h"
# include <stdio.h>
#ifdef HAVE_MALLOC_H
# include <malloc.h>
#endif
# include <stdlib.h>
# include "globals.h"
@@ -129,7 +132,7 @@ const char*lookup_pattern(const char*key)
%%
start: section_list
start: section_list ;
section_list
: section
+112
View File
@@ -0,0 +1,112 @@
/*
* Copyright (c) 2002 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: substit.c,v 1.4 2002/08/12 01:35:01 steve Exp $"
#endif
# include <string.h>
# include <stdlib.h>
#ifdef HAVE_MALLOC_H
# include <malloc.h>
#endif
char* substitutions(const char*str)
{
size_t nbuf = strlen(str) + 1;
char*buf = malloc(nbuf);
char*cp = buf;
while (*str) {
if ((str[0] == '$') && (str[1] == '(')) {
/* If I find a $(x) string in the source, replace
it in the destination with the contents of the
environment variable x. */
char*name;
char*value;
const char*ep = strchr(str, ')');
str += 2;
name = malloc(ep-str+1);
strncpy(name, str, ep-str);
name[ep-str] = 0;
str = ep + 1;
value = getenv(name);
free(name);
if (value == 0)
continue;
if (strlen(value) >= (nbuf - (cp-buf))) {
size_t old_size = cp - buf;
nbuf = (cp - buf) + strlen(value) + 1;
buf = realloc(buf, nbuf);
cp = buf + old_size;
}
strcpy(cp, value);
cp += strlen(cp);
} else {
if ( (cp - buf) == nbuf ) {
size_t old_size = nbuf;
nbuf = old_size + 32;
buf = realloc(buf, nbuf);
cp = buf + old_size;
}
*cp++ = *str++;
}
}
/* Add the trailing nul to the string, and reallocate the
buffer to be a tight fit. */
if ( (cp - buf) == nbuf ) {
size_t old_size = nbuf;
nbuf = old_size + 1;
buf = realloc(buf, nbuf);
buf[old_size] = 0;
} else {
*cp++ = 0;
nbuf = cp - buf;
buf = realloc(buf, nbuf);
}
return buf;
}
/*
* $Log: substit.c,v $
* Revision 1.4 2002/08/12 01:35:01 steve
* conditional ident string using autoconfig.
*
* Revision 1.3 2002/08/11 23:47:04 steve
* Add missing Log and Ident strings.
*
* Revision 1.2 2002/06/25 01:33:01 steve
* include malloc.h only when available.
*
* Revision 1.1 2002/06/23 20:10:51 steve
* Variable substitution in command files.
*
*/
+66 -11
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1999 Stephen Williams (steve@icarus.com)
* Copyright (c) 1999-2002 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -16,8 +16,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: dup_expr.cc,v 1.5 2001/07/25 03:10:48 steve Exp $"
#ifdef HAVE_CVS_IDENT
#ident "$Id: dup_expr.cc,v 1.9 2002/11/09 00:25:27 steve Exp $"
#endif
# include "config.h"
@@ -31,17 +31,79 @@ NetEScope* NetEScope::dup_expr() const
return 0;
}
NetESelect* NetESelect::dup_expr() const
{
return new NetESelect(expr_->dup_expr(), base_->dup_expr(),
expr_width());
}
NetESFunc* NetESFunc::dup_expr() const
{
NetESFunc*tmp = new NetESFunc(name_, expr_width(), nparms());
for (unsigned idx = 0 ; idx < nparms() ; idx += 1)
assert(tmp);
for (unsigned idx = 0 ; idx < nparms() ; idx += 1) {
assert(tmp->parm(idx));
tmp->parm(idx, tmp->parm(idx)->dup_expr());
}
return tmp;
}
NetESignal* NetESignal::dup_expr() const
{
NetESignal*tmp = new NetESignal(net_, msi_, lsi_);
assert(tmp);
tmp->expr_width(expr_width());
return tmp;
}
NetETernary* NetETernary::dup_expr() const
{
NetETernary*tmp = new NetETernary(cond_->dup_expr(),
true_val_->dup_expr(),
false_val_->dup_expr());
return tmp;
}
NetEUFunc* NetEUFunc::dup_expr() const
{
NetEUFunc*tmp;
svector<NetExpr*> tmp_parms (parms_.count());
for (unsigned idx = 0 ; idx < tmp_parms.count() ; idx += 1) {
assert(parms_[idx]);
tmp_parms[idx] = parms_[idx]->dup_expr();
}
tmp = new NetEUFunc(func_, result_->dup_expr(), tmp_parms);
return tmp;
}
NetEUnary* NetEUnary::dup_expr() const
{
NetEUnary*tmp = new NetEUnary(op_, expr_->dup_expr());
assert(tmp);
return tmp;
}
/*
* $Log: dup_expr.cc,v $
* Revision 1.9 2002/11/09 00:25:27 steve
* Add dup_expr for user defined function calls.
*
* Revision 1.8 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.7 2002/01/28 00:52:41 steve
* Add support for bit select of parameters.
* This leads to a NetESelect node and the
* vvp code generator to support that.
*
* Revision 1.6 2001/11/19 01:54:14 steve
* Port close cropping behavior from mcrgb
* Move window array reset to libmc.
*
* Revision 1.5 2001/07/25 03:10:48 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
@@ -53,12 +115,5 @@ NetESFunc* NetESFunc::dup_expr() const
* Revision 1.3 2000/05/04 03:37:58 steve
* Add infrastructure for system functions, move
* $time to that structure and add $random.
*
* Revision 1.2 2000/02/23 02:56:54 steve
* Macintosh compilers do not support ident.
*
* Revision 1.1 1999/11/27 19:07:57 steve
* Support the creation of scopes.
*
*/
+13 -6
View File
@@ -16,8 +16,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: elab_anet.cc,v 1.3 2001/07/25 03:10:48 steve Exp $"
#ifdef HAVE_CVS_IDENT
#ident "$Id: elab_anet.cc,v 1.5 2002/08/12 01:34:58 steve Exp $"
#endif
# include "config.h"
@@ -104,10 +104,10 @@ NetNet* PEConcat::elaborate_anet(Design*des, NetScope*scope) const
NetNet* PEIdent::elaborate_anet(Design*des, NetScope*scope) const
{
NetNet*sig = des->find_signal(scope, text_);
NetNet*sig = des->find_signal(scope, path_);
if (sig == 0) {
if (NetMemory*mem = des->find_memory(scope, text_)) {
if (NetMemory*mem = des->find_memory(scope, path_)) {
cerr << get_line() << ": error: memories not allowed "
<< "on left side of procedural continuous "
<< "asignment." << endl;
@@ -115,7 +115,7 @@ NetNet* PEIdent::elaborate_anet(Design*des, NetScope*scope) const
return 0;
}
cerr << get_line() << ": error: reg ``" << text_ << "'' "
cerr << get_line() << ": error: reg ``" << path_ << "'' "
<< "is undefined in this scope." << endl;
des->errors += 1;
return 0;
@@ -127,7 +127,7 @@ NetNet* PEIdent::elaborate_anet(Design*des, NetScope*scope) const
break;
default:
cerr << get_line() << ": error: " << text_ << " is not "
cerr << get_line() << ": error: " << path_ << " is not "
<< "a reg in this context." << endl;
des->errors += 1;
return 0;
@@ -149,6 +149,13 @@ NetNet* PEIdent::elaborate_anet(Design*des, NetScope*scope) const
/*
* $Log: elab_anet.cc,v $
* Revision 1.5 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.4 2001/12/03 04:47:14 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
*
* Revision 1.3 2001/07/25 03:10:48 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
+368 -105
View File
@@ -16,8 +16,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: elab_expr.cc,v 1.42 2001/07/29 22:22:40 steve Exp $"
#ifdef HAVE_CVS_IDENT
#ident "$Id: elab_expr.cc,v 1.66 2002/09/21 21:28:18 steve Exp $"
#endif
# include "config.h"
@@ -28,7 +28,7 @@
# include "netmisc.h"
# include "util.h"
NetExpr* PExpr::elaborate_expr(Design*des, NetScope*) const
NetExpr* PExpr::elaborate_expr(Design*des, NetScope*, bool) const
{
cerr << get_line() << ": internal error: I do not know how to elaborate"
<< " expression. " << endl;
@@ -43,8 +43,11 @@ NetExpr* PExpr::elaborate_expr(Design*des, NetScope*) const
* and right sides, and creating one of a variety of different NetExpr
* types.
*/
NetEBinary* PEBinary::elaborate_expr(Design*des, NetScope*scope) const
NetEBinary* PEBinary::elaborate_expr(Design*des, NetScope*scope, bool) const
{
assert(left_);
assert(right_);
NetExpr*lp = left_->elaborate_expr(des, scope);
NetExpr*rp = right_->elaborate_expr(des, scope);
if ((lp == 0) || (rp == 0)) {
@@ -53,6 +56,7 @@ NetEBinary* PEBinary::elaborate_expr(Design*des, NetScope*scope) const
return 0;
}
/* If either expression can be evaluated ahead of time, then
do so. This can prove helpful later. */
{ NetExpr*tmp;
@@ -61,6 +65,7 @@ NetEBinary* PEBinary::elaborate_expr(Design*des, NetScope*scope) const
delete lp;
lp = tmp;
}
tmp = rp->eval_tree();
if (tmp) {
delete rp;
@@ -115,7 +120,8 @@ NetEBinary* PEBinary::elaborate_expr_base_(Design*des,
case '^':
case '&':
case '|':
case 'O':
case 'O': // NOR (~|)
case 'A': // NAND (~&)
case 'X':
tmp = new NetEBBits(op_, lp, rp);
tmp->set_line(*this);
@@ -157,10 +163,60 @@ NetEBinary* PEBinary::elaborate_expr_base_(Design*des,
*/
NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope) const
{
/* Catch the special case that the system function is the
$signed function. This function is special, in that it does
not lead to executable code but takes the single parameter
and makes it into a signed expression. No bits are changed,
it just changes the interpretation. */
if (strcmp(path_.peek_name(0), "$signed") == 0) {
if ((parms_.count() != 1) || (parms_[0] == 0)) {
cerr << get_line() << ": error: The $signed() function "
<< "takes exactly one(1) argument." << endl;
des->errors += 1;
return 0;
}
PExpr*expr = parms_[0];
NetExpr*sub = expr->elaborate_expr(des, scope, true);
sub->cast_signed(true);
return sub;
}
/* Interpret the internal $sizeof system function to return
the bit width of the sub-expression. The value of the
sub-expression is not used, so the expression itself can be
deleted. */
if ((strcmp(path_.peek_name(0), "$sizeof") == 0)
|| (strcmp(path_.peek_name(0), "$bits") == 0)) {
if ((parms_.count() != 1) || (parms_[0] == 0)) {
cerr << get_line() << ": error: The $bits() function "
<< "takes exactly one(1) argument." << endl;
des->errors += 1;
return 0;
}
if (strcmp(path_.peek_name(0), "$sizeof") == 0)
cerr << get_line() << ": warning: $sizeof is deprecated."
<< " Use $bits() instead." << endl;
PExpr*expr = parms_[0];
NetExpr*sub = expr->elaborate_expr(des, scope, true);
verinum val (sub->expr_width(), 8*sizeof(unsigned));
delete sub;
sub = new NetEConst(val);
sub->set_line(*this);
return sub;
}
unsigned wid = 32;
if (name_ == "$time")
if (strcmp(path_.peek_name(0), "$time") == 0)
wid = 64;
if (strcmp(path_.peek_name(0), "$stime") == 0)
wid = 32;
/* How many parameters are there? The Verilog language allows
@@ -175,7 +231,7 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope) const
if ((nparms == 1) && (parms_[0] == 0))
nparms = 0;
NetESFunc*fun = new NetESFunc(name_, wid, nparms);
NetESFunc*fun = new NetESFunc(path_.peek_name(0), wid, nparms);
/* Now run through the expected parameters. If we find that
there are missing parameters, print an error message.
@@ -188,7 +244,7 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope) const
for (unsigned idx = 0 ; idx < nparms ; idx += 1) {
PExpr*expr = parms_[idx];
if (expr) {
NetExpr*tmp1 = expr->elaborate_expr(des, scope);
NetExpr*tmp1 = expr->elaborate_expr(des, scope, true);
if (NetExpr*tmp2 = tmp1->eval_tree()) {
delete tmp1;
fun->parm(idx, tmp2);
@@ -203,7 +259,8 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope) const
}
if (missing_parms > 0) {
cerr << get_line() << ": error: The function " << name_
cerr << get_line() << ": error: The function "
<< path_.peek_name(0)
<< " has been called with empty parameters." << endl;
cerr << get_line() << ": : Verilog doesn't allow "
<< "passing empty parameters to functions." << endl;
@@ -213,47 +270,31 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope) const
return fun;
}
NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope) const
NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope, bool) const
{
if (name_[0] == '$')
if (path_.peek_name(0)[0] == '$')
return elaborate_sfunc_(des, scope);
NetFuncDef*def = des->find_function(scope, name_);
NetFuncDef*def = des->find_function(scope, path_);
if (def == 0) {
cerr << get_line() << ": error: No function " << name_ <<
cerr << get_line() << ": error: No function " << path_ <<
" in this context (" << scope->name() << ")." << endl;
des->errors += 1;
return 0;
}
assert(def);
NetScope*dscope = des->find_scope(def->name());
NetScope*dscope = def->scope();
assert(dscope);
/* How many parameters have I got? Normally the size of the
list is correct, but there is the special case of a list of
1 nil pointer. This is how the parser tells me of no
parameter. In other words, ``func()'' is 1 nil parameter. */
if (! check_call_matches_definition_(des, dscope))
return 0;
unsigned parms_count = parms_.count();
if ((parms_count == 1) && (parms_[0] == 0))
parms_count = 0;
if (dscope->type() != NetScope::FUNC) {
cerr << get_line() << ": error: Attempt to call scope "
<< dscope->name() << " as a function." << endl;
des->errors += 1;
return 0;
}
if ((parms_count+1) != dscope->func_def()->port_count()) {
cerr << get_line() << ": error: Function " << dscope->name()
<< " expects " << (dscope->func_def()->port_count()-1)
<< " parameters, you passed " << parms_count << "."
<< endl;
des->errors += 1;
return 0;
}
svector<NetExpr*> parms (parms_count);
@@ -275,7 +316,7 @@ NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope) const
}
if (missing_parms > 0) {
cerr << get_line() << ": error: The function " << name_
cerr << get_line() << ": error: The function " << path_
<< " has been called with empty parameters." << endl;
cerr << get_line() << ": : Verilog doesn't allow "
<< "passing empty parameters to functions." << endl;
@@ -291,11 +332,10 @@ NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope) const
dscope, in this case, is the scope of the function, so the
return value is the name within that scope. */
string rname = name_;
NetNet*res = des->find_signal(dscope, parse_last_name(rname));
NetNet*res = dscope->find_signal(dscope->basename());
if (res == 0) {
cerr << get_line() << ": internal error: Unable to locate "
"function return value for " << name_ << " in " <<
"function return value for " << path_ << " in " <<
def->name() << "." << endl;
des->errors += 1;
return 0;
@@ -309,9 +349,9 @@ NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope) const
}
NetExpr* PEConcat::elaborate_expr(Design*des, NetScope*scope) const
NetExpr* PEConcat::elaborate_expr(Design*des, NetScope*scope, bool) const
{
unsigned repeat = 1;
NetExpr* repeat = 0;
/* If there is a repeat expression, then evaluate the constant
value and set the repeat count. */
@@ -327,20 +367,21 @@ NetExpr* PEConcat::elaborate_expr(Design*des, NetScope*scope) const
cerr << get_line() << ": : The expression is: "
<< *tmp << endl;
des->errors += 1;
return 0;
}
repeat = rep->value().as_ulong();
repeat = rep;
}
/* Make the empty concat expression. */
NetEConcat*tmp = new NetEConcat(parms_.count(), repeat);
tmp->set_line(*this);
unsigned wid_sum = 0;
/* Elaborate all the parameters and attach them to the concat node. */
for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) {
assert(parms_[idx]);
NetExpr*ex = parms_[idx]->elaborate_expr(des, scope);
NetExpr*ex = elab_and_eval(des, scope, parms_[idx]);
if (ex == 0) continue;
ex->set_line(*parms_[idx]);
@@ -352,33 +393,159 @@ NetExpr* PEConcat::elaborate_expr(Design*des, NetScope*scope) const
des->errors += 1;
}
wid_sum += ex->expr_width();
tmp->set(idx, ex);
}
tmp->set_width(wid_sum * tmp->repeat());
return tmp;
}
NetExpr* PEFNumber::elaborate_expr(Design*des, NetScope*scope) const
NetExpr* PEFNumber::elaborate_expr(Design*des, NetScope*scope, bool) const
{
long val = value_->as_long();
return new NetEConst(verinum(val));
}
NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope) const
/*
* Elaborate an identifier in an expression. The identifier can be a
* parameter name, a signal name or a memory name. It can also be a
* scope name (Return a NetEScope) but only certain callers can use
* scope names. However, we still support it here.
*
* Function names are not handled here, they are detected by the
* parser and are elaborated by PECallFunction.
*
* The signal name may be escaped, but that affects nothing here.
*/
NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
bool sys_task_arg) const
{
assert(text_[0] != '$');
//string name = path+"."+text_;
assert(scope);
// If the identifier name is a parameter name, then return
// a reference to the parameter expression.
if (const NetExpr*ex = des->find_parameter(scope, text_)) {
if (const NetExpr*ex = des->find_parameter(scope, path_)) {
NetExpr*tmp;
if (dynamic_cast<const NetExpr*>(ex))
tmp = ex->dup_expr();
else
tmp = new NetEParam(des, scope, text_);
tmp = new NetEParam(des, scope, path_);
if (msb_ && lsb_) {
/* If the parameter has a part select, we support
it by pulling the right bits out and making a
sized unsigned constant. This code assumes the
lsb of a parameter is 0 and the msb is the
width of the parameter. */
verinum*lsn = lsb_->eval_const(des, scope);
verinum*msn = msb_->eval_const(des, scope);
if ((lsn == 0) || (msn == 0)) {
cerr << get_line() << ": error: "
"Part select expresions must be "
"constant expressions." << endl;
des->errors += 1;
return 0;
}
long lsb = lsn->as_long();
long msb = msn->as_long();
if ((lsb < 0) || (msb < lsb)) {
cerr << get_line() << ": error: invalid part "
<< "select: " << path_
<< "["<<msb<<":"<<lsb<<"]" << endl;
des->errors += 1;
return 0;
}
NetEConst*le = dynamic_cast<NetEConst*>(tmp);
assert(le);
verinum result (verinum::V0, msb-lsb+1, true);
verinum exl = le->value();
/* Pull the bits from the parameter, one at a
time. If the bit is within the range, simply
copy it to the result. If the bit is outside
the range, we sign extend signed unsized
numbers, zero extend unsigned unsigned numbers,
and X extend sized numbers. */
for (long idx = lsb ; idx <= msb ; idx += 1) {
if (idx < exl.len())
result.set(idx-lsb, exl.get(idx));
else if (exl.is_string())
result.set(idx-lsb, verinum::V0);
else if (exl.has_len())
result.set(idx-lsb, verinum::Vx);
else if (exl.has_sign())
result.set(idx-lsb, exl.get(exl.len()-1));
else
result.set(idx-lsb, verinum::V0);
}
/* If the input is a string, and the part select
is working on byte boundaries, then the result
can be made into a string. */
if (exl.is_string()
&& (lsb%8 == 0)
&& (result.len()%8 == 0))
result = verinum(result.as_string());
delete tmp;
tmp = new NetEConst(result);
} else if (msb_) {
/* Handle the case where a parameter has a bit
select attached to it. Generate a NetESelect
object to select the bit as desired. */
NetExpr*mtmp = msb_->elaborate_expr(des, scope);
if (! dynamic_cast<NetEConst*>(mtmp)) {
NetExpr*re = mtmp->eval_tree();
if (re) {
delete mtmp;
mtmp = re;
}
}
/* Let's first try to get constant values for both
the parameter and the bit select. If they are
both constant, then evaluate the bit select and
return instead a single-bit constant. */
NetEConst*le = dynamic_cast<NetEConst*>(tmp);
NetEConst*re = dynamic_cast<NetEConst*>(mtmp);
if (le && re) {
verinum lv = le->value();
verinum rv = re->value();
verinum::V rb = verinum::Vx;
long ridx = rv.as_long();
if ((ridx >= 0) && (ridx < lv.len())) {
rb = lv[ridx];
} else if ((ridx >= 0) && (!lv.has_len())) {
if (lv.has_sign())
rb = lv[lv.len()-1];
else
rb = verinum::V0;
}
NetEConst*re = new NetEConst(verinum(rb, 1));
delete tmp;
delete mtmp;
tmp = re;
} else {
NetESelect*stmp = new NetESelect(tmp, mtmp, 1);
tmp->set_line(*this);
tmp = stmp;
}
}
tmp->set_line(*this);
return tmp;
@@ -386,7 +553,7 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope) const
// If the identifier names a signal (a register or wire)
// then create a NetESignal node to handle it.
if (NetNet*net = des->find_signal(scope, text_)) {
if (NetNet*net = des->find_signal(scope, path_)) {
// If this is a part select of a signal, then make a new
// temporary signal that is connected to just the
@@ -394,8 +561,8 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope) const
// the foo[msb:lsb] expression in the original.
if (lsb_) {
assert(msb_);
verinum*lsn = lsb_->eval_const(des, scope->name());
verinum*msn = msb_->eval_const(des, scope->name());
verinum*lsn = lsb_->eval_const(des, scope);
verinum*msn = msb_->eval_const(des, scope);
if ((lsn == 0) || (msn == 0)) {
cerr << get_line() << ": error: "
"Part select expresions must be "
@@ -460,17 +627,27 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope) const
// to the part select, so that I save the effort of
// making a mux part in the netlist.
verinum*msn;
if (msb_ && (msn = msb_->eval_const(des, scope->name()))) {
if (msb_ && (msn = msb_->eval_const(des, scope))) {
assert(idx_ == 0);
unsigned long msv = msn->as_ulong();
unsigned idx = net->sb_to_idx(msv);
if (idx >= net->pin_count()) {
cerr << get_line() << ": internal error: "
<< "bit " << msv << " out of range of net "
/* The bit select is out of range of the
vector. This is legal, but returns a
constant 1'bx value. */
verinum x (verinum::Vx);
NetEConst*tmp = new NetEConst(x);
tmp->set_line(*this);
cerr << get_line() << ": warning: Bit select ["
<< msv << "] out of range of vector "
<< net->name() << "[" << net->msb()
<< ":" << net->lsb() << "]." << endl;
return 0;
cerr << get_line() << ": : Replacing "
<< "expression with a constant 1'bx." << endl;
delete msn;
return tmp;
}
NetESignal*tmp = new NetESignal(net, idx, idx);
@@ -500,12 +677,25 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope) const
// If the identifier names a memory, then this is a
// memory reference and I must generate a NetEMemory
// object to handle it.
if (NetMemory*mem = des->find_memory(scope, text_)) {
if (NetMemory*mem = des->find_memory(scope, path_)) {
if (msb_ == 0) {
NetEMemory*node = new NetEMemory(mem);
node->set_line(*this);
return node;
// If this memory is an argument to a system task,
// then it is OK for it to not have an index.
if (sys_task_arg) {
NetEMemory*node = new NetEMemory(mem);
node->set_line(*this);
return node;
}
// If it is not a simple system task argument,
// this a missing index is an error.
cerr << get_line() << ": error: memory " << mem->name()
<< " needs an index in this context." << endl;
des->errors += 1;
return 0;
}
assert(msb_ != 0);
if (lsb_) {
cerr << get_line() << ": error: part select of a memory: "
@@ -518,7 +708,7 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope) const
assert(idx_ == 0);
NetExpr*i = msb_->elaborate_expr(des, scope);
if (msb_ && i == 0) {
cerr << get_line() << ": error: Unable to exaborate "
cerr << get_line() << ": error: Unable to elaborate "
"index expression `" << *msb_ << "'" << endl;
des->errors += 1;
return 0;
@@ -532,16 +722,17 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope) const
// Finally, if this is a scope name, then return that. Look
// first to see if this is a name of a local scope. Failing
// that, search globally for a heirarchical name.
if (NetScope*nsc = scope->child(text_)) {
NetEScope*tmp = new NetEScope(nsc);
tmp->set_line(*this);
return tmp;
}
if ((path_.peek_name(1) == 0))
if (NetScope*nsc = scope->child(path_.peek_name(0))) {
NetEScope*tmp = new NetEScope(nsc);
tmp->set_line(*this);
return tmp;
}
// NOTE: This search pretty much assumes that text_ is a
// complete hierarchical name, since there is no mention of
// the current scope in the call to find_scope.
if (NetScope*nsc = des->find_scope(text_)) {
if (NetScope*nsc = des->find_scope(path_)) {
NetEScope*tmp = new NetEScope(nsc);
tmp->set_line(*this);
return tmp;
@@ -549,12 +740,12 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope) const
// I cannot interpret this identifier. Error message.
cerr << get_line() << ": error: Unable to bind wire/reg/memory "
"`" << text_ << "' in `" << scope->name() << "'" << endl;
"`" << path_ << "' in `" << scope->name() << "'" << endl;
des->errors += 1;
return 0;
}
NetEConst* PENumber::elaborate_expr(Design*des, NetScope*) const
NetEConst* PENumber::elaborate_expr(Design*des, NetScope*, bool) const
{
assert(value_);
NetEConst*tmp = new NetEConst(*value_);
@@ -562,7 +753,7 @@ NetEConst* PENumber::elaborate_expr(Design*des, NetScope*) const
return tmp;
}
NetEConst* PEString::elaborate_expr(Design*des, NetScope*) const
NetEConst* PEString::elaborate_expr(Design*des, NetScope*, bool) const
{
NetEConst*tmp = new NetEConst(value());
tmp->set_line(*this);
@@ -574,7 +765,7 @@ NetEConst* PEString::elaborate_expr(Design*des, NetScope*) const
* parsed so I can presume that they exist, and call elaboration
* methods. If any elaboration fails, then give up and return 0.
*/
NetETernary*PETernary::elaborate_expr(Design*des, NetScope*scope) const
NetETernary*PETernary::elaborate_expr(Design*des, NetScope*scope, bool) const
{
assert(expr_);
assert(tru_);
@@ -601,7 +792,7 @@ NetETernary*PETernary::elaborate_expr(Design*des, NetScope*scope) const
return res;
}
NetEUnary* PEUnary::elaborate_expr(Design*des, NetScope*scope) const
NetExpr* PEUnary::elaborate_expr(Design*des, NetScope*scope, bool) const
{
NetExpr*ip = expr_->elaborate_expr(des, scope);
if (ip == 0) return 0;
@@ -610,13 +801,69 @@ NetEUnary* PEUnary::elaborate_expr(Design*des, NetScope*scope) const
* just like in PEBinary::elaborate_expr() ?
*/
NetEUnary*tmp;
NetExpr*tmp;
switch (op_) {
default:
tmp = new NetEUnary(op_, ip);
tmp->set_line(*this);
break;
case '-':
if (NetEConst*ipc = dynamic_cast<NetEConst*>(ip)) {
verinum val = ipc->value();
verinum zero (verinum::V0, val.len(), val.has_len());
val = zero - val;
val.has_sign(ipc->has_sign());
tmp = new NetEConst(val);
delete ip;
} else {
tmp = new NetEUnary(op_, ip);
tmp->set_line(*this);
}
break;
case '+':
tmp = ip;
break;
case '!': // Logical NOT
/* If the operand to unary ! is a constant, then I can
evaluate this expression here and return a logical
constant in its place. */
if (NetEConst*ipc = dynamic_cast<NetEConst*>(ip)) {
verinum val = ipc->value();
unsigned v1 = 0;
unsigned vx = 0;
for (unsigned idx = 0 ; idx < val.len() ; idx += 1)
switch (val[idx]) {
case verinum::V0:
break;
case verinum::V1:
v1 += 1;
break;
default:
vx += 1;
break;
}
verinum::V res;
if (v1 > 0)
res = verinum::V0;
else if (vx > 0)
res = verinum::Vx;
else
res = verinum::V1;
verinum vres (res, 1, true);
tmp = new NetEConst(vres);
tmp->set_line(*this);
delete ip;
} else {
tmp = new NetEUReduce(op_, ip);
tmp->set_line(*this);
}
break;
case '&': // Reduction AND
case '|': // Reduction OR
case '^': // Reduction XOR
@@ -626,60 +873,76 @@ NetEUnary* PEUnary::elaborate_expr(Design*des, NetScope*scope) const
tmp = new NetEUReduce(op_, ip);
tmp->set_line(*this);
break;
case '~':
tmp = new NetEUBits(op_, ip);
tmp->set_line(*this);
break;
}
return tmp;
}
/*
* $Log: elab_expr.cc,v $
* Revision 1.42 2001/07/29 22:22:40 steve
* support local reference to scope in expressions.
* Revision 1.66 2002/09/21 21:28:18 steve
* Allow constant bit selects out of range.
*
* Revision 1.41 2001/07/27 04:51:44 steve
* Handle part select expressions as variants of
* NetESignal/IVL_EX_SIGNAL objects, instead of
* creating new and useless temporary signals.
* Revision 1.65 2002/09/18 04:08:45 steve
* Spelling errors.
*
* Revision 1.40 2001/07/25 03:10:48 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
* Revision 1.64 2002/09/12 15:49:43 steve
* Add support for binary nand operator.
*
* Revision 1.39 2001/06/30 21:28:35 steve
* Detect parameter mismatches.
* Revision 1.63 2002/08/19 02:39:16 steve
* Support parameters with defined ranges.
*
* Revision 1.38 2001/06/23 19:53:03 steve
* Look up functor return register with tail of name.
* Revision 1.62 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.37 2001/04/06 02:28:02 steve
* Generate vvp code for functions with ports.
* Revision 1.61 2002/06/14 21:38:41 steve
* Fix expression width for repeat concatenations.
*
* Revision 1.36 2001/02/10 20:29:39 steve
* In the context of range declarations, use elab_and_eval instead
* of the less robust eval_const methods.
* Revision 1.60 2002/05/24 00:44:54 steve
* Add support for $bits (SystemVerilog)
*
* Revision 1.35 2001/02/09 05:44:23 steve
* support evaluation of constant < in expressions.
* Revision 1.59 2002/05/06 02:30:27 steve
* Allow parameters in concatenation of widths are defined.
*
* Revision 1.34 2001/01/14 23:04:55 steve
* Generalize the evaluation of floating point delays, and
* get it working with delay assignment statements.
* Revision 1.58 2002/05/05 21:11:49 steve
* Put off evaluation of concatenation repeat expresions
* until after parameters are defined. This allows parms
* to be used in repeat expresions.
*
* Allow parameters to be referenced by hierarchical name.
* Add the builtin $signed system function.
*
* Revision 1.33 2001/01/13 22:20:08 steve
* Parse parameters within nested scopes.
* Revision 1.57 2002/04/27 05:03:46 steve
* Preserve stringiness string part select and concatenation.
*
* Revision 1.32 2001/01/02 04:21:13 steve
* Support a bunch of unary operators in parameter expressions.
* Revision 1.56 2002/04/27 02:38:04 steve
* Support selecting bits from parameters.
*
* Revision 1.31 2000/12/10 22:01:35 steve
* Support decimal constants in behavioral delays.
* Revision 1.55 2002/04/25 05:04:31 steve
* Evaluate constant bit select of constants.
*
* Revision 1.30 2000/11/29 05:24:00 steve
* synthesis for unary reduction ! and N operators.
* Revision 1.54 2002/04/14 21:16:48 steve
* Evaluate logical not at elaboration time.
*
* Revision 1.53 2002/04/14 03:55:25 steve
* Precalculate unary - if possible.
*
* Revision 1.52 2002/04/13 02:33:17 steve
* Detect missing indices to memories (PR#421)
*
* Revision 1.51 2002/03/09 02:10:22 steve
* Add the NetUserFunc netlist node.
*
* Revision 1.50 2002/01/28 00:52:41 steve
* Add support for bit select of parameters.
* This leads to a NetESelect node and the
* vvp code generator to support that.
*
* Revision 1.49 2002/01/11 05:25:45 steve
* The stime system function is 32bits.
*/
+104 -22
View File
@@ -16,8 +16,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: elab_lval.cc,v 1.14 2001/08/25 23:50:02 steve Exp $"
#ifdef HAVE_CVS_IDENT
#ident "$Id: elab_lval.cc,v 1.23 2002/11/21 23:27:51 steve Exp $"
#endif
# include "config.h"
@@ -67,7 +67,7 @@
*/
NetAssign_* PExpr::elaborate_lval(Design*des, NetScope*scope) const
{
NetNet*ll = elaborate_net(des, scope->name(), 0, 0, 0, 0);
NetNet*ll = 0;
if (ll == 0) {
cerr << get_line() << ": Assignment l-value too complex."
<< endl;
@@ -135,25 +135,24 @@ NetAssign_* PEIdent::elaborate_lval(Design*des, NetScope*scope) const
{
/* Get the signal referenced by the identifier, and make sure
it is a register. (Wires are not allows in this context. */
NetNet*reg = des->find_signal(scope, name());
NetNet*reg = des->find_signal(scope, path_);
if (reg == 0) {
NetMemory*mem = des->find_memory(scope, name());
if (mem != 0) {
cerr << get_line() << ": sorry: I cannot handle "
<< "memories in this l-value context." << endl;
} else {
cerr << get_line() << ": error: Could not find variable ``"
<< name() << "'' in ``" << scope->name() <<
"''" << endl;
}
NetMemory*mem = des->find_memory(scope, path_);
if (mem != 0)
return elaborate_mem_lval_(des, scope, mem);
cerr << get_line() << ": error: Could not find variable ``"
<< path_ << "'' in ``" << scope->name() <<
"''" << endl;
des->errors += 1;
return 0;
}
assert(reg);
if (reg->type() != NetNet::REG) {
cerr << get_line() << ": error: " << name() <<
cerr << get_line() << ": error: " << path_ <<
" is not a reg/integer/time in " << scope->name() <<
"." << endl;
des->errors += 1;
@@ -168,19 +167,23 @@ NetAssign_* PEIdent::elaborate_lval(Design*des, NetScope*scope) const
two bit select expressions, and both must be
constant. Evaluate them and pass the results back to
the caller. */
verinum*vl = lsb_->eval_const(des, scope->name());
verinum*vl = lsb_->eval_const(des, scope);
if (vl == 0) {
cerr << lsb_->get_line() << ": error: "
"Part select expressions must be constant: "
<< *lsb_;
"Part select expressions must be constant."
<< endl;
cerr << lsb_->get_line() << ": : This lsb expression "
"violates the rule: " << *lsb_ << endl;
des->errors += 1;
return 0;
}
verinum*vm = msb_->eval_const(des, scope->name());
if (vl == 0) {
verinum*vm = msb_->eval_const(des, scope);
if (vm == 0) {
cerr << msb_->get_line() << ": error: "
"Part select expressions must be constant: "
<< *msb_;
"Part select expressions must be constant."
<< endl;
cerr << msb_->get_line() << ": : This msb expression "
"violates the rule: " << *msb_ << endl;
des->errors += 1;
return 0;
}
@@ -197,7 +200,7 @@ NetAssign_* PEIdent::elaborate_lval(Design*des, NetScope*scope) const
expression it not constant, then return the
expression as a mux. */
assert(lsb_ == 0);
verinum*v = msb_->eval_const(des, scope->name());
verinum*v = msb_->eval_const(des, scope);
if (v == 0) {
NetExpr*m = msb_->elaborate_expr(des, scope);
assert(m);
@@ -275,8 +278,87 @@ NetAssign_* PEIdent::elaborate_lval(Design*des, NetScope*scope) const
return lv;
}
NetAssign_* PEIdent::elaborate_mem_lval_(Design*des, NetScope*scope,
NetMemory*mem) const
{
if (msb_ == 0) {
cerr << get_line() << ": error: Assign to memory \""
<< mem->name() << "\" requires a word select index."
<< endl;
des->errors += 1;
return 0;
}
if (msb_ && lsb_) {
cerr << get_line() << ": error: Cannot use part select on "
<< "memory \"" << mem->name() << ".\"" << endl;
des->errors += 1;
return 0;
}
assert(msb_ && !lsb_);
NetExpr*ix = msb_->elaborate_expr(des, scope);
if (ix == 0)
return 0;
/* Evaluate the memory index expression down as must as
possible. Ideally, we can get it down to a constant. */
if (! dynamic_cast<NetEConst*>(ix)) {
NetExpr*tmp = ix->eval_tree();
if (tmp) {
tmp->set_line(*ix);
delete ix;
ix = tmp;
}
}
NetAssign_*lv = new NetAssign_(mem);
lv->set_bmux(ix);
lv->set_part(0, mem->width());
return lv;
}
NetAssign_* PENumber::elaborate_lval(Design*des, NetScope*) const
{
cerr << get_line() << ": error: Constant values not allowed "
<< "in l-value expressions." << endl;
des->errors += 1;
return 0;
}
/*
* $Log: elab_lval.cc,v $
* Revision 1.23 2002/11/21 23:27:51 steve
* Precalculate indices to l-value arrays.
*
* Revision 1.22 2002/11/21 18:15:40 steve
* Fix const test of msb in assignment l-values.
*
* Revision 1.21 2002/11/02 01:10:49 steve
* Detect memories without work index in l-value.
*
* Revision 1.20 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.19 2002/06/04 05:38:44 steve
* Add support for memory words in l-value of
* blocking assignments, and remove the special
* NetAssignMem class.
*
* Revision 1.18 2002/03/09 04:02:26 steve
* Constant expressions are not l-values for task ports.
*
* Revision 1.17 2001/12/03 04:47:14 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
*
* Revision 1.16 2001/11/08 05:15:50 steve
* Remove string paths from PExpr elaboration.
*
* Revision 1.15 2001/11/07 04:01:59 steve
* eval_const uses scope instead of a string path.
*
* Revision 1.14 2001/08/25 23:50:02 steve
* Change the NetAssign_ class to refer to the signal
* instead of link into the netlist. This is faster
+715 -536
View File
File diff suppressed because it is too large Load Diff
+81 -22
View File
@@ -16,8 +16,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: elab_pexpr.cc,v 1.9 2001/07/25 03:10:49 steve Exp $"
#ifdef HAVE_CVS_IDENT
#ident "$Id: elab_pexpr.cc,v 1.18 2002/12/05 02:14:33 steve Exp $"
#endif
# include "config.h"
@@ -66,28 +66,21 @@ NetExpr*PEBinary::elaborate_pexpr (Design*des, NetScope*scope) const
*/
NetEConcat* PEConcat::elaborate_pexpr(Design*des, NetScope*scope) const
{
unsigned repeat = 1;
NetExpr* repeat = 0;
/* If there is a repeat expression, then evaluate the constant
value and set the repeat count.
XXXX Potential bug XXX In principle, the repeat expression
can have a parameter name in it. Since where are in the
working of parameters now, we will not be able to
accurately evaluate such expressions. So eventually, I will
need to be able to defer the evaluation of the expression. */
value and set the repeat count. */
if (repeat_) {
verinum*vrep = repeat_->eval_const(des, scope->name());
if (vrep == 0) {
repeat = repeat_->elaborate_pexpr(des, scope);
if (repeat == 0) {
cerr << get_line() << ": error: "
"concatenation repeat expression cannot be evaluated."
<< endl;
des->errors += 1;
return 0;
}
repeat = vrep->as_ulong();
delete vrep;
/* continue on even if the repeat expression doesn't
work, as we can find more errors. */
}
/* Make the empty concat expression. */
@@ -101,7 +94,22 @@ NetEConcat* PEConcat::elaborate_pexpr(Design*des, NetScope*scope) const
assert(parms_[idx]);
NetExpr*ex = parms_[idx]->elaborate_pexpr(des, scope);
if (ex == 0) continue;
ex->set_line(*parms_[idx]);
if (dynamic_cast<NetEParam*>(ex)) {
/* If this parameter is a NetEParam, then put off
the width check for later. */
} else if (! ex->has_width()) {
cerr << ex->get_line() << ": error: operand of "
<< "concatenation has indefinite width: "
<< *ex << endl;
des->errors += 1;
}
tmp->set(idx, ex);
}
@@ -121,25 +129,42 @@ NetExpr*PEFNumber::elaborate_pexpr(Design*des, NetScope*scope) const
*/
NetExpr*PEIdent::elaborate_pexpr(Design*des, NetScope*scope) const
{
string path = text_;
string name = parse_last_name(path);
hname_t path = path_;
char*name = path.remove_tail_name();
NetScope*pscope = scope;
if (path != "")
if (path.peek_name(0))
pscope = des->find_scope(scope, path);
assert(pscope);
const NetExpr*ex = pscope->get_parameter(name);
if (ex == 0) {
cerr << get_line() << ": error: identifier ``" << text_ <<
cerr << get_line() << ": error: identifier ``" << path_ <<
"'' is not a parameter in " << scope->name() << "." << endl;
des->errors += 1;
delete name;
return 0;
}
NetExpr*res = new NetEParam(des, pscope, name);
NetExpr*res = new NetEParam(des, pscope, hname_t(name));
assert(res);
delete name;
assert(idx_ == 0);
if (msb_ && lsb_) {
cerr << get_line() << ": sorry: Cannot part select "
"bits of parameters." << endl;
des->errors += 1;
} else if (msb_) {
/* We have here a bit select. Insert a NetESelect node
to handle it. */
NetExpr*tmp = msb_->elaborate_pexpr(des, scope);
if (tmp != 0) {
res = new NetESelect(res, tmp, 1);
}
}
return res;
}
@@ -203,6 +228,40 @@ NetExpr*PEUnary::elaborate_pexpr (Design*des, NetScope*scope) const
/*
* $Log: elab_pexpr.cc,v $
* Revision 1.18 2002/12/05 02:14:33 steve
* Support bit select in constant expressions.
*
* Revision 1.17 2002/11/09 01:40:19 steve
* Postpone parameter width check to evaluation.
*
* Revision 1.16 2002/08/12 01:34:59 steve
* conditional ident string using autoconfig.
*
* Revision 1.15 2002/05/06 02:30:27 steve
* Allow parameters in concatenation of widths are defined.
*
* Revision 1.14 2002/05/05 21:11:50 steve
* Put off evaluation of concatenation repeat expresions
* until after parameters are defined. This allows parms
* to be used in repeat expresions.
*
* Add the builtin $signed system function.
*
* Revision 1.13 2002/01/28 00:52:41 steve
* Add support for bit select of parameters.
* This leads to a NetESelect node and the
* vvp code generator to support that.
*
* Revision 1.12 2001/12/03 04:47:14 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
*
* Revision 1.11 2001/11/07 04:01:59 steve
* eval_const uses scope instead of a string path.
*
* Revision 1.10 2001/10/07 03:38:08 steve
* parameter names do not have defined size.
*
* Revision 1.9 2001/07/25 03:10:49 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
+99 -32
View File
@@ -16,8 +16,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: elab_scope.cc,v 1.9 2001/07/25 03:10:49 steve Exp $"
#ifdef HAVE_CVS_IDENT
#ident "$Id: elab_scope.cc,v 1.17 2002/10/19 22:59:49 steve Exp $"
#endif
# include "config.h"
@@ -54,7 +54,8 @@ bool Module::elaborate_scope(Design*des, NetScope*scope) const
// the pform and just place a NetEParam placeholder in the
// place of the elaborated expression.
typedef map<string,PExpr*>::const_iterator mparm_it_t;
typedef map<string,param_expr_t>::const_iterator mparm_it_t;
typedef map<hname_t,PExpr*>::const_iterator hparm_it_t;
// This loop scans the parameters in the module, and creates
@@ -63,13 +64,21 @@ bool Module::elaborate_scope(Design*des, NetScope*scope) const
for (mparm_it_t cur = parameters.begin()
; cur != parameters.end() ; cur ++) {
scope->set_parameter((*cur).first, new NetEParam);
NetEParam*tmp = new NetEParam;
if ((*cur).second.msb)
tmp->cast_signed( (*cur).second.signed_flag );
scope->set_parameter((*cur).first, tmp, 0, 0, false);
}
for (mparm_it_t cur = localparams.begin()
; cur != localparams.end() ; cur ++) {
scope->set_parameter((*cur).first, new NetEParam);
NetEParam*tmp = new NetEParam;
if ((*cur).second.msb)
tmp->cast_signed( (*cur).second.signed_flag );
scope->set_parameter((*cur).first, tmp, 0, 0, false);
}
@@ -81,11 +90,29 @@ bool Module::elaborate_scope(Design*des, NetScope*scope) const
for (mparm_it_t cur = parameters.begin()
; cur != parameters.end() ; cur ++) {
PExpr*ex = (*cur).second;
PExpr*ex = (*cur).second.expr;
assert(ex);
NetExpr*val = ex->elaborate_pexpr(des, scope);
val = scope->set_parameter((*cur).first, val);
NetExpr*msb = 0;
NetExpr*lsb = 0;
bool signed_flag = false;
/* If the parameter declaration includes msb and lsb,
then use them to calculate a width for the
result. Then make sure the constant expression of the
parameter value is coerced to have the correct
and defined width. */
if ((*cur).second.msb) {
msb = (*cur).second.msb ->elaborate_pexpr(des, scope);
assert(msb);
lsb = (*cur).second.lsb ->elaborate_pexpr(des, scope);
signed_flag = (*cur).second.signed_flag;
}
val->cast_signed(signed_flag);
val = scope->set_parameter((*cur).first, val,
msb, lsb, signed_flag);
assert(val);
delete val;
}
@@ -93,11 +120,11 @@ bool Module::elaborate_scope(Design*des, NetScope*scope) const
for (mparm_it_t cur = localparams.begin()
; cur != localparams.end() ; cur ++) {
PExpr*ex = (*cur).second;
PExpr*ex = (*cur).second.expr;
assert(ex);
NetExpr*val = ex->elaborate_pexpr(des, scope);
val = scope->set_parameter((*cur).first, val);
val = scope->set_parameter((*cur).first, val, 0, 0, false);
assert(val);
delete val;
}
@@ -112,7 +139,7 @@ bool Module::elaborate_scope(Design*des, NetScope*scope) const
// here becuase the parameter receiving the assignment may be
// in a scope not discovered by this pass.
for (mparm_it_t cur = defparms.begin()
for (hparm_it_t cur = defparms.begin()
; cur != defparms.end() ; cur ++ ) {
PExpr*ex = (*cur).second;
@@ -134,7 +161,7 @@ bool Module::elaborate_scope(Design*des, NetScope*scope) const
for (tasks_it_t cur = tasks_.begin()
; cur != tasks_.end() ; cur ++ ) {
NetScope*task_scope = new NetScope(scope, (*cur).first,
NetScope*task_scope = new NetScope(scope, (*cur).first.c_str(),
NetScope::TASK);
(*cur).second->elaborate_scope(des, task_scope);
}
@@ -149,7 +176,7 @@ bool Module::elaborate_scope(Design*des, NetScope*scope) const
for (funcs_it_t cur = funcs_.begin()
; cur != funcs_.end() ; cur ++ ) {
NetScope*func_scope = new NetScope(scope, (*cur).first,
NetScope*func_scope = new NetScope(scope, (*cur).first.c_str(),
NetScope::FUNC);
(*cur).second->elaborate_scope(des, func_scope);
}
@@ -197,7 +224,7 @@ void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const
{
if (get_name() == "") {
cerr << get_line() << ": error: Instantiation of module "
<< mod->get_name() << " requires an instance name." << endl;
<< mod->mod_name() << " requires an instance name." << endl;
des->errors += 1;
return;
}
@@ -205,13 +232,11 @@ void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const
// Missing module instance names have already been rejected.
assert(get_name() != "");
string path = sc->name();
// Check for duplicate scopes. Simply look up the scope I'm
// about to create, and if I find it then somebody beat me to
// it.
if (NetScope*tmp = des->find_scope(path + "." + get_name())) {
if (NetScope*tmp = sc->child(get_name())) {
cerr << get_line() << ": error: Instance/Scope name " <<
get_name() << " already used in this context." <<
endl;
@@ -227,11 +252,11 @@ void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const
if (scn->type() != NetScope::MODULE)
continue;
if (mod->get_name() != scn->module_name())
if (strcmp(mod->mod_name(), scn->module_name()) != 0)
continue;
cerr << get_line() << ": error: You cannot instantiate "
<< "module " << mod->get_name() << " within itself." << endl;
<< "module " << mod->mod_name() << " within itself." << endl;
cerr << get_line() << ": : The offending instance is "
<< sc->name() << "." << get_name() << " within "
@@ -242,8 +267,8 @@ void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const
}
// Create the new scope as a MODULE with my name.
NetScope*my_scope = new NetScope(sc, get_name(), NetScope::MODULE);
my_scope->set_module_name(mod->get_name().c_str());
NetScope*my_scope = new NetScope(sc, get_name().c_str(), NetScope::MODULE);
my_scope->set_module_name(mod->mod_name());
// Set time units and precision.
my_scope->time_unit(mod->time_unit);
@@ -257,8 +282,10 @@ void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const
// later.)
mod->elaborate_scope(des, my_scope);
// Look for module parameter replacements. This map receives
// those replacements.
// Look for module parameter replacements. The "replace" map
// maps parameter name to replacement expression that is
// passed. It is built up by the ordered overrices or named
// overrides.
typedef map<string,PExpr*>::const_iterator mparm_it_t;
map<string,PExpr*> replace;
@@ -272,12 +299,18 @@ void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const
if (overrides_) {
assert(parms_ == 0);
list<string>::const_iterator cur = mod->param_names.begin();
for (unsigned idx = 0
; idx < overrides_->count()
; idx += 1, cur++) {
replace[*cur] = (*overrides_)[idx];
}
unsigned idx = 0;
for (;;) {
if (idx >= overrides_->count())
break;
if (cur == mod->param_names.end())
break;
replace[*cur] = (*overrides_)[idx];
idx += 1;
cur ++;
}
}
// Named parameter overrides carry a name with each override
@@ -299,16 +332,21 @@ void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const
PExpr*tmp = (*cur).second;
NetExpr*val = tmp->elaborate_pexpr(des, sc);
val = my_scope->set_parameter((*cur).first, val);
assert(val);
delete val;
bool flag = my_scope->replace_parameter((*cur).first, val);
if (! flag) {
cerr << val->get_line() << ": warning: parameter "
<< (*cur).first << " not found in "
<< sc->name() << "." << endl;
}
}
}
/*
* The isn't really able to create new scopes, but it does create the
* event name in the current scope, so can be done during the
* elaborate_scope scan.
* elaborate_scope scan. Note that the name_ of the PEvent object has
* no hierarchy, but neither does the NetEvent, until it is stored in
* the NetScope object.
*/
void PEvent::elaborate_scope(Design*des, NetScope*scope) const
{
@@ -324,6 +362,9 @@ void PFunction::elaborate_scope(Design*des, NetScope*scope) const
void PTask::elaborate_scope(Design*des, NetScope*scope) const
{
assert(scope->type() == NetScope::TASK);
if (statement_)
statement_->elaborate_scope(des, scope);
}
@@ -346,7 +387,7 @@ void PBlock::elaborate_scope(Design*des, NetScope*scope) const
NetScope*my_scope = scope;
if (name_ != "") {
my_scope = new NetScope(scope, name_, bl_type_==BL_PAR
my_scope = new NetScope(scope, name_.c_str(), bl_type_==BL_PAR
? NetScope::FORK_JOIN
: NetScope::BEGIN_END);
}
@@ -455,6 +496,32 @@ void PWhile::elaborate_scope(Design*des, NetScope*scope) const
/*
* $Log: elab_scope.cc,v $
* Revision 1.17 2002/10/19 22:59:49 steve
* Redo the parameter vector support to allow
* parameter names in range expressions.
*
* Revision 1.16 2002/09/01 03:01:48 steve
* Properly cast signedness of parameters with ranges.
*
* Revision 1.15 2002/08/19 02:39:16 steve
* Support parameters with defined ranges.
*
* Revision 1.14 2002/08/12 01:34:59 steve
* conditional ident string using autoconfig.
*
* Revision 1.13 2001/12/30 04:47:57 steve
* Properly handle empty target in positionla parameter override.
*
* Revision 1.12 2001/12/03 04:47:14 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
*
* Revision 1.11 2001/10/20 05:21:51 steve
* Scope/module names are char* instead of string.
*
* Revision 1.10 2001/10/09 02:01:04 steve
* Tasks can have sub-scopes.
*
* Revision 1.9 2001/07/25 03:10:49 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
+161 -41
View File
@@ -16,8 +16,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: elab_sig.cc,v 1.14 2001/07/25 03:10:49 steve Exp $"
#ifdef HAVE_CVS_IDENT
#ident "$Id: elab_sig.cc,v 1.25 2002/08/12 01:34:59 steve Exp $"
#endif
# include "config.h"
@@ -39,7 +39,7 @@
* within the port_t that have a matching name.
*/
static bool signal_is_in_port(const svector<Module::port_t*>&ports,
const string&name)
const hname_t&name)
{
for (unsigned idx = 0 ; idx < ports.count() ; idx += 1) {
@@ -53,7 +53,7 @@ static bool signal_is_in_port(const svector<Module::port_t*>&ports,
// together that form the port.
for (unsigned cc = 0 ; cc < pp->expr.count() ; cc += 1) {
assert(pp->expr[cc]);
if (pp->expr[cc]->name() == name)
if (pp->expr[cc]->path() == name)
return true;
}
}
@@ -67,24 +67,62 @@ bool Module::elaborate_sig(Design*des, NetScope*scope) const
// Get all the explicitly declared wires of the module and
// start the signals list with them.
const map<string,PWire*>&wl = get_wires();
const map<hname_t,PWire*>&wl = get_wires();
for (map<string,PWire*>::const_iterator wt = wl.begin()
// Scan all the ports of the module, and make sure that each
// is connected to wires that have port declarations.
for (unsigned idx = 0 ; idx < ports.count() ; idx += 1) {
Module::port_t*pp = ports[idx];
if (pp == 0)
continue;
map<hname_t,PWire*>::const_iterator wt;
for (unsigned cc = 0 ; cc < pp->expr.count() ; cc += 1) {
hname_t port_path (pp->expr[cc]->path());
wt = wl.find(port_path);
if (wt == wl.end()) {
cerr << get_line() << ": error: "
<< "Port " << pp->expr[cc]->path() << " ("
<< (idx+1) << ") of module " << name_
<< " is not declared within module." << endl;
des->errors += 1;
continue;
}
if ((*wt).second->get_port_type() == NetNet::NOT_A_PORT) {
cerr << get_line() << ": error: "
<< "Port " << pp->expr[cc]->path() << " ("
<< (idx+1) << ") of module " << name_
<< " has no direction declaration."
<< endl;
des->errors += 1;
}
}
}
for (map<hname_t,PWire*>::const_iterator wt = wl.begin()
; wt != wl.end()
; wt ++ ) {
PWire*cur = (*wt).second;
cur->elaborate_sig(des, scope);
NetNet*sig = scope->find_signal_in_child(cur->path());
// If this wire is a signal of the module (as opposed to
// a port of a function) and is a port, then check that
// the module knows about it.
NetNet*sig = scope->find_signal(cur->name());
// the module knows about it. We know that the signal is
// the name of a signal within a subscope of a module
// (a task, a function, etc.) if the name for the PWire
// has hierarchy.
if (sig && (sig->scope() == scope)
&& (cur->get_port_type() != NetNet::NOT_A_PORT)) {
string name = (*wt).first;
if (! signal_is_in_port(ports_, name)) {
hname_t name = (*wt).first;
if (! signal_is_in_port(ports, name)) {
cerr << cur->get_line() << ": error: Signal "
<< name << " has a declared direction "
@@ -93,6 +131,7 @@ bool Module::elaborate_sig(Design*des, NetScope*scope) const
}
}
/* If the signal is an input and is also declared as a
reg, then report an error. */
@@ -101,7 +140,7 @@ bool Module::elaborate_sig(Design*des, NetScope*scope) const
&& (sig->type() == NetNet::REG)) {
cerr << cur->get_line() << ": error: "
<< cur->name() << " in module "
<< cur->path() << " in module "
<< scope->module_name()
<< " declared as input and as a reg type." << endl;
des->errors += 1;
@@ -112,7 +151,7 @@ bool Module::elaborate_sig(Design*des, NetScope*scope) const
&& (sig->type() == NetNet::REG)) {
cerr << cur->get_line() << ": error: "
<< cur->name() << " in module "
<< cur->path() << " in module "
<< scope->module_name()
<< " declared as inout and as a reg type." << endl;
des->errors += 1;
@@ -198,6 +237,17 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const
string fname = scope->basename();
assert(scope->type() == NetScope::FUNC);
/* Make sure the function has at least one input port. If it
fails this test, print an error message. Keep going so we
can find more errors. */
if (ports_ == 0) {
cerr << get_line() << ": error: Function " << fname
<< " has no ports." << endl;
cerr << get_line() << ": : Functions must have"
<< " at least one input port." << endl;
des->errors += 1;
}
svector<NetNet*>ports (ports_? ports_->count()+1 : 1);
/* Get the reg for the return value. I know the name of the
@@ -220,12 +270,13 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const
name. We know by design that the port name is given
as two components: <func>.<port>. */
string pname = (*ports_)[idx]->name();
string ppath = parse_first_name(pname);
hname_t path = (*ports_)[idx]->path();
string pname = path.peek_name(1);
string ppath = path.peek_name(0);
if (ppath != scope->basename()) {
cerr << get_line() << ": internal error: function "
<< "port " << (*ports_)[idx]->name()
<< "port " << (*ports_)[idx]->path()
<< " has wrong name for function "
<< scope->name() << "." << endl;
des->errors += 1;
@@ -268,16 +319,15 @@ void PTask::elaborate_sig(Design*des, NetScope*scope) const
name. We know by design that the port name is given
as two components: <task>.<port>. */
string pname = (*ports_)[idx]->name();
string ppath = parse_first_name(pname);
assert(pname != "");
hname_t path = (*ports_)[idx]->path();
assert(path.peek_name(0) && path.peek_name(1));
/* check that the current scope really does have the
name of the first component of the task port name. Do
this by looking up the task scope in the parent of
the current scope. */
if (scope->parent()->child(ppath) != scope) {
cerr << "internal error: task scope " << ppath
if (scope->parent()->child(path.peek_name(0)) != scope) {
cerr << "internal error: task scope " << path
<< " not the same as scope " << scope->name()
<< "?!" << endl;
return;
@@ -286,11 +336,11 @@ void PTask::elaborate_sig(Design*des, NetScope*scope) const
/* Find the signal for the port. We know by definition
that it is in the scope of the task, so look only in
the scope. */
NetNet*tmp = scope->find_signal(pname);
NetNet*tmp = scope->find_signal(path.peek_name(1));
if (tmp == 0) {
cerr << get_line() << ": internal error: "
<< "Could not find port " << pname
<< "Could not find port " << path.peek_name(1)
<< " in scope " << scope->name() << endl;
scope->dump(cerr);
}
@@ -319,19 +369,14 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
/* The parser may produce hierarchical names for wires. I here
follow the scopes down to the base where I actually want to
elaborate the NetNet object. */
string basename = name_;
for (;;) {
string p = parse_first_name(basename);
if (basename == "") {
basename = p;
break;
}
scope = scope->child(p);
assert(scope);
{ hname_t tmp_path = hname_;
free(tmp_path.remove_tail_name());
for (unsigned idx = 0 ; tmp_path.peek_name(idx) ; idx += 1) {
scope = scope->child(tmp_path.peek_name(idx));
assert(scope);
}
}
const string path = scope->name();
NetNet::Type wtype = type_;
if (wtype == NetNet::IMPLICIT)
wtype = NetNet::WIRE;
@@ -345,6 +390,10 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
if (msb_.count()) {
svector<long>mnum (msb_.count());
svector<long>lnum (msb_.count());
/* There may be places where the signal is declared as a
scaler. Count those here, for consistency check
later. */
unsigned count_scalars = 0;
/* There may be multiple declarations of ranges, because
the symbol may have its range declared in i.e. input
@@ -353,6 +402,14 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
for (unsigned idx = 0 ; idx < msb_.count() ; idx += 1) {
if (msb_[idx] == 0) {
count_scalars += 1;
assert(lsb_[idx] == 0);
mnum[idx] = 0;
lnum[idx] = 0;
continue;
}
NetEConst*tmp;
NetExpr*texpr = elab_and_eval(des, scope, msb_[idx]);
@@ -383,6 +440,18 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
}
/* Check that the declarations were all scalar or all
vector. It is an error to mix them. Use the
count_scalars to know. */
if ((count_scalars > 0) && (count_scalars != msb_.count())) {
cerr << get_line() << ": error: Signal ``" << hname_
<< "'' declared both as a vector and a scalar."
<< endl;
des->errors += 1;
return;
}
/* Make sure all the values for msb and lsb match by
value. If not, report an error. */
for (unsigned idx = 1 ; idx < msb_.count() ; idx += 1) {
@@ -390,7 +459,7 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
cerr << get_line() << ": error: Inconsistent width, "
"[" << mnum[idx] << ":" << lnum[idx] << "]"
" vs. [" << mnum[0] << ":" << lnum[0] << "]"
" for signal ``" << basename << "''" << endl;
" for signal ``" << hname_ << "''" << endl;
des->errors += 1;
return;
}
@@ -406,18 +475,22 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
}
unsigned nattrib = 0;
attrib_list_t*attrib_list = evaluate_attributes(attributes, nattrib,
des, scope);
if (lidx_ || ridx_) {
assert(lidx_ && ridx_);
// If the register has indices, then this is a
// memory. Create the memory object.
verinum*lval = lidx_->eval_const(des, path);
verinum*rval = ridx_->eval_const(des, path);
verinum*lval = lidx_->eval_const(des, scope);
verinum*rval = ridx_->eval_const(des, scope);
if ((lval == 0) || (rval == 0)) {
cerr << get_line() << ": internal error: There is "
<< "a problem evaluating indices for ``"
<< basename << "''." << endl;
<< hname_.peek_tail_name() << "''." << endl;
des->errors += 1;
return;
}
@@ -425,25 +498,72 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
assert(lval);
assert(rval);
string name = hname_.peek_tail_name();
long lnum = lval->as_long();
long rnum = rval->as_long();
delete lval;
delete rval;
NetMemory*sig = new NetMemory(scope, path+"."+basename,
wid, lnum, rnum);
NetMemory*sig = new NetMemory(scope, name, wid, lnum, rnum);
} else {
NetNet*sig = new NetNet(scope, path + "." +basename, wtype, msb, lsb);
/* Make a hierarchical make for the signal. */
string name = scope->name();
name = name + "." + hname_.peek_tail_name();
NetNet*sig = new NetNet(scope, name, wtype, msb, lsb);
sig->set_line(*this);
sig->port_type(port_type_);
sig->set_signed(get_signed());
sig->set_attributes(attributes);
sig->set_isint(get_isint());
for (unsigned idx = 0 ; idx < nattrib ; idx += 1)
sig->attribute(attrib_list[idx].key, attrib_list[idx].val);
}
}
/*
* $Log: elab_sig.cc,v $
* Revision 1.25 2002/08/12 01:34:59 steve
* conditional ident string using autoconfig.
*
* Revision 1.24 2002/08/05 04:18:45 steve
* Store only the base name of memories.
*
* Revision 1.23 2002/06/21 04:59:35 steve
* Carry integerness throughout the compilation.
*
* Revision 1.22 2002/05/23 03:08:51 steve
* Add language support for Verilog-2001 attribute
* syntax. Hook this support into existing $attribute
* handling, and add number and void value types.
*
* Add to the ivl_target API new functions for access
* of complex attributes attached to gates.
*
* Revision 1.21 2002/05/19 23:37:28 steve
* Parse port_declaration_lists from the 2001 Standard.
*
* Revision 1.20 2002/01/26 05:28:28 steve
* Detect scalar/vector declarion mismatch.
*
* Revision 1.19 2002/01/23 03:35:17 steve
* Detect incorrect function ports.
*
* Revision 1.18 2001/12/03 04:47:14 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
*
* Revision 1.17 2001/11/07 04:01:59 steve
* eval_const uses scope instead of a string path.
*
* Revision 1.16 2001/11/01 05:21:26 steve
* Catch ports that have no direction.
*
* Revision 1.15 2001/10/31 03:11:15 steve
* detect module ports not declared within the module.
*
* Revision 1.14 2001/07/25 03:10:49 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
+610 -653
View File
File diff suppressed because it is too large Load Diff
+61 -22
View File
@@ -16,8 +16,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: emit.cc,v 1.62 2001/08/25 23:50:02 steve Exp $"
#ifdef HAVE_CVS_IDENT
#ident "$Id: emit.cc,v 1.70 2002/11/03 20:36:10 steve Exp $"
#endif
# include "config.h"
@@ -128,6 +128,11 @@ bool NetRamDq::emit_node(struct target_t*tgt) const
return true;
}
bool NetUserFunc::emit_node(struct target_t*tgt) const
{
return tgt->net_function(this);
}
bool NetBUFZ::emit_node(struct target_t*tgt) const
{
return tgt->bufz(this);
@@ -156,18 +161,6 @@ bool NetAssignNB::emit_proc(struct target_t*tgt) const
return true;
}
bool NetAssignMem::emit_proc(struct target_t*tgt) const
{
tgt->proc_assign_mem(this);
return true;
}
bool NetAssignMemNB::emit_proc(struct target_t*tgt) const
{
tgt->proc_assign_mem_nb(this);
return true;
}
bool NetBlock::emit_proc(struct target_t*tgt) const
{
return tgt->proc_block(this);
@@ -186,8 +179,7 @@ bool NetCAssign::emit_proc(struct target_t*tgt) const
bool NetCondit::emit_proc(struct target_t*tgt) const
{
tgt->proc_condit(this);
return true;
return tgt->proc_condit(this);
}
bool NetDeassign::emit_proc(struct target_t*tgt) const
@@ -263,16 +255,20 @@ void NetBlock::emit_recurse(struct target_t*tgt) const
} while (cur != last_);
}
void NetCondit::emit_recurse_if(struct target_t*tgt) const
bool NetCondit::emit_recurse_if(struct target_t*tgt) const
{
if (if_)
if_->emit_proc(tgt);
return if_->emit_proc(tgt);
else
return true;
}
void NetCondit::emit_recurse_else(struct target_t*tgt) const
bool NetCondit::emit_recurse_else(struct target_t*tgt) const
{
if (else_)
else_->emit_proc(tgt);
return else_->emit_proc(tgt);
else
return true;
}
bool NetEvProbe::emit_node(struct target_t*tgt) const
@@ -369,7 +365,9 @@ bool Design::emit(struct target_t*tgt) const
return false;
// enumerate the scopes
root_scope_->emit_scope(tgt);
for (list<NetScope*>::const_iterator scope = root_scopes_.begin();
scope != root_scopes_.end(); scope++)
(*scope)->emit_scope(tgt);
// emit nodes
@@ -383,7 +381,9 @@ bool Design::emit(struct target_t*tgt) const
// emit task and function definitions
root_scope_->emit_defs(tgt);
for (list<NetScope*>::const_iterator scope = root_scopes_.begin();
scope != root_scopes_.end(); scope++)
(*scope)->emit_defs(tgt);
// emit the processes
@@ -427,6 +427,11 @@ void NetEScope::expr_scan(struct expr_scan_t*tgt) const
tgt->expr_scope(this);
}
void NetESelect::expr_scan(struct expr_scan_t*tgt) const
{
tgt->expr_select(this);
}
void NetESFunc::expr_scan(struct expr_scan_t*tgt) const
{
tgt->expr_sfunc(this);
@@ -465,11 +470,45 @@ bool emit(const Design*des, const char*type)
return des->emit(tgt->meth);
}
cerr << "error: Code generator type " << type
<< " not found." << endl;
return false;
}
/*
* $Log: emit.cc,v $
* Revision 1.70 2002/11/03 20:36:10 steve
* Error message for mising code generator type.
*
* Revision 1.69 2002/08/12 01:34:59 steve
* conditional ident string using autoconfig.
*
* Revision 1.68 2002/06/05 03:44:25 steve
* Add support for memory words in l-value of
* non-blocking assignments, and remove the special
* NetAssignMem_ and NetAssignMemNB classes.
*
* Revision 1.67 2002/06/04 05:38:44 steve
* Add support for memory words in l-value of
* blocking assignments, and remove the special
* NetAssignMem class.
*
* Revision 1.66 2002/03/09 02:10:22 steve
* Add the NetUserFunc netlist node.
*
* Revision 1.65 2002/01/28 00:52:41 steve
* Add support for bit select of parameters.
* This leads to a NetESelect node and the
* vvp code generator to support that.
*
* Revision 1.64 2002/01/19 19:02:08 steve
* Pass back target errors processing conditionals.
*
* Revision 1.63 2001/10/19 21:53:24 steve
* Support multiple root modules (Philip Blundell)
*
* Revision 1.62 2001/08/25 23:50:02 steve
* Change the NetAssign_ class to refer to the signal
* instead of link into the netlist. This is faster
+118 -104
View File
@@ -16,8 +16,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: eval.cc,v 1.21 2001/07/25 03:10:49 steve Exp $"
#ifdef HAVE_CVS_IDENT
#ident "$Id: eval.cc,v 1.32 2002/10/19 22:59:49 steve Exp $"
#endif
# include "config.h"
@@ -28,65 +28,74 @@
# include "netlist.h"
# include "compiler.h"
verinum* PExpr::eval_const(const Design*, const string&) const
verinum* PExpr::eval_const(const Design*, const NetScope*) const
{
return 0;
}
verinum* PEBinary::eval_const(const Design*des, const string&path) const
verinum* PEBinary::eval_const(const Design*des, const NetScope*scope) const
{
verinum*l = left_->eval_const(des, path);
verinum*l = left_->eval_const(des, scope);
if (l == 0) return 0;
verinum*r = right_->eval_const(des, path);
verinum*r = right_->eval_const(des, scope);
if (r == 0) {
delete l;
return 0;
}
verinum*res;
switch (op_) {
case '+': {
assert(l->is_defined());
assert(r->is_defined());
long lv = l->as_long();
long rv = r->as_long();
res = new verinum(lv+rv, l->len());
if (l->is_defined() && r->is_defined()) {
long lv = l->as_long();
long rv = r->as_long();
res = new verinum(lv+rv, l->len());
} else {
res = new verinum(verinum::Vx, l->len());
}
break;
}
case '-': {
assert(l->is_defined());
assert(r->is_defined());
long lv = l->as_long();
long rv = r->as_long();
res = new verinum(lv-rv, l->len());
if (l->is_defined() && r->is_defined()) {
long lv = l->as_long();
long rv = r->as_long();
res = new verinum(lv-rv, l->len());
} else {
res = new verinum(verinum::Vx, l->len());
}
break;
}
case '*': {
assert(l->is_defined());
assert(r->is_defined());
long lv = l->as_long();
long rv = r->as_long();
res = new verinum(lv * rv, l->len());
if (l->is_defined() && r->is_defined()) {
long lv = l->as_long();
long rv = r->as_long();
res = new verinum(lv * rv, l->len());
} else {
res = new verinum(verinum::Vx, l->len());
}
break;
}
case '/': {
assert(l->is_defined());
assert(r->is_defined());
long lv = l->as_long();
long rv = r->as_long();
res = new verinum(lv / rv, l->len());
if (l->is_defined() && r->is_defined()) {
long lv = l->as_long();
long rv = r->as_long();
res = new verinum(lv / rv, l->len());
} else {
res = new verinum(verinum::Vx, l->len());
}
break;
}
case '%': {
assert(l->is_defined());
assert(r->is_defined());
long lv = l->as_long();
long rv = r->as_long();
res = new verinum(lv % rv, l->len());
if (l->is_defined() && r->is_defined()) {
long lv = l->as_long();
long rv = r->as_long();
res = new verinum(lv % rv, l->len());
} else {
res = new verinum(verinum::Vx, l->len());
}
break;
}
case 'l': {
case 'l': { // left shift (<<)
assert(r->is_defined());
unsigned long rv = r->as_ulong();
res = new verinum(verinum::V0, l->len());
@@ -97,6 +106,17 @@ verinum* PEBinary::eval_const(const Design*des, const string&path) const
}
break;
}
case 'r': { // right shift (>>)
assert(r->is_defined());
unsigned long rv = r->as_ulong();
res = new verinum(verinum::V0, l->len());
if (rv < res->len()) {
unsigned cnt = res->len() - rv;
for (unsigned idx = 0 ; idx < cnt ; idx += 1)
res->set(idx, l->get(idx+rv));
}
break;
}
default:
delete l;
@@ -114,42 +134,50 @@ verinum* PEBinary::eval_const(const Design*des, const string&path) const
* Evaluate an identifier as a constant expression. This is only
* possible if the identifier is that of a parameter.
*/
verinum* PEIdent::eval_const(const Design*des, const string&path) const
verinum* PEIdent::eval_const(const Design*des, const NetScope*scope) const
{
const NetScope*scope = des->find_scope(path);
assert(scope);
const NetExpr*expr = des->find_parameter(scope, text_);
const NetExpr*expr = des->find_parameter(scope, path_);
if (expr == 0)
return 0;
assert(msb_ == 0);
if (dynamic_cast<const NetEParam*>(expr)) {
cerr << get_line() << ": sorry: I cannot evaluate ``" <<
text_ << "'' in this scope: " << scope->name() << endl;
const NetEConst*eval = dynamic_cast<const NetEConst*>(expr);
if (eval == 0) {
cerr << get_line() << ": internal error: Unable to evaluate "
<< "constant expression (parameter=" << path_
<< "): " << *expr << endl;
return 0;
}
const NetEConst*eval = dynamic_cast<const NetEConst*>(expr);
assert(eval);
if (msb_ || lsb_)
return 0;
return new verinum(eval->value());
}
verinum* PEFNumber::eval_const(const Design*, const string&) const
verinum* PEFNumber::eval_const(const Design*, const NetScope*) const
{
long val = value_->as_long();
return new verinum(val);
}
verinum* PENumber::eval_const(const Design*, const string&) const
verinum* PENumber::eval_const(const Design*, const NetScope*) const
{
return new verinum(value());
}
verinum* PETernary::eval_const(const Design*des, const string&path) const
verinum* PEString::eval_const(const Design*, const NetScope*) const
{
verinum*test = expr_->eval_const(des, path);
return new verinum(string(text_));
}
verinum* PETernary::eval_const(const Design*des, const NetScope*scope) const
{
verinum*test = expr_->eval_const(des, scope);
if (test == 0)
return 0;
@@ -157,9 +185,9 @@ verinum* PETernary::eval_const(const Design*des, const string&path) const
delete test;
switch (bit) {
case verinum::V0:
return fal_->eval_const(des, path);
return fal_->eval_const(des, scope);
case verinum::V1:
return tru_->eval_const(des, path);
return tru_->eval_const(des, scope);
default:
return 0;
// XXXX It is possible to handle this case if both fal_
@@ -167,9 +195,9 @@ verinum* PETernary::eval_const(const Design*des, const string&path) const
}
}
verinum* PEUnary::eval_const(const Design*des, const string&path) const
verinum* PEUnary::eval_const(const Design*des, const NetScope*scope) const
{
verinum*val = expr_->eval_const(des, path);
verinum*val = expr_->eval_const(des, scope);
if (val == 0)
return 0;
@@ -198,6 +226,46 @@ verinum* PEUnary::eval_const(const Design*des, const string&path) const
/*
* $Log: eval.cc,v $
* Revision 1.32 2002/10/19 22:59:49 steve
* Redo the parameter vector support to allow
* parameter names in range expressions.
*
* Revision 1.31 2002/10/13 05:01:07 steve
* More verbose eval_const assert message.
*
* Revision 1.30 2002/08/12 01:34:59 steve
* conditional ident string using autoconfig.
*
* Revision 1.29 2002/06/07 02:57:54 steve
* Simply give up on constants with indices.
*
* Revision 1.28 2002/06/06 18:57:04 steve
* Better error for identifier index eval.
*
* Revision 1.27 2002/05/23 03:08:51 steve
* Add language support for Verilog-2001 attribute
* syntax. Hook this support into existing $attribute
* handling, and add number and void value types.
*
* Add to the ivl_target API new functions for access
* of complex attributes attached to gates.
*
* Revision 1.26 2001/12/29 22:10:10 steve
* constant eval of arithmetic with x and z.
*
* Revision 1.25 2001/12/29 00:43:55 steve
* Evaluate constant right shifts.
*
* Revision 1.24 2001/12/03 04:47:15 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
*
* Revision 1.23 2001/11/07 04:01:59 steve
* eval_const uses scope instead of a string path.
*
* Revision 1.22 2001/11/06 06:11:55 steve
* Support more real arithmetic in delay constants.
*
* Revision 1.21 2001/07/25 03:10:49 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
@@ -222,59 +290,5 @@ verinum* PEUnary::eval_const(const Design*des, const string&path) const
*
* Revision 1.15 2000/09/07 22:38:13 steve
* Support unary + and - in constants.
*
* Revision 1.14 2000/03/08 04:36:53 steve
* Redesign the implementation of scopes and parameters.
* I now generate the scopes and notice the parameters
* in a separate pass over the pform. Once the scopes
* are generated, I can process overrides and evalutate
* paremeters before elaboration begins.
*
* Revision 1.13 2000/02/23 02:56:54 steve
* Macintosh compilers do not support ident.
*
* Revision 1.12 1999/11/30 04:48:17 steve
* Handle evaluation of ternary during elaboration.
*
* Revision 1.11 1999/11/28 23:42:02 steve
* NetESignal object no longer need to be NetNode
* objects. Let them keep a pointer to NetNet objects.
*
* Revision 1.10 1999/11/21 20:03:24 steve
* Handle multiply in constant expressions.
*
* Revision 1.9 1999/10/08 17:48:09 steve
* Support + in constant expressions.
*
* Revision 1.8 1999/09/20 02:21:10 steve
* Elaborate parameters in phases.
*
* Revision 1.7 1999/09/18 01:52:48 steve
* Remove spurious message.
*
* Revision 1.6 1999/09/16 04:18:15 steve
* elaborate concatenation repeats.
*
* Revision 1.5 1999/08/06 04:05:28 steve
* Handle scope of parameters.
*
* Revision 1.4 1999/07/17 19:51:00 steve
* netlist support for ternary operator.
*
* Revision 1.3 1999/05/30 01:11:46 steve
* Exressions are trees that can duplicate, and not DAGS.
*
* Revision 1.2 1999/05/10 00:16:58 steve
* Parse and elaborate the concatenate operator
* in structural contexts, Replace vector<PExpr*>
* and list<PExpr*> with svector<PExpr*>, evaluate
* constant expressions with parameters, handle
* memories as lvalues.
*
* Parse task declarations, integer types.
*
* Revision 1.1 1998/11/03 23:28:58 steve
* Introduce verilog to CVS.
*
*/
+98
View File
@@ -0,0 +1,98 @@
/*
* Copyright (c) 2002 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: eval_attrib.cc,v 1.5 2002/08/12 01:34:59 steve Exp $"
#endif
# include "config.h"
# include "util.h"
# include "PExpr.h"
# include "netlist.h"
# include <iostream>
# include <assert.h>
/*
* The evaluate_attributes function evaluates the attribute
* expressions from the map, and resturns a table in a form suitable
* for passing to netlist devices.
*/
attrib_list_t* evaluate_attributes(const map<string,PExpr*>&att,
unsigned&natt,
const Design*des,
const NetScope*scope)
{
natt = att.size();
if (natt == 0)
return 0;
attrib_list_t*table = new attrib_list_t [natt];
unsigned idx = 0;
typedef map<string,PExpr*>::const_iterator iter_t;
for (iter_t cur = att.begin() ; cur != att.end() ; cur ++, idx++) {
table[idx].key = (*cur).first;
PExpr*exp = (*cur).second;
/* If the attribute value is given in the source, then
evalulate it as a constant. If the value is not
given, then assume the value is 1. */
verinum*tmp;
if (exp)
tmp = exp->eval_const(des, scope);
else
tmp = new verinum(1);
if (tmp == 0)
cerr << "internal error: no result for " << *exp << endl;
assert(tmp);
table[idx].val = *tmp;
delete tmp;
}
assert(idx == natt);
return table;
}
/*
* $Log: eval_attrib.cc,v $
* Revision 1.5 2002/08/12 01:34:59 steve
* conditional ident string using autoconfig.
*
* Revision 1.4 2002/08/10 21:59:39 steve
* The default attribute value is 1.
*
* Revision 1.3 2002/06/06 18:57:18 steve
* Use standard name for iostream.
*
* Revision 1.2 2002/06/03 03:55:14 steve
* compile warnings.
*
* Revision 1.1 2002/05/23 03:08:51 steve
* Add language support for Verilog-2001 attribute
* syntax. Hook this support into existing $attribute
* handling, and add number and void value types.
*
* Add to the ivl_target API new functions for access
* of complex attributes attached to gates.
*
*/
+54 -2
View File
@@ -16,8 +16,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: eval_rconst.cc,v 1.2 2001/07/25 03:10:49 steve Exp $"
#ifdef HAVE_CVS_IDENT
#ident "$Id: eval_rconst.cc,v 1.5 2002/08/12 01:34:59 steve Exp $"
#endif
# include "config.h"
@@ -36,8 +36,60 @@ verireal* PEFNumber::eval_rconst(const Design*, const NetScope*) const
return res;
}
verireal* PENumber::eval_rconst(const Design*, const NetScope*) const
{
verireal*res = new verireal(value_->as_long());
return res;
}
verireal* PEBinary::eval_rconst(const Design*des, const NetScope*scope) const
{
verireal*lef = left_->eval_rconst(des, scope);
verireal*rig = right_->eval_rconst(des, scope);
verireal*res = 0;
switch (op_) {
case '*':
if (lef == 0)
break;
if (rig == 0)
break;
res = new verireal;
*res = (*lef) * (*rig);
break;
default:
break;
}
delete lef;
delete rig;
return res;
}
verireal* PEIdent::eval_rconst(const Design*des, const NetScope*scope) const
{
verinum* val = eval_const(des, scope);
if (val == 0)
return 0;
verireal*res = new verireal(val->as_long());
delete val;
return res;
}
/*
* $Log: eval_rconst.cc,v $
* Revision 1.5 2002/08/12 01:34:59 steve
* conditional ident string using autoconfig.
*
* Revision 1.4 2001/11/07 04:01:59 steve
* eval_const uses scope instead of a string path.
*
* Revision 1.3 2001/11/06 06:11:55 steve
* Support more real arithmetic in delay constants.
*
* Revision 1.2 2001/07/25 03:10:49 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
+333 -83
View File
@@ -16,8 +16,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: eval_tree.cc,v 1.26 2001/07/25 03:10:49 steve Exp $"
#ifdef HAVE_CVS_IDENT
#ident "$Id: eval_tree.cc,v 1.44 2002/12/05 02:14:33 steve Exp $"
#endif
# include "config.h"
@@ -81,8 +81,22 @@ NetEConst* NetEBBits::eval_tree()
eval_sub_tree_();
NetEConst*lc = dynamic_cast<NetEConst*>(left_);
if (lc == 0) return 0;
NetEConst*rc = dynamic_cast<NetEConst*>(right_);
/* Notice the special case where one of the operands is 0 and
this is a bitwise &. If this happens, then the result is
known to be 0. */
if ((op() == '&') && lc && (lc->value() == verinum(0))) {
verinum res (verinum::V0, expr_width());
return new NetEConst(res);
}
if ((op() == '&') && rc && (rc->value() == verinum(0))) {
verinum res (verinum::V0, expr_width());
return new NetEConst(res);
}
if (lc == 0) return 0;
if (rc == 0) return 0;
verinum lval = lc->value();
@@ -116,11 +130,11 @@ NetEConst* NetEBBits::eval_tree()
if (lwid < rwid)
for (unsigned idx = lwid ; idx < rwid ; idx += 1)
res.set(idx, lval.get(idx));
res.set(idx, rval.get(idx));
if (rwid < lwid)
for (unsigned idx = rwid ; idx < lwid ; idx += 1)
res.set(idx, rval.get(idx));
res.set(idx, lval.get(idx));
break;
}
@@ -152,15 +166,30 @@ NetEConst* NetEBComp::eval_eqeq_()
const verinum&lv = l->value();
const verinum&rv = r->value();
if (lv.len() < rv.len())
return 0;
unsigned s_len = lv.len();
if (rv.len() < s_len) s_len = rv.len();
verinum result(verinum::V1, 1);
for (unsigned idx = 0 ; idx < lv.len(); idx += 1) {
for (unsigned idx = 0 ; idx < s_len; idx += 1) {
if (lv[idx] != rv[idx])
result = verinum::V0;
}
// If one operand was wider than the other, check that the
// remaining bits are all zero
if (lv.len() > s_len) {
for (unsigned idx = s_len; idx < lv.len(); idx += 1) {
if (lv[idx] != 0)
result = verinum::V0;
}
}
if (rv.len() > s_len) {
for (unsigned idx = s_len; idx < rv.len(); idx += 1) {
if (rv[idx] != 0)
result = verinum::V0;
}
}
return new NetEConst(result);
}
@@ -195,14 +224,16 @@ NetEConst* NetEBComp::eval_less_()
return new NetEConst(result);
}
if (lv.has_sign() && rv.has_sign() && (lv.as_long() < rv.as_long())) {
verinum result(verinum::V1, 1);
return new NetEConst(result);
}
if (lv.as_ulong() < rv.as_ulong()) {
verinum result(verinum::V1, 1);
return new NetEConst(result);
if (lv.has_sign() && rv.has_sign()) {
if (lv.as_long() < rv.as_long()) {
verinum result(verinum::V1, 1);
return new NetEConst(result);
}
} else {
if (lv.as_ulong() < rv.as_ulong()) {
verinum result(verinum::V1, 1);
return new NetEConst(result);
}
}
verinum result(verinum::V0, 1);
@@ -220,6 +251,7 @@ NetEConst* NetEBComp::eval_leeq_()
return new NetEConst(result);
}
/* Detect the case where the right side is greater that or
equal to the largest value the left side can possibly
have. */
@@ -239,14 +271,16 @@ NetEConst* NetEBComp::eval_leeq_()
return new NetEConst(result);
}
if (lv.has_sign() && rv.has_sign() && (lv.as_long() <= rv.as_long())) {
verinum result(verinum::V1, 1);
return new NetEConst(result);
}
if (lv.as_ulong() <= rv.as_ulong()) {
verinum result(verinum::V1, 1);
return new NetEConst(result);
if (lv.has_sign() && rv.has_sign()) {
if (lv.as_long() <= rv.as_long()) {
verinum result(verinum::V1, 1);
return new NetEConst(result);
}
} else {
if (lv.as_ulong() <= rv.as_ulong()) {
verinum result(verinum::V1, 1);
return new NetEConst(result);
}
}
verinum result(verinum::V0, 1);
@@ -685,6 +719,10 @@ NetEConst* NetEBShift::eval_tree()
NetEConst* NetEConcat::eval_tree()
{
unsigned repeat_val = repeat();
unsigned local_errors = 0;
unsigned gap = 0;
for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) {
// Parameter not here? This is an error, but presumably
@@ -692,10 +730,13 @@ NetEConst* NetEConcat::eval_tree()
if (parms_[idx] == 0)
continue;
// If this parameter is already a constant, all is well
// so go on.
if (dynamic_cast<NetEConst*>(parms_[idx]))
if (dynamic_cast<NetEConst*>(parms_[idx])) {
gap += parms_[idx]->expr_width();
continue;
}
// Finally, try to evaluate the parameter expression
// that is here. If I succeed, reset the parameter to
@@ -705,37 +746,64 @@ NetEConst* NetEConcat::eval_tree()
if (expr) {
delete parms_[idx];
parms_[idx] = expr;
if (! expr->has_width()) {
cerr << get_line() << ": error: concatenation "
<< "operand has indefinite width: "
<< *parms_[idx] << endl;
local_errors += 1;
} else if (expr->expr_width() == 0) {
cerr << expr->get_line() << ": internal error: "
<< "Operand of concatenation has no width: "
<< *expr << endl;
local_errors += 1;
}
gap += expr->expr_width();
}
}
if (local_errors > 0)
return 0;
// Handle the special case that the repeat expression is
// zero. In this case, just return a 0 value with the expected
// width.
if (repeat_ == 0) {
if (repeat_val == 0) {
verinum val (verinum::V0, expr_width());
NetEConst*res = new NetEConst(val);
res->set_width(val.len());
return res;
}
// Figure out the width of the repeated expression, and make a
// verinum to hold the result.
unsigned gap = expr_width() / repeat_;
verinum val (verinum::Vx, repeat_ * gap);
// At this point, the "gap" is the width of a single repeat of
// the concatenation. The total width of the result is the gap
// times the repeat count.
verinum val (verinum::Vx, repeat_val * gap);
// build up the result from least significant to most.
unsigned cur = 0;
bool is_string_flag = true;
for (unsigned idx = parms_.count() ; idx > 0 ; idx -= 1) {
NetEConst*expr = dynamic_cast<NetEConst*>(parms_[idx-1]);
if (expr == 0)
return 0;
verinum tmp = expr->value();
for (unsigned bit = 0 ; bit < tmp.len() ; bit += 1, cur += 1)
for (unsigned rep = 0 ; rep < repeat_ ; rep += 1)
for (unsigned bit = 0; bit < tmp.len(); bit += 1, cur += 1)
for (unsigned rep = 0 ; rep < repeat_val ; rep += 1)
val.set(rep*gap+cur, tmp[bit]);
is_string_flag = is_string_flag && tmp.is_string();
}
/* If all the values were strings, then re-stringify this
constant. This might be useful information in the code
generator or other optimizer steps. */
if (is_string_flag) {
val = verinum(val.as_string());
}
NetEConst*res = new NetEConst(val);
@@ -743,13 +811,58 @@ NetEConst* NetEConcat::eval_tree()
return res;
}
/*
* There are limits to our ability to evaluate a memory reference
* expression, because the content of a memory is never
* constant. However, the index expression may be precalculated, and
* there are certain index values that do give us constant results.
*/
NetExpr* NetEMemory::eval_tree()
{
/* Attempt to evaluate the index expression to a constant, if
it is not already. */
if (idx_ && !dynamic_cast<NetEConst*>(idx_)) {
NetExpr* tmp = idx_->eval_tree();
if (tmp) {
delete idx_;
idx_ = tmp;
}
}
NetEConst*itmp = dynamic_cast<NetEConst*>(idx_);
if (itmp == 0)
return 0;
verinum ival = itmp->value();
/* If the index expression has any x or z bits, then we know
already that the expression result is a constant x. */
if (! ival.is_defined()) {
verinum xres (verinum::Vx, mem_->width(), false);
NetEConst*res = new NetEConst(xres);
return res;
}
/* If the index expression is outside the range of the memory,
then the result is a constant x. */
unsigned norm_idx = mem_->index_to_address(ival.as_long());
if (norm_idx >= mem_->count()) {
verinum xres (verinum::Vx, mem_->width(), false);
NetEConst*res = new NetEConst(xres);
return res;
}
return 0;
}
NetExpr* NetEParam::eval_tree()
{
if (des_ == 0)
return 0;
assert(scope_);
const NetExpr*expr = scope_->get_parameter(name_);
assert(name_.peek_name(1) == 0);
const NetExpr*expr = scope_->get_parameter(name_.peek_name(0));
if (expr == 0) {
cerr << get_line() << ": internal error: Unable to match "
<< "parameter " << name_ << " in scope "
@@ -777,10 +890,57 @@ NetExpr* NetEParam::eval_tree()
// The result can be saved as the value of the parameter for
// future reference, and return a copy to the caller.
scope_->set_parameter(name_, res);
scope_->replace_parameter(name_.peek_name(0), res);
return res->dup_expr();
}
NetEConst* NetESelect::eval_tree()
{
NetEConst*expr = dynamic_cast<NetEConst*>(expr_);
if (expr == 0) {
NetExpr*tmp = expr_->eval_tree();
if (tmp != 0) {
delete expr_;
expr_ = tmp;
}
expr = dynamic_cast<NetEConst*>(expr_);
}
NetEConst*base = dynamic_cast<NetEConst*>(base_);
if (base == 0) {
NetExpr*tmp = base_->eval_tree();
if (tmp != 0) {
delete base_;
base_ = tmp;
}
base = dynamic_cast<NetEConst*>(base_);
}
if (expr == 0)
return 0;
if (base == 0)
return 0;
verinum eval = expr->value();
verinum oval (verinum::V0, expr_width(), true);
long bval = base->value().as_long();
for (long idx = 0 ; idx < expr_width() ; idx += 1) {
if ((bval >= eval.len()) || (bval < 0))
oval.set(idx, verinum::Vx);
else
oval.set(idx, eval.get(bval));
bval += 1;
}
NetEConst*res = new NetEConst(oval);
return res;
}
/*
* A ternary expression evaluation is controlled by the condition
* expression. If the condition evaluates to true or false, then
@@ -792,48 +952,49 @@ NetExpr* NetETernary::eval_tree()
{
NetExpr*tmp;
/* Evaluate the cond_ to a constant. If it already is a
constant, then there is nothing to do. */
assert(cond_);
if (0 == dynamic_cast<NetEConst*>(cond_)) {
tmp = cond_->eval_tree();
if (tmp != 0) {
delete cond_;
cond_ = tmp;
}
}
assert(true_val_);
if (0 == dynamic_cast<NetEConst*>(true_val_)) {
tmp = true_val_->eval_tree();
if (tmp != 0) {
delete true_val_;
true_val_ = tmp;
}
}
assert(false_val_);
if (0 == dynamic_cast<NetEConst*>(false_val_)) {
tmp = false_val_->eval_tree();
if (tmp != 0) {
delete false_val_;
false_val_ = tmp;
}
}
NetEConst*c = dynamic_cast<NetEConst*>(cond_);
if (c == 0) {
tmp = cond_->eval_tree();
c = dynamic_cast<NetEConst*>(tmp);
if (c == 0)
return 0;
if (c == 0)
return 0;
assert(cond_ != c);
delete cond_;
cond_ = c;
}
/* If the condition is 1 or 0, return the true or false
expression. Try to evaluate the expression down as far as
we can. */
if (c->value().get(0) == verinum::V1) {
tmp = dynamic_cast<NetEConst*>(true_val_);
if (tmp) return tmp->dup_expr();
tmp = true_val_->eval_tree();
if (tmp) {
delete true_val_;
true_val_ = tmp;
}
if (c->value().get(0) == verinum::V1)
return true_val_->dup_expr();
}
if (c->value().get(0) == verinum::V0) {
tmp = dynamic_cast<NetEConst*>(false_val_);
if (tmp) return tmp->dup_expr();
tmp = false_val_->eval_tree();
if (tmp) {
delete false_val_;
false_val_ = tmp;
}
if (c->value().get(0) == verinum::V0)
return false_val_->dup_expr();
}
/* Here we have a more complex case. We need to evaluate both
@@ -841,27 +1002,14 @@ NetExpr* NetETernary::eval_tree()
build up a constant result. */
NetEConst*t = dynamic_cast<NetEConst*>(true_val_);
if (t == 0) {
tmp = true_val_->eval_tree();
t = dynamic_cast<NetEConst*>(tmp);
if (t == 0)
return 0;
delete true_val_;
true_val_ = t;
}
if (t == 0)
return 0;
NetEConst*f = dynamic_cast<NetEConst*>(false_val_);
if (f == 0) {
tmp = false_val_->eval_tree();
f = dynamic_cast<NetEConst*>(tmp);
if (f == 0)
return 0;
if (f == 0)
return 0;
delete false_val_;
false_val_ = f;
}
unsigned size = t->expr_width();
assert(size == f->expr_width());
@@ -884,6 +1032,7 @@ NetExpr* NetETernary::eval_tree()
void NetEUnary::eval_expr_()
{
assert(expr_);
if (dynamic_cast<NetEConst*>(expr_))
return;
@@ -906,6 +1055,24 @@ NetEConst* NetEUnary::eval_tree()
switch (op_) {
case '+':
/* Unary + is a no-op. */
return new NetEConst(val);
case '-': {
if (val.is_defined()) {
verinum tmp (verinum::V0, val.len());
tmp.has_sign(val.has_sign());
val = tmp - val;
} else {
for (unsigned idx = 0 ; idx < val.len() ; idx += 1)
val.set(idx, verinum::Vx);
}
return new NetEConst(val);
}
case '~': {
/* Bitwise not is even simpler then logical
@@ -927,7 +1094,6 @@ NetEConst* NetEUnary::eval_tree()
}
default:
delete rval;
return 0;
}
}
@@ -972,6 +1138,7 @@ NetEConst* NetEUReduce::eval_tree()
}
res = v1? verinum::V0 : (vx? verinum::Vx : verinum::V1);
break;
}
case '&': {
@@ -988,6 +1155,28 @@ NetEConst* NetEUReduce::eval_tree()
break;
}
case '^': {
/* Reduction XOR. */
unsigned ones = 0, unknown = 0;
for (unsigned idx = 0 ; idx < val.len() ; idx += 1)
switch (val.get(idx)) {
case verinum::V0:
break;
case verinum::V1:
ones += 1;
break;
default:
unknown += 1;
break;
}
if (unknown)
return new NetEConst(verinum(verinum::Vx,1,true));
if (ones%2)
return new NetEConst(verinum(verinum::V1,1,true));
return new NetEConst(verinum(verinum::V0,1,true));
}
default:
return 0;
}
@@ -998,6 +1187,67 @@ NetEConst* NetEUReduce::eval_tree()
/*
* $Log: eval_tree.cc,v $
* Revision 1.44 2002/12/05 02:14:33 steve
* Support bit select in constant expressions.
*
* Revision 1.43 2002/11/09 01:40:19 steve
* Postpone parameter width check to evaluation.
*
* Revision 1.42 2002/10/19 22:59:49 steve
* Redo the parameter vector support to allow
* parameter names in range expressions.
*
* Revision 1.41 2002/08/12 01:34:59 steve
* conditional ident string using autoconfig.
*
* Revision 1.40 2002/05/25 16:43:47 steve
* Eval ^ and &0 expressions.
*
* Revision 1.39 2002/05/06 02:30:27 steve
* Allow parameters in concatenation of widths are defined.
*
* Revision 1.38 2002/05/05 21:11:50 steve
* Put off evaluation of concatenation repeat expresions
* until after parameters are defined. This allows parms
* to be used in repeat expresions.
*
* Add the builtin $signed system function.
*
* Revision 1.37 2002/04/27 05:03:46 steve
* Preserve stringiness string part select and concatenation.
*
* Revision 1.36 2002/04/27 03:17:15 steve
* Fixup eval of signed constants.
*
* Revision 1.35 2002/04/24 02:47:02 steve
* Fix compile time eval of signed <= signed.
*
* Revision 1.34 2002/04/14 19:28:47 steve
* Fix constant evaluation of unary
*
* Revision 1.33 2002/02/01 05:09:14 steve
* Propagate sign in unary minus.
*
* Revision 1.32 2002/01/22 01:40:04 steve
* Precalculate constant results of memory index expressions.
*
* Revision 1.31 2001/12/30 00:39:25 steve
* Evaluate constant unary minus.
*
* Revision 1.30 2001/12/03 04:47:15 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
*
* Revision 1.29 2001/11/19 01:54:14 steve
* Port close cropping behavior from mcrgb
* Move window array reset to libmc.
*
* Revision 1.28 2001/10/22 15:31:21 steve
* fix constant overrun in | operands.
*
* Revision 1.27 2001/10/20 00:11:24 steve
* Evaluate constant == when operands differ in width.
*
* Revision 1.26 2001/07/25 03:10:49 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
+3
View File
@@ -0,0 +1,3 @@
,*
hello_vpi.vpi
show_vcd.vcd
+1035
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -31,7 +31,7 @@
* file "hello" which is compiled, linked and ready to run. Run this
* program like so:
*
* ./hello
* vvp hello
*
* and the program will print the message to its output. Easy! For
* more on how to make the iverilog command work, see the iverilog
+75
View File
@@ -0,0 +1,75 @@
/*
* Copyright (c) 2002 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: hello_vpi.c,v 1.3 2002/08/12 01:35:01 steve Exp $"
#endif
/*
* This file contains an example VPI module to demonstrate the tools
* to create vpi modules. To compile this module, use the iverilog-vpi
* command like so:
*
* iverilog-vpi hello_vpi.c
*
* The result is the hello_vpi.vpi module. See the hello_vpi.vl
* program for example Verilog code to call this module.
*/
# include <vpi_user.h>
static int my_hello_calltf(char *xx)
{
vpi_printf("Hello World, from VPI.\n");
return 0;
}
static void my_hello_register()
{
s_vpi_systf_data tf_data;
tf_data.type = vpiSysTask;
tf_data.tfname = "$my_hello";
tf_data.calltf = my_hello_calltf;
tf_data.compiletf = 0;
tf_data.sizetf = 0;
vpi_register_systf(&tf_data);
}
/*
* This is a table of register functions. This table is the external
* symbol that the simulator looks for when loading this .vpi module.
*/
void (*vlog_startup_routines[])() = {
my_hello_register,
0
};
/*
* $Log: hello_vpi.c,v $
* Revision 1.3 2002/08/12 01:35:01 steve
* conditional ident string using autoconfig.
*
* Revision 1.2 2002/08/11 23:47:04 steve
* Add missing Log and Ident strings.
*
* Revision 1.1 2002/04/18 03:25:16 steve
* More examples.
*
*/
+49
View File
@@ -0,0 +1,49 @@
/*
* Copyright (c) 2002 Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
/*
* Here we have the canonical "Hello, World" program written in Verilog,
* with VPI. It uses the hello_vpi.vpi module that is compiled from
* the hello_vpi.c program also in this directory. See the
* hello_vpi.c for instructions on how to compile it.
*
* Compile this program with the command:
*
* iverilog -ohello_vpi hello_vpi.vl
*
* After churning for a little while, the program will create the output
* file "hello" which is compiled, linked and ready to run. Run this
* program like so:
*
* vvp -M. -mhello_vpi hello_vpi
*
* and the program will print the message to its output. Easy! For
* more on how to make the iverilog command work, see the iverilog
* manual page.
*/
module main();
initial
begin
$my_hello;
$finish ;
end
endmodule
+1 -1
View File
@@ -41,7 +41,7 @@
* To view the output generated by running show_vcd, start the GTKWave
* viewer with the command:
*
* wave show_vcd.vcd
* gtkwave show_vcd.vcd
*
* The GTKWave program will display its main window, and show in a small
* status box (upper left corner) that it succeeded in loading the dump
+377
View File
@@ -0,0 +1,377 @@
/*
* Copyright (c) 2002 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
* $Id: sqrt-virtex.v,v 1.2 2002/11/13 01:49:43 steve Exp $"
*/
/*
* This module is a synthesizeable square-root function. It is also a
* detailed example of how to target Xilinx Virtex parts using
* Icarus Verilog. In fact, for no particular reason other then to
* be excessively specific, I will step through the process of
* generating a design for a Spartan-II XC2S15-VQ100, and also how to
* generate a generic library part for larger Virtex designs.
*
* In addition to Icarus Verilog, you will need implementation
* software from Xilinx. As of this writing, this example was tested
* with Foundation 4.2i, but it should work the same with ISE and
* Webpack software.
*
* This example source contains all the Verilog needed to do
* everything described below. We use conditional compilation to
* select the bits of Verilog that are needed to perform each specific
* task.
*
* SIMULATE THE DESIGN
*
* This source file includes a simulation test bench. To compile the
* program to include this test bench, use the command line:
*
* iverilog -DSIMULATE=1 -oa.out sqrt-virtex.v
*
* This generates the file "a.out" that can then be executed with the
* command:
*
* vvp a.out
*
* This causes the simulation to run a long set of example sqrt
* calculations. Each result is checked by the test bench to assure
* that the result is valid. When it is done, the program prints
* "PASSED" and finishes the simulation.
*
* When you take a close look at the "main" module below, you will see
* that it uses Verilog constructs that are not synthesizeable. This
* is fine, as we will never try to synthesize it.
*
* LIBRARY PARTS
*
* One can use the sqrt32 module to generate an EDIF file suitable for
* use as a library part. This part can be imported to the Xilinx
* schematic editor, then placed like any other pre-existing
* macro. One can also pass the generated EDIF as a precompiled macro
* that other designers may use as they see fit.
*
* To make an EDIF file from the sqrt32 module, execute the command:
*
* iverilog -osqrt32.edf -tfpga -parch=virtex sqrt-virtex.v
*
* The -parch=virtex tells the code generator to generate code for the
* virtex architecture family (we don't yet care what specific part)
* and the -osqrt32.edf places the output into the file
* sqrt32.edf.
*
* Without any preprocessor directives, the only module is the sqrt32
* module, so sqrt32 is compiled as the root. The ports of the module
* are automatically made into ports of the sqrt32.edf netlist, and
* the contents of the sqrt32 module are connected approprately.
*
* COMPLETE CHIP DESIGNS
*
* To make a complete chip design, there are other bits that need to
* be accounted for. Signals must be assigned to pins, and some
* special devices may need to be created. We also want to write into
* the EDIF file complete part information so that the implementation
* tools know how to route the complete design. The command to compile
* for our target part is:
*
* iverilog -ochip.edf -tfpga \
* -parch=virtex -ppart=XC2S15-VQ100 \
* -DMAKE_CHIP=1 sqrt-virtex.v
*
* This command uses the "chip" module as the root. This module in
* turn has ports that are destined to be the pins of the completed
* part. The -ppart= option gives complete part information, that is
* in turn written into the EDIF file. This saves us the drudgery of
* repeating that part number for later commands.
*
* The next steps involve Xilinx software, and to talk to Xilinx
* software, the netlist must be in the form of an "ngd" file, a
* binary netlist format. The command:
*
* ngdbuild chip.edf chip.ngd
*
* does the trick. The input to ngdbuild is the chip.edf file created
* by Icarus Verilog, and the output is the chip.ngd file that the
* implementation tools may read. From this point, it is best to refer
* to Xilinx documentation for the software you are using, but the
* quick summary is:
*
* map -o map.ncd chip.ngd
* par -w map.ncd chip.ncd
*
* The result of this sequence of commands is the chip.ncd file that
* is ready to be viewed by FPGA Edit, or converted to a bit stream,
* or whatever.
*
* POST MAP SIMULATION
*
* Warm fuzzies are good, and retesting your design after the part
* is mapped by the Xilinx backend tools is a cheap source of fuzzies.
* The command to make a Verilog file out of the mapped design is:
*
* ngd2ver chip.ngd chip_root.v
*
* This command creates from the chip.ngd the file "chip_root.v" that
* contains Verilog code that simulates the mapped design. This output
* Verilog has the single root module "chip_root", which came from the
* name of the root module when we were making hte EDIF file in the
* first place. The module has ports named just line the ports of the
* chip_root module below.
*
* The generated Verilog uses the library in the directory
* $(XILINX)/verilog/src/simprims. This directory comes with the ISE
* WebPACK installation that you are using. Icarus Verilog is able to
* simulate using that library.
*
* To compile a post-map simulation of the chip_root.v, use the
* command:
*
* iverilog -DSIMULATE -DPOST_MAP -ob.out \
* -y $(XILINX)/verilog/src/simprims \
* sqrt-virtex.v chip_root.v \
* $(XILINX)/verilog/src/glbl.v
*
* This command line generates b.out from the source files
* sqrt-virtex.v and chip_root.v (the latter from ngd2ver)
* and the "-y <path>" flag specifies the library directory that will
* be needed. The glbl.v source file is also included to provide the
* GSR and related signals.
*
* The POST_MAP compiler directive causes the GSR manipulations
* included in the test bench to be compiled in, to simulate the chip
* startup. Other then that, the test bench runs the post-map design
* the same way the pre-synthesis design works.
*
* Run this design with the command:
*
* vvp b.out
*
* And there you go.
*/
`ifndef POST_MAP
/*
* This module approximates the square root of an unsigned 32bit
* number. The algorithm works by doing a bit-wise binary search.
* Starting from the most significant bit, the accumulated value
* tries to put a 1 in the bit position. If that makes the square
* too big for the input, the bit is left zero, otherwise it is set
* in the result. This continues for each bit, decreasing in
* significance, until all the bits are calculated or all the
* remaining bits are zero.
*
* Since the result is an integer, this function really calculates
* value of the expression:
*
* x = floor(sqrt(y))
*
* where sqrt(y) is the exact square root of y and floor(N) is the
* largest integer <= N.
*
* For 32bit numbers, this will never run more then 16 iterations,
* which amounts to 16 clocks.
*/
module sqrt32(clk, rdy, reset, x, .y(acc));
input clk;
output rdy;
input reset;
input [31:0] x;
output [15:0] acc;
// acc holds the accumulated result, and acc2 is the accumulated
// square of the accumulated result.
reg [15:0] acc;
reg [31:0] acc2;
// Keep track of which bit I'm working on.
reg [4:0] bitl;
wire [15:0] bit = 1 << bitl;
wire [31:0] bit2 = 1 << (bitl << 1);
// The output is ready when the bitl counter underflows.
wire rdy = bitl[4];
// guess holds the potential next values for acc, and guess2 holds
// the square of that guess. The guess2 calculation is a little bit
// subtle. The idea is that:
//
// guess2 = (acc + bit) * (acc + bit)
// = (acc * acc) + 2*acc*bit + bit*bit
// = acc2 + 2*acc*bit + bit2
// = acc2 + 2 * (acc<<bitl) + bit
//
// This works out using shifts because bit and bit2 are known to
// have only a single bit in them.
wire [15:0] guess = acc | bit;
wire [31:0] guess2 = acc2 + bit2 + ((acc << bitl) << 1);
(* ivl_synthesis_on *)
always @(posedge clk or posedge reset)
if (reset) begin
acc = 0;
acc2 = 0;
bitl = 15;
end else begin
if (guess2 <= x) begin
acc <= guess;
acc2 <= guess2;
end
bitl <= bitl - 5'd1;
end
endmodule // sqrt32
`endif // `ifndef POST_MAP
`ifdef SIMULATE
/*
* This module is a test bench for the sqrt32 module. It runs some
* test input values through the sqrt32 module, and checks that the
* output is valid. If an invalid output is generated, print and
* error message and stop immediately. If all the tested values pass,
* then print PASSED after the test is complete.
*/
module main;
reg [31:0] x;
reg clk, reset;
wire [15:0] y;
wire rdy;
`ifdef POST_MAP
chip_root dut(.clk(clk), .reset(reset), .rdy(rdy), .x(x), .y(y));
`else
sqrt32 dut(.clk(clk), .reset(reset), .rdy(rdy), .x(x), .y(y));
`endif
(* ivl_synthesis_off *)
always #5 clk = !clk;
task reset_dut;
begin
reset = 1;
#1 reset = 0;
@(negedge clk) ;
end
endtask // reset_dut
task crank_dut;
begin
while (rdy == 0) begin
@(posedge clk) /* wait */;
end
end
endtask // crank_dut
`ifdef POST_MAP
reg GSR;
assign glbl.GSR = GSR;
`endif
integer idx;
(* ivl_synthesis_off *)
initial begin
reset = 0;
clk = 0;
/* If doing a post-map simulation, when we need to wiggle
The GSR bit to simulate chip power-up. */
`ifdef POST_MAP
GSR = 1;
#100 GSR = 0;
`endif
#100 x = 1;
reset_dut;
crank_dut;
$display("x=%d, y=%d", x, y);
x = 3;
reset_dut;
crank_dut;
$display("x=%d, y=%d", x, y);
x = 4;
reset_dut;
crank_dut;
$display("x=%d, y=%d", x, y);
for (idx = 0 ; idx < 200 ; idx = idx + 1) begin
x = $random;
reset_dut;
crank_dut;
$display("x=%d, y=%d", x, y);
if (x < (y * y)) begin
$display("ERROR: y is too big");
$finish;
end
if (x > ((y + 1)*(y + 1))) begin
$display("ERROR: y is too small");
$finish;
end
end
$display("PASSED");
$finish;
end
endmodule // main
`endif
`ifdef MAKE_CHIP
/*
* This module represents the chip packaging that we intend to
* generate. We bind pins here, and route the clock to the global
* clock buffer.
*/
module chip_root(clk, rdy, reset, x, y);
input clk;
output rdy;
input reset;
input [31:0] x;
output [15:0] y;
wire clk_int;
(* cellref="BUFG:O,I" *)
buf gbuf (clk_int, clk);
sqrt32 dut(.clk(clk_int), .reset(reset), .rdy(rdy), .x(x), .y(y));
/* Assign the clk to GCLK0, which is on pin P39. */
$attribute(clk, "PAD", "39");
// We don't care where the remaining pins go, so set the pin number
// to 0. This tells the implementation tools that we want a PAD,
// but we don't care which. Also note the use of a comma (,)
// separated list to assign pins to the bits of a vector.
$attribute(rdy, "PAD", "0");
$attribute(reset, "PAD", "0");
$attribute(x, "PAD", "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0");
$attribute(y, "PAD", "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0");
endmodule // chip_root
`endif
+54
View File
@@ -0,0 +1,54 @@
/*
* Copyright (c) 1999 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
// This example describes a 16x1 RAM that can be synthesized into
// a CLB ram in a Xilinx FPGA.
module ram16x1 (q, d, a, we, wclk);
output q;
input d;
input [3:0] a;
input we;
input wclk;
reg mem[15:0];
assign q = mem[a];
always @(posedge wclk) if (we) mem[a] = d;
endmodule /* ram16x1 */
module main;
wire q;
reg d;
reg [3:0] a;
reg we, wclk;
ram16x1 r1 (q, d, a, we, wclk);
initial begin
$monitor("q = %b", q);
d = 0;
wclk = 0;
a = 5;
we = 1;
#1 wclk = 1;
#1 wclk = 0;
end
endmodule /* main */
+139 -15
View File
@@ -16,8 +16,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: expr_synth.cc,v 1.26 2001/08/31 22:59:48 steve Exp $"
#ifdef HAVE_CVS_IDENT
#ident "$Id: expr_synth.cc,v 1.37 2002/11/17 23:37:55 steve Exp $"
#endif
# include "config.h"
@@ -50,6 +50,7 @@ NetNet* NetEBAdd::synthesize(Design*des)
string path = lsig->scope()->name()+"."+lsig->scope()->local_symbol();
NetNet*osig = new NetNet(lsig->scope(), path, NetNet::IMPLICIT, width);
osig->local_flag(true);
string oname = des->local_symbol(path);
NetAddSub *adder = new NetAddSub(lsig->scope(), oname, width);
@@ -62,10 +63,10 @@ NetNet* NetEBAdd::synthesize(Design*des)
switch (op()) {
case '+':
adder->attribute("LPM_Direction", "ADD");
adder->attribute("LPM_Direction", verinum("ADD"));
break;
case '-':
adder->attribute("LPM_Direction", "SUB");
adder->attribute("LPM_Direction", verinum("SUB"));
break;
}
@@ -107,6 +108,26 @@ NetNet* NetEBBits::synthesize(Design*des)
string oname = des->local_symbol(path);
NetLogic*gate;
/* If the rsig bit is constant, then look for special
cases that I can use to reduce the generated
logic. If I find one, then handle it immediately and
skip the rest of the processing of this bit. */
if (rsig->pin(idx).nexus()->drivers_constant()) {
verinum::V bval = rsig->pin(idx).nexus()->driven_value();
/* (A & 0) is (0) */
if ((op() == '&') && bval == verinum::V0) {
connect(osig->pin(idx), rsig->pin(idx));
continue;
}
/* (A & 1) is A */
if ((op() == '&') && bval == verinum::V1) {
connect(osig->pin(idx), lsig->pin(idx));
continue;
}
}
switch (op()) {
case '&':
gate = new NetLogic(scope, oname, 3, NetLogic::AND);
@@ -171,6 +192,33 @@ NetNet* NetEBComp::synthesize(Design*des)
gate = new NetLogic(scope, des->local_symbol(path),
lsig->pin_count()+1, NetLogic::OR);
break;
case '>':
/* sig > 0 is true if any bit in sig is set. This
is very much like sig != 0. (0 > sig) shouldn't
happen. */
if (rcon) {
gate = new NetLogic(scope, des->local_symbol(path),
lsig->pin_count()+1, NetLogic::OR);
} else {
assert(0);
gate = new NetLogic(scope, des->local_symbol(path),
lsig->pin_count()+1, NetLogic::NOR);
}
break;
case '<':
/* 0 < sig is handled like sig > 0. */
if (! rcon) {
gate = new NetLogic(scope, des->local_symbol(path),
lsig->pin_count()+1, NetLogic::OR);
} else {
assert(0);
gate = new NetLogic(scope, des->local_symbol(path),
lsig->pin_count()+1, NetLogic::NOR);
}
break;
default:
assert(0);
}
@@ -353,27 +401,36 @@ NetNet* NetEBLogic::synthesize(Design*des)
NetNet* NetEConcat::synthesize(Design*des)
{
NetScope*scope = des->find_root_scope();
assert(scope);
assert(repeat_ == 1);
/* First, synthesize the operands. */
NetNet**tmp = new NetNet*[parms_.count()];
for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1)
tmp[idx] = parms_[idx]->synthesize(des);
assert(tmp[0]);
NetScope*scope = tmp[0]->scope();
assert(scope);
/* Make a NetNet object to carry the output vector. */
string path = scope->name() + "." + scope->local_symbol();
NetNet*osig = new NetNet(scope, path, NetNet::IMPLICIT, expr_width());
osig->local_flag(true);
/* Connect the output vector to the operands. */
unsigned obit = 0;
for (unsigned idx = parms_.count() ; idx > 0 ; idx -= 1) {
NetNet*tmp = parms_[idx-1]->synthesize(des);
for (unsigned bit = 0 ; bit < tmp->pin_count() ; bit += 1) {
connect(osig->pin(obit), tmp->pin(bit));
assert(tmp[idx-1]);
for (unsigned bit = 0; bit < tmp[idx-1]->pin_count(); bit += 1) {
connect(osig->pin(obit), tmp[idx-1]->pin(bit));
obit += 1;
}
if (tmp->local_flag() && tmp->get_eref() == 0)
delete tmp;
if (tmp[idx-1]->local_flag() && tmp[idx-1]->get_refs() == 0)
delete tmp[idx-1];
}
delete[]tmp;
return osig;
}
@@ -387,7 +444,7 @@ NetNet* NetEConst::synthesize(Design*des)
NetNet*osig = new NetNet(scope, path, NetNet::IMPLICIT, width);
osig->local_flag(true);
NetConst*con = new NetConst(des->local_symbol(path), value());
NetConst*con = new NetConst(scope, des->local_symbol(path), value());
for (unsigned idx = 0 ; idx < width; idx += 1)
connect(osig->pin(idx), con->pin(idx));
@@ -458,6 +515,26 @@ NetNet* NetEUReduce::synthesize(Design*des)
NetLogic::AND);
break;
case '|':
gate = new NetLogic(scope, oname, isig->pin_count()+1,
NetLogic::OR);
break;
case '^':
gate = new NetLogic(scope, oname, isig->pin_count()+1,
NetLogic::XOR);
break;
case 'A':
gate = new NetLogic(scope, oname, isig->pin_count()+1,
NetLogic::NAND);
break;
case 'X':
gate = new NetLogic(scope, oname, isig->pin_count()+1,
NetLogic::XNOR);
break;
default:
cerr << get_line() << ": internal error: "
<< "Unable to synthesize " << *this << "." << endl;
@@ -472,7 +549,12 @@ NetNet* NetEUReduce::synthesize(Design*des)
return osig;
}
/*
* Synthesize a ?: operator an a NetMux device. Connect the condition
* expression to the select input, then connect the true and false
* expressions to the B and A inputs. This way, when the select input
* is one, the B input, which is the true expression, is selected.
*/
NetNet* NetETernary::synthesize(Design *des)
{
NetNet*csig = cond_->synthesize(des);
@@ -501,7 +583,7 @@ NetNet* NetETernary::synthesize(Design *des)
}
/*
* When synthesizing a signal expressoin, it is usually fine to simply
* When synthesizing a signal expression, it is usually fine to simply
* return the NetNet that it refers to. If this is a part select,
* though, a bit more work needs to be done. Return a temporary that
* represents the connections to the selected bits.
@@ -553,6 +635,48 @@ NetNet* NetESignal::synthesize(Design*des)
/*
* $Log: expr_synth.cc,v $
* Revision 1.37 2002/11/17 23:37:55 steve
* Magnitude compare to 0.
*
* Revision 1.36 2002/08/12 01:34:59 steve
* conditional ident string using autoconfig.
*
* Revision 1.35 2002/07/07 22:31:39 steve
* Smart synthesis of binary AND expressions.
*
* Revision 1.34 2002/07/05 21:26:17 steve
* Avoid emitting to vvp local net symbols.
*
* Revision 1.33 2002/05/26 01:39:02 steve
* Carry Verilog 2001 attributes with processes,
* all the way through to the ivl_target API.
*
* Divide signal reference counts between rval
* and lval references.
*
* Revision 1.32 2002/05/23 03:08:51 steve
* Add language support for Verilog-2001 attribute
* syntax. Hook this support into existing $attribute
* handling, and add number and void value types.
*
* Add to the ivl_target API new functions for access
* of complex attributes attached to gates.
*
* Revision 1.31 2001/12/30 17:06:52 steve
* Synthesize reduction logic.
*
* Revision 1.30 2001/12/18 05:34:02 steve
* Comments about MUX synthesis.
*
* Revision 1.29 2001/11/29 01:58:18 steve
* Handle part selects in l-values of DFF devices.
*
* Revision 1.28 2001/10/28 01:14:53 steve
* NetObj constructor finally requires a scope.
*
* Revision 1.27 2001/10/20 05:21:51 steve
* Scope/module names are char* instead of string.
*
* Revision 1.26 2001/08/31 22:59:48 steve
* synthesize the special case of compare with 0.
*
+49 -118
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1999-2000 Stephen Williams (steve@icarus.com)
* Copyright (c) 1999-2002 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -16,8 +16,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: functor.cc,v 1.25 2001/07/25 03:10:49 steve Exp $"
#ifdef HAVE_CVS_IDENT
#ident "$Id: functor.cc,v 1.31 2002/08/16 05:18:27 steve Exp $"
#endif
# include "config.h"
@@ -114,7 +114,9 @@ void NetScope::run_functor(Design*des, functor_t*fun)
void Design::functor(functor_t*fun)
{
// Scan the scopes
root_scope_->run_functor(this, fun);
for (list<NetScope*>::const_iterator scope = root_scopes_.begin();
scope != root_scopes_.end(); scope++)
(*scope)->run_functor(this, fun);
// apply to processes
procs_idx_ = procs_;
@@ -126,30 +128,31 @@ void Design::functor(functor_t*fun)
// apply to nodes
if (nodes_) {
assert(nodes_functor_cur_ == 0);
assert(nodes_functor_nxt_ == 0);
/* Scan the circular list of nodes, starting with the
front of the list. (nodes_ points to the *end* of the
list.) The bar is the end point. At the end of the
do-while loop, I know that the bar has been
processed or (if bar == 0) no undeleted node has been
processed. */
NetNode*cur = nodes_->node_next_;
NetNode*bar = 0;
front of the list.
This loop interacts with the Design::del_node method
so that the functor is free to delete any nodes it
choose. The destructors of the NetNode objects call
the del_node method, which checks with the
nodes_functor_* members, to keep the iterator
operating safely. */
nodes_functor_cur_ = nodes_;
do {
NetNode*tmp = cur->node_next_;
cur->functor_node(this, fun);
nodes_functor_nxt_ = nodes_functor_cur_->node_next_;
nodes_functor_cur_->functor_node(this, fun);
/* Detect the case that cur has been deleted by
noticing if tmp->node_prev_ no longer points to
cur. If that's the case, clear the bar. */
if (tmp->node_prev_ != cur) {
if (cur == bar)
bar = 0;
} else if (bar == 0) {
bar = cur;
}
cur = tmp;
if (nodes_functor_nxt_ == 0)
break;
nodes_functor_cur_ = nodes_functor_nxt_;
} while (nodes_ && (nodes_functor_cur_ != nodes_));
nodes_functor_cur_ = 0;
nodes_functor_nxt_ = 0;
} while (nodes_ && (cur != bar));
}
}
@@ -232,35 +235,13 @@ int NetAssignNB::match_proc(proc_match_t*that)
return that->assign_nb(this);
}
int proc_match_t::assign_mem(NetAssignMem*)
{
return 0;
}
int NetAssignMem::match_proc(proc_match_t*that)
{
return that->assign_mem(this);
}
int proc_match_t::assign_mem_nb(NetAssignMemNB*)
{
return 0;
}
int NetAssignMemNB::match_proc(proc_match_t*that)
{
return that->assign_mem_nb(this);
}
int proc_match_t::block(NetBlock*)
{
cerr << "default (failing) match for block" << endl;
return 0;
}
int NetBlock::match_proc(proc_match_t*that)
{
cerr << "NetBlock::match_proc" << endl;
return that->block(this);
}
@@ -286,6 +267,28 @@ int proc_match_t::event_wait(NetEvWait*)
/*
* $Log: functor.cc,v $
* Revision 1.31 2002/08/16 05:18:27 steve
* Fix intermix of node functors and node delete.
*
* Revision 1.30 2002/08/12 01:34:59 steve
* conditional ident string using autoconfig.
*
* Revision 1.29 2002/08/10 22:07:38 steve
* Remove useless error messages.
*
* Revision 1.28 2002/06/05 03:44:25 steve
* Add support for memory words in l-value of
* non-blocking assignments, and remove the special
* NetAssignMem_ and NetAssignMemNB classes.
*
* Revision 1.27 2002/06/04 05:38:44 steve
* Add support for memory words in l-value of
* blocking assignments, and remove the special
* NetAssignMem class.
*
* Revision 1.26 2001/10/19 21:53:24 steve
* Support multiple root modules (Philip Blundell)
*
* Revision 1.25 2001/07/25 03:10:49 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
@@ -301,77 +304,5 @@ int proc_match_t::event_wait(NetEvWait*)
*
* Revision 1.21 2000/08/01 02:48:41 steve
* Support <= in synthesis of DFF and ram devices.
*
* Revision 1.20 2000/07/16 04:56:07 steve
* Handle some edge cases during node scans.
*
* Revision 1.19 2000/07/15 05:13:43 steve
* Detect muxing Vz as a bufufN.
*
* Revision 1.18 2000/05/02 00:58:12 steve
* Move signal tables to the NetScope class.
*
* Revision 1.17 2000/04/20 00:28:03 steve
* Catch some simple identity compareoptimizations.
*
* Revision 1.16 2000/04/18 04:50:19 steve
* Clean up unneeded NetEvent objects.
*
* Revision 1.15 2000/04/16 23:32:18 steve
* Synthesis of comparator in expressions.
*
* Connect the NetEvent and related classes
* together better.
*
* Revision 1.14 2000/04/12 20:02:53 steve
* Finally remove the NetNEvent and NetPEvent classes,
* Get synthesis working with the NetEvWait class,
* and get started supporting multiple events in a
* wait in vvm.
*
* Revision 1.13 2000/04/01 21:40:22 steve
* Add support for integer division.
*
* Revision 1.12 2000/02/23 02:56:54 steve
* Macintosh compilers do not support ident.
*
* Revision 1.11 2000/02/13 04:35:43 steve
* Include some block matching from Larry.
*
* Revision 1.10 2000/01/13 03:35:35 steve
* Multiplication all the way to simulation.
*
* Revision 1.9 2000/01/02 17:57:20 steve
* Handle nodes running out during node scan.
*
* Revision 1.8 1999/12/30 04:19:12 steve
* Propogate constant 0 in low bits of adders.
*
* Revision 1.7 1999/12/17 06:18:16 steve
* Rewrite the cprop functor to use the functor_t interface.
*
* Revision 1.6 1999/12/05 02:24:08 steve
* Synthesize LPM_RAM_DQ for writes into memories.
*
* Revision 1.5 1999/12/01 06:06:16 steve
* Redo synth to use match_proc_t scanner.
*
* Revision 1.4 1999/11/18 03:52:19 steve
* Turn NetTmp objects into normal local NetNet objects,
* and add the nodangle functor to clean up the local
* symbols generated by elaboration and other steps.
*
* Revision 1.3 1999/11/01 02:07:40 steve
* Add the synth functor to do generic synthesis
* and add the LPM_FF device to handle rows of
* flip-flops.
*
* Revision 1.2 1999/07/18 05:52:46 steve
* xnfsyn generates DFF objects for XNF output, and
* properly rewrites the Design netlist in the process.
*
* Revision 1.1 1999/07/17 22:01:13 steve
* Add the functor interface for functor transforms.
*
*/
+15 -31
View File
@@ -18,8 +18,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: functor.h,v 1.17 2000/09/17 21:26:15 steve Exp $"
#ifdef HAVE_CVS_IDENT
#ident "$Id: functor.h,v 1.20 2002/08/12 01:34:59 steve Exp $"
#endif
/*
@@ -83,9 +83,7 @@ struct proc_match_t {
virtual ~proc_match_t();
virtual int assign(class NetAssign*);
virtual int assign_mem(class NetAssignMem*);
virtual int assign_nb(class NetAssignNB*);
virtual int assign_mem_nb(class NetAssignMemNB*);
virtual int condit(class NetCondit*);
virtual int event_wait(class NetEvWait*);
virtual int block(class NetBlock*);
@@ -94,6 +92,19 @@ struct proc_match_t {
/*
* $Log: functor.h,v $
* Revision 1.20 2002/08/12 01:34:59 steve
* conditional ident string using autoconfig.
*
* Revision 1.19 2002/06/05 03:44:25 steve
* Add support for memory words in l-value of
* non-blocking assignments, and remove the special
* NetAssignMem_ and NetAssignMemNB classes.
*
* Revision 1.18 2002/06/04 05:38:44 steve
* Add support for memory words in l-value of
* blocking assignments, and remove the special
* NetAssignMem class.
*
* Revision 1.17 2000/09/17 21:26:15 steve
* Add support for modulus (Eric Aardoom)
*
@@ -108,32 +119,5 @@ struct proc_match_t {
*
* Revision 1.13 2000/04/20 00:28:03 steve
* Catch some simple identity compareoptimizations.
*
* Revision 1.12 2000/04/18 04:50:19 steve
* Clean up unneeded NetEvent objects.
*
* Revision 1.11 2000/04/12 20:02:53 steve
* Finally remove the NetNEvent and NetPEvent classes,
* Get synthesis working with the NetEvWait class,
* and get started supporting multiple events in a
* wait in vvm.
*
* Revision 1.10 2000/04/01 21:40:22 steve
* Add support for integer division.
*
* Revision 1.9 2000/02/23 02:56:54 steve
* Macintosh compilers do not support ident.
*
* Revision 1.8 2000/02/13 04:35:43 steve
* Include some block matching from Larry.
*
* Revision 1.7 2000/01/13 03:35:35 steve
* Multiplication all the way to simulation.
*
* Revision 1.6 1999/12/30 04:19:12 steve
* Propogate constant 0 in low bits of adders.
*
* Revision 1.5 1999/12/17 06:18:16 steve
* Rewrite the cprop functor to use the functor_t interface.
*/
#endif
+106 -5
View File
@@ -86,7 +86,7 @@ tool so it is not clear that the standard really is at fault. It is
clear, however, that somebody goofed somewhere.
My personal opinion is that there is no logical need to require that
all module_item_declarations preceed any other module items. I
all module_item_declarations precede any other module items. I
personally would oppose such a restriction. It may make sense to
require that declarations of variables within a module be preceded by
their use, although even that is not necessary for the implementation
@@ -97,7 +97,7 @@ sample2 can have implications that affect any declaration order
rules. When reaching into a module with a hierarchical name, the
module being referenced is already completely declared (or not
declared at all, as in sample2) so module_item order is completely
irrelevent. But a "declare before use" rule would infect module
irrelevant. But a "declare before use" rule would infect module
ordering, by requiring that modules that are used be first defined.
@@ -141,7 +141,7 @@ ports.
With the above in mind, I have decided to *allow* function and task
ports to be declared with types, as long as the types are variable
types, such ag reg or integer. Without this, there would be no
types, such as reg or integer. Without this, there would be no
portable way to pass integers into functions/tasks. The standard does
not say it is allowed, but it doesn't *disallow* it, and other
commercial tools seem to work similarly.
@@ -172,7 +172,7 @@ take it that x is allowed, as that is what Verilog-XL does.
There seems to be ambiguity in how code like this should be parsed:
repeat (5) @(posedge clk) <statment>;
repeat (5) @(posedge clk) <statement>;
There are two valid interpretations of this code, from the
IEEE1364-1995 standard. One looks like this:
@@ -318,8 +318,109 @@ the right length, and will therefore flag instances u5 and u6 as
errors. The IEEE1364 standard should be more specific one way or the
other.
$Id: ieee1364-notes.txt,v 1.8 2001/08/01 05:17:31 steve Exp $
* UNKNOWN VALUES IN L-VALUE BIT SELECTS
Consider this example:
reg [7:0] vec;
wire [4:0] idx = <expr>;
[...]
vec[idx] = 1;
So long as the value of idx is a valid bit select address, the
behavior of this assignment is obvious. However, there is no explicit
word in the standard as to what happens if the value is out of
range. The standard clearly states the value of an expression when the
bit-select or part select is out of range (the value is x) but does
not address the behavior when the expression is an l-value.
Icarus Verilog will take the position that bit select expressions in
the l-value will select oblivion if it is out of range. That is, if
idx has a value that is not a valid bit select of vec, then the
assignment will have no effect.
* SCHEDULING VALUES IN LOGIC
The interaction between blocking assignments in procedural code and
logic gates in gate-level code and expressions is poorly defined in
Verilog. Consider this example:
reg a;
reg b;
wire q = a & b;
initial begin
a = 1;
b = 0;
#1 b = 1;
if (q !== 0) begin
$display("FAILED -- q changed too soon? %b", q);
$finish;
end
end
This is a confusing situation. It is clear from the Verilog standard
that an assignment to a variable using a blocking assign causes the
l-value to receive the value before the assignment completes. This
means that a subsequent read of the assigned variable *must* read back
what was blocking-assigned.
However, in the example above, the "wire q = a & b" expresses some
gate logic between a/b and q. The standard does not say whether a read
out of logic should read the value computed from previous assigns to
the input from the same thread. Specifically, when "a" and "b" are
assigned by blocking assignments, will a read of "q" get the computed
value or the existing value?
In fact, existing commercial tools do it both ways. Some tools print
the FAILED message in the above example, and some do not. Icarus
Verilog does not print the FAILED message in the above example,
because the gate value change is *scheduled* when inputs are assigned,
but not propagated until the thread gives up the processor.
Icarus Verilog chooses this behavior in order to filter out zero-width
pulses as early as possible. The implication of this is that a read of
the output of combinational logic will most likely *not* reflect the
changes in inputs until the thread that changed the inputs yields
execution.
* BIT AND PART SELECTS OF PARAMETERS
Bit and part selects are supposed to only be supported on vector nets
and variables (wires, regs, etc.) However, it is common for Verilog
compilers to also support bit and part select on parameters. Icarus
Verilog also chooses to support bit and part selects on parameter
names, but we need to define what that means.
A bit or a part select on a parameter expression returns an unsigned
value with a defined size. The parameter value is considered be a
constant vector of bits foo[X:0]. That is, zero based. The bit and
part selects operate from that assumption.
Verilog 2001 adds syntax to allow the user to explicitly declare the
parameter range (i.e. parameter [5:0] foo = 9;) so Icarus Verilog will
(or should) use the explicitly declared vector dimensions to interpret
bit and part selects.
$Id: ieee1364-notes.txt,v 1.13 2002/08/20 04:11:53 steve Exp $
$Log: ieee1364-notes.txt,v $
Revision 1.13 2002/08/20 04:11:53 steve
Support parameters with defined ranges.
Revision 1.12 2002/06/11 03:34:33 steve
Spelling patch (Larry Doolittle)
Revision 1.11 2002/04/27 02:38:04 steve
Support selecting bits from parameters.
Revision 1.10 2002/03/31 01:54:13 steve
Notes about scheduling
Revision 1.9 2002/01/26 02:08:07 steve
Handle x in l-value of set/x
Revision 1.8 2001/08/01 05:17:31 steve
Accept empty port lists to module instantiation.
+72
View File
@@ -0,0 +1,72 @@
.TH iverilog-vpi 1 "$Date: 2002/11/23 00:51:53 $" Version "$Date: 2002/11/23 00:51:53 $"
.SH NAME
iverilog-vpi - Compile front end for VPI modules
.SH SYNOPSIS
.B iverilog-vpi
[--name=\fIname\fP]
\fIsourcefile\fP...
.SH DESCRIPTION
.PP
\fIiverilog-vpi\fP is a tool to simplify the compilation of VPI
modules for use with Icarus Verilog. It takes on the command line a
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.
.SH OPTIONS
.l
\fIiverilog-vpi\fP accepts the following options:
.TP 8
.B -l\fIlibrary\fP
Include the named library in the link of the VPI module. This allows
VPI modules to further reference external libraries.
.TP 8
.B --name=\fIname\fP
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.
.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.
.TP 8
.B -mingw=\fIpath\fP
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 notmally 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.
.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 "AUTHOR"
.nf
Steve Williams ([email protected])
.SH SEE ALSO
iverilog(1), vvp(1),
.BR "<http://www.icarus.com/eda/verilog/>",
.BR "<http://www.mingw.org>",
.SH COPYRIGHT
.nf
Copyright \(co 2002 Stephen Williams
This document can be freely redistributed according to the terms of the
GNU General Public License version 2.0
+114
View File
@@ -0,0 +1,114 @@
#!/bin/sh
#
# This source code is free software; you can redistribute it
# and/or modify it in source code form under the terms of the GNU
# Library General Public License as published by the Free Software
# Foundation; either version 2 of the License, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Library General Public License for more details.
#
# You should have received a copy of the GNU Library General Public
# License along with this program; if not, write to the Free
# Software Foundation, Inc.,
# 59 Temple Place - Suite 330
# Boston, MA 02111-1307, USA
#
#ident "$Id: iverilog-vpi.sh,v 1.9 2002/10/19 23:18:52 steve Exp $"
# These are the variables used for compiling files
CC=gcc
CXX=gcc
CFLAGS="@PIC@ -O -I@INCLUDEDIR@"
# These are used for linking...
LD=gcc
LDFLAGS="@SHARED@"
LDLIBS="-L@LIBDIR@ -lveriuser -lvpi"
CCSRC=
CXSRC=
OBJ=
LIB=
OUT=
# --
# parse the command line switches. This collects the source files
# and precompiled object files, and maybe user libraries. As we are
# going, guess an output file name.
for parm
do
case $parm
in
*.c) CCSRC="$CCSRC $parm"
if [ x$OUT = x ]; then
OUT=`basename $parm .c`
fi
;;
*.cc) CXSRC="$CXSRC $parm"
if [ x$OUT = x ]; then
OUT=`basename $parm .cc`
fi
;;
*.o) OBJ="$OBJ $parm"
if [ x$OUT = x ]; then
OUT=`basename $parm .o`
fi
;;
--name=*)
OUT=`echo $parm | cut -b8-`
;;
-l*) LIB="$LIB $parm"
;;
esac
done
if [ x$OUT = x ]; then
echo "Usage: $0 [src and obj files]..."
exit 0
fi
# Put the .vpi on the result file.
OUT=$OUT".vpi"
compile_errors=0
# Compile all the source files into object files
for src in $CCSRC
do
base=`basename $src .c`
obj=$base".o"
echo "Compiling $src..."
$CC -c -o $obj $CFLAGS $src || compile_errors=`expr $compile_errors + 1`
OBJ="$OBJ $obj"
done
for src in $CXSRC
do
base=`basename $src .cc`
obj=$base".o"
echo "Compiling $src..."
$CXX -c -o $obj $CFLAGS $src || compile_errors=`expr $compile_errors + 1`
OBJ="$OBJ $obj"
done
if test $compile_errors -gt 0
then
echo "Some ($compile_errors) files failed to compile."
exit $compile_errors
fi
echo "Making $OUT from $OBJ..."
exec $LD -o $OUT $LDFLAGS $OBJ $LIB $LDLIBS
+13 -17
View File
@@ -28,10 +28,16 @@
#
# %B Substitute the base libdir, -B flag of iverilog.
#
# %C Substitute the path to the temporary config file.
#
# %f Substitute the -f flags from the command line.
#
# %g Substitule the -g flag
#
# %s Substitute the start module (-s flag) from the user.
#
# %M Substitute the value of the -M<depfile> flag.
#
# %N Substitute the value of the -N<path> flag.
#
# %o Substitute the value of the -o<path> flag, or the default
@@ -56,42 +62,32 @@
# be useful and interesting if the -N flag is included.
[-tnull -S]
<ivl>%B/ivl %[v-v] %W %[s-s%s] %[N-N%N] %[T-T%T] -tdll -fDLL=%B/null.tgt -- -
<ivl>%B/ivl %[v-v] -C%C %g %W %s %[M-M%M] %[N-N%N] %[T-T%T] -tdll -fDLL=%B/null.tgt -Fsynth -Fsyn-rules -- -
[-tnull]
<ivl>%B/ivl %[v-v] %W %[s-s%s] %[N-N%N] %[T-T%T] -tdll -fDLL=%B/null.tgt -- -
<ivl>%B/ivl %[v-v] -C%C %g %W %s %[M-M%M] %[N-N%N] %[T-T%T] -tdll -fDLL=%B/null.tgt -- -
# --
# The vvp target generates code that the vvp simulation engine can execute.
# These rules support synthesized and non-synthesized variants.
[-tvvp -S]
<ivl>%B/ivl %[v-v] %W %[s-s%s] %[N-N%N] %[T-T%T] -tdll -fDLL=%B/vvp.tgt -fVVP_EXECUTABLE=%B/../../bin/vvp -Fsynth -Fsyn-rules -Fcprop -Fnodangle %f %m -o%o -- -
<ivl>%B/ivl %[v-v] -C%C %g %W %s %[M-M%M] %[N-N%N] %[T-T%T] -tdll -fDLL=%B/vvp.tgt -fVVP_EXECUTABLE=%B/../../bin/vvp -Fsynth2 -Fsynth -Fsyn-rules -Fcprop -Fnodangle %f %m -o%o -- -
[-tvvp]
<ivl>%B/ivl %[v-v] %W %[s-s%s] %[N-N%N] %[T-T%T] -tdll -fDLL=%B/vvp.tgt -fVVP_EXECUTABLE=%B/../../bin/vvp -Fcprop -Fnodangle %f %m -o%o -- -
# --
# The vvm target uses the <ivl> string to take the preprocessed code from
# standard input, compile it with the vvm code generator and write the
# result to %o.cc. The driver assumes this when invoking the C++ compiler
# on the result.
[-tvvm]
<ivl>%B/ivl %[v-v] %W %[s-s%s] %[N-N%N] %[T-T%T] -tvvm -Fcprop -Fnodangle -fVPI_MODULE_PATH=%B %f %m -o%o.cc -- -
<ivl>%B/ivl %[v-v] -C%C %g %W %s %[M-M%M] %[N-N%N] %[T-T%T] -tdll -fDLL=%B/vvp.tgt -fVVP_EXECUTABLE=%B/../../bin/vvp -Fcprop -Fnodangle %f %m -o%o -- -
# This is the XNF code generator.
[-txnf]
<ivl>%B/ivl %[v-v] %[s-s%s] %[N-N%N] %[T-T%T] -txnf -Fsynth -Fsyn-rules -Fcprop -Fnodangle -o%o -- -
<ivl>%B/ivl -C%C %[v-v] %g %s %[M-M%M] %[N-N%N] %[T-T%T] -txnf -Fsynth -Fsyn-rules -Fxnfio -Fcprop -Fnodangle -o%o -- -
# And this is another XNF code generator, under development.
[-tfpga]
<ivl>%B/ivl %[v-v] %[s-s%s] %[N-N%N] %[T-T%T] %f -tdll -fDLL=%B/fpga.tgt -Fsynth -Fsyn-rules -Fcprop -Fnodangle -o%o -- -
<ivl>%B/ivl -C%C %[v-v] %g %s %[M-M%M] %[N-N%N] %[T-T%T] %f -tdll -fDLL=%B/fpga.tgt -Fsynth2 -Fsynth -Fsyn-rules -Fcprop -Fnodangle -o%o -- -
# --
# This is the pal code generator. The target module requires the -fpart=<type>
# flag to specify the part type.
[-tpal]
<ivl>%B/ivl %[v-v] %[s-s%s] %[N-N%N] %[T-T%T] -tdll -fDLL=%B/pal.tgt -Fsynth -Fsyn-rules -Fcprop -Fnodangle -o%o -- -
<ivl>%B/ivl -C%C %[v-v] %g %s %[M-M%M] %[N-N%N] %[T-T%T] %f -tdll -fDLL=%B/pal.tgt -Fsynth -Fsyn-rules -Fcprop -Fnodangle -o%o -- -
+20 -1
View File
@@ -5,6 +5,7 @@ ivl_design_consts
ivl_design_flag
ivl_design_process
ivl_design_root
ivl_design_roots
ivl_design_time_precision
ivl_const_bits
@@ -41,6 +42,10 @@ ivl_expr_string
ivl_expr_uvalue
ivl_expr_width
ivl_logic_attr
ivl_logic_attr_cnt
ivl_logic_attr_val
ivl_logic_delay
ivl_logic_name
ivl_logic_basename
ivl_logic_scope
@@ -49,11 +54,16 @@ ivl_logic_pin
ivl_logic_pins
ivl_logic_udp
ivl_lpm_aset_value
ivl_lpm_async_clr
ivl_lpm_async_set
ivl_lpm_basename
ivl_lpm_clk
ivl_lpm_data
ivl_lpm_datab
ivl_lpm_data2
ivl_lpm_data2_width
ivl_lpm_define
ivl_lpm_enable
ivl_lpm_memory
ivl_lpm_name
@@ -74,8 +84,8 @@ ivl_lval_pins
ivl_lval_sig
ivl_memory_basename
ivl_memory_name
ivl_memory_root
ivl_memory_scope
ivl_memory_size
ivl_memory_width
@@ -114,6 +124,10 @@ ivl_scope_type
ivl_scope_tname
ivl_signal_attr
ivl_signal_attr_cnt
ivl_signal_attr_val
ivl_signal_integer
ivl_signal_local
ivl_signal_pin
ivl_signal_pins
ivl_signal_port
@@ -122,6 +136,8 @@ ivl_signal_type
ivl_signal_name
ivl_signal_basename
ivl_process_attr_cnt
ivl_process_attr_val
ivl_process_scope
ivl_process_stmt
ivl_process_type
@@ -129,6 +145,7 @@ ivl_process_type
ivl_statement_type
ivl_stmt_block_count
ivl_stmt_block_scope
ivl_stmt_block_stmt
ivl_stmt_call
ivl_stmt_case_count
@@ -144,6 +161,8 @@ ivl_stmt_lval
ivl_stmt_lvals
ivl_stmt_lwidth
ivl_stmt_name
ivl_stmt_nexus
ivl_stmt_nexus_count
ivl_stmt_parm
ivl_stmt_parm_count
ivl_stmt_rval
+249 -261
View File
@@ -18,8 +18,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: ivl_target.h,v 1.80 2001/09/01 01:57:31 steve Exp $"
#ifdef HAVE_CVS_IDENT
#ident "$Id: ivl_target.h,v 1.108 2002/10/23 01:47:17 steve Exp $"
#endif
#ifdef __cplusplus
@@ -98,7 +98,7 @@ _BEGIN_DECL
* ivl_process_t
* A Verilog process is represented by one of these. A process may
* be an "initial" or an "always" process. These come from initial
* or always statements from the verilog source.
* or always statements from the Verilog source.
*
* ivl_scope_t
* Elaborated scopes within a design are represented by this
@@ -164,6 +164,7 @@ typedef enum ivl_expr_type_e {
IVL_EX_MEMORY,
IVL_EX_NUMBER,
IVL_EX_SCOPE,
IVL_EX_SELECT,
IVL_EX_SFUNC,
IVL_EX_SIGNAL,
IVL_EX_STRING,
@@ -175,30 +176,30 @@ typedef enum ivl_expr_type_e {
/* This is the type code for an ivl_net_logic_t object. */
typedef enum ivl_logic_e {
IVL_LO_NONE = 0,
IVL_LO_AND,
IVL_LO_BUF,
IVL_LO_BUFIF0,
IVL_LO_BUFIF1,
IVL_LO_BUFZ,
IVL_LO_NAND,
IVL_LO_NMOS,
IVL_LO_NOR,
IVL_LO_NOT,
IVL_LO_NOTIF0,
IVL_LO_NOTIF1,
IVL_LO_OR,
IVL_LO_PULLDOWN,
IVL_LO_PULLUP,
IVL_LO_RNMOS,
IVL_LO_RPMOS,
IVL_LO_PMOS,
IVL_LO_XNOR,
IVL_LO_XOR,
IVL_LO_NONE = 0,
IVL_LO_AND = 1,
IVL_LO_BUF = 2,
IVL_LO_BUFIF0 = 3,
IVL_LO_BUFIF1 = 4,
IVL_LO_BUFZ = 5,
IVL_LO_NAND = 6,
IVL_LO_NMOS = 7,
IVL_LO_NOR = 8,
IVL_LO_NOT = 9,
IVL_LO_NOTIF0 = 10,
IVL_LO_NOTIF1 = 11,
IVL_LO_OR = 12,
IVL_LO_PULLDOWN = 13,
IVL_LO_PULLUP = 14,
IVL_LO_RNMOS = 15,
IVL_LO_RPMOS = 16,
IVL_LO_PMOS = 17,
IVL_LO_XNOR = 18,
IVL_LO_XOR = 19,
IVL_LO_EEQ,
IVL_LO_EEQ = 20,
IVL_LO_UDP
IVL_LO_UDP = 21
} ivl_logic_t;
/* This is the type of an LPM object. */
@@ -208,13 +209,16 @@ typedef enum ivl_lpm_type_e {
IVL_LPM_CMP_GE = 1,
IVL_LPM_CMP_GT = 2,
IVL_LPM_CMP_NE = 11,
IVL_LPM_DIVIDE = 12,
IVL_LPM_FF = 3,
IVL_LPM_MOD = 13,
IVL_LPM_MULT = 4,
IVL_LPM_MUX = 5,
IVL_LPM_SHIFTL = 6,
IVL_LPM_SHIFTR = 7,
IVL_LPM_SUB = 8,
IVL_LPM_RAM = 9
IVL_LPM_RAM = 9,
IVL_LPM_UFUNC = 14
} ivl_lpm_type_t;
/* Processes are initial or always blocks with a statement. This is
@@ -257,7 +261,6 @@ typedef enum ivl_signal_type_e {
IVL_SIT_TRIAND,
IVL_SIT_TRIOR,
IVL_SIT_WAND,
IVL_SIT_WIRE,
IVL_SIT_WOR
} ivl_signal_type_t;
@@ -271,12 +274,16 @@ typedef enum ivl_statement_type_e {
IVL_ST_CASE,
IVL_ST_CASEX,
IVL_ST_CASEZ,
IVL_ST_CASSIGN,
IVL_ST_CONDIT,
IVL_ST_DEASSIGN,
IVL_ST_DELAY,
IVL_ST_DELAYX,
IVL_ST_DISABLE,
IVL_ST_FORCE,
IVL_ST_FOREVER,
IVL_ST_FORK,
IVL_ST_RELEASE,
IVL_ST_REPEAT,
IVL_ST_STASK,
IVL_ST_TRIGGER,
@@ -293,6 +300,24 @@ typedef int (*ivl_process_f)(ivl_process_t net, void*cd);
the user passes to the scanner. */
typedef int (ivl_scope_f)(ivl_scope_t net, void*cd);
/* Attributes, which can be attached to various object types, have
this form. */
typedef enum ivl_attribute_type_e {
IVL_ATT_VOID = 0,
IVL_ATT_STR,
IVL_ATT_NUM
} ivl_attribute_type_t;
struct ivl_attribute_s {
const char*key;
ivl_attribute_type_t type;
union val_ {
const char*str;
long num;
} val;
};
typedef const struct ivl_attribute_s*ivl_attribute_t;
/* DESIGN
* When handed a design (ivl_design_t) there are a few things that you
@@ -312,7 +337,7 @@ typedef int (ivl_scope_f)(ivl_scope_t net, void*cd);
*
* ivl_design_process
* This function scans the processes (threads) in the design. It
* calls the user suplied function on each of the processes until
* calls the user supplied function on each of the processes until
* one of the functors returns non-0 or all the processes are
* scanned. This function will return 0, or the non-zero value that
* was returned from the last scanned process.
@@ -331,6 +356,9 @@ extern const char* ivl_design_flag(ivl_design_t des, const char*key);
extern int ivl_design_process(ivl_design_t des,
ivl_process_f fun, void*cd);
extern ivl_scope_t ivl_design_root(ivl_design_t des);
extern void ivl_design_roots(ivl_design_t des,
ivl_scope_t **scopes,
unsigned int *nscopes);
extern int ivl_design_time_precision(ivl_design_t des);
extern unsigned ivl_design_consts(ivl_design_t des);
@@ -390,7 +418,15 @@ extern ivl_nexus_t ivl_event_pos(ivl_event_t net, unsigned idx);
*
* ivl_expr_width
* This method returns the bit width of the expression at this
* node. It can be applied to any expression node.
* node. It can be applied to any expression node, and returns the
* *output* width of the expression node.
*
* ivl_expr_opcode
* IVL_EX_BINARY and IVL_EX_UNARY expression nodes include an
* upcode from this table:
* & -- AND
* A -- NAND (~&)
* X -- XNOR (~^)
*/
extern ivl_expr_type_t ivl_expr_type(ivl_expr_t net);
@@ -401,7 +437,7 @@ extern const char* ivl_expr_bits(ivl_expr_t net);
extern ivl_scope_t ivl_expr_def(ivl_expr_t net);
/* IVL_EX_SIGNAL */
extern unsigned ivl_expr_lsi(ivl_expr_t net);
/* IVL_EX_SIGNAL, IVL_EX_SFUNC, IVL_EX_MEMORY */
/* IVL_EX_SIGNAL, IVL_EX_SFUNC */
extern const char* ivl_expr_name(ivl_expr_t net);
/* IVL_EX_BINARY IVL_EX_UNARY */
extern char ivl_expr_opcode(ivl_expr_t net);
@@ -433,13 +469,28 @@ extern unsigned ivl_expr_width(ivl_expr_t net);
/*
* Memory.
*
* ivl_memory_name (DEPRECATED)
*
* ivl_memory_basename
* This returns the base name of the memory object. The base name
* does not include the name of the scopes that contains the object.
*
* ivl_memory_size
* ivl_memory_width
* These functions return the dimensions of the memory. The size is
* the number of words in the memory, and the width is the number
* of bits in each word.
*
* ivl_memory_scope
* This returns the scope that contains the memory.
*/
extern const char*ivl_memory_name(ivl_memory_t net);
extern const char*ivl_memory_basename(ivl_memory_t net);
extern int ivl_memory_root(ivl_memory_t net);
extern ivl_scope_t ivl_memory_scope(ivl_memory_t net);
extern unsigned ivl_memory_size(ivl_memory_t net);
extern unsigned ivl_memory_width(ivl_memory_t net);
extern ivl_memory_t ivl_expr_memory(ivl_expr_t net);
/* LOGIC
@@ -466,6 +517,16 @@ extern ivl_memory_t ivl_expr_memory(ivl_expr_t net);
*
* ivl_logic_pins
* ivl_logic_pin
*
* ivl_logic_attr
* Return the value of a specific attribute, given the key name as
* a string. If the key is not defined, then return 0 (null).
*
* ivl_logic_attr_cnt
* ivl_logic_attr_val
* These support iterating over logic attributes. The _cnt method
* returns the number of attributes attached to the gate, and the
* ivl_logic_attr_val returns the value of the attribute.
*/
extern const char* ivl_logic_name(ivl_net_logic_t net);
@@ -475,6 +536,13 @@ extern ivl_logic_t ivl_logic_type(ivl_net_logic_t net);
extern ivl_nexus_t ivl_logic_pin(ivl_net_logic_t net, unsigned pin);
extern unsigned ivl_logic_pins(ivl_net_logic_t net);
extern ivl_udp_t ivl_logic_udp(ivl_net_logic_t net);
extern unsigned ivl_logic_delay(ivl_net_logic_t net, unsigned transition);
/* DEPRECATED */
extern const char* ivl_logic_attr(ivl_net_logic_t net, const char*key);
extern unsigned ivl_logic_attr_cnt(ivl_net_logic_t net);
extern ivl_attribute_t ivl_logic_attr_val(ivl_net_logic_t net, unsigned idx);
/* UDP
*
@@ -505,7 +573,7 @@ extern const char* ivl_udp_name(ivl_udp_t net);
* this device.
*
* ivl_lpm_type
* Return the ivl_lpm_type_t of the secific LPM device.
* Return the ivl_lpm_type_t of the specific LPM device.
*
* ivl_lpm_width
* Return the width of the LPM device. What this means depends on
@@ -522,7 +590,7 @@ extern const char* ivl_udp_name(ivl_udp_t net);
* vector for devices that have more inputs.
*
* ivl_lpm_datab
* Return the input data nexis for device types that have a second
* Return the input data nexus for device types that have a second
* input vector. For example, arithmetic devices are like this.
*
* ivl_lpm_q
@@ -535,7 +603,7 @@ extern const char* ivl_udp_name(ivl_udp_t net);
*
* ivl_lpm_size
* In addition to a width, some devices have a size. The size is
* often the number of inputs per out, i.e. the number of inputs
* often the number of inputs per out, i.e., the number of inputs
* per bit for a MUX.
*/
extern const char* ivl_lpm_name(ivl_lpm_t net);
@@ -544,17 +612,26 @@ extern ivl_scope_t ivl_lpm_scope(ivl_lpm_t net);
extern ivl_lpm_type_t ivl_lpm_type(ivl_lpm_t net);
extern unsigned ivl_lpm_width(ivl_lpm_t net);
/* IVL_LPM_FF */
extern ivl_nexus_t ivl_lpm_async_clr(ivl_lpm_t net);
extern ivl_nexus_t ivl_lpm_async_set(ivl_lpm_t net);
extern ivl_expr_t ivl_lpm_aset_value(ivl_lpm_t net);
/* IVL_LPM_FF IVL_LPM_RAM */
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);
/* IVL_LPM_FF IVL_LPM_RAM */
extern ivl_nexus_t ivl_lpm_enable(ivl_lpm_t net);
/* IVL_LPM_ADD IVL_LPM_FF IVL_LPM_MULT IVL_LPM_RAM IVL_LPM_SUB */
extern ivl_nexus_t ivl_lpm_data(ivl_lpm_t net, unsigned idx);
/* IVL_LPM_ADD IVL_LPM_MULT IVL_LPM_SUB */
/* IVL_LPM_MUX IVL_LPM_UFUNC */
extern ivl_nexus_t ivl_lpm_datab(ivl_lpm_t net, unsigned idx);
/* IVL_LPM_MUX */
extern ivl_nexus_t ivl_lpm_data2(ivl_lpm_t net, unsigned sdx, unsigned idx);
/* IVL_LPM_ADD IVL_LPM_FF IVL_LPM_MULT IVL_LPM_RAM IVL_LPM_SUB */
/* IVL_LPM_UFUNC */
extern unsigned ivl_lpm_data2_width(ivl_lpm_t net, unsigned sdx);
/* IVL_LPM_ADD IVL_LPM_FF IVL_LPM_MULT IVL_LPM_RAM IVL_LPM_SUB
IVL_LPM_UFUNC */
extern ivl_nexus_t ivl_lpm_q(ivl_lpm_t net, unsigned idx);
/* IVL_LPM_MUX IVL_LPM_RAM */
extern unsigned ivl_lpm_selects(ivl_lpm_t net);
@@ -655,7 +732,7 @@ extern ivl_signal_t ivl_lval_sig(ivl_lval_t net);
* connected to the nexus.
*
* If the target is an LPM device, then this value is zero, and it
* is up to the application to find the pin that referse to this
* is up to the application to find the pin that refers to this
* nexus. The problem is that LPM devices do not have a pinout per
* se, the pins all have specific names.
*
@@ -710,8 +787,25 @@ extern ivl_signal_t ivl_nexus_ptr_sig(ivl_nexus_ptr_t net);
* generally when a module is instantiated, though they also come from
* named blocks, tasks and functions.
*
* (NOTE: Module scopes are *instances* of modules, and not the module
* definition. A definition may apply to many instances.)
* - module instances (IVL_SCT_MODULE)
* A module instance scope may contain events, logic gates, lpm
* nodes, signals, and possibly children. The children are further
* instances, or function/task scopes. Module instances do *not*
* contain a definition.
*
* - function scopes (IVL_SCT_FUNCTION)
* These scopes represent functions. A function may not be a root,
* so it is contained within a module instance scope. A function is
* required to have a definition (in the form of a statement) and a
* signal (IVL_SIG_REG) that is its return value.
*
* A single function scope is created each time the module with the
* definition is instantiated.
*
*
* - task scopes (IVL_SCT_TASK)
* [...]
*
*
* ivl_scope_children
* A scope may in turn contain other scopes. This method iterates
@@ -736,6 +830,11 @@ extern ivl_signal_t ivl_nexus_ptr_sig(ivl_nexus_ptr_t net);
* Scopes have 0 or more logic devices in them. A logic device is
* represented by ivl_logic_t.
*
* ivl_scope_lpm
* ivl_scope_lpms
* Scopes have 0 or more LPM devices in them. These functions access
* those devices.
*
* ivl_scope_name
* ivl_scope_basename
* Every scope has a hierarchical name. This name is also a prefix
@@ -796,7 +895,7 @@ extern const char* ivl_scope_tname(ivl_scope_t net);
/* SIGNALS
* Signals are named things in the Verilog source, like wires and
* regs, and also named things that are preated as temporaries during
* regs, and also named things that are created as temporaries during
* certain elaboration or optimization steps. A signal may also be a
* port of a module or task.
*
@@ -806,7 +905,7 @@ extern const char* ivl_scope_tname(ivl_scope_t net);
* ivl_signal_pins
* ivl_signal_pin
* The ivl_signal_pin function returns the nexus connected to the
* signal. If the signal is a vectory, the idx can be a non-zero
* signal. If the signal is a vector, the idx can be a non-zero
* value, and the result is the nexus for the specified bit.
*
* ivl_signal_port
@@ -819,16 +918,28 @@ extern const char* ivl_scope_tname(ivl_scope_t net);
* net or variable may be signed. This function returns true if the
* signal is signed.
*
* ivl_signal_type
* Return the type of the signal, i.e. reg, wire, tri0, et al.
* ivl_signal_local
* A signal that was generated by the compiler as a place holder is
* marked as local.
*
* ivl_signal_name
* ivl_signal_type
* Return the type of the signal, i.e., reg, wire, tri0, etc.
*
* ivl_signal_name (DEPRECATED)
* This function returns the fully scoped hierarchical name for the
* signal. The name refers to the entire vector that is the signal.
*
* NOTE: This function is deprecated. The heirarchical name is too
* vague a construct when escaped names can have . characters in
* them. Do no use this function in new code, it will disappear.
*
* ivl_signal_basename
* This function returns the name of the signal, without the scope
* information. This is the tail of the signal name.
* information. This is the tail of the signal name. Since Verilog
* has an escape syntax, this name can contain any ASCII
* characters, except NULL or white space. The leading \ and
* trailing ' ' of escaped names in Verilog source are not part of
* the name, so not included here.
*
* ivl_signal_attr
* Icarus Verilog supports attaching attributes to signals, with
@@ -841,11 +952,16 @@ extern ivl_nexus_t ivl_signal_pin(ivl_signal_t net, unsigned idx);
extern unsigned ivl_signal_pins(ivl_signal_t net);
extern ivl_signal_port_t ivl_signal_port(ivl_signal_t net);
extern int ivl_signal_signed(ivl_signal_t net);
extern int ivl_signal_integer(ivl_signal_t net);
extern int ivl_signal_local(ivl_signal_t net);
extern ivl_signal_type_t ivl_signal_type(ivl_signal_t net);
extern const char* ivl_signal_name(ivl_signal_t net);
extern const char* ivl_signal_basename(ivl_signal_t net);
extern const char* ivl_signal_attr(ivl_signal_t net, const char*key);
extern unsigned ivl_signal_attr_cnt(ivl_signal_t net);
extern ivl_attribute_t ivl_signal_attr_val(ivl_signal_t net, unsigned idx);
/*
* These functions get information about a process. A process is
@@ -854,7 +970,7 @@ extern const char* ivl_signal_attr(ivl_signal_t net, const char*key);
* may be a compound statement.)
*
* The ivl_process_type function gets the type of the process,
* an "inital" or "always" statement.
* an "initial" or "always" statement.
*
* A process is placed in a scope. The statement within the process
* operates within the scope of the process unless there are calls
@@ -863,6 +979,9 @@ extern const char* ivl_signal_attr(ivl_signal_t net, const char*key);
* The ivl_process_stmt function gets the statement that forms the
* process. See the statement related functions for how to manipulate
* statements.
*
* Processes can have attributes attached to them. the attr_cnt and
* attr_val methods return those attributes.
*/
extern ivl_process_type_t ivl_process_type(ivl_process_t net);
@@ -870,6 +989,9 @@ extern ivl_scope_t ivl_process_scope(ivl_process_t net);
extern ivl_statement_t ivl_process_stmt(ivl_process_t net);
extern unsigned ivl_process_attr_cnt(ivl_process_t net);
extern ivl_attribute_t ivl_process_attr_val(ivl_process_t net, unsigned idx);
/*
* These functions manage statements of various type. This includes
* all the different kinds of statements (as enumerated in
@@ -877,7 +999,7 @@ extern ivl_statement_t ivl_process_stmt(ivl_process_t net);
*
* The ivl_statement_type() function returns the type code for the
* statement. This is the major type, and implies which of the later
* functions are applicable to the statemnt.
* functions are applicable to the statement.
*/
extern ivl_statement_type_t ivl_statement_type(ivl_statement_t net);
@@ -887,11 +1009,18 @@ extern ivl_statement_type_t ivl_statement_type(ivl_statement_t net);
* make up the statement. Many of these functions apply to more then
* one type of statement, so the comment in front of them tells which
* statement types can be passed to the function.
*
* ivl_stmt_block_scope
* If the block is named, then there is a scope associated with
* this. The code generator may need to know this in order to
* handle disable statements.
*/
/* IVL_ST_BLOCK, IVL_ST_FORK */
extern unsigned ivl_stmt_block_count(ivl_statement_t net);
/* IVL_ST_BLOCK, IVL_ST_FORK */
extern ivl_scope_t ivl_stmt_block_scope(ivl_statement_t net);
/* IVL_ST_BLOCK, IVL_ST_FORK */
extern ivl_statement_t ivl_stmt_block_stmt(ivl_statement_t net, unsigned i);
/* IVL_ST_UTASK IVL_ST_DISABLE */
extern ivl_scope_t ivl_stmt_call(ivl_statement_t net);
@@ -913,14 +1042,19 @@ extern ivl_expr_t ivl_stmt_delay_expr(ivl_statement_t net);
extern unsigned long ivl_stmt_delay_val(ivl_statement_t net);
/* IVL_ST_WAIT */
extern ivl_event_t ivl_stmt_event(ivl_statement_t net);
/* IVL_ST_ASSIGN IVL_ST_ASSIGN_NB */
/* IVL_ST_ASSIGN IVL_ST_ASSIGN_NB IVL_ST_CASSIGN IVL_ST_DEASSIGN
IVL_ST_FORCE IVL_ST_RELEASE */
extern ivl_lval_t ivl_stmt_lval(ivl_statement_t net, unsigned idx);
/* IVL_ST_ASSIGN IVL_ST_ASSIGN_NB */
/* IVL_ST_ASSIGN IVL_ST_ASSIGN_NB IVL_ST_CASSIGN IVL_ST_DEASSIGN
IVL_ST_FORCE IVL_ST_RELEASE */
extern unsigned ivl_stmt_lvals(ivl_statement_t net);
/* IVL_ST_ASSIGN IVL_ST_ASSIGN_NB */
extern unsigned ivl_stmt_lwidth(ivl_statement_t net);
/* IVL_ST_STASK */
extern const char* ivl_stmt_name(ivl_statement_t net);
/* IVL_ST_CASSIGN IVL_ST_FORCE */
extern ivl_nexus_t ivl_stmt_nexus(ivl_statement_t net, unsigned idx);
extern unsigned ivl_stmt_nexus_count(ivl_statement_t net);
/* IVL_ST_STASK */
extern ivl_expr_t ivl_stmt_parm(ivl_statement_t net, unsigned idx);
/* IVL_ST_STASK */
@@ -932,6 +1066,14 @@ extern ivl_expr_t ivl_stmt_rval(ivl_statement_t net);
extern ivl_statement_t ivl_stmt_sub_stmt(ivl_statement_t net);
#if defined(__MINGW32__) || defined (__CYGWIN32__)
# define DLLEXPORT __declspec(dllexport)
#else
# define DLLEXPORT
#endif
extern DLLEXPORT int target_design(ivl_design_t des);
/* target_design
@@ -949,239 +1091,85 @@ _END_DECL
/*
* $Log: ivl_target.h,v $
* Revision 1.80 2001/09/01 01:57:31 steve
* Make constants available through the design root
* Revision 1.108 2002/10/23 01:47:17 steve
* Fix synth2 handling of aset/aclr signals where
* flip-flops are split by begin-end blocks.
*
* Revision 1.79 2001/08/31 22:58:39 steve
* Support DFF CE inputs.
* Revision 1.107 2002/09/26 03:18:04 steve
* Generate vvp code for asynch set/reset of NetFF.
*
* Revision 1.78 2001/08/28 04:07:17 steve
* Add some ivl_target convenience functions.
* Revision 1.106 2002/09/12 15:49:43 steve
* Add support for binary nand operator.
*
* Revision 1.77 2001/08/25 23:50:03 steve
* Change the NetAssign_ class to refer to the signal
* instead of link into the netlist. This is faster
* and uses less space. Make the NetAssignNB carry
* the delays instead of the NetAssign_ lval objects.
* Revision 1.105 2002/08/24 05:03:40 steve
* Missing declaration of ivl_memory_scope.
*
* Change the vvp code generator to support multiple
* l-values, i.e. concatenations of part selects.
* Revision 1.104 2002/08/12 01:34:59 steve
* conditional ident string using autoconfig.
*
* Revision 1.76 2001/08/10 00:40:45 steve
* tgt-vvp generates code that skips nets as inputs.
* Revision 1.103 2002/08/05 04:18:45 steve
* Store only the base name of memories.
*
* Revision 1.75 2001/07/27 04:51:44 steve
* Handle part select expressions as variants of
* NetESignal/IVL_EX_SIGNAL objects, instead of
* creating new and useless temporary signals.
* Revision 1.102 2002/08/04 18:28:14 steve
* Do not use hierarchical names of memories to
* generate vvp labels. -tdll target does not
* used hierarchical name string to look up the
* memory objects in the design.
*
* Revision 1.74 2001/07/27 02:41:55 steve
* Fix binding of dangling function ports. do not elide them.
* Revision 1.101 2002/07/05 21:26:17 steve
* Avoid emitting to vvp local net symbols.
*
* Revision 1.73 2001/07/22 00:17:49 steve
* Support the NetESubSignal expressions in vvp.tgt.
* Revision 1.100 2002/06/21 04:59:35 steve
* Carry integerness throughout the compilation.
*
* Revision 1.72 2001/07/19 04:55:06 steve
* Support calculated delays in vvp.tgt.
* Revision 1.99 2002/06/11 03:34:33 steve
* Spelling patch (Larry Doolittle)
*
* Revision 1.71 2001/07/04 22:59:25 steve
* handle left shifter in dll output.
* Revision 1.98 2002/05/27 00:08:45 steve
* Support carrying the scope of named begin-end
* blocks down to the code generator, and have
* the vvp code generator use that to support disable.
*
* Revision 1.70 2001/06/30 23:03:16 steve
* support fast programming by only writing the bits
* that are listed in the input file.
* Revision 1.97 2002/05/26 01:39:02 steve
* Carry Verilog 2001 attributes with processes,
* all the way through to the ivl_target API.
*
* Revision 1.69 2001/06/19 03:01:10 steve
* Add structural EEQ gates (Stephan Boettcher)
* Divide signal reference counts between rval
* and lval references.
*
* Revision 1.68 2001/06/16 23:45:05 steve
* Add support for structural multiply in t-dll.
* Add code generators and vvp support for both
* structural and behavioral multiply.
* Revision 1.96 2002/05/24 04:36:23 steve
* Verilog 2001 attriubtes on nets/wires.
*
* Revision 1.67 2001/06/16 02:41:41 steve
* Generate code to support memory access in continuous
* assignment statements. (Stephan Boettcher)
* Revision 1.95 2002/05/23 03:08:51 steve
* Add language support for Verilog-2001 attribute
* syntax. Hook this support into existing $attribute
* handling, and add number and void value types.
*
* Revision 1.66 2001/06/15 04:14:18 steve
* Generate vvp code for GT and GE comparisons.
* Add to the ivl_target API new functions for access
* of complex attributes attached to gates.
*
* Revision 1.65 2001/06/07 03:09:37 steve
* support subtraction in tgt-vvp.
* Revision 1.94 2002/03/17 19:30:20 steve
* Add API to support user defined function.
*
* Revision 1.64 2001/06/07 02:12:43 steve
* Support structural addition.
* Revision 1.93 2002/03/09 02:10:22 steve
* Add the NetUserFunc netlist node.
*
* Revision 1.63 2001/05/20 01:06:16 steve
* stub ivl_expr_parms for sfunctions.
* Revision 1.92 2002/01/28 00:52:41 steve
* Add support for bit select of parameters.
* This leads to a NetESelect node and the
* vvp code generator to support that.
*
* Revision 1.62 2001/05/17 04:37:02 steve
* Behavioral ternary operators for vvp.
* Revision 1.91 2002/01/03 04:19:01 steve
* Add structural modulus support down to vvp.
*
* Revision 1.61 2001/05/12 03:18:44 steve
* Make sure LPM devices have drives on outputs.
* Revision 1.90 2001/12/15 02:13:17 steve
* The IVL_SIT_WIRE type does not exist, it is a
* synonym for IVL_SIT_TRI.
*
* Revision 1.60 2001/05/08 23:59:33 steve
* Add ivl and vvp.tgt support for memories in
* expressions and l-values. (Stephan Boettcher)
* Revision 1.89 2001/12/06 03:11:00 steve
* Add ivl_logic_delay function to ivl_target.
*
* Revision 1.59 2001/05/08 04:13:12 steve
* sort enumeration values.
*
* Revision 1.58 2001/05/06 17:48:20 steve
* Support memory objects. (Stephan Boettcher)
*
* Revision 1.57 2001/04/29 23:17:38 steve
* Carry drive strengths in the ivl_nexus_ptr_t, and
* handle constant devices in targets.'
*
* Revision 1.56 2001/04/29 20:19:10 steve
* Add pullup and pulldown devices.
*
* Revision 1.55 2001/04/26 05:12:02 steve
* Implement simple MUXZ for ?: operators.
*
* Revision 1.54 2001/04/22 23:09:46 steve
* More UDP consolidation from Stephan Boettcher.
*
* Revision 1.53 2001/04/21 00:55:46 steve
* Generate code for disable.
*
* Revision 1.52 2001/04/15 02:58:11 steve
* vvp support for <= with internal delay.
*
* Revision 1.51 2001/04/07 19:24:36 steve
* Add the disable statemnent.
*
* Revision 1.50 2001/04/06 02:28:02 steve
* Generate vvp code for functions with ports.
*
* Revision 1.49 2001/04/05 03:20:57 steve
* Generate vvp code for the repeat statement.
*
* Revision 1.48 2001/04/05 01:12:27 steve
* Get signed compares working correctly in vvp.
*
* Revision 1.47 2001/04/04 04:50:35 steve
* Support forever loops in the tgt-vvp target.
*
* Revision 1.46 2001/04/03 04:50:37 steve
* Support non-blocking assignments.
*
* Revision 1.45 2001/04/02 02:28:12 steve
* Generate code for task calls.
*
* Revision 1.44 2001/04/02 00:28:35 steve
* Support the scope expression node.
*
* Revision 1.43 2001/04/01 06:52:27 steve
* support the NetWhile statement.
*
* Revision 1.42 2001/04/01 04:38:17 steve
* dead cruft.
*
* Revision 1.41 2001/04/01 01:48:21 steve
* Redesign event information to support arbitrary edge combining.
*
* Revision 1.40 2001/03/31 17:36:38 steve
* Generate vvp code for case statements.
*
* Revision 1.39 2001/03/30 05:49:52 steve
* Generate code for fork/join statements.
*
* Revision 1.38 2001/03/29 02:52:39 steve
* Add unary ~ operator to tgt-vvp.
*
* Revision 1.37 2001/03/28 06:07:39 steve
* Add the ivl_event_t to ivl_target, and use that to generate
* .event statements in vvp way ahead of the thread that uses it.
*
* Revision 1.36 2001/03/27 06:27:40 steve
* Generate code for simple @ statements.
*
* Revision 1.35 2001/03/20 01:44:13 steve
* Put processes in the proper scope.
*
* Revision 1.34 2001/01/15 22:05:14 steve
* Declare ivl_scope_type functions.
*
* Revision 1.33 2001/01/15 00:47:01 steve
* Pass scope type information to the target module.
*
* Revision 1.32 2001/01/15 00:05:39 steve
* Add client data pointer for scope and process scanners.
*
* Revision 1.31 2001/01/06 06:31:58 steve
* declaration initialization for time variables.
*
* Revision 1.30 2000/12/05 06:29:33 steve
* Make signal attributes available to ivl_target API.
*
* Revision 1.29 2000/11/12 17:47:29 steve
* flip-flop pins for ivl_target API.
*
* Revision 1.28 2000/11/11 01:52:09 steve
* change set for support of nmos, pmos, rnmos, rpmos, notif0, and notif1
* change set to correct behavior of bufif0 and bufif1
* (Tim Leight)
*
* Also includes fix for PR#27
*
* Revision 1.27 2000/11/11 00:03:36 steve
* Add support for the t-dll backend grabing flip-flops.
*
* Revision 1.26 2000/10/31 17:49:02 steve
* Support time variables.
*
* Revision 1.25 2000/10/28 22:32:34 steve
* API for concatenation expressions.
*
* Revision 1.24 2000/10/28 17:55:03 steve
* stub for the concat operator.
*
* Revision 1.23 2000/10/25 05:41:24 steve
* Get target signal from nexus_ptr.
*
* Revision 1.22 2000/10/21 16:49:45 steve
* Reduce the target entry points to the target_design.
*
* Revision 1.21 2000/10/18 20:04:39 steve
* Add ivl_lval_t and support for assignment l-values.
*
* Revision 1.20 2000/10/15 04:46:23 steve
* Scopes and processes are accessible randomly from
* the design, and signals and logic are accessible
* from scopes. Remove the target calls that are no
* longer needed.
*
* Add the ivl_nexus_ptr_t and the means to get at
* them from nexus objects.
*
* Give names to methods that manipulate the ivl_design_t
* type more consistent names.
*
* Revision 1.19 2000/10/13 03:39:27 steve
* Include constants in nexus targets.
*
* Revision 1.18 2000/10/08 04:01:54 steve
* Back pointers in the nexus objects into the devices
* that point to it.
*
* Collect threads into a list in the design.
*
* Revision 1.17 2000/10/07 19:45:43 steve
* Put logic devices into scopes.
*
* Revision 1.16 2000/10/06 23:46:50 steve
* ivl_target updates, including more complete
* handling of ivl_nexus_t objects. Much reduced
* dependencies on pointers to netlist objects.
*
* Revision 1.15 2000/10/05 05:03:01 steve
* xor and constant devices.
*
* Revision 1.14 2000/09/30 02:18:15 steve
* ivl_expr_t support for binary operators,
* Create a proper ivl_scope_t object.
* Revision 1.88 2001/11/14 03:28:49 steve
* DLL target support for force and release.
*/
#endif
+51
View File
@@ -0,0 +1,51 @@
Icarus Verilog LOADABLE TARGET API (ivl_target)
Copyright 2002 Stephen Williams <[email protected]>
$Id: ivl_target.txt,v 1.3 2002/06/11 03:34:33 steve Exp $
The ivl_target API is the interface available to modules that the
Icarus Verilog compiler loads to act as a code generator. The API
provides an interface to the elaborated, possibly synthesized, design
for code generators that are intended to write netlist files or
executable programs.
The functions and types of the API are summarized in the ivl_target.h
header file. This document describes how the functions and types of
the API are used to access and interpret the netlist of the design.
LPM DEVICES
All LPM devices support a small set of common LPM functions, as
described in the ivl_target header file. The ivl_lpm_t object has a
type enumerated by ivl_lpm_type_t, and that type is accessible via the
ivl_lpm_type function.
The following are type specific aspects of LPM devices.
* IVL_LPM_UFUNC
This LPM represents a user defined function. It is a way to connect
behavioral code into a structural network. The UFUNC device has a
vector output and a set of inputs. The ivl_lpm_define function returns
the definition as an ivl_scope_t object.
The output vector is accessible through the ivl_lpm_q, and the output
has the width defined by ivl_lpm_width. This similar to most every
other LPM device with outputs.
There are ivl_lpm_size() input ports, each with the width
ivl_lpm_data2_width(). The actual nexus is indexed by ivl_lpm_data2().
$Log: ivl_target.txt,v $
Revision 1.3 2002/06/11 03:34:33 steve
Spelling patch (Larry Doolittle)
Revision 1.2 2002/03/17 19:31:17 steve
Add API to support user defined function.
Revision 1.1 2002/03/09 02:10:22 steve
Add the NetUserFunc netlist node.
+10 -2
View File
@@ -18,8 +18,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: globals.h,v 1.5 2000/09/13 22:33:13 steve Exp $"
#ifdef HAVE_CVS_IDENT
#ident "$Id: globals.h,v 1.7 2002/08/12 01:35:02 steve Exp $"
#endif
# include <stdio.h>
@@ -37,11 +37,19 @@ extern int line_direct_flag;
extern unsigned error_count;
extern FILE *depend_file;
/* This is the entry to the parser. */
extern int yyparse();
/*
* $Log: globals.h,v $
* Revision 1.7 2002/08/12 01:35:02 steve
* conditional ident string using autoconfig.
*
* Revision 1.6 2002/04/04 05:26:13 steve
* Add dependency generation.
*
* Revision 1.5 2000/09/13 22:33:13 steve
* undefined macros are null (with warnings.)
*
+6 -6
View File
@@ -49,7 +49,7 @@ valid options include:
flags as needed.
-L
Generate #line directives. The ivl compiler understands
Generate `line directives. The ivl compiler understands
these directives and uses them to keep track of the
current line of the original source file. This makes error
messages more meaningful.
@@ -89,17 +89,17 @@ proper will not reflect the actual line numbers in the source file.
To handle this situation, the preprocessor can generate line
directives. These directives are lines of the form:
#line <name> <num>
`line <num> <name> <level>
where <name> is the file name in double-quotes and <num> is the line
number in the file. The parser changes the filename and line number
counters in such a way that the next line is line number <num>+1 in
counters in such a way that the next line is line number <num> in
the file named <name>. For example:
#line "foo.vl" 5
`line 6 "foo.vl" 0
// I am on line 6 in file foo.vl.
The preprocessor generates a #line directive every time it switches
files. That includes starting an included file (#line "foo.vlh" 0) or
The preprocessor generates a `line directive every time it switches
files. That includes starting an included file (`line 1 "foo.vlh" 1) or
returning to the including file.
+177 -43
View File
@@ -1,7 +1,7 @@
%{
/*
* Copyright (c) 1999 Stephen Williams ([email protected])
* Copyright (c) 1999-2002 Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -19,13 +19,16 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: lexor.lex,v 1.24 2001/07/25 03:10:50 steve Exp $"
#ident "$Id: lexor.lex,v 1.36 2002/11/08 00:04:16 steve Exp $"
#endif
# include "config.h"
# include <stdio.h>
#ifdef HAVE_MALLOC_H
# include <malloc.h>
#endif
# include <stdlib.h>
# include <string.h>
# include <assert.h>
@@ -40,6 +43,7 @@ static void def_start();
static void def_finish();
static void def_undefine();
static void do_define();
static int def_is_done();
static int is_defined(const char*name);
static void include_filename();
@@ -63,6 +67,8 @@ struct include_stack_t {
struct include_stack_t*next;
};
static void emit_pathline(struct include_stack_t *isp);
static struct include_stack_t*file_queue = 0;
static struct include_stack_t*istack = 0;
static struct include_stack_t*standby = 0;
@@ -86,6 +92,7 @@ static int comment_enter = 0;
%x PPINCLUDE
%x PPDEFINE
%x CCOMMENT
%x PCOMENT
%x CSTRING
%x ERROR_LINE
@@ -108,6 +115,15 @@ W [ \t\b\f]+
<CCOMMENT>\n { istack->lineno += 1; ECHO; }
<CCOMMENT>"*/" { BEGIN(comment_enter); ECHO; }
/* Detect and pass multiline pragma comments. As with C-style
comments, pragma comments are passed through, and CPP directives
contained within are ignored. */
"(*" { comment_enter = YY_START; BEGIN(PCOMENT); ECHO; }
<PCOMENT>. { ECHO; }
<PCOMENT>\n { istack->lineno += 1; ECHO; }
<PCOMENT>"*)" { BEGIN(comment_enter); ECHO; }
/* Strings do not contain macros or preprocessor directives. */
\" { comment_enter = YY_START; BEGIN(CSTRING); ECHO; }
<CSTRING>\\\" { yymore(); }
@@ -121,6 +137,7 @@ W [ \t\b\f]+
^{W}?`include { yy_push_state(PPINCLUDE); }
<PPINCLUDE>`[a-zA-Z][a-zA-Z0-9_]* { def_match(); }
<PPINCLUDE>\"[^\"]*\" { include_filename(); }
<PPINCLUDE>[ \t\b\f] { ; }
@@ -142,9 +159,9 @@ W [ \t\b\f]+
/* Anything that is not matched by the above is an error of some
sort. Print and error message and absorb the rest of the line. */
<PPINCLUDE>. {
fprintf(stderr, "%s:%u: error: malformed `include directive."
" Did you quote the file name?\n", istack->path,
istack->lineno+1);
emit_pathline(istack);
fprintf(stderr, "error: malformed `include directive."
" Did you quote the file name?\n");
error_count += 1;
BEGIN(ERROR_LINE); }
@@ -153,17 +170,23 @@ W [ \t\b\f]+
directive and the name, go into PPDEFINE mode and prepare to
collect the defined value. */
`define{W}[a-zA-Z_][a-zA-Z0-9_]*{W}? { yy_push_state(PPDEFINE); def_start(); }
`define{W}[a-zA-Z_][a-zA-Z0-9_$]*{W}? { yy_push_state(PPDEFINE); def_start(); }
<PPDEFINE>.* { do_define(); }
<PPDEFINE>(\n|"\r\n"|"\n\r") {
def_finish();
istack->lineno += 1;
fputc('\n', yyout);
yy_pop_state();
<PPDEFINE>.* {
do_define();
}
<PPDEFINE>(\n|"\r\n"|"\n\r") {
if (def_is_done()) {
def_finish();
istack->lineno += 1;
yy_pop_state();
}
fputc('\n', yyout);
}
/* If the define is terminated by an EOF, then finish the define
whether there was a continuation or not. */
<PPDEFINE><<EOF>> {
def_finish();
istack->lineno += 1;
@@ -171,7 +194,7 @@ W [ \t\b\f]+
yy_pop_state();
}
`undef{W}[a-zA-Z_][a-zA-Z0-9_]*{W}?.* { def_undefine(); }
`undef{W}[a-zA-Z_][a-zA-Z0-9_$]*{W}?.* { def_undefine(); }
/* Detect conditional compilation directives, and parse them. If I
@@ -183,12 +206,11 @@ W [ \t\b\f]+
condition that stacks on top of the IFDEF_FALSE so that output is
not accidentally turned on within nested ifdefs. */
^{W}?`ifdef{W}[a-zA-Z_][a-zA-Z0-9_]*.* {
`ifdef{W}[a-zA-Z_][a-zA-Z0-9_$]* {
char*name = strchr(yytext, '`');
assert(name);
name += 6;
name += strspn(name, " \t\b\f");
name[strcspn(name, " \t\b\f")] = 0;
if (is_defined(name)) {
yy_push_state(IFDEF_TRUE);
@@ -197,21 +219,36 @@ W [ \t\b\f]+
}
}
<IFDEF_FALSE,IFDEF_SUPR>^{W}?`ifdef{W}.* { yy_push_state(IFDEF_SUPR); }
`ifndef{W}[a-zA-Z_][a-zA-Z0-9_$]* {
char*name = strchr(yytext, '`');
assert(name);
name += 7;
name += strspn(name, " \t\b\f");
<IFDEF_TRUE>{W}?`else.* { BEGIN(IFDEF_FALSE); }
<IFDEF_FALSE>{W}?`else.* { BEGIN(IFDEF_TRUE); }
<IFDEF_SUPR>{W}?`else.* { }
if (!is_defined(name)) {
yy_push_state(IFDEF_TRUE);
} else {
yy_push_state(IFDEF_FALSE);
}
}
<IFDEF_FALSE,IFDEF_SUPR>`ifdef{W} { yy_push_state(IFDEF_SUPR); }
<IFDEF_FALSE,IFDEF_SUPR>`ifndef{W} { yy_push_state(IFDEF_SUPR); }
<IFDEF_TRUE>`else { BEGIN(IFDEF_FALSE); }
<IFDEF_FALSE>`else { BEGIN(IFDEF_TRUE); }
<IFDEF_SUPR>`else { }
<IFDEF_FALSE,IFDEF_SUPR>"//".* { }
<IFDEF_FALSE,IFDEF_SUPR>. { }
<IFDEF_FALSE,IFDEF_SUPR>\n { istack->lineno += 1; fputc('\n', yyout); }
<IFDEF_FALSE,IFDEF_TRUE,IFDEF_SUPR>^{W}?`endif.* {
<IFDEF_FALSE,IFDEF_TRUE,IFDEF_SUPR>`endif {
yy_pop_state();
}
/* This pattern notices macros and arranges for them to be replaced. */
`[a-zA-Z][a-zA-Z0-9_]* { def_match(); }
`[a-zA-Z][a-zA-Z0-9_$]* { def_match(); }
/* Any text that is not a directive just gets passed through to the
output. Very easy. */
@@ -286,9 +323,9 @@ static void def_match()
yy_switch_to_buffer(yy_new_buffer(istack->file, YY_BUF_SIZE));
} else {
fprintf(stderr, "%s:%u: warning: macro %s undefined "
"(and assumed null) at this point.\n",
istack->path, istack->lineno, yytext);
emit_pathline(istack);
fprintf(stderr, "warning: macro %s undefined "
"(and assumed null) at this point.\n", yytext);
}
}
@@ -345,33 +382,98 @@ void define_macro(const char*name, const char*value, int keyword)
}
}
/*
* The do_define function accumulates the defined value in these
* variables. When the define is over, the def_finish() function
* executes the define and clears this text. The define_continue_flag
* is set if do_define detects that the definition is to be continued
* on the next line.
*/
static char* define_text = 0;
static size_t define_cnt = 0;
static int define_continue_flag = 0;
/*
* Collect the definition. Normally, this returns 0. If there is a
* continuation, then return 1 and this function may be called again
* to collect another line of the definition.
*/
static void do_define()
{
char *cp;
define_continue_flag = 0;
/* FIXME: This strips trailing line comments out of the
definition. It's not adequate as the "//" may have been
quoted or commented, but it'll do for now. */
char *cp;
if(cp = strstr(yytext, "//"))
*cp = 0;
/* Trim trailing white space. */
cp = yytext + strlen(yytext);
while (cp > yytext) {
cp -= 1;
if (!isspace(*cp))
if (!isspace(cp[-1]))
break;
cp -= 1;
*cp = 0;
}
define_macro(def_name, yytext, 0);
def_name[0] = 0;
/* Detect the continuation sequence. If I find it, remove it
and the white space that preceeds it, then replace all that
with a single newline. */
if ((cp > yytext) && (cp[-1] == '\\')) {
cp -= 1;
cp[0] = 0;
while ((cp > yytext) && isspace(cp[-1])) {
cp -= 1;
*cp = 0;
}
*cp++ = '\n';
*cp = 0;
define_continue_flag = 1;
}
/* Accumulate this text into the define_text string. */
define_text = realloc(define_text, define_cnt + (cp-yytext) + 1);
strcpy(define_text+define_cnt, yytext);
define_cnt += cp-yytext;
}
/*
* Return true if the definition text is done. This is the opposite of
* the define_continue_flag.
*/
static int def_is_done()
{
return define_continue_flag? 0 : 1;
}
/*
* After some number of calls to do_define, this function is called to
* assigned value to the parsed name. If there is no value, then
* assign the string "1"
*/
static void def_finish()
{
if (def_name[0])
define_macro(def_name, "1", 0);
define_continue_flag = 0;
if (def_name[0]) {
if (define_text) {
define_macro(def_name, define_text, 0);
free(define_text);
define_text = 0;
define_cnt = 0;
} else {
define_macro(def_name, "1", 0);
}
def_name[0] = 0;
}
}
static void def_undefine()
@@ -477,12 +579,16 @@ static void def_undefine()
static void output_init()
{
if (line_direct_flag)
fprintf(yyout, "#line \"%s\" 0\n", istack->path);
fprintf(yyout, "`line 1 \"%s\" 0\n", istack->path);
}
static void include_filename()
{
assert(standby == 0);
if(standby) {
emit_pathline(istack);
fprintf(stderr, "error: malformed `include directive. Extra junk on line?\n");
exit(1);
}
standby = malloc(sizeof(struct include_stack_t));
standby->path = strdup(yytext+1);
standby->path[strlen(standby->path)-1] = 0;
@@ -494,7 +600,9 @@ static void do_include()
if (standby->path[0] == '/') {
standby->file = fopen(standby->path, "r");
if(depend_file && standby->file) {
fprintf(depend_file, "%s\n", istack->path);
}
} else {
unsigned idx = 0;
standby->file = 0;
@@ -502,14 +610,18 @@ static void do_include()
char path[4096];
sprintf(path, "%s/%s", include_dir[idx], standby->path);
standby->file = fopen(path, "r");
if (standby->file)
if (standby->file) {
if(depend_file) {
fprintf(depend_file, "%s\n", path);
}
break;
}
}
}
if (standby->file == 0) {
perror(standby->path);
fprintf(stderr, "%s:%u: Include file %s not found\n",
istack->path, istack->lineno, standby->path);
exit(1);
}
@@ -521,8 +633,24 @@ static void do_include()
yy_switch_to_buffer(yy_new_buffer(istack->file, YY_BUF_SIZE));
if (line_direct_flag && istack->path)
fprintf(yyout, "\n#line \"%s\" %u\n",
istack->path, istack->lineno);
fprintf(yyout, "\n`line %u \"%s\" 1\n",
istack->lineno+1, istack->path);
}
/* walk the include stack until we find an entry with a valid pathname,
* and print the file and line from that entry for use in an error message.
* The istack entries created by def_match() for macro expansions do not
* contain pathnames. This finds instead the real file in which the outermost
* macro was used.
*/
static void emit_pathline(struct include_stack_t*isp)
{
while(isp && (isp->path == NULL)) {
isp = isp->next;
}
assert(isp);
fprintf(stderr, "%s:%u: ",
isp->path, isp->lineno+1);
}
/*
@@ -574,7 +702,10 @@ static int yywrap()
}
if (line_direct_flag)
fprintf(yyout, "\n#line \"%s\" 0\n", istack->path);
fprintf(yyout, "\n`line 1 \"%s\" 0\n", istack->path);
if(depend_file) {
fprintf(depend_file, "%s\n", istack->path);
}
yyrestart(istack->file);
return 0;
@@ -587,8 +718,8 @@ static int yywrap()
yy_switch_to_buffer(istack->yybs);
if (line_direct_flag && istack->path && !line_mask_flag)
fprintf(yyout, "\n#line \"%s\" %u\n",
istack->path, istack->lineno);
fprintf(yyout, "\n`line %u \"%s\" 2\n",
istack->lineno+1, istack->path);
return 0;
}
@@ -610,6 +741,9 @@ void reset_lexor(FILE*out, char*paths[])
perror(paths[0]);
exit(1);
}
if(depend_file) {
fprintf(depend_file, "%s\n", paths[0]);
}
yyout = out;
+127 -10
View File
@@ -16,8 +16,8 @@ const char COPYRIGHT[] =
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: main.c,v 1.11 2001/07/25 03:10:50 steve Exp $"
#ifdef HAVE_CVS_IDENT
#ident "$Id: main.c,v 1.16 2002/08/12 01:35:02 steve Exp $"
#endif
# include "config.h"
@@ -42,7 +42,9 @@ const char VERSION[] = "$Name: $ $State: Exp $";
# include <stdio.h>
# include <stdlib.h>
#ifdef HAVE_MALLOC_H
# include <malloc.h>
#endif
# include <unistd.h>
# include <string.h>
#if defined(HAVE_GETOPT_H)
@@ -56,18 +58,75 @@ extern int optind;
extern const char*optarg;
#endif
/*
* Keep in source_list an array of pointers to file names. The array
* is terminated by a pointer to null.
*/
static char**source_list = 0;
static unsigned source_cnt = 0;
void add_source_file(const char*name)
{
if (source_list == 0) {
source_list = calloc(2, sizeof(char*));
source_list[0] = strdup(name);
source_list[1] = 0;
source_cnt = 1;
} else {
source_list = realloc(source_list, sizeof(char*) * (source_cnt+2));
source_list[source_cnt+0] = strdup(name);
source_list[source_cnt+1] = 0;
source_cnt += 1;
}
}
char**include_dir = 0;
unsigned include_cnt = 0;
int line_direct_flag = 0;
unsigned error_count = 0;
FILE *depend_file = NULL;
/*
* This function reads from a file a list of file names. Each name
* starts with the first non-space character, and ends with the last
* non-space character. Spaces in the middle are OK.
*/
static int flist_read_names(const char*path)
{
char line_buf[2048];
FILE*fd = fopen(path, "r");
if (fd == 0) {
fprintf(stderr, "%s: unable to open for reading.\n", path);
return 1;
}
while (fgets(line_buf, sizeof line_buf, fd) != 0) {
char*cp = line_buf + strspn(line_buf, " \t\r\b\f");
char*tail = cp + strlen(cp);
while (tail > cp) {
if (! isspace(tail[-1]))
break;
tail -= 1;
tail[0] = 0;
}
if (cp < tail)
add_source_file(cp);
}
return 0;
}
int main(int argc, char*argv[])
{
int opt;
int opt, idx;
const char*flist_path = 0;
unsigned flag_errors = 0;
char*out_path = 0;
char *dep_path = NULL;
FILE*out;
/* Define preprocessor keywords that I plan to just pass. */
@@ -93,7 +152,7 @@ int main(int argc, char*argv[])
include_dir[0] = strdup(".");
include_cnt = 1;
while ((opt = getopt(argc, argv, "D:I:K:Lo:v")) != EOF) switch (opt) {
while ((opt = getopt(argc, argv, "D:f:I:K:LM:o:v")) != EOF) switch (opt) {
case 'D': {
char*tmp = strdup(optarg);
@@ -108,6 +167,14 @@ int main(int argc, char*argv[])
break;
}
case 'f':
if (flist_path) {
fprintf(stderr, "%s: duplicate -f flag\n", argv[0]);
flag_errors += 1;
}
flist_path = optarg;
break;
case 'I':
include_dir = realloc(include_dir, (include_cnt+1)*sizeof(char*));
include_dir[include_cnt] = strdup(optarg);
@@ -127,6 +194,14 @@ int main(int argc, char*argv[])
line_direct_flag = 1;
break;
case 'M':
if (dep_path) {
fprintf(stderr, "duplicate -M flag.\n");
} else {
dep_path = optarg;
}
break;
case 'o':
if (out_path) {
fprintf(stderr, "duplicate -o flag.\n");
@@ -147,21 +222,35 @@ int main(int argc, char*argv[])
break;
}
if (optind == argc)
flag_errors += 1;
if (flag_errors) {
fprintf(stderr, "\nUsage: %s [-v][-L][-I<dir>][-D<def>] <file>...\n"
" -D<def> - Predefine a value.\n"
" -f<fil> - Read the sources listed in the file\n"
" -I<dir> - Add an include file search directory\n"
" -K<def> - Define a keyword macro that I just pass\n"
" -L - Emit line number directives\n"
" -M<fil> - Write dependencies to <fil>\n"
" -o<fil> - Send the output to <fil>\n"
" -v - Print version information\n",
argv[0]);
return flag_errors;
}
/* Collect the file names on the command line in the source
file list, then if there is a file list, read more file
names from there. */
for (idx = optind ; idx < argc ; idx += 1)
add_source_file(argv[idx]);
if (flist_path) {
int rc = flist_read_names(flist_path);
if (rc != 0)
return rc;
}
/* Figure out what to use for an output file. Write to stdout
if no path is specified. */
if (out_path) {
out = fopen(out_path, "w");
if (out == 0) {
@@ -172,20 +261,48 @@ int main(int argc, char*argv[])
out = stdout;
}
if (argv[optind] == 0) {
if(dep_path) {
depend_file = fopen(dep_path, "w");
if (depend_file == 0) {
perror(dep_path);
exit(1);
}
}
if (source_cnt == 0) {
fprintf(stderr, "%s: No input files given.\n", argv[0]);
return 1;
}
reset_lexor(out, argv+optind);
/* Pass to the lexical analyzer the list of input file, and
start the parser. */
reset_lexor(out, source_list);
if (yyparse()) return -1;
if(depend_file) {
fclose(depend_file);
}
return error_count;
}
/*
* $Log: main.c,v $
* Revision 1.16 2002/08/12 01:35:02 steve
* conditional ident string using autoconfig.
*
* Revision 1.15 2002/04/04 05:26:13 steve
* Add dependency generation.
*
* Revision 1.14 2001/11/21 02:59:27 steve
* Remove diag print.
*
* Revision 1.13 2001/11/21 02:20:35 steve
* Pass list of file to ivlpp via temporary file.
*
* Revision 1.12 2001/09/15 18:27:04 steve
* Make configure detect malloc.h
*
* Revision 1.11 2001/07/25 03:10:50 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
+3 -1
View File
@@ -19,9 +19,11 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: parse.y,v 1.2 2000/08/20 17:49:05 steve Exp $"
#ident "$Id: parse.y,v 1.3 2002/01/24 03:57:45 steve Exp $"
#endif
# include <stdio.h>
static void yyerror(const char*msg);
%}
+136 -65
View File
@@ -19,23 +19,22 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: lexor.lex,v 1.62 2001/08/31 17:38:41 steve Exp $"
#ident "$Id: lexor.lex,v 1.74 2002/12/04 02:07:00 steve Exp $"
#endif
# include "config.h"
//# define YYSTYPE lexval
# include <iostream.h>
# include <iostream>
# include "compiler.h"
# include "parse_misc.h"
# include "parse_api.h"
# include "parse.h"
# include <ctype.h>
# include <string.h>
# include "lexor_keyword.h"
extern FILE*vl_input;
extern string vl_file;
# define YY_USER_INIT reset_lexor();
# define yylval VLlval
@@ -75,9 +74,9 @@ static const char* set_file_name(char*text)
}
extern void pform_set_timescale(int, int);
extern void pform_set_timescale(int, int, const char*file, unsigned line);
static void reset_lexor();
void reset_lexor();
static void line_directive();
static void line_directive2();
@@ -90,12 +89,15 @@ static verinum*make_unsized_dec(const char*txt);
static verinum*make_unsized_octal(const char*txt);
static verinum*make_unsized_hex(const char*txt);
static int dec_buf_div2(char *buf);
static void process_timescale(const char*txt);
static int comment_enter;
%}
%x CCOMMENT
%x PCOMMENT
%x LCOMMENT
%x CSTRING
%s UDPTABLE
@@ -111,15 +113,24 @@ W [ \t\b\f\r]+
[ \t\b\f\r] { ; }
\n { yylloc.first_line += 1; }
/* C++ style comments start with / / and run to the ene of the
current line. These are very easy to handle. */
"//".* { comment_enter = YY_START; BEGIN(LCOMMENT); }
<LCOMMENT>. { yymore(); }
<LCOMMENT>\n { yylloc.first_line += 1; BEGIN(comment_enter); }
/* The contents of C-style comments are ignored, like white space. */
"/*" { comment_enter = YY_START; BEGIN(CCOMMENT); }
<CCOMMENT>. { yymore(); }
<CCOMMENT>\n { yylloc.first_line += 1; yymore(); }
<CCOMMENT>"*/" { BEGIN(comment_enter); }
"(*" { return K_PSTAR; }
"*)" { return K_STARP; }
"<<" { return K_LS; }
">>" { return K_RS; }
"<=" { return K_LE; }
@@ -182,20 +193,19 @@ W [ \t\b\f\r]+
[a-zA-Z_][a-zA-Z0-9$_]* {
int rc = lexor_keyword_code(yytext, yyleng);
if (rc == IDENTIFIER)
if (rc == IDENTIFIER) {
yylval.text = strdup(yytext);
else
if (strncmp(yylval.text,"PATHPULSE$", 10) == 0)
rc = PATHPULSE_IDENTIFIER;
} else {
yylval.text = 0;
}
return rc;
}
[a-zA-Z_][a-zA-Z0-9$_]*(\.[a-zA-Z_][a-zA-Z0-9$_]*)+ {
yylval.text = strdup(yytext);
return HIDENTIFIER; }
\\[^ \t\b\f\r]+ {
\\[^ \t\b\f\r\n]+ {
yylval.text = strdup(yytext+1);
return IDENTIFIER; }
@@ -217,15 +227,6 @@ W [ \t\b\f\r]+
yylval.text = strdup(yytext);
return SYSTEM_IDENTIFIER; }
\.{W}?(([a-zA-Z_][a-zA-Z0-9$_]*)|(\\[^ \t\b\f\r]+)) {
char*cp = yytext+1;
while ( (!(isalpha(*cp) || (*cp == '_'))) && (*cp != '\\'))
cp += 1;
if (*cp == '\\')
cp++;
yylval.text = strdup(cp);
return PORTNAME; }
[0-9][0-9_]*[ \t]*\'[sS]?[dD][ \t]*[0-9][0-9_]* {
yylval.number = make_sized_dec(yytext);
return NUMBER; }
@@ -249,19 +250,38 @@ W [ \t\b\f\r]+
return NUMBER; }
[0-9][0-9_]* {
/* Handle the special case of the unsized decimal number. */
unsigned long value = 0;
for (const char*cp = yytext ; *cp ; cp += 1) {
if (*cp != '_')
value = 10 * value + (*cp - '0');
char buf[4096];
if (strlen(yytext) >= sizeof(buf)-2){
fprintf(stderr, "Ridicilously long decimal constant will be truncated!\n");
}
assert(INTEGER_WIDTH <= (8*sizeof(value)));
unsigned nbits = INTEGER_WIDTH;
verinum::V*bits = new verinum::V[8 * sizeof value];
strncpy(buf, yytext, sizeof(buf)-2);
buf[sizeof(buf)-1] = 0;
for (unsigned idx = 0 ; idx < nbits ; idx += 1, value >>= 1) {
bits[idx] = (value&1) ? verinum::V1 : verinum::V0;
/* Convert the decimal number to a binary value, one digit at
a time. Watch out for overflow. */
verinum::V*bits = new verinum::V[INTEGER_WIDTH];
unsigned idx=0;
unsigned nbits=INTEGER_WIDTH;
while(idx<nbits){
int rem = dec_buf_div2(buf);
bits[idx] = (rem==1) ? verinum::V1 : verinum::V0;
++idx;
}
for(; idx<nbits; ++idx){
bits[idx] = verinum::V0;
}
/* If we run out of bits to hold the value, but there are
still valueable bits in the number, print a warning. */
if (strcmp(buf, "0") != 0){
cerr << yylloc.text << ":" << yylloc.first_line <<
": warning: Numeric decimal constant ``" << yytext <<
"'' truncated to " << nbits << " bits." << endl;
}
yylval.number = new verinum(bits, nbits, false);
@@ -355,7 +375,7 @@ W [ \t\b\f\r]+
if (isgraph(yytext[0]))
cerr << yytext[0];
else
cerr << (unsigned)yytext[0];
cerr << "hex " << hex << (0xffU & ((unsigned) (yytext[0])));
cerr << ")" << endl; }
@@ -746,7 +766,7 @@ static verinum*make_sized_hex(const char*txt)
"'' truncated to " << size << " bits." << endl;
// zero extend hex numbers
while (idx < size) switch (ptr[1]) {
while (idx < size) switch (ptr[0]) {
case 'x': case 'X':
bits[idx++] = verinum::Vx;
break;
@@ -832,13 +852,65 @@ static verinum*make_unsized_hex(const char*txt)
return out;
}
/* Divide the integer given by the string by 2. Return the remainder bit. */
static int dec_buf_div2(char *buf)
{
int partial;
int len = strlen(buf);
char *dst_ptr;
int pos;
partial = 0;
pos = 0;
/* dst_ptr overwrites buf, but all characters that are overwritten
were already used by the reader. */
dst_ptr = buf;
while(buf[pos] == '0')
++pos;
for(; pos<len; ++pos){
if (buf[pos]=='_')
continue;
assert(isdigit(buf[pos]));
partial= partial*10 + (buf[pos]-'0');
if (partial >= 2){
*dst_ptr = partial/2 + '0';
partial = partial & 1;
++dst_ptr;
}
else{
*dst_ptr = '0';
++dst_ptr;
}
}
// If result of division was zero string, it should remain that way.
// Don't eat the last zero...
if (dst_ptr == buf){
*dst_ptr = '0';
++dst_ptr;
}
*dst_ptr = 0;
return partial;
}
/*
* Making a decimal number is much easier then the other base numbers
* because there are no z or x values to worry about.
*/
static verinum*make_dec_with_size(unsigned size, bool fixed, const char*ptr)
{
char buf[4096];
bool signed_flag = false;
if (tolower(*ptr) == 's') {
signed_flag = true;
ptr += 1;
@@ -849,40 +921,36 @@ static verinum*make_dec_with_size(unsigned size, bool fixed, const char*ptr)
while (*ptr && ((*ptr == ' ') || (*ptr == '\t')))
ptr += 1;
const char*digits = ptr;
/* Convert the decimal number to a binary value, one digit at
a time. Watch out for overflow. */
unsigned long value = 0;
for ( ; *ptr ; ptr += 1)
if (isdigit(*ptr)) {
unsigned long tmp = value * 10 + (*ptr - '0');
if (tmp < value)
cerr << yylloc.text << ":" << yylloc.first_line <<
": warning: Numeric decimal constant ``"
<< digits << "'' is too large." << endl;
value *= 10;
value += *ptr - '0';
} else {
assert(*ptr == '_');
}
verinum::V*bits = new verinum::V[size];
for (unsigned idx = 0 ; idx < size ; idx += 1) {
bits[idx] = (value&1)? verinum::V1 : verinum::V0;
value /= 2;
if (strlen(ptr) >= sizeof(buf)-2){
fprintf(stderr, "Ridicilously long decimal constant will be truncated!\n");
}
/* If we run out of bits to hold the value, but there are
still valueable bits in the number, print a warning. */
strncpy(buf, ptr, sizeof(buf)-2);
buf[sizeof(buf)-1] = 0;
if (value != 0)
/* Convert the decimal number to a binary value, one digit at
a time. Watch out for overflow. */
verinum::V*bits = new verinum::V[size];
unsigned idx=0;
while(idx<size){
int rem = dec_buf_div2(buf);
bits[idx] = (rem==1) ? verinum::V1 : verinum::V0;
++idx;
}
for(; idx<size; ++idx){
bits[idx] = verinum::V0;
}
/* If we run out of bits to hold the value, but there are
still valueable bits in the number, print a warning. */
if (strcmp(buf, "0") != 0){
cerr << yylloc.text << ":" << yylloc.first_line <<
": warning: Numeric decimal constant ``" << digits <<
": warning: Numeric decimal constant ``" << ptr <<
"'' truncated to " << size << " bits." << endl;
}
verinum*out = new verinum(bits, size, fixed);
out->has_sign(signed_flag);
@@ -1010,7 +1078,7 @@ static void process_timescale(const char*txt)
return;
}
pform_set_timescale(unit, prec);
pform_set_timescale(unit, prec, yylloc.text, yylloc.first_line);
}
int yywrap()
@@ -1049,6 +1117,8 @@ static void line_directive2()
cp += strspn(cp, " ");
yylloc.first_line = strtoul(cp,&cp,10);
yylloc.first_line -= 1;
cp += strspn(cp, " ");
if (*cp == 0) return;
@@ -1066,7 +1136,8 @@ static void line_directive2()
yylloc.text = set_file_name(buf);
}
static void reset_lexor()
extern FILE*vl_input;
void reset_lexor()
{
yyrestart(vl_input);
yylloc.first_line = 1;
+1 -1
View File
@@ -82,7 +82,7 @@ rpmos, K_rpmos
rtran, K_rtran
rtranif0, K_rtranif0
rtranif1, K_rtranif1
scalered, K_scalered
scalared, K_scalared
signed, K_signed
small, K_small
specify, K_specify
+5 -2
View File
@@ -18,14 +18,17 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: lexor_keyword.h,v 1.1 2000/03/12 17:09:41 steve Exp $"
#ifdef HAVE_CVS_IDENT
#ident "$Id: lexor_keyword.h,v 1.2 2002/08/12 01:34:59 steve Exp $"
#endif
extern int lexor_keyword_code (const char*str, unsigned len);
/*
* $Log: lexor_keyword.h,v $
* Revision 1.2 2002/08/12 01:34:59 steve
* conditional ident string using autoconfig.
*
* Revision 1.1 2000/03/12 17:09:41 steve
* Support localparam.
*
+4
View File
@@ -0,0 +1,4 @@
Makefile
configure
config.*
dep
+89
View File
@@ -0,0 +1,89 @@
#
# This source code is free software; you can redistribute it
# and/or modify it in source code form under the terms of the GNU
# Library General Public License as published by the Free Software
# Foundation; either version 2 of the License, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Library General Public License for more details.
#
# You should have received a copy of the GNU Library General Public
# License along with this program; if not, write to the Free
# Software Foundation, Inc.,
# 59 Temple Place - Suite 330
# Boston, MA 02111-1307, USA
#
#ident "$Id: Makefile.in,v 1.14 2002/06/11 15:19:12 steve Exp $"
#
#
SHELL = /bin/sh
prefix = @prefix@
exec_prefix = @exec_prefix@
srcdir = @srcdir@
VPATH = $(srcdir)
bindir = @bindir@
libdir = @libdir@
includedir = $(prefix)/include
CC = @CC@ -I$(srcdir) -I$(srcdir)/..
CXX = @CXX@ -I$(srcdir) -I$(srcdir)/..
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
CPPFLAGS = @CPPFLAGS@ @DEFS@
CXXFLAGS = @CXXFLAGS@
CFLAGS = @CFLAGS@
LDFLAGS = @LDFLAGS@
STRIP = @STRIP@
A = a_close.o a_fetch_argc.o a_fetch_argv.o a_fetch_fullname.o \
a_fetch_tfarg.o a_handle_tfarg.o \
a_initialize.o a_next_topmod.o a_object_of_type.o a_product_version.o \
a_set_value.o a_version.o
O = asynch.o finish.o getcstringp.o getinstance.o getlongp.o \
getp.o getsimtime.o io_print.o mc_scan_plusargs.o nump.o putlongp.o \
putp.o veriusertfs.o $A
all: libveriuser.a
check: all
Makefile: Makefile.in config.status
./config.status
libveriuser.a: $O
rm -f $@
ar cvq $@ $O
%.o: %.c
@[ -d dep ] || mkdir dep
$(CC) -Wall $(CPPFLAGS) $(CFLAGS) -MD -c $< -o $*.o
mv $*.d dep
clean:
rm -f *.o dep/*.d libveriuser.a
distclean: clean
rm -f Makefile config.status config.log config.cache
install:: all installdirs $(libdir)/libveriuser.a
$(libdir)/libveriuser.a: ./libveriuser.a
$(INSTALL_DATA) ./libveriuser.a $(libdir)/libveriuser.a
installdirs: mkinstalldirs
$(srcdir)/mkinstalldirs $(includedir) $(libdir)
uninstall::
rm -f $(libdir)/libveriuser.a
-include $(patsubst %.o, dep/%.d, $O)
+35
View File
@@ -0,0 +1,35 @@
/*
* Copyright (c) 2002 Michael Ruff (mruff at chiaro.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: a_close.c,v 1.2 2002/08/12 01:35:02 steve Exp $"
#endif
# include <acc_user.h>
void acc_close(void) { }
/*
* $Log: a_close.c,v $
* Revision 1.2 2002/08/12 01:35:02 steve
* conditional ident string using autoconfig.
*
* Revision 1.1 2002/05/23 03:46:42 steve
* Add the acc_user.h header file.
*
*/
+49
View File
@@ -0,0 +1,49 @@
/* vi:sw=6
* Copyright (c) 2002 Michael Ruff (mruff at chiaro.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: a_fetch_argc.c,v 1.2 2002/08/12 01:35:02 steve Exp $"
#endif
# include <vpi_user.h>
# include <veriuser.h>
/*
* acc_fetch_argc implemented using VPI interface
*/
int acc_fetch_argc(void)
{
s_vpi_vlog_info vpi_vlog_info;
/* get command line info */
if (! vpi_get_vlog_info(&vpi_vlog_info))
return 0;
/* return argc */
return vpi_vlog_info.argc;
}
/*
* $Log: a_fetch_argc.c,v $
* Revision 1.2 2002/08/12 01:35:02 steve
* conditional ident string using autoconfig.
*
* Revision 1.1 2002/06/11 15:19:12 steve
* Add acc_fetch_argc/argv/version (mruff)
*
*/

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