Compare commits

...
1070 Commits
Author SHA1 Message Date
steve 298a352cbd Add documentation for the code generator. 2001-09-02 23:58:49 +00:00
steve 356552faad Add virtex support for some basic logic, the DFF
and constant signals.
2001-09-02 23:53:55 +00:00
steve 5e1e79b3c4 Rearrange the XNF code generator to be generic-xnf
so that non-XNF code generation is also possible.

 Start into the virtex EDIF output driver.
2001-09-02 21:33:07 +00:00
steve 2996d2eb19 Generic ADD code. 2001-09-01 04:30:44 +00:00
steve 16023cbbd6 Generate code for MUX devices. 2001-09-01 02:28:42 +00:00
steve 77927972e5 identity compare, and PWR records for constants. 2001-09-01 02:01:30 +00:00
steve d762a320dc Make constants available through the design root 2001-09-01 01:57:31 +00:00
steve a9e54e7553 dead comments. 2001-09-01 00:58:16 +00:00
steve 8b8a3d83e0 Relax pin count restriction on logic gates. 2001-08-31 23:02:13 +00:00
steve 3fbbd4080a synthesize the special case of compare with 0. 2001-08-31 22:59:48 +00:00
steve e79a371f76 Support DFF CE inputs. 2001-08-31 22:58:39 +00:00
steve c507379f09 Handle more path polarity cases. 2001-08-31 21:08:35 +00:00
steve 47031767fa Parse $setuphold statements. 2001-08-31 17:38:41 +00:00
steve af5e68448c Add the fpga target. 2001-08-31 17:28:10 +00:00
steve c1c88f87c6 Many more logic gate types. 2001-08-31 04:17:56 +00:00
steve a9b5c9c037 Add root port SIG records. 2001-08-31 02:59:06 +00:00
steve 03b428b6cb Handle update in place of repeat constants. 2001-08-31 01:37:56 +00:00
steve 271a835305 Bind escaped names with non-escaped equivilents. (PR#256) 2001-08-30 22:40:12 +00:00
steve a3c3019a04 Mangle nexus names. 2001-08-30 04:31:04 +00:00
steve f063bf833f Add the fpga target. 2001-08-28 04:14:20 +00:00
steve 2002c03cef Add some ivl_target convenience functions. 2001-08-28 04:07:17 +00:00
steve b8be5e80cd Generate code for l-value bit selects. 2001-08-26 23:00:13 +00:00
steve c29e11ed36 Add the assign/x0 and set/x opcodes. 2001-08-26 22:59:32 +00:00
steve e35ed6e91c 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.

 Change the vvp code generator to support multiple
 l-values, i.e. concatenations of part selects.
2001-08-25 23:50:02 +00:00
steve 794ce68a6c Only use fvectors for nets and vars. 2001-08-25 17:22:32 +00:00
steve 31aa85ce7d Handle wide assignment to narrow return value. 2001-08-23 02:54:15 +00:00
steve 15c2b0317d statement ends after while loop labels. 2001-08-16 03:45:17 +00:00
steve 820d8b9edc Support various other string formats for time. 2001-08-16 03:29:31 +00:00
steve a3a0f5f432 Add some missing print escape sequences. 2001-08-16 03:26:04 +00:00
steve a98b5023a8 Describe the new .net behavior. 2001-08-10 04:31:27 +00:00
steve 645c8913f1 Neaten and document the resolv object. 2001-08-10 04:31:09 +00:00
steve 066284d5c2 Make sure arithmetic objects run at time 0. 2001-08-10 00:50:50 +00:00
steve 2802601c44 tgt-vvp generates code that skips nets as inputs. 2001-08-10 00:40:45 +00:00
steve 962a77c6b8 Rearrange bison parameters for portability. 2001-08-10 00:39:22 +00:00
steve ca801574e3 Include functor address in debug functor print. 2001-08-09 22:25:30 +00:00
steve 606c1d38bb Nets (wires) do not use their own functors.
Modifications to propagation of values.
 (Stephan Boettcher)
2001-08-09 19:38:23 +00:00
steve 147ee59940 memory port bug fix. 2001-08-09 19:37:05 +00:00
steve 2e3fc89831 rearrange bison parameters for compatability. 2001-08-09 19:35:29 +00:00
steve 82bccd335d Initial implementation of vvp_fvectors.
(Stephan Boettcher)
2001-08-08 01:05:06 +00:00
steve bfc05e2d71 Unused variable warnings. 2001-08-08 00:57:20 +00:00
steve c8135595be signed/unsigned warnings? 2001-08-08 00:53:50 +00:00
steve d5658d4180 dosify compiled with mingw does not know cygwin paths. 2001-08-05 17:28:40 +00:00
steve 8356e6a51f Properly synthesize part selects. 2001-08-05 02:49:07 +00:00
steve fbf55b9df4 Get the hello.vl and sqrt.vl names right. 2001-08-04 05:53:44 +00:00
steve 176e6d09ca Add install of examples for Windows. 2001-08-03 17:06:47 +00:00
steve b72d1c297d More detailed messages about unsupported things. 2001-08-03 17:06:10 +00:00
steve f5b9c26735 Detect system function used as a task. 2001-08-03 06:50:44 +00:00
steve d8141252e9 Accept empty port lists to module instantiation. 2001-08-01 05:17:31 +00:00
steve ed86dee65d Initialize initial functor tables. 2001-07-30 03:53:01 +00:00
steve f535cd3077 Add quickstart and mingw.txt to documentation list. 2001-07-30 03:44:48 +00:00
steve 537757a7b9 Cleanup defines and types for mingw compile. 2001-07-30 02:44:05 +00:00
steve 4fb354776e misspell ivl_expr_lsi 2001-07-30 02:43:20 +00:00
steve 1583b1e84a Reference the iverilog man page. 2001-07-29 22:50:44 +00:00
steve 45ff04ecb6 Reference the vvp man page. 2001-07-29 22:50:28 +00:00
steve ef08e43cf2 support local reference to scope in expressions. 2001-07-29 22:22:40 +00:00
steve e17f7f5146 Detect a missing task definition before it crashes me. 2001-07-28 22:13:11 +00:00
steve 8654412844 lsb vs msb in error message. 2001-07-28 22:00:27 +00:00
steve 140533db50 If module name has a /, skip the path search. 2001-07-28 03:29:42 +00:00
steve 00cacae2a3 Generate constant symbols for supply nets. 2001-07-28 03:18:50 +00:00
steve 7e0b0d7328 Support C<su0> and C<su1> special symbols. 2001-07-28 03:12:39 +00:00
steve 1be77d68ce Evaluate part selects when passed to system tasks. 2001-07-28 01:18:07 +00:00
steve c5a5a11b7f Support getting the signal from IVL_EX_SIGNAL expressions. 2001-07-28 01:17:40 +00:00
steve becc7cb56a Handle part select expressions as variants of
NetESignal/IVL_EX_SIGNAL objects, instead of
 creating new and useless temporary signals.
2001-07-27 04:51:44 +00:00
steve 629a02cccf Fix binding of dangling function ports. do not elide them. 2001-07-27 02:41:55 +00:00
steve f28b97ebfd Spelling error 2001-07-27 02:41:28 +00:00
steve c5234e95cd Make the -M flag add module search paths. 2001-07-26 03:13:51 +00:00
steve b825f8d2b2 Create a config.h.in file to hold all the config
junk, and support gcc 3.0. (Stephan Boettcher)
2001-07-25 03:10:48 +00:00
steve eb08253ed0 UPdate for 0.5 content. 2001-07-25 02:32:11 +00:00
steve 7b79fd98e5 Fast UDP tables (Stephan Boettcher) 2001-07-24 01:44:50 +00:00
steve 6d5fcf5853 Implement string value for signals. 2001-07-24 01:34:56 +00:00
steve bc284ee6d8 supply signals give input values. 2001-07-22 21:31:14 +00:00
steve 260b4166c1 Recognize supply signal types. 2001-07-22 21:30:56 +00:00
steve b59cc5ff6d Update config.sub and config.guess scripts. 2001-07-22 19:50:55 +00:00
steve 5c89fb71ae Handle repeat for concatenation expressions. 2001-07-22 19:33:51 +00:00
steve 3baa8c0445 vvm does not have a stdlog. 2001-07-22 18:19:19 +00:00
steve ce589da58a Support the NetESubSignal expressions in vvp.tgt. 2001-07-22 00:17:49 +00:00
steve 0bb9359c05 ignore config.cache. 2001-07-22 00:17:22 +00:00
steve 54140dadcf Add the load/x instruction for bit selects. 2001-07-22 00:04:50 +00:00
steve 60c22aefeb Add the -h flag for help. (Stephan Boettcher) 2001-07-21 21:18:55 +00:00
steve 69a2331791 Document the -l flag (Stephan Boettcher) 2001-07-21 21:15:51 +00:00
steve 29cfd8ccfe Add a quick-start document. 2001-07-21 04:39:26 +00:00
steve bf67f386de Add the vvp man page. 2001-07-21 04:34:25 +00:00
steve a2f07011c1 Fix blending of ambiguous pairs. 2001-07-21 02:34:39 +00:00
steve 0bd6cf7b6f Fix of_END when a middle thread ends. 2001-07-20 04:57:00 +00:00
steve cd8e491028 Support calculated delays in vvp.tgt. 2001-07-19 04:55:06 +00:00
steve e773ccfe49 Add support for the delayx opcode. 2001-07-19 04:40:55 +00:00
steve 83de770387 Do not connect reg to module outputs. 2001-07-19 03:43:15 +00:00
steve b3a8098506 EOF is the same as resume. 2001-07-19 02:20:55 +00:00
steve 05407f488f Relax driver limit from 64 to forever (Stephan Boettcher) 2001-07-18 02:44:39 +00:00
steve 85d53ebbf4 Handle 0 counts in repeat concatenation. 2001-07-16 20:41:41 +00:00
steve e4139f4819 Schedule instead of propagating UDP output. (Stephan Boettcher) 2001-07-16 19:08:32 +00:00
steve 45c935af45 Cut off scope iteration when depth runs out. 2001-07-16 18:53:16 +00:00
steve cfbfd9ec1d Properly pad unknow values. (Stephan Boettcher) 2001-07-16 18:48:07 +00:00
steve ae209a144f Add a stdlog output for vvp, and vvp options
to direct them around. (Stephan Boettcher.)
2001-07-16 18:40:19 +00:00
steve 64837efac5 Nest resolvers when there are lots of drivers (Stephan Boettcher) 2001-07-16 18:31:49 +00:00
steve 8d73df2b04 Make vvp output executable (Stephan Boettcher) 2001-07-16 18:26:08 +00:00
steve 59117c2e42 dot in escaped identifiers are not scope. (Stephan Boettcher) 2001-07-16 18:20:27 +00:00
steve e23dd57c9d Reshuffle -v and -V flags of ivl. (Stephan Boettcher) 2001-07-16 18:14:56 +00:00
steve 0e20be774e Initialize allocated functors (Stephan Boettcher) 2001-07-16 18:06:01 +00:00
steve c3ae00ae49 Merge sig and old_ival into union to save space. 2001-07-16 17:57:51 +00:00
steve a7328ecce1 Rewire signal callback support for fast lookup. (Stephan Boettcher) 2001-07-13 03:02:34 +00:00
steve 15a952a143 Remove width restriction on subtraction. 2001-07-13 00:38:57 +00:00
steve 3154f07817 compile libvpi.a with PIC flags (Dan McMahill) 2001-07-11 19:32:02 +00:00
steve 4e700bffb8 support postpone of $systask parameters. (Stephan Boettcher) 2001-07-11 04:43:57 +00:00
steve 7b2d4c9ef6 Get endian of vpiIntVal from constants. 2001-07-11 04:40:52 +00:00
steve da828a218f Add support for REadOnlySync and monitors. 2001-07-11 02:27:21 +00:00
steve 13ef84bc35 Manually create the stage-2 callback structure. 2001-07-11 02:22:17 +00:00
steve c7b36322f6 Properly step through wide inputs. (Stephan Boettcher) 2001-07-09 15:38:35 +00:00
steve 8cc89a3a1f Pass parameters to system functions. 2001-07-07 20:20:10 +00:00
steve b8c5aff0cb Generate !== an an inverted === 2001-07-07 04:37:18 +00:00
steve fb0c387b12 Detect and make available to t-dll the right shift. 2001-07-07 03:01:37 +00:00
steve 1628045b55 Generate code for right shift. 2001-07-07 03:01:06 +00:00
steve 608e5a4dbb Add the .shift/r functor. 2001-07-07 02:57:33 +00:00
steve 30787fd49e Put synthesized signals in proper scope. 2001-07-07 01:38:45 +00:00
steve 1e231c3338 Properly initialize unconnected shift inputs. 2001-07-06 05:02:43 +00:00
steve 370549a19a Generate code for structural left shift. 2001-07-06 04:48:04 +00:00
steve 39c39f0162 Add structural left shift (.shift/l) 2001-07-06 04:46:44 +00:00
steve bcaa122fb9 handle left shifter in dll output. 2001-07-04 22:59:25 +00:00
steve 96403de903 Describe .shift behavior. 2001-07-04 22:59:04 +00:00
steve ab5cad18de Relax limit on behavioral subtraction. 2001-07-04 04:57:10 +00:00
steve b1c548a981 Scope-locals use _s instead of _l. 2001-07-04 04:34:06 +00:00
steve 039769dbaf Generate verbuse status messages (Stephan Boettcher) 2001-07-03 04:09:24 +00:00
steve a76d6dc352 Add the -V flag, and some verbose messages. 2001-07-02 01:57:27 +00:00
steve 7eab75ded1 Parse a lot more specify syntax. 2001-07-01 23:44:43 +00:00
steve ef9c7c4a30 Print memory l-values. 2001-07-01 23:44:19 +00:00
steve 4c54e070ed header statements donot necessarily end in a string. 2001-07-01 23:43:58 +00:00
steve 80c609853a export the ivl_design_time_precision function. 2001-07-01 23:43:23 +00:00
steve eeabc7234c Make sure tmp net gets connected to ramdq output 2001-07-01 23:37:48 +00:00
steve 79b740284a Make NetFF constructor take const char* for the name. 2001-07-01 00:27:34 +00:00
steve ab7b353ace support fast programming by only writing the bits
that are listed in the input file.
2001-06-30 23:03:16 +00:00
steve 3b82a15521 reflect new default vvp target type. 2001-06-30 22:59:40 +00:00
steve 97d972ebb3 More details about running Icarus Verilog. 2001-06-30 21:54:16 +00:00
steve 5f5081827d Make the vvp target the default. 2001-06-30 21:53:42 +00:00
steve 6b7b4e700a Detect parameter mismatches. 2001-06-30 21:28:35 +00:00
steve baac893d22 Support non-const right shift (unsigned). 2001-06-30 21:07:26 +00:00
steve d680e594ed typo in CYMODE=EXAMINE-CI string. 2001-06-30 20:11:15 +00:00
steve 42adc49e57 Get include and lib paths right for mingw and vvm. 2001-06-30 04:23:02 +00:00
steve 4a2168b352 Describe the mingw compile. 2001-06-30 01:04:07 +00:00
steve 44d4660fe8 Redo the ivl_root calculator for mingw. 2001-06-30 00:59:24 +00:00
steve 45d4117c02 Handle null parameters to system tasks. 2001-06-29 02:41:05 +00:00
steve ae837a6347 Relax limit on width of structural sum. 2001-06-29 01:20:20 +00:00
steve 426fc18d10 Relax limit on width of structural sum. 2001-06-29 01:20:20 +00:00
steve 2531ed89cd Properly support signal full names. 2001-06-29 00:44:56 +00:00
steve 566d5c9a93 Get a private copy of the object name. 2001-06-29 00:42:39 +00:00
steve a033c331b6 Report line of unsupported cassign. 2001-06-27 18:34:43 +00:00
steve 066b534307 Get include and lib paths from Makefile. 2001-06-27 02:22:26 +00:00
steve 64cabd8074 Give task/function definitions a vpi type object. 2001-06-25 03:12:06 +00:00
steve a0db52c69f More robust about incorrect arguments. 2001-06-25 03:11:41 +00:00
steve 7bbedd1b55 Look up functor return register with tail of name. 2001-06-23 19:53:03 +00:00
steve 0340256b4c Include stdlib.h 2001-06-23 18:41:02 +00:00
steve c4bd8b1463 Generate %shiftl instructions for shift. 2001-06-23 18:40:34 +00:00
steve a2d465804f Add the %shiftl/i0 instruction. 2001-06-23 18:26:26 +00:00
steve 3c5d32637c Only try the readline library if vvp_debus is enabled. 2001-06-23 18:26:12 +00:00
steve c93cb71162 Allow forward references of task scopes. (Stephan Boettcher) 2001-06-23 01:04:07 +00:00
steve c3960f8e6a Support macromodule as module. 2001-06-23 00:31:06 +00:00
steve 96d04bb5a0 Handle short inputs to tasks. (Stephan Boettcher) 2001-06-23 00:30:42 +00:00
steve 1f1bfd0eab Infinitely wide behavioral add. 2001-06-22 00:03:05 +00:00
steve 8cdf51f913 Initialize stmt_cur_ substatements during dll case building. 2001-06-21 23:23:14 +00:00
steve 1f3eedcfd7 Some documentation of callback behavior. 2001-06-21 23:05:08 +00:00
steve 541f269c20 Support cbValueChange callbacks. 2001-06-21 22:54:12 +00:00
steve 68a7ddefd3 Escaped identifiers in behavioral expressions. (Stephan Boettcher) 2001-06-21 04:53:59 +00:00
steve 3961c68928 Add dumpon and dumpoff (Stephan Boettcher) 2001-06-21 04:15:22 +00:00
steve 832b795826 Edit ivl_install_dir only on mingw 2001-06-20 02:25:40 +00:00
steve 7a6be47603 Get va_start arguments in right order. 2001-06-19 14:57:10 +00:00
steve 81536481cc Add structural EEQ gates (Stephan Boettcher) 2001-06-19 03:01:10 +00:00
steve 6e703c5744 RAM_DQ pins are inputs, so connect HiZ to the nexus. 2001-06-18 03:25:20 +00:00
steve 82e8e51736 1. Logic with more than 4 inputs
2. Id and name mangling
  3. A memory leak in draw_net_in_scope()
  (Stephan Boettcher)
2001-06-18 03:10:34 +00:00
steve 905529081d Add the ~& reduction operator. 2001-06-18 01:54:49 +00:00
steve 4159c98c58 More behavioral unary reduction operators.
(Stephan Boettcher)
2001-06-18 01:09:32 +00:00
steve e40efec4bd Add more UDP edge types, and finish up compile
and run-time support. (Stephan Boettcher)
2001-06-18 00:51:23 +00:00
steve e418625457 export memory symbols in Windows. 2001-06-17 23:55:00 +00:00
steve 4b82d26f5e Add support for structural multiply in t-dll.
Add code generators and vvp support for both
 structural and behavioral multiply.
2001-06-16 23:45:05 +00:00
steve 63a02d1c0a Relax width restriction for structural comparators. 2001-06-16 03:36:03 +00:00
steve bf42772995 Generate code to support memory access in continuous
assignment statements. (Stephan Boettcher)
2001-06-16 02:41:41 +00:00
steve b75221e9bf Fix library path calculation on non Windows systems
to include the install directories. (Brendan Simon)
2001-06-15 05:14:21 +00:00
steve 1e9a54d134 iberty library only needed on Windows 2001-06-15 05:05:04 +00:00
steve ff0b59ff6b support LE and LT comparators. 2001-06-15 05:01:09 +00:00
steve b3a5a0e5ab Generate vvp code for GT and GE comparisons. 2001-06-15 04:14:18 +00:00
steve e002b1c1c4 Add .cmp statements for structural comparison. 2001-06-15 04:07:57 +00:00
steve 7009dc8d9b Change the VPI call process so that loaded .vpi modules
use a function table instead of implicit binding.
2001-06-15 03:28:30 +00:00
steve e28b7f06c5 update documentation to describe vpi in vvp. 2001-06-12 23:32:49 +00:00
steve b6e1d63cb0 Change the VPI call process so that loaded .vpi modules
use a function table instead of implicit binding.
2001-06-12 03:53:10 +00:00
steve 5a279dbdc8 Instructions can forward reference functors. 2001-06-10 17:12:51 +00:00
steve 3ad3a2ab57 support scan of scope from VPI. 2001-06-10 16:47:49 +00:00
steve 5361efe8ed Account for carry out on add devices. 2001-06-07 04:20:10 +00:00
steve 2f2657b765 support subtraction in tgt-vvp. 2001-06-07 03:09:37 +00:00
steve 19a7f3faeb Implement .arith/sub subtraction. 2001-06-07 03:09:03 +00:00
steve f480943649 Support structural addition. 2001-06-07 02:12:43 +00:00
steve f3019ff5a0 Add structural addition. 2001-06-05 03:05:41 +00:00
steve 33ee5c26b0 Fix the fork example. 2001-06-03 20:36:52 +00:00
steve 1e9184f0f9 Make the bufif0 and bufif1 gates strength aware,
and accurately propagate strengths of outputs.
2001-05-31 04:12:43 +00:00
steve 19251f7a79 Propagate strength-values instead of drive strengths. 2001-05-30 03:02:35 +00:00
steve b79da2c4d6 Detect input and input ports declared as reg. 2001-05-25 02:21:34 +00:00
steve e68ba4c73a Attach noops to case labels. 2001-05-24 04:31:00 +00:00
steve 39ffe91230 Add behavioral modulus. 2001-05-24 04:20:10 +00:00
steve 150fc6f3ee correctly interpret signed decimal values. 2001-05-22 04:08:49 +00:00
steve a7411eb00d Get the initial inputs to functors set at xxxx. 2001-05-22 04:08:16 +00:00
steve 660fd7c1d4 Update the mingw build to not require cygwin files. 2001-05-22 02:14:47 +00:00
steve 53772db66d Document configure details. 2001-05-22 02:07:08 +00:00
steve 93dd08bdf5 Configure diable of ipal. 2001-05-22 02:06:39 +00:00
steve 176d707e0a configure detect exe suffixes. 2001-05-22 02:05:50 +00:00
steve 34dade1b65 Fix WIFEXITED macro. 2001-05-20 18:22:02 +00:00
steve 4e815f8565 local declares if the header is missing. 2001-05-20 18:06:57 +00:00
steve e69a3ed934 declare getopt by hand in mingw32 compile. 2001-05-20 17:34:53 +00:00
steve 77d63aba74 make distclean target. 2001-05-20 17:13:27 +00:00
steve de8c725890 Mingw32 support (Venkat Iyer) 2001-05-20 15:09:39 +00:00
steve d4b2958e50 Deleted wrong time when -Tmax is selected. 2001-05-20 15:03:25 +00:00
steve 8669b372e0 Implement reduction nor. 2001-05-20 01:18:38 +00:00
steve 61991e6367 stub ivl_expr_parms for sfunctions. 2001-05-20 01:06:16 +00:00
steve bdcb813727 Initial support for system functions. 2001-05-20 01:02:55 +00:00
steve e6f1510a40 Make vthread_put_but expand the space if needed. 2001-05-20 00:56:48 +00:00
steve 224af78463 Add support for system function calls. 2001-05-20 00:46:12 +00:00
steve 983bf5cbab include missing externs on vthread_put_bit. 2001-05-20 00:45:43 +00:00
steve 96bcf6eac4 Get bit ordering right when making decimal strings. 2001-05-20 00:40:12 +00:00
steve 0872ad34cf Behavioral ternary operators for vvp. 2001-05-17 04:37:02 +00:00
steve 5aee3b866a do not assert if memory reference is invalid. 2001-05-17 03:35:22 +00:00
steve 3ce86f5664 Make error message include error: prefix. 2001-05-17 03:34:47 +00:00
steve 23e5394fb4 Make sure to get local headers first. 2001-05-17 03:22:18 +00:00
steve be7ac7a2ca Update help message. 2001-05-17 03:14:26 +00:00
steve a616cfd0c2 Update to new LPM API for flip-flops. 2001-05-16 03:55:30 +00:00
steve e85b669307 Add the glossary file. 2001-05-15 15:09:08 +00:00
steve bc6dfeb4a9 Skip the , in module lists. 2001-05-14 00:55:31 +00:00
steve bf96986c38 test width of target with bit size of long. 2001-05-14 00:42:32 +00:00
steve 26cfbb2b7b calculate the output of resolvers. 2001-05-13 21:05:06 +00:00
steve 35fc2a609d ignore make check droppings. 2001-05-13 05:06:25 +00:00
steve f05b13c630 A resolver that understands some simple strengths. 2001-05-12 20:38:06 +00:00
steve 4d8954be4c Fixup the resolver syntax. 2001-05-12 16:34:47 +00:00
steve 1d0a9871c2 Generate resolvers for multiple drivers. 2001-05-12 03:31:01 +00:00
steve 2292751fc3 Make sure LPM devices have drives on outputs. 2001-05-12 03:18:44 +00:00
steve a6524e47e2 Silly copyright typo. 2001-05-12 01:48:57 +00:00
steve 02b9aa9163 No entry breakpoint if debug is compiled out. 2001-05-11 03:26:31 +00:00
steve 754adce4a4 Missing export symbols. 2001-05-11 03:25:55 +00:00
steve f3fdf70b56 Export new ivl_ symbols. 2001-05-11 02:43:38 +00:00
steve 38db6fde0c Help for enable-vvp-debug 2001-05-11 02:10:30 +00:00
steve 4f804577f9 Add the --enable-vvp-debug option to the configure
script of vvp, and detect getopt.h.
2001-05-11 02:06:14 +00:00
steve 44a182d92c VVP support for memories in expressions,
including general support for thread bit
 vectors as system task parameters.
 (Stephan Boettcher)
2001-05-10 00:26:53 +00:00
steve 91d65d0e4e Add the vpi_user strength definitions. 2001-05-10 00:16:00 +00:00
steve a88f030b52 Now that the interactive debugger exists,
there is no use for the output dump.
2001-05-09 04:23:18 +00:00
steve 4537de8120 Implement the .resolv syntax. 2001-05-09 02:53:25 +00:00
steve 100bdedac3 input file for memory test. 2001-05-09 02:48:53 +00:00
steve 914ad85e63 Add ivl and vvp.tgt support for memories in
expressions and l-values. (Stephan Boettcher)
2001-05-08 23:59:33 +00:00
steve b3c2ad0a65 preliminary resolver documentation. 2001-05-08 23:58:43 +00:00
steve 2e12635494 Add to the debugger the ability to view and
break on functors.

 Add strengths to functors at compile time,
 and Make functors pass their strengths as they
 propagate their output.
2001-05-08 23:32:26 +00:00
steve 4325b787c0 more missing API symbols. 2001-05-08 04:13:51 +00:00
steve 4e3c702cc7 sort enumeration values. 2001-05-08 04:13:12 +00:00
steve 213cb1b08a Behavioral code to read memories. (Stephan Boettcher) 2001-05-06 17:54:33 +00:00
steve b7569f4d70 Support memory objects. (Stephan Boettcher) 2001-05-06 17:48:20 +00:00
steve e328cf9fed Add the %ix/get instruction. (Stephan Boettcher) 2001-05-06 17:42:22 +00:00
steve 78af3dbdc0 Regularize the mode-42 functor handling. 2001-05-06 03:51:37 +00:00
steve 372674b4c0 Add the memory.vvp example. 2001-05-06 03:50:26 +00:00
steve 8d0f7e1594 Propagate non-x constant net values. 2001-05-06 00:18:13 +00:00
steve 558fea33fb Generate code that causes the value of a net to be passed
passed through all nets of a nexus.
2001-05-06 00:01:02 +00:00
steve de5930f7d8 Add the beginnings of an interactive debugger. 2001-05-05 23:55:46 +00:00
steve e09a14aa44 Forward the simulation time for every event. 2001-05-05 23:51:49 +00:00
steve d45c7c58df Generate code for the fully general event or. 2001-05-03 04:55:46 +00:00
steve b5e0f46229 Generate null statements for conditional labels. 2001-05-03 04:55:28 +00:00
steve 12229e4826 Fix handling of a mode 1 functor that feeds into a
mode 2 functor. Feed the result only if the event
 is triggered, and do pass to the output even if no
 threads are waiting.
2001-05-03 04:54:33 +00:00
steve 8f88525819 dll build of many probes forgot to index the probe. 2001-05-03 01:52:45 +00:00
steve a225fe304d Document memory related opcodes,
parser uses numbv_s structures instead of the
 symbv_s and a mess of unions,
 Add the %is/sub instruction.
       (Stephan Boettcher)
2001-05-02 23:16:50 +00:00
steve 0f9eb13245 Remove the init parameter of functors, and instead use
the special C<?> symbols to initialize inputs. This is
 clearer and more regular.
2001-05-02 04:05:16 +00:00
steve 06437b7fba Support behavioral subtraction. 2001-05-02 01:57:25 +00:00
steve ba910c0fac Describe a generic event a bit. 2001-05-02 01:38:13 +00:00
steve 28278d3c09 initialize is_schedule. 2001-05-02 01:37:38 +00:00
steve 2bf7653ab9 Implement %ix/load. 2001-05-01 05:00:02 +00:00
steve cb39b3b65c Account for ipoint_input_index behavior in inputs_connect. 2001-05-01 02:18:15 +00:00
steve 3e3757bde7 Comparisons cant leave their results in the opcode
result area or their values will be clobbered by other
 parts of a complex expression.
2001-05-01 02:07:34 +00:00
steve 8b4befd4fc Add support for memory objects. (Stephan Boettcher) 2001-05-01 01:09:39 +00:00
steve 972e9c866b OR is %or. Get this right. 2001-04-30 05:11:18 +00:00
steve f758010f01 Describe constant functor inputs in the symbol section. 2001-04-30 04:51:27 +00:00
steve 8057faccc1 Fix up functor inputs to support C<?> values. 2001-04-30 03:53:19 +00:00
steve 3f952a2fd2 detect multiple drivers on nexa. 2001-04-30 00:00:27 +00:00
steve eb71c70c99 Carry drive strengths in the ivl_nexus_ptr_t, and
handle constant devices in targets.'
2001-04-29 23:17:38 +00:00
steve 2a44cf70b1 Add bufif and pull devices. 2001-04-29 23:16:31 +00:00
steve 431b16639d Add bufif0 and bufif1 functors. 2001-04-29 23:13:33 +00:00
steve 014e68b62f Support .net constant inputs. 2001-04-29 22:59:46 +00:00
steve 31291f5d8a Evalulate logical or (||) 2001-04-29 20:47:39 +00:00
steve a52b34cb64 Add pullup and pulldown devices. 2001-04-29 20:19:10 +00:00
steve 3ca55bf327 Better handling of module item errors. 2001-04-29 20:18:34 +00:00
steve 9bb2cee686 UDP instances need not have user supplied names. 2001-04-28 23:18:08 +00:00
steve 4f3bdd9f38 Accept single strengths for pullup and pulldown. 2001-04-28 22:56:15 +00:00
steve efe41c2435 input connect cleanup. (Stephan Boettcher) 2001-04-28 20:24:03 +00:00
steve f855cb19b8 Excessive header include. 2001-04-28 20:09:05 +00:00
steve 861ed55879 Support marking vvp interpreter (Stephan Boettcher) 2001-04-28 20:06:07 +00:00
steve 35e0dcdd3d More robust parsing of compiler directives. 2001-04-28 18:43:18 +00:00
steve a72a8607e6 New exported symbols for ivl_target API. 2001-04-26 23:33:48 +00:00
steve 904747acf5 Link time references fixed. 2001-04-26 23:32:31 +00:00
steve 4d40a336c0 Look for the strip tool 2001-04-26 23:32:02 +00:00
steve 32e9c8049a Spurious declaration 2001-04-26 16:12:48 +00:00
steve bb24624979 Assure gperf is present. 2001-04-26 16:12:29 +00:00
steve 506bc87e82 Handle missing or uninstalled .conf files. 2001-04-26 16:04:39 +00:00
steve 986885bd70 Add the mode-42 functor concept to UDPs. 2001-04-26 15:52:22 +00:00
steve 73c4893ef7 Implement simple MUXZ for ?: operators. 2001-04-26 05:12:02 +00:00
steve 62c9f39297 Redo and simplify UDP behavior. 2001-04-26 03:10:55 +00:00
steve 8b5f62a5e5 Support $deposit to a wire or reg. 2001-04-26 00:01:33 +00:00
steve aec5841c7f Implement vpi_put_value for signals. 2001-04-25 04:45:52 +00:00
steve c997c090a1 Document the UDP implementation. 2001-04-25 04:35:05 +00:00
steve 0ab60cd3c3 Fix setting StX in vpip_bits_set_value. 2001-04-24 15:47:37 +00:00
steve ae23a8f6bf Fix underflow when UDP has 1 input. 2001-04-24 03:48:53 +00:00
steve 46e868d313 Fix generation of udp/comb definitions. 2001-04-24 02:59:52 +00:00
steve 8dfa322b8b Support for UDP devices in VVP (Stephen Boettcher) 2001-04-24 02:23:58 +00:00
steve 2f2f08b02f Missing symbols. 2001-04-23 00:42:37 +00:00
steve 102fd24dd2 Support unconnected .net objects. 2001-04-23 00:37:58 +00:00
steve 66cf3ec8fa More UDP consolidation from Stephan Boettcher. 2001-04-22 23:09:45 +00:00
steve 57b0d9691e Right shift by constant. 2001-04-21 03:26:23 +00:00
steve 7c6f496765 Add NAND and XNOR functors. 2001-04-21 02:04:01 +00:00
steve 67e72ce77e Left shift by a constant amount. 2001-04-21 01:49:17 +00:00
steve c97692d715 Generate code for disable. 2001-04-21 00:55:46 +00:00
steve 66f83f3b08 Working %disable and reap handling references from scheduler. 2001-04-21 00:34:39 +00:00
steve 3765bdd3ac Spurious assert of empty statemnt. 2001-04-19 03:04:47 +00:00
steve 39bcdfb7b4 Use the new %fork syntax. 2001-04-18 05:12:03 +00:00
steve 57cd770650 %end complete the %join for the parent. 2001-04-18 05:04:19 +00:00
steve 3194b0c53a Resolve forward references for %fork. 2001-04-18 05:03:49 +00:00
steve 9e8005f7b7 Put threads into scopes. 2001-04-18 04:21:23 +00:00
steve 41ce198a1f add XOR support. 2001-04-15 16:37:48 +00:00
steve 05e30ed43b Add support for behavioral xnor. 2001-04-15 04:07:56 +00:00
steve 09cd582cc5 Oops, excessive test assert neets to be removed. 2001-04-15 03:19:44 +00:00
steve 235781ce08 Handle noop as case statements. 2001-04-15 03:14:31 +00:00
steve 70aeb980d8 vvp support for <= with internal delay. 2001-04-15 02:58:11 +00:00
steve d0d6189874 Less picky about ternary operands. 2001-04-14 22:50:39 +00:00
steve 8205d0fcc9 Use event/or for wide anyedge statements. 2001-04-14 05:11:49 +00:00
steve 60d068a33e support the .event/or statement. 2001-04-14 05:10:56 +00:00
steve e1a4b457c2 Initialize the waiting_for_event member. 2001-04-14 05:10:05 +00:00
steve 86e18226eb More complete reap of all threads. 2001-04-13 03:55:18 +00:00
steve 7fa2975c24 Add new symbols for windows. 2001-04-10 17:21:21 +00:00
steve d39190243b Add the disable statemnent. 2001-04-07 19:24:36 +00:00
steve 0550287658 Generate vvp code for functions with ports. 2001-04-06 02:28:02 +00:00
steve 82947a9343 Generate vvp code for the repeat statement. 2001-04-05 03:20:57 +00:00
steve b7fb806611 Generate signed .net and .var statements. 2001-04-05 01:38:24 +00:00
steve 6a236061de Add the .var/s and .net/s statements for VPI support. 2001-04-05 01:34:26 +00:00
steve 898639d7bf Get signed compares working correctly in vvp. 2001-04-05 01:12:27 +00:00
steve 6322400b83 support decimal strings from signals. 2001-04-04 17:43:19 +00:00
steve 9b7341889d Get intval from a binary constant. 2001-04-04 05:07:19 +00:00
steve 0653f859bc Support forever loops in the tgt-vvp target. 2001-04-04 04:50:35 +00:00
steve 48ff66cbce Take vector form as parameters to vpi_call. 2001-04-04 04:33:08 +00:00
steve 1b2a6f8bed Fix broken look scanning down bits of number. 2001-04-04 04:28:41 +00:00
steve c6cf665c4a emit vpi parameters values as vectors. 2001-04-04 04:14:09 +00:00
steve 19c84ff9a2 Support non-blocking assignments. 2001-04-03 04:50:37 +00:00
steve 15398a8f58 VPI access time as a decimal string, and
stub vpi access to the scopes.
2001-04-03 03:46:14 +00:00
steve 9d2e22576e support functor_set push for blocking assignment. 2001-04-03 03:18:34 +00:00
steve 3ffb3c7011 thread bit allocation leak in assign. 2001-04-02 04:09:20 +00:00
steve cac4c8d5ce Evaluate binary & and | operators. 2001-04-02 03:47:49 +00:00
steve f40d006c26 Generate code for task calls. 2001-04-02 02:28:12 +00:00
steve e6c36597eb Support the scope expression node. 2001-04-02 00:28:35 +00:00
steve 141808b787 Scopes and numbers as vpi_call parameters. 2001-04-02 00:27:53 +00:00
steve 003f103408 Take numbers as system task parameters. 2001-04-02 00:24:30 +00:00
steve ce66498c88 Unary ! is a reduction operator. 2001-04-01 22:26:21 +00:00
steve bf30a0bc07 Add the reduction nor instruction. 2001-04-01 22:25:33 +00:00
steve f8e6d782e1 Implement the unary ! operator. 2001-04-01 21:47:29 +00:00
steve 7a8135c703 Recognize the BUF device. 2001-04-01 21:34:48 +00:00
steve 311e1ce9ee Add the buf functor type. 2001-04-01 21:31:46 +00:00
steve 9bce21ddb7 Generate code for < and <=. 2001-04-01 07:22:42 +00:00
steve c4e438d4ba Implement the less-then and %or instructions. 2001-04-01 07:22:08 +00:00
steve a2da2d59df support the NetWhile statement. 2001-04-01 06:52:27 +00:00
steve 56a4236576 Evaluate the logical AND operator. 2001-04-01 06:49:32 +00:00
steve 2443c655f2 Generate code for while statements. 2001-04-01 06:49:04 +00:00
steve ae1d5227de Support empty statements for hanging labels. 2001-04-01 06:40:44 +00:00
steve 5769bbe15e Add the bitwise %and instruction. 2001-04-01 06:12:13 +00:00
steve 6dbf7333c8 dead cruft. 2001-04-01 04:38:17 +00:00
steve 4352ce6753 Generate code for casex and casez 2001-04-01 04:34:59 +00:00
steve 29a50a52ca Implement %cmp/x and %cmp/z instructions. 2001-04-01 04:34:28 +00:00
steve d25690cc8e Redesign event information to support arbitrary edge combining. 2001-04-01 01:48:21 +00:00
steve e29ecdc234 Fix compilation warnings. 2001-03-31 19:29:23 +00:00
steve 0f6eea7024 Handle $time as system task parameter. 2001-03-31 19:08:22 +00:00
steve 97dd559fca Clear results of condition expressions. 2001-03-31 19:02:13 +00:00
steve a4c722b195 Add VPI support for the simulation time. 2001-03-31 19:00:43 +00:00
steve b3a3b888d8 Generate vvp code for case statements. 2001-03-31 17:36:38 +00:00
steve 2f1d258acb Add the jmp/1 instruction. 2001-03-31 17:36:02 +00:00
steve 7aa9bc9892 Generate code for + and concat expressions. 2001-03-31 02:00:44 +00:00
steve 4a058632b2 Add the ADD instrunction. 2001-03-31 01:59:58 +00:00
steve 6a72b4c10e Make empty event sub-expression a noop. 2001-03-30 23:24:02 +00:00
steve 00d44222dd Initialize the event_ list of new scopes. 2001-03-30 06:10:15 +00:00
steve b36b6d0ca0 Generate code for fork/join statements. 2001-03-30 05:49:52 +00:00
steve 386958f9a0 Add fork and join instructions. 2001-03-30 04:55:22 +00:00
steve f6eb581aff Handle truncation/padding of numbers. 2001-03-29 05:16:25 +00:00
steve 966f7a4bff Behavioral trigger statements. 2001-03-29 03:47:38 +00:00
steve 2cb76cabef events can take up to 4 inputs. 2001-03-29 03:47:13 +00:00
steve 609d5fe727 Support named events as mode 2 functors. 2001-03-29 03:46:36 +00:00
steve 522d0ec864 Add unary ~ operator to tgt-vvp. 2001-03-29 02:52:39 +00:00
steve ad8565f8a6 Add const probe method to NetEvent. 2001-03-29 02:52:01 +00:00
steve b0c003dc34 include string.h for strcmp et al. 2001-03-28 17:24:32 +00:00
steve a4e528f0c3 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.
2001-03-28 06:07:39 +00:00
steve c8d9ade58c Evaluate === and !== 2001-03-27 06:43:27 +00:00
steve 61e3eed49c Generate code for simple @ statements. 2001-03-27 06:27:40 +00:00
steve afb8e285db Support error code from target_t::end_design method. 2001-03-27 03:31:06 +00:00
steve 79ce94b585 Add the .event statement and the %wait instruction. 2001-03-26 04:00:39 +00:00
steve f7f5ccce05 Add vpiOctStrVal access to signals. 2001-03-25 20:45:09 +00:00
steve 25d25ff7fe Support NOR and NOT gates. 2001-03-25 19:38:23 +00:00
steve 31b0037299 Support making hex strings. 2001-03-25 19:38:05 +00:00
steve 16f514739f Calculate NOR and NOT tables, and also the hex_digits table. 2001-03-25 19:37:26 +00:00
steve 604ce0db09 Accept <> characters in labels and symbols. 2001-03-25 19:36:45 +00:00
steve a71dbd3987 Draw AND NOR and NOT gates. 2001-03-25 19:36:12 +00:00
steve 417186b06f Add a README for notes about the vvp target. 2001-03-25 18:10:39 +00:00
steve ac91dc38b8 Recursive make check target. 2001-03-25 05:59:46 +00:00
steve 6d0be3de3a vpip.def needed by vpip, not vvm. 2001-03-25 04:48:04 +00:00
steve 2d4f33a0dd Use the correct paths for vpip in make check. 2001-03-25 04:47:47 +00:00
steve c6088c8820 Add JMP0XZ and postpone net inputs when needed. 2001-03-25 03:54:26 +00:00
steve 5134636932 Include signal bit index in functor input. 2001-03-25 03:53:40 +00:00
steve 5d051ffbde Skip true clause if condition ix 0, x or z 2001-03-25 03:53:24 +00:00
steve 97985bba64 Generate .net statements, and nexus inputs. 2001-03-25 03:25:43 +00:00
steve 9ec5fa972e Draw signal inputs to system tasks. 2001-03-25 03:24:10 +00:00
steve 9e04ef4abd Add the .net statement. 2001-03-25 00:35:35 +00:00
steve 68dc83b322 Use the :vpi_module directive. 2001-03-25 00:34:40 +00:00
steve 97e9b62080 Describe the .net directive. 2001-03-24 22:59:28 +00:00
steve 4072021ba4 Install vvp and vvp.tgt. 2001-03-24 22:58:56 +00:00
steve c901945871 eq is x if either value of cmp/u has x or z. 2001-03-23 04:56:03 +00:00
steve 95281e5d82 Generate :module statements. 2001-03-23 02:41:04 +00:00
steve 2858c2f09b Add the :module header statement. 2001-03-23 02:40:22 +00:00
steve 034cdae445 assignments with non-trival r-values. 2001-03-23 01:54:32 +00:00
steve e71ea8c9de Support set of functors from thread bits. 2001-03-23 01:53:46 +00:00
steve b2a136e07e Handle vectors pulled out of a constant bit. 2001-03-23 01:11:06 +00:00
steve c2dc3fe5c3 Assure that operands are the correct width. 2001-03-23 01:10:24 +00:00
steve 548ff4f89a Detect undefined system tasks at compile time. 2001-03-22 22:38:13 +00:00
steve b3c24adb11 install vvp. 2001-03-22 22:37:36 +00:00
steve e81d0d9f23 Compile in a default VPI module dir. 2001-03-22 21:26:53 +00:00
steve 715d140d85 Test print that interferes with output. 2001-03-22 05:39:34 +00:00
steve fa46de1021 Add code label forward references. 2001-03-22 05:28:41 +00:00
steve aa31884d3b no longer need out message. 2001-03-22 05:28:16 +00:00
steve aacce5ef1b implement %load, %inv, %jum/0 and %cmp/u 2001-03-22 05:08:00 +00:00
steve 565088160e Geneate code for conditional statements. 2001-03-22 05:06:21 +00:00
steve b24011b84b fgetc patch from Peter Monta. 2001-03-22 02:23:17 +00:00
steve 2b8d9abd3e Allow var objects as vpiHandle arguments to %vpi_call. 2001-03-21 05:13:03 +00:00
steve e24facfaf6 Describe the compilation major steps. 2001-03-21 05:12:15 +00:00
steve 27e717839a Scan the scopes of a design, and draw behavioral
blocking  assignments of constants to vectors.
2001-03-21 01:49:43 +00:00
steve 52c7108782 Add support for variable vectors. 2001-03-20 06:16:23 +00:00
steve 90ed3dd124 Copyright notices. 2001-03-20 02:48:40 +00:00
steve 8118203766 Lexical numbers may be signed. 2001-03-20 02:45:25 +00:00
steve e8518c5056 Put processes in the proper scope. 2001-03-20 01:44:13 +00:00
steve f02d4574f9 Get vpi_user from .., not ../vpip. 2001-03-20 01:43:16 +00:00
steve f1ff1149f7 vpi_user.h is in .., and not ./vpi. 2001-03-20 00:29:10 +00:00
steve 034a38ea36 Fix inclule paths to find files in srcdir. 2001-03-19 04:37:59 +00:00
steve f8c3b84f68 Add support for the vpiReset sim control. 2001-03-19 01:55:38 +00:00
steve d8ef63efd1 Pass -o value to vvp target. 2001-03-19 01:29:13 +00:00
steve a240be73e7 vpi_user header file is a root header. 2001-03-19 01:21:45 +00:00
steve 1563643c92 Add the tgt-vvp code generator target. 2001-03-19 01:20:46 +00:00
steve 5b89249f10 Add the hello example program. 2001-03-18 04:37:35 +00:00
steve bf70673380 Accept empty statements. 2001-03-18 04:37:16 +00:00
steve 6779f01f3a Add support for string constants to VPI. 2001-03-18 04:35:18 +00:00
steve 66f7ef97da Add support for vpi scopes. 2001-03-18 00:37:55 +00:00
steve e03859b834 $display can take 0 arguments. 2001-03-18 00:31:32 +00:00
steve f2c1902984 Add structures for VPI support, and all the %vpi_call
instruction. Get linking of VPI modules to work.
2001-03-16 01:44:34 +00:00
steve 32f3881344 Rearrange VPI support libraries. 2001-03-14 19:27:44 +00:00
steve 264e629c74 VPI support documentation. 2001-03-14 19:26:58 +00:00
steve 8969ab03d7 Thread details 2001-03-14 19:26:40 +00:00
steve 952ebe8516 Copyright notice. 2001-03-14 19:26:15 +00:00
steve f355cf334c Stub install and unistall targets. 2001-03-14 19:26:01 +00:00
steve 01c5321208 Add chapter on threads vs functors vs events. 2001-03-13 00:49:50 +00:00
steve 970ba895c9 Compact the vvp_code_s structure. 2001-03-11 23:06:49 +00:00
steve cbc3be0304 Functor values and propagation. 2001-03-11 22:42:11 +00:00
steve cb65ee5e00 Add the vvp engine to cvs. 2001-03-11 00:29:38 +00:00
steve debe707097 check signals in the cprop functor. 2001-02-18 01:07:32 +00:00
steve 79b60da54c I allow function ports to have types. 2001-02-17 05:27:31 +00:00
steve 84c7795d16 Allow task ports to be given real types. 2001-02-17 05:15:33 +00:00
steve 410a93b52c Cannot elide task ports. 2001-02-17 05:14:35 +00:00
steve 78355b6038 Check that the port really exists here. 2001-02-17 05:13:36 +00:00
steve 59b69c6dd1 Constant propagation for compare ==. 2001-02-16 03:27:31 +00:00
steve d3bff8a451 links to root inputs are not constant. 2001-02-16 03:27:07 +00:00
steve 43ddd97426 Missing . in names generated from scope locals. 2001-02-16 03:25:09 +00:00
steve 4399042b8d Use Mersenne Twister 19937 pseudo-random number generator
for the $random system task, and support the seed paramter.
2001-02-16 00:26:38 +00:00
steve 2b0aaec8ab FreeBSD port has a maintainer now. 2001-02-15 06:59:35 +00:00
steve 7d7ccd4f08 Generate proper code for wide condition expressions. 2001-02-13 04:11:24 +00:00
steve 93463b6ff5 Binary or and nor resilient to bit widths. 2001-02-13 03:38:55 +00:00
steve 4b0c56c3a8 Rant about bit widths. 2001-02-12 16:48:04 +00:00
steve 1bae567728 Add the netmisc.cc source file. 2001-02-11 02:15:52 +00:00
steve 7d7beeecc1 Binary operators with operands of indefinite width
has itself an indefinite width.
2001-02-10 21:20:38 +00:00
steve f5d0211864 In the context of range declarations, use elab_and_eval instead
of the less robust eval_const methods.
2001-02-10 20:29:39 +00:00
steve 1f4232187c Slightly more specific error message. 2001-02-10 19:50:33 +00:00
steve f45ba008d8 Catch constants driving root module ports. (PR#130) 2001-02-10 04:50:54 +00:00
steve ac629b313c Report errors when XNF code has constant X values. (PR#128) 2001-02-10 03:22:49 +00:00
steve 563065053e Make the add func resilient to bit widths (PR#141) 2001-02-10 01:57:18 +00:00
steve 2b903f5d0e Detect part select out of range in nets. (PR#138) 2001-02-09 20:18:15 +00:00
steve 7ef3b44ab1 support evaluation of constant < in expressions. 2001-02-09 05:44:23 +00:00
steve 8376553349 Report bit/part select out of range errors. (PR#133) 2001-02-09 03:16:48 +00:00
steve 3885f17d0f Be more clear about scope of failure. 2001-02-09 02:49:59 +00:00
steve 4b0e5bd173 trim the length of unsized numbers. 2001-02-08 05:38:18 +00:00
steve d78c7392c2 Remove dead code. 2001-02-08 01:10:30 +00:00
steve cf3f1b38c3 ivl_target header search path fixes. 2001-02-07 22:21:59 +00:00
steve 2fbc0af1ea Fix expression widths for rvalues and parameters (PR#131,132) 2001-02-07 21:47:13 +00:00
steve 94a1d59817 Support constant evaluation of / and % (PR#124) 2001-02-07 02:46:31 +00:00
steve 57d1bfaf29 Add 0? and 1? patterns to UDP syntax. (PR#137) 2001-02-07 01:08:21 +00:00
steve d6701803d1 Latest rpm compresses man pages. Fine, I can cope. 2001-02-04 01:00:51 +00:00
steve 9e624ac833 Update to 0.4 release. 2001-02-04 00:03:57 +00:00
steve 0175c727ee The -f flag is obsolete. 2001-02-01 17:12:44 +00:00
steve 90250baf0f Forgot to actually allow the -p flag. 2001-02-01 17:12:22 +00:00
steve cc22ae833a support leading _ in names. 2001-01-29 22:48:10 +00:00
steve 6c4b5cf2c2 Fix sign extension of evaluated constants. (PR#91) 2001-01-27 05:41:48 +00:00
steve 88a2ca2168 Handle wide net constants with unary minus. 2001-01-25 02:05:16 +00:00
steve 41242735ed Handle some special cases of unary 2's complement,
and improve netlist expression width handling.
2001-01-24 02:52:30 +00:00
steve ab11943496 Fix hand bad karma btw AC_LANG_CPLUSPLUS and AC_EXEEXT 2001-01-23 19:52:03 +00:00
steve d9f0065f93 Forgot to actually *open* the VCD output. 2001-01-23 18:50:26 +00:00
steve 53dfdacce8 Support default dumpfiles. 2001-01-22 20:58:31 +00:00
steve 4e44515078 Switch hte -f flag to the -p flag. 2001-01-20 19:02:04 +00:00
steve 2b11f78d63 Catch malformed include directives (PR#100) 2001-01-20 03:10:35 +00:00
steve a4de0af79d apologize for not supporting non-constant delays. 2001-01-20 02:15:50 +00:00
steve 145ac49233 NetMux needs a scope. (PR#115) 2001-01-18 03:16:35 +00:00
steve 6479319fea LDFLAGS when linking pal.tgt. 2001-01-18 03:09:45 +00:00
steve f224ed3a90 Fix out-of-bound pins for comparator (PR#108) 2001-01-16 04:51:52 +00:00
steve 5f292e546d Get rid of gate templates. 2001-01-16 03:57:46 +00:00
steve 65020bc6de Use the iosfwd header if available. 2001-01-16 02:44:17 +00:00
steve 6adb50e860 Add missing NetLogic gate types to ::logic method. 2001-01-15 22:08:32 +00:00
steve 1ea417dc30 Declare ivl_scope_type functions. 2001-01-15 22:05:14 +00:00
steve a00924089d Pass scope type information to the target module. 2001-01-15 00:47:01 +00:00
steve 66716f5101 Add client data pointer for scope and process scanners. 2001-01-15 00:05:39 +00:00
steve 219df169a3 Generalize the evaluation of floating point delays, and
get it working with delay assignment statements.

 Allow parameters to be referenced by hierarchical name.
2001-01-14 23:04:55 +00:00
steve b712c3f5ca possible HP/UX portability support. 2001-01-14 17:12:59 +00:00
steve 02fc59fbdf Parse parameters within nested scopes. 2001-01-13 22:20:08 +00:00
steve 4e7a5d55d0 Handle error idents in constants not in any scope (PR#97) 2001-01-12 04:31:27 +00:00
steve 5fb7f9ca91 Generated function prototype. (PR#107) 2001-01-12 04:20:18 +00:00
steve 246f2d5884 Match memories within task scopes. (PR#101) 2001-01-10 05:32:44 +00:00
steve 5276752276 Build task outputs as lval instead of nets. (PR#98) 2001-01-10 03:13:23 +00:00
steve 6bf599e839 Cope with width mismatches to module ports (PR#89) 2001-01-09 05:58:47 +00:00
steve fff32b1b54 Clean up the jedec header that is written. 2001-01-09 04:41:32 +00:00
steve a64a4d7a9b Fixes to support compilation using vpath. 2001-01-09 03:11:27 +00:00
steve 9eb6f9dbb9 Generate the jedec to configure the macrocells. 2001-01-09 03:10:48 +00:00
steve 430e46d718 Assert on length of bit vector. 2001-01-07 18:22:15 +00:00
steve cd9a30707b Detect port direction attached to non-ports. 2001-01-07 07:00:31 +00:00
steve ad0853d666 Support signed decimal display of variables. 2001-01-06 22:22:17 +00:00
steve cc18d065aa declaration initialization for time variables. 2001-01-06 06:31:58 +00:00
steve 14c67a5389 James has moved. 2001-01-06 04:32:56 +00:00
steve 68e672e61a Support arrays of integers. 2001-01-06 02:29:35 +00:00
steve 2703456ad4 Document the -c flag. 2001-01-05 05:16:03 +00:00
steve 8ee00ec562 Fix net division to cope with small output sizes. 2001-01-05 03:19:47 +00:00
steve 8bfae1e641 Evaluate constant === and !== expressions. 2001-01-04 16:49:50 +00:00
steve 8befc6f7c4 Add support for << is signal indices. 2001-01-04 04:47:51 +00:00
steve d5ec89813d Evaluate constant logical && and ||. 2001-01-04 04:28:42 +00:00
steve ac7ae1ba6f Resolve repeat ambiguity in favor of loop. 2001-01-02 17:28:08 +00:00
steve 120a211e68 Support a bunch of unary operators in parameter expressions. 2001-01-02 04:21:13 +00:00
steve b6a18098c7 Evaluate constant &, | and unary ~. 2001-01-02 03:23:40 +00:00
steve 112936d661 Fix shift and ternary operators in parameter expressions (PR#86) 2001-01-01 21:49:33 +00:00
steve 4d09c43ecf Add $stop that does a finish. 2001-01-01 19:33:44 +00:00
steve 2a6f8634f6 repeat loops ambiguity. 2001-01-01 19:12:35 +00:00
steve 5803e8c42c Handle function scopes in dumpvars scn (PR#95) 2001-01-01 08:10:35 +00:00
steve eda3c63f72 reg_assign into function ports. (PR#95) 2001-01-01 01:41:09 +00:00
steve 365b149ec1 Propagate initial value of constants into wires. 2000-12-30 03:11:15 +00:00
steve e68c26bb87 Generate smaller code for reg assigns. 2000-12-17 05:33:11 +00:00
steve 4e7f8766fa Generate loops to initialize vectors or constants. 2000-12-16 23:55:24 +00:00
steve fe209a6996 Handle non-constant l-values. 2000-12-16 20:00:17 +00:00
steve f4671a3082 Evaluate <= and ?: in parameter expressions (PR#81) 2000-12-16 19:03:30 +00:00
steve c9881c115a Spelling error. 2000-12-16 17:16:08 +00:00
steve 0a3bda87d6 Observe delays in non-blocking assignments (PR#83) 2000-12-16 16:57:43 +00:00
steve 8ae4e25720 Detect recursive instantiations (PR#2) 2000-12-16 01:45:47 +00:00
steve 44131d4b16 Allow non-blocking assign to pad memory word with zeros. 2000-12-15 21:54:43 +00:00
steve d5eb3a2bad concatenation as parameter to system tasks. PR#64) 2000-12-15 21:40:26 +00:00
steve 086348035e Fix memory access in vvm. (PR#70) 2000-12-15 20:05:16 +00:00
steve 05b5b91a84 A dlerror implementatin that HP/UX might like. 2000-12-15 18:06:47 +00:00
steve bcbd5b2c5c Remove limits from the similar events search. 2000-12-15 17:45:07 +00:00
steve 8c680d158a Autoconfigure the dlopen functions. 2000-12-15 05:45:25 +00:00
steve 8fe6324aec functions with system tasks (PR#46) 2000-12-15 03:06:04 +00:00
steve 15a426cc73 remove dead macro. 2000-12-15 02:00:31 +00:00
steve 770dfe5eaa Trim dr from the string line. 2000-12-15 02:00:11 +00:00
steve 5144725b8f Accept x in outputs of primitive. (PR#84) 2000-12-15 01:24:17 +00:00
steve 189f55b894 rounding of time and x in primitives. 2000-12-15 00:21:46 +00:00
steve e836bc951d Detect -mdll support in Cygwin. 2000-12-14 23:38:04 +00:00
steve f0718b1345 Start support for fitting the logic. 2000-12-14 23:37:47 +00:00
steve 9cb91ce9aa Eat carriage returns. 2000-12-14 23:36:59 +00:00
steve 4abf4b0a9a include vpi_user.h. 2000-12-14 23:36:34 +00:00
steve 7d622fc6ab Support more logic gate types. 2000-12-14 23:23:07 +00:00
steve 3e73ec3e0f sorry for concatenated memories in l-values. (PR#76) 2000-12-12 06:14:51 +00:00
steve 36a1b37789 Fix truncated octal constants (PR#76) 2000-12-12 06:13:44 +00:00
steve e34ef2a2b9 NetEUFuncs are allowed as system task parameters. 2000-12-12 03:30:44 +00:00
steve fd0f618529 out-line vvm_bitset_t methods. 2000-12-12 03:30:25 +00:00
steve a010dd1cc0 Mangle [] characters. (PR#67) 2000-12-11 01:06:24 +00:00
steve 5dbea64759 Add support for signed reg variables,
simulate in t-vvm signed comparisons.
2000-12-11 00:31:43 +00:00
steve 084a464cf1 Support decimal constants in behavioral delays. 2000-12-10 22:01:35 +00:00
steve c0f951c146 vpiStringVal handles leding nulls as blanks. (PR#62) 2000-12-10 19:15:19 +00:00
steve 9ddd0491f7 Support delays on continuous assignment from idents. (PR#40) 2000-12-10 06:41:59 +00:00
steve 245472ca63 unary expressions as parameters (PR#42, PR#68) 2000-12-09 06:17:20 +00:00
steve 371f43e227 documentation... 2000-12-09 05:40:42 +00:00
steve 9fe0d9b120 Add the -tpal target to use the pal.tgt module. 2000-12-09 05:40:09 +00:00
steve 16c50ad810 Stuff registers into macrocells. 2000-12-09 03:42:52 +00:00
steve a4da2c7ed5 The ipal library is called ipal. 2000-12-09 01:19:58 +00:00
steve 40da501cec Add the pal loadable target. 2000-12-09 01:17:38 +00:00
steve f6507cba43 Check lvalue of procedural continuous assign (PR#29) 2000-12-06 06:31:09 +00:00
steve e027247a0e fix portfaults pass values. 2000-12-06 05:15:21 +00:00
steve 789e862ca4 parse real and realtime declarations. 2000-12-05 22:32:05 +00:00
steve a6b83ac5da real and trireg not supported. 2000-12-05 22:31:38 +00:00
steve 3b9a60414e Make signal attributes available to ivl_target API. 2000-12-05 06:29:33 +00:00
steve 4f638882c9 Add Attrib class for holding NetObj attributes. 2000-12-04 17:37:03 +00:00
steve 4faec154f0 Finally remove the verilog.sh script. 2000-12-02 05:57:46 +00:00
steve ff53b60c66 Remove excess *.d dependencies for parse.d 2000-12-02 05:30:08 +00:00
steve a2a40869b0 Spelling error in comment. 2000-12-02 05:08:04 +00:00
steve b714f57797 Catch up to null.tgt and libvpip.a files. 2000-12-02 05:07:14 +00:00
steve d0ec7e2c02 Make the null target into a loadable target. 2000-12-02 04:50:32 +00:00
steve d16d29c591 Support for %s in $display (PR#62) 2000-12-02 02:40:56 +00:00
steve e310532434 Handle null statements inside a wait. (PR#60) 2000-12-01 23:52:49 +00:00
steve 4eed86d519 Detect part select errors on l-values. 2000-12-01 02:55:37 +00:00
steve ef49fc127f Change LineInfo to store const C strings. 2000-11-30 17:31:42 +00:00
steve e6151db172 Add command file (-c) support from Nadim Shaikli. 2000-11-30 02:50:54 +00:00
steve 28af357c8a Clean a bit more completely. 2000-11-29 23:59:29 +00:00
steve a5c69b50e5 Do not delete synthesized signals used in expressions. 2000-11-29 23:16:18 +00:00
steve 02f876ac69 More informative BUFZ warning. 2000-11-29 23:15:54 +00:00
steve ea921efced synthesis for unary reduction ! and N operators. 2000-11-29 05:24:00 +00:00
steve 4bf3e37af3 Add XNF support for NE comparators. 2000-11-29 02:54:49 +00:00
steve 291ab97422 Add support for || synthesis (PR#53) 2000-11-29 02:09:52 +00:00
steve 12db3340cc Typo writing I pins to AND gates in compare. 2000-11-29 01:34:17 +00:00
steve e33fb3ce51 Propagate constants through xnor gates. (PR#51) 2000-11-23 01:55:52 +00:00
steve 92424eea10 synthesize the rvalue of <= statements. 2000-11-22 21:18:42 +00:00
steve 4ca0bffc7f Connect the CE if it is linked at all. 2000-11-22 21:18:20 +00:00
steve c86da66b77 Allow sole module to be a root. 2000-11-22 20:48:32 +00:00
steve f7d62b96aa whoops, wrong copyright notice. 2000-11-21 03:55:20 +00:00
steve 482323843e Whoops, return the calculated constant value rom driven_value. 2000-11-20 01:41:12 +00:00
steve f4443a7dfa Add support for supply nets (PR#17) 2000-11-20 00:58:40 +00:00
steve 1f07ba52b6 Integer parameter comments. 2000-11-19 22:03:04 +00:00
steve ec0d12b738 Killing some signals might make others killable. 2000-11-19 20:48:53 +00:00
steve 457d193238 Fix cases where signal iteration might die early. 2000-11-19 20:48:30 +00:00
steve e05b9a4769 Replace AND constand propagation. 2000-11-19 05:26:58 +00:00
steve 2750977e4a Thorough constant propagation for or and nor gates. 2000-11-18 05:13:27 +00:00
steve ff5846100c Delete unreferenced signals no matter what. 2000-11-18 05:12:45 +00:00
steve da926fa08b Watch out in functor, it may delete the last signal. 2000-11-18 04:53:04 +00:00
steve fc6978e4de Handle constant propagation through XOR gates,
including reducing the gate to a constant,
 a buffer or an inverter if possible.
2000-11-18 04:10:37 +00:00
steve 11e6440162 Fix warning about temporaries. 2000-11-15 20:31:05 +00:00
steve f74368dec2 Missing LPM related symbols in ivl.def. 2000-11-15 20:30:21 +00:00
steve 4b264a4c58 More robust way to cope with parse.cc compilation. 2000-11-15 19:26:35 +00:00
steve 0ca9b2736b flip-flop pins for ivl_target API. 2000-11-12 17:47:29 +00:00
steve 28bc621f11 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
2000-11-11 01:52:09 +00:00
steve 197ed46b26 configure bindir and libdir 2000-11-11 00:48:35 +00:00
steve b05aadfd94 Configure bindir and libdir 2000-11-11 00:38:40 +00:00
steve a8da692540 Add support for the t-dll backend grabing flip-flops. 2000-11-11 00:03:36 +00:00
steve 1d6f48914f Initialize scope when creating it. 2000-11-09 22:19:34 +00:00
steve 1046c86c84 Remember to include the -S condition. 2000-11-09 21:58:00 +00:00
steve 47ce0f3c46 show concatenation operators. 2000-11-09 05:14:07 +00:00
steve 2dd1d070ec Display l-values with width. 2000-11-07 06:14:06 +00:00
steve f4ed0e35af Handle connectsion to internally unconnected modules (PR#38) 2000-11-05 06:05:59 +00:00
steve 61ad0b23c8 Apply sequential UDP rework from Stephan Boettcher (PR#39) 2000-11-04 06:36:24 +00:00
steve 5415dd70c5 Integrate parameter count changes (PR#34) 2000-11-04 05:49:22 +00:00
steve ff514aab72 pad different width inputs to muxes. (PR#14) 2000-11-04 05:06:04 +00:00
steve d7788b88b7 Modifications in support of gcc 2.96 2000-11-04 01:54:01 +00:00
steve a1cfabafb8 Use the %m string properly. 2000-11-04 01:53:24 +00:00
steve 35769ef541 Scope information is needed by all types of display tasks. 2000-11-04 01:52:57 +00:00
steve 80d3342178 VCD scans tasks (PR#35) 2000-11-01 06:05:44 +00:00
steve 4d27b947bc Add the general $time system function. 2000-11-01 03:19:36 +00:00
steve 3591e06c4e Support time variables. 2000-10-31 17:49:02 +00:00
steve 88c8547486 Remove C++ string from variable lists. 2000-10-31 17:00:04 +00:00
steve d92ac5772c Spelling error. 2000-10-31 16:59:45 +00:00
steve f2997d7767 Detect reverse bit order in part select. (PR#33) 2000-10-30 21:35:40 +00:00
steve 7df9943679 get width right for reversed part select net. (PR#33) 2000-10-30 20:55:53 +00:00
steve f3dfff7d76 task threads ned their scope initialized. (PR#32) 2000-10-29 17:10:02 +00:00
steve 23a5bd072d Remove the compiled in Verilog target. 2000-10-28 22:35:58 +00:00
steve d6efae4bdd API for concatenation expressions. 2000-10-28 22:32:34 +00:00
steve 10fbb2a1bb Glitches in cygwin build process. 2000-10-28 19:12:43 +00:00
steve 5b65f15df4 stub for the concat operator. 2000-10-28 17:55:03 +00:00
steve 72229abda6 check explicitly uses local libraries. 2000-10-28 17:51:45 +00:00
steve 427de3ab0b Handle - and _ in target names. 2000-10-28 17:51:01 +00:00
steve 6962841546 Split vpip for everybody. 2000-10-28 17:27:59 +00:00
steve bb414303a0 make check target (PR#3) 2000-10-28 04:16:11 +00:00
steve 431228e881 make check target (PR#3) 2000-10-28 03:58:11 +00:00
steve 07d7008853 Use the conf file to generate the vvm ivl string. 2000-10-28 03:45:47 +00:00
steve 7545db5e26 Use the conf file to generate the vvm ivl string. 2000-10-28 03:45:47 +00:00
steve ad4931e813 Add scope to threads in vvm, pass that scope
to vpi sysTaskFunc objects, and add vpi calls
 to access that information.

 $display displays scope in %m (PR#1)
2000-10-28 00:51:41 +00:00
steve f915efaf15 Fix handling of errors in behavioral lvalues. (PR#28) 2000-10-26 17:09:46 +00:00
steve df660bab0c draw proper signal references for the gates. 2000-10-26 16:42:25 +00:00
steve 26350fdcf5 emit declarations of signals and gates. 2000-10-26 00:32:28 +00:00
steve 0e7ca326ce Put signals into a signal_table 2000-10-26 00:29:10 +00:00
steve 88b479a82b mangle the backslash to a dollar. 2000-10-25 23:21:37 +00:00
steve e08314eaf5 Scan the processes, and get the target signals 2000-10-25 05:41:55 +00:00
steve b8fe10d27d Get target signal from nexus_ptr. 2000-10-25 05:41:24 +00:00
steve 1cc7b6d4d7 Nexus value is initially unknown so that it propogates for sure. 2000-10-23 00:32:48 +00:00
steve bb9eb2cd1d Fix decimal constant overflow warning (PR#26) 2000-10-22 22:27:59 +00:00
steve add2ae16fa Reduce the target entry points to the target_design. 2000-10-21 16:49:45 +00:00
steve ecf71efc84 Document the -C flag of iverilog. 2000-10-18 21:53:05 +00:00
steve e10679633d Add ivl_lval_t and support for assignment l-values. 2000-10-18 20:04:39 +00:00
steve f5fae7f271 Stubs so that cygwin port will link ivl. 2000-10-16 22:44:54 +00:00
steve 90ae46476c Makefile patches to support target loading under cygwin. 2000-10-15 21:02:08 +00:00
steve 2dedd6c067 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.
2000-10-15 04:46:23 +00:00
steve 7ee46bc621 More sophisticated number length warning. 2000-10-14 16:48:59 +00:00
steve 368e5b72be bit width warnings from Jim Norris (PR#24) 2000-10-14 04:07:54 +00:00
steve f526d235d1 Check for missing concat subexpressions (PR#11) 2000-10-14 02:23:02 +00:00
steve 06f5482631 Skip the o radix in octal numbers. 2000-10-14 01:31:30 +00:00
steve 52b649cd5e Include constants in nexus targets. 2000-10-13 03:39:27 +00:00
steve 588966320f commentary. 2000-10-13 03:38:48 +00:00
steve 5ce28c193a iverilog with an iverilog.conf configuration file. 2000-10-08 22:36:55 +00:00
steve c9bcda147e Missing stream in call to fprintf. 2000-10-08 05:00:04 +00:00
steve 4819d54d51 Fix repeat concatenation with multiple expressions (PR#10) 2000-10-08 04:59:36 +00:00
steve 8fe887ffe1 Back pointers in the nexus objects into the devices
that point to it.

 Collect threads into a list in the design.
2000-10-08 04:01:54 +00:00
steve 76e2c509d7 Put logic devices into scopes. 2000-10-07 19:45:42 +00:00
steve 6f69773c57 ivl_target updates, including more complete
handling of ivl_nexus_t objects. Much reduced
 dependencies on pointers to netlist objects.
2000-10-06 23:46:50 +00:00
steve 8ba1facb66 Replace data references with function calls. (Venkat) 2000-10-06 23:11:39 +00:00
steve 20d07a7366 Eliminate zero inputs to xor. 2000-10-06 21:26:34 +00:00
steve 02bee9358c sfuncs are char* and are compared with strcmp 2000-10-06 02:21:35 +00:00
steve 41f3ba65a1 xor and constant devices. 2000-10-05 05:03:01 +00:00
steve ce19190eae Overview documentation for loadable targets. 2000-10-04 22:13:51 +00:00
steve d7fcd66826 Overview documentation for loadable targets. 2000-10-04 21:50:55 +00:00
steve 9680de25cd Fix the clean target and excess dependencies. 2000-10-04 17:08:31 +00:00
steve aac5fc246a Use char8 instead of string to store name. 2000-10-04 16:30:39 +00:00
steve 887654b7c5 Use .def file instead of _dllexport. 2000-10-04 02:37:44 +00:00
steve 07aa86f0fa print reg signals. 2000-10-04 02:24:20 +00:00
steve 2f668421a3 Strip the installed .vpi file. 2000-10-04 02:01:40 +00:00
steve bb777f317b Cleanup build of VPI modules under Cygwin. (Venkat) 2000-10-03 16:15:35 +00:00
steve b34a451cbc Cygwin port changes from Venkat 2000-09-30 03:20:47 +00:00
steve c12e0f5416 ivl_expr_t support for binary operators,
Create a proper ivl_scope_t object.
2000-09-30 02:18:15 +00:00
steve 40028f263f Do not put noop statements into blocks. 2000-09-29 22:58:57 +00:00
steve 21e0e8a8a1 Cnstant evaluation of NE. 2000-09-29 04:42:56 +00:00
steve 700bcfda70 handel, by truncation, verinums that are to long for long integers. 2000-09-28 03:55:55 +00:00
steve fff759de20 multiply in parameter expressions. 2000-09-27 18:28:37 +00:00
steve 79b1c51e68 Detect indefinite widths where definite widths are required. 2000-09-26 05:05:58 +00:00
steve 8b581cef46 Remove the obsolete NetEIdent class. 2000-09-26 01:35:42 +00:00
steve d6b43519a8 Add EX_NUMBER and ST_TRIGGER to dll-api. 2000-09-26 00:30:07 +00:00
steve cbe20e8bcf fix null pointer when elaborating undefined task. 2000-09-24 17:41:13 +00:00
steve e8bb53e2ea API access to signal type and port type. 2000-09-24 15:46:00 +00:00
steve 2be1c115ff Move some NetNet method out of the header file. 2000-09-24 15:44:44 +00:00
steve 36cc374ec9 Add support for signal expressions. 2000-09-24 02:21:53 +00:00
steve 043bd2876b Update documentation to use iverilog. 2000-09-23 17:46:11 +00:00
steve 57ced29227 Handle unknowns in decimal strings. 2000-09-23 16:34:47 +00:00
steve 80c69d565b Add enough tgt-verilog code to support hello world. 2000-09-23 05:15:07 +00:00
steve 3a2eff2265 Parse specify delay values. 2000-09-23 03:04:10 +00:00
steve 48ff3590bc Access to the name of a system task call. 2000-09-22 03:58:30 +00:00
steve 9067c91656 Correctly measure comples l-values of assignments. 2000-09-20 02:53:14 +00:00
steve 13c1378666 Remember to make the includedir. 2000-09-20 01:02:13 +00:00
steve 39cf6bd164 Introduce the means to get statement types. 2000-09-19 04:15:27 +00:00
steve ea53f2b54f Typo stepping ot next probe in delete. 2000-09-19 03:00:36 +00:00
steve effc84c46d Get the structure for ivl_statement_t worked out. 2000-09-18 01:24:32 +00:00
steve 89d7176734 Add support for modulus (Eric Aardoom) 2000-09-17 21:26:15 +00:00
steve f8478a4408 More thorough credits section. 2000-09-17 19:06:58 +00:00
steve 8978bbd5e6 full featured l-values for non-blocking assiginment. 2000-09-16 21:28:14 +00:00
steve 063d56ffc1 undefined macros are null (with warnings.) 2000-09-13 22:33:13 +00:00
steve 67472379b4 Error message for invalid variable list. 2000-09-13 16:32:26 +00:00
steve 7e9a7ed0cb Version information for vlog_vpi_info. 2000-09-12 01:17:40 +00:00
steve db1b53c1e7 Oops, the -m flag takes a parameter and needs the : 2000-09-12 01:17:19 +00:00
steve 68c6c48a18 Some error checking. 2000-09-10 15:43:59 +00:00
steve 3c94635f99 Agressively merge NetAssign_ within concatenations. 2000-09-10 03:59:59 +00:00
steve 8a69c54886 elaborate complex l-values 2000-09-10 02:18:16 +00:00
steve b6ce313e91 move lval elaboration to PExpr virtual methods. 2000-09-09 15:21:26 +00:00
steve 3ae76a8638 initialize vlog info. 2000-09-08 17:08:10 +00:00
steve d86b37d90f Support unary + and - in constants. 2000-09-07 22:38:13 +00:00
steve e27934a577 ack, detect when lval fails. 2000-09-07 22:37:48 +00:00
steve ddcba9d91f The + operator now preserves signedness. 2000-09-07 22:37:10 +00:00
steve 44438c9678 more robust abut ternary bit widths. 2000-09-07 21:28:51 +00:00
steve 4cf75adf94 Fix bit padding of assign signal-to-signal 2000-09-07 01:29:44 +00:00
steve 49570b8cd9 encapsulate access to the l-value expected width. 2000-09-07 00:06:53 +00:00
steve 24e46723b0 Change elaborate_lval to return NetAssign_ objects. 2000-09-03 17:58:35 +00:00
steve e95d0c3b87 Properly ignore NetAssign_ objects. 2000-09-03 17:58:14 +00:00
steve ece3f5e0a2 Slightly more helpful warning. 2000-09-03 17:57:53 +00:00
steve 115d24a292 Pull NetAssign_ creation out of constructors. 2000-09-02 23:40:12 +00:00
steve ac81f6a201 Rearrange NetAssign to make NetAssign_ separate. 2000-09-02 20:54:20 +00:00
steve ff32325d07 t-dll iterates signals, and passes them to the
target module.

 Some of NetObj should return char*, not string.
2000-08-27 15:51:50 +00:00
steve eb781a7441 Handle out of range part select expressions. 2000-08-26 01:31:29 +00:00
steve 8876cda37f Get at gate information for ivl_target interface. 2000-08-26 00:54:03 +00:00
steve df113f962b Clean up warnings and portability issues. 2000-08-20 17:49:04 +00:00
steve d0fc6d515d Add ivl_target support for logic gates, and
make the interface more accessible.
2000-08-20 04:13:56 +00:00
steve 3cb666dd2f Add target calls for scope, events and logic. 2000-08-19 18:12:42 +00:00
steve a59bbdeb4f Proper error messages when port direction is missing. 2000-08-18 04:38:57 +00:00
steve 9abd84952b add th t-dll functions for net_const, net_bufz and processes. 2000-08-14 04:39:56 +00:00
steve 3ae4d2cf91 use -fPIC for sparc. 2000-08-12 20:54:33 +00:00
steve 534521f88b Limit signal scope search at module boundaries. 2000-08-12 17:59:48 +00:00
steve 566aad9e15 Start stub for loadable targets. 2000-08-12 16:34:37 +00:00
steve 248baa26e1 Move all file manipulation out of target class. 2000-08-09 03:43:45 +00:00
steve 91a462e38c Add the -N switch to the iverilog command. 2000-08-09 01:34:00 +00:00
steve d58533fd7b target methods need not take a file stream. 2000-08-08 01:50:42 +00:00
steve dab45178a7 Add vpi_vlog_info support from Adrian 2000-08-08 01:47:40 +00:00
steve e01137ced3 cleanup. 2000-08-02 14:48:15 +00:00
steve b5a36fef70 use bufif0 if z is in true case of mux. 2000-08-02 14:48:01 +00:00
steve 2e3e9ecf37 tri01 support in vvm. 2000-08-02 00:57:02 +00:00
steve 60c2046be6 Extend x or z that is top bit of a constant. 2000-08-01 22:44:26 +00:00
steve 1325a3e2b6 Use the iverilog command in documentation. 2000-08-01 21:32:40 +00:00
steve d677f226f3 Support <= in synthesis of DFF and ram devices. 2000-08-01 02:48:41 +00:00
steve eb93e3d2f5 Treat CR as white space in timespec lines. 2000-08-01 02:14:34 +00:00
steve 7cccbda275 Handle different forms of line end. 2000-08-01 01:38:25 +00:00
steve 931ec257f0 Report error when dumpfile is missing. 2000-07-31 03:34:31 +00:00
steve b6562d3ed9 timescale and min:typ:max expressions *do* work onw. 2000-07-30 22:09:09 +00:00
steve 0243fca8dc Rearrange task and function elaboration so that the
NetTaskDef and NetFuncDef functions are created during
 signal enaboration, and carry these objects in the
 NetScope class instead of the extra, useless map in
 the Design class.
2000-07-30 18:25:43 +00:00
steve 30a81731dd Introduce min:typ:max support. 2000-07-29 17:58:20 +00:00
steve 3aa250b16b Report code generation errors through proc_delay. 2000-07-29 16:21:08 +00:00
steve 39c71ef68a fix problem coalescing events w/ probes. 2000-07-29 03:55:38 +00:00
steve 4494a7a4f3 Support elaboration of disable statements. 2000-07-27 05:13:44 +00:00
steve 739365abe5 Parse disable statements to pform. 2000-07-26 05:08:07 +00:00
steve 880b712140 Get VCD timescale from design precision. 2000-07-26 04:07:59 +00:00
steve 08e6bf2e27 Make simulation precision available to VPI. 2000-07-26 03:53:11 +00:00
steve 5f7c298a21 Fix RAM matching. 2000-07-26 03:52:59 +00:00
steve 34399cf297 memory is not a data type in verilog. 2000-07-25 22:49:32 +00:00
steve cb7b1b6c94 Unlink z constants from nets. 2000-07-25 02:55:13 +00:00
steve 53489e6abe Document ieee1364 issues. 2000-07-23 18:06:31 +00:00
steve 4f75d04a42 Document time scale in netlists. 2000-07-23 18:06:15 +00:00
steve 81dab9c572 Excessive assert. 2000-07-23 02:41:32 +00:00
steve 286cef19fb Parse and elaborate timescale to scopes. 2000-07-22 22:09:03 +00:00
steve 741b17245d Handle some edge cases during node scans. 2000-07-16 04:56:07 +00:00
steve 2a08824ae9 Detect muxing Vz as a bufufN. 2000-07-15 05:13:43 +00:00
steve 42e4ff47c8 Move inital value handling from NetNet to Nexus
objects. This allows better propogation of inital
 values.

 Clean up constant propagation  a bit to account
 for regs that are not really values.
2000-07-14 06:12:56 +00:00
steve 8dd2fc7095 More detailed handling of exit status from commands. 2000-07-11 23:30:03 +00:00
steve c07cc005bd proper init method for bufz devices. 2000-07-11 23:08:33 +00:00
steve 79ca317c1d Better handle failures to build lexor_keyword.cc 2000-07-11 23:07:28 +00:00
steve b8946d4cb3 Add the dist_uniform function. 2000-07-08 22:41:07 +00:00
steve 8902645fa7 Allow set vpiIntVal on bitset type objects. 2000-07-08 22:40:07 +00:00
steve 9c12fcffe4 pass zero-delay values immediately. 2000-07-08 22:39:32 +00:00
steve 9b59001cf9 Eleminate reduction gate for 1-bit compares. 2000-07-08 04:59:20 +00:00
steve 18eb34921f Add support for non-constant delays in delay statements,
Support evaluating ! in constant expressions, and
 move some code from netlist.cc to net_proc.cc.
2000-07-07 04:53:53 +00:00
steve cdb3eb7e6b Connect all the l and r bits of a NE expression. 2000-07-06 18:13:24 +00:00
steve e152b91226 unop_not can take out width same as in width. 2000-07-06 18:12:28 +00:00
steve 056a3f7220 Allow unary operators in constant expressions. 2000-06-30 15:50:20 +00:00
steve 888360dd3b Handle errors from parser slightly differently. 2000-06-30 15:49:44 +00:00
steve 337eee7dcb Reduce result is OK in ~ operator. 2000-06-30 15:47:06 +00:00
steve de76c77820 Catch errors from compile that leave the low 8 bits empty. 2000-06-30 04:42:23 +00:00
steve 642e1bccd9 Use nexus type to get nexus name. 2000-06-28 18:38:54 +00:00
steve 1562784a48 Initialize memories as they are create. 2000-06-28 18:38:00 +00:00
steve 042724612e Handle delay_value_lists in simple paths. (Wen-jung Tseng) 2000-06-27 16:00:40 +00:00
steve 62d83e962a properly match unconnected_drive directive. (Wen-jung Tseng) 2000-06-27 04:36:29 +00:00
steve 583868e74e Redesign Links to include the Nexus class that
carries properties of the connected set of links.
2000-06-25 19:59:41 +00:00
steve e52ada617e Get rid of useless next_link method. 2000-06-24 22:55:19 +00:00
steve f3384c7da5 expression scan uses tgt_ to get output files. 2000-06-24 16:40:46 +00:00
steve d94acc1c5c Update to final release. 2000-06-21 19:09:54 +00:00
steve 4febf5801b Handle width expansion of shift operators. 2000-06-18 03:29:52 +00:00
steve e52243a82d Up to rc2 in the file name. 2000-06-18 02:02:26 +00:00
steve db8cc7d98d Detect some hosts that do not support -rdynamic. 2000-06-16 19:00:06 +00:00
steve bec4a205ec Do not install bin/verilog. 2000-06-16 18:59:49 +00:00
steve a2d3a5aab0 Do not include bin/verilog in the product. 2000-06-16 18:59:07 +00:00
steve 9bc3a8f241 Solaris pkg files. 2000-06-16 18:58:45 +00:00
steve 8f64656984 Binary expressions as operands to system tasks. 2000-06-15 04:23:17 +00:00
steve 6f3153d703 Ignore more things in null target. 2000-06-14 20:29:39 +00:00
steve 80878e2e53 Support concatenation in parameter expressions. 2000-06-13 05:22:16 +00:00
steve 66ae567b25 Index in memory assign should be a NetExpr. 2000-06-13 03:24:48 +00:00
steve 413d852012 NetEParam supports dup_expr. 2000-06-12 03:57:10 +00:00
steve 8b03550a1e Fix subract of short value form long one. 2000-06-12 03:56:51 +00:00
steve 6329549938 Prepare for release candidate. 2000-06-10 17:51:40 +00:00
steve 6f9cc57e70 Current reality of what is supported. 2000-06-07 03:53:16 +00:00
steve 3d85c66b02 Do not install obsolete verilog script. 2000-06-07 03:52:55 +00:00
steve fcbbbfe3d6 Expand constants in its special case assignment. (Stephan Boettcher) 2000-06-06 02:32:45 +00:00
steve ea8bc7f419 Interpret the depth paramter of dumpvars. 2000-06-03 02:22:15 +00:00
steve 161fa9c4e7 Do not attach temporaries to scopes. 2000-06-03 02:13:43 +00:00
steve c2b134e7d6 Output signal of + is a temporary. 2000-06-03 02:13:15 +00:00
steve 9c1dc92d74 Parameters can be strings. 2000-06-01 02:31:39 +00:00
steve a674df662f The NetESignal shortcut cannot expand an rvalue. 2000-05-31 03:52:07 +00:00
steve c1c0168893 Globally merge redundant event objects. 2000-05-31 02:26:49 +00:00
steve 9c65596b1a typo: fix vpiReadVal to vpiRealVal 2000-05-31 02:15:43 +00:00
steve 503ed3276f typ vpiRealType. 2000-05-31 01:32:16 +00:00
steve 14d87e3e11 Typo saving third delay value in list. 2000-05-31 01:31:52 +00:00
steve fd09bc3e3e Merge similar probes within a module. 2000-05-27 19:33:23 +00:00
steve e0dcdf6b72 Handle wide conditions in ternary operator. 2000-05-26 05:26:11 +00:00
steve 0c62321402 Emin init code only once per nexus. 2000-05-25 06:02:12 +00:00
steve 1bde1b862d Optimize assignment from signals. 2000-05-25 01:45:35 +00:00
steve 8fc2dc2cd1 Better parsing of expressions lists will empty expressoins. 2000-05-23 16:03:13 +00:00
steve 092b1bded5 Add vpi numbers to the bits table. 2000-05-20 02:48:51 +00:00
steve b93415e8f1 Combine constants into a bit table. 2000-05-20 02:26:23 +00:00
steve 28df01b880 Add the integer modulus function. 2000-05-19 04:22:55 +00:00
steve 2f419f0e08 Catch part select of memories as an error. 2000-05-19 01:55:09 +00:00
steve d9eed14972 Accept different widths for add operands. 2000-05-19 01:43:16 +00:00
steve cc3d4c8231 Ternary operator handles bit sizes. 2000-05-18 20:35:08 +00:00
steve 38b4de87ad Overcautious assert in shift is removed. 2000-05-18 20:23:40 +00:00
steve 0f13af2ea1 Support writing scalars and vectors to signals. 2000-05-18 03:27:32 +00:00
steve a96fa80ccc Add the module option to iverilog. 2000-05-17 03:53:29 +00:00
steve 085c31d671 syn-rules.cc.output is generated. 2000-05-16 04:05:59 +00:00
steve 3676d66408 Module ports are really special PEIdent
expressions, because a name can be used
 many places in the port list.
2000-05-16 04:05:15 +00:00
steve addedf7231 Fix -f flag handling. 2000-05-14 19:41:52 +00:00
steve 562e4c28d2 Update to use iverilog. 2000-05-14 19:41:22 +00:00
steve 1e0e1a2b64 Add a demonstration of DFF initialization. 2000-05-14 19:41:08 +00:00
steve ea96c3ef66 Support initialization of FF Q value. 2000-05-14 17:55:04 +00:00
steve cca036c4a8 Make rules consistent with token stream. 2000-05-13 22:46:22 +00:00
steve 3c9902d93e Use yacc based synthesizer. 2000-05-13 20:55:47 +00:00
steve e5511fd0a7 Up to date support, and mention iverilog. 2000-05-13 20:55:15 +00:00
steve afdb76c929 Use iverilog command. 2000-05-13 20:54:48 +00:00
steve b44abcd481 Get rid of gverilog source. 2000-05-12 05:23:15 +00:00
steve c3282bfa6c NetCAssign needs to incr_eref its lval to lock it down. 2000-05-12 01:22:41 +00:00
steve 367db72c99 Add support for procedural continuous assignment. 2000-05-11 23:37:26 +00:00
steve 4f0b0cb8ce No need for nobufz. 2000-05-11 01:44:52 +00:00
steve d68339a96a Calculate the X output value from drive0 and drive1 2000-05-11 01:37:33 +00:00
steve 6021c7b192 Give strengths to logic and bufz devices. 2000-05-09 21:16:35 +00:00
steve d4bab8709b Remove test print. 2000-05-09 00:02:29 +00:00
steve 2f59918c74 Parameterize LD lib in C++ command line. 2000-05-09 00:02:13 +00:00
steve de1a7a0933 Deliver gate output strengths to the netlist. 2000-05-08 05:30:19 +00:00
steve e9742c662b no need for nobufz functor. 2000-05-08 05:29:43 +00:00
steve e81ce68e8c Use bufz to make assignments directional. 2000-05-08 05:28:29 +00:00
steve c98e4b25b3 Restore vvm_bufz to working condition. 2000-05-08 05:27:32 +00:00
steve c4d8ded269 non-blocking assignment to a bit select. 2000-05-07 21:17:21 +00:00
steve 35a2690d75 Properly elaborate repeat concatenations. 2000-05-07 20:48:14 +00:00
steve ca6631fdda Fix connection of Direction of LMP_CLSHIFT
to constant values. Remember to add a signal
 to the nexus and connect the receiver in vvm.
2000-05-07 19:40:26 +00:00
steve b28f258463 Import MCD support from Stephen Tell, and add
system function parameter support to the IVL core.
2000-05-07 18:20:07 +00:00
steve b90cda1f3f Carry strength values from Verilog source to the
pform and netlist for gates.

 Change vvm constants to use the driver_t to drive
 a constant value. This works better if there are
 multiple drivers on a signal.
2000-05-07 04:37:55 +00:00
steve ca2fd41bb6 Carry assignment strength to pform. 2000-05-06 15:41:56 +00:00
steve 43643ba98f Add the -I and -D switches to iverilog. 2000-05-05 01:07:42 +00:00
steve f847b9cfeb Tell ivlpp to generate line number directives. 2000-05-04 20:08:20 +00:00
steve fbe475ef7d Add infrastructure for system functions, move
$time to that structure and add $random.
2000-05-04 03:37:58 +00:00
steve f95b082339 More features of ivl available through iverilog. 2000-05-03 22:14:31 +00:00
steve 0a70a8a954 Allow ternary result to be padded to result width. 2000-05-03 21:21:36 +00:00
steve ed5e587cf1 Support named for in VPI. 2000-05-03 05:03:26 +00:00
steve 1db70a0c46 Move signal elaboration to a seperate pass. 2000-05-02 16:27:38 +00:00
steve 69612ceb73 Move memories to the NetScope object. 2000-05-02 03:13:30 +00:00
steve 8d8f1e2401 Move signal tables to the NetScope class. 2000-05-02 00:58:11 +00:00
steve b175e4aef7 Better inc and lib paths for iverilog. 2000-05-01 23:55:22 +00:00
steve 8a4937bada missing header file. 2000-04-29 04:53:44 +00:00
steve b5b15a5990 The -f flag is now in place. 2000-04-29 01:20:14 +00:00
steve 3aef1be0e7 Proper bounds checking of the left operator of right shift. 2000-04-29 01:19:47 +00:00
steve 77361fb8a0 Overly aggressive eliding of task calls. 2000-04-28 23:12:12 +00:00
steve 3a9be680a4 Skip empty tasks. 2000-04-28 22:17:47 +00:00
steve acfb5c177d Over agressive signal elimination in constant probadation. 2000-04-28 21:00:28 +00:00
steve 2b40c7ce11 integer division in expressions properly get width. 2000-04-28 18:43:23 +00:00
steve 08e9a114a2 Catch memory word parameters to tasks. 2000-04-28 16:50:53 +00:00
steve 1f7090135b Mussed up command string mashing. 2000-04-26 21:11:41 +00:00
steve 1412eb2697 iverilog man page. 2000-04-26 20:53:21 +00:00
steve dab5999621 Handle assigning small values to big registers. 2000-04-26 18:35:11 +00:00
steve 906c7b4783 Do not set width too small to hold significant bits. 2000-04-26 03:33:32 +00:00
steve e78af393de AND handles argument padding if necessary. 2000-04-26 03:32:40 +00:00
steve 72c8897d13 Handling mixing of defines within ifdef/endif. 2000-04-26 01:35:26 +00:00
steve 9ca1791b43 automatically generate macro interface code. 2000-04-23 23:03:13 +00:00
steve 6e8fe39cc7 Better comments about bufif devices. 2000-04-23 21:17:31 +00:00
steve 6446add9cd Emit code for the bufif devices. 2000-04-23 21:15:07 +00:00
steve ebacf88b14 The -s flag. 2000-04-23 21:14:32 +00:00
steve a8114ae122 Add support for the procedural release statement. 2000-04-23 03:45:24 +00:00
steve 44838f8973 Add support for force assignment. 2000-04-22 04:20:19 +00:00
steve ad8811282b module path in vvm target. 2000-04-21 22:54:47 +00:00
steve 181b776f0c Support the -tnull target type. 2000-04-21 22:51:38 +00:00
steve c0d51dd2eb Add the iverilog driver program. 2000-04-21 06:41:02 +00:00
steve 99a891b8a1 Bit padding in assignment to memory. 2000-04-21 04:38:15 +00:00
steve 23725cf42c Catch bad operand to some unary operators. 2000-04-21 03:22:18 +00:00
steve 9a36dcd33d Many Unary operators have known widths. 2000-04-21 02:46:42 +00:00
steve d539b0b5fe Generic multiplier (Chris Lattner) 2000-04-21 02:30:40 +00:00
steve 37e65614a0 exit if hex value is missing. 2000-04-21 02:00:35 +00:00
steve 88d3ad51b0 Generate code for identity compare. Use gates. 2000-04-20 02:34:47 +00:00
steve 2094a2f466 Catch some simple identity compareoptimizations. 2000-04-20 00:28:03 +00:00
steve 74c43032b3 Clean up unneeded NetEvent objects. 2000-04-18 04:50:19 +00:00
steve 4f07c43976 Minor cleanup of NetTaskDef. 2000-04-18 01:02:53 +00:00
steve 726f7b8b11 Synthesis of comparator in expressions.
Connect the NetEvent and related classes
 together better.
2000-04-16 23:32:18 +00:00
steve 5624a66bbb Catch expressions that are part of conditionals. 2000-04-16 22:57:34 +00:00
steve 7484feceb5 fork-join support in vvm. 2000-04-15 19:51:30 +00:00
steve d033509359 Support chained events. 2000-04-15 02:25:32 +00:00
steve 62c6422724 Document the calling convention. 2000-04-15 01:44:59 +00:00
steve df0808d5bb No more class derivation from vvm_thread. 2000-04-14 23:31:53 +00:00
steve 4493e968da 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.
2000-04-12 20:02:52 +00:00
steve 59bbc27268 Backwards sense of assert test. 2000-04-12 16:08:46 +00:00
steve b1fd927acb 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.
2000-04-12 04:23:57 +00:00
steve b0d0cdbd7d Multiple thread can block on an event. 2000-04-12 01:53:07 +00:00
steve 8dbd64121f All events now use the NetEvent class. 2000-04-10 05:26:05 +00:00
steve 72b3508911 Catch event declarations during scope elaborate. 2000-04-09 17:44:30 +00:00
steve 8d16ee9dd5 uninitialized event_ list. 2000-04-09 17:04:56 +00:00
steve cad5df1e9f Donot create tables that have no entries. 2000-04-09 16:55:42 +00:00
steve e9b06f1022 Catch event names in parentheses. 2000-04-09 16:43:50 +00:00
steve 7307deb3a9 Catch duplicate $dumpvars of symbols (ajb) 2000-04-09 04:18:16 +00:00
steve f6959ba09e Fix memory object compile problems. 2000-04-08 05:49:59 +00:00
steve 2693a8cd7d Revamped VCD id generation and duplicates removal. (ajb) 2000-04-08 05:28:39 +00:00
steve 30e8289239 Simulate named event trigger and waits. 2000-04-04 03:20:15 +00:00
steve b62a7ace5c Remove the useless sref template. 2000-04-02 04:26:06 +00:00
steve 67bdd433a9 Detect the signed keyword. 2000-04-02 04:25:39 +00:00
steve 6150be2324 detect unsupported block on named events. 2000-04-01 22:14:19 +00:00
steve 694ff934af Add support for integer division. 2000-04-01 21:40:22 +00:00
steve 2dd010dc04 Named events as far as the pform. 2000-04-01 19:31:57 +00:00
steve 26dcecebdb allow cancelling of cbValueChange events. 2000-03-31 07:08:39 +00:00
steve d97ab9be23 New and improved combinational primitives. 2000-03-29 04:37:10 +00:00
steve 995f7e89d1 Handle define of macro without value. 2000-03-29 04:36:42 +00:00
steve 995f61ace4 Forgot to return elaborate result (Dan Nelsen) 2000-03-29 04:06:28 +00:00
steve b9d19d3358 Speling error. 2000-03-27 04:38:15 +00:00
steve ffc3a42405 Remove the vvm_bits_t abstract class. 2000-03-26 16:55:41 +00:00
steve 8a10511105 vvm_bitset_t is no longer a template. 2000-03-26 16:28:31 +00:00
steve 9f84deeb56 signal bits are referenced at run time by the vpiSignal struct. 2000-03-25 05:02:24 +00:00
steve dcaea50b8f Remove all remain vvm_bitset_t return values,
and disallow vvm_bitset_t copying.
2000-03-25 02:43:56 +00:00
steve c790ccca5a Update vvm_ram_dq to nexus style. 2000-03-24 03:47:01 +00:00
steve edc40f1792 vvm_unop and vvm_binop pass result by reference
instead of returning a value.
2000-03-24 02:43:36 +00:00
steve eb9ed665f3 Do not create 0 length parameters to system tasks. 2000-03-23 03:24:39 +00:00
steve d4370a0878 Integrate drive resolution function. 2000-03-22 05:16:38 +00:00
steve a9e11d6546 Replace the vpip_bit_t with a typedef and
define values for all the different bit
 values, including strengths.
2000-03-22 04:26:40 +00:00
steve 649ce73047 Minor performance boost for gperf keyword table. 2000-03-21 05:08:32 +00:00
steve 3265f3f63a Remove dangerous tmp signal delete. 2000-03-20 17:54:10 +00:00
steve c3da6febbd More complete error message about no signal. 2000-03-20 17:40:54 +00:00
steve c5b64b4ad4 Do not link adder pins that ar unconnected. 2000-03-20 17:40:33 +00:00
steve 44d30ad127 select correct bit when reg has non-zero lsb. 2000-03-20 16:57:22 +00:00
steve 94270ff988 Fix lval part select of non-blocking assign. 2000-03-20 15:28:58 +00:00
steve 2deb379c06 Update the FF device to nexus style. 2000-03-18 23:22:37 +00:00
steve 09e0d668a6 Handle EOF in defines. 2000-03-18 06:12:26 +00:00
steve 80bd855329 Update bufz to nexus style. 2000-03-18 02:26:02 +00:00
steve 567de6ba39 Generate references into a table of nexus objects instead of
generating lots of isolated nexus objects. Easier on linkers
 and compilers,

 Add missing nexus support for l-value bit selects,

 Detemplatize the vvm_mux type.

 Fix up the vvm_nexus destructor to disconnect from drivers.
2000-03-18 01:26:59 +00:00
steve 48de739506 Switch to control warnings. 2000-03-17 21:50:25 +00:00
steve 3adaf23aab Detemplatize the vvm_signal_t class. 2000-03-17 20:21:14 +00:00
steve e71413123e nor2 and and2 optimized gates. 2000-03-17 19:23:59 +00:00
steve 51e96a2d8b Adder and comparator in nexus style. 2000-03-17 17:25:53 +00:00
steve 38fd245767 Remove some useless template parameters. 2000-03-17 03:36:07 +00:00
steve 20712d3fcc Update vvm_mult to nexus style. 2000-03-17 03:05:13 +00:00
steve 8cbf4f815e vvm_clshift implementation without templates. 2000-03-17 02:22:03 +00:00
steve 5ea3610d4a Update LPM_MUX to nexus style. 2000-03-16 23:13:49 +00:00
steve 9deb7f6ba5 Update LMP_CLSHIFT to use nexus interface. 2000-03-16 21:47:27 +00:00
steve 7ab6ff77ad Properly initialize driver and nexus values. 2000-03-16 21:45:07 +00:00
steve 2563e2b717 Revise the VVM backend to use nexus objects so that
drivers and resolution functions can be used, and
 the t-vvm module doesn't need to write a zillion
 output functions.
2000-03-16 19:03:03 +00:00
steve 2e05f7f7ec Remove unneeded templates. 2000-03-13 00:02:34 +00:00
steve 01c5147079 Connect output of NB assign to indexed pin. 2000-03-12 21:41:47 +00:00
steve 71a506a28a Binary and unary operators in parameter expressions. 2000-03-12 18:22:11 +00:00
steve 6eef54595f Support localparam. 2000-03-12 17:09:40 +00:00
steve 79f772200a Allow parameter identifiers in parameter expressions. 2000-03-12 04:35:22 +00:00
steve 78ab1a7bba Locate scopes in statements. 2000-03-11 03:25:51 +00:00
steve 61822d48aa Handle defparam to partial hierarchical names. 2000-03-10 06:20:48 +00:00
steve e7efc2709a 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.
2000-03-08 04:36:53 +00:00
steve 0fbca815b4 Fix up start of the readmemx lexor. 2000-03-05 20:01:19 +00:00
steve 1698a19cf6 Parse all the various edge types. 2000-03-05 18:26:51 +00:00
steve 7b5b5c2f39 Handle mixed case in UDP edges. 2000-03-05 06:14:10 +00:00
steve 2a68121685 Use the new cell, instead of the deleted old one. 2000-03-05 06:13:29 +00:00
steve 380d5620e6 Simpler implementation of multiplication. 2000-03-04 01:13:54 +00:00
steve aae17041ef Remove excess variable. 2000-02-29 05:20:21 +00:00
steve 1d7cf5bb8c Handle scope of complex guards when writing case in functions. 2000-02-29 05:02:30 +00:00
steve 8696a4363a Fix warning and typo. 2000-02-29 01:41:32 +00:00
steve 59c240bc9b I no longer need to declare string and number tables early. 2000-02-24 01:57:10 +00:00
steve d751b05cec change not to v_not. 2000-02-24 01:56:28 +00:00
steve 843af31958 Some compilers do not accept the not symbol. 2000-02-23 04:43:43 +00:00
steve 5aea537ab9 Add Kato to the list. 2000-02-23 04:42:49 +00:00
steve b734ecf02f Macintosh compilers do not support ident. 2000-02-23 02:56:53 +00:00
steve 5b52c384d6 Catch module instantiation arrays. 2000-02-18 05:15:02 +00:00
steve 2cba0a50f3 Fix overlap of identifiers when multiple modules used. 2000-02-17 06:04:30 +00:00
steve b354cf68b8 Fix up width matching in structural bitwise operators. 2000-02-16 03:58:27 +00:00
steve a9264d71c6 Unary reduction operators do not set their operand width 2000-02-14 06:04:52 +00:00
steve e0873f6c14 Support case in functions. 2000-02-14 01:20:50 +00:00
steve b8ddbcf62b support if-else in function definitions. 2000-02-14 00:12:09 +00:00
steve bd09bed662 Mark the line numbers of NetCondit nodes. 2000-02-14 00:11:11 +00:00
steve 1ee4015aa8 Handle selecting memory words at run time. 2000-02-13 19:59:33 +00:00
steve a8d787bd66 Accept memory words as parameter to $display. 2000-02-13 19:18:27 +00:00
steve e77bcf6910 Include some block matching from Larry. 2000-02-13 04:35:43 +00:00
steve 2bc8f79e0f Update xilinx-hints.txt from Larry. 2000-02-13 04:06:49 +00:00
steve e58be1b128 Jason moved. 2000-02-13 04:05:47 +00:00
steve ee180f6cf0 Include the scope in named gates. 2000-02-06 23:13:14 +00:00
steve ce0b97a8f0 Fix up compiling with configured -ldl switch. 2000-02-05 06:40:35 +00:00
steve cf8d17a6ab Handle systems that need underscores in symbols. 2000-01-24 00:18:20 +00:00
steve e6bd088984 Compile time problems with vpi_user.h 2000-01-23 23:54:36 +00:00
steve 9b3c3b6e7a add the -m flag. 2000-01-21 05:41:51 +00:00
steve dc5bd8ea59 $dumpall checkpointing in VCD dump. 2000-01-20 06:04:55 +00:00
steve 121b6c2ecb missing break is switch. 2000-01-18 04:53:57 +00:00
steve 57d28e4f86 Support structural XNOR. 2000-01-18 04:53:40 +00:00
steve d84b72609d Add the XNOR operator. 2000-01-13 06:05:46 +00:00
steve ef98be1192 Support for multiple VPI modules. 2000-01-13 05:11:24 +00:00
steve 3b9dedbc86 Catch some parameter problems. 2000-01-13 04:48:50 +00:00
steve aa8908c52f Multiplication all the way to simulation. 2000-01-13 03:35:35 +00:00
steve 3d1ffced57 Elaborate net widths of constants to as small
as is possible, obeying context constraints.

 Comparison operators can handle operands with
 different widths.
2000-01-11 04:20:57 +00:00
steve f37f69f160 minor type syntax fix for stubborn C++ compilers. 2000-01-10 22:16:24 +00:00
steve fac3bde2c8 Elaborate parameters afer binding of overrides. 2000-01-10 01:35:23 +00:00
steve 9125a4c451 Careful with wires connected to multiple ports. 2000-01-09 20:37:57 +00:00
steve bed47a4ab4 Make the library install directory. 2000-01-09 17:43:28 +00:00
steve 2de887c2ff Support named parameter override lists. 2000-01-09 05:50:48 +00:00
steve fdf2c1b0d0 Non-blocking memory writes. 2000-01-08 03:09:14 +00:00
steve 7f78b9bf56 Handle longer paths and the null target (spe) 2000-01-08 02:28:43 +00:00
steve d6f53b2582 Initial support for signed constants. 2000-01-07 03:45:49 +00:00
steve 848110bc33 Only sign-extend unsized numbers. 2000-01-06 05:57:06 +00:00
steve eb4cdc5026 Cleanup and some asserts. 2000-01-06 05:56:22 +00:00
steve 3d673c1f02 Add memory address range check. 2000-01-06 05:56:02 +00:00
steve a48b4c4f8d Functor support from Stefan 2000-01-04 02:51:54 +00:00
steve ba7fdb580d Add a signal to nexus of padding constant. 2000-01-02 22:07:09 +00:00
steve 9e5ff89ef3 Add structural reduction NAND,
Fix size coercion of structural shifts.
2000-01-02 21:45:31 +00:00
steve 0d5e4b40d0 Structural reduction XNOR. 2000-01-02 19:39:03 +00:00
steve 142b9e667d Do not overrun the pin index when the LSB != 0. 2000-01-02 18:25:37 +00:00
steve f3b76d958d It is possible for node to initialize several pins of a signal. 2000-01-02 17:57:56 +00:00
steve 87d6df5204 Handle nodes running out during node scan. 2000-01-02 17:57:20 +00:00
steve c7193fa6fe Do not delete constants that input to exressions. 2000-01-02 17:56:42 +00:00
steve 645c24289e Handle general constant expressions in delays. 2000-01-02 01:59:52 +00:00
steve e52a5be16e Forgot to handle no overrides at all. 2000-01-02 01:59:28 +00:00
steve 7e37b61a05 Fix module parameter override syntax. 2000-01-01 23:47:58 +00:00
steve cbd353fbb8 Fix forming of ivlpp command line. 2000-01-01 21:33:50 +00:00
steve 4c274223cf Move ivl and ivlpp to the lib directory. 2000-01-01 20:57:50 +00:00
steve 65e4e9f428 Properly expand/shrink constants in expressions. 2000-01-01 19:56:51 +00:00
steve e6820ed169 Handle synthesis of concatenation. 2000-01-01 06:18:00 +00:00
steve c3cb0f2371 Propogate line number information when expanding expressions. 2000-01-01 06:17:25 +00:00
steve 31f1ceea9f delay1 expressions can take parentheses. 1999-12-31 17:39:00 +00:00
steve 94afe54741 Standardize some of the error messages. 1999-12-31 17:38:37 +00:00
steve 080f161c37 Fix output file name calculations. 1999-12-31 05:27:42 +00:00
steve 5ce35e3e60 Fix event trigger and repeat control parse errors. 1999-12-31 03:24:30 +00:00
steve 6d0edcf58a Support reg initial assignment syntax. 1999-12-30 19:06:14 +00:00
steve 7033836e01 Remove the now useless sigfold functor. 1999-12-30 17:37:13 +00:00
steve b7409d98ff Version and ebug options. 1999-12-30 04:59:39 +00:00
steve b6d1bb1fa7 Propogate constant 0 in low bits of adders. 1999-12-30 04:19:12 +00:00
steve 4558a7d8d0 Proper init_ method prototype. 1999-12-19 20:57:07 +00:00
steve 22c2625ace Add the gverilog driver program. 1999-12-18 04:15:01 +00:00
steve 4de8ba489d Rewrite the cprop functor to use the functor_t interface. 1999-12-17 06:18:15 +00:00
steve 65ae92859c NetConst can now hold wide constants. 1999-12-17 03:38:46 +00:00
steve d355270c2d Capture the carry out of carry-chain addition. 1999-12-16 18:54:32 +00:00
steve ced7cc6d60 Structural logical or. 1999-12-16 03:46:39 +00:00
steve d54cc14ca2 Simulate carry output on adders. 1999-12-16 02:42:14 +00:00
steve 98a57f4fac Handle blanks after b is binary numbers 1999-12-16 01:20:17 +00:00
steve 40ca71b10b Support named begin scope at run time. 1999-12-15 18:21:20 +00:00
steve e7e58cdd71 Add readmemb. 1999-12-15 04:35:34 +00:00
steve 1dcf9de34c Implement vpi_put_value for memory words. 1999-12-15 04:15:17 +00:00
steve fcb1d8dc72 Excess warning. 1999-12-15 04:02:38 +00:00
steve 5fa7e1c31b Add the VPI implementation of $readmemh. 1999-12-15 04:01:14 +00:00
steve 6e3c258edb Detect duplicate scopes. 1999-12-14 23:42:16 +00:00
steve 6be5421c8a Remove the useless vvm_simulation class. 1999-12-12 19:47:54 +00:00
steve 76655ce2bb Allow memories without indices in expressions. 1999-12-12 06:03:14 +00:00
steve 3e1738dcec Fix support for attaching attributes to primitive gates. 1999-12-11 05:45:41 +00:00
steve ec8dec74a6 Example how to mke OUTFF devices in IOBs. 1999-12-11 04:10:39 +00:00
steve 838d25890b Various spelling fixes. 1999-12-09 06:00:55 +00:00
steve 4a6d3a5104 Fix const/non-const errors. 1999-12-09 06:00:00 +00:00
steve b688cdbc40 Add some examples as documentation. 1999-12-05 21:08:56 +00:00
steve 09de918198 Generate XNF RAMS from synthesized memories. 1999-12-05 19:30:42 +00:00
steve 3e2bb85f58 Synthesize LPM_RAM_DQ for writes into memories. 1999-12-05 02:24:08 +00:00
336 changed files with 72569 additions and 12403 deletions
+8 -1
View File
@@ -1,12 +1,19 @@
lexor_keyword.cc
parse.h
parse.cc
parse.cc.output
syn-rules.cc
syn-rules.cc.output
lexor.cc
ivl
ivl.exp
dep
configure
Makefile
verilog
check
check.cc
config.status
config.log
config.cache
config.h
dosify
+131
View File
@@ -0,0 +1,131 @@
/*
* Copyright (c) 2000 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)
#ident "$Id: Attrib.cc,v 1.2 2001/07/25 03:10:48 steve Exp $"
#endif
# include "config.h"
# include "Attrib.h"
# include <assert.h>
Attrib::Attrib()
{
nlist_ = 0;
list_ = 0;
}
Attrib::~Attrib()
{
delete[] list_;
}
void Attrib::set_attributes(const map<string,string>&attr)
{
assert(list_ == 0);
nlist_ = attr.size();
list_ = new cell_[nlist_];
map<string,string>::const_iterator idx;
unsigned jdx;
for (idx = attr.begin(), jdx = 0 ; idx != attr.end() ; idx ++, jdx++) {
struct cell_*tmp = list_ + jdx;
tmp->key = (*idx).first;
tmp->val = (*idx).second;
}
}
string Attrib::attribute(const string&key) const
{
for (unsigned idx = 0 ; idx < nlist_ ; idx += 1) {
if (key == list_[idx].key)
return list_[idx].val;
}
return "";
}
void Attrib::attribute(const string&key, const string&value)
{
unsigned idx;
for (idx = 0 ; idx < nlist_ ; idx += 1) {
if (key == list_[idx].key) {
list_[idx].val = value;
return;
}
}
struct cell_*tmp = new struct cell_[nlist_+1];
for (idx = 0 ; idx < nlist_ ; idx += 1)
tmp[idx] = list_[idx];
tmp[nlist_].key = key;
tmp[nlist_].val = value;
nlist_ += 1;
delete[]list_;
list_ = tmp;
}
bool Attrib::has_compat_attributes(const Attrib&that) const
{
unsigned idx;
for (idx = 0 ; idx < that.nlist_ ; idx += 1) {
string tmp = attribute(that.list_[idx].key);
if (tmp != that.list_[idx].val)
return false;
}
return true;
}
unsigned Attrib::size() const
{
return nlist_;
}
string Attrib::key(unsigned idx) const
{
assert(idx < nlist_);
return list_[idx].key;
}
string Attrib::value(unsigned idx) const
{
assert(idx < nlist_);
return list_[idx].val;
}
/*
* $Log: Attrib.cc,v $
* 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)
*
* Revision 1.1 2000/12/04 17:37:03 steve
* Add Attrib class for holding NetObj attributes.
*
*/
+69
View File
@@ -0,0 +1,69 @@
#ifndef __Attrib_H
#define __Attrib_H
/*
* Copyright (c) 2000 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)
#ident "$Id: Attrib.h,v 1.1 2000/12/04 17:37:03 steve Exp $"
#endif
# include <string>
# include <map>
/*
* This class keeps a map of key/value pairs. The map can be set from
* an STL map, or by setting individual mappings.
*/
class Attrib {
public:
Attrib();
~Attrib();
void set_attributes(const map<string,string>&attr);
string attribute(const string&key) const;
void attribute(const string&key, const string&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;
private:
struct cell_ {
string key;
string val;
};
unsigned nlist_;
struct cell_*list_;
private: // not implemented
Attrib(const Attrib&);
Attrib& operator= (const Attrib&);
};
/*
* $Log: Attrib.h,v $
* Revision 1.1 2000/12/04 17:37:03 steve
* Add Attrib class for holding NetObj attributes.
*
*/
#endif
+55
View File
@@ -0,0 +1,55 @@
/*
* Copyright (c) 2000 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: LineInfo.cc,v 1.2 2001/07/25 03:10:48 steve Exp $"
#endif
# include "config.h"
# include "LineInfo.h"
# include <cstdio>
LineInfo::~LineInfo()
{
}
string LineInfo::get_line() const
{
char buf[8];
sprintf(buf, "%u", lineno_);
return string(file_? file_ : "") + ":" + buf;
}
void LineInfo::set_line(const LineInfo&that)
{
file_ = that.file_;
lineno_ = that.lineno_;
}
/*
* $Log: LineInfo.cc,v $
* 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)
*
* Revision 1.1 2000/11/30 17:31:42 steve
* Change LineInfo to store const C strings.
*
*/
+23 -35
View File
@@ -18,59 +18,47 @@
* 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: LineInfo.h,v 1.3 1999/02/15 02:06:15 steve Exp $"
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: LineInfo.h,v 1.5 2000/11/30 17:31:42 steve Exp $"
#endif
# include <cstdio>
# include <string>
/*
* This class holds line information for an internal object.
*
* Note that the file names are C-style strings that are allocated by
* the lexor (which parses the line directives) and are never
* deallocated. We can therefore safely store the pointer and never
* delete the string, even if LineInfo objects are destroyed.
*/
class LineInfo {
public:
LineInfo() : lineno_(0) { }
LineInfo() : file_(0), lineno_(0) { }
~LineInfo();
string get_line() const
{ char buf[8];
sprintf(buf, "%u", lineno_);
return file_ + ":" + buf;
}
string get_line() const;
void set_line(const LineInfo&that)
{ file_ = that.file_;
lineno_ = that.lineno_;
}
void set_line(const LineInfo&that);
void set_file(const string&f) { file_ = f; }
void set_file(const char*f) { file_ = f; }
void set_lineno(unsigned n) { lineno_ = n; }
private:
string file_;
const char* file_;
unsigned lineno_;
};
/*
* $Log: LineInfo.h,v $
* Revision 1.5 2000/11/30 17:31:42 steve
* Change LineInfo to store const C strings.
*
* Revision 1.4 2000/02/23 02:56:53 steve
* Macintosh compilers do not support ident.
*
* Revision 1.3 1999/02/15 02:06:15 steve
* Elaborate gate ranges.
*
* Revision 1.2 1999/02/01 00:26:48 steve
* Carry some line info to the netlist,
* Dump line numbers for processes.
* Elaborate prints errors about port vector
* width mismatch
* Emit better handles null statements.
*
* Revision 1.1 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.
*
*/
#endif
+153 -50
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,126 +16,231 @@
# 59 Temple Place - Suite 330
# Boston, MA 02111-1307, USA
#
#ident "$Id: Makefile.in,v 1.30 1999/11/29 17:02:21 steve Exp $"
#ident "$Id: Makefile.in,v 1.103 2001/08/10 00:40:00 steve Exp $"
#
#
SHELL = /bin/sh
VERSION = 0.0
VERSION = 0.5
prefix = @prefix@
exec_prefix = @exec_prefix@
srcdir = @srcdir@
SUBDIRS = @subdirs@
VPATH = $(srcdir)
bindir = $(exec_prefix)/bin
libdir = $(exec_prefix)/lib
mandir = @mandir@
bindir = @bindir@
libdir = @libdir@
includedir = $(prefix)/include
dllib=@DLLIB@
rdynamic=@rdynamic@
CC = @CC@
CXX = @CXX@
INSTALL = @INSTALL@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
STRIP = @STRIP@
CPPFLAGS = @CPPFLAGS@ @DEFS@
CXXFLAGS = @CXXFLAGS@ -I$(srcdir)
CXXFLAGS = @CXXFLAGS@ -I. -I$(srcdir)
PICFLAGS = @PICFLAG@
LDFLAGS = @LDFLAGS@
all: ivl verilog
cd vpi ; $(MAKE) all
# The TARGETS variable lists the target modules that can be build and
# installed. Some of them depend on external things, so are only
# compiled if the prerequisites are installed.
TARGETS = tgt-null
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
cd vpi ; $(MAKE) all
cd ivlpp ; $(MAKE) all
cd driver ; $(MAKE) all
cd tgt-verilog ; $(MAKE) all
cd tgt-stub ; $(MAKE) all
for tgt in $(TARGETS); do (cd $$tgt ; $(MAKE) all); done
# In the windows world, the installer will need a dosify program to
# dosify text files.
ifeq (@WIN32@,yes)
all: dosify.exe
dosify.exe: dosify.c
$(CC) -o dosify.exe dosify.c
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'
clean:
rm -f *.o parse.cc parse.cc.output parse.h dep/*.d lexor.cc verilog
cd vpi ; $(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
cd vvm ; $(MAKE) clean
cd vpi ; $(MAKE) clean
cd driver ; $(MAKE) clean
cd ivlpp ; $(MAKE) clean
cd tgt-verilog ; $(MAKE) clean
cd tgt-stub ; $(MAKE) clean
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) clean); done
for tgt in $(TARGETS); do (cd $$tgt ; $(MAKE) clean); done
distclean: clean
rm -f vpi/Makefile
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
TT = t-null.o t-verilog.o t-vvm.o t-xnf.o
FF = nobufz.o nodangle.o propinit.o sigfold.o synth.o xnfio.o xnfsyn.o
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
O = main.o cprop.o design_dump.o dup_expr.o elaborate.o elab_expr.o \
elab_net.o emit.o eval.o eval_tree.o expr_synth.o functor.o \
lexor.o lexor_keyword.o mangle.o netlist.o pad_to_width.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 \
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 \
parse.o parse_misc.o pform.o pform_dump.o \
set_width.o \
verinum.o verireal.o target.o targets.o Module.o PDelays.o PExpr.o PGate.o \
verinum.o verireal.o target.o targets.o util.o \
Attrib.o LineInfo.o Module.o PDelays.o PEvent.o \
PExpr.o PGate.o \
PTask.o PFunction.o PWire.o Statement.o \
$(FF) $(TT)
Makefile: Makefile.in config.status
Makefile: Makefile.in config.h.in config.status
./config.status
# Make the actual verilog program from the script template. This
# simply invloves editing the substitution strings in the script into
# the configured copy.
tmp1 = bindir
tmp2 = libdir
tmp3 = includedir
tmp4 = CXX
verilog: $(srcdir)/verilog.sh
sed -e 's;@$(tmp1)@;@bindir@;' \
-e 's;@$(tmp2)@;@libdir@;' \
-e 's;@$(tmp3)@;@includedir@;' \
-e 's;@$(tmp4)@;@CXX@;' < $< > $@
ivl: $O
$(CXX) $(CXXFLAGS) -o ivl $O
libvpi.a: vpithunk.o
rm -f $@
ar cvq $@ vpithunk.o
%.o dep/%.d: %.cc
# The vpithunk.c file (that makes up the libvpi.a library) needs to
# be make with PIC flags, because shared objects load it.
vpithunk.o: vpithunk.c
@[ -d dep ] || mkdir dep
$(CC) $(CPPFLAGS) $(CFLAGS) $(PICFLAGS) -MD -c $< -o $*.o
mv $*.d dep/$*.d
ifeq (@WIN32@,yes)
ivl@EXEEXT@: $O ivl.def
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
$(CXX) $(CXXFLAGS) $(rdynamic) $(LDFLAGS) -o ivl@EXEEXT@ $O $(dllib)
endif
%.o: %.cc
@[ -d dep ] || mkdir dep
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -MD -c $< -o $*.o
mv $*.d dep/$*.d
lexor.o dep/lexor.d: lexor.cc parse.h
lexor.o: lexor.cc parse.h
parse.o dep/parse.d: parse.cc
parse.o: parse.cc
parse.h parse.cc: $(srcdir)/parse.y
bison --verbose -t -p VL -d $(srcdir)/parse.y -o parse.cc
bison --verbose -t -p VL -d -o parse.cc $(srcdir)/parse.y
mv parse.cc.h parse.h
syn-rules.cc: $(srcdir)/syn-rules.y
bison --verbose -p syn_ -o syn-rules.cc $(srcdir)/syn-rules.y
lexor.cc: $(srcdir)/lexor.lex
flex -PVL -s -olexor.cc $(srcdir)/lexor.lex
install: all installdirs $(bindir)/verilog $(bindir)/ivl $(mandir)/man1/verilog.1
cd vpi ; $(MAKE) install
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)
ifeq (@WIN32@,yes)
WIN32_INSTALL = $(prefix)/hello.vl $(prefix)/sqrt.vl $(prefix)/QUICK_START.txt
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
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)/verilog: ./verilog
$(INSTALL_PROGRAM) ./verilog $(bindir)/verilog
$(libdir)/libvpi.a : ./libvpi.a
$(INSTALL_DATA) libvpi.a $(libdir)/libvpi.a
$(bindir)/ivl: ivl
$(INSTALL_PROGRAM) ./ivl $(bindir)/ivl
$(STRIP) $(bindir)/ivl
$(libdir)/ivl/ivl@EXEEXT@: ./ivl@EXEEXT@
$(INSTALL_PROGRAM) ./ivl@EXEEXT@ $(libdir)/ivl/ivl@EXEEXT@
$(STRIP) $(libdir)/ivl/ivl@EXEEXT@
$(mandir)/man1/verilog.1: $(srcdir)/verilog.1
$(INSTALL_DATA) $(srcdir)/verilog.1 $(mandir)/man1/verilog.1
$(libdir)/ivl/iverilog.conf: $(srcdir)/iverilog.conf
$(INSTALL_DATA) $(srcdir)/iverilog.conf $(libdir)/ivl/iverilog.conf
$(includedir)/ivl_target.h: $(srcdir)/ivl_target.h
$(INSTALL_DATA) $(srcdir)/ivl_target.h $(includedir)/ivl_target.h
$(includedir)/vpi_user.h: $(srcdir)/vpi_user.h
$(INSTALL_DATA) $(srcdir)/vpi_user.h $(includedir)/vpi_user.h
# In windows installations, put a few examples and the quick_start
# into the destination directory.
ifeq (@WIN32@,yes)
$(prefix)/hello.vl: $(srcdir)/examples/hello.vl
./dosify.exe $(srcdir)/examples/hello.vl tmp.vl
mv tmp.vl $(prefix)/hello.vl
$(prefix)/sqrt.vl: $(srcdir)/examples/sqrt.vl
./dosify.exe $(srcdir)/examples/sqrt.vl tmp.vl
mv tmp.vl $(prefix)/sqrt.vl
$(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) $(mandir)/man1
$(srcdir)/mkinstalldirs $(bindir) $(includedir) $(libdir)/ivl
uninstall:
rm -f $(bindir)/ivl
rm -f $(libdir)/ivl/ivl@EXEEXT@
rm -f $(bindir)/verilog
rm -f $(mandir)/man1/verilog.1
rm -f $(bindir)/gverilog@EXEEXT@
rm -f $(includedir)/ivl_target.h
rm -f $(includedir)/vpi_user.h
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
-include $(patsubst %.o, dep/%.d, $O)
-include $(patsubst %.o, dep/%.d, vpithunk.o)
+83 -20
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998 Stephen Williams ([email protected])
* Copyright (c) 1998-2000 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
@@ -16,26 +16,23 @@
* 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: Module.cc,v 1.7 1999/09/17 02:06:25 steve Exp $"
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: Module.cc,v 1.15 2001/07/25 03:10:48 steve Exp $"
#endif
# include "config.h"
# include "Module.h"
# include "PGate.h"
# include "PWire.h"
# include <assert.h>
Module::Module(const string&name, const svector<Module::port_t*>*pp)
: name_(name)
{
if (pp) {
if (pp)
ports_ = *pp;
for (unsigned idx = 0 ; idx < ports_.count() ; idx += 1) {
port_t*cur = ports_[idx];
if (cur == 0)
continue;
for (unsigned jdx = 0 ; jdx < cur->wires.count() ; jdx += 1)
add_wire(cur->wires[jdx]);
}
}
}
void Module::add_gate(PGate*gate)
@@ -53,9 +50,14 @@ void Module::add_function(const string &name, PFunction *func)
funcs_[name] = func;
}
void Module::add_wire(PWire*wire)
PWire* Module::add_wire(PWire*wire)
{
wires_.push_back(wire);
PWire*&ep = wires_[wire->name()];
if (ep) return ep;
assert(ep == 0);
ep = wire;
return wire;
}
void Module::add_behavior(PProcess*b)
@@ -68,10 +70,20 @@ unsigned Module::port_count() const
return ports_.count();
}
const svector<PWire*>& Module::get_port(unsigned idx) const
/*
* Return the array of PEIdent object that are at this port of the
* module. If the port is internally unconnected, return an empty
* array.
*/
const svector<PEIdent*>& Module::get_port(unsigned idx) const
{
assert(idx < ports_.count());
return ports_[idx]->wires;
static svector<PEIdent*> zero;
if (ports_[idx])
return ports_[idx]->expr;
else
return zero;
}
unsigned Module::find_port(const string&name) const
@@ -85,22 +97,73 @@ unsigned Module::find_port(const string&name) const
}
PWire* Module::get_wire(const string&name)
PWire* Module::get_wire(const string&name) const
{
for (list<PWire*>::iterator cur = wires_.begin()
; cur != wires_.end()
map<string,PWire*>::const_iterator obj = wires_.find(name);
if (obj == wires_.end())
return 0;
else
return (*obj).second;
}
PGate* Module::get_gate(const string&name)
{
for (list<PGate*>::iterator cur = gates_.begin()
; cur != gates_.end()
; cur ++ ) {
if ((*cur)->name() == name)
if ((*cur)->get_name() == name)
return *cur;
}
return 0;
}
const map<string,PWire*>& Module::get_wires() const
{
return wires_;
}
const list<PGate*>& Module::get_gates() const
{
return gates_;
}
const list<PProcess*>& Module::get_behaviors() const
{
return behaviors_;
}
/*
* $Log: Module.cc,v $
* 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)
*
* Revision 1.14 2000/11/15 20:31:05 steve
* Fix warning about temporaries.
*
* Revision 1.13 2000/11/05 06:05:59 steve
* Handle connectsion to internally unconnected modules (PR#38)
*
* Revision 1.12 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.11 2000/03/12 17:09:40 steve
* Support localparam.
*
* Revision 1.10 2000/02/23 02:56:53 steve
* Macintosh compilers do not support ident.
*
* Revision 1.9 2000/01/09 20:37:57 steve
* Careful with wires connected to multiple ports.
*
* Revision 1.8 1999/12/11 05:45:41 steve
* Fix support for attaching attributes to primitive gates.
*
* Revision 1.7 1999/09/17 02:06:25 steve
* Handle unconnected module ports.
*
+81 -14
View File
@@ -1,7 +1,7 @@
#ifndef __Module_H
#define __Module_H
/*
* Copyright (c) 1998 Stephen Williams ([email protected])
* Copyright (c) 1998-2000 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,15 +18,18 @@
* 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: Module.h,v 1.10 1999/11/27 19:07:57 steve Exp $"
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: Module.h,v 1.21 2000/11/05 06:05:59 steve Exp $"
#endif
# include <list>
# include <map>
# include "svector.h"
# include "named.h"
# include <string>
class PEvent;
class PExpr;
class PEIdent;
class PGate;
class PTask;
class PFunction;
@@ -51,9 +54,7 @@ class Module {
public:
struct port_t {
string name;
svector<PWire*>wires;
port_t(int c=0) : wires(c) { }
svector<PEIdent*> expr;
};
public:
@@ -64,6 +65,13 @@ class Module {
module is elaborated. During parsing, I put the parameters
into this map. */
map<string,PExpr*>parameters;
map<string,PExpr*>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;
/* Parameters may be overridden at instantiation time;
the overrides do not contain explicit parameter names,
@@ -73,34 +81,54 @@ class Module {
a parameter-index to its name. */
list<string> param_names;
/* Keep a table of named events declared in the module. */
map<string,PEvent*>events;
/* These are the timescale for this module. The default is
set by the `timescale directive. */
int time_unit, time_precision;
const string&get_name() const { return name_; }
void add_gate(PGate*gate);
void add_wire(PWire*wire);
// The add_wire method adds a wire by name, but only if the
// wire name doesn't already exist. Either way, the result is
// the existing wire or the pointer passed in.
PWire* add_wire(PWire*wire);
void add_behavior(PProcess*behave);
void add_task(const string&name, PTask*def);
void add_function(const string&name, PFunction*def);
unsigned port_count() const;
const svector<PWire*>& get_port(unsigned idx) const;
const svector<PEIdent*>& get_port(unsigned idx) const;
unsigned find_port(const string&) const;
// Find a wire by name. This is used for connecting gates to
// existing wires, etc.
PWire* get_wire(const string&name);
PWire* get_wire(const string&name) const;
PGate* get_gate(const string&name);
const list<PWire*>& get_wires() const { return wires_; }
const list<PGate*>& get_gates() const { return gates_; }
const list<PProcess*>& get_behaviors() const { return behaviors_; }
const map<string,PWire*>& get_wires() const;
const list<PGate*>& get_gates() const;
const list<PProcess*>& get_behaviors() const;
void dump(ostream&out) const;
bool elaborate(Design*, NetScope*scope, svector<PExpr*>*overrides_) const;
bool elaborate(Design*, NetScope*scope) const;
bool elaborate_scope(Design*, NetScope*scope) const;
bool elaborate_sig(Design*, NetScope*scope) const;
private:
const string name_;
/* This is an array of port descriptors, which is in turn a
named array of PEident pointers. */
svector<port_t*> ports_;
list<PWire*> wires_;
map<string,PWire*> wires_;
list<PGate*> gates_;
list<PProcess*> behaviors_;
map<string,PTask*> tasks_;
@@ -114,6 +142,45 @@ class Module {
/*
* $Log: Module.h,v $
* Revision 1.21 2000/11/05 06:05:59 steve
* Handle connectsion to internally unconnected modules (PR#38)
*
* Revision 1.20 2000/07/22 22:09:03 steve
* Parse and elaborate timescale to scopes.
*
* Revision 1.19 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.18 2000/05/02 16:27:38 steve
* Move signal elaboration to a seperate pass.
*
* Revision 1.17 2000/04/01 19:31:57 steve
* Named events as far as the pform.
*
* Revision 1.16 2000/03/12 17:09:40 steve
* Support localparam.
*
* Revision 1.15 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.14 2000/02/23 02:56:53 steve
* Macintosh compilers do not support ident.
*
* Revision 1.13 2000/01/09 20:37:57 steve
* Careful with wires connected to multiple ports.
*
* Revision 1.12 2000/01/09 05:50:48 steve
* Support named parameter override lists.
*
* Revision 1.11 1999/12/11 05:45:41 steve
* Fix support for attaching attributes to primitive gates.
*
* Revision 1.10 1999/11/27 19:07:57 steve
* Support the creation of scopes.
*
+65 -19
View File
@@ -16,10 +16,14 @@
* 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: PDelays.cc,v 1.1 1999/09/04 19:11:46 steve Exp $"
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: PDelays.cc,v 1.5 2001/07/25 03:10:48 steve Exp $"
#endif
# include "config.h"
# include <iostream>
# include "PDelays.h"
# include "PExpr.h"
# include "verinum.h"
@@ -52,30 +56,56 @@ void PDelays::set_delays(const svector<PExpr*>*del)
delay_[idx] = (*del)[idx];
}
void PDelays::eval_delays(Design*des, const string&path,
unsigned long&rise_time,
unsigned long&fall_time,
unsigned long&decay_time) const
static unsigned long calculate_val(Design*des, const NetScope*scope,
const PExpr*expr)
{
verinum*dv;
assert(expr);
unsigned long val;
int shift = scope->time_unit() - des->get_precision();
if (verireal*dr = expr->eval_rconst(des, scope)) {
val = dr->as_long(shift);
delete dr;
} else {
verinum*dv = expr->eval_const(des, scope->name());
if (dv == 0) {
cerr << expr->get_line() << ": sorry: non-constant "
<< "delays not supported here: " << *expr << endl;
des->errors += 1;
return 0;
}
assert(dv);
val = dv->as_ulong();
val = des->scale_to_precision(val, scope);
delete dv;
}
return val;
}
void PDelays::eval_delays(Design*des, const string&path,
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();
if (delay_[0]) {
dv = delay_[0]->eval_const(des, path);
assert(dv);
rise_time = dv->as_ulong();
delete dv;
rise_time = calculate_val(des, scope, delay_[0]);
if (delay_[1]) {
dv = delay_[1]->eval_const(des, path);
assert(dv);
fall_time = dv->as_ulong();
delete dv;
fall_time = calculate_val(des, scope, delay_[1]);
if (delay_[2]) {
dv = delay_[2]->eval_const(des, path);
assert(dv);
decay_time = dv->as_ulong();
delete dv;
decay_time = calculate_val(des, scope, delay_[2]);
} else {
if (rise_time < fall_time)
decay_time = rise_time;
@@ -96,6 +126,22 @@ void PDelays::eval_delays(Design*des, const string&path,
/*
* $Log: PDelays.cc,v $
* 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)
*
* Revision 1.4 2001/01/20 02:15:50 steve
* apologize for not supporting non-constant delays.
*
* Revision 1.3 2001/01/14 23:04:55 steve
* Generalize the evaluation of floating point delays, and
* get it working with delay assignment statements.
*
* Allow parameters to be referenced by hierarchical name.
*
* Revision 1.2 2000/02/23 02:56:53 steve
* Macintosh compilers do not support ident.
*
* Revision 1.1 1999/09/04 19:11:46 steve
* Add support for delayed non-blocking assignments.
*
+15 -3
View File
@@ -18,15 +18,21 @@
* 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: PDelays.h,v 1.1 1999/09/04 19:11:46 steve Exp $"
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: PDelays.h,v 1.3 2001/01/16 02:44:17 steve Exp $"
#endif
# include "svector.h"
# include <string>
#ifdef HAVE_IOSFWD
# include <iosfwd>
#else
class ostream;
#endif
class Design;
class PExpr;
class ostream;
/*
* Various PForm objects can carry delays. These delays include rise,
@@ -60,6 +66,12 @@ ostream& operator << (ostream&o, const PDelays&);
/*
* $Log: PDelays.h,v $
* Revision 1.3 2001/01/16 02:44:17 steve
* Use the iosfwd header if available.
*
* Revision 1.2 2000/02/23 02:56:53 steve
* Macintosh compilers do not support ident.
*
* Revision 1.1 1999/09/04 19:11:46 steve
* Add support for delayed non-blocking assignments.
*
+51
View File
@@ -0,0 +1,51 @@
/*
* Copyright (c) 200Stephen 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: PEvent.cc,v 1.2 2001/07/25 03:10:48 steve Exp $"
#endif
# include "config.h"
# include "PEvent.h"
PEvent::PEvent(const string&n)
: name_(n)
{
}
PEvent::~PEvent()
{
}
string PEvent::name() const
{
return name_;
}
/*
* $Log: PEvent.cc,v $
* 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)
*
* Revision 1.1 2000/04/01 19:31:57 steve
* Named events as far as the pform.
*
*/
+68
View File
@@ -0,0 +1,68 @@
#ifndef __PEvent_H
#define __PEvent_H
/*
* Copyright (c) 2000 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: PEvent.h,v 1.4 2001/01/16 02:44:18 steve Exp $"
#endif
# include "LineInfo.h"
# include <string>
class Design;
class NetScope;
/*
* The PEvent class represents event objects. These are things that
* are declared in Verilog as ``event foo;''
*/
class PEvent : public LineInfo {
public:
explicit PEvent(const string&name);
~PEvent();
string name() const;
void elaborate_scope(Design*des, NetScope*scope) const;
private:
string name_;
private: // not implemented
PEvent(const PEvent&);
PEvent& operator= (const PEvent&);
};
/*
* $Log: PEvent.h,v $
* Revision 1.4 2001/01/16 02:44:18 steve
* Use the iosfwd header if available.
*
* Revision 1.3 2000/04/09 17:44:30 steve
* Catch event declarations during scope elaborate.
*
* Revision 1.2 2000/04/04 03:20:15 steve
* Simulate named event trigger and waits.
*
* Revision 1.1 2000/04/01 19:31:57 steve
* Named events as far as the pform.
*
*/
#endif
+198 -12
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998 Stephen Williams <[email protected]>
* Copyright (c) 1998-1999 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
@@ -16,14 +16,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)
#ident "$Id: PExpr.cc,v 1.11 1999/10/31 04:11:27 steve Exp $"
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: PExpr.cc,v 1.24 2001/07/25 03:10:48 steve Exp $"
#endif
# include "config.h"
# include <iostream>
# include "PExpr.h"
# include "Module.h"
# include <typeinfo>
PExpr::PExpr()
{
}
PExpr::~PExpr()
{
}
@@ -41,16 +49,18 @@ bool PExpr::is_constant(Module*) const
NetNet* PExpr::elaborate_net(Design*des, const string&path, unsigned,
unsigned long,
unsigned long,
unsigned long) const
unsigned long,
Link::strength_t,
Link::strength_t) const
{
cerr << "Don't know how to elaborate `" << *this
<< "' as gates." << endl;
cerr << get_line() << ": error: Unable to elaborate `"
<< *this << "' as gates." << endl;
return 0;
}
NetNet* PExpr::elaborate_lnet(Design*des, const string&path) const
{
cerr << get_line() << ": expression not valid in assign l-value: "
cerr << get_line() << ": error: expression not valid in assign l-value: "
<< *this << endl;
return 0;
}
@@ -60,15 +70,25 @@ bool PEBinary::is_constant(Module*mod) const
return left_->is_constant(mod) && right_->is_constant(mod);
}
PECallFunction::PECallFunction(const string &n, const svector<PExpr *> &parms)
PECallFunction::PECallFunction(const char*n, const svector<PExpr *> &parms)
: name_(n), parms_(parms)
{
}
PECallFunction::PECallFunction(const char*n)
: name_(n)
{
}
PECallFunction::~PECallFunction()
{
}
PEConcat::PEConcat(const svector<PExpr*>&p, PExpr*r)
: parms_(p), repeat_(r)
{
}
bool PEConcat::is_constant(Module *mod) const
{
bool constant = repeat_? repeat_->is_constant(mod) : true;
@@ -83,14 +103,91 @@ PEConcat::~PEConcat()
delete repeat_;
}
PEEvent::PEEvent(PEEvent::edge_t t, PExpr*e)
: type_(t), expr_(e)
{
}
PEEvent::~PEEvent()
{
}
PEEvent::edge_t PEEvent::type() const
{
return type_;
}
PExpr* PEEvent::expr() const
{
return expr_;
}
PEFNumber::PEFNumber(verireal*v)
: value_(v)
{
}
PEFNumber::~PEFNumber()
{
delete value_;
}
const verireal& PEFNumber::value() const
{
return *value_;
}
bool PEFNumber::is_constant(Module*) const
{
return true;
}
PEIdent::PEIdent(const string&s)
: text_(s), msb_(0), lsb_(0), idx_(0)
{
}
PEIdent::~PEIdent()
{
}
string PEIdent::name() const
{
return text_;
}
/*
* An identifier can be in a constant expresion if (and only if) it is
* a parameter.
*/
bool PEIdent::is_constant(Module*mod) const
{
map<string,PExpr*>::const_iterator cur = mod->parameters.find(text_);
return cur != mod->parameters.end();
map<string,PExpr*>::const_iterator cur;
if (mod == 0) return false;
cur = mod->parameters.find(text_);
if (cur != mod->parameters.end()) return true;
cur = mod->localparams.find(text_);
if (cur != mod->localparams.end()) return true;
return false;
}
PENumber::PENumber(verinum*vp)
: value_(vp)
{
assert(vp);
}
PENumber::~PENumber()
{
delete value_;
}
const verinum& PENumber::value() const
{
return *value_;
}
bool PENumber::is_the_same(const PExpr*that) const
@@ -107,6 +204,20 @@ bool PENumber::is_constant(Module*) const
return true;
}
PEString::PEString(const string&s)
: text_(s)
{
}
PEString::~PEString()
{
}
string PEString::value() const
{
return text_;
}
bool PEString::is_constant(Module*) const
{
return true;
@@ -121,13 +232,88 @@ PETernary::~PETernary()
{
}
bool PETernary::is_constant(Module*) const
bool PETernary::is_constant(Module*m) const
{
return false;
return expr_->is_constant(m)
&& tru_->is_constant(m)
&& fal_->is_constant(m);
}
PEUnary::PEUnary(char op, PExpr*ex)
: op_(op), expr_(ex)
{
}
PEUnary::~PEUnary()
{
}
bool PEUnary::is_constant(Module*m) const
{
return expr_->is_constant(m);
}
/*
* $Log: PExpr.cc,v $
* 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)
*
* Revision 1.23 2001/01/14 23:04:55 steve
* Generalize the evaluation of floating point delays, and
* get it working with delay assignment statements.
*
* Allow parameters to be referenced by hierarchical name.
*
* Revision 1.22 2001/01/12 04:31:27 steve
* Handle error idents in constants not in any scope (PR#97)
*
* Revision 1.21 2000/12/16 19:03:30 steve
* Evaluate <= and ?: in parameter expressions (PR#81)
*
* Revision 1.20 2000/12/10 22:01:35 steve
* Support decimal constants in behavioral delays.
*
* Revision 1.19 2000/06/30 15:50:20 steve
* Allow unary operators in constant expressions.
*
* Revision 1.18 2000/05/07 04:37:55 steve
* Carry strength values from Verilog source to the
* pform and netlist for gates.
*
* 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.17 2000/05/04 03:37:58 steve
* Add infrastructure for system functions, move
* $time to that structure and add $random.
*
* Revision 1.16 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.15 2000/04/01 19:31:57 steve
* Named events as far as the pform.
*
* Revision 1.14 2000/03/12 18:22:11 steve
* Binary and unary operators in parameter expressions.
*
* Revision 1.13 2000/02/23 02:56:53 steve
* Macintosh compilers do not support ident.
*
* Revision 1.12 1999/12/31 17:38:37 steve
* Standardize some of the error messages.
*
* Revision 1.11 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
+273 -46
View File
@@ -1,7 +1,7 @@
#ifndef __PExpr_H
#define __PExpr_H
/*
* Copyright (c) 1998-1999 Stephen Williams <[email protected]>
* Copyright (c) 1998-2000 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,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)
#ident "$Id: PExpr.h,v 1.25 1999/11/21 00:13:08 steve Exp $"
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: PExpr.h,v 1.48 2001/01/14 23:04:55 steve Exp $"
#endif
# include <string>
@@ -32,6 +32,7 @@ class Design;
class Module;
class NetNet;
class NetExpr;
class NetScope;
/*
* The PExpr class hierarchy supports the description of
@@ -43,13 +44,21 @@ class NetExpr;
*/
class PExpr : public LineInfo {
public:
PExpr();
virtual ~PExpr();
virtual void dump(ostream&) const;
// Procedural elaboration of the expression.
virtual NetExpr*elaborate_expr(Design*des, const string&path) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope) const;
// Elaborate expressions that are the r-value of parameter
// assignments. This elaboration follows the restrictions of
// constant expressions and supports later overriding and
// evaluation of parameters.
virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
// This method elaborate the expression as gates, for use in a
// continuous assign or other wholly structural context.
@@ -57,17 +66,33 @@ class PExpr : public LineInfo {
unsigned lwidth,
unsigned long rise,
unsigned long fall,
unsigned long decay) const;
unsigned long decay,
Link::strength_t drive0 =Link::STRONG,
Link::strength_t drive1 =Link::STRONG)
const;
// This method elaborates the expression as NetNet objects. It
// only allows regs suitable for procedural continuous assignments.
virtual NetNet* elaborate_anet(Design*des, NetScope*scope) const;
// 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;
// Expressions that can be in the l-value of procedural
// assignments can be elaborated with this method.
virtual NetAssign_* elaborate_lval(Design*des, NetScope*scope) const;
// 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;
// This attempts to evaluate a constant expression as a
// decimal floating point. This is used when calculating delay
// constants.
virtual verireal* eval_rconst(const Design*, const NetScope*) const;
// This method returns true if that expression is the same as
// this expression. This method is used for comparing
// expressions that must be structurally "identical".
@@ -79,6 +104,9 @@ class PExpr : public LineInfo {
// of expresions.
virtual bool is_constant(Module*) const;
private: // not implemented
PExpr(const PExpr&);
PExpr& operator= (const PExpr&);
};
ostream& operator << (ostream&, const PExpr&);
@@ -86,18 +114,26 @@ ostream& operator << (ostream&, const PExpr&);
class PEConcat : public PExpr {
public:
PEConcat(const svector<PExpr*>&p, PExpr*r =0)
: parms_(p), repeat_(r) { }
PEConcat(const svector<PExpr*>&p, PExpr*r =0);
~PEConcat();
virtual void dump(ostream&) const;
// Concatenated Regs can be on the left of procedural
// 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,
unsigned width,
unsigned long rise,
unsigned long fall,
unsigned long decay) const;
virtual NetExpr*elaborate_expr(Design*des, const string&path) const;
unsigned long decay,
Link::strength_t drive0,
Link::strength_t drive1) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*) const;
virtual NetEConcat*elaborate_pexpr(Design*des, NetScope*) const;
virtual NetAssign_* elaborate_lval(Design*des, NetScope*scope) const;
virtual bool is_constant(Module*) const;
private:
@@ -105,48 +141,101 @@ class PEConcat : public PExpr {
PExpr*repeat_;
};
/*
* Event expressions are expressions that can be combined with the
* event "or" operator. These include "posedge foo" and similar, and
* also include named events. "edge" events are associated with an
* expression, whereas named events simply have a name, which
* represents an event variable.
*/
class PEEvent : public PExpr {
public:
PEEvent(NetNEvent::Type t, PExpr*e)
: type_(t), expr_(e)
{ }
enum edge_t {ANYEDGE, POSEDGE, NEGEDGE, POSITIVE};
NetNEvent::Type type() const { return type_; }
PExpr* expr() const { return expr_; }
// Use this constructor to create events based on edges or levels.
PEEvent(edge_t t, PExpr*e);
~PEEvent();
edge_t type() const;
PExpr* expr() const;
virtual void dump(ostream&) const;
private:
edge_t type_;
PExpr *expr_;
};
/*
* This holds a floating point constant in the source.
*/
class PEFNumber : public PExpr {
public:
explicit PEFNumber(verireal*vp);
~PEFNumber();
const verireal& value() const;
/* 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;
/* This method returns the full floating point value. */
virtual verireal* eval_rconst(const Design*, const NetScope*) const;
/* 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_pexpr(Design*des, NetScope*sc) const;
virtual void dump(ostream&) const;
private:
NetNEvent::Type type_;
PExpr*expr_;
verireal*value_;
};
class PEIdent : public PExpr {
public:
explicit PEIdent(const string&s)
: text_(s), msb_(0), lsb_(0), idx_(0) { }
explicit PEIdent(const string&s);
~PEIdent();
virtual void dump(ostream&) const;
// Regs can be on the left of procedural continuous assignments
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;
// 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,
unsigned lwidth,
unsigned long rise,
unsigned long fall,
unsigned long decay) const;
unsigned long decay,
Link::strength_t drive0,
Link::strength_t drive1) const;
virtual NetExpr*elaborate_expr(Design*des, const string&path) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*) const;
virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
// Elaborate the PEIdent as a port to a module. This method
// only applies to Ident expressions.
NetNet* elaborate_port(Design*des, NetScope*sc) const;
virtual bool is_constant(Module*) const;
verinum* eval_const(const Design*des, const string&path) const;
// XXXX
string name() const { return text_; }
string name() const;
private:
string text_;
@@ -170,19 +259,21 @@ class PEIdent : public PExpr {
class PENumber : public PExpr {
public:
explicit PENumber(verinum*vp)
: value_(vp) { assert(vp); }
~PENumber() { delete value_; }
explicit PENumber(verinum*vp);
~PENumber();
const verinum& value() const { return *value_; }
const verinum& value() const;
virtual void dump(ostream&) const;
virtual NetNet* elaborate_net(Design*des, const string&path,
unsigned lwidth,
unsigned long rise,
unsigned long fall,
unsigned long decay) const;
virtual NetExpr*elaborate_expr(Design*des, const string&path) const;
unsigned long decay,
Link::strength_t drive0,
Link::strength_t drive1) const;
virtual NetEConst*elaborate_expr(Design*des, NetScope*) const;
virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
virtual verinum* eval_const(const Design*des, const string&path) const;
virtual bool is_the_same(const PExpr*that) const;
@@ -195,12 +286,13 @@ class PENumber : public PExpr {
class PEString : public PExpr {
public:
explicit PEString(const string&s)
: text_(s) { }
explicit PEString(const string&s);
~PEString();
string value() const { return text_; }
string value() const;
virtual void dump(ostream&) const;
virtual NetExpr*elaborate_expr(Design*des, const string&path) const;
virtual NetEConst*elaborate_expr(Design*des, NetScope*) const;
virtual NetEConst*elaborate_pexpr(Design*des, NetScope*sc) const;
virtual bool is_constant(Module*) const;
@@ -211,16 +303,22 @@ class PEString : public PExpr {
class PEUnary : public PExpr {
public:
explicit PEUnary(char op, PExpr*ex)
: op_(op), expr_(ex) { }
explicit PEUnary(char op, PExpr*ex);
~PEUnary();
virtual void dump(ostream&out) const;
virtual NetNet* elaborate_net(Design*des, const string&path,
unsigned width,
unsigned long rise,
unsigned long fall,
unsigned long decay) const;
virtual NetExpr*elaborate_expr(Design*des, const string&path) const;
unsigned long decay,
Link::strength_t drive0,
Link::strength_t drive1) const;
virtual NetEUnary*elaborate_expr(Design*des, NetScope*) const;
virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
virtual verinum* eval_const(const Design*des, const string&path) const;
virtual bool is_constant(Module*) const;
private:
char op_;
@@ -240,8 +338,11 @@ class PEBinary : public PExpr {
unsigned width,
unsigned long rise,
unsigned long fall,
unsigned long decay) const;
virtual NetExpr*elaborate_expr(Design*des, const string&path) const;
unsigned long decay,
Link::strength_t drive0,
Link::strength_t drive1) const;
virtual NetEBinary*elaborate_expr(Design*des, NetScope*) const;
virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
virtual verinum* eval_const(const Design*des, const string&path) const;
private:
@@ -249,16 +350,43 @@ class PEBinary : public PExpr {
PExpr*left_;
PExpr*right_;
NetEBinary*elaborate_expr_base_(Design*, NetExpr*lp, NetExpr*rp) const;
NetNet* elaborate_net_add_(Design*des, const string&path,
unsigned lwidth,
unsigned long rise,
unsigned long fall,
unsigned long decay) const;
NetNet* elaborate_net_bit_(Design*des, const string&path,
unsigned lwidth,
unsigned long rise,
unsigned long fall,
unsigned long decay) const;
NetNet* elaborate_net_cmp_(Design*des, const string&path,
unsigned lwidth,
unsigned long rise,
unsigned long fall,
unsigned long decay) const;
NetNet* elaborate_net_div_(Design*des, const string&path,
unsigned lwidth,
unsigned long rise,
unsigned long fall,
unsigned long decay) const;
NetNet* elaborate_net_mod_(Design*des, const string&path,
unsigned lwidth,
unsigned long rise,
unsigned long fall,
unsigned long decay) const;
NetNet* elaborate_net_log_(Design*des, const string&path,
unsigned lwidth,
unsigned long rise,
unsigned long fall,
unsigned long decay) const;
NetNet* elaborate_net_mul_(Design*des, const string&path,
unsigned lwidth,
unsigned long rise,
unsigned long fall,
unsigned long decay) const;
NetNet* elaborate_net_shift_(Design*des, const string&path,
unsigned lwidth,
unsigned long rise,
@@ -281,10 +409,13 @@ class PETernary : public PExpr {
virtual void dump(ostream&out) const;
virtual NetNet* elaborate_net(Design*des, const string&path,
unsigned width,
unsigned long rise =0,
unsigned long fall =0,
unsigned long decay =0) const;
virtual NetExpr*elaborate_expr(Design*des, const string&path) const;
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_pexpr(Design*des, NetScope*sc) const;
virtual verinum* eval_const(const Design*des, const string&path) const;
private:
@@ -294,25 +425,121 @@ class PETernary : public PExpr {
};
/*
* This class represents a parsed call to a function.
* This class represents a parsed call to a function, including calls
* to system functions.
*/
class PECallFunction : public PExpr {
public:
explicit PECallFunction(const string &n, const svector<PExpr *> &parms);
explicit PECallFunction(const char*n, const svector<PExpr *> &parms);
explicit PECallFunction(const char*n);
~PECallFunction();
virtual void dump(ostream &) const;
virtual NetExpr*elaborate_expr(Design*des, const string&path) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope) const;
private:
string name_;
svector<PExpr *> parms_;
NetESFunc* elaborate_sfunc_(Design*des, const string&path) 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.
*
* Allow parameters to be referenced by hierarchical name.
*
* Revision 1.47 2000/12/16 19:03:30 steve
* Evaluate <= and ?: in parameter expressions (PR#81)
*
* Revision 1.46 2000/12/10 22:01:35 steve
* Support decimal constants in behavioral delays.
*
* Revision 1.45 2000/12/06 06:31:09 steve
* Check lvalue of procedural continuous assign (PR#29)
*
* Revision 1.44 2000/09/17 21:26:15 steve
* Add support for modulus (Eric Aardoom)
*
* Revision 1.43 2000/09/09 15:21:26 steve
* move lval elaboration to PExpr virtual methods.
*
* Revision 1.42 2000/09/07 22:38:13 steve
* Support unary + and - in constants.
*
* Revision 1.41 2000/06/30 15:50:20 steve
* Allow unary operators in constant expressions.
*
* Revision 1.40 2000/06/13 05:22:16 steve
* Support concatenation in parameter expressions.
*
* Revision 1.39 2000/06/01 02:31:39 steve
* Parameters can be strings.
*
* 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.37 2000/05/07 04:37:56 steve
* Carry strength values from Verilog source to the
* pform and netlist for gates.
*
* 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.
*
+29 -4
View File
@@ -16,14 +16,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)
#ident "$Id: PFunction.cc,v 1.2 1999/08/25 22:22:41 steve Exp $"
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: PFunction.cc,v 1.5 2001/07/25 03:10:48 steve Exp $"
#endif
# include "config.h"
#include "PTask.h"
PFunction::PFunction(svector<PWire*>*p, Statement*s)
: out_(0), ports_(p), statement_(s)
PFunction::PFunction()
: out_(0), ports_(0), statement_(0)
{
}
@@ -31,6 +33,19 @@ PFunction::~PFunction()
{
}
void PFunction::set_ports(svector<PWire *>*p)
{
assert(ports_ == 0);
ports_ = p;
}
void PFunction::set_statement(Statement*s)
{
assert(s != 0);
assert(statement_ == 0);
statement_ = s;
}
void PFunction::set_output(PWire*o)
{
assert(out_ == 0);
@@ -39,6 +54,16 @@ void PFunction::set_output(PWire*o)
/*
* $Log: PFunction.cc,v $
* 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)
*
* Revision 1.4 2001/01/13 22:20:08 steve
* Parse parameters within nested scopes.
*
* Revision 1.3 2000/02/23 02:56:53 steve
* Macintosh compilers do not support ident.
*
* Revision 1.2 1999/08/25 22:22:41 steve
* elaborate some aspects of functions.
*
+91 -3
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1999 Stephen Williams ([email protected])
* Copyright (c) 1999-2000 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
@@ -16,10 +16,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: PGate.cc,v 1.5 1999/09/14 01:50:35 steve Exp $"
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: PGate.cc,v 1.10 2001/07/25 03:10:48 steve Exp $"
#endif
# include "config.h"
# include "PGate.h"
# include "PExpr.h"
# include "verinum.h"
@@ -31,6 +33,8 @@ PGate::PGate(const string&name,
: name_(name), pins_(pins)
{
if (del) delay_.set_delays(del);
str0_ = STRONG;
str1_ = STRONG;
}
PGate::PGate(const string&name,
@@ -39,17 +43,45 @@ PGate::PGate(const string&name,
: name_(name), pins_(pins)
{
if (del) delay_.set_delay(del);
str0_ = STRONG;
str1_ = STRONG;
}
PGate::PGate(const string&name, svector<PExpr*>*pins)
: name_(name), pins_(pins)
{
str0_ = STRONG;
str1_ = STRONG;
}
PGate::~PGate()
{
}
PGate::strength_t PGate::strength0() const
{
return str0_;
}
void PGate::strength0(PGate::strength_t s)
{
str0_ = s;
}
PGate::strength_t PGate::strength1() const
{
return str1_;
}
void PGate::strength1(PGate::strength_t s)
{
str1_ = s;
}
void PGate::elaborate_scope(Design*, NetScope*) const
{
}
/*
* This method is used during elaboration to calculate the
* rise/fall/decay times for the gate. These values were set in pform
@@ -110,8 +142,64 @@ 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),
npins_(0), parms_(0), nparms_(0), msb_(0), lsb_(0)
{
}
PGModule::PGModule(const string&type, const string&name,
named<PExpr*>*pins, unsigned npins)
: PGate(name, 0), type_(type), overrides_(0), pins_(pins),
npins_(npins), parms_(0), nparms_(0), msb_(0), lsb_(0)
{
}
void PGModule::set_parameters(svector<PExpr*>*o)
{
assert(overrides_ == 0);
overrides_ = o;
}
void PGModule::set_parameters(named<PExpr*>*pa, unsigned npa)
{
assert(parms_ == 0);
assert(overrides_ == 0);
parms_ = pa;
nparms_ = npa;
}
void PGModule::set_range(PExpr*msb, PExpr*lsb)
{
assert(msb_ == 0);
assert(lsb_ == 0);
msb_ = msb;
lsb_ = lsb;
}
/*
* $Log: PGate.cc,v $
* 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)
*
* Revision 1.9 2000/05/06 15:41:56 steve
* Carry assignment strength to pform.
*
* Revision 1.8 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.7 2000/02/23 02:56:53 steve
* Macintosh compilers do not support ident.
*
* Revision 1.6 2000/02/18 05:15:02 steve
* Catch module instantiation arrays.
*
* Revision 1.5 1999/09/14 01:50:35 steve
* Handle gates without delays.
*
+81 -12
View File
@@ -1,7 +1,7 @@
#ifndef __PGate_H
#define __PGate_H
/*
* Copyright (c) 1998-1999 Stephen Williams ([email protected])
* Copyright (c) 1998-2000 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,16 +18,20 @@
* 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: PGate.h,v 1.10 1999/09/04 19:11:46 steve Exp $"
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: PGate.h,v 1.19 2001/04/22 23:09:45 steve Exp $"
#endif
# include "svector.h"
# include "named.h"
# include "LineInfo.h"
# include "PDelays.h"
# include <map>
# include <string>
class PExpr;
class PUdp;
class Design;
class NetScope;
class Module;
/*
@@ -38,10 +42,17 @@ class Module;
* This pins of a gate are connected to expressions. The elaboration
* step will need to convert expressions to a network of gates in
* order to elaborate expression inputs, but that can easily be done.
*
* The PGate base class also carries the strength0 and strength1
* strengths for those gates where the driver[s] can be described by a
* single strength pair. There is a strength of the 0 drive, and a
* strength of the 1 drive.
*/
class PGate : public LineInfo {
public:
enum strength_t { HIGHZ, WEAK, PULL, STRONG, SUPPLY };
explicit PGate(const string&name, svector<PExpr*>*pins,
const svector<PExpr*>*del);
@@ -62,8 +73,18 @@ class PGate : public LineInfo {
unsigned pin_count() const { return pins_? pins_->count() : 0; }
const PExpr*pin(unsigned idx) const { return (*pins_)[idx]; }
strength_t strength0() const;
strength_t strength1() const;
void strength0(strength_t);
void strength1(strength_t);
map<string,string> attributes;
virtual void dump(ostream&out) const;
virtual void elaborate(Design*des, const string&path) const;
virtual void elaborate_scope(Design*des, NetScope*sc) const;
virtual bool elaborate_sig(Design*des, NetScope*scope) const;
protected:
const svector<PExpr*>* get_pins() const { return pins_; }
@@ -76,6 +97,8 @@ class PGate : public LineInfo {
PDelays delay_;
svector<PExpr*>*pins_;
strength_t str0_, str1_;
private: // not implemented
PGate(const PGate&);
PGate& operator= (const PGate&);
@@ -151,35 +174,81 @@ class PGModule : public PGate {
// If the binding of ports is by position, this constructor
// builds everything all at once.
explicit PGModule(const string&type, const string&name,
svector<PExpr*>*overrides, svector<PExpr*>*pins)
: PGate(name, pins), type_(type), overrides_(overrides), pins_(0), npins_(0) { }
svector<PExpr*>*pins);
// If the binding of ports is by name, this constructor takes
// the bindings and stores them for later elaboration.
struct bind_t {
string name;
PExpr* parm;
};
explicit PGModule(const string&type, const string&name,
svector<PExpr*>*overrides, bind_t*pins, unsigned npins)
: PGate(name, 0), type_(type), overrides_(overrides), pins_(pins), npins_(npins) { }
named<PExpr*>*pins, unsigned npins);
// Parameter overrides can come as an ordered list, or a set
// of named expressions.
void set_parameters(svector<PExpr*>*o);
void set_parameters(named<PExpr*>*pa, unsigned npa);
// Modules can be instantiated in ranges. The parser uses this
// method to pass the range to the pform.
void set_range(PExpr*msb, PExpr*lsb);
virtual void dump(ostream&out) const;
virtual void elaborate(Design*, const string&path) const;
virtual void elaborate_scope(Design*des, NetScope*sc) const;
virtual bool elaborate_sig(Design*des, NetScope*scope) const;
private:
string type_;
svector<PExpr*>*overrides_;
bind_t*pins_;
named<PExpr*>*pins_;
unsigned npins_;
// These members support parameter override by name
named<PExpr*>*parms_;
unsigned nparms_;
// Arrays of modules are give if these are set.
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_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.19 2001/04/22 23:09:45 steve
* More UDP consolidation from Stephan Boettcher.
*
* Revision 1.18 2000/05/06 15:41:56 steve
* Carry assignment strength to pform.
*
* Revision 1.17 2000/05/02 16:27:38 steve
* Move signal elaboration to a seperate pass.
*
* Revision 1.16 2000/03/29 04:37:10 steve
* New and improved combinational primitives.
*
* Revision 1.15 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.14 2000/02/23 02:56:53 steve
* Macintosh compilers do not support ident.
*
* Revision 1.13 2000/02/18 05:15:02 steve
* Catch module instantiation arrays.
*
* Revision 1.12 2000/01/09 05:50:48 steve
* Support named parameter override lists.
*
* Revision 1.11 1999/12/11 05:45:41 steve
* Fix support for attaching attributes to primitive gates.
*
* Revision 1.10 1999/09/04 19:11:46 steve
* Add support for delayed non-blocking assignments.
*
+32 -4
View File
@@ -16,14 +16,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)
#ident "$Id: PTask.cc,v 1.2 1999/07/24 02:11:19 steve Exp $"
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: PTask.cc,v 1.6 2001/07/25 03:10:48 steve Exp $"
#endif
# include "config.h"
# include "PTask.h"
PTask::PTask(svector<PWire*>*p, Statement*s)
: ports_(p), statement_(s)
PTask::PTask()
: ports_(0), statement_(0)
{
}
@@ -31,8 +33,34 @@ PTask::~PTask()
{
}
void PTask::set_ports(svector<PWire*>*p)
{
assert(ports_ == 0);
ports_ = p;
}
void PTask::set_statement(Statement*s)
{
assert(statement_ == 0);
statement_ = s;
}
/*
* $Log: PTask.cc,v $
* 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)
*
* Revision 1.5 2001/04/19 03:04:47 steve
* Spurious assert of empty statemnt.
*
* Revision 1.4 2001/01/13 22:20:08 steve
* Parse parameters within nested scopes.
*
* Revision 1.3 2000/02/23 02:56:53 steve
* Macintosh compilers do not support ident.
*
* Revision 1.2 1999/07/24 02:11:19 steve
* Elaborate task input ports.
*
+49 -10
View File
@@ -1,7 +1,7 @@
#ifndef __PTask_H
#define __PTask_H
/*
* Copyright (c) 1999 Stephen Williams ([email protected])
* Copyright (c) 1999-2000 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,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)
#ident "$Id: PTask.h,v 1.6 1999/09/30 21:28:34 steve Exp $"
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: PTask.h,v 1.10 2001/01/13 22:20:08 steve Exp $"
#endif
# include "LineInfo.h"
# include "svector.h"
# include <string>
class Design;
class NetScope;
class PWire;
class Statement;
@@ -35,11 +36,23 @@ class Statement;
class PTask : public LineInfo {
public:
explicit PTask(svector<PWire*>*p, Statement*s);
explicit PTask();
~PTask();
void elaborate_1(Design*des, const string&path) const;
void elaborate_2(Design*des, const string&path) const;
void set_ports(svector<PWire *>*p);
void set_statement(Statement *s);
// Tasks introduce scope, to need to be handled during the
// scope elaboration pass. The scope passed is my scope,
// created by the containing scope. I fill it in with stuff if
// I need to.
void elaborate_scope(Design*des, NetScope*scope) const;
// Bind the ports to the regs that are the ports.
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 dump(ostream&, unsigned) const;
@@ -60,14 +73,20 @@ class PTask : public LineInfo {
class PFunction : public LineInfo {
public:
explicit PFunction(svector<PWire *>*p, Statement *s);
explicit PFunction();
~PFunction();
void set_ports(svector<PWire *>*p);
void set_statement(Statement *s);
void set_output(PWire*);
/* Functions are elaborated in 2 passes. */
void elaborate_1(Design *des, const string &path) const;
void elaborate_2(Design *des, const string &path) const;
void elaborate_scope(Design*des, NetScope*scope) const;
/* elaborate the ports and return value. */
void elaborate_sig(Design *des, NetScope*) const;
/* Elaborate the behavioral statement. */
void elaborate(Design *des, NetScope*) const;
void dump(ostream&, unsigned) const;
@@ -79,6 +98,26 @@ class PFunction : public LineInfo {
/*
* $Log: PTask.h,v $
* Revision 1.10 2001/01/13 22:20:08 steve
* Parse parameters within nested scopes.
*
* Revision 1.9 2000/07/30 18:25:43 steve
* Rearrange task and function elaboration so that the
* NetTaskDef and NetFuncDef functions are created during
* signal enaboration, and carry these objects in the
* NetScope class instead of the extra, useless map in
* the Design class.
*
* Revision 1.8 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.7 2000/02/23 02:56:53 steve
* Macintosh compilers do not support ident.
*
* Revision 1.6 1999/09/30 21:28:34 steve
* Handle mutual reference of tasks by elaborating
* task definitions in two passes, like functions.
+10 -4
View File
@@ -1,7 +1,7 @@
#ifndef __PUdp_H
#define __PUdp_H
/*
* Copyright (c) 1998 Stephen Williams ([email protected])
* Copyright (c) 1998-2000 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,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)
#ident "$Id: PUdp.h,v 1.3 1999/06/15 03:44:53 steve Exp $"
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: PUdp.h,v 1.5 2001/04/22 23:09:45 steve Exp $"
#endif
# include <map>
@@ -72,8 +72,8 @@ class PUdp {
void dump(ostream&out) const;
private:
const string name_;
private:
private: // Not implemented
PUdp(const PUdp&);
@@ -82,6 +82,12 @@ class PUdp {
/*
* $Log: PUdp.h,v $
* Revision 1.5 2001/04/22 23:09:45 steve
* More UDP consolidation from Stephan Boettcher.
*
* Revision 1.4 2000/02/23 02:56:53 steve
* Macintosh compilers do not support ident.
*
* Revision 1.3 1999/06/15 03:44:53 steve
* Get rid of the STL vector template.
*
+30 -6
View File
@@ -16,15 +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
*/
#if !defined(WINNT)
#ident "$Id: PWire.cc,v 1.2 1999/09/10 05:02:09 steve Exp $"
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: PWire.cc,v 1.6 2001/07/25 03:10:48 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), lidx_(0), ridx_(0)
: name_(n), type_(t), port_type_(pt), signed_(false), lidx_(0), ridx_(0)
{
}
@@ -43,11 +45,9 @@ bool PWire::set_wire_type(NetNet::Type t)
return true;
case NetNet::IMPLICIT_REG:
if (t == NetNet::REG) { type_ = t; return true; }
if (t == NetNet::INTEGER) {type_ = t; return true; }
return false;
case NetNet::REG:
if (t == NetNet::REG) return true;
if (t == NetNet::INTEGER) {type_ = t; return true; }
return false;
default:
if (type_ != t)
@@ -83,6 +83,16 @@ bool PWire::set_port_type(NetNet::PortType pt)
}
}
void PWire::set_signed(bool flag)
{
signed_ = flag;
}
bool PWire::get_signed() const
{
return signed_;
}
void PWire::set_range(PExpr*m, PExpr*l)
{
msb_ = svector<PExpr*>(msb_,m);
@@ -93,13 +103,27 @@ void PWire::set_memory_idx(PExpr*ldx, PExpr*rdx)
{
assert(lidx_ == 0);
assert(ridx_ == 0);
assert((type_ == NetNet::REG) || (type_ == NetNet::INTEGER));
assert(type_ == NetNet::REG);
lidx_ = ldx;
ridx_ = rdx;
}
/*
* $Log: PWire.cc,v $
* 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)
*
* Revision 1.5 2001/01/06 02:29:35 steve
* Support arrays of integers.
*
* Revision 1.4 2000/12/11 00:31:43 steve
* Add support for signed reg variables,
* simulate in t-vvm signed comparisons.
*
* Revision 1.3 2000/02/23 02:56:54 steve
* Macintosh compilers do not support ident.
*
* Revision 1.2 1999/09/10 05:02:09 steve
* Handle integers at task parameters.
*
+28 -5
View File
@@ -1,7 +1,7 @@
#ifndef __PWire_H
#define __PWire_H
/*
* Copyright (c) 1998 Stephen Williams ([email protected])
* Copyright (c) 1998-2000 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,15 +18,21 @@
* 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: PWire.h,v 1.6 1999/11/27 19:07:57 steve Exp $"
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: PWire.h,v 1.10 2001/01/16 02:44:18 steve Exp $"
#endif
# include "netlist.h"
# include "LineInfo.h"
# include <map>
# include <map>
# include "svector.h"
#ifdef HAVE_IOSFWD
# include <iosfwd>
#else
class ostream;
#endif
class PExpr;
class Design;
@@ -49,6 +55,9 @@ class PWire : public LineInfo {
NetNet::PortType get_port_type() const;
bool set_port_type(NetNet::PortType);
void set_signed(bool flag);
bool get_signed() const;
void set_range(PExpr*msb, PExpr*lsb);
void set_memory_idx(PExpr*ldx, PExpr*rdx);
@@ -58,12 +67,13 @@ class PWire : public LineInfo {
// Write myself to the specified stream.
void dump(ostream&out) const;
void elaborate(Design*, NetScope*scope) const;
void elaborate_sig(Design*, NetScope*scope) const;
private:
string name_;
NetNet::Type type_;
NetNet::PortType port_type_;
bool signed_;
// These members hold expressions for the bit width of the
// wire. If they do not exist, the wire is 1 bit wide.
@@ -82,6 +92,19 @@ class PWire : public LineInfo {
/*
* $Log: PWire.h,v $
* Revision 1.10 2001/01/16 02:44:18 steve
* Use the iosfwd header if available.
*
* Revision 1.9 2000/12/11 00:31:43 steve
* Add support for signed reg variables,
* simulate in t-vvm signed comparisons.
*
* Revision 1.8 2000/05/02 16:27:38 steve
* Move signal elaboration to a seperate pass.
*
* Revision 1.7 2000/02/23 02:56:54 steve
* Macintosh compilers do not support ident.
*
* Revision 1.6 1999/11/27 19:07:57 steve
* Support the creation of scopes.
*
+83
View File
@@ -0,0 +1,83 @@
* Getting Started with Icarus Verilog
Icarus Verilog is a Verilog compiler. It is suitable for use as a
simulator, and, to some degree, synthesizer. Icarus Verilog runs under
Linux and a variety of UNIX systems, as well as Windows as a command
line tool, so the instructions are generally applicable to all
environments. Note that this is only a quick start. For more detailed
documentation, see the manual page for the iverilog command.
* Hello, World!
The first thing you want to do as a user is learn how to compile and
execute even the most trivial design. For the purposes of simulation,
we use as our example *the* most trivial simulation:
module main;
initial
begin
$display("Hello, World");
$finish ;
end
endmodule
By a text editor (or copy hello.vl from the Icarus Verilog examples
directory) arrange for this program to be in a text file, "hello.vl".
Next, compile this program with a command like this:
% iverilog -o hello hello.vl
The results of this compile are placed into the file "hello", as the
"-o" flag tells the compiler where to place the compiled result. Next,
execute the compiled program like so:
% vvp hello
Hello, World
And there it is, the program has been executed. So what happened? The
first step, the "iverilog" command, read and interpreted the source
file, then generated a compiled result. The compiled form may be
selected by command line switches, but the default form is the VVP
format, which is actually run by the "vvp" command.
The "iverilog" and "vvp" commands are the only commands that users
use to invoke Icarus Verilog. What the compiler actually does is
controlled by command line switches. In our little example, we asked
the compiler to compile the source program to the default vvp form,
which is in turn executed by the vvp program.
* Windows Install
The easiest way to install under Windows is to get a precompiled
installer for the version you wish to install. Icarus Verilog is
distributed for Windows users as a self-installing .exe. Just execute
the installer and follow the instructions. During the install, take
note of the directory where the program is installed: for example,
C:\iverilog is a good place to install.
Once the binary is installed, you need to add the bin directory to
your execution path. The executables you need are in C:\iverilog\bin,
where the "C:\iverilog" part is actually the root of where you
installed the package. The programs are in the bin subdirectory. Put
this directory in your PATH environment variable, and the above
commands become accessible to you at the command line prompt, or even
in batch files.
* Linux Install
Under Linux, the install is even easier. For RedHat and Mandrake based
systems, there is the appropriate RPM file. Just install the package
with the "rpm -U <file>" command. Debian users should get Icarus
Verilog packages from the main Debian software site.
* Install From Source
In this case, see the readme and other documentation that comes with
the source.
+275 -160
View File
@@ -1,23 +1,28 @@
THE ICARUS VERILOG COMPILATION SYSTEM
September 18, 1999
September 17, 2000
1.0 What is ICARUS Verilog?
Icarus Verilog is intended to compile ALL of the Verilog HDL as described
in the IEEE-1364 standard. Of course, it's not quite there yet. It does
currently handle a mix of structural and behavioral constructs. For a
view of the current state of Icarus Verilog, see its home page at
<http://www.icarus.com/eda/verilog>.
Icarus Verilog is intended to compile ALL of the Verilog HDL as
described in the IEEE-1364 standard. Of course, it's not quite there
yet. It does currently handle a mix of structural and behavioral
constructs. For a view of the current state of Icarus Verilog, see its
home page at <http://www.icarus.com/eda/verilog>.
IVL 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
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, etc.
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.
2.0 Building/Installing IVL From Source
For instructions on how to run Icarus Verilog, see the ``iverilog''
man page.
2.0 Building/Installing Icarus Verilog From Source
If you are starting from source, the build process is designed to be
as simple as practical. Someone basically familiar with the target
@@ -31,16 +36,27 @@ You need the following software to compile Icarus Verilog from source
on a UNIX-like system:
- GNU Make
The Makefiles use some GNU extensions to, so a basic POSIX
The Makefiles use some GNU extensions, so a basic POSIX
make will not work. Linux systems typically come with a
satisfactory make.
satisfactory make. BSD based systems (i.e. NetBSD, FreeBSD)
typically have GNU make as the gmake program.
- ISO C++ Compiler
The ivl program is written in C++ and makes use of templates
and some of the standard C++ library. egcs compilers with
the associated libstdc++ are known to work.
The ivl and ivlpp programs are written in C++ and make use
of templates and some of the standard C++ library. egcs and
recent gcc compilers with the associated libstdc++ are known
to work. MSVC++ 5 and 6 are known to definitely *not* work.
- bison
- bison and flex
- gperf 2.7
The lexical analyzer doesn't recognize keywords directly,
but instead matches symbols and looks them up in a hash
table in order to get the proper lexical code. The gperf
program generates the lookup table.
A version problem with this program is the most common cause
of difficulty. See the Icarus Verilog FAQ.
2.2 Compilation
@@ -51,16 +67,48 @@ with the commands:
./configure
make
2.3 Installation
Normally, this command automatically figures out every thing it needs
to know. It generally works pretty well. There are a few flags to the
configure script that modify its behavior:
--without-ipal
This turns off support for Icarus PAL, whether ipal
libaries are installed or not.
--prefix=<root>
The default is /usr/local, which causes the tool suite to
be compiled for install in /usr/local/bin,
/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.
2.3 (Optional) Testing
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
by root.
2.4 Installation
Now install the files in an appropriate place. (The makefiles by
default install in /usr/local unless you specify a different prefix
with the --prefix=<path> flag to the configure command.) Do this as
root.
with the --prefix=<path> flag to the configure command.) You may need
to do this as root to gain access to installation directories.
make install
3.0 How IVL Works
2.5 Uninstallation
The generated Makefiles also include the uninstall target. This should
remove all the files that ``make install'' creates.
3.0 How Icarus Verilog Works
This tool includes a parser which reads in Verilog (plus extensions)
and generates an internal netlist. The netlist is passed to various
@@ -86,8 +134,8 @@ step. There may be dangling references, and it is not yet clear which
module is the root.
One can see a human readable version of the final PFORM by using the
``-P <path>'' flag to the compiler. This will cause ivl to dump the
PFORM into the file named <path>.
``-P <path>'' flag to the compiler. This will cause iverilog to dump
the PFORM into the file named <path>.
3.3 Elaboration
@@ -95,7 +143,8 @@ This phase takes the pform and generates a netlist. The driver selects
(by user request or lucky guess) the root module to elaborate,
resolves references and expands the instantiations to form the design
netlist. (See netlist.txt.) Final semantic checks are performed during
elaboration, and some simple optimizations are performed.
elaboration, and some simple optimizations are performed. The netlist
includes all the behavioral descriptions, as well as gates and wires.
The elaborate() function performs the elaboration.
@@ -104,6 +153,31 @@ optimized netlist by using the ``-N <path>'' flag to the compiler. If
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
first, followed by the structural and behavioral elaboration.
3.3.1 Scope Elaboration
This pass scans through the pform looking for scopes and parameters. A
tree of NetScope objects is built up and placed in the Design object,
with the root module represented by the root NetScope object. The
elab_scope.cc and elab_pexpr.cc files contain most of the code for
handling this phase.
The tail of the elaborate_scope behavior (after the pform is
traversed) includes a scan of the NetScope tree to locate defparam
assignments that were collected during scope elaboration. This is when
the defparam overrides are applied to the parameters.
3.3.2 Netlist Elaboration
After the scopes and parameters are generated and the NetScope tree
fully formed, the elaboration runs through the pform again, this time
generating the structural and behavioral netlist. Parameters are
elaborated and evaluated by now so all the constants of code
generation are now known locally, so the netlist can be generated by
simply passing through the pform.
3.4 Optimization
This is actually a collection of processing steps that perform
@@ -114,7 +188,7 @@ some useful transformations would be,
- combinational reduction
- Constant propagation
The actual functions performed are specified on the command line by
The actual functions performed are specified on the ivl command line by
the -F flags (See below).
3.5 Code Generation
@@ -127,76 +201,10 @@ The emit() method of the Design class performs this step. It runs
through the design elements, calling target functions as need arises
to generate actual output.
The target code generator to used is given by the -t flag on the
The user selects the target code generator with the -t flag on the
command line.
4.0 Running Verilog
The preferred way to invoke the compiler with the verilog(1)
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 verilog(1) man page for usage details.
4.1 Running IVL Directly
The ivl command is the compiler driver, that invokes the parser,
optimization functions and the code generator.
Usage: ivl <options>... file
ivl -h
-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.
-f <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.
-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.
-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 <name>
Select the output format for the compiled result. Use the
"ivl -h" command to get a list of configured targets.
-v
Print version and copyright information for ivl.
ATTRIBUTES
3.6 ATTRIBUTES
The parser accepts as an extension to Verilog the $attribute module
item. The syntax of the $attribute item is:
@@ -221,14 +229,105 @@ names a primitive earlier in the compilation unit and the statement is
placed in global scope, instead of within a module. The semicolon is
not part of a type attribute.
Currently, type attributes are only supported for UDP types.
Note that attributes are also occasionally used for communication
between processing steps. Processing steps that are aware of others
may place attributes on netlist objects to communicate information to
later steps.
4.1 EXAMPLES
4.0 Running iverilog
The preferred way to invoke the compiler is with the iverilog(1)
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
Example: Compiling "hello.vl"
@@ -245,45 +344,32 @@ endmodule
--------------------------------------------------------------
Insure that "verilog" is on your search path, and the vpi library
Insure that "iverilog" is on your search path, and the vpi library
is available.
For csh -
To compile the program:
setenv PATH /usr/local/bin:$PATH
setenv VPI_MODULE_PATH /usr/local/lib/ivl
verilog hello.vl
iverilog hello.vl
(The above presumes that /usr/local/include and /usr/local/lib are
part of the compiler search path, which is usually the case for gcc.)
To run the program
To run the program:
./hello
./a.out
You can use the "-o" switch to name the output command to be generated
by the compiler. See the iverilog(1) man page.
5.0 Unsupported Constructs
IVL 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, and does not account
for errors in the compiler. See the Icarus Verilog web page for the
current state of support for Verilog.
- Min/Typ/Max expressions: Example: a = (1 : 6 : 14);
- Memories work, but only in procedural code.
reg [1:0] b [2:0], bar;
wire [1:0] foo;
always foo = b[i]; // sorry
always @(i) bar = b[i]; // OK
- `timescale directive
- force/release/assign/deassign procedural assignments not
supported.
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,
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.:
@@ -293,62 +379,44 @@ current state of support for Verilog.
[...]
end
- fork/join is not supported in vvm runtime
- Structural shift operators are in general not supported.
Procedural expressions are OK. Constant expressions are OK.
assign foo = a << b; // sorry
always @(a or b) foo = a << b; // OK
parameter foo = a << b; // OK
- Functions in structural contexts are not supported.
assign foo = user_function(a,b); // sorry
always @(a or b) foo = user_function(a,b); // OK
- multiplicative operators (*, /, %) are not supported.
- real data types not supported. This includes real and
realtime. However, floating point constants in delay expressions
are supported so that `timescale works properly.
assign foo = a * b; // sorry
always @(a or b) foo = a * b; // sorry
- System functions are supported, but the compiler presumes that
they return 32 bits. This is the typical case.
- event data type is not supported.
- Specify blocks are parsed but ignored in general.
- real data type not supported.
- system functions are not supported. (User defined functions are
supported, and system tasks are supported.)
assign foo = $some_function(a,b); // sorry
always @(a or b) foo = $some_function(a,b); // sorry
- non-constant delay expressions, i.e.:
reg [7:0] del;
always #(reg) $display($time,,"del = %d", del); // sorry
- drive strengths are parsed, bug ignored.
Specify blocks are parsed but ignored in general.
- trireg is not supported. tri0 and tri1 are supported.
6.0 CREDITS
Except where otherwise noted, ivl and ivlpp are Copyright Stephen
Williams. The proper notices are in the head of each file. However,
I have received aid in the form of fixes, Verilog guidance, and
especially testing from many people, including (in alphabetical order):
Except where otherwise noted, Icarus Verilog, ivl and ivlpp are
Copyright Stephen Williams. The proper notices are in the head of each
file. However, I have early on received aid in the form of fixes,
Verilog guidance, and especially testing from many people, including
(in alphabetical order):
Eric Aardoom <[email protected]>
Stephan I. Boettcher <[email protected]>
Ed Carter <[email protected]>
Larry Doolittle <[email protected]>
Guy Hutchison <[email protected]>
Ales Hvezda <[email protected]>
James Lee <jml@seva.com>
Venkat Iyer <venkat@comit.com>
Yasuhisa Kato <[email protected]>
James Lee <[email protected]>
Peter Monta <[email protected]>
Daniel H. Nelsen <[email protected]>
Stefan Petersen <[email protected]>
Jason Schonberg <schon@mips.com>
Jason Schonberg <schonm@yahoo.com>
Stuart Sutherland <[email protected]>
Stephen Tell <[email protected]>
Stefan Theide <[email protected]>
@@ -357,3 +425,50 @@ especially testing from many people, including (in alphabetical order):
and others. Testers in particular include a larger community of people
interested in a GPL Verilog for Linux. Special thanks to Steve Wilson
for collecting and organizing the test suite code for all those testers.
6.1 PORT MAINTAINERS
This is a list of people who have created ports and precompiled
packages for various operating systems. These folks have graciously
taken on the task of building Icarus Verilog on their systems and
bundled it into neat packages.(+) If you want to be added to the list (or
removed from the list) send e-mail to me.
FreeBSD/{Intel,alpha}
Ying-Chieh Liao <[email protected]>
Linux/{alpha,Intel} (RPMS)
Stephen Williams <[email protected]>
Linux/* (.debs)
Hamish Moffatt <[email protected]>
Macintosh -- MacO/S
Yasuhisa Kato <[email protected]>
NetBSD/*
Dan McMahill <[email protected]>
Solaris/SPARC packages (.pkg)
Dan McMahill <[email protected]>
Cygwin32/*
Venkat Iyer <[email protected]>
Mingw32
Venkat Iyer <[email protected]>
(+) These are not the only systems where Icarus Verilog has been run,
just the systems where precompiled binaries are publicly available.
6.2 TEST SUITE MANAGER
Steve Wilson <[email protected]> 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.
+134 -3
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998 Stephen Williams ([email protected])
* Copyright (c) 1998-1999 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
@@ -16,10 +16,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: Statement.cc,v 1.16 1999/09/29 18:36:02 steve Exp $"
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: Statement.cc,v 1.23 2001/07/25 03:10:48 steve Exp $"
#endif
# include "config.h"
# include "Statement.h"
# include "PExpr.h"
@@ -122,6 +124,22 @@ PCase::~PCase()
delete[]items_;
}
PCAssign::PCAssign(PExpr*l, PExpr*r)
: lval_(l), expr_(r)
{
}
PCAssign::~PCAssign()
{
delete lval_;
delete expr_;
}
PCondit::PCondit(PExpr*ex, Statement*i, Statement*e)
: expr_(ex), if_(i), else_(e)
{
}
PCondit::~PCondit()
{
delete expr_;
@@ -129,6 +147,68 @@ PCondit::~PCondit()
delete else_;
}
PDeassign::PDeassign(PExpr*l)
: lval_(l)
{
}
PDeassign::~PDeassign()
{
delete lval_;
}
PDelayStatement::PDelayStatement(PExpr*d, Statement*st)
: delay_(d), statement_(st)
{
}
PDelayStatement::~PDelayStatement()
{
}
PDisable::PDisable(const string&sc)
: scope_(sc)
{
}
PDisable::~PDisable()
{
}
PEventStatement::PEventStatement(const svector<PEEvent*>&ee)
: expr_(ee), statement_(0)
{
}
PEventStatement::PEventStatement(PEEvent*ee)
: expr_(1), statement_(0)
{
expr_[0] = ee;
}
PEventStatement::~PEventStatement()
{
// delete the events and the statement?
}
void PEventStatement::set_statement(Statement*st)
{
statement_ = st;
}
PForce::PForce(PExpr*l, PExpr*r)
: lval_(l), expr_(r)
{
}
PForce::~PForce()
{
delete lval_;
delete expr_;
}
PForever::PForever(Statement*s)
: statement_(s)
{
@@ -144,6 +224,16 @@ PProcess::~PProcess()
delete statement_;
}
PRelease::PRelease(PExpr*l)
: lval_(l)
{
}
PRelease::~PRelease()
{
delete lval_;
}
PRepeat::PRepeat(PExpr*e, Statement*s)
: expr_(e), statement_(s)
{
@@ -155,6 +245,15 @@ PRepeat::~PRepeat()
delete statement_;
}
PTrigger::PTrigger(const string&e)
: event_(e)
{
}
PTrigger::~PTrigger()
{
}
PWhile::~PWhile()
{
delete cond_;
@@ -163,6 +262,38 @@ PWhile::~PWhile()
/*
* $Log: Statement.cc,v $
* 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
*
+158 -15
View File
@@ -1,7 +1,7 @@
#ifndef __Statement_H
#define __Statement_H
/*
* Copyright (c) 1998 Stephen Williams ([email protected])
* Copyright (c) 1998-2000 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,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)
#ident "$Id: Statement.h,v 1.20 1999/09/29 18:36:02 steve Exp $"
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: Statement.h,v 1.29 2000/09/09 15:21:26 steve Exp $"
#endif
# include <string>
@@ -30,6 +30,11 @@
class PExpr;
class Statement;
class PEventStatement;
class Design;
class NetAssign_;
class NetCAssign;
class NetDeassign;
class NetScope;
/*
* The PProcess is the root of a behavioral process. Each process gets
@@ -70,6 +75,7 @@ class Statement : public LineInfo {
virtual void dump(ostream&out, unsigned ind) const;
virtual NetProc* elaborate(Design*des, const string&path) const;
virtual void elaborate_scope(Design*des, NetScope*scope) const;
};
/*
@@ -88,9 +94,7 @@ class PAssign_ : public Statement {
const PExpr* rval() const { return rval_; }
protected:
NetNet*elaborate_lval(Design*, const string&path,
unsigned&lsb, unsigned&msb,
NetExpr*&mux) const;
NetAssign_* elaborate_lval(Design*, NetScope*scope) const;
PDelays delay_;
PEventStatement*event_;
@@ -155,6 +159,7 @@ class PBlock : public Statement {
virtual void dump(ostream&out, unsigned ind) const;
virtual NetProc* elaborate(Design*des, const string&path) const;
virtual void elaborate_scope(Design*des, NetScope*scope) const;
private:
string name_;
@@ -204,6 +209,7 @@ class PCase : public Statement {
~PCase();
virtual NetProc* elaborate(Design*des, const string&path) const;
virtual void elaborate_scope(Design*des, NetScope*scope) const;
virtual void dump(ostream&out, unsigned ind) const;
private:
@@ -217,14 +223,28 @@ class PCase : public Statement {
PCase& operator= (const PCase&);
};
class PCAssign : public Statement {
public:
explicit PCAssign(PExpr*l, PExpr*r);
~PCAssign();
virtual NetCAssign* elaborate(Design*des, const string&path) const;
virtual void dump(ostream&out, unsigned ind) const;
private:
PExpr*lval_;
PExpr*expr_;
};
class PCondit : public Statement {
public:
PCondit(PExpr*ex, Statement*i, Statement*e)
: expr_(ex), if_(i), else_(e) { }
PCondit(PExpr*ex, Statement*i, Statement*e);
~PCondit();
virtual NetProc* elaborate(Design*des, const string&path) const;
virtual void elaborate_scope(Design*des, NetScope*scope) const;
virtual void dump(ostream&out, unsigned ind) const;
private:
@@ -237,34 +257,72 @@ class PCondit : public Statement {
PCondit& operator= (const PCondit&);
};
class PDeassign : public Statement {
public:
explicit PDeassign(PExpr*l);
~PDeassign();
virtual NetDeassign* elaborate(Design*des, const string&path) const;
virtual void dump(ostream&out, unsigned ind) const;
private:
PExpr*lval_;
};
class PDelayStatement : public Statement {
public:
PDelayStatement(PExpr*d, Statement*st)
: delay_(d), statement_(st) { }
PDelayStatement(PExpr*d, Statement*st);
~PDelayStatement();
virtual void dump(ostream&out, unsigned ind) const;
virtual NetProc* elaborate(Design*des, const string&path) const;
virtual void elaborate_scope(Design*des, NetScope*scope) const;
private:
PExpr*delay_;
Statement*statement_;
};
/*
* This represends the parsing of a disable <scope> statement.
*/
class PDisable : public Statement {
public:
explicit PDisable(const string&sc);
~PDisable();
virtual void dump(ostream&out, unsigned ind) const;
virtual NetProc* elaborate(Design*des, const string&path) const;
private:
string scope_;
};
/*
* The event statement represents the event delay in behavioral
* code. It comes from such things as:
*
* @name <statement>;
* @(expr) <statement>;
*/
class PEventStatement : public Statement {
public:
PEventStatement(const svector<PEEvent*>&ee)
: expr_(ee), statement_(0) { }
explicit PEventStatement(const svector<PEEvent*>&ee);
explicit PEventStatement(PEEvent*ee);
PEventStatement(PEEvent*ee)
: expr_(1), statement_(0) { expr_[0] = ee; }
~PEventStatement();
void set_statement(Statement*st) { statement_ = st; }
void set_statement(Statement*st);
virtual void dump(ostream&out, unsigned ind) const;
virtual NetProc* elaborate(Design*des, const string&path) 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.
@@ -275,12 +333,27 @@ class PEventStatement : public Statement {
Statement*statement_;
};
class PForce : public Statement {
public:
explicit PForce(PExpr*l, PExpr*r);
~PForce();
virtual NetProc* elaborate(Design*des, const string&path) const;
virtual void dump(ostream&out, unsigned ind) const;
private:
PExpr*lval_;
PExpr*expr_;
};
class PForever : public Statement {
public:
explicit PForever(Statement*s);
~PForever();
virtual NetProc* elaborate(Design*des, const string&path) const;
virtual void elaborate_scope(Design*des, NetScope*scope) const;
virtual void dump(ostream&out, unsigned ind) const;
private:
@@ -297,6 +370,7 @@ class PForStatement : public Statement {
{ }
virtual NetProc* elaborate(Design*des, const string&path) const;
virtual void elaborate_scope(Design*des, NetScope*scope) const;
virtual void dump(ostream&out, unsigned ind) const;
private:
@@ -323,6 +397,7 @@ class PRepeat : public Statement {
~PRepeat();
virtual NetProc* elaborate(Design*des, const string&path) const;
virtual void elaborate_scope(Design*des, NetScope*scope) const;
virtual void dump(ostream&out, unsigned ind) const;
private:
@@ -330,6 +405,36 @@ class PRepeat : public Statement {
Statement*statement_;
};
class PRelease : public Statement {
public:
explicit PRelease(PExpr*l);
~PRelease();
virtual NetProc* elaborate(Design*des, const string&path) const;
virtual void dump(ostream&out, unsigned ind) const;
private:
PExpr*lval_;
};
/*
* The PTrigger statement sends a trigger to a named event. Take the
* name here.
*/
class PTrigger : public Statement {
public:
explicit PTrigger(const string&ev);
~PTrigger();
virtual NetProc* elaborate(Design*des, const string&path) const;
virtual void dump(ostream&out, unsigned ind) const;
private:
string event_;
};
class PWhile : public Statement {
public:
@@ -338,6 +443,7 @@ class PWhile : public Statement {
~PWhile();
virtual NetProc* elaborate(Design*des, const string&path) const;
virtual void elaborate_scope(Design*des, NetScope*scope) const;
virtual void dump(ostream&out, unsigned ind) const;
private:
@@ -347,6 +453,43 @@ class PWhile : public Statement {
/*
* $Log: Statement.h,v $
* Revision 1.29 2000/09/09 15:21:26 steve
* move lval elaboration to PExpr virtual methods.
*
* Revision 1.28 2000/09/03 17:58:35 steve
* Change elaborate_lval to return NetAssign_ objects.
*
* Revision 1.27 2000/07/26 05:08:07 steve
* Parse disable statements to pform.
*
* Revision 1.26 2000/05/11 23:37:26 steve
* Add support for procedural continuous assignment.
*
* Revision 1.25 2000/04/22 04:20:19 steve
* Add support for force assignment.
*
* Revision 1.24 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.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
*
+16
View File
@@ -0,0 +1,16 @@
#!/bin/sh
#
# This shell script exists to run autoconf on source distributions
# that are pulled from CVS. The configure scripts are not included
# in CVS, and there are several configure.in files, so it is easiest
# to just run this script to autoconf wherever needed.
#
echo "Autoconf in root..."
autoconf
for dir in vpip vvp tgt-vvp tgt-fpga
do
echo "Autoconf in $dir..."
( cd $dir ; autoconf )
done
+6
View File
@@ -0,0 +1,6 @@
# The make check target uses this to check the compilation of the
# compiler.
[-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 -- -
+49 -3
View File
@@ -1,7 +1,7 @@
#ifndef __compiler_H
#define __compiler_H
/*
* Copyright (c) 1999 Stephen Williams ([email protected])
* Copyright (c) 1999-2000 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,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)
#ident "$Id: compiler.h,v 1.1 1999/06/06 20:42:48 steve Exp $"
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: compiler.h,v 1.5 2000/10/31 17:49:02 steve Exp $"
#endif
/*
@@ -33,8 +33,54 @@
# define INTEGER_WIDTH 32
#endif
/* The TIME_WIDTH is the width of time variables. */
#ifndef TIME_WIDTH
# define TIME_WIDTH 64
#endif
/*
* When doing dynamic linking, we need a uniform way to identify the
* symbol. Some compilers put leading _, some trailing _. The
* configure script figures out which is the local convention and
* defines NEED_LU and NEED_TU as required.
*/
#ifdef NEED_LU
#define LU "_"
#else
#define LU ""
#endif
#ifdef NEED_TU
#define TU "_"
#else
#define TU ""
#endif
/*
* These are flags to enable various sorts of warnings. By default all
* the warnings are of, the -W<list> parameter arranges for each to be
* enabled.
*/
/* Implicit definitions of wires. */
extern bool warn_implicit;
/*
* $Log: compiler.h,v $
* Revision 1.5 2000/10/31 17:49:02 steve
* Support time variables.
*
* 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.3 2000/03/17 21:50:25 steve
* Switch to control warnings.
*
* Revision 1.2 2000/02/23 02:56:54 steve
* Macintosh compilers do not support ident.
*
* Revision 1.1 1999/06/06 20:42:48 steve
* Make compiler width a compile time constant.
*
+411 -140
View File
@@ -1,6 +1,7 @@
#! /bin/sh
# Attempt to guess a canonical system name.
# Copyright (C) 1992, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000
# Free Software Foundation, Inc.
#
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -22,7 +23,7 @@
# the same distribution terms that you use for the rest of that program.
# Written by Per Bothner <[email protected]>.
# The master version of this file is at the FSF in /home/gd/gnu/lib.
# Please send patches to <[email protected]>.
#
# This script attempts to guess a canonical system name similar to
# config.sub. If it succeeds, it prints the system name on stdout, and
@@ -35,6 +36,20 @@
# (but try to keep the structure clean).
#
# Use $HOST_CC if defined. $CC may point to a cross-compiler
if test x"$CC_FOR_BUILD" = x; then
if test x"$HOST_CC" != x; then
CC_FOR_BUILD="$HOST_CC"
else
if test x"$CC" != x; then
CC_FOR_BUILD="$CC"
else
CC_FOR_BUILD=cc
fi
fi
fi
# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
# ([email protected] 8/24/94.)
if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
@@ -46,11 +61,49 @@ UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
trap 'rm -f dummy.c dummy.o dummy; exit 1' 1 2 15
dummy=dummy-$$
trap 'rm -f $dummy.c $dummy.o $dummy; exit 1' 1 2 15
# Note: order is significant - the case branches are not exclusive.
case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
*:NetBSD:*:*)
# Netbsd (nbsd) targets should (where applicable) match one or
# more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
# *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
# switched to ELF, *-*-netbsd* would select the old
# object file format. This provides both forward
# compatibility and a consistent mechanism for selecting the
# object file format.
# Determine the machine/vendor (is the vendor relevant).
case "${UNAME_MACHINE}" in
amiga) machine=m68k-cbm ;;
arm32) machine=arm-unknown ;;
atari*) machine=m68k-atari ;;
sun3*) machine=m68k-sun ;;
mac68k) machine=m68k-apple ;;
macppc) machine=powerpc-apple ;;
hp3[0-9][05]) machine=m68k-hp ;;
ibmrt|romp-ibm) machine=romp-ibm ;;
*) machine=${UNAME_MACHINE}-unknown ;;
esac
# The Operating System including object format.
if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
| grep __ELF__ >/dev/null
then
# Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
# Return netbsd for either. FIX?
os=netbsd
else
os=netbsdelf
fi
# The OS release
release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
# contains redundant information, the shorter form:
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
echo "${machine}-${os}${release}"
exit 0 ;;
alpha:OSF1:*:*)
if test $UNAME_RELEASE = "V4.0"; then
UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
@@ -59,46 +112,62 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
# A Tn.n version is a released field test version.
# A Xn.n version is an unreleased experimental baselevel.
# 1.2 uses "1.2" for uname -r.
cat <<EOF >dummy.s
cat <<EOF >$dummy.s
.data
\$Lformat:
.byte 37,100,45,37,120,10,0 # "%d-%x\n"
.text
.globl main
.align 4
.ent main
main:
.frame \$30,0,\$26,0
.prologue 0
.long 0x47e03d80 # implver $0
lda \$2,259
.long 0x47e20c21 # amask $2,$1
srl \$1,8,\$2
sll \$2,2,\$2
sll \$0,3,\$0
addl \$1,\$0,\$0
addl \$2,\$0,\$0
ret \$31,(\$26),1
.frame \$30,16,\$26,0
ldgp \$29,0(\$27)
.prologue 1
.long 0x47e03d80 # implver \$0
lda \$2,-1
.long 0x47e20c21 # amask \$2,\$1
lda \$16,\$Lformat
mov \$0,\$17
not \$1,\$18
jsr \$26,printf
ldgp \$29,0(\$26)
mov 0,\$16
jsr \$26,exit
.end main
EOF
${CC-cc} dummy.s -o dummy 2>/dev/null
$CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null
if test "$?" = 0 ; then
./dummy
case "$?" in
7)
case `./$dummy` in
0-0)
UNAME_MACHINE="alpha"
;;
15)
1-0)
UNAME_MACHINE="alphaev5"
;;
14)
1-1)
UNAME_MACHINE="alphaev56"
;;
10)
1-101)
UNAME_MACHINE="alphapca56"
;;
16)
2-303)
UNAME_MACHINE="alphaev6"
;;
2-307)
UNAME_MACHINE="alphaev67"
;;
esac
fi
rm -f dummy.s dummy
echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr [[A-Z]] [[a-z]]`
rm -f $dummy.s $dummy
echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
exit 0 ;;
Alpha\ *:Windows_NT*:*)
# How do we know it's Interix rather than the generic POSIX subsystem?
# Should we change UNAME_MACHINE based on the output of uname instead
# of the specific Alpha model?
echo alpha-pc-interix
exit 0 ;;
21064:Windows_NT:50:3)
echo alpha-dec-winnt3.5
@@ -106,12 +175,12 @@ EOF
Amiga*:UNIX_System_V:4.0:*)
echo m68k-cbm-sysv4
exit 0;;
amiga:NetBSD:*:*)
echo m68k-cbm-netbsd${UNAME_RELEASE}
exit 0 ;;
amiga:OpenBSD:*:*)
echo m68k-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
*:[Aa]miga[Oo][Ss]:*:*)
echo ${UNAME_MACHINE}-unknown-amigaos
exit 0 ;;
arc64:OpenBSD:*:*)
echo mips64el-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
@@ -130,16 +199,16 @@ EOF
wgrisc:OpenBSD:*:*)
echo mipsel-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
*:OS/390:*:*)
echo i370-ibm-openedition
exit 0 ;;
arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
echo arm-acorn-riscix${UNAME_RELEASE}
exit 0;;
arm32:NetBSD:*:*)
echo arm-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
exit 0 ;;
SR2?01:HI-UX/MPP:*:*)
echo hppa1.1-hitachi-hiuxmpp
exit 0;;
Pyramid*:OSx*:*:*|MIS*:OSx*:*:*)
Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
# [email protected] (Earle F. Ake) contributed MIS and NILE.
if test "`(/bin/universe) 2>/dev/null`" = att ; then
echo pyramid-pyramid-sysv3
@@ -147,9 +216,12 @@ EOF
echo pyramid-pyramid-bsd
fi
exit 0 ;;
NILE:*:*:dcosx)
NILE*:*:*:dcosx)
echo pyramid-pyramid-svr4
exit 0 ;;
sun4H:SunOS:5.*:*)
echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit 0 ;;
sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit 0 ;;
@@ -189,21 +261,38 @@ EOF
aushp:SunOS:*:*)
echo sparc-auspex-sunos${UNAME_RELEASE}
exit 0 ;;
atari*:NetBSD:*:*)
echo m68k-atari-netbsd${UNAME_RELEASE}
exit 0 ;;
atari*:OpenBSD:*:*)
echo m68k-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
sun3*:NetBSD:*:*)
echo m68k-sun-netbsd${UNAME_RELEASE}
# The situation for MiNT is a little confusing. The machine name
# can be virtually everything (everything which is not
# "atarist" or "atariste" at least should have a processor
# > m68000). The system name ranges from "MiNT" over "FreeMiNT"
# to the lowercase version "mint" (or "freemint"). Finally
# the system name "TOS" denotes a system which is actually not
# MiNT. But MiNT is downward compatible to TOS, so this should
# be no problem.
atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
echo m68k-atari-mint${UNAME_RELEASE}
exit 0 ;;
atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
echo m68k-atari-mint${UNAME_RELEASE}
exit 0 ;;
*falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
echo m68k-atari-mint${UNAME_RELEASE}
exit 0 ;;
milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
echo m68k-milan-mint${UNAME_RELEASE}
exit 0 ;;
hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
echo m68k-hades-mint${UNAME_RELEASE}
exit 0 ;;
*:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
echo m68k-unknown-mint${UNAME_RELEASE}
exit 0 ;;
sun3*:OpenBSD:*:*)
echo m68k-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
mac68k:NetBSD:*:*)
echo m68k-apple-netbsd${UNAME_RELEASE}
exit 0 ;;
mac68k:OpenBSD:*:*)
echo m68k-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
@@ -225,12 +314,17 @@ EOF
VAX*:ULTRIX*:*:*)
echo vax-dec-ultrix${UNAME_RELEASE}
exit 0 ;;
2020:CLIX:*:*)
2020:CLIX:*:* | 2430:CLIX:*:*)
echo clipper-intergraph-clix${UNAME_RELEASE}
exit 0 ;;
mips:*:*:UMIPS | mips:*:*:RISCos)
sed 's/^ //' << EOF >dummy.c
int main (argc, argv) int argc; char **argv; {
sed 's/^ //' << EOF >$dummy.c
#ifdef __cplusplus
#include <stdio.h> /* for printf() prototype */
int main (int argc, char *argv[]) {
#else
int main (argc, argv) int argc; char *argv[]; {
#endif
#if defined (host_mips) && defined (MIPSEB)
#if defined (SYSTYPE_SYSV)
printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
@@ -245,10 +339,10 @@ EOF
exit (-1);
}
EOF
${CC-cc} dummy.c -o dummy \
&& ./dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
&& rm dummy.c dummy && exit 0
rm -f dummy.c dummy
$CC_FOR_BUILD $dummy.c -o $dummy \
&& ./$dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
&& rm $dummy.c $dummy && exit 0
rm -f $dummy.c $dummy
echo mips-mips-riscos${UNAME_RELEASE}
exit 0 ;;
Night_Hawk:Power_UNIX:*:*)
@@ -266,15 +360,18 @@ EOF
AViiON:dgux:*:*)
# DG/UX returns AViiON for all architectures
UNAME_PROCESSOR=`/usr/bin/uname -p`
if [ $UNAME_PROCESSOR = mc88100 -o $UNAME_PROCESSOR = mc88110 ] ; then
if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx \
-o ${TARGET_BINARY_INTERFACE}x = x ] ; then
if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
then
if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
[ ${TARGET_BINARY_INTERFACE}x = x ]
then
echo m88k-dg-dgux${UNAME_RELEASE}
else
else
echo m88k-dg-dguxbcs${UNAME_RELEASE}
fi
else
echo i586-dg-dgux${UNAME_RELEASE}
fi
else echo i586-dg-dgux${UNAME_RELEASE}
fi
exit 0 ;;
M88*:DolphinOS:*:*) # DolphinOS (SVR3)
echo m88k-dolphin-sysv3
@@ -300,7 +397,7 @@ EOF
exit 0 ;;
*:AIX:2:3)
if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
sed 's/^ //' << EOF >dummy.c
sed 's/^ //' << EOF >$dummy.c
#include <sys/systemcfg.h>
main()
@@ -311,8 +408,8 @@ EOF
exit(0);
}
EOF
${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0
rm -f dummy.c dummy
$CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm $dummy.c $dummy && exit 0
rm -f $dummy.c $dummy
echo rs6000-ibm-aix3.2.5
elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
echo rs6000-ibm-aix3.2.4
@@ -321,7 +418,8 @@ EOF
fi
exit 0 ;;
*:AIX:*:4)
if /usr/sbin/lsattr -EHl proc0 | grep POWER >/dev/null 2>&1; then
IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | head -1 | awk '{ print $1 }'`
if /usr/sbin/lsattr -EHl ${IBM_CPU_ID} | grep POWER >/dev/null 2>&1; then
IBM_ARCH=rs6000
else
IBM_ARCH=powerpc
@@ -339,7 +437,7 @@ EOF
ibmrt:4.4BSD:*|romp-ibm:BSD:*)
echo romp-ibm-bsd4.4
exit 0 ;;
ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC NetBSD and
ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and
echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
exit 0 ;; # report: romp-ibm BSD 4.3
*:BOSX:*:*)
@@ -354,18 +452,52 @@ EOF
hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
echo m68k-hp-bsd4.4
exit 0 ;;
9000/[3478]??:HP-UX:*:*)
9000/[34678]??:HP-UX:*:*)
case "${UNAME_MACHINE}" in
9000/31? ) HP_ARCH=m68000 ;;
9000/[34]?? ) HP_ARCH=m68k ;;
9000/7?? | 9000/8?[1679] ) HP_ARCH=hppa1.1 ;;
9000/8?? ) HP_ARCH=hppa1.0 ;;
9000/[678][0-9][0-9])
sed 's/^ //' << EOF >$dummy.c
#define _HPUX_SOURCE
#include <stdlib.h>
#include <unistd.h>
int main ()
{
#if defined(_SC_KERNEL_BITS)
long bits = sysconf(_SC_KERNEL_BITS);
#endif
long cpu = sysconf (_SC_CPU_VERSION);
switch (cpu)
{
case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
case CPU_PA_RISC2_0:
#if defined(_SC_KERNEL_BITS)
switch (bits)
{
case 64: puts ("hppa2.0w"); break;
case 32: puts ("hppa2.0n"); break;
default: puts ("hppa2.0"); break;
} break;
#else /* !defined(_SC_KERNEL_BITS) */
puts ("hppa2.0"); break;
#endif
default: puts ("hppa1.0"); break;
}
exit (0);
}
EOF
(CCOPTS= $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null ) && HP_ARCH=`./$dummy`
rm -f $dummy.c $dummy
esac
HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
echo ${HP_ARCH}-hp-hpux${HPUX_REV}
exit 0 ;;
3050*:HI-UX:*:*)
sed 's/^ //' << EOF >dummy.c
sed 's/^ //' << EOF >$dummy.c
#include <unistd.h>
int
main ()
@@ -390,8 +522,8 @@ EOF
exit (0);
}
EOF
${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0
rm -f dummy.c dummy
$CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm $dummy.c $dummy && exit 0
rm -f $dummy.c $dummy
echo unknown-hitachi-hiuxwe2
exit 0 ;;
9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
@@ -400,6 +532,9 @@ EOF
9000/8??:4.3bsd:*:*)
echo hppa1.0-hp-bsd
exit 0 ;;
*9??*:MPE/iX:*:*)
echo hppa1.0-hp-mpeix
exit 0 ;;
hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
echo hppa1.1-hp-osf
exit 0 ;;
@@ -416,6 +551,9 @@ EOF
parisc*:Lites*:*:*)
echo hppa1.1-hp-lites
exit 0 ;;
hppa*:OpenBSD:*:*)
echo hppa-unknown-openbsd
exit 0 ;;
C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
echo c1-convex-bsd
exit 0 ;;
@@ -446,45 +584,60 @@ EOF
-e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/
exit 0 ;;
CRAY*TS:*:*:*)
echo t90-cray-unicos${UNAME_RELEASE}
echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
exit 0 ;;
CRAY*T3E:*:*:*)
echo alpha-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
exit 0 ;;
CRAY*SV1:*:*:*)
echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
exit 0 ;;
CRAY-2:*:*:*)
echo cray2-cray-unicos
exit 0 ;;
F300:UNIX_System_V:*:*)
FUJITSU_SYS=`uname -p | tr [A-Z] [a-z] | sed -e 's/\///'`
FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
echo "f300-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
exit 0 ;;
F301:UNIX_System_V:*:*)
echo f301-fujitsu-uxpv`echo $UNAME_RELEASE | sed 's/ .*//'`
exit 0 ;;
hp3[0-9][05]:NetBSD:*:*)
echo m68k-hp-netbsd${UNAME_RELEASE}
exit 0 ;;
hp300:OpenBSD:*:*)
echo m68k-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
i?86:BSD/386:*:* | *:BSD/OS:*:*)
i?86:BSD/386:*:* | i?86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
exit 0 ;;
sparc*:BSD/OS:*:*)
echo sparc-unknown-bsdi${UNAME_RELEASE}
exit 0 ;;
*:BSD/OS:*:*)
echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
exit 0 ;;
*:FreeBSD:*:*)
echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
exit 0 ;;
*:NetBSD:*:*)
echo ${UNAME_MACHINE}-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
exit 0 ;;
*:OpenBSD:*:*)
echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
exit 0 ;;
i*:CYGWIN*:*)
echo i386-pc-cygwin32
echo ${UNAME_MACHINE}-pc-cygwin
exit 0 ;;
i*:MINGW*:*)
echo i386-pc-mingw32
echo ${UNAME_MACHINE}-pc-mingw32
exit 0 ;;
i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
# How do we know it's Interix rather than the generic POSIX subsystem?
# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
# UNAME_MACHINE based on the output of uname instead of i386?
echo i386-pc-interix
exit 0 ;;
i*:UWIN*:*)
echo ${UNAME_MACHINE}-pc-uwin
exit 0 ;;
p*:CYGWIN*:*)
echo powerpcle-unknown-cygwin32
echo powerpcle-unknown-cygwin
exit 0 ;;
prep*:SunOS:5.*:*)
echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
@@ -493,9 +646,11 @@ EOF
echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
exit 0 ;;
*:Linux:*:*)
# The BFD linker knows what the default object file format is, so
# first see if it will tell us.
ld_help_string=`ld --help 2>&1`
# first see if it will tell us. cd to the root directory to prevent
# problems with other programs or directories called `ld' in the path.
ld_help_string=`cd /; ld --help 2>&1`
ld_supported_emulations=`echo $ld_help_string \
| sed -ne '/supported emulations:/!d
s/[ ][ ]*/ /g
@@ -503,13 +658,45 @@ EOF
s/ .*//
p'`
case "$ld_supported_emulations" in
i?86linux) echo "${UNAME_MACHINE}-pc-linux-gnuaout" ; exit 0 ;;
i?86coff) echo "${UNAME_MACHINE}-pc-linux-gnucoff" ; exit 0 ;;
sparclinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;;
m68klinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;;
elf32ppc)
*ia64)
echo "${UNAME_MACHINE}-unknown-linux"
exit 0
;;
i?86linux)
echo "${UNAME_MACHINE}-pc-linux-gnuaout"
exit 0
;;
elf_i?86)
echo "${UNAME_MACHINE}-pc-linux"
exit 0
;;
i?86coff)
echo "${UNAME_MACHINE}-pc-linux-gnucoff"
exit 0
;;
sparclinux)
echo "${UNAME_MACHINE}-unknown-linux-gnuaout"
exit 0
;;
armlinux)
echo "${UNAME_MACHINE}-unknown-linux-gnuaout"
exit 0
;;
elf32arm*)
echo "${UNAME_MACHINE}-unknown-linux-gnuoldld"
exit 0
;;
armelf_linux*)
echo "${UNAME_MACHINE}-unknown-linux-gnu"
exit 0
;;
m68klinux)
echo "${UNAME_MACHINE}-unknown-linux-gnuaout"
exit 0
;;
elf32ppc | elf32ppclinux)
# Determine Lib Version
cat >dummy.c <<EOF
cat >$dummy.c <<EOF
#include <features.h>
#if defined(__GLIBC__)
extern char __libc_version[];
@@ -528,71 +715,85 @@ main(argc, argv)
}
EOF
LIBC=""
${CC-cc} dummy.c -o dummy 2>/dev/null
$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null
if test "$?" = 0 ; then
./dummy | grep 1\.99 > /dev/null
./$dummy | grep 1\.99 > /dev/null
if test "$?" = 0 ; then
LIBC="libc1"
fi
fi
rm -f dummy.c dummy
echo powerpc-unknown-linux-gnu${LIBC} ; exit 0 ;;
fi
rm -f $dummy.c $dummy
echo powerpc-unknown-linux-gnu${LIBC}
exit 0
;;
esac
if test "${UNAME_MACHINE}" = "alpha" ; then
sed 's/^ //' <<EOF >dummy.s
.globl main
.ent main
main:
.frame \$30,0,\$26,0
.prologue 0
.long 0x47e03d80 # implver $0
lda \$2,259
.long 0x47e20c21 # amask $2,$1
srl \$1,8,\$2
sll \$2,2,\$2
sll \$0,3,\$0
addl \$1,\$0,\$0
addl \$2,\$0,\$0
ret \$31,(\$26),1
.end main
cat <<EOF >$dummy.s
.data
\$Lformat:
.byte 37,100,45,37,120,10,0 # "%d-%x\n"
.text
.globl main
.align 4
.ent main
main:
.frame \$30,16,\$26,0
ldgp \$29,0(\$27)
.prologue 1
.long 0x47e03d80 # implver \$0
lda \$2,-1
.long 0x47e20c21 # amask \$2,\$1
lda \$16,\$Lformat
mov \$0,\$17
not \$1,\$18
jsr \$26,printf
ldgp \$29,0(\$26)
mov 0,\$16
jsr \$26,exit
.end main
EOF
LIBC=""
${CC-cc} dummy.s -o dummy 2>/dev/null
$CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null
if test "$?" = 0 ; then
./dummy
case "$?" in
7)
case `./$dummy` in
0-0)
UNAME_MACHINE="alpha"
;;
15)
1-0)
UNAME_MACHINE="alphaev5"
;;
14)
1-1)
UNAME_MACHINE="alphaev56"
;;
10)
1-101)
UNAME_MACHINE="alphapca56"
;;
16)
2-303)
UNAME_MACHINE="alphaev6"
;;
esac
2-307)
UNAME_MACHINE="alphaev67"
;;
esac
objdump --private-headers dummy | \
objdump --private-headers $dummy | \
grep ld.so.1 > /dev/null
if test "$?" = 0 ; then
LIBC="libc1"
fi
fi
rm -f dummy.s dummy
fi
rm -f $dummy.s $dummy
echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} ; exit 0
elif test "${UNAME_MACHINE}" = "mips" ; then
cat >dummy.c <<EOF
main(argc, argv)
int argc;
char *argv[];
{
cat >$dummy.c <<EOF
#ifdef __cplusplus
#include <stdio.h> /* for printf() prototype */
int main (int argc, char *argv[]) {
#else
int main (argc, argv) int argc; char *argv[]; {
#endif
#ifdef __MIPSEB__
printf ("%s-unknown-linux-gnu\n", argv[1]);
#endif
@@ -602,8 +803,10 @@ main(argc, argv)
return 0;
}
EOF
${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy "${UNAME_MACHINE}" && rm dummy.c dummy && exit 0
rm -f dummy.c dummy
$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm $dummy.c $dummy && exit 0
rm -f $dummy.c $dummy
elif test "${UNAME_MACHINE}" = "s390"; then
echo s390-ibm-linux && exit 0
else
# Either a pre-BFD a.out linker (linux-gnuoldld)
# or one that does not give us useful --help.
@@ -622,12 +825,14 @@ EOF
;;
esac
# Determine whether the default compiler is a.out or elf
cat >dummy.c <<EOF
cat >$dummy.c <<EOF
#include <features.h>
main(argc, argv)
int argc;
char *argv[];
{
#ifdef __cplusplus
#include <stdio.h> /* for printf() prototype */
int main (int argc, char *argv[]) {
#else
int main (argc, argv) int argc; char *argv[]; {
#endif
#ifdef __ELF__
# ifdef __GLIBC__
# if __GLIBC__ >= 2
@@ -644,8 +849,8 @@ main(argc, argv)
return 0;
}
EOF
${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy "${UNAME_MACHINE}" && rm dummy.c dummy && exit 0
rm -f dummy.c dummy
$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm $dummy.c $dummy && exit 0
rm -f $dummy.c $dummy
fi ;;
# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. earlier versions
# are messed up and put the nodename in both sysname and nodename.
@@ -661,10 +866,20 @@ EOF
echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
exit 0 ;;
i?86:*:4.*:* | i?86:SYSTEM_V:4.*:*)
UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
echo ${UNAME_MACHINE}-univel-sysv${UNAME_RELEASE}
echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
else
echo ${UNAME_MACHINE}-pc-sysv${UNAME_RELEASE}
echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
fi
exit 0 ;;
i?86:*:5:7*)
# Fixed at (any) Pentium or better
UNAME_MACHINE=i586
if [ ${UNAME_SYSTEM} = "UnixWare" ] ; then
echo ${UNAME_MACHINE}-sco-sysv${UNAME_RELEASE}uw${UNAME_VERSION}
else
echo ${UNAME_MACHINE}-pc-sysv${UNAME_RELEASE}
fi
exit 0 ;;
i?86:*:3.2:*)
@@ -676,12 +891,20 @@ EOF
(/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486
(/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \
&& UNAME_MACHINE=i586
(/bin/uname -X|egrep '^Machine.*Pent ?II' >/dev/null) \
&& UNAME_MACHINE=i686
(/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) \
&& UNAME_MACHINE=i686
echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
else
echo ${UNAME_MACHINE}-pc-sysv32
fi
exit 0 ;;
i?86:*DOS:*:*)
echo ${UNAME_MACHINE}-pc-msdosdjgpp
exit 0 ;;
pc:*:*:*)
# Left here for compatibility:
# uname -m prints for DJGPP always 'pc', but it prints nothing about
# the processor, so we play safe by assuming i386.
echo i386-pc-msdosdjgpp
@@ -722,7 +945,7 @@ EOF
mc68030:UNIX_System_V:4.*:*)
echo m68k-atari-sysv4
exit 0 ;;
i?86:LynxOS:2.*:*)
i?86:LynxOS:2.*:* | i?86:LynxOS:3.[01]*:*)
echo i386-unknown-lynxos${UNAME_RELEASE}
exit 0 ;;
TSUNAMI:LynxOS:2.*:*)
@@ -734,6 +957,9 @@ EOF
SM[BE]S:UNIX_SV:*:*)
echo mips-dde-sysv${UNAME_RELEASE}
exit 0 ;;
RM*:ReliantUNIX-*:*:*)
echo mips-sni-sysv4
exit 0 ;;
RM*:SINIX-*:*:*)
echo mips-sni-sysv4
exit 0 ;;
@@ -764,19 +990,61 @@ EOF
news*:NEWS-OS:*:6*)
echo mips-sony-newsos6
exit 0 ;;
R3000:*System_V*:*:* | R4000:UNIX_SYSV:*:*)
R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
if [ -d /usr/nec ]; then
echo mips-nec-sysv${UNAME_RELEASE}
else
echo mips-unknown-sysv${UNAME_RELEASE}
fi
exit 0 ;;
BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
echo powerpc-be-beos
exit 0 ;;
BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only.
echo powerpc-apple-beos
exit 0 ;;
BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
echo i586-pc-beos
exit 0 ;;
SX-4:SUPER-UX:*:*)
echo sx4-nec-superux${UNAME_RELEASE}
exit 0 ;;
SX-5:SUPER-UX:*:*)
echo sx5-nec-superux${UNAME_RELEASE}
exit 0 ;;
Power*:Rhapsody:*:*)
echo powerpc-apple-rhapsody${UNAME_RELEASE}
exit 0 ;;
*:Rhapsody:*:*)
echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
exit 0 ;;
*:Darwin:*:*)
echo `uname -p`-apple-darwin${UNAME_RELEASE}
exit 0 ;;
*:procnto*:*:* | *:QNX:[0123456789]*:*)
if test "${UNAME_MACHINE}" = "x86pc"; then
UNAME_MACHINE=pc
fi
echo `uname -p`-${UNAME_MACHINE}-nto-qnx
exit 0 ;;
*:QNX:*:4*)
echo i386-pc-qnx
exit 0 ;;
NSR-W:NONSTOP_KERNEL:*:*)
echo nsr-tandem-nsk${UNAME_RELEASE}
exit 0 ;;
BS2000:POSIX*:*:*)
echo bs2000-siemens-sysv
exit 0 ;;
DS/*:UNIX_System_V:*:*)
echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
exit 0 ;;
esac
#echo '(No uname command or uname output not recognized.)' 1>&2
#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
cat >dummy.c <<EOF
cat >$dummy.c <<EOF
#ifdef _SEQUENT_
# include <sys/types.h>
# include <sys/utsname.h>
@@ -814,7 +1082,10 @@ main ()
#endif
int version;
version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
if (version < 4)
printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
else
printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
exit (0);
#endif
@@ -874,8 +1145,8 @@ main ()
}
EOF
${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy && rm dummy.c dummy && exit 0
rm -f dummy.c dummy
$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy && rm $dummy.c $dummy && exit 0
rm -f $dummy.c $dummy
# Apollos put the system type in the environment.
+52
View File
@@ -0,0 +1,52 @@
#ifndef __config_H /* -*- c++ -*- */
#define __config_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
*/
#if !defined(WINNT)
#ident "$Id: config.h.in,v 1.1 2001/07/25 03:10:48 steve Exp $"
#endif
#if defined(__cplusplus)
# if !defined(__GNUC__)
using namespace std;
# elif (__GNUC__ == 3)
using namespace std;
# endif
#endif
# undef NEED_LU
# undef NEED_TU
# undef WLU
# undef WTU
# undef HAVE_TIMES
# undef HAVE_IOSFWD
# undef HAVE_GETOPT_H
# undef HAVE_DLFCN_H
# undef HAVE_DL_H
# undef HAVE_FCHMOD
# undef HAVE_LIBREADLINE
/*
* $Log: config.h.in,v $
* 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)
*
*/
#endif // __config_H
Vendored
+236 -146
View File
@@ -1,6 +1,8 @@
#! /bin/sh
# Configuration validation subroutine script, version 1.1.
# Copyright (C) 1991, 92, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000
# Free Software Foundation, Inc.
#
# This file is (in principle) common to ALL GNU software.
# The presence of a machine in this file suggests that SOME GNU software
# can handle that machine. It does not imply ALL GNU software can.
@@ -25,6 +27,9 @@
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# Written by Per Bothner <[email protected]>.
# Please send patches to <[email protected]>.
#
# Configuration subroutine to validate and canonicalize a configuration type.
# Supply the specified configuration type as an argument.
# If it is invalid, we print an error message on stderr and exit with code 1.
@@ -68,7 +73,7 @@ esac
# Here we must recognize all the valid KERNEL-OS combinations.
maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
case $maybe_os in
linux-gnu*)
nto-qnx* | linux-gnu*)
os=-$maybe_os
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
;;
@@ -98,21 +103,21 @@ case $os in
os=
basic_machine=$1
;;
-sim | -cisco | -oki | -wec | -winbond ) # CYGNUS LOCAL
-sim | -cisco | -oki | -wec | -winbond)
os=
basic_machine=$1
;;
-scout) # CYGNUS LOCAL
-scout)
;;
-wrs) # CYGNUS LOCAL
os=vxworks
-wrs)
os=-vxworks
basic_machine=$1
;;
-hiux*)
os=-hiuxwe2
;;
-sco5)
os=sco3.2v5
os=-sco3.2v5
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-sco4)
@@ -131,6 +136,9 @@ case $os in
os=-sco3.2v2
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-udk*)
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-isc)
os=-isc2.2
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
@@ -153,44 +161,40 @@ case $os in
-psos*)
os=-psos
;;
-mint | -mint[0-9]*)
basic_machine=m68k-atari
os=-mint
;;
esac
# Decode aliases for certain CPU-COMPANY combinations.
case $basic_machine in
# Recognize the basic CPU types without company name.
# Some are omitted here because they have special meanings below.
tahoe | i860 | m32r | m68k | m68000 | m88k | ns32k | arc | arm \
| arme[lb] | pyramid | mn10200 | mn10300 \
| tron | a29k | 580 | i960 | h8300 | hppa | hppa1.0 | hppa1.1 \
| alpha | alphaev5 | alphaev56 | we32k | ns16k | clipper \
| i370 | sh | powerpc | powerpcle | 1750a | dsp16xx | pdp11 \
| mips64 | mipsel | mips64el | mips64orion | mips64orionel \
| mipstx39 | mipstx39el \
| sparc | sparclet | sparclite | sparc64 | v850)
tahoe | i860 | ia64 | m32r | m68k | m68000 | m88k | ns32k | arc | arm \
| arme[lb] | pyramid | mn10200 | mn10300 | tron | a29k \
| 580 | i960 | h8300 \
| x86 | ppcbe | mipsbe | mipsle | shbe | shle | armbe | armle \
| hppa | hppa1.0 | hppa1.1 | hppa2.0 | hppa2.0w | hppa2.0n \
| hppa64 \
| alpha | alphaev[4-8] | alphaev56 | alphapca5[67] \
| alphaev6[78] \
| we32k | ns16k | clipper | i370 | sh | powerpc | powerpcle \
| 1750a | dsp16xx | pdp11 | mips16 | mips64 | mipsel | mips64el \
| mips64orion | mips64orionel | mipstx39 | mipstx39el \
| mips64vr4300 | mips64vr4300el | mips64vr4100 | mips64vr4100el \
| mips64vr5000 | miprs64vr5000el | mcore \
| sparc | sparclet | sparclite | sparc64 | sparcv9 | v850 | c4x \
| thumb | d10v | fr30 | avr)
basic_machine=$basic_machine-unknown
;;
m88110 | m680[01234]0 | m683?2 | m68360 | z8k | v70 | h8500 | w65) # CYGNUS LOCAL
basic_machine=$basic_machine-unknown
;;
mips64vr4300 | mips64vr4300el) # CYGNUS LOCAL jsmith/vr4300
basic_machine=$basic_machine-unknown
;;
mips64vr4100 | mips64vr4100el) # CYGNUS LOCAL jsmith/vr4100
basic_machine=$basic_machine-unknown
;;
mips64vr5000 | mips64vr5000el) # CYGNUS LOCAL ian/vr5000
basic_machine=$basic_machine-unknown
;;
mips16) # CYGNUS LOCAL krk/mips16
basic_machine=$basic_machine-unknown
;;
d10v) # CYGNUS LOCAL meissner/d10v
basic_machine=$basic_machine-unknown
m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | z8k | v70 | h8500 | w65 | pj | pjl)
;;
# We use `pc' rather than `unknown'
# because (1) that's what they normally are, and
# (2) the word "unknown" tends to confuse beginning users.
i[3456]86)
i[34567]86)
basic_machine=$basic_machine-pc
;;
# Object if more than one company name word.
@@ -199,30 +203,32 @@ case $basic_machine in
exit 1
;;
# Recognize the basic CPU types with company name.
vax-* | tahoe-* | i[3456]86-* | i860-* | m32r-* | m68k-* | m68000-* \
# FIXME: clean up the formatting here.
vax-* | tahoe-* | i[34567]86-* | i860-* | ia64-* | m32r-* | m68k-* | m68000-* \
| m88k-* | sparc-* | ns32k-* | fx80-* | arc-* | arm-* | c[123]* \
| mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* \
| power-* | none-* | 580-* | cray2-* | h8300-* | i960-* \
| xmp-* | ymp-* | hppa-* | hppa1.0-* | hppa1.1-* \
| alpha-* | alphaev5-* | alphaev56-* | we32k-* | cydra-* \
| ns16k-* | pn-* | np1-* | xps100-* | clipper-* | orion-* \
| power-* | none-* | 580-* | cray2-* | h8300-* | h8500-* | i960-* \
| xmp-* | ymp-* \
| x86-* | ppcbe-* | mipsbe-* | mipsle-* | shbe-* | shle-* | armbe-* | armle-* \
| hppa-* | hppa1.0-* | hppa1.1-* | hppa2.0-* | hppa2.0w-* \
| hppa2.0n-* | hppa64-* \
| alpha-* | alphaev[4-8]-* | alphaev56-* | alphapca5[67]-* \
| alphaev6[78]-* \
| we32k-* | cydra-* | ns16k-* | pn-* | np1-* | xps100-* \
| clipper-* | orion-* \
| sparclite-* | pdp11-* | sh-* | powerpc-* | powerpcle-* \
| sparc64-* | mips64-* | mipsel-* \
| sparc64-* | sparcv9-* | sparc86x-* | mips16-* | mips64-* | mipsel-* \
| mips64el-* | mips64orion-* | mips64orionel-* \
| mipstx39-* | mipstx39el-* \
| f301-*)
;;
m88110-* | m680[01234]0-* | m683?2-* | m68360-* | z8k-* | h8500-* | d10v-*) # CYGNUS LOCAL
;;
mips64vr4300-* | mips64vr4300el-*) # CYGNUS LOCAL jsmith/vr4300
;;
mips64vr4100-* | mips64vr4100el-*) # CYGNUS LOCAL jsmith/vr4100
;;
mips16-*) # CYGNUS LOCAL krk/mips16
| mips64vr4100-* | mips64vr4100el-* | mips64vr4300-* | mips64vr4300el-* \
| mipstx39-* | mipstx39el-* | mcore-* \
| f301-* | armv*-* | s390-* | sv1-* | t3e-* \
| m88110-* | m680[01234]0-* | m683?2-* | m68360-* | z8k-* | d10v-* \
| thumb-* | v850-* | d30v-* | tic30-* | c30-* | fr30-* \
| bs2000-*)
;;
# Recognize the various machine names and aliases which stand
# for a CPU type and a company and sometimes even an OS.
386bsd) # CYGNUS LOCAL
386bsd)
basic_machine=i386-unknown
os=-bsd
;;
@@ -232,11 +238,11 @@ case $basic_machine in
3b*)
basic_machine=we32k-att
;;
a29khif) # CYGNUS LOCAL
a29khif)
basic_machine=a29k-amd
os=-udi
;;
adobe68k) # CYGNUS LOCAL
adobe68k)
basic_machine=m68010-adobe
os=-scout
;;
@@ -269,7 +275,7 @@ case $basic_machine in
basic_machine=m68k-apollo
os=-sysv
;;
apollo68bsd) # CYGNUS LOCAL
apollo68bsd)
basic_machine=m68k-apollo
os=-bsd
;;
@@ -349,7 +355,7 @@ case $basic_machine in
encore | umax | mmax)
basic_machine=ns32k-encore
;;
es1800 | OSE68k | ose68k | ose | OSE) # CYGNUS LOCAL
es1800 | OSE68k | ose68k | ose | OSE)
basic_machine=m68k-ericsson
os=-ose
;;
@@ -371,11 +377,11 @@ case $basic_machine in
basic_machine=h8300-hitachi
os=-hms
;;
h8300xray) # CYGNUS LOCAL
h8300xray)
basic_machine=h8300-hitachi
os=-xray
;;
h8500hms) # CYGNUS LOCAL
h8500hms)
basic_machine=h8500-hitachi
os=-hms
;;
@@ -394,29 +400,30 @@ case $basic_machine in
basic_machine=m68k-hp
os=-hpux
;;
w89k-*) # CYGNUS LOCAL
basic_machine=hppa1.1-winbond
os=-proelf
;;
op50n-*) # CYGNUS LOCAL
basic_machine=hppa1.1-oki
os=-proelf
;;
op60c-*) # CYGNUS LOCAL
basic_machine=hppa1.1-oki
os=-proelf
;;
hppro) # CYGNUS LOCAL
basic_machine=hppa1.1-hp
os=-proelf
;;
hp3k9[0-9][0-9] | hp9[0-9][0-9])
basic_machine=hppa1.0-hp
;;
hp9k2[0-9][0-9] | hp9k31[0-9])
basic_machine=m68000-hp
;;
hp9k3[2-9][0-9])
basic_machine=m68k-hp
;;
hp9k7[0-9][0-9] | hp7[0-9][0-9] | hp9k8[0-9]7 | hp8[0-9]7)
hp9k6[0-9][0-9] | hp6[0-9][0-9])
basic_machine=hppa1.0-hp
;;
hp9k7[0-79][0-9] | hp7[0-79][0-9])
basic_machine=hppa1.1-hp
;;
hp9k78[0-9] | hp78[0-9])
# FIXME: really hppa2.0-hp
basic_machine=hppa1.1-hp
;;
hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
# FIXME: really hppa2.0-hp
basic_machine=hppa1.1-hp
;;
hp9k8[0-9][13679] | hp8[0-9][13679])
basic_machine=hppa1.1-hp
;;
hp9k8[0-9][0-9] | hp8[0-9][0-9])
@@ -425,43 +432,50 @@ case $basic_machine in
hppa-next)
os=-nextstep3
;;
hppaosf) # CYGNUS LOCAL
hppaosf)
basic_machine=hppa1.1-hp
os=-osf
;;
hppro)
basic_machine=hppa1.1-hp
os=-proelf
;;
i370-ibm* | ibm*)
basic_machine=i370-ibm
os=-mvs
;;
# I'm not sure what "Sysv32" means. Should this be sysv3.2?
i[3456]86v32)
i[34567]86v32)
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
os=-sysv32
;;
i[3456]86v4*)
i[34567]86v4*)
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
os=-sysv4
;;
i[3456]86v)
i[34567]86v)
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
os=-sysv
;;
i[3456]86sol2)
i[34567]86sol2)
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
os=-solaris2
;;
i386mach) # CYGNUS LOCAL
i386mach)
basic_machine=i386-mach
os=-mach
;;
i386-vsta | vsta) # CYGNUS LOCAL
i386-vsta | vsta)
basic_machine=i386-unknown
os=-vsta
;;
i386-go32 | go32) # CYGNUS LOCAL
i386-go32 | go32)
basic_machine=i386-unknown
os=-go32
;;
i386-mingw32 | mingw32)
basic_machine=i386-unknown
os=-mingw32
;;
iris | iris4d)
basic_machine=mips-sgi
case $os in
@@ -490,6 +504,10 @@ case $basic_machine in
miniframe)
basic_machine=m68000-convergent
;;
*mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
basic_machine=m68k-atari
os=-mint
;;
mipsel*-linux*)
basic_machine=mipsel-unknown
os=-linux-gnu
@@ -504,22 +522,34 @@ case $basic_machine in
mips3*)
basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
;;
monitor) # CYGNUS LOCAL
mmix*)
basic_machine=mmix-knuth
os=-mmixware
;;
monitor)
basic_machine=m68k-rom68k
os=-coff
;;
msdos) # CYGNUS LOCAL
basic_machine=i386-unknown
msdos)
basic_machine=i386-unknown
os=-msdos
;;
mvs)
basic_machine=i370-ibm
os=-mvs
;;
ncr3000)
basic_machine=i486-ncr
os=-sysv4
;;
netbsd386)
basic_machine=i386-unknown # CYGNUS LOCAL
basic_machine=i386-unknown
os=-netbsd
;;
netwinder)
basic_machine=armv4l-rebel
os=-linux
;;
news | news700 | news800 | news900)
basic_machine=m68k-sony
os=-newsos
@@ -532,7 +562,7 @@ case $basic_machine in
basic_machine=mips-sony
os=-newsos
;;
necv70) # CYGNUS LOCAL
necv70)
basic_machine=v70-nec
os=-sysv
;;
@@ -561,18 +591,25 @@ case $basic_machine in
basic_machine=i960-intel
os=-nindy
;;
mon960) # CYGNUS LOCAL
mon960)
basic_machine=i960-intel
os=-mon960
;;
np1)
basic_machine=np1-gould
;;
OSE68000 | ose68000) # CYGNUS LOCAL
nsr-tandem)
basic_machine=nsr-tandem
;;
op50n-* | op60c-*)
basic_machine=hppa1.1-oki
os=-proelf
;;
OSE68000 | ose68000)
basic_machine=m68000-ericsson
os=-ose
;;
os68k) # CYGNUS LOCAL
os68k)
basic_machine=m68k-none
os=-os68k
;;
@@ -593,25 +630,23 @@ case $basic_machine in
pc532 | pc532-*)
basic_machine=ns32k-pc532
;;
pentium | p5)
basic_machine=i586-intel
pentium | p5 | k5 | k6 | nexen)
basic_machine=i586-pc
;;
pentiumpro | p6)
basic_machine=i686-intel
pentiumpro | p6 | 6x86)
basic_machine=i686-pc
;;
pentium-* | p5-*)
pentiumii | pentium2)
basic_machine=i786-pc
;;
pentium-* | p5-* | k5-* | k6-* | nexen-*)
basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
pentiumpro-* | p6-*)
pentiumpro-* | p6-* | 6x86-*)
basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
k5)
# We don't have specific support for AMD's K5 yet, so just call it a Pentium
basic_machine=i586-amd
;;
nexen)
# We don't have specific support for Nexgen yet, so just call it a Pentium
basic_machine=i586-nexgen
pentiumii-* | pentium2-*)
basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
pn)
basic_machine=pn-gould
@@ -631,7 +666,7 @@ case $basic_machine in
ps2)
basic_machine=i386-ibm
;;
rom68k) # CYGNUS LOCAL
rom68k)
basic_machine=m68k-rom68k
os=-coff
;;
@@ -641,7 +676,7 @@ case $basic_machine in
rtpc | rtpc-*)
basic_machine=romp-ibm
;;
sa29200) # CYGNUS LOCAL
sa29200)
basic_machine=a29k-amd
os=-udi
;;
@@ -652,7 +687,7 @@ case $basic_machine in
basic_machine=sh-hitachi
os=-hms
;;
sparclite-wrs) # CYGNUS LOCAL
sparclite-wrs)
basic_machine=sparclite-wrs
os=-vxworks
;;
@@ -663,10 +698,10 @@ case $basic_machine in
spur)
basic_machine=spur-unknown
;;
st2000) # CYGNUS LOCAL
st2000)
basic_machine=m68k-tandem
;;
stratus) # CYGNUS LOCAL
stratus)
basic_machine=i860-stratus
os=-sysv4
;;
@@ -710,10 +745,18 @@ case $basic_machine in
sun386 | sun386i | roadrunner)
basic_machine=i386-sun
;;
sv1)
basic_machine=sv1-cray
os=-unicos
;;
symmetry)
basic_machine=i386-sequent
os=-dynix
;;
t3e)
basic_machine=t3e-cray
os=-unicos
;;
tx39)
basic_machine=mipstx39-unknown
;;
@@ -731,7 +774,7 @@ case $basic_machine in
basic_machine=a29k-nyu
os=-sym1
;;
v810 | necv810) # CYGNUS LOCAL
v810 | necv810)
basic_machine=v810-nec
os=-none
;;
@@ -758,9 +801,13 @@ case $basic_machine in
basic_machine=a29k-wrs
os=-vxworks
;;
w65*) # CYGNUS LOCAL
basic_machine=w65-wdc
os=-none
w65*)
basic_machine=w65-wdc
os=-none
;;
w89k-*)
basic_machine=hppa1.1-winbond
os=-proelf
;;
xmp)
basic_machine=xmp-cray
@@ -769,7 +816,7 @@ case $basic_machine in
xps | xps100)
basic_machine=xps100-honeywell
;;
z8k-*-coff) # CYGNUS LOCAL
z8k-*-coff)
basic_machine=z8k-unknown
os=-sim
;;
@@ -780,13 +827,13 @@ case $basic_machine in
# Here we handle the default manufacturer of certain CPU types. It is in
# some cases the only manufacturer, in others, it is the most popular.
w89k) # CYGNUS LOCAL
w89k)
basic_machine=hppa1.1-winbond
;;
op50n) # CYGNUS LOCAL
op50n)
basic_machine=hppa1.1-oki
;;
op60c) # CYGNUS LOCAL
op60c)
basic_machine=hppa1.1-oki
;;
mips)
@@ -811,7 +858,7 @@ case $basic_machine in
we32k)
basic_machine=we32k-att
;;
sparc)
sparc | sparcv9)
basic_machine=sparc-sun
;;
cydra)
@@ -823,12 +870,16 @@ case $basic_machine in
orion105)
basic_machine=clipper-highlevel
;;
mac | mpw | mac-mpw) # CYGNUS LOCAL
mac | mpw | mac-mpw)
basic_machine=m68k-apple
;;
pmac | pmac-mpw) # CYGNUS LOCAL
pmac | pmac-mpw)
basic_machine=powerpc-apple
;;
c4x*)
basic_machine=c4x-none
os=-coff
;;
*)
echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
exit 1
@@ -861,9 +912,12 @@ case $os in
-solaris)
os=-solaris2
;;
-unixware* | svr4*)
-svr4*)
os=-sysv4
;;
-unixware*)
os=-sysv4.2uw
;;
-gnu/linux*)
os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
;;
@@ -879,22 +933,34 @@ case $os in
| -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
| -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
| -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \
| -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* \
| -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
| -cygwin32* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
| -mingw32* | -linux-gnu* | -uxpv*)
| -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
| -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \
| -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \
| -openstep* | -oskit*)
# Remember, each alternative MUST END IN *, to match a version number.
;;
# CYGNUS LOCAL
-qnx*)
case $basic_machine in
x86-* | i[34567]86-*)
;;
*)
os=-nto$os
;;
esac
;;
-nto*)
os=-nto-qnx
;;
-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
| -windows* | -osx | -abug | -netware* | -os9* | -beos* \
| -macos* | -mpw* | -magic* | -mon960* | -lnews* )
| -windows* | -osx | -abug | -netware* | -os9* | -beos* \
| -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
;;
-mac*)
os=`echo $os | sed -e 's|mac|macos|'`
;;
# END CYGNUS LOCAL
-linux*)
os=`echo $os | sed -e 's|linux|linux-gnu|'`
;;
@@ -904,6 +970,12 @@ case $os in
-sunos6*)
os=`echo $os | sed -e 's|sunos6|solaris3|'`
;;
-opened*)
os=-openedition
;;
-wince*)
os=-wince
;;
-osfrose*)
os=-osfrose
;;
@@ -919,7 +991,7 @@ case $os in
-acis*)
os=-aos
;;
-386bsd) # CYGNUS LOCAL
-386bsd)
os=-bsd
;;
-ctix* | -uts*)
@@ -928,6 +1000,9 @@ case $os in
-ns2 )
os=-nextstep2
;;
-nsk)
os=-nsk
;;
# Preserve the version number of sinix5.
-sinix5.*)
os=`echo $os | sed -e 's|sinix|sysv|'`
@@ -953,15 +1028,18 @@ case $os in
# This must come after -sysvr4.
-sysv*)
;;
-ose*) # CYGNUS LOCAL
-ose*)
os=-ose
;;
-es1800*) # CYGNUS LOCAL
-es1800*)
os=-ose
;;
-xenix)
os=-xenix
;;
-*mint | -*MiNT)
os=-mint
;;
-none)
;;
*)
@@ -987,6 +1065,9 @@ case $basic_machine in
*-acorn)
os=-riscix1.2
;;
arm*-rebel)
os=-linux
;;
arm*-semi)
os=-aout
;;
@@ -1008,34 +1089,34 @@ case $basic_machine in
# default.
# os=-sunos4
;;
m68*-cisco) # CYGNUS LOCAL
m68*-cisco)
os=-aout
;;
mips*-cisco) # CYGNUS LOCAL
mips*-cisco)
os=-elf
;;
mips*-*)
os=-elf
;;
mips*-*) # CYGNUS LOCAL
os=-elf
;;
*-tti) # must be before sparc entry or we get the wrong os.
os=-sysv3
;;
sparc-* | *-sun)
os=-sunos4.1.1
;;
*-be) # CYGNUS LOCAL
*-be)
os=-beos
;;
*-ibm)
os=-aix
;;
*-wec) # CYGNUS LOCAL
*-wec)
os=-proelf
;;
*-winbond) # CYGNUS LOCAL
*-winbond)
os=-proelf
;;
*-oki) # CYGNUS LOCAL
*-oki)
os=-proelf
;;
*-hp)
@@ -1101,15 +1182,18 @@ case $basic_machine in
f301-fujitsu)
os=-uxpv
;;
*-rom68k) # CYGNUS LOCAL
*-rom68k)
os=-coff
;;
*-*bug) # CYGNUS LOCAL
*-*bug)
os=-coff
;;
*-apple) # CYGNUS LOCAL
*-apple)
os=-macos
;;
*-atari*)
os=-mint
;;
*)
os=-none
;;
@@ -1131,12 +1215,15 @@ case $basic_machine in
-aix*)
vendor=ibm
;;
-beos*) # CYGNUS LOCAL
-beos*)
vendor=be
;;
-hpux*)
vendor=hp
;;
-mpeix*)
vendor=hp
;;
-hiux*)
vendor=hitachi
;;
@@ -1152,7 +1239,7 @@ case $basic_machine in
-genix*)
vendor=ns
;;
-mvs*)
-mvs* | -opened*)
vendor=ibm
;;
-ptx*)
@@ -1164,12 +1251,15 @@ case $basic_machine in
-aux*)
vendor=apple
;;
-hms*) # CYGNUS LOCAL
-hms*)
vendor=hitachi
;;
-mpw* | -macos*) # CYGNUS LOCAL
-mpw* | -macos*)
vendor=apple
;;
-*mint | -*MiNT)
vendor=atari
;;
esac
basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
;;
+198 -2
View File
@@ -1,11 +1,207 @@
dnl Process this file with autoconf to produce a configure script.
AC_INIT(netlist.h)
AC_CONFIG_HEADER(config.h)
dnl Checks for programs.
AC_PROG_CC
AC_PROG_CXX
AC_CHECK_TOOL(STRIP, strip, true)
AC_CHECK_HEADERS(getopt.h)
AC_CHECK_PROGS(XGPERF,gperf,none)
if test "$XGPERF" = "none"
then
echo "*** Error: No suitable gperf found. ***"
echo " Please install the 'gperf' package."
exit 1
fi
AC_LANG_CPLUSPLUS
AC_CHECK_HEADERS(getopt.h iosfwd sys/wait.h)
AC_MSG_CHECKING(for sys/times)
AC_TRY_LINK(
#include <unistd.h>
#include <sys/times.h>
,{clock_t a = times(0)/sysconf(_SC_CLK_TCK);},
do_times=yes
AC_DEFINE(HAVE_TIMES,1),
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,
if test "$with_ipal" = no; then
echo Disabling ipal support
HAVE_IPAL=
fi
)
AC_SUBST(HAVE_IPAL)
# --
# Look for a dl library to use. First look for the standard dlopen
# functions, and failing that look for the HP specific shl_load function.
AC_CHECK_HEADERS(dlfcn.h dl.h, break)
DLLIB=''
AC_CHECK_LIB(dl,dlopen,[DLLIB=-ldl])
if test -z "$DLLIB" ; then
AC_CHECK_LIB(dld,shl_load,[DLLIB=-ldld])
fi
AC_SUBST(DLLIB)
AC_PROG_INSTALL
AC_OUTPUT(Makefile vpi/Makefile ivlpp/Makefile vvm/Makefile)
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.
AC_MSG_CHECKING("for flag to make position independent code")
PICFLAG=-fPIC
case "${host}" in
*-*-cygwin*)
PICFLAG=
;;
*-*-hpux*)
PICFLAG=+z
;;
esac
AC_SUBST(PICFLAG)
AC_MSG_RESULT($PICFLAG)
# mingw needs to link with libiberty.a
AC_MSG_CHECKING("for extra libs needed")
EXTRALIBS=
case "${host}" in
*-*-cygwin*)
if test $ac_cv_mingw32 = yes; then
EXTRALIBS="-liberty"
fi
;;
esac
AC_SUBST(EXTRALIBS)
AC_MSG_RESULT($EXTRALIBS)
# The -rdynamic flag is used by iverilog when compiling the target,
# to know how to export symbols of the main program to loadable modules
# that are brought in by -ldl
AC_MSG_CHECKING("for -rdynamic compiler flag")
rdynamic=-rdynamic
case "${host}" in
*-*-netbsd*)
rdynamic="-Wl,--export-dynamic"
;;
*-*-solaris*)
rdynamic=""
;;
*-*-cygwin*)
rdynamic=""
;;
*-*-hpux*)
rdynamic="-E"
;;
esac
AC_SUBST(rdynamic)
AC_MSG_RESULT($rdynamic)
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
;;
*-*-hpux*)
shared="-b"
;;
esac
AC_SUBST(shared)
AC_MSG_RESULT($shared)
AC_CONFIG_SUBDIRS(vpip vvp tgt-vvp tgt-fpga)
AC_OUTPUT(Makefile vpi/Makefile ivlpp/Makefile vvm/Makefile driver/Makefile tgt-null/Makefile tgt-stub/Makefile tgt-verilog/Makefile tgt-pal/Makefile)
+953 -111
View File
File diff suppressed because it is too large Load Diff
+53
View File
@@ -0,0 +1,53 @@
This file describes the build procedure under cygwin32 (Windows 95/98/NT/2K)
----------------------------------------------------------------------------
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 ./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
To build your own extensions - just include vpi_user.h and link with
a command like this:
$(CC) -shared -o <dllname> <objects> -Wl,--enable-auto-image-base -L../vvm -lvvm -lvpip
- Venkat Iyer <[email protected]>
+500 -482
View File
File diff suppressed because it is too large Load Diff
+75
View File
@@ -0,0 +1,75 @@
/*
* 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
*
* $Id: dosify.c,v 1.1 2001/08/03 17:06:47 steve Exp $
*/
/*
* This is a simple program to make a dosified copy of the
* original. That is, it converts unix style line ends to DOS
* style. This is useful for installing text files.
*
* The exact substitution is to replace \n with \r\n. If the line
* already ends with \r\n then it is not changed to \r\r\n.
*/
# include <stdio.h>
int main(int argc, char*argv[])
{
FILE*ifile;
FILE*ofile;
int ch, pr;
if (argc != 3) {
fprintf(stderr, "Usage: %s <input> <output>\n", argv[0]);
return 1;
}
ifile = fopen(argv[1], "rb");
if (ifile == 0) {
fprintf(stderr, "Unable to open %s for input.\n", argv[1]);
return 2;
}
ofile = fopen(argv[2], "wb");
if (ofile == 0) {
fprintf(stderr, "Unable to open %s for output.\n", argv[2]);
return 2;
}
pr = 0;
while ((ch = fgetc(ifile)) != EOF) {
if ((ch == '\n') && (pr != '\r'))
fputc('\r', ofile);
fputc(ch, ofile);
pr = ch;
}
return 0;
}
/*
* $Log: dosify.c,v $
* Revision 1.1 2001/08/03 17:06:47 steve
* Add install of examples for Windows.
*
*/
+6
View File
@@ -0,0 +1,6 @@
Makefile
parse.c
parse.h
parse.output
lexor.c
iverilog
+91
View File
@@ -0,0 +1,91 @@
#
# 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. In order to redistribute the software in
# binary form, you will need a Picture Elements Binary Software
# License.
#
# 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.6 2001/08/10 00:39:42 steve Exp $"
#
#
SHELL = /bin/sh
VERSION = 0.0
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@
rdynamic=@rdynamic@
CC = @CC@
CXX = @CXX@
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
CPPFLAGS = @CPPFLAGS@ @DEFS@
CFLAGS = @CFLAGS@ -I. -I$(srcdir)/..
CXXFLAGS = @CXXFLAGS@ -I. -I$(srcdir)/..
LDFLAGS = @LDFLAGS@
all: iverilog@EXEEXT@
clean:
rm -f *.o lexor.c parse.c parse.h parse.output
O = main.o build_string.o lexor.o parse.o
iverilog@EXEEXT@: $O
$(CC) $(LDFLAGS) $O -o iverilog@EXEEXT@ @EXTRALIBS@
lexor.c: lexor.lex
flex -s -olexor.c $(srcdir)/lexor.lex
parse.h parse.c: parse.y
bison --verbose -t -d -o parse.c $(srcdir)/parse.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
build_string.o: build_string.c globals.h
lexor.o: lexor.c parse.h globals.h
parse.o: parse.c globals.h
install: all installdirs $(bindir)/iverilog@EXEEXT@ $(mandir)/man1/iverilog.1
$(bindir)/iverilog@EXEEXT@: ./iverilog@EXEEXT@
$(INSTALL_PROGRAM) ./iverilog@EXEEXT@ $(bindir)/iverilog@EXEEXT@
$(mandir)/man1/iverilog.1: $(srcdir)/iverilog.man
$(INSTALL_DATA) $(srcdir)/iverilog.man $(mandir)/man1/iverilog.1
installdirs: ../mkinstalldirs
$(srcdir)/../mkinstalldirs $(bindir) $(mandir)/man1
uninstall:
rm -f $(bindir)/iverilog@EXEEXT@
rm -f $(mandir)/man1/iverilog.1
+161
View File
@@ -0,0 +1,161 @@
/*
* Copyright (c) 2000 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: build_string.c,v 1.4 2001/07/25 03:10:50 steve Exp $"
#endif
# include "config.h"
# include "globals.h"
# include <string.h>
# include <assert.h>
int build_string(char*output, size_t olen, const char*pattern)
{
char tmp_buf[1024];
char*output_save = output;
while (*pattern) {
if (*pattern == '%') {
pattern += 1;
switch (*pattern) {
case 0:
break;
case '%':
*output++ = '%';
break;
case '[': {
const char*tail;
pattern += 1;
assert(*pattern);
tail = strchr(pattern+1, ']');
assert(tail);
strncpy(tmp_buf, pattern+1, tail-pattern-1);
tmp_buf[tail-pattern-1] = 0;
if (((*pattern == 's') && start)
|| ((*pattern == 'v') && verbose_flag)
|| ((*pattern == 'N') && npath)
|| ((*pattern == 'T') && mtm)) {
int rc = build_string(output, olen,
tmp_buf);
output += rc;
olen -= rc;
}
pattern = tail;
break;
}
case 'B':
strcpy(output, base);
output += strlen(base);
olen -= strlen(base);
break;
case 'f':
if (f_list) {
strcpy(output, f_list);
output += strlen(f_list);
olen -= strlen(f_list);
}
break;
case 'm':
if (mod_list) {
strcpy(output, mod_list);
output += strlen(mod_list);
olen -= strlen(mod_list);
}
break;
case 'N':
if (npath) {
strcpy(output, npath);
output += strlen(npath);
olen -= strlen(npath);
}
break;
case 'o':
strcpy(output, opath);
output += strlen(opath);
olen -= strlen(opath);
break;
case 's':
if (start) {
strcpy(output, start);
output += strlen(start);
olen -= strlen(start);
}
break;
case 'T':
if (mtm) {
strcpy(output, mtm);
output += strlen(mtm);
olen -= strlen(mtm);
}
break;
case 't':
strcpy(output, targ);
output += strlen(targ);
olen -= strlen(targ);
break;
case 'W':
strcpy(output, warning_flags);
output += strlen(warning_flags);
olen -= strlen(warning_flags);
break;
}
pattern += 1;
} else {
*output++ = *pattern++;
olen -= 1;
}
}
*output = 0;
return output-output_save;
}
/*
* $Log: build_string.c,v $
* 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)
*
* Revision 1.3 2001/07/03 04:09:25 steve
* Generate verbuse status messages (Stephan Boettcher)
*
* Revision 1.2 2000/10/28 03:45:47 steve
* Use the conf file to generate the vvm ivl string.
*
* Revision 1.1 2000/10/08 22:36:56 steve
* iverilog with an iverilog.conf configuration file.
*
*/
+78
View File
@@ -0,0 +1,78 @@
#ifndef __globals_H
#define __globals_H
/*
* Copyright (c) 2000 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: globals.h,v 1.4 2001/07/03 04:09:25 steve Exp $"
#endif
# include <stddef.h>
/* This is the base (i.e. -B<value>) of the Icarus Verilog files. */
extern const char*base;
/* This is a list of all the -f<key>=<value> options from the
command line, concatenated together. */
extern char*f_list;
extern char*mod_list;
/* This is the optional -Tmin|typ|max setting. */
extern const char*mtm;
/* 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 flag is true if the -S flag was used on the command line. */
extern int synth_flag;
/* This is the name of the selected target. */
extern const char*targ;
/* -v */
extern int verbose_flag;
extern char warning_flags[];
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.4 2001/07/03 04:09:25 steve
* Generate verbuse status messages (Stephan Boettcher)
*
* Revision 1.3 2000/11/09 21:58:00 steve
* Remember to include the -S condition.
*
* Revision 1.2 2000/10/28 03:45:47 steve
* Use the conf file to generate the vvm ivl string.
*
* Revision 1.1 2000/10/08 22:36:56 steve
* iverilog with an iverilog.conf configuration file.
*
*/
#endif
+202
View File
@@ -0,0 +1,202 @@
.TH iverilog 1 "$Date: 2001/08/31 17:28:10 $" Version "$Date: 2001/08/31 17:28:10 $"
.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
.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.
.SH OPTIONS
.l
\fIiverilog\fP accepts the following options:
.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
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.
.TP 8
.B -c\fIfile\fP
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.)
.TP 8
.B -C\fIpath\fP
This flag selects the driver configuration file to use. Normally, the
iverilog program will read its configuration file from
/usr/lib/ivl/iverilog.conf (or the install path configured at compile
time) but the user can specify the path to a different configuration
file. This is useful when testing new configuration files. See the
installed configuration file for a summary of the file format.
.TP 8
.B -D\fImacro\fP
Defines macro \fImacro\fP with the string `1' as its definition. This
form is normally only used to trigger ifdef conditionals in the
Verilog source.
.TP 8
.B -D\fImacro=defn\fP
Defines macro \fImacro\fP as \fIdefn\fP.
.TP 8
.B -E
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.
.TP 8
.B -I\fIincludedir\fP
Append directory \fIincludepdir\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\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
the order specified. The system module is implicit and always included.
.TP 8
.B -N\fIpath\fP
This is used for debugging the compiler proper. Dump the final netlist
form of the design to the specified file. It otherwise does not affect
operation of the compiler. The dump happens after the design is
elaborated and optimized.
.TP 8
.B -o \fIfilename\fP
Place output in the file \fIfilename\fP. If no output file name is
specified, \fIiverilog\fP uses the default name \fBa.out\fP.
.TP 8
.B -p\fIflag=value\fP
Assign a value to a target specific flag. The \fB-p\fP switch may be
used as often as necessary to specify all the desired flags. The flags
that are used depend on the target that is selected, and are described
in target specific documentation. Flags that are not used are ignored.
.TP 8
.B -S
Synthesize. Normally, if the target can accept behavioral
descriptions the compiler will leave processes in behavioral
form. The \fB-S\fP switch causes the compiler to perform synthesis
even if it is not necessary for the target. If the target type is a
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.
.TP 8
.B -T\fImin|typ|max\fP
Use this switch to select min, typ or max times from min:typ:max
expressions. Normally, the compiler will simply use the typ value from
these expressions (with a warning) but this switch will tell the
compiler explicitly which value to use. This will suppress the
warning that the compiler is making a choice.
.TP 8
.B -t\fItarget\fP
Use this switch to specify the target output format. See the
\fBTARGETS\fP section below for a list of valid output formats.
.TP 8
.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.
.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
multiple \fB-W\fP switches are used, the warning set is the union of
all the requested classes.
.SH TARGETS
The Icarus Verilog compiler supports a variety of targets, for
different purposes, and the \fB-t\fP switch is used to select the
desired target.
.TP 8
.B null
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.
.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.
.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.
.SH "WARNING TYPES"
These are the types of warnings that can be selected by the \fB-W\fP
switch.
.TP 8
.B all
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
source, this will print a warning at its first use.
.SH EXAMPLES
These examples assume that you have a Verilog source file called hello.v in
the current directory
To compile hello.v to an executable file called a.out:
iverilog hello.v
To compile hello.v to an executable file called hello:
iverilog -o hello hello.v
To compile and run explicitly using the vvp runtime:
iverilog -ohello.vvp -tvvp hello.v
To compile hello.v to a file in XNF-format called hello.xnf
iverilog -txnf -ohello.xnf hello.v
.SH "AUTHOR"
.nf
Steve Williams ([email protected])
.SH SEE ALSO
vvp(1),
.BR "<http://www.icarus.com/eda/verilog/>"
.SH COPYRIGHT
.nf
Copyright \(co 2000 Stephen Williams
This document can be freely redistributed according to the terms of the
GNU General Public License version 2.0
+80
View File
@@ -0,0 +1,80 @@
%{
/*
* Copyright (c) 2000 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: lexor.lex,v 1.5 2001/07/25 03:10:50 steve Exp $"
#endif
# include "config.h"
# include <string.h>
# include "parse.h"
%}
%x CTOKENS
%x PATTERN
%%
"#".* { /* eat comments */; }
"\n" { /* eat line-ends */; }
"\r" { /* eat line-ends */; }
"[" { BEGIN(CTOKENS); return '['; }
<CTOKENS>"]" { BEGIN(0); return ']'; }
<CTOKENS>[ \t\b]+ { /* skip white space */; }
<CTOKENS>"-S" { return CT_S; }
<CTOKENS>"-t"[a-zA-Z0-9\-_]+ {
yylval.text = strdup(yytext+2);
return CT_t; }
"<"[^>]*">" {
BEGIN(PATTERN);
yylval.text = strdup(yytext);
return PATTERN_NAME; }
<PATTERN>.* {
BEGIN(0);
/* Trim off a trailing \r. This is an issue in the DOS world. */
if (yytext[strlen(yytext)-1] == '\r')
yytext[strlen(yytext)-1] = 0;
yylval.text = strdup(yytext);
return PATTERN_TEXT; }
. { fprintf(stderr, "driver lexor: Unmatched character: %c\n", yytext[0]); }
%%
void reset_lexor(FILE*fd)
{
yyrestart(fd);
}
int yywrap()
{
return 1;
}
+690
View File
@@ -0,0 +1,690 @@
/*
* Copyright (c) 2000-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
*/
#ident "$Id: main.c,v 1.21 2001/07/25 03:10:50 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"
" [-N file] [-o filename] [-p flag=value]\n"
" [-s topmodule] [-t target] [-T min|typ|max]\n"
" [-W class] source_file(s)\n"
"See man page for details.";
#define MAXSIZE 4096
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <sys/types.h>
#ifdef HAVE_SYS_WAIT_H
#include <sys/wait.h>
#endif
#ifdef __MINGW32__
#include <windows.h>
#endif
#if HAVE_GETOPT_H
#include <getopt.h>
#endif
#if defined(__MINGW32__) && !defined(HAVE_GETOPT_H)
extern int getopt(int argc, char*argv[], const char*fmt);
extern int optind;
extern const char*optarg;
#endif
#if !defined(WIFEXITED)
# define WIFEXITED(rc) ((rc&0x7f) == 0)
#endif
#if !defined(WEXITSTATUS)
# define WEXITSTATUS(rc) (rc>>8)
#endif
#ifndef IVL_ROOT
# define IVL_ROOT "."
#endif
#ifndef RDYNAMIC
# define RDYNAMIC "-rdynamic"
#endif
# include "globals.h"
#ifdef __MINGW32__
const char sep = '\\';
#else
const char sep = '/';
#endif
const char*base = 0;
const char*mtm = 0;
const char*opath = "a.out" EXEEXT;
const char*npath = 0;
const char*targ = "vvp";
const char*start = 0;
char warning_flags[16] = "";
char*inc_list = 0;
char*def_list = 0;
char*mod_list = 0;
char*command_filename = 0;
char*f_list = 0;
int synth_flag = 0;
int verbose_flag = 0;
int command_file = 0;
int inside_c_comment = 0;
FILE *fp;
char line[MAXSIZE];
char tmp[MAXSIZE];
static char ivl_root[MAXSIZE];
/*
* This is the default target type. It looks up the bits that are
* needed to run the command from the configuration file (which is
* already parsed for us) so we can handle must of the generic cases.
*/
static int t_default(char*cmd, unsigned ncmd)
{
int rc;
const char*pattern;
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))
return WEXITSTATUS(rc);
fprintf(stderr, "Command signaled: %s\n", cmd);
return -1;
}
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)
{
if (warning_flags[0] == 0)
strcpy(warning_flags, "-W");
if (strcmp(name,"all") == 0) {
strcat(warning_flags, "i");
} else if (strcmp(name,"implicit") == 0) {
if (! strchr(warning_flags+2, 'i'))
strcat(warning_flags, "i");
}
}
int main(int argc, char **argv)
{
const char*config_path = 0;
char*cmd;
unsigned ncmd;
int e_flag = 0;
int opt, idx;
char*cp;
#ifdef __MINGW32__
{ char * s;
char basepath[1024];
GetModuleFileName(NULL,basepath,1024);
/* Calculate the ivl_root from the path to the command. This
is necessary because of the installation process in
Windows. Mostly, it is those darn drive letters, but oh
well. We know the command path is formed like this:
D:\iverilog\bin\iverilog.exe
The IVL_ROOT in a Windows installation is the path:
D:\iverilog\lib\ivl
so we chop the file name and the last directory by
turning the last two \ characters to null. Then we append
the lib\ivl to finish. */
strncpy(ivl_root, basepath, MAXSIZE);
s = strrchr(ivl_root, sep);
if (s) *s = 0;
s = strrchr(ivl_root, sep);
if (s) *s = 0;
strcat(ivl_root, "\\lib\\ivl");
base = ivl_root;
}
#else
/* In a UNIX environment, the IVL_ROOT from the Makefile is
dependable. It points to the $prefix/lib/ivl directory,
where the sub-parts are installed. */
strcpy(ivl_root, IVL_ROOT);
base = ivl_root;
#endif
while ((opt = getopt(argc, argv, "B:C:c:D:Ef:hI:m:N::o:p:Ss:T:t:vW:")) != EOF) {
switch (opt) {
case 'B':
base = optarg;
break;
case 'C':
config_path = optarg;
break;
case 'c':
command_filename = malloc(strlen(optarg)+1);
strcat(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);
}
break;
case 'E':
e_flag = 1;
break;
case 'f':
fprintf(stderr, "warning: The -f flag is moved to -p\n");
case 'p':
if (f_list == 0) {
f_list = malloc(strlen(" -p")+strlen(optarg)+1);
strcpy(f_list, " -p");
strcat(f_list, optarg);
} else {
f_list = realloc(f_list, strlen(f_list) +
strlen(" -p") +
strlen(optarg) + 1);
strcat(f_list, " -p");
strcat(f_list, optarg);
}
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);
}
break;
case 'm':
if (mod_list == 0) {
mod_list = malloc(strlen(" -m")+strlen(optarg)+1);
strcpy(mod_list, " -m");
strcat(mod_list, optarg);
} else {
mod_list = realloc(mod_list, strlen(mod_list)
+ strlen(" -m")
+ strlen(optarg) + 1);
strcat(mod_list, " -m");
strcat(mod_list, optarg);
}
break;
case 'N':
npath = optarg;
break;
case 'o':
opath = optarg;
break;
case 'S':
synth_flag = 1;
break;
case 's':
start = optarg;
break;
case 'T':
if (strcmp(optarg,"min") == 0) {
mtm = "min";
} else if (strcmp(optarg,"typ") == 0) {
mtm = "typ";
} else if (strcmp(optarg,"max") == 0) {
mtm = "max";
} else {
fprintf(stderr, "%s: invalid -T%s argument\n",
argv[0], optarg);
return 1;
}
break;
case 't':
targ = optarg;
break;
case 'v':
verbose_flag = 1;
break;
case 'W':
process_warning_switch(optarg);
break;
case '?':
default:
return 1;
}
}
if ((optind == argc) && !command_filename) {
fprintf(stderr, "%s: No input files.\n", argv[0]);
fprintf(stderr, "%s\n", HELP);
return 1;
}
/* Load the iverilog.conf file to get our substitution
strings. */
{ char path[1024];
FILE*fd;
if (config_path) {
strcpy(path, config_path);
} else {
sprintf(path, "%s%civerilog.conf", base,sep);
}
fd = fopen(path, "r");
if (fd == 0) {
fprintf(stderr, "Config file \"%s\" not found\n",path);
return 1;
}
reset_lexor(fd);
yyparse();
}
/* Start building the preprocess command line. */
sprintf(tmp, "%s%civlpp %s%s", base,sep,
verbose_flag?" -v":"",
e_flag?"":" -L");
ncmd = strlen(tmp);
cmd = malloc(ncmd + 1);
strcpy(cmd, tmp);
if (inc_list) {
cmd = realloc(cmd, ncmd + strlen(inc_list) + 1);
strcat(cmd, inc_list);
ncmd += strlen(inc_list);
}
if (def_list) {
cmd = realloc(cmd, ncmd + strlen(def_list) + 1);
strcat(cmd, def_list);
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 the -E flag was given on the command line, then all we
do is run the preprocessor and put the output where the
user wants it. */
if (e_flag) {
int rc;
if (strcmp(opath,"-") != 0) {
sprintf(tmp, " > %s", opath);
cmd = realloc(cmd, ncmd+strlen(tmp)+1);
strcpy(cmd+ncmd, tmp);
ncmd += strlen(tmp);
}
if (verbose_flag)
printf("preprocess: %s\n", cmd);
rc = system(cmd);
if (rc != 0) {
if (WIFEXITED(rc)) {
fprintf(stderr, "errors preprocessing Verilog program.\n");
return WEXITSTATUS(rc);
}
fprintf(stderr, "Command signaled: %s\n", cmd);
return -1;
}
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);
}
return 0;
}
/*
* $Log: main.c,v $
* 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)
*
* Revision 1.20 2001/06/30 21:53:42 steve
* Make the vvp target the default.
*
* Revision 1.19 2001/06/30 04:23:02 steve
* Get include and lib paths right for mingw and vvm.
*
* Revision 1.18 2001/06/30 00:59:24 steve
* Redo the ivl_root calculator for mingw.
*
* Revision 1.17 2001/06/27 02:22:26 steve
* Get include and lib paths from Makefile.
*
* Revision 1.16 2001/06/20 02:25:40 steve
* Edit ivl_install_dir only on mingw
*
* Revision 1.15 2001/06/15 05:14:21 steve
* Fix library path calculation on non Windows systems
* to include the install directories. (Brendan Simon)
*
* Revision 1.14 2001/06/12 03:53:10 steve
* Change the VPI call process so that loaded .vpi modules
* use a function table instead of implicit binding.
*
* Revision 1.13 2001/05/20 18:22:02 steve
* Fix WIFEXITED macro.
*
* Revision 1.12 2001/05/20 18:06:57 steve
* local declares if the header is missing.
*
* Revision 1.11 2001/05/20 15:09:40 steve
* Mingw32 support (Venkat Iyer)
*
* Revision 1.10 2001/05/17 03:14:26 steve
* Update help message.
*
* Revision 1.9 2001/04/26 16:04:39 steve
* Handle missing or uninstalled .conf files.
*
* Revision 1.8 2001/02/01 17:12:22 steve
* Forgot to actually allow the -p flag.
*
* Revision 1.7 2001/01/20 19:02:05 steve
* Switch hte -f flag to the -p flag.
*/
+164
View File
@@ -0,0 +1,164 @@
%{
/*
* Copyright (c) 2000 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: parse.y,v 1.3 2001/07/25 03:10:50 steve Exp $"
#endif
# include "config.h"
# include <stdio.h>
# include <malloc.h>
# include "globals.h"
void yyerror(const char*);
enum drive_code_t {
CODE_S,
CODE_t,
};
struct drive_cond {
struct drive_cond*next;
enum drive_code_t code;
char* text;
};
static struct drive_cond *cur_cond = 0;
static void add_cond(enum drive_code_t code, char*text)
{
struct drive_cond*tmp;
tmp = calloc(1, sizeof(struct drive_cond));
tmp->code = code;
tmp->text = text;
tmp->next = cur_cond;
cur_cond = tmp;
}
struct drive_pattern {
struct drive_pattern*next;
char*name;
char*text;
struct drive_cond*cond;
};
static struct drive_pattern *patterns = 0;
static struct drive_pattern *plast = 0;
static void add_pattern(char*name, char*text)
{
struct drive_pattern*tmp;
tmp = calloc(1, sizeof(struct drive_pattern));
tmp->name = name;
tmp->text = text;
tmp->cond = cur_cond;
tmp->next = 0;
if (plast) {
plast->next = tmp;
plast = tmp;
} else {
patterns = tmp;
plast = tmp;
}
}
const char*lookup_pattern(const char*key)
{
struct drive_pattern*cur;
struct drive_cond*cc;
for (cur = patterns ; cur ; cur = cur->next) {
if (strcmp(key, cur->name) != 0)
continue;
for (cc = cur->cond ; cc ; cc = cc->next) {
switch (cc->code) {
case CODE_S:
if (synth_flag)
continue;
break;
case CODE_t:
if (strcmp(targ, cc->text) == 0)
continue;
break;
}
break;
}
if (cc) continue;
return cur->text;
}
return 0;
}
%}
%union {
char*text;
};
%token <text> PATTERN_NAME PATTERN_TEXT
%token <text> CT_t
%token CT_S
%%
start: section_list
section_list
: section
| section_list section
;
section : '[' ctoken_list ']' pattern_list { cur_cond = 0; } ;
ctoken_list
: ctoken
| ctoken_list ctoken
;
ctoken : CT_S { add_cond(CODE_S, 0); }
| CT_t { add_cond(CODE_t, $1); }
;
pattern_list
: pattern
| pattern_list pattern
;
pattern : PATTERN_NAME PATTERN_TEXT
{ add_pattern($1, $2); }
;
%%
void yyerror(const char*msg)
{
fprintf(stderr, "%s\n", msg);
}
+28 -2
View File
@@ -16,10 +16,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: dup_expr.cc,v 1.1 1999/11/27 19:07:57 steve Exp $"
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: dup_expr.cc,v 1.5 2001/07/25 03:10:48 steve Exp $"
#endif
# include "config.h"
# include "netlist.h"
# include <cassert>
@@ -29,8 +31,32 @@ NetEScope* NetEScope::dup_expr() const
return 0;
}
NetESFunc* NetESFunc::dup_expr() const
{
NetESFunc*tmp = new NetESFunc(name_, expr_width(), nparms());
for (unsigned idx = 0 ; idx < nparms() ; idx += 1)
tmp->parm(idx, tmp->parm(idx)->dup_expr());
return tmp;
}
/*
* $Log: dup_expr.cc,v $
* 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)
*
* Revision 1.4 2000/05/07 18:20:07 steve
* Import MCD support from Stephen Tell, and add
* system function parameter support to the IVL core.
*
* 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.
*
+163
View File
@@ -0,0 +1,163 @@
/*
* Copyright (c) 2000 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: elab_anet.cc,v 1.3 2001/07/25 03:10:48 steve Exp $"
#endif
# include "config.h"
/*
* The elaborate_anet methods elaborate expressions that are intended
* to be the left side of procedural continuous assignments.
*/
# include "PExpr.h"
# include "netlist.h"
# include <iostream>
NetNet* PExpr::elaborate_anet(Design*des, NetScope*scope) const
{
cerr << get_line() << ": error: Invalid expression on left side "
<< "of precedural continuous asignment." << endl;
return 0;
}
NetNet* PEConcat::elaborate_anet(Design*des, NetScope*scope) const
{
if (repeat_) {
cerr << get_line() << ": error: Repeat concatenations make "
"no sense in l-value expressions. I refuse." << endl;
des->errors += 1;
return 0;
}
svector<NetNet*>nets (parms_.count());
unsigned pins = 0;
unsigned errors = 0;
for (unsigned idx = 0 ; idx < nets.count() ; idx += 1) {
if (parms_[idx] == 0) {
cerr << get_line() << ": error: Empty expressions "
<< "not allowed in concatenations." << endl;
errors += 1;
continue;
}
nets[idx] = parms_[idx]->elaborate_anet(des, scope);
if (nets[idx] == 0)
errors += 1;
else
pins += nets[idx]->pin_count();
}
/* If any of the sub expressions failed to elaborate, then
delete all those that did and abort myself. */
if (errors) {
for (unsigned idx = 0 ; idx < nets.count() ; idx += 1) {
if (nets[idx]) delete nets[idx];
}
des->errors += 1;
return 0;
}
/* Make the temporary signal that connects to all the
operands, and connect it up. Scan the operands of the
concat operator from least significant to most significant,
which is opposite from how they are given in the list.
Allow for a repeat count other then 1 by repeating the
connect loop as many times as necessary. */
NetNet*osig = new NetNet(scope, des->local_symbol(scope->name()),
NetNet::IMPLICIT_REG, pins);
pins = 0;
for (unsigned idx = nets.count() ; idx > 0 ; idx -= 1) {
NetNet*cur = nets[idx-1];
for (unsigned pin = 0; pin < cur->pin_count(); pin += 1) {
connect(osig->pin(pins), cur->pin(pin));
pins += 1;
}
}
osig->local_flag(true);
return osig;
}
NetNet* PEIdent::elaborate_anet(Design*des, NetScope*scope) const
{
NetNet*sig = des->find_signal(scope, text_);
if (sig == 0) {
if (NetMemory*mem = des->find_memory(scope, text_)) {
cerr << get_line() << ": error: memories not allowed "
<< "on left side of procedural continuous "
<< "asignment." << endl;
des->errors += 1;
return 0;
}
cerr << get_line() << ": error: reg ``" << text_ << "'' "
<< "is undefined in this scope." << endl;
des->errors += 1;
return 0;
}
switch (sig->type()) {
case NetNet::REG:
case NetNet::IMPLICIT_REG:
break;
default:
cerr << get_line() << ": error: " << text_ << " is not "
<< "a reg in this context." << endl;
des->errors += 1;
return 0;
}
assert(sig);
if (msb_ || lsb_) {
cerr << get_line() << ": error: bit/part selects not allowed "
<< "on left side of procedural continuous asignment."
<< endl;
des->errors += 1;
return 0;
}
return sig;
}
/*
* $Log: elab_anet.cc,v $
* 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)
*
* Revision 1.2 2001/01/06 02:29:36 steve
* Support arrays of integers.
*
* Revision 1.1 2000/12/06 06:31:09 steve
* Check lvalue of procedural continuous assign (PR#29)
*
*/
+403 -91
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1999 Stephen Williams ([email protected])
* Copyright (c) 1999-2000 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
@@ -16,24 +16,37 @@
* 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: elab_expr.cc,v 1.12 1999/11/30 04:54:01 steve Exp $"
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: elab_expr.cc,v 1.42 2001/07/29 22:22:40 steve Exp $"
#endif
# include "config.h"
# include "pform.h"
# include "netlist.h"
# include "netmisc.h"
# include "util.h"
NetExpr* PExpr::elaborate_expr(Design*des, NetScope*) const
{
cerr << get_line() << ": internal error: I do not know how to elaborate"
<< " expression. " << endl;
cerr << get_line() << ": : Expression is: " << *this
<< endl;
des->errors += 1;
return 0;
}
/*
* Elaborate binary expressions. This involves elaborating the left
* and right sides, and creating one of a variety of different NetExpr
* types.
*/
NetExpr* PEBinary::elaborate_expr(Design*des, const string&path) const
NetEBinary* PEBinary::elaborate_expr(Design*des, NetScope*scope) const
{
bool flag;
NetExpr*lp = left_->elaborate_expr(des, path);
NetExpr*rp = right_->elaborate_expr(des, path);
NetExpr*lp = left_->elaborate_expr(des, scope);
NetExpr*rp = right_->elaborate_expr(des, scope);
if ((lp == 0) || (rp == 0)) {
delete lp;
delete rp;
@@ -55,7 +68,21 @@ NetExpr* PEBinary::elaborate_expr(Design*des, const string&path) const
}
}
NetEBinary*tmp = elaborate_expr_base_(des, lp, rp);
return tmp;
}
/*
* This is common elaboration of the operator. It presumes that the
* operands are elaborated as necessary, and all I need to do is make
* the correct NetEBinary object and connect the parameters.
*/
NetEBinary* PEBinary::elaborate_expr_base_(Design*des,
NetExpr*lp, NetExpr*rp) const
{
bool flag;
NetEBinary*tmp;
switch (op_) {
default:
tmp = new NetEBinary(op_, lp, rp);
@@ -68,6 +95,17 @@ NetExpr* PEBinary::elaborate_expr(Design*des, const string&path) const
tmp->set_line(*this);
break;
case '*':
tmp = new NetEBMult(op_, lp, rp);
tmp->set_line(*this);
break;
case '/':
case '%':
tmp = new NetEBDiv(op_, lp, rp);
tmp->set_line(*this);
break;
case 'l':
case 'r':
tmp = new NetEBShift(op_, lp, rp);
@@ -111,38 +149,150 @@ NetExpr* PEBinary::elaborate_expr(Design*des, const string&path) const
return tmp;
}
NetESFunc* PECallFunction::elaborate_sfunc_(Design*des, const string&path) const
/*
* Given a call to a system function, generate the proper expression
* nodes to represent the call in the netlist. Since we don't support
* size_tf functions, make assumptions about widths based on some
* known function names.
*/
NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope) const
{
cerr << get_line() << ": sorry: system functions not supported."
<< endl;
des->errors += 1;
return 0;
unsigned wid = 32;
if (name_ == "$time")
wid = 64;
/* How many parameters are there? The Verilog language allows
empty parameters in certain contexts, so the parser will
allow things like func(1,,3). It will also cause func() to
be interpreted as a single empty parameter.
Functions cannot really take empty parameters, but the
case ``func()'' is the same as no parmaters at all. So
catch that special case here. */
unsigned nparms = parms_.count();
if ((nparms == 1) && (parms_[0] == 0))
nparms = 0;
NetESFunc*fun = new NetESFunc(name_, wid, nparms);
/* Now run through the expected parameters. If we find that
there are missing parameters, print an error message.
While we're at it, try to evaluate the function parameter
expression as much as possible, and use the reduced
expression if one is created. */
unsigned missing_parms = 0;
for (unsigned idx = 0 ; idx < nparms ; idx += 1) {
PExpr*expr = parms_[idx];
if (expr) {
NetExpr*tmp1 = expr->elaborate_expr(des, scope);
if (NetExpr*tmp2 = tmp1->eval_tree()) {
delete tmp1;
fun->parm(idx, tmp2);
} else {
fun->parm(idx, tmp1);
}
} else {
missing_parms += 1;
fun->parm(idx, 0);
}
}
if (missing_parms > 0) {
cerr << get_line() << ": error: The function " << name_
<< " has been called with empty parameters." << endl;
cerr << get_line() << ": : Verilog doesn't allow "
<< "passing empty parameters to functions." << endl;
des->errors += 1;
}
return fun;
}
NetExpr* PECallFunction::elaborate_expr(Design*des, const string&path) const
NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope) const
{
if (name_[0] == '$')
return elaborate_sfunc_(des, path);
return elaborate_sfunc_(des, scope);
string myname = path+"."+name_;
NetFuncDef*def = des->find_function(path, name_);
NetFuncDef*def = des->find_function(scope, name_);
if (def == 0) {
cerr << get_line() << ": error: No function " << name_ <<
" in this context (" << path << ")." << endl;
" in this context (" << scope->name() << ")." << endl;
des->errors += 1;
return 0;
}
assert(def);
svector<NetExpr*> parms (parms_.count());
for (unsigned idx = 0 ; idx < parms.count() ; idx += 1) {
NetExpr*tmp = parms_[idx]->elaborate_expr(des, myname);
parms[idx] = tmp;
NetScope*dscope = des->find_scope(def->name());
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. */
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;
}
/* Look for the return value signal for the called function in
the context of the function definition, not my context. */
NetNet*res = des->find_signal(def->name(), name_);
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);
/* Elaborate the input expressions for the function. This is
done in the scope of the function call, and not the scope
of the function being called. The scope of the called
function is elaborated when the definition is elaborated. */
unsigned missing_parms = 0;
for (unsigned idx = 0 ; idx < parms.count() ; idx += 1) {
PExpr*tmp = parms_[idx];
if (tmp) {
parms[idx] = tmp->elaborate_expr(des, scope);
} else {
missing_parms += 1;
parms[idx] = 0;
}
}
if (missing_parms > 0) {
cerr << get_line() << ": error: The function " << name_
<< " has been called with empty parameters." << endl;
cerr << get_line() << ": : Verilog doesn't allow "
<< "passing empty parameters to functions." << endl;
des->errors += 1;
}
/* Look for the return value signal for the called
function. This return value is a magic signal in the scope
of the function, that has the name of the function. The
function code assigns to this signal to return a value.
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));
if (res == 0) {
cerr << get_line() << ": internal error: Unable to locate "
"function return value for " << name_ << " in " <<
@@ -154,27 +304,81 @@ NetExpr* PECallFunction::elaborate_expr(Design*des, const string&path) const
assert(res);
NetESignal*eres = new NetESignal(res);
assert(eres);
NetEUFunc*func = new NetEUFunc(def, eres, parms);
NetEUFunc*func = new NetEUFunc(dscope, eres, parms);
return func;
}
NetExpr* PEIdent::elaborate_expr(Design*des, const string&path) const
NetExpr* PEConcat::elaborate_expr(Design*des, NetScope*scope) const
{
// System identifiers show up in the netlist as identifiers.
if (text_[0] == '$')
return new NetEIdent(text_, 64);
unsigned repeat = 1;
string name = path+"."+text_;
/* If there is a repeat expression, then evaluate the constant
value and set the repeat count. */
if (repeat_) {
NetExpr*tmp = elab_and_eval(des, scope, repeat_);
assert(tmp);
NetEConst*rep = dynamic_cast<NetEConst*>(tmp);
if (rep == 0) {
cerr << get_line() << ": error: "
"concatenation repeat expression cannot be evaluated."
<< endl;
cerr << get_line() << ": : The expression is: "
<< *tmp << endl;
des->errors += 1;
return 0;
}
repeat = rep->value().as_ulong();
}
/* Make the empty concat expression. */
NetEConcat*tmp = new NetEConcat(parms_.count(), repeat);
tmp->set_line(*this);
/* 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);
if (ex == 0) continue;
ex->set_line(*parms_[idx]);
if (! ex->has_width()) {
cerr << ex->get_line() << ": error: operand of "
<< "concatenation has indefinite width: "
<< *ex << endl;
des->errors += 1;
}
tmp->set(idx, ex);
}
return tmp;
}
NetExpr* PEFNumber::elaborate_expr(Design*des, NetScope*scope) const
{
long val = value_->as_long();
return new NetEConst(verinum(val));
}
NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope) 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(path, text_)) {
if (const NetExpr*ex = des->find_parameter(scope, text_)) {
NetExpr*tmp;
if (dynamic_cast<const NetExpr*>(ex))
tmp = ex->dup_expr();
else
tmp = new NetEParam(des, path, text_);
tmp = new NetEParam(des, scope, text_);
tmp->set_line(*this);
return tmp;
@@ -182,15 +386,16 @@ NetExpr* PEIdent::elaborate_expr(Design*des, const string&path) 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(path, text_)) {
if (NetNet*net = des->find_signal(scope, text_)) {
// If this is a part select of a signal, then make a new
// temporary signal that is connected to just the
// selected bits.
// selected bits. The lsb_ and msb_ expressions are from
// the foo[msb:lsb] expression in the original.
if (lsb_) {
assert(msb_);
verinum*lsn = lsb_->eval_const(des, path);
verinum*msn = msb_->eval_const(des, path);
verinum*lsn = lsb_->eval_const(des, scope->name());
verinum*msn = msb_->eval_const(des, scope->name());
if ((lsn == 0) || (msn == 0)) {
cerr << get_line() << ": error: "
"Part select expresions must be "
@@ -201,24 +406,53 @@ NetExpr* PEIdent::elaborate_expr(Design*des, const string&path) const
assert(lsn);
assert(msn);
unsigned long lsv = lsn->as_ulong();
unsigned long msv = msn->as_ulong();
/* The indices of part selects are signed
integers, so allow negative values. However,
the width that they represent is
unsigned. Remember that any order is possible,
i.e. [1:0], [-4,6], etc. */
long lsv = lsn->as_long();
long msv = msn->as_long();
unsigned long wid = 1 + ((msv>lsv)? (msv-lsv) : (lsv-msv));
if (wid > net->pin_count()) {
cerr << get_line() << ": error: part select ["
<< msv << ":" << lsv << "] out of range."
<< endl;
des->errors += 1;
delete lsn;
delete msn;
return 0;
}
assert(wid <= net->pin_count());
assert(net->sb_to_idx(msv) >= net->sb_to_idx(lsv));
string tname = des->local_symbol(path);
NetTmp*tsig = new NetTmp(tname, wid);
if (net->sb_to_idx(msv) < net->sb_to_idx(lsv)) {
cerr << get_line() << ": error: part select ["
<< msv << ":" << lsv << "] out of order."
<< endl;
des->errors += 1;
delete lsn;
delete msn;
return 0;
}
// Connect the pins from the lsb up to the msb.
unsigned off = net->sb_to_idx(lsv);
for (unsigned idx = 0 ; idx < wid ; idx += 1)
connect(tsig->pin(idx), net->pin(idx+off));
NetESignal*tmp = new NetESignal(tsig);
if (net->sb_to_idx(msv) >= net->pin_count()) {
cerr << get_line() << ": error: part select ["
<< msv << ":" << lsv << "] out of range."
<< endl;
des->errors += 1;
delete lsn;
delete msn;
return 0;
}
NetESignal*tmp = new NetESignal(net,
net->sb_to_idx(msv),
net->sb_to_idx(lsv));
tmp->set_line(*this);
des->add_signal(tsig);
return tmp;
}
@@ -226,17 +460,22 @@ NetExpr* PEIdent::elaborate_expr(Design*des, const string&path) 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, path))) {
if (msb_ && (msn = msb_->eval_const(des, scope->name()))) {
assert(idx_ == 0);
unsigned long msv = msn->as_ulong();
unsigned idx = net->sb_to_idx(msv);
string tname = des->local_symbol(path);
NetTmp*tsig = new NetTmp(tname);
connect(tsig->pin(0), net->pin(msv));
NetESignal*tmp = new NetESignal(tsig);
if (idx >= net->pin_count()) {
cerr << get_line() << ": internal error: "
<< "bit " << msv << " out of range of net "
<< net->name() << "[" << net->msb()
<< ":" << net->lsb() << "]." << endl;
return 0;
}
NetESignal*tmp = new NetESignal(net, idx, idx);
tmp->set_line(*this);
des->add_signal(tsig);
return tmp;
}
@@ -246,8 +485,8 @@ NetExpr* PEIdent::elaborate_expr(Design*des, const string&path) const
// Non-constant bit select? punt and make a subsignal
// device to mux the bit in the net.
if (msb_) {
NetExpr*ex = msb_->elaborate_expr(des, path);
NetESubSignal*ss = new NetESubSignal(node, ex);
NetExpr*ex = msb_->elaborate_expr(des, scope);
NetEBitSel*ss = new NetEBitSel(node, ex);
ss->set_line(*this);
return ss;
}
@@ -261,17 +500,23 @@ NetExpr* PEIdent::elaborate_expr(Design*des, const string&path) 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(path, text_)) {
if (NetMemory*mem = des->find_memory(scope, text_)) {
if (msb_ == 0) {
cerr << get_line() << ": error: Memory ``" << name <<
"'' referenced without an index expression." << endl;
NetEMemory*node = new NetEMemory(mem);
node->set_line(*this);
return node;
}
assert(msb_ != 0);
if (lsb_) {
cerr << get_line() << ": error: part select of a memory: "
<< mem->name() << endl;
des->errors += 1;
return 0;
}
assert(msb_ != 0);
assert(lsb_ == 0);
assert(idx_ == 0);
NetExpr*i = msb_->elaborate_expr(des, path);
NetExpr*i = msb_->elaborate_expr(des, scope);
if (msb_ && i == 0) {
cerr << get_line() << ": error: Unable to exaborate "
"index expression `" << *msb_ << "'" << endl;
@@ -284,7 +529,18 @@ NetExpr* PEIdent::elaborate_expr(Design*des, const string&path) const
return node;
}
// Finally, if this is a scope name, then return that.
// 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;
}
// 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_)) {
NetEScope*tmp = new NetEScope(nsc);
tmp->set_line(*this);
@@ -293,33 +549,48 @@ NetExpr* PEIdent::elaborate_expr(Design*des, const string&path) const
// I cannot interpret this identifier. Error message.
cerr << get_line() << ": error: Unable to bind wire/reg/memory "
"`" << path << "." << text_ << "'" << endl;
"`" << text_ << "' in `" << scope->name() << "'" << endl;
des->errors += 1;
return 0;
}
NetEConst* PENumber::elaborate_expr(Design*des, NetScope*) const
{
assert(value_);
NetEConst*tmp = new NetEConst(*value_);
tmp->set_line(*this);
return tmp;
}
NetEConst* PEString::elaborate_expr(Design*des, NetScope*) const
{
NetEConst*tmp = new NetEConst(value());
tmp->set_line(*this);
return tmp;
}
/*
* Elaborate the Ternary operator. I know that the expressions were
* parsed so I can presume that they exist, and call elaboration
* methods. If any elaboration fails, then give up and return 0.
*/
NetExpr*PETernary::elaborate_expr(Design*des, const string&path) const
NetETernary*PETernary::elaborate_expr(Design*des, NetScope*scope) const
{
assert(expr_);
assert(tru_);
assert(fal_);
NetExpr*con = expr_->elaborate_expr(des, path);
NetExpr*con = expr_->elaborate_expr(des, scope);
if (con == 0)
return 0;
NetExpr*tru = tru_->elaborate_expr(des, path);
NetExpr*tru = tru_->elaborate_expr(des, scope);
if (tru == 0) {
delete con;
return 0;
}
NetExpr*fal = fal_->elaborate_expr(des, path);
NetExpr*fal = fal_->elaborate_expr(des, scope);
if (fal == 0) {
delete con;
delete tru;
@@ -330,44 +601,85 @@ NetExpr*PETernary::elaborate_expr(Design*des, const string&path) const
return res;
}
NetEUnary* PEUnary::elaborate_expr(Design*des, NetScope*scope) const
{
NetExpr*ip = expr_->elaborate_expr(des, scope);
if (ip == 0) return 0;
/* Should we evaluate expressions ahead of time,
* just like in PEBinary::elaborate_expr() ?
*/
NetEUnary*tmp;
switch (op_) {
default:
tmp = new NetEUnary(op_, ip);
tmp->set_line(*this);
break;
case '!': // Logical NOT
case '&': // Reduction AND
case '|': // Reduction OR
case '^': // Reduction XOR
case 'A': // Reduction NAND (~&)
case 'N': // Reduction NOR (~|)
case 'X': // Reduction NXOR (~^)
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.12 1999/11/30 04:54:01 steve
* Match scope names as last resort.
* Revision 1.42 2001/07/29 22:22:40 steve
* support local reference to scope in expressions.
*
* 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.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.10 1999/11/27 19:07:57 steve
* Support the creation of scopes.
* 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.9 1999/11/21 17:35:37 steve
* Memory name lookup handles scopes.
* Revision 1.39 2001/06/30 21:28:35 steve
* Detect parameter mismatches.
*
* Revision 1.8 1999/11/10 02:52:24 steve
* Create the vpiMemory handle type.
* Revision 1.38 2001/06/23 19:53:03 steve
* Look up functor return register with tail of name.
*
* Revision 1.7 1999/10/18 00:02:21 steve
* Catch unindexed memory reference.
* Revision 1.37 2001/04/06 02:28:02 steve
* Generate vvp code for functions with ports.
*
* Revision 1.6 1999/09/30 02:43:02 steve
* Elaborate ~^ and ~| operators.
* 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.5 1999/09/30 00:48:49 steve
* Cope with errors during ternary operator elaboration.
* Revision 1.35 2001/02/09 05:44:23 steve
* support evaluation of constant < in expressions.
*
* Revision 1.4 1999/09/29 22:57:10 steve
* Move code to elab_expr.cc
* 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.3 1999/09/25 02:57:30 steve
* Parse system function calls.
* Allow parameters to be referenced by hierarchical name.
*
* Revision 1.2 1999/09/21 00:13:40 steve
* Support parameters that reference other paramters.
* Revision 1.33 2001/01/13 22:20:08 steve
* Parse parameters within nested scopes.
*
* Revision 1.1 1999/09/20 02:21:10 steve
* Elaborate parameters in phases.
* Revision 1.32 2001/01/02 04:21:13 steve
* Support a bunch of unary operators in parameter expressions.
*
* Revision 1.31 2000/12/10 22:01:35 steve
* Support decimal constants in behavioral delays.
*
* Revision 1.30 2000/11/29 05:24:00 steve
* synthesis for unary reduction ! and N operators.
*/
+330
View File
@@ -0,0 +1,330 @@
/*
* Copyright (c) 2000 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: elab_lval.cc,v 1.14 2001/08/25 23:50:02 steve Exp $"
#endif
# include "config.h"
# include "PExpr.h"
# include "netlist.h"
# include <iostream>
/*
* These methods generate a NetAssign_ object for the l-value of the
* assignemnt. This is common code for the = and <= statements.
*
* What gets generated depends on the structure of the l-value. If the
* l-value is a simple name (i.e. foo <= <value>) the the NetAssign_
* is created the width of the foo reg and connected to all the
* bits.
*
* If there is a part select (i.e. foo[3:1] <= <value>) the NetAssign_
* is made only as wide as it needs to be (3 bits in this example) and
* connected to the correct bits of foo. A constant bit select is a
* special case of the part select.
*
* If the bit-select is non-constant (i.e. foo[<expr>] = <value>) the
* NetAssign_ is made wide enough to connect to all the bits of foo,
* then the mux expression is elaborated and attached to the
* NetAssign_ node as a b_mux value. The target must interpret the
* presense of a bmux value as taking a single bit and assigning it to
* the bit selected by the bmux expression.
*
* If the l-value expression is non-trivial, but can be fully
* evaluated at compile time (meaning any bit selects are constant)
* then elaboration will make a single NetAssign_ that connects to a
* synthetic reg that in turn connects to all the proper pins of the
* l-value.
*
* This last case can turn up in statements like: {a, b[1]} = c;
* rather then create a NetAssign_ for each item in the contatenation,
* elaboration makes a single NetAssign_ and connects it up properly.
*/
/*
* The default interpretation of an l-value to a procedural assignment
* is to try to make a net elaboration, and see if the result is
* suitable for assignment.
*/
NetAssign_* PExpr::elaborate_lval(Design*des, NetScope*scope) const
{
NetNet*ll = elaborate_net(des, scope->name(), 0, 0, 0, 0);
if (ll == 0) {
cerr << get_line() << ": Assignment l-value too complex."
<< endl;
return 0;
}
NetAssign_*lv = new NetAssign_(ll);
return lv;
}
/*
* Concatenation expressions can appear as l-values. Handle them here.
*
* If adjacent l-values in the concatenation are not bit selects, then
* merge them into a single NetAssign_ object. This can happen is code
* like ``{ ...a, b, ...}''. As long as "a" and "b" do not have bit
* selects (or the bit selects are constant) we can merge the
* NetAssign_ objects.
*
* Be careful to get the bit order right. In the expression ``{a, b}''
* a is the MSB and b the LSB. Connect the LSB to the low pins of the
* NetAssign_ object.
*/
NetAssign_* PEConcat::elaborate_lval(Design*des, NetScope*scope) const
{
if (repeat_) {
cerr << get_line() << ": error: Repeat concatenations make "
"no sense in l-value expressions. I refuse." << endl;
des->errors += 1;
return 0;
}
NetAssign_*res = 0;
for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) {
NetAssign_*tmp = parms_[idx]->elaborate_lval(des, scope);
/* If the l-value doesn't elaborate, the error was
already detected and printed. We just skip it and let
the compiler catch more errors. */
if (tmp == 0)
continue;
assert(tmp);
/* Link the new l-value to the previous one. */
NetAssign_*last = tmp;
while (last->more)
last = last->more;
last->more = res;
res = tmp;
}
return res;
}
/*
* Handle the ident as an l-value. This includes bit and part selects
* of that ident.
*/
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());
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;
}
des->errors += 1;
return 0;
}
assert(reg);
if (reg->type() != NetNet::REG) {
cerr << get_line() << ": error: " << name() <<
" is not a reg/integer/time in " << scope->name() <<
"." << endl;
des->errors += 1;
return 0;
}
long msb, lsb;
NetExpr*mux;
if (msb_ && lsb_) {
/* This handles part selects. In this case, there are
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());
if (vl == 0) {
cerr << lsb_->get_line() << ": error: "
"Part select expressions must be constant: "
<< *lsb_;
des->errors += 1;
return 0;
}
verinum*vm = msb_->eval_const(des, scope->name());
if (vl == 0) {
cerr << msb_->get_line() << ": error: "
"Part select expressions must be constant: "
<< *msb_;
des->errors += 1;
return 0;
}
msb = vm->as_long();
lsb = vl->as_long();
mux = 0;
} else if (msb_) {
/* If there is only a single select expression, it is a
bit select. Evaluate the constant value and treat it
as a part select with a bit width of 1. If the
expression it not constant, then return the
expression as a mux. */
assert(lsb_ == 0);
verinum*v = msb_->eval_const(des, scope->name());
if (v == 0) {
NetExpr*m = msb_->elaborate_expr(des, scope);
assert(m);
msb = 0;
lsb = 0;
mux = m;
} else {
msb = v->as_long();
lsb = v->as_long();
mux = 0;
}
} else {
/* No select expressions, so presume a part select the
width of the register. */
assert(msb_ == 0);
assert(lsb_ == 0);
msb = reg->msb();
lsb = reg->lsb();
mux = 0;
}
NetAssign_*lv;
if (mux) {
/* If there is a non-constant bit select, make a
NetAssign_ to the target reg and attach a
bmux to select the target bit. */
lv = new NetAssign_(reg);
lv->set_bmux(mux);
} else {
/* If the bit/part select is constant, then make the
NetAssign_ only as wide as it needs to be and connect
only to the selected bits of the reg. */
unsigned loff = reg->sb_to_idx(lsb);
unsigned moff = reg->sb_to_idx(msb);
unsigned wid = moff - loff + 1;
if (moff < loff) {
cerr << get_line() << ": error: part select "
<< reg->name() << "[" << msb<<":"<<lsb<<"]"
<< " is reversed." << endl;
des->errors += 1;
return 0;
}
/* If the part select extends beyond the extreme of the
variable, then report an error. Note that loff is
converted to normalized form so is relative the
variable pins. */
if ((wid + loff) > reg->pin_count()) {
cerr << get_line() << ": error: bit/part select "
<< reg->name() << "[" << msb<<":"<<lsb<<"]"
<< " is out of range." << endl;
des->errors += 1;
return 0;
}
lv = new NetAssign_(reg);
lv->set_part(loff, wid);
assert(moff < reg->pin_count());
}
return lv;
}
/*
* $Log: elab_lval.cc,v $
* 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
* and uses less space. Make the NetAssignNB carry
* the delays instead of the NetAssign_ lval objects.
*
* Change the vvp code generator to support multiple
* l-values, i.e. concatenations of part selects.
*
* Revision 1.13 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.12 2001/02/09 03:16:48 steve
* Report bit/part select out of range errors. (PR#133)
*
* Revision 1.11 2001/01/10 03:13:23 steve
* Build task outputs as lval instead of nets. (PR#98)
*
* Revision 1.10 2001/01/06 06:31:58 steve
* declaration initialization for time variables.
*
* Revision 1.9 2001/01/06 02:29:36 steve
* Support arrays of integers.
*
* Revision 1.8 2000/12/12 06:14:51 steve
* sorry for concatenated memories in l-values. (PR#76)
*
* Revision 1.7 2000/12/01 02:55:37 steve
* Detect part select errors on l-values.
*
* Revision 1.6 2000/10/31 17:49:02 steve
* Support time variables.
*
* Revision 1.5 2000/10/26 17:09:46 steve
* Fix handling of errors in behavioral lvalues. (PR#28)
*
* Revision 1.4 2000/09/10 15:43:59 steve
* Some error checking.
*
* Revision 1.3 2000/09/10 03:59:59 steve
* Agressively merge NetAssign_ within concatenations.
*
* Revision 1.2 2000/09/10 02:18:16 steve
* elaborate complex l-values
*
* Revision 1.1 2000/09/09 15:21:26 steve
* move lval elaboration to PExpr virtual methods.
*
*/
+1491 -269
View File
File diff suppressed because it is too large Load Diff
+242
View File
@@ -0,0 +1,242 @@
/*
* Copyright (c) 2000 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: elab_pexpr.cc,v 1.9 2001/07/25 03:10:49 steve Exp $"
#endif
# include "config.h"
# include "PExpr.h"
# include "util.h"
# include <iostream>
NetExpr*PExpr::elaborate_pexpr(Design*des, NetScope*sc) const
{
cerr << get_line() << ": error: invalid parameter expression: "
<< *this << endl;
des->errors += 1;
return 0;
}
/*
* Binary operators have sub-expressions that must be elaborated as
* parameter expressions. If either of them fail, then give up. Once
* they are taken care of, make the base object just as in any other
* expression.
*/
NetExpr*PEBinary::elaborate_pexpr (Design*des, NetScope*scope) const
{
NetExpr*lp = left_->elaborate_pexpr(des, scope);
NetExpr*rp = right_->elaborate_pexpr(des, scope);
if ((lp == 0) || (rp == 0)) {
delete lp;
delete rp;
return 0;
}
NetEBinary*tmp = elaborate_expr_base_(des, lp, rp);
return tmp;
}
/*
* Event though parameters are not generally sized, parameter
* expressions can include concatenation expressions. This requires
* that the subexpressions all have well-defined size (in spite of
* being in a parameter expression) in order to get a defined
* value. The sub-expressions themsilves must also be value parameter
* expressions.
*/
NetEConcat* PEConcat::elaborate_pexpr(Design*des, NetScope*scope) const
{
unsigned repeat = 1;
/* 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. */
if (repeat_) {
verinum*vrep = repeat_->eval_const(des, scope->name());
if (vrep == 0) {
cerr << get_line() << ": error: "
"concatenation repeat expression cannot be evaluated."
<< endl;
des->errors += 1;
return 0;
}
repeat = vrep->as_ulong();
delete vrep;
}
/* Make the empty concat expression. */
NetEConcat*tmp = new NetEConcat(parms_.count(), repeat);
tmp->set_line(*this);
/* Elaborate all the operands and attach them to the concat
node. Use the elaborate_pexpr method instead of the
elaborate_expr method. */
for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) {
assert(parms_[idx]);
NetExpr*ex = parms_[idx]->elaborate_pexpr(des, scope);
if (ex == 0) continue;
ex->set_line(*parms_[idx]);
tmp->set(idx, ex);
}
return tmp;
}
NetExpr*PEFNumber::elaborate_pexpr(Design*des, NetScope*scope) const
{
return elaborate_expr(des, scope);
}
/*
* Parameter expressions may reference other parameters, but only in
* the current scope. Preserve the parameter reference in the
* parameter expression I'm generating, instead of evaluating it now,
* because the referenced parameter may yet be overridden.
*/
NetExpr*PEIdent::elaborate_pexpr(Design*des, NetScope*scope) const
{
string path = text_;
string name = parse_last_name(path);
NetScope*pscope = scope;
if (path != "")
pscope = des->find_scope(scope, path);
assert(pscope);
const NetExpr*ex = pscope->get_parameter(name);
if (ex == 0) {
cerr << get_line() << ": error: identifier ``" << text_ <<
"'' is not a parameter in " << scope->name() << "." << endl;
des->errors += 1;
return 0;
}
NetExpr*res = new NetEParam(des, pscope, name);
assert(res);
return res;
}
/*
* Simple numbers can be elaborated by the elaborate_expr method.
*/
NetExpr*PENumber::elaborate_pexpr(Design*des, NetScope*sc) const
{
return elaborate_expr(des, sc);
}
NetEConst* PEString::elaborate_pexpr(Design*des, NetScope*scope) const
{
return elaborate_expr(des, scope);
}
NetETernary* PETernary::elaborate_pexpr(Design*des, NetScope*scope) const
{
NetExpr*c = expr_->elaborate_pexpr(des, scope);
NetExpr*t = tru_->elaborate_pexpr(des, scope);
NetExpr*f = fal_->elaborate_pexpr(des, scope);
if (c == 0) return 0;
if (t == 0) return 0;
if (f == 0) return 0;
return new NetETernary(c, t, f);
}
NetExpr*PEUnary::elaborate_pexpr (Design*des, NetScope*scope) const
{
NetExpr*ip = expr_->elaborate_pexpr(des, scope);
if (ip == 0) return 0;
/* Should we evaluate expressions ahead of time,
* just like in PEBinary::elaborate_expr() ?
*/
NetEUnary*tmp;
switch (op_) {
default:
tmp = new NetEUnary(op_, ip);
tmp->set_line(*this);
break;
case '~':
tmp = new NetEUBits(op_, ip);
tmp->set_line(*this);
break;
case '!': // Logical NOT
case '&': // Reduction AND
case '|': // Reduction OR
case '^': // Reduction XOR
case 'A': // Reduction NAND (~&)
case 'N': // Reduction NOR (~|)
case 'X': // Reduction NXOR (~^)
tmp = new NetEUReduce(op_, ip);
tmp->set_line(*this);
break;
}
return tmp;
}
/*
* $Log: elab_pexpr.cc,v $
* 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)
*
* Revision 1.8 2001/01/14 23:04:56 steve
* Generalize the evaluation of floating point delays, and
* get it working with delay assignment statements.
*
* Allow parameters to be referenced by hierarchical name.
*
* Revision 1.7 2001/01/02 04:21:13 steve
* Support a bunch of unary operators in parameter expressions.
*
* Revision 1.6 2000/12/16 19:03:30 steve
* Evaluate <= and ?: in parameter expressions (PR#81)
*
* Revision 1.5 2000/06/13 05:22:16 steve
* Support concatenation in parameter expressions.
*
* Revision 1.4 2000/06/01 02:31:39 steve
* Parameters can be strings.
*
* Revision 1.3 2000/03/12 18:22:11 steve
* Binary and unary operators in parameter expressions.
*
* Revision 1.2 2000/03/12 04:35:22 steve
* Allow parameter identifiers in parameter expressions.
*
* Revision 1.1 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.
*
*/
+495
View File
@@ -0,0 +1,495 @@
/*
* Copyright (c) 2000 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: elab_scope.cc,v 1.9 2001/07/25 03:10:49 steve Exp $"
#endif
# include "config.h"
# include <iostream>
/*
* Elaboration happens in two passes, generally. The first scans the
* pform to generate the NetScope tree and attach it to the Design
* object. The methods in this source file implement the elaboration
* of the scopes.
*/
# include "Module.h"
# include "PEvent.h"
# include "PExpr.h"
# include "PGate.h"
# include "PTask.h"
# include "PWire.h"
# include "Statement.h"
# include "netlist.h"
# include <typeinfo>
bool Module::elaborate_scope(Design*des, NetScope*scope) const
{
// Generate all the parameters that this instance of this
// module introduces to the design. This loop elaborates the
// parameters, but doesn't evaluate references to
// parameters. This scan practically locates all the
// parameters and puts them in the parameter table in the
// design.
// No expressions are evaluated, yet. For now, leave them in
// the pform and just place a NetEParam placeholder in the
// place of the elaborated expression.
typedef map<string,PExpr*>::const_iterator mparm_it_t;
// This loop scans the parameters in the module, and creates
// stub parameter entries in the scope for the parameter name.
for (mparm_it_t cur = parameters.begin()
; cur != parameters.end() ; cur ++) {
scope->set_parameter((*cur).first, new NetEParam);
}
for (mparm_it_t cur = localparams.begin()
; cur != localparams.end() ; cur ++) {
scope->set_parameter((*cur).first, new NetEParam);
}
// Now scan the parameters again, this time elaborating them
// for use as parameter values. This is after the previous
// scan so that local parameter names can be used in the
// r-value expressions.
for (mparm_it_t cur = parameters.begin()
; cur != parameters.end() ; cur ++) {
PExpr*ex = (*cur).second;
assert(ex);
NetExpr*val = ex->elaborate_pexpr(des, scope);
val = scope->set_parameter((*cur).first, val);
assert(val);
delete val;
}
for (mparm_it_t cur = localparams.begin()
; cur != localparams.end() ; cur ++) {
PExpr*ex = (*cur).second;
assert(ex);
NetExpr*val = ex->elaborate_pexpr(des, scope);
val = scope->set_parameter((*cur).first, val);
assert(val);
delete val;
}
// Run through the defparams for this module, elaborate the
// expressions in this context and save the result is a table
// for later final override.
// It is OK to elaborate the expressions of the defparam here
// because Verilog requires that the expressions only use
// local parameter names. It is *not* OK to do the override
// here becuase the parameter receiving the assignment may be
// in a scope not discovered by this pass.
for (mparm_it_t cur = defparms.begin()
; cur != defparms.end() ; cur ++ ) {
PExpr*ex = (*cur).second;
assert(ex);
NetExpr*val = ex->elaborate_pexpr(des, scope);
if (val == 0) continue;
scope->defparams[(*cur).first] = val;
}
// Tasks introduce new scopes, so scan the tasks in this
// module. Create a scope for the task and pass that to the
// elaborate_scope method of the PTask for detailed
// processing.
typedef map<string,PTask*>::const_iterator tasks_it_t;
for (tasks_it_t cur = tasks_.begin()
; cur != tasks_.end() ; cur ++ ) {
NetScope*task_scope = new NetScope(scope, (*cur).first,
NetScope::TASK);
(*cur).second->elaborate_scope(des, task_scope);
}
// Functions are very similar to tasks, at least from the
// perspective of scopes. So handle them exactly the same
// way.
typedef map<string,PFunction*>::const_iterator funcs_it_t;
for (funcs_it_t cur = funcs_.begin()
; cur != funcs_.end() ; cur ++ ) {
NetScope*func_scope = new NetScope(scope, (*cur).first,
NetScope::FUNC);
(*cur).second->elaborate_scope(des, func_scope);
}
// Gates include modules, which might introduce new scopes, so
// scan all of them to create those scopes.
typedef list<PGate*>::const_iterator gates_it_t;
for (gates_it_t cur = gates_.begin()
; cur != gates_.end() ; cur ++ ) {
(*cur) -> elaborate_scope(des, scope);
}
// initial and always blocks may contain begin-end and
// fork-join blocks that can introduce scopes. Therefore, I
// get to scan processes here.
typedef list<PProcess*>::const_iterator proc_it_t;
for (proc_it_t cur = behaviors_.begin()
; cur != behaviors_.end() ; cur ++ ) {
(*cur) -> statement() -> elaborate_scope(des, scope);
}
// Scan through all the named events in this scope. We do not
// need anything more then the current scope to do this
// elaboration, so do it now. This allows for normal
// elaboration to reference these events.
for (map<string,PEvent*>::const_iterator et = events.begin()
; et != events.end() ; et ++ ) {
(*et).second->elaborate_scope(des, scope);
}
return des->errors == 0;
}
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;
des->errors += 1;
return;
}
// 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())) {
cerr << get_line() << ": error: Instance/Scope name " <<
get_name() << " already used in this context." <<
endl;
des->errors += 1;
return;
}
// check for recursive instantiation by scanning the current
// scope and its parents. Look for a module instantiation of
// the same module, but farther up in the scope.
for (NetScope*scn = sc ; scn ; scn = scn->parent()) {
if (scn->type() != NetScope::MODULE)
continue;
if (mod->get_name() != scn->module_name())
continue;
cerr << get_line() << ": error: You cannot instantiate "
<< "module " << mod->get_name() << " within itself." << endl;
cerr << get_line() << ": : The offending instance is "
<< sc->name() << "." << get_name() << " within "
<< scn->name() << "." << endl;
des->errors += 1;
return;
}
// 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());
// Set time units and precision.
my_scope->time_unit(mod->time_unit);
my_scope->time_precision(mod->time_precision);
des->set_precision(mod->time_precision);
// This call actually arranges for the description of the
// module type to process this instance and handle parameters
// and sub-scopes that might occur. Parameters are also
// created in that scope, as they exist. (I'll override them
// later.)
mod->elaborate_scope(des, my_scope);
// Look for module parameter replacements. This map receives
// those replacements.
typedef map<string,PExpr*>::const_iterator mparm_it_t;
map<string,PExpr*> replace;
// Positional parameter overrides are matched to parameter
// names by using the param_names list of parameter
// names. This is an ordered list of names so the first name
// is parameter 0, the second parameter 1, and so on.
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];
}
}
// Named parameter overrides carry a name with each override
// so the mapping into the replace list is much easier.
if (parms_) {
assert(overrides_ == 0);
for (unsigned idx = 0 ; idx < nparms_ ; idx += 1)
replace[parms_[idx].name] = parms_[idx].parm;
}
// And here we scan the replacements we collected. Elaborate
// the expression in my context, then replace the sub-scope
// parameter value with the new expression.
for (mparm_it_t cur = replace.begin()
; cur != replace.end() ; cur ++ ) {
PExpr*tmp = (*cur).second;
NetExpr*val = tmp->elaborate_pexpr(des, sc);
val = my_scope->set_parameter((*cur).first, val);
assert(val);
delete val;
}
}
/*
* 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.
*/
void PEvent::elaborate_scope(Design*des, NetScope*scope) const
{
NetEvent*ev = new NetEvent(name_);
ev->set_line(*this);
scope->add_event(ev);
}
void PFunction::elaborate_scope(Design*des, NetScope*scope) const
{
}
void PTask::elaborate_scope(Design*des, NetScope*scope) const
{
assert(scope->type() == NetScope::TASK);
}
/*
* The base statement does not have sub-statements and does not
* introduce any scope, so this is a no-op.
*/
void Statement::elaborate_scope(Design*, NetScope*) const
{
}
/*
* When I get a behavioral block, check to see if it has a name. If it
* does, then create a new scope for the statements within it,
* otherwise use the current scope. Use the selected scope to scan the
* statements that I contain.
*/
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
? NetScope::FORK_JOIN
: NetScope::BEGIN_END);
}
for (unsigned idx = 0 ; idx < list_.count() ; idx += 1)
list_[idx] -> elaborate_scope(des, my_scope);
}
/*
* The case statement itseof does not introduce scope, but contains
* other statements that may be named blocks. So scan the case items
* with the elaborate_scope method.
*/
void PCase::elaborate_scope(Design*des, NetScope*scope) const
{
assert(items_);
for (unsigned idx = 0 ; idx < (*items_).count() ; idx += 1) {
assert( (*items_)[idx] );
if (Statement*sp = (*items_)[idx]->stat)
sp -> elaborate_scope(des, scope);
}
}
/*
* The conditional statement (if-else) does not introduce scope, but
* the statements of the clauses may, so elaborate_scope the contained
* statements.
*/
void PCondit::elaborate_scope(Design*des, NetScope*scope) const
{
if (if_)
if_ -> elaborate_scope(des, scope);
if (else_)
else_ -> elaborate_scope(des, scope);
}
/*
* Statements that contain a further statement but do not
* intrinsically add a scope need to elaborate_scope the contained
* statement.
*/
void PDelayStatement::elaborate_scope(Design*des, NetScope*scope) const
{
if (statement_)
statement_ -> elaborate_scope(des, scope);
}
/*
* Statements that contain a further statement but do not
* intrinsically add a scope need to elaborate_scope the contained
* statement.
*/
void PEventStatement::elaborate_scope(Design*des, NetScope*scope) const
{
if (statement_)
statement_ -> elaborate_scope(des, scope);
}
/*
* Statements that contain a further statement but do not
* intrinsically add a scope need to elaborate_scope the contained
* statement.
*/
void PForever::elaborate_scope(Design*des, NetScope*scope) const
{
if (statement_)
statement_ -> elaborate_scope(des, scope);
}
/*
* Statements that contain a further statement but do not
* intrinsically add a scope need to elaborate_scope the contained
* statement.
*/
void PForStatement::elaborate_scope(Design*des, NetScope*scope) const
{
if (statement_)
statement_ -> elaborate_scope(des, scope);
}
/*
* Statements that contain a further statement but do not
* intrinsically add a scope need to elaborate_scope the contained
* statement.
*/
void PRepeat::elaborate_scope(Design*des, NetScope*scope) const
{
if (statement_)
statement_ -> elaborate_scope(des, scope);
}
/*
* Statements that contain a further statement but do not
* intrinsically add a scope need to elaborate_scope the contained
* statement.
*/
void PWhile::elaborate_scope(Design*des, NetScope*scope) const
{
if (statement_)
statement_ -> elaborate_scope(des, scope);
}
/*
* $Log: elab_scope.cc,v $
* 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)
*
* Revision 1.8 2001/04/28 23:18:08 steve
* UDP instances need not have user supplied names.
*
* Revision 1.7 2000/12/16 01:45:48 steve
* Detect recursive instantiations (PR#2)
*
* Revision 1.6 2000/07/30 18:25:43 steve
* Rearrange task and function elaboration so that the
* NetTaskDef and NetFuncDef functions are created during
* signal enaboration, and carry these objects in the
* NetScope class instead of the extra, useless map in
* the Design class.
*
* Revision 1.5 2000/07/22 22:09:03 steve
* Parse and elaborate timescale to scopes.
*
* Revision 1.4 2000/04/09 17:44:30 steve
* Catch event declarations during scope elaborate.
*
* Revision 1.3 2000/03/12 17:09:41 steve
* Support localparam.
*
* Revision 1.2 2000/03/11 03:25:52 steve
* Locate scopes in statements.
*
* Revision 1.1 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.
*
*/
+502
View File
@@ -0,0 +1,502 @@
/*
* Copyright (c) 2000 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: elab_sig.cc,v 1.14 2001/07/25 03:10:49 steve Exp $"
#endif
# include "config.h"
# include <iostream>
# include "Module.h"
# include "PExpr.h"
# include "PGate.h"
# include "PTask.h"
# include "PWire.h"
# include "netlist.h"
# include "netmisc.h"
# include "util.h"
/*
* This local function checks if a named signal is connected to a
* port. It looks in the array of ports passed, for NetEIdent objects
* within the port_t that have a matching name.
*/
static bool signal_is_in_port(const svector<Module::port_t*>&ports,
const string&name)
{
for (unsigned idx = 0 ; idx < ports.count() ; idx += 1) {
Module::port_t*pp = ports[idx];
// Skip internally unconnected ports.
if (pp == 0)
continue;
// This port has an internal connection. In this case,
// the port has 0 or more NetEIdent objects concatenated
// 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)
return true;
}
}
return false;
}
bool Module::elaborate_sig(Design*des, NetScope*scope) const
{
bool flag = true;
// Get all the explicitly declared wires of the module and
// start the signals list with them.
const map<string,PWire*>&wl = get_wires();
for (map<string,PWire*>::const_iterator wt = wl.begin()
; wt != wl.end()
; wt ++ ) {
PWire*cur = (*wt).second;
cur->elaborate_sig(des, scope);
// 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());
if (sig && (sig->scope() == scope)
&& (cur->get_port_type() != NetNet::NOT_A_PORT)) {
string name = (*wt).first;
if (! signal_is_in_port(ports_, name)) {
cerr << cur->get_line() << ": error: Signal "
<< name << " has a declared direction "
<< "but is not a port." << endl;
des->errors += 1;
}
}
/* If the signal is an input and is also declared as a
reg, then report an error. */
if (sig && (sig->scope() == scope)
&& (sig->port_type() == NetNet::PINPUT)
&& (sig->type() == NetNet::REG)) {
cerr << cur->get_line() << ": error: "
<< cur->name() << " in module "
<< scope->module_name()
<< " declared as input and as a reg type." << endl;
des->errors += 1;
}
if (sig && (sig->scope() == scope)
&& (sig->port_type() == NetNet::PINOUT)
&& (sig->type() == NetNet::REG)) {
cerr << cur->get_line() << ": error: "
<< cur->name() << " in module "
<< scope->module_name()
<< " declared as inout and as a reg type." << endl;
des->errors += 1;
}
}
// Get all the gates of the module and elaborate them by
// connecting them to the signals. The gate may be simple or
// complex. What we are looking for is gates that are modules
// that can create scopes and signals.
const list<PGate*>&gl = get_gates();
for (list<PGate*>::const_iterator gt = gl.begin()
; gt != gl.end()
; gt ++ ) {
flag &= (*gt)->elaborate_sig(des, scope);
}
typedef map<string,PFunction*>::const_iterator mfunc_it_t;
for (mfunc_it_t cur = funcs_.begin()
; cur != funcs_.end() ; cur ++) {
NetScope*fscope = scope->child((*cur).first);
if (scope == 0) {
cerr << (*cur).second->get_line() << ": internal error: "
<< "Child scope for function " << (*cur).first
<< " missing in " << scope->name() << "." << endl;
des->errors += 1;
continue;
}
(*cur).second->elaborate_sig(des, fscope);
}
// After all the wires are elaborated, we are free to
// elaborate the ports of the tasks defined within this
// module. Run through them now.
typedef map<string,PTask*>::const_iterator mtask_it_t;
for (mtask_it_t cur = tasks_.begin()
; cur != tasks_.end() ; cur ++) {
NetScope*tscope = scope->child((*cur).first);
assert(tscope);
(*cur).second->elaborate_sig(des, tscope);
}
return flag;
}
bool PGModule::elaborate_sig_mod_(Design*des, NetScope*scope,
Module*rmod) const
{
// Missing module instance names have already been rejected.
assert(get_name() != "");
if (msb_) {
cerr << get_line() << ": sorry: Module instantiation arrays "
"are not yet supported." << endl;
des->errors += 1;
return false;
}
// I know a priori that the elaborate_scope created the scope
// already, so just look it up as a child of the current scope.
NetScope*my_scope = scope->child(get_name());
assert(my_scope);
return rmod->elaborate_sig(des, my_scope);
}
/*
* A function definition exists within an elaborated module.
*/
void PFunction::elaborate_sig(Design*des, NetScope*scope) const
{
string fname = scope->basename();
assert(scope->type() == NetScope::FUNC);
svector<NetNet*>ports (ports_? ports_->count()+1 : 1);
/* Get the reg for the return value. I know the name of the
reg variable, and I know that it is in this scope, so look
it up directly. */
ports[0] = scope->find_signal(scope->basename());
if (ports[0] == 0) {
cerr << get_line() << ": internal error: function scope "
<< scope->name() << " is missing return reg "
<< fname << "." << endl;
scope->dump(cerr);
des->errors += 1;
return;
}
if (ports_)
for (unsigned idx = 0 ; idx < ports_->count() ; idx += 1) {
/* Parse the port name into the task name and the reg
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);
if (ppath != scope->basename()) {
cerr << get_line() << ": internal error: function "
<< "port " << (*ports_)[idx]->name()
<< " has wrong name for function "
<< scope->name() << "." << endl;
des->errors += 1;
}
NetNet*tmp = scope->find_signal(pname);
if (tmp == 0) {
cerr << get_line() << ": internal error: function "
<< scope->name() << " is missing port "
<< pname << "." << endl;
scope->dump(cerr);
des->errors += 1;
}
ports[idx+1] = tmp;
}
NetFuncDef*def = new NetFuncDef(scope, ports);
scope->set_func_def(def);
}
/*
* A task definition is a scope within an elaborated module. When we
* are elaborating signals, the scopes have already been created, as
* have the reg objects that are the parameters of this task. The
* elaborate_sig method of PTask is therefore left to connect the
* signals to the ports of the NetTaskDef definition. We know for
* certain that signals exist (They are in my scope!) so the port
* binding is sure to work.
*/
void PTask::elaborate_sig(Design*des, NetScope*scope) const
{
assert(scope->type() == NetScope::TASK);
svector<NetNet*>ports (ports_? ports_->count() : 0);
for (unsigned idx = 0 ; idx < ports.count() ; idx += 1) {
/* Parse the port name into the task name and the reg
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 != "");
/* 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
<< " not the same as scope " << scope->name()
<< "?!" << endl;
return;
}
/* 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);
if (tmp == 0) {
cerr << get_line() << ": internal error: "
<< "Could not find port " << pname
<< " in scope " << scope->name() << endl;
scope->dump(cerr);
}
ports[idx] = tmp;
}
NetTaskDef*def = new NetTaskDef(scope->name(), ports);
scope->set_task_def(def);
}
bool PGate::elaborate_sig(Design*des, NetScope*scope) const
{
return true;
}
/*
* Elaborate a source wire. The "wire" is the declaration of wires,
* registers, ports and memories. The parser has already merged the
* multiple properties of a wire (i.e. "input wire") so come the
* elaboration this creates an object in the design that represent the
* defined item.
*/
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);
}
const string path = scope->name();
NetNet::Type wtype = type_;
if (wtype == NetNet::IMPLICIT)
wtype = NetNet::WIRE;
if (wtype == NetNet::IMPLICIT_REG)
wtype = NetNet::REG;
unsigned wid = 1;
long lsb = 0, msb = 0;
assert(msb_.count() == lsb_.count());
if (msb_.count()) {
svector<long>mnum (msb_.count());
svector<long>lnum (msb_.count());
/* There may be multiple declarations of ranges, because
the symbol may have its range declared in i.e. input
and reg declarations. Calculate *all* the numbers
here. I will resolve the values later. */
for (unsigned idx = 0 ; idx < msb_.count() ; idx += 1) {
NetEConst*tmp;
NetExpr*texpr = elab_and_eval(des, scope, msb_[idx]);
tmp = dynamic_cast<NetEConst*>(texpr);
if (tmp == 0) {
cerr << msb_[idx]->get_line() << ": error: "
"Unable to evaluate constant expression ``" <<
*msb_[idx] << "''." << endl;
des->errors += 1;
return;
}
mnum[idx] = tmp->value().as_long();
delete texpr;
texpr = elab_and_eval(des, scope, lsb_[idx]);
tmp = dynamic_cast<NetEConst*>(texpr);
if (tmp == 0) {
cerr << msb_[idx]->get_line() << ": error: "
"Unable to evaluate constant expression ``" <<
*lsb_[idx] << "''." << endl;
des->errors += 1;
return;
}
lnum[idx] = tmp->value().as_long();
delete texpr;
}
/* 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) {
if ((mnum[idx] != mnum[0]) || (lnum[idx] != lnum[0])) {
cerr << get_line() << ": error: Inconsistent width, "
"[" << mnum[idx] << ":" << lnum[idx] << "]"
" vs. [" << mnum[0] << ":" << lnum[0] << "]"
" for signal ``" << basename << "''" << endl;
des->errors += 1;
return;
}
}
lsb = lnum[0];
msb = mnum[0];
if (mnum[0] > lnum[0])
wid = mnum[0] - lnum[0] + 1;
else
wid = lnum[0] - mnum[0] + 1;
}
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);
if ((lval == 0) || (rval == 0)) {
cerr << get_line() << ": internal error: There is "
<< "a problem evaluating indices for ``"
<< basename << "''." << endl;
des->errors += 1;
return;
}
assert(lval);
assert(rval);
long lnum = lval->as_long();
long rnum = rval->as_long();
delete lval;
delete rval;
NetMemory*sig = new NetMemory(scope, path+"."+basename,
wid, lnum, rnum);
} else {
NetNet*sig = new NetNet(scope, path + "." +basename, wtype, msb, lsb);
sig->set_line(*this);
sig->port_type(port_type_);
sig->set_signed(get_signed());
sig->set_attributes(attributes);
}
}
/*
* $Log: elab_sig.cc,v $
* 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)
*
* Revision 1.13 2001/05/25 02:21:34 steve
* Detect input and input ports declared as reg.
*
* Revision 1.12 2001/02/17 05:15:33 steve
* Allow task ports to be given real types.
*
* Revision 1.11 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.10 2001/01/13 22:20:08 steve
* Parse parameters within nested scopes.
*
* Revision 1.9 2001/01/07 07:00:31 steve
* Detect port direction attached to non-ports.
*
* Revision 1.8 2001/01/04 04:47:51 steve
* Add support for << is signal indices.
*
* Revision 1.7 2000/12/11 00:31:43 steve
* Add support for signed reg variables,
* simulate in t-vvm signed comparisons.
*
* Revision 1.6 2000/12/04 17:37:04 steve
* Add Attrib class for holding NetObj attributes.
*
* Revision 1.5 2000/11/20 00:58:40 steve
* Add support for supply nets (PR#17)
*
* Revision 1.4 2000/09/07 22:37:48 steve
* ack, detect when lval fails.
*
* Revision 1.3 2000/07/30 18:25:43 steve
* Rearrange task and function elaboration so that the
* NetTaskDef and NetFuncDef functions are created during
* signal enaboration, and carry these objects in the
* NetScope class instead of the extra, useless map in
* the Design class.
*
* Revision 1.2 2000/07/14 06:12:57 steve
* Move inital value handling from NetNet to Nexus
* objects. This allows better propogation of inital
* values.
*
* Clean up constant propagation a bit to account
* for regs that are not really values.
*
* Revision 1.1 2000/05/02 16:27:38 steve
* Move signal elaboration to a seperate pass.
*
*/
+1297 -917
View File
File diff suppressed because it is too large Load Diff
+283 -237
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998 Stephen Williams ([email protected])
* Copyright (c) 1998-2000 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
@@ -16,200 +16,242 @@
* 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: emit.cc,v 1.31 1999/11/28 23:42:02 steve Exp $"
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: emit.cc,v 1.62 2001/08/25 23:50:02 steve Exp $"
#endif
# include "config.h"
# include <iostream>
/*
* The emit function is called to generate the output required of the
* target.
*/
# include "target.h"
# include "netlist.h"
# include <iostream>
# include <typeinfo>
# include <cassert>
void NetNode::emit_node(ostream&o, struct target_t*tgt) const
bool NetNode::emit_node(struct target_t*tgt) const
{
cerr << "EMIT: Gate type? " << typeid(*this).name() << endl;
return false;
}
void NetLogic::emit_node(ostream&o, struct target_t*tgt) const
bool NetLogic::emit_node(struct target_t*tgt) const
{
tgt->logic(o, this);
tgt->logic(this);
return true;
}
void NetUDP::emit_node(ostream&o, struct target_t*tgt) const
bool NetUDP::emit_node(struct target_t*tgt) const
{
tgt->udp(o, this);
tgt->udp(this);
return true;
}
void NetAddSub::emit_node(ostream&o, struct target_t*tgt) const
bool NetAddSub::emit_node(struct target_t*tgt) const
{
tgt->lpm_add_sub(o, this);
tgt->lpm_add_sub(this);
return true;
}
void NetAssign::emit_node(ostream&o, struct target_t*tgt) const
bool NetCaseCmp::emit_node(struct target_t*tgt) const
{
tgt->net_assign(o, this);
tgt->net_case_cmp(this);
return true;
}
void NetAssignNB::emit_node(ostream&o, struct target_t*tgt) const
bool NetCAssign::emit_node(struct target_t*tgt) const
{
tgt->net_assign_nb(o, this);
tgt->net_cassign(this);
return true;
}
void NetCaseCmp::emit_node(ostream&o, struct target_t*tgt) const
bool NetCLShift::emit_node(struct target_t*tgt) const
{
tgt->net_case_cmp(o, this);
tgt->lpm_clshift(this);
return true;
}
void NetCLShift::emit_node(ostream&o, struct target_t*tgt) const
bool NetCompare::emit_node(struct target_t*tgt) const
{
tgt->lpm_clshift(o, this);
tgt->lpm_compare(this);
return true;
}
void NetCompare::emit_node(ostream&o, struct target_t*tgt) const
bool NetConst::emit_node(struct target_t*tgt) const
{
tgt->lpm_compare(o, this);
return tgt->net_const(this);
}
void NetConst::emit_node(ostream&o, struct target_t*tgt) const
bool NetDivide::emit_node(struct target_t*tgt) const
{
tgt->net_const(o, this);
tgt->lpm_divide(this);
return true;
}
void NetFF::emit_node(ostream&o, struct target_t*tgt) const
bool NetFF::emit_node(struct target_t*tgt) const
{
tgt->lpm_ff(o, this);
tgt->lpm_ff(this);
return true;
}
void NetMux::emit_node(ostream&o, struct target_t*tgt) const
bool NetForce::emit_node(struct target_t*tgt) const
{
tgt->lpm_mux(o, this);
tgt->net_force(this);
return true;
}
void NetRamDq::emit_node(ostream&o, struct target_t*tgt) const
bool NetModulo::emit_node(struct target_t*tgt) const
{
tgt->lpm_ram_dq(o, this);
tgt->lpm_modulo(this);
return true;
}
void NetNEvent::emit_node(ostream&o, struct target_t*tgt) const
bool NetMult::emit_node(struct target_t*tgt) const
{
tgt->net_event(o, this);
tgt->lpm_mult(this);
return true;
}
void NetBUFZ::emit_node(ostream&o, struct target_t*tgt) const
bool NetMux::emit_node(struct target_t*tgt) const
{
tgt->bufz(o, this);
tgt->lpm_mux(this);
return true;
}
bool NetProcTop::emit(ostream&o, struct target_t*tgt) const
bool NetRamDq::emit_node(struct target_t*tgt) const
{
return tgt->process(o, this);
tgt->lpm_ram_dq(this);
return true;
}
bool NetProc::emit_proc(ostream&o, struct target_t*tgt) const
bool NetBUFZ::emit_node(struct target_t*tgt) const
{
return tgt->bufz(this);
}
bool NetProcTop::emit(struct target_t*tgt) const
{
return tgt->process(this);
}
bool NetProc::emit_proc(struct target_t*tgt) const
{
cerr << "EMIT: Proc type? " << typeid(*this).name() << endl;
return false;
}
bool NetAssign::emit_proc(ostream&o, struct target_t*tgt) const
bool NetAssign::emit_proc(struct target_t*tgt) const
{
tgt->proc_assign(o, this);
tgt->proc_assign(this);
return true;
}
bool NetAssignNB::emit_proc(ostream&o, struct target_t*tgt) const
bool NetAssignNB::emit_proc(struct target_t*tgt) const
{
tgt->proc_assign_nb(o, this);
tgt->proc_assign_nb(this);
return true;
}
bool NetAssignMem::emit_proc(ostream&o, struct target_t*tgt) const
bool NetAssignMem::emit_proc(struct target_t*tgt) const
{
tgt->proc_assign_mem(o, this);
tgt->proc_assign_mem(this);
return true;
}
bool NetAssignMemNB::emit_proc(ostream&o, struct target_t*tgt) const
bool NetAssignMemNB::emit_proc(struct target_t*tgt) const
{
tgt->proc_assign_mem_nb(o, this);
tgt->proc_assign_mem_nb(this);
return true;
}
bool NetBlock::emit_proc(ostream&o, struct target_t*tgt) const
bool NetBlock::emit_proc(struct target_t*tgt) const
{
return tgt->proc_block(o, this);
return tgt->proc_block(this);
}
bool NetCase::emit_proc(ostream&o, struct target_t*tgt) const
bool NetCase::emit_proc(struct target_t*tgt) const
{
tgt->proc_case(o, this);
tgt->proc_case(this);
return true;
}
bool NetCondit::emit_proc(ostream&o, struct target_t*tgt) const
bool NetCAssign::emit_proc(struct target_t*tgt) const
{
tgt->proc_condit(o, this);
return tgt->proc_cassign(this);
}
bool NetCondit::emit_proc(struct target_t*tgt) const
{
tgt->proc_condit(this);
return true;
}
bool NetForever::emit_proc(ostream&o, struct target_t*tgt) const
bool NetDeassign::emit_proc(struct target_t*tgt) const
{
tgt->proc_forever(o, this);
return tgt->proc_deassign(this);
}
bool NetDisable::emit_proc(struct target_t*tgt) const
{
return tgt->proc_disable(this);
}
bool NetForce::emit_proc(struct target_t*tgt) const
{
return tgt->proc_force(this);
}
bool NetForever::emit_proc(struct target_t*tgt) const
{
tgt->proc_forever(this);
return true;
}
bool NetPDelay::emit_proc(ostream&o, struct target_t*tgt) const
bool NetPDelay::emit_proc(struct target_t*tgt) const
{
tgt->proc_delay(o, this);
return tgt->proc_delay(this);
}
bool NetPDelay::emit_proc_recurse(struct target_t*tgt) const
{
if (statement_) return statement_->emit_proc(tgt);
return true;
}
void NetPDelay::emit_proc_recurse(ostream&o, struct target_t*tgt) const
bool NetRelease::emit_proc(struct target_t*tgt) const
{
if (statement_) statement_->emit_proc(o, tgt);
return tgt->proc_release(this);
}
bool NetPEvent::emit_proc(ostream&o, struct target_t*tgt) const
bool NetRepeat::emit_proc(struct target_t*tgt) const
{
tgt->proc_event(o, this);
tgt->proc_repeat(this);
return true;
}
void NetPEvent::emit_proc_recurse(ostream&o, struct target_t*tgt) const
bool NetSTask::emit_proc(struct target_t*tgt) const
{
if (statement_) statement_->emit_proc(o, tgt);
}
bool NetRepeat::emit_proc(ostream&o, struct target_t*tgt) const
{
tgt->proc_repeat(o, this);
tgt->proc_stask(this);
return true;
}
bool NetSTask::emit_proc(ostream&o, struct target_t*tgt) const
bool NetUTask::emit_proc(struct target_t*tgt) const
{
tgt->proc_stask(o, this);
tgt->proc_utask(this);
return true;
}
bool NetUTask::emit_proc(ostream&o, struct target_t*tgt) const
bool NetWhile::emit_proc(struct target_t*tgt) const
{
tgt->proc_utask(o, this);
tgt->proc_while(this);
return true;
}
bool NetWhile::emit_proc(ostream&o, struct target_t*tgt) const
{
tgt->proc_while(o, this);
return true;
}
void NetBlock::emit_recurse(ostream&o, struct target_t*tgt) const
void NetBlock::emit_recurse(struct target_t*tgt) const
{
if (last_ == 0)
return;
@@ -217,101 +259,140 @@ void NetBlock::emit_recurse(ostream&o, struct target_t*tgt) const
NetProc*cur = last_;
do {
cur = cur->next_;
cur->emit_proc(o, tgt);
cur->emit_proc(tgt);
} while (cur != last_);
}
void NetCondit::emit_recurse_if(ostream&o, struct target_t*tgt) const
void NetCondit::emit_recurse_if(struct target_t*tgt) const
{
if (if_)
if_->emit_proc(o, tgt);
if_->emit_proc(tgt);
}
void NetCondit::emit_recurse_else(ostream&o, struct target_t*tgt) const
void NetCondit::emit_recurse_else(struct target_t*tgt) const
{
if (else_)
else_->emit_proc(o, tgt);
else_->emit_proc(tgt);
}
void NetForever::emit_recurse(ostream&o, struct target_t*tgt) const
bool NetEvProbe::emit_node(struct target_t*tgt) const
{
tgt->net_probe(this);
return true;
}
bool NetEvTrig::emit_proc(struct target_t*tgt) const
{
return tgt->proc_trigger(this);
}
bool NetEvWait::emit_proc(struct target_t*tgt) const
{
return tgt->proc_wait(this);
}
bool NetEvWait::emit_recurse(struct target_t*tgt) const
{
if (!statement_) return true;
return statement_->emit_proc(tgt);
}
void NetForever::emit_recurse(struct target_t*tgt) const
{
if (statement_)
statement_->emit_proc(o, tgt);
statement_->emit_proc(tgt);
}
void NetRepeat::emit_recurse(ostream&o, struct target_t*tgt) const
void NetRepeat::emit_recurse(struct target_t*tgt) const
{
if (statement_)
statement_->emit_proc(o, tgt);
statement_->emit_proc(tgt);
}
void NetWhile::emit_proc_recurse(ostream&o, struct target_t*tgt) const
void NetScope::emit_scope(struct target_t*tgt) const
{
proc_->emit_proc(o, tgt);
}
tgt->scope(this);
bool Design::emit(ostream&o, struct target_t*tgt) const
{
bool rc = true;
tgt->start_design(o, this);
for (NetEvent*cur = events_ ; cur ; cur = cur->snext_)
tgt->event(cur);
// enumerate the scopes
{ map<string,NetScope*>::const_iterator sc;
for (sc = scopes_.begin() ; sc != scopes_.end() ; sc++) {
tgt->scope(o, (*sc).second);
}
}
for (NetScope*cur = sub_ ; cur ; cur = cur->sib_)
cur->emit_scope(tgt);
// emit signals
if (signals_) {
NetNet*cur = signals_->sig_next_;
do {
tgt->signal(o, cur);
tgt->signal(cur);
cur = cur->sig_next_;
} while (cur != signals_->sig_next_);
}
// emit memories
{
map<string,NetMemory*>::const_iterator mi;
for (mi = memories_.begin() ; mi != memories_.end() ; mi++) {
tgt->memory(o, (*mi).second);
}
if (memories_) {
NetMemory*cur = memories_->snext_;
do {
tgt->memory(cur);
cur = cur->snext_;
} while (cur != memories_->snext_);
}
}
void NetScope::emit_defs(struct target_t*tgt) const
{
switch (type_) {
case MODULE:
for (NetScope*cur = sub_ ; cur ; cur = cur->sib_)
cur->emit_defs(tgt);
break;
case FUNC:
tgt->func_def(this);
break;
case TASK:
tgt->task_def(this);
break;
}
}
void NetWhile::emit_proc_recurse(struct target_t*tgt) const
{
proc_->emit_proc(tgt);
}
bool Design::emit(struct target_t*tgt) const
{
bool rc = true;
rc = rc && tgt->start_design(this);
if (rc == false)
return false;
// enumerate the scopes
root_scope_->emit_scope(tgt);
// emit nodes
if (nodes_) {
NetNode*cur = nodes_->node_next_;
do {
cur->emit_node(o, tgt);
rc = rc && cur->emit_node(tgt);
cur = cur->node_next_;
} while (cur != nodes_->node_next_);
}
// emit function definitions
{
map<string,NetFuncDef*>::const_iterator ta;
for (ta = funcs_.begin() ; ta != funcs_.end() ; ta ++) {
tgt->func_def(o, (*ta).second);
}
}
// emit task and function definitions
root_scope_->emit_defs(tgt);
// emit task definitions
{
map<string,NetTaskDef*>::const_iterator ta;
for (ta = tasks_.begin() ; ta != tasks_.end() ; ta ++) {
tgt->task_def(o, (*ta).second);
}
}
// emit the processes
for (const NetProcTop*idx = procs_ ; idx ; idx = idx->next_)
rc = rc && idx->emit(o, tgt);
rc = rc && idx->emit(tgt);
if (tgt->end_design(this) != 0)
rc = false;
tgt->end_design(o, this);
return rc;
}
@@ -330,11 +411,6 @@ void NetEConst::expr_scan(struct expr_scan_t*tgt) const
tgt->expr_const(this);
}
void NetEIdent::expr_scan(struct expr_scan_t*tgt) const
{
tgt->expr_ident(this);
}
void NetEMemory::expr_scan(struct expr_scan_t*tgt) const
{
tgt->expr_memory(this);
@@ -351,6 +427,11 @@ void NetEScope::expr_scan(struct expr_scan_t*tgt) const
tgt->expr_scope(this);
}
void NetESFunc::expr_scan(struct expr_scan_t*tgt) const
{
tgt->expr_sfunc(this);
}
void NetEUFunc::expr_scan(struct expr_scan_t*tgt) const
{
tgt->expr_ufunc(this);
@@ -361,7 +442,7 @@ void NetESignal::expr_scan(struct expr_scan_t*tgt) const
tgt->expr_signal(this);
}
void NetESubSignal::expr_scan(struct expr_scan_t*tgt) const
void NetEBitSel::expr_scan(struct expr_scan_t*tgt) const
{
tgt->expr_subsignal(this);
}
@@ -376,12 +457,12 @@ void NetEUnary::expr_scan(struct expr_scan_t*tgt) const
tgt->expr_unary(this);
}
bool emit(ostream&o, const Design*des, const char*type)
bool emit(const Design*des, const char*type)
{
for (unsigned idx = 0 ; target_table[idx] ; idx += 1) {
const struct target*tgt = target_table[idx];
if (tgt->name == type)
return des->emit(o, tgt->meth);
if (strcmp(tgt->name, type) == 0)
return des->emit(tgt->meth);
}
}
@@ -389,135 +470,100 @@ bool emit(ostream&o, const Design*des, const char*type)
/*
* $Log: emit.cc,v $
* Revision 1.31 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.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
* and uses less space. Make the NetAssignNB carry
* the delays instead of the NetAssign_ lval objects.
*
* Revision 1.30 1999/11/27 19:07:57 steve
* Support the creation of scopes.
* Change the vvp code generator to support multiple
* l-values, i.e. concatenations of part selects.
*
* Revision 1.29 1999/11/21 00:13:08 steve
* Support memories in continuous assignments.
* Revision 1.61 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.28 1999/11/14 23:43:45 steve
* Support combinatorial comparators.
* Revision 1.60 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)
*
* Revision 1.27 1999/11/14 20:24:28 steve
* Add support for the LPM_CLSHIFT device.
* Revision 1.59 2001/04/22 23:09:46 steve
* More UDP consolidation from Stephan Boettcher.
*
* Revision 1.26 1999/11/04 03:53:26 steve
* Patch to synthesize unary ~ and the ternary operator.
* Thanks to Larry Doolittle <[email protected]>.
* Revision 1.58 2001/04/06 02:28:02 steve
* Generate vvp code for functions with ports.
*
* Add the LPM_MUX device, and integrate it with the
* ternary synthesis from Larry. Replace the lpm_mux
* generator in t-xnf.cc to use XNF EQU devices to
* put muxs into function units.
* Revision 1.57 2001/04/02 02:28:12 steve
* Generate code for task calls.
*
* Rewrite elaborate_net for the PETernary class to
* also use the LPM_MUX device.
* Revision 1.56 2001/03/27 03:31:06 steve
* Support error code from target_t::end_design method.
*
* Revision 1.25 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.55 2000/11/04 01:54:01 steve
* Modifications in support of gcc 2.96
*
* Revision 1.24 1999/10/10 01:59:54 steve
* Structural case equals device.
* Revision 1.54 2000/09/26 01:35:42 steve
* Remove the obsolete NetEIdent class.
*
* Revision 1.23 1999/09/22 16:57:23 steve
* Catch parallel blocks in vvm emit.
* Revision 1.53 2000/09/17 21:26:15 steve
* Add support for modulus (Eric Aardoom)
*
* Revision 1.22 1999/09/20 02:21:10 steve
* Elaborate parameters in phases.
* Revision 1.52 2000/09/02 20:54:20 steve
* Rearrange NetAssign to make NetAssign_ separate.
*
* Revision 1.21 1999/09/15 01:55:06 steve
* Elaborate non-blocking assignment to memories.
* Revision 1.51 2000/08/14 04:39:56 steve
* add th t-dll functions for net_const, net_bufz and processes.
*
* Revision 1.20 1999/09/03 04:28:38 steve
* elaborate the binary plus operator.
* Revision 1.50 2000/08/09 03:43:45 steve
* Move all file manipulation out of target class.
*
* Revision 1.19 1999/08/31 22:38:29 steve
* Elaborate and emit to vvm procedural functions.
* Revision 1.49 2000/08/08 01:50:42 steve
* target methods need not take a file stream.
*
* Revision 1.18 1999/07/17 19:50:59 steve
* netlist support for ternary operator.
* Revision 1.48 2000/07/30 18:25:43 steve
* Rearrange task and function elaboration so that the
* NetTaskDef and NetFuncDef functions are created during
* signal enaboration, and carry these objects in the
* NetScope class instead of the extra, useless map in
* the Design class.
*
* Revision 1.17 1999/07/17 03:39:11 steve
* simplified process scan for targets.
* Revision 1.47 2000/07/29 16:21:08 steve
* Report code generation errors through proc_delay.
*
* Revision 1.16 1999/07/07 04:20:57 steve
* Emit vvm for user defined tasks.
* Revision 1.46 2000/07/27 05:13:44 steve
* Support elaboration of disable statements.
*
* Revision 1.15 1999/07/03 02:12:51 steve
* Elaborate user defined tasks.
* Revision 1.45 2000/05/11 23:37:27 steve
* Add support for procedural continuous assignment.
*
* Revision 1.14 1999/06/19 21:06:16 steve
* Elaborate and supprort to vvm the forever
* and repeat statements.
* Revision 1.44 2000/05/04 03:37:58 steve
* Add infrastructure for system functions, move
* $time to that structure and add $random.
*
* Revision 1.13 1999/06/09 03:00:06 steve
* Add support for procedural concatenation expression.
* Revision 1.43 2000/05/02 03:13:31 steve
* Move memories to the NetScope object.
*
* Revision 1.12 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.42 2000/05/02 00:58:12 steve
* Move signal tables to the NetScope class.
*
* Revision 1.11 1999/05/12 04:03:19 steve
* emit NetAssignMem objects in vvm target.
* Revision 1.41 2000/04/23 03:45:24 steve
* Add support for the procedural release statement.
*
* Revision 1.10 1999/05/07 01:21:18 steve
* Handle total lack of nodes and signals.
* Revision 1.40 2000/04/22 04:20:19 steve
* Add support for force assignment.
*
* Revision 1.9 1999/05/01 02:57:53 steve
* Handle much more complex event expressions.
* Revision 1.39 2000/04/12 04:23:58 steve
* Named events really should be expressed with PEIdent
* objects in the pform,
*
* Revision 1.8 1999/04/25 00:44:10 steve
* Core handles subsignal expressions.
*
* Revision 1.7 1999/04/19 01:59:36 steve
* Add memories to the parse and elaboration phases.
*
* Revision 1.6 1999/02/08 02:49:56 steve
* Turn the NetESignal into a NetNode so
* that it can connect to the netlist.
* Implement the case statement.
* Convince t-vvm to output code for
* the case statement.
*
* Revision 1.5 1999/02/01 00:26:49 steve
* Carry some line info to the netlist,
* Dump line numbers for processes.
* Elaborate prints errors about port vector
* width mismatch
* Emit better handles null statements.
*
* Revision 1.4 1998/12/01 00:42:14 steve
* Elaborate UDP devices,
* Support UDP type attributes, and
* pass those attributes to nodes that
* are instantiated by elaboration,
* Put modules into a map instead of
* a simple list.
*
* Revision 1.3 1998/11/09 18:55:34 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:57 steve
* Introduce verilog to CVS.
* 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.
*/
+96 -5
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998 Stephen Williams ([email protected])
* Copyright (c) 1998-1999 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
@@ -16,12 +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
*/
#if !defined(WINNT)
#ident "$Id: eval.cc,v 1.12 1999/11/30 04:48:17 steve Exp $"
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: eval.cc,v 1.21 2001/07/25 03:10:49 steve Exp $"
#endif
# include "config.h"
# include <iostream>
# include "PExpr.h"
# include "netlist.h"
# include "compiler.h"
verinum* PExpr::eval_const(const Design*, const string&) const
{
@@ -81,22 +86,39 @@ verinum* PEBinary::eval_const(const Design*des, const string&path) const
res = new verinum(lv % rv, l->len());
break;
}
case 'l': {
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+rv, l->get(idx));
}
break;
}
default:
delete l;
delete r;
return 0;
}
delete l;
delete r;
return res;
}
/*
* 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
{
const NetExpr*expr = des->find_parameter(path, text_);
const NetScope*scope = des->find_scope(path);
assert(scope);
const NetExpr*expr = des->find_parameter(scope, text_);
if (expr == 0)
return 0;
@@ -105,7 +127,7 @@ verinum* PEIdent::eval_const(const Design*des, const string&path) const
if (dynamic_cast<const NetEParam*>(expr)) {
cerr << get_line() << ": sorry: I cannot evaluate ``" <<
text_ << "'' in this context." << endl;
text_ << "'' in this scope: " << scope->name() << endl;
return 0;
}
@@ -114,6 +136,12 @@ verinum* PEIdent::eval_const(const Design*des, const string&path) const
return new verinum(eval->value());
}
verinum* PEFNumber::eval_const(const Design*, const string&) const
{
long val = value_->as_long();
return new verinum(val);
}
verinum* PENumber::eval_const(const Design*, const string&) const
{
return new verinum(value());
@@ -139,9 +167,72 @@ verinum* PETernary::eval_const(const Design*des, const string&path) const
}
}
verinum* PEUnary::eval_const(const Design*des, const string&path) const
{
verinum*val = expr_->eval_const(des, path);
if (val == 0)
return 0;
switch (op_) {
case '+':
return val;
case '-': {
/* We need to expand the value a bit if we are
taking the 2's complement so that we are
guaranteed to not overflow. */
verinum tmp (0UL, val->len()+1);
for (unsigned idx = 0 ; idx < val->len() ; idx += 1)
tmp.set(idx, val->get(idx));
*val = v_not(tmp) + verinum(verinum::V1, 1);
val->has_sign(true);
return val;
}
}
delete val;
return 0;
}
/*
* $Log: eval.cc,v $
* 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)
*
* Revision 1.20 2001/02/09 02:49:59 steve
* Be more clear about scope of failure.
*
* Revision 1.19 2001/01/27 05:41:48 steve
* Fix sign extension of evaluated constants. (PR#91)
*
* Revision 1.18 2001/01/14 23:04:56 steve
* Generalize the evaluation of floating point delays, and
* get it working with delay assignment statements.
*
* Allow parameters to be referenced by hierarchical name.
*
* Revision 1.17 2001/01/04 04:47:51 steve
* Add support for << is signal indices.
*
* Revision 1.16 2000/12/10 22:01:36 steve
* Support decimal constants in behavioral delays.
*
* 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.
*
+52
View File
@@ -0,0 +1,52 @@
/*
* 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: eval_rconst.cc,v 1.2 2001/07/25 03:10:49 steve Exp $"
#endif
# include "config.h"
# include "PExpr.h"
verireal* PExpr::eval_rconst(const Design*, const NetScope*) const
{
return 0;
}
verireal* PEFNumber::eval_rconst(const Design*, const NetScope*) const
{
verireal*res = new verireal;
*res = *value_;
return res;
}
/*
* $Log: eval_rconst.cc,v $
* 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)
*
* Revision 1.1 2001/01/14 23:04:56 steve
* Generalize the evaluation of floating point delays, and
* get it working with delay assignment statements.
*
* Allow parameters to be referenced by hierarchical name.
*
*/
+824 -17
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1999 Stephen Williams ([email protected])
* Copyright (c) 1999-2000 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
@@ -16,10 +16,14 @@
* 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: eval_tree.cc,v 1.6 1999/10/22 23:57:53 steve Exp $"
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: eval_tree.cc,v 1.26 2001/07/25 03:10:49 steve Exp $"
#endif
# include "config.h"
# include <iostream>
# include "netlist.h"
NetExpr* NetExpr::eval_tree()
@@ -72,6 +76,72 @@ NetEConst* NetEBAdd::eval_tree()
return new NetEConst(val);
}
NetEConst* NetEBBits::eval_tree()
{
eval_sub_tree_();
NetEConst*lc = dynamic_cast<NetEConst*>(left_);
if (lc == 0) return 0;
NetEConst*rc = dynamic_cast<NetEConst*>(right_);
if (rc == 0) return 0;
verinum lval = lc->value();
verinum rval = rc->value();
unsigned lwid = lc->expr_width();
if (lwid == 0) lwid = lval.len();
unsigned rwid = rc->expr_width();
if (rwid == 0) rwid = rval.len();
unsigned wid = expr_width();
if (wid == 0)
wid = (rwid > lwid)? rwid : lwid;
verinum res (verinum::V0, wid);
if (lwid > wid)
lwid = wid;
if (rwid > wid)
rwid = wid;
switch (op()) {
case '|': {
unsigned cnt = lwid;
if (cnt > wid) cnt = wid;
if (cnt > rwid) cnt = rwid;
for (unsigned idx = 0 ; idx < cnt ; idx += 1)
res.set(idx, lval.get(idx) | rval.get(idx));
if (lwid < rwid)
for (unsigned idx = lwid ; idx < rwid ; idx += 1)
res.set(idx, lval.get(idx));
if (rwid < lwid)
for (unsigned idx = rwid ; idx < lwid ; idx += 1)
res.set(idx, rval.get(idx));
break;
}
case '&': {
unsigned cnt = lwid;
if (cnt > wid) cnt = wid;
if (cnt > rwid) cnt = rwid;
for (unsigned idx = 0 ; idx < cnt ; idx += 1)
res.set(idx, lval.get(idx) & rval.get(idx));
break;
}
default:
return 0;
}
return new NetEConst(res);
}
NetEConst* NetEBComp::eval_eqeq_()
{
NetEConst*l = dynamic_cast<NetEConst*>(left_);
@@ -95,12 +165,60 @@ NetEConst* NetEBComp::eval_eqeq_()
}
NetEConst* NetEBComp::eval_less_()
{
NetEConst*r = dynamic_cast<NetEConst*>(right_);
if (r == 0) return 0;
verinum rv = r->value();
if (! rv.is_defined()) {
verinum result(verinum::Vx, 1);
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. */
assert(left_->expr_width() > 0);
verinum lv (verinum::V1, left_->expr_width());
if (lv < rv) {
verinum result(verinum::V1, 1);
return new NetEConst(result);
}
/* Now go on to the normal test of the values. */
NetEConst*l = dynamic_cast<NetEConst*>(left_);
if (l == 0) return 0;
lv = l->value();
if (! lv.is_defined()) {
verinum result(verinum::Vx, 1);
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);
}
verinum result(verinum::V0, 1);
return new NetEConst(result);
}
NetEConst* NetEBComp::eval_leeq_()
{
NetEConst*r = dynamic_cast<NetEConst*>(right_);
if (r == 0) return 0;
verinum rv = r->value();
if (! rv.is_defined()) {
verinum result(verinum::Vx, 1);
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
@@ -112,30 +230,388 @@ NetEConst* NetEBComp::eval_leeq_()
return new NetEConst(result);
}
return 0;
/* Now go on to the normal test of the values. */
NetEConst*l = dynamic_cast<NetEConst*>(left_);
if (l == 0) return 0;
lv = l->value();
if (! lv.is_defined()) {
verinum result(verinum::Vx, 1);
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);
}
verinum result(verinum::V0, 1);
return new NetEConst(result);
}
NetEConst* NetEBComp::eval_gt_()
{
NetEConst*l = dynamic_cast<NetEConst*>(left_);
if (l == 0) return 0;
verinum lv = l->value();
if (! lv.is_defined()) {
verinum result(verinum::Vx, 1);
return new NetEConst(result);
}
/* Detect the case where the left side is greater than the
largest value the right side can possibly have. */
assert(right_->expr_width() > 0);
verinum rv (verinum::V1, right_->expr_width());
if (lv > rv) {
verinum result(verinum::V1, 1);
return new NetEConst(result);
}
/* Now go on to the normal test of the values. */
NetEConst*r = dynamic_cast<NetEConst*>(right_);
if (r == 0) return 0;
rv = r->value();
if (! rv.is_defined()) {
verinum result(verinum::Vx, 1);
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);
}
verinum result(verinum::V0, 1);
return new NetEConst(result);
}
NetEConst* NetEBComp::eval_gteq_()
{
NetEConst*l = dynamic_cast<NetEConst*>(left_);
if (l == 0) return 0;
verinum lv = l->value();
if (! lv.is_defined()) {
verinum result(verinum::Vx, 1);
return new NetEConst(result);
}
/* Detect the case where the left side is greater than the
largest value the right side can possibly have. */
assert(right_->expr_width() > 0);
verinum rv (verinum::V1, right_->expr_width());
if (lv >= rv) {
verinum result(verinum::V1, 1);
return new NetEConst(result);
}
/* Now go on to the normal test of the values. */
NetEConst*r = dynamic_cast<NetEConst*>(right_);
if (r == 0) return 0;
rv = r->value();
if (! rv.is_defined()) {
verinum result(verinum::Vx, 1);
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);
}
verinum result(verinum::V0, 1);
return new NetEConst(result);
}
NetEConst* NetEBComp::eval_neeq_()
{
NetEConst*l = dynamic_cast<NetEConst*>(left_);
if (l == 0) return 0;
NetEConst*r = dynamic_cast<NetEConst*>(right_);
if (r == 0) return 0;
const verinum&lv = l->value();
const verinum&rv = r->value();
verinum::V res = verinum::V0;
unsigned top = lv.len();
if (rv.len() < top)
top = rv.len();
for (unsigned idx = 0 ; idx < top ; idx += 1) {
switch (lv.get(idx)) {
case verinum::Vx:
case verinum::Vz:
res = verinum::Vx;
break;
default:
break;
}
switch (rv.get(idx)) {
case verinum::Vx:
case verinum::Vz:
res = verinum::Vx;
break;
default:
break;
}
if (res == verinum::Vx)
break;
if (rv.get(idx) != lv.get(idx))
res = verinum::V1;
}
if (res != verinum::Vx) {
for (unsigned idx = top ; idx < lv.len() ; idx += 1)
switch (lv.get(idx)) {
case verinum::Vx:
case verinum::Vz:
res = verinum::Vx;
break;
case verinum::V1:
if (res != verinum::Vx)
res = verinum::V1;
break;
default:
break;
}
for (unsigned idx = top ; idx < rv.len() ; idx += 1)
switch (rv.get(idx)) {
case verinum::Vx:
case verinum::Vz:
res = verinum::Vx;
break;
case verinum::V1:
if (res != verinum::Vx)
res = verinum::V1;
break;
default:
break;
}
}
return new NetEConst(verinum(res));
}
NetEConst* NetEBComp::eval_eqeqeq_()
{
NetEConst*l = dynamic_cast<NetEConst*>(left_);
if (l == 0) return 0;
NetEConst*r = dynamic_cast<NetEConst*>(right_);
if (r == 0) return 0;
const verinum&lv = l->value();
const verinum&rv = r->value();
verinum::V res = verinum::V1;
unsigned cnt = lv.len();
if (cnt > rv.len())
cnt = rv.len();
for (unsigned idx = 0 ; idx < cnt ; idx += 1)
if (lv.get(idx) != rv.get(idx))
res = verinum::V0;
for (unsigned idx = cnt ; idx < lv.len() ; idx += 1)
if (lv.get(idx) != verinum::V0)
res = verinum::V0;
for (unsigned idx = cnt ; idx < rv.len() ; idx += 1)
if (rv.get(idx) != verinum::V0)
res = verinum::V0;
return new NetEConst(verinum(res, 1));
}
NetEConst* NetEBComp::eval_neeqeq_()
{
NetEConst*tmp = eval_eqeqeq_();
if (tmp == 0)
return 0;
NetEConst*res;
if (tmp->value().get(0) == verinum::V0)
res = new NetEConst(verinum(verinum::V1,1));
else
res = new NetEConst(verinum(verinum::V0,1));
delete tmp;
return res;
}
NetEConst* NetEBComp::eval_tree()
{
eval_sub_tree_();
switch (op_) {
case 'e':
case 'E': // Case equality (===)
return eval_eqeqeq_();
case 'e': // Equality (==)
return eval_eqeq_();
case 'L':
case 'G': // >=
return eval_gteq_();
case 'L': // <=
return eval_leeq_();
case 'N': // Cse inequality (!==)
return eval_neeqeq_();
case 'n': // not-equal (!=)
return eval_neeq_();
case '<': // Less than
return eval_less_();
case '>': // Greater then
return eval_gt_();
default:
return 0;
}
}
/*
* The NetEBDiv operator includes the / and % opeators. First evaluate
* the sub-expressions, then perform the required operation.
*/
NetEConst* NetEBDiv::eval_tree()
{
eval_sub_tree_();
NetEConst*lc = dynamic_cast<NetEConst*>(left_);
if (lc == 0) return 0;
NetEConst*rc = dynamic_cast<NetEConst*>(right_);
if (rc == 0) return 0;
verinum lval = lc->value();
verinum rval = rc->value();
switch (op_) {
case '/':
return new NetEConst(lval / rval);
case '%':
return new NetEConst(lval % rval);
}
return 0;
}
NetEConst* NetEBLogic::eval_tree()
{
eval_sub_tree_();
return 0;
NetEConst*lc = dynamic_cast<NetEConst*>(left_);
if (lc == 0) return 0;
NetEConst*rc = dynamic_cast<NetEConst*>(right_);
if (rc == 0) return 0;
verinum::V lv = verinum::V0;
verinum::V rv = verinum::V0;
verinum v = lc->value();
for (unsigned idx = 0 ; idx < v.len() ; idx += 1)
if (v.get(idx) == verinum::V1)
lv = verinum::V1;
if (lv == verinum::V0)
for (unsigned idx = 0 ; idx < v.len() ; idx += 1)
if (v.get(idx) != verinum::V0)
lv = verinum::Vx;
v = rc->value();
for (unsigned idx = 0 ; idx < v.len() ; idx += 1)
if (v.get(idx) == verinum::V1)
rv = verinum::V1;
if (lv == verinum::V0)
for (unsigned idx = 0 ; idx < v.len() ; idx += 1)
if (v.get(idx) != verinum::V0)
rv = verinum::Vx;
verinum::V res;
switch (op_) {
case 'a': { // Logical AND (&&)
if ((lv == verinum::V0) || (rv == verinum::V0))
res = verinum::V0;
else if ((lv == verinum::V1) && (rv == verinum::V1))
res = verinum::V1;
else
res = verinum::Vx;
break;
}
case 'o': { // Logical OR (||)
if ((lv == verinum::V1) || (rv == verinum::V1))
res = verinum::V1;
else if ((lv == verinum::V0) && (rv == verinum::V0))
res = verinum::V0;
else
res = verinum::Vx;
break;
}
default:
return 0;
}
return new NetEConst(verinum(res, 1));
}
NetEConst* NetEBMult::eval_tree()
{
eval_sub_tree_();
NetEConst*lc = dynamic_cast<NetEConst*>(left_);
if (lc == 0) return 0;
NetEConst*rc = dynamic_cast<NetEConst*>(right_);
if (rc == 0) return 0;
verinum lval = lc->value();
verinum rval = rc->value();
return new NetEConst(lval * rval);
}
/*
@@ -157,32 +633,57 @@ NetEConst* NetEBShift::eval_tree()
verinum rv = re->value();
verinum lv = le->value();
/* Calculate the width of the result. If it is not fixed, then
get it from the left operand. */
unsigned wid = expr_width();
if (wid == 0)
wid = left_->expr_width();
if (rv.is_defined()) {
unsigned wid = expr_width();
unsigned shift = rv.as_ulong();
assert(wid);
verinum nv (verinum::V0, wid);
if (op() == 'r')
for (unsigned idx = 0 ; idx < (wid-shift) ; idx += 1)
if (op() == 'r') {
unsigned cnt = wid;
if (cnt > nv.len())
cnt = nv.len();
if (shift >= lv.len())
cnt = 0;
else if (cnt > (lv.len()-shift))
cnt = (lv.len()-shift);
for (unsigned idx = 0 ; idx < cnt ; idx += 1)
nv.set(idx, lv[idx+shift]);
else
for (unsigned idx = 0 ; idx < (wid-shift) ; idx += 1)
} else {
unsigned cnt = wid;
if (cnt > lv.len())
cnt = lv.len();
if (shift >= nv.len())
cnt = 0;
else if (cnt > (nv.len()-shift))
cnt = nv.len() - shift;
for (unsigned idx = 0 ; idx < cnt ; idx += 1)
nv.set(idx+shift, lv[idx]);
}
res = new NetEConst(nv);
} else {
verinum nv (verinum::Vx, expr_width());
assert(wid);
verinum nv (verinum::Vx, wid);
res = new NetEConst(nv);
}
return res;
}
NetExpr* NetEConcat::eval_tree()
NetEConst* NetEConcat::eval_tree()
{
for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) {
@@ -207,6 +708,18 @@ NetExpr* NetEConcat::eval_tree()
}
}
// 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) {
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);
@@ -235,7 +748,15 @@ NetExpr* NetEParam::eval_tree()
if (des_ == 0)
return 0;
const NetExpr*expr = des_->find_parameter(path_, name_);
assert(scope_);
const NetExpr*expr = scope_->get_parameter(name_);
if (expr == 0) {
cerr << get_line() << ": internal error: Unable to match "
<< "parameter " << name_ << " in scope "
<< scope_->name() << endl;
return 0;
}
assert(expr);
NetExpr*nexpr = expr->dup_expr();
@@ -256,12 +777,298 @@ 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.
des_->set_parameter(path_+"."+name_, res);
scope_->set_parameter(name_, res);
return res->dup_expr();
}
/*
* A ternary expression evaluation is controlled by the condition
* expression. If the condition evaluates to true or false, then
* return the evaluated true or false expression. If the condition
* evaluates to x or z, then merge the constant bits of the true and
* false expressions.
*/
NetExpr* NetETernary::eval_tree()
{
NetExpr*tmp;
/* Evaluate the cond_ to a constant. If it already is a
constant, then there is nothing to do. */
NetEConst*c = dynamic_cast<NetEConst*>(cond_);
if (c == 0) {
tmp = cond_->eval_tree();
c = dynamic_cast<NetEConst*>(tmp);
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;
}
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;
}
return false_val_->dup_expr();
}
/* Here we have a more complex case. We need to evaluate both
expressions down to constants then compare the values to
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;
}
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;
delete false_val_;
false_val_ = f;
}
unsigned size = t->expr_width();
assert(size == f->expr_width());
verinum val (verinum::V0, size);
for (unsigned idx = 0 ; idx < size ; idx += 1) {
verinum::V tv = t->value().get(idx);
verinum::V fv = f->value().get(idx);
if (tv == fv)
val.set(idx, tv);
else
val.set(idx, verinum::Vx);
}
NetEConst*rc = new NetEConst(val);
rc->set_line(*this);
return rc;
}
void NetEUnary::eval_expr_()
{
if (dynamic_cast<NetEConst*>(expr_))
return;
NetExpr*oper = expr_->eval_tree();
if (oper == 0)
return;
delete expr_;
expr_ = oper;
}
NetEConst* NetEUnary::eval_tree()
{
eval_expr_();
NetEConst*rval = dynamic_cast<NetEConst*>(expr_);
if (rval == 0)
return 0;
verinum val = rval->value();
switch (op_) {
case '~': {
/* Bitwise not is even simpler then logical
not. Just invert all the bits of the operand and
make the new value with the same dimensions. */
for (unsigned idx = 0 ; idx < val.len() ; idx += 1)
switch (val.get(idx)) {
case verinum::V0:
val.set(idx, verinum::V1);
break;
case verinum::V1:
val.set(idx, verinum::V0);
break;
default:
val.set(idx, verinum::Vx);
}
return new NetEConst(val);
}
default:
delete rval;
return 0;
}
}
NetEConst* NetEUBits::eval_tree()
{
return NetEUnary::eval_tree();
}
NetEConst* NetEUReduce::eval_tree()
{
eval_expr_();
NetEConst*rval = dynamic_cast<NetEConst*>(expr_);
if (rval == 0)
return 0;
verinum val = rval->value();
verinum::V res;
switch (op_) {
case '!': {
/* Evaluate the unary logical not by first scanning
the operand value for V1 and Vx bits. If we find
any V1 bits we know that the value is TRUE, so
the result of ! is V0. If there are no V1 bits
but there are some Vx/Vz bits, the result is
unknown. Otherwise, the result is V1. */
unsigned v1 = 0, vx = 0;
for (unsigned idx = 0 ; idx < val.len() ; idx += 1) {
switch (val.get(idx)) {
case verinum::V0:
break;
case verinum::V1:
v1 += 1;
break;
default:
vx += 1;
break;
}
}
res = v1? verinum::V0 : (vx? verinum::Vx : verinum::V1);
}
case '&': {
res = verinum::V1;
for (unsigned idx = 0 ; idx < val.len() ; idx += 1)
res = res & val.get(idx);
break;
}
case '|': {
res = verinum::V0;
for (unsigned idx = 0 ; idx < val.len() ; idx += 1)
res = res | val.get(idx);
break;
}
default:
return 0;
}
return new NetEConst(verinum(res, 1));
}
/*
* $Log: eval_tree.cc,v $
* 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)
*
* Revision 1.25 2001/07/16 20:41:41 steve
* Handle 0 counts in repeat concatenation.
*
* Revision 1.24 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.23 2001/02/09 05:44:23 steve
* support evaluation of constant < in expressions.
*
* Revision 1.22 2001/02/07 02:46:31 steve
* Support constant evaluation of / and % (PR#124)
*
* Revision 1.21 2001/01/14 23:04:56 steve
* Generalize the evaluation of floating point delays, and
* get it working with delay assignment statements.
*
* Allow parameters to be referenced by hierarchical name.
*
* Revision 1.20 2001/01/04 16:49:50 steve
* Evaluate constant === and !== expressions.
*
* Revision 1.19 2001/01/04 04:28:42 steve
* Evaluate constant logical && and ||.
*
* Revision 1.18 2001/01/02 04:21:14 steve
* Support a bunch of unary operators in parameter expressions.
*
* Revision 1.17 2001/01/02 03:23:40 steve
* Evaluate constant &, | and unary ~.
*
* Revision 1.16 2001/01/01 21:49:33 steve
* Fix shift and ternary operators in parameter expressions (PR#86)
*
* Revision 1.15 2000/12/16 20:00:17 steve
* Handle non-constant l-values.
*
* Revision 1.14 2000/12/16 19:03:30 steve
* Evaluate <= and ?: in parameter expressions (PR#81)
*
* Revision 1.13 2000/09/29 04:42:56 steve
* Cnstant evaluation of NE.
*
* Revision 1.12 2000/09/27 18:28:37 steve
* multiply in parameter expressions.
*
* Revision 1.11 2000/07/07 04:53:54 steve
* Add support for non-constant delays in delay statements,
* Support evaluating ! in constant expressions, and
* move some code from netlist.cc to net_proc.cc.
*
* Revision 1.10 2000/04/28 18:43:23 steve
* integer division in expressions properly get width.
*
* Revision 1.9 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.8 2000/02/23 02:56:54 steve
* Macintosh compilers do not support ident.
*
* Revision 1.7 2000/01/13 03:35:35 steve
* Multiplication all the way to simulation.
*
* Revision 1.6 1999/10/22 23:57:53 steve
* do the <= in bits, not numbers.
*
+87
View File
@@ -0,0 +1,87 @@
/*
* Copyright (c) 2000 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
*/
/*
* This source file demonstrates how to synthesize CLB flip-flops from
* Icarus Verilog, including giving the device an initial value.
*
* To compile this for XNF, try a command like this:
*
* iverilog -txnf -ppart=XC4010XLPQ160 -pncf=clbff.ncf -oclbff.xnf clbff.v
*
* That command causes an clbff.xnf and clbff.ncf file to be created.
* Next, make the clbff.ngd file with the command:
*
* xnf2ngd -l xilinxun -u clbff.xnf clbff.ngo
* ngdbuild clbff.ngo clbff.ngd
*
* Finally, map the file to fully render it in the target part. The
* par command is the step that actually optimizes the design and tries
* to meet timing constraints.
*
* map -o map.ncd clbff.ngd
* par -w map.ncd clbff.ncd
*
* At this point, you can use the FPGA Editor to edit the clbff.ncd
* file. Notice that the design uses two CLB flip-flops (possibly in
* the same CLB) with their outputs ANDed together. If you go into the
* block editor, you will see that the FF connected to main/Q<0> is
* configured so start up reset, and the FF connected to main/Q<1> is
* configured to start up set.
*/
module main;
wire clk, iclk;
wire i0, i1;
wire out;
wire [1:0] D = {i1, i0};
// This statement declares Q to be a 2 bit reg vector. The
// initial assignment will cause the synthesized device to take
// on an initial value specified here. Without the assignment,
// the initial value is unspecified. (Verilog simulates it as 2'bx.)
reg [1:0] Q = 2'b10;
// This simple logic gate get turned into a function unit.
// The par program will map this into a CLB F or G unit.
and (out, Q[0], Q[1]);
// This creates a global clock buffer. Notice how I attach an
// attribute to the named gate to force it to be mapped to the
// desired XNF device. This device will not be pulled into the
// IOB associated with iclk because of the attribute.
buf gbuf(clk, iclk);
$attribute(gbuf, "XNF-LCA", "GCLK:O,I");
// This is mapped to a DFF. Since Q and D are two bits wide, the
// code generator actually makes two DFF devices that share a
// clock input.
always @(posedge clk) Q <= D;
// These attribute commands assign pins to the listed wires.
// This can be done to wires and registers, as internally both
// are treated as named signals.
$attribute(out, "PAD", "o150");
$attribute(i0, "PAD", "i152");
$attribute(i1, "PAD", "i153");
$attribute(iclk,"PAD", "i154");
endmodule /* main */
+49
View File
@@ -0,0 +1,49 @@
/*
* Copyright (c) 1998 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.
* We simply print to the program output a simple message. This example
* demonstrates the process of compiling and executing a program with
* Icarus Verilog.
*
* Compile this program with the command:
*
* iverilog -ohello hello.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:
*
* ./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
* manual page.
*/
module main();
initial
begin
$display("Hello, World");
$finish ;
end
endmodule
+76
View File
@@ -0,0 +1,76 @@
/*
* Copyright (c) 1998-1999 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
*/
/*
* IVL should generate an AND gate, and should make an OBUF and two
* IBUF objects, along with the PAD objects.
*
* To compile this for XNF, try a command like this:
*
* iverilog -txnf -ppart=XC4010XLPQ160 -ooutff.xnf -pncf=outff.ncf outff.v
*
* That command causes an outff.xnf and outff.ncf file to be created.
* Next, make the outff.ngd file with the command:
*
* xnf2ngd -l xilinxun -u outff.xnf outff.ngo
* ngdbuild outff.ngo outff.ngd
*
* Finally, map the file to fully render it in the target part. The
* par command is the step that actually optimizes the design and tries
* to meet timing constraints.
*
* map -o map.ncd outff.ngd
* par -w map.ncd outff.ncd
*
* At this point, you can use the FPGA Editor to edit the outff.ncd
* file to see that the AND gate is in a CLB and the IOB for pin 150
* has its flip-flop in use, and that gbuf is a global buffer.
*/
module main;
wire clk, iclk;
wire i0, i1;
wire out;
reg o0;
// This simple logic gate get turned into a function unit.
// The par program will map this into a CLB F or G unit.
and (out, i0, i1);
// This creates a global clock buffer. Notice how I attach an
// attribute to the named gate to force it to be mapped to the
// desired XNF device. This device will not be pulled into the
// IOB associated with iclk because of the attribute.
buf gbuf(clk, iclk);
$attribute(gbuf, "XNF-LCA", "GCLK:O,I");
// This is mapped to a DFF. Since o0 is connected to a PAD, it
// is turned into a OUTFF so that it get placed into an IOB.
always @(posedge clk) o0 = out;
// These attribute commands assign pins to the listed wires.
// This can be done to wires and registers, as internally both
// are treated as named signals.
$attribute(o0, "PAD", "o150");
$attribute(i0, "PAD", "i152");
$attribute(i1, "PAD", "i153");
$attribute(iclk,"PAD", "i154");
endmodule /* main */
+121
View File
@@ -0,0 +1,121 @@
/*
* Copyright (c) 2000 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 shows how to use Icarus Verilog to generate PLD output.
* The design is intended to fit into a 22v10 in a PLCC package, with
* pin assignments locked down by design. The command to compile this
* into a jedec file is;
*
* iverilog -tpal -ppart=generic-22v10-plcc -opal_reg.jed pal_reg.v
*
* The output file name (passed through the -o<file> switch) can be
* any file you desire. If the compilation and fittin all succeed, the
* output file will be a JEDEC file that you can take to your favorite
* PROM programmer to program the part.
*
* This source demonstrates some important principles of synthesizing
* a design for a PLD, including how to specify synchronous logic, and
* how to assign signals to pins. The pin assignment in particular is
* part specific, and must be right for the fitting to succeed.
*/
/*
* The register module is an 8 bit register that copies the input to
* the output registers on the rising edge of the clk input. The
* always statement creates a simple d-type flip-flop that is loaded
* on the rising edge of the clock.
*
* The output drivers are controlled by a single active low output
* enable. I used bufif0 devices in this example, but the exact same
* thing can be achived with a continuous assignment like so:
*
* assign out = oe? 8'hzz : Q;
*
* Many people prefer the expression form. It is true that it does
* seem to express the intent a bit more clearly.
*/
module register (out, val, clk, oe);
output [7:0] out;
input [7:0] val;
input clk, oe;
reg [7:0] Q;
wire [7:0] out;
bufif0 drv[7:0](out, Q, oe);
always @(posedge clk) Q = val;
endmodule
/*
* The module pal is used to attach pin information to all the pins of
* the device. We use this to lock down the pin assignments of the
* synthesized result. The pin number assignments are for a 22v10 in
* a PLCC package.
*
* Note that this module has no logic in it. It is a convention I use
* that I put all the functionality in a seperate module (seen above)
* and isolate the Icarus Verilog specific $attribute madness into a
* top-level module. The advantage of this style is that the entire
* module can be `ifdef'ed out when doing simulation and you don't
* need to worry that functionality will be affected.
*/
module pal;
wire out7, out6, out5, out4, out3, out2, out1, out0;
wire inp7, inp6, inp5, inp4, inp3, inp2, inp1, inp0;
wire clk, oe;
// The PAD attributes attach the wires to pins of the
// device. Output pins are prefixed by a 'o', and input pins by an
// 'i'. If not all the available output pins are used, then the
// remaining are available for the synthesizer to drop internal
// registers or extra logic layers.
$attribute(out7, "PAD", "o27");
$attribute(out6, "PAD", "o26");
$attribute(out5, "PAD", "o25");
$attribute(out4, "PAD", "o24");
$attribute(out3, "PAD", "o23");
$attribute(out2, "PAD", "o21");
$attribute(out1, "PAD", "o20");
$attribute(out0, "PAD", "o19");
$attribute(inp7, "PAD", "i10");
$attribute(inp6, "PAD", "i9");
$attribute(inp5, "PAD", "i7");
$attribute(inp4, "PAD", "i6");
$attribute(inp3, "PAD", "i5");
$attribute(inp2, "PAD", "i4");
$attribute(inp1, "PAD", "i3");
$attribute(inp0, "PAD", "i2");
//$attribute(clk, "PAD", "CLK");
$attribute(oe, "PAD", "i13");
register dev({out7, out6, out5, out4, out3, out2, out1, out0},
{inp7, inp6, inp5, inp4, inp3, inp2, inp1, inp0},
clk, oe);
endmodule // pal
+114
View File
@@ -0,0 +1,114 @@
/*
* Copyright (c) 1999 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
*/
/*
* This example program simulates a 16x1 ram, and is used as an
* example for using VCD output and waveform viewers.
*
* Like any other Verilog simulation, compile this program with the
* command:
*
* iverilog show_vcd.vl
*
* This will generate the show_vcd command in the current directory.
* When you run the command, you will see the output from all the
* calls to $display, but also there will be a dump file ``show_vcd.vcd''.
* The name of this file is set by the statement:
*
* $dumpfile("show_vcd.vcd");
*
* in the main module. The output file uses the standard VCD file format
* so can be viewed using off-the-shelf waveform viewers. The remaining
* steps describe how to use GTKWave to view the file. If you are using
* a different viewer, see the documentation for that tool.
*
* To view the output generated by running show_vcd, start the GTKWave
* viewer with the command:
*
* wave 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
* file. However, there are no waveforms displayed yet. Select signals to
* add to the waveform display using the menu selection:
*
* "Search --> Signal Search Tree"
*
* This will bring up a dialog box that shows in directory tree format
* the signals of the program. Select the signals you wish to view, and
* click one of the buttons on the bottom of the dialog box to display
* the selected signals in the waveform window. Click "Exit" on the box
* to get rid of it.
*
* The magic that makes all this work is contained in the $dumpfile and
* $dumpvars system tasks. The $dumpfile task tells the simulation where
* to write the VCD output. This task must be called once before the
* $dumpvars task is called.
*
* The $dumpvars task tells the simulation what variables to write to
* the VCD output. The first parameter is how far to descend while
* scanning a scope, and the remaining paramters are signals or scope
* names to include in the dump. If a scope name is given, all the
* signals within the scope are dumped. If a wire or register name is
* given, that signal is included.
*/
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
$dumpfile("show_vcd.vcd");
$dumpvars(1, main.r1);
wclk = 0;
we = 1;
for (a = 0 ; a < 4'hf ; a = a + 1) begin
d = a[0];
#1 wclk = 1;
#1 wclk = 0;
$display("r1[%x] == %b", a, q);
end
for (a = 0 ; a < 4'hf ; a = a + 1)
#1 if (q !== a[0]) begin
$display("FAILED -- mem[%h] !== %b", a, a[0]);
$finish;
end
$display("PASSED");
end
endmodule /* main */
+140
View File
@@ -0,0 +1,140 @@
/*
* Copyright (c) 1999 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
*
* $Id: sqrt.vl,v 1.3 2000/11/04 01:53:24 steve Exp $"
*/
/*
* This example shows that Icarus Verilog can run non-trivial
* programs, too. This uses a variety of Verilog language features
* to implement the module of a square-root device. The program
* uses IEEE1364-1995 language features and should work correctly
* on any Verilog compiler.
*
* Run the file with Icarus Verilog under UNIX using the command:
*
* % iverilog -osqrt sqrt.v
* % ./sqrt
*/
/*
* 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
* to 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);
task clear;
begin
acc = 0;
acc2 = 0;
bitl = 15;
end
endtask
initial clear;
always @(reset or posedge clk)
if (reset)
clear;
else begin
if (guess2 <= x) begin
acc <= guess;
acc2 <= guess2;
end
bitl <= bitl - 1;
end
endmodule
module main;
reg clk, reset;
reg [31:0] value;
wire [15:0] result;
wire rdy;
sqrt32 root(.clk(clk), .rdy(rdy), .reset(reset), .x(value), .y(result));
always #5 clk = ~clk;
always @(posedge rdy) begin
$display("sqrt(%d) --> %d", value, result);
$finish;
end
initial begin
clk = 0;
reset = 1;
$monitor($time,,"%m.acc = %b", root.acc);
#100 value = 63;
reset = 0;
end
endmodule /* main */
+103
View File
@@ -0,0 +1,103 @@
/*
* Copyright (c) 1999 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
*/
/*
* This example demonstrates Icarus Verilog's ability to synthesize
* efficient adders for Xilinx 4000 series FPGAs. The synthesis and
* code generation makes an adder and translates that into XOR gates
* and fast carry chain hardware.
*
* To compile this for XNF, try a command like this:
*
* iverilog -txnf -ppart=XC4010XLPQ160 -pncf=xnf_add.ncf -oxnf_add.xnf xnf_add.v
*
* That command causes an xnf_add.xnf and xnf_add.ncf file to be created.
* Next, Use Xilinx Alliance or Foundation tools to make the xnf_add.ngd
* file with the command:
*
* xnf2ngd -l xilinxun -u xnf_add.xnf xnf_add.ngo
* ngdbuild xnf_add.ngo xnf_add.ngd
*
* Finally, map the file to fully render it in the target part. The
* par command is the step that actually optimizes the design and tries
* to meet timing constraints.
*
* map -o map.ncd xnf_add.ngd
* par -w map.ncd xnf_add.ncd
*
* At this point, you can use the Xilinx FPGA Editor to edit the xnf_add.ncd
* file and see the carry chains made up to support the adder.
*/
module main;
wire [3:0] a, b;
wire [3:0] out;
wire carry;
wire a0, a1, a2, a3, b0, b1, b2, b3;
wire out0, out1, out2, out3;
// This creates the actual adder. Note that we also create a link
// to the carry output. The principle adder is 4 bits wide, so two
// IOBs are used to to the actual addition. PAR will place them in
// order along carry lines. An extra carry cell from below a[0] is
// used in FORCE-0 mode to load the bottom carry node.
//
// The carry signal from the top CY device is used to drive the
// main.carry wire shown here. It is managed in this case by using
// an ADD-FG-CI CY device for the top pair and using the CLB above
// the carry chain, with its CY in EXAMINE-CI mode, to put the carry
// out through its G function unit.
assign {carry, out} = a + b;
// These attribute commands assign pins to the listed wires.
// This can be done to wires and registers, as internally both
// are treated as named signals. It doesn't work (yet) on vectors,
// though, so break out the vectors with scaler assignments.
assign a[0] = a0;
assign a[1] = a1;
assign a[2] = a2;
assign a[3] = a3;
$attribute(a0, "PAD", "i150");
$attribute(a1, "PAD", "i152");
$attribute(a2, "PAD", "i153");
$attribute(a3, "PAD", "i154");
assign b[0] = b0;
assign b[1] = b1;
assign b[2] = b2;
assign b[3] = b3;
$attribute(b0, "PAD", "i155");
$attribute(b1, "PAD", "i156");
$attribute(b2, "PAD", "i157");
$attribute(b3, "PAD", "i158");
assign out0 = out[0];
assign out1 = out[1];
assign out2 = out[2];
assign out3 = out[3];
$attribute(out0, "PAD", "o71");
$attribute(out1, "PAD", "o72");
$attribute(out2, "PAD", "o73");
$attribute(out3, "PAD", "o74");
$attribute(carry, "PAD", "o75");
endmodule /* main */
+451 -34
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1999 Stephen Williams (steve@icarus.com)
* Copyright (c) 1999-2000 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,12 +16,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)
#ident "$Id: expr_synth.cc,v 1.6 1999/11/28 23:42:02 steve Exp $"
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: expr_synth.cc,v 1.26 2001/08/31 22:59:48 steve Exp $"
#endif
# include "netlist.h"
# include "config.h"
# include <iostream>
# include "netlist.h"
# include "netmisc.h"
NetNet* NetExpr::synthesize(Design*des)
{
@@ -38,24 +42,23 @@ NetNet* NetEBAdd::synthesize(Design*des)
{
assert((op()=='+') || (op()=='-'));
string path = des->local_symbol("SYNTH");
NetNet*lsig = left_->synthesize(des);
NetNet*rsig = right_->synthesize(des);
assert(lsig->pin_count() == rsig->pin_count());
unsigned width=lsig->pin_count();
NetNet*osig = new NetNet(0, path, NetNet::IMPLICIT, width);
string path = lsig->scope()->name()+"."+lsig->scope()->local_symbol();
NetNet*osig = new NetNet(lsig->scope(), path, NetNet::IMPLICIT, width);
string oname = des->local_symbol(path);
NetAddSub *adder = new NetAddSub(oname, width);
NetAddSub *adder = new NetAddSub(lsig->scope(), oname, width);
for (unsigned idx = 0 ; idx < width; idx += 1) {
connect(lsig->pin(idx), adder->pin_DataA(idx));
connect(rsig->pin(idx), adder->pin_DataB(idx));
connect(osig->pin(idx), adder->pin_Result(idx));
}
des->add_node(adder);
des->add_signal(osig);
switch (op()) {
case '+':
@@ -77,12 +80,28 @@ NetNet* NetEBAdd::synthesize(Design*des)
*/
NetNet* NetEBBits::synthesize(Design*des)
{
string path = des->local_symbol("SYNTH");
NetNet*lsig = left_->synthesize(des);
NetNet*rsig = right_->synthesize(des);
NetScope*scope = lsig->scope();
assert(scope);
string path = des->local_symbol(scope->name());
if (lsig->pin_count() != rsig->pin_count()) {
cerr << get_line() << ": internal error: bitwise (" << op_
<< ") widths do not match: " << lsig->pin_count()
<< " != " << rsig->pin_count() << endl;
cerr << get_line() << ": : width="
<< lsig->pin_count() << ": " << *left_ << endl;
cerr << get_line() << ": : width="
<< rsig->pin_count() << ": " << *right_ << endl;
return 0;
}
assert(lsig->pin_count() == rsig->pin_count());
NetNet*osig = new NetNet(0, path, NetNet::IMPLICIT, lsig->pin_count());
NetNet*osig = new NetNet(scope, path, NetNet::IMPLICIT,
lsig->pin_count());
osig->local_flag(true);
for (unsigned idx = 0 ; idx < osig->pin_count() ; idx += 1) {
string oname = des->local_symbol(path);
@@ -90,19 +109,19 @@ NetNet* NetEBBits::synthesize(Design*des)
switch (op()) {
case '&':
gate = new NetLogic(oname, 3, NetLogic::AND);
gate = new NetLogic(scope, oname, 3, NetLogic::AND);
break;
case '|':
gate = new NetLogic(oname, 3, NetLogic::OR);
gate = new NetLogic(scope, oname, 3, NetLogic::OR);
break;
case '^':
gate = new NetLogic(oname, 3, NetLogic::XOR);
gate = new NetLogic(scope, oname, 3, NetLogic::XOR);
break;
case 'O':
gate = new NetLogic(oname, 3, NetLogic::NOR);
gate = new NetLogic(scope, oname, 3, NetLogic::NOR);
break;
case 'X':
gate = new NetLogic(oname, 3, NetLogic::XNOR);
gate = new NetLogic(scope, oname, 3, NetLogic::XNOR);
break;
default:
assert(0);
@@ -115,23 +134,264 @@ NetNet* NetEBBits::synthesize(Design*des)
des->add_node(gate);
}
des->add_signal(osig);
return osig;
}
NetNet* NetEBComp::synthesize(Design*des)
{
NetEConst*lcon = reinterpret_cast<NetEConst*>(left_);
NetEConst*rcon = reinterpret_cast<NetEConst*>(right_);
/* Handle the special case where one of the inputs is constant
0. We can use an OR gate to do the comparison. Synthesize
the non-const side as normal, then or(nor) the signals
together to get result. */
if ((rcon && (rcon->value() == verinum(0UL,rcon->expr_width())))
|| (lcon && (lcon->value() == verinum(0UL,lcon->expr_width())))) {
NetNet*lsig = rcon
? left_->synthesize(des)
: right_->synthesize(des);
NetScope*scope = lsig->scope();
assert(scope);
string path = des->local_symbol(scope->name());
NetNet*osig = new NetNet(scope, path, NetNet::IMPLICIT, 1);
osig->local_flag(true);
NetLogic*gate;
switch (op_) {
case 'e':
case 'E':
gate = new NetLogic(scope, des->local_symbol(path),
lsig->pin_count()+1, NetLogic::NOR);
break;
case 'n':
case 'N':
gate = new NetLogic(scope, des->local_symbol(path),
lsig->pin_count()+1, NetLogic::OR);
break;
default:
assert(0);
}
connect(gate->pin(0), osig->pin(0));
for (unsigned idx = 0 ; idx < lsig->pin_count() ; idx += 1)
connect(gate->pin(idx+1), lsig->pin(idx));
des->add_node(gate);
return osig;
}
NetNet*lsig = left_->synthesize(des);
NetNet*rsig = right_->synthesize(des);
NetScope*scope = lsig->scope();
assert(scope);
string path = des->local_symbol(scope->name());
unsigned width = lsig->pin_count();
if (rsig->pin_count() > lsig->pin_count())
width = rsig->pin_count();
lsig = pad_to_width(des, lsig, width);
rsig = pad_to_width(des, rsig, width);
NetNet*osig = new NetNet(scope, path, NetNet::IMPLICIT, 1);
osig->local_flag(true);
/* Handle the special case of a single bit equality
operation. Make an XNOR gate instead of a comparator. */
if ((width == 1) && ((op_ == 'e') || (op_ == 'E'))) {
NetLogic*gate = new NetLogic(scope, des->local_symbol(path),
3, NetLogic::XNOR);
connect(gate->pin(0), osig->pin(0));
connect(gate->pin(1), lsig->pin(0));
connect(gate->pin(2), rsig->pin(0));
des->add_node(gate);
return osig;
}
/* Handle the special case of a single bit inequality
operation. This is similar to single bit equality, but uses
an XOR instead of an XNOR gate. */
if ((width == 1) && ((op_ == 'n') || (op_ == 'N'))) {
NetLogic*gate = new NetLogic(scope, des->local_symbol(path),
3, NetLogic::XOR);
connect(gate->pin(0), osig->pin(0));
connect(gate->pin(1), lsig->pin(0));
connect(gate->pin(2), rsig->pin(0));
des->add_node(gate);
return osig;
}
NetCompare*dev = new NetCompare(scope, des->local_symbol(path), width);
des->add_node(dev);
for (unsigned idx = 0 ; idx < lsig->pin_count() ; idx += 1)
connect(dev->pin_DataA(idx), lsig->pin(idx));
for (unsigned idx = 0 ; idx < rsig->pin_count() ; idx += 1)
connect(dev->pin_DataB(idx), rsig->pin(idx));
switch (op_) {
case '<':
connect(dev->pin_ALB(), osig->pin(0));
break;
case '>':
connect(dev->pin_AGB(), osig->pin(0));
break;
case 'e': // ==
case 'E': // === ?
connect(dev->pin_AEB(), osig->pin(0));
break;
case 'G': // >=
connect(dev->pin_AGEB(), osig->pin(0));
break;
case 'L': // <=
connect(dev->pin_ALEB(), osig->pin(0));
break;
case 'n': // !=
case 'N': // !==
connect(dev->pin_ANEB(), osig->pin(0));
break;
default:
cerr << get_line() << ": internal error: cannot synthesize "
"comparison: " << *this << endl;
des->errors += 1;
return 0;
}
return osig;
}
NetNet* NetEBDiv::synthesize(Design*des)
{
cerr << get_line() << ": internal error: cannot synthesize division: "
<< *this << endl;
des->errors += 1;
return 0;
}
NetNet* NetEBLogic::synthesize(Design*des)
{
NetNet*lsig = left_->synthesize(des);
NetNet*rsig = right_->synthesize(des);
if (lsig == 0)
return 0;
if (rsig == 0)
return 0;
NetScope*scope = lsig->scope();
assert(scope);
string path = des->local_symbol(scope->name());
NetNet*osig = new NetNet(scope, path, NetNet::IMPLICIT, 1);
osig->local_flag(true);
if (op() == 'o') {
/* Logic OR can handle the reduction *and* the logical
comparison with a single wide OR gate. So handle this
magically. */
string oname = des->local_symbol(path);
NetLogic*olog;
olog = new NetLogic(scope, oname,
lsig->pin_count()+rsig->pin_count()+1,
NetLogic::OR);
connect(osig->pin(0), olog->pin(0));
unsigned pin = 1;
for (unsigned idx = 0 ; idx < lsig->pin_count() ; idx = 1)
connect(olog->pin(pin+idx), lsig->pin(idx));
pin += lsig->pin_count();
for (unsigned idx = 0 ; idx < rsig->pin_count() ; idx = 1)
connect(olog->pin(pin+idx), rsig->pin(idx));
des->add_node(olog);
} else {
assert(op() == 'a');
/* Create the logic AND gate. This is a single bit
output, with inputs for each of the operands. */
NetLogic*olog;
string oname = des->local_symbol(path);
olog = new NetLogic(scope, oname, 3, NetLogic::AND);
connect(osig->pin(0), olog->pin(0));
des->add_node(olog);
/* XXXX Here, I need to reduce the parameters with
reduction or. */
/* By this point, the left and right parameters have been
reduced to single bit values. Now we just connect them to
the logic gate. */
assert(lsig->pin_count() == 1);
connect(lsig->pin(0), olog->pin(1));
assert(rsig->pin_count() == 1);
connect(lsig->pin(0), olog->pin(2));
}
return osig;
}
NetNet* NetEConcat::synthesize(Design*des)
{
NetScope*scope = des->find_root_scope();
assert(scope);
assert(repeat_ == 1);
string path = scope->name() + "." + scope->local_symbol();
NetNet*osig = new NetNet(scope, path, NetNet::IMPLICIT, expr_width());
osig->local_flag(true);
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));
obit += 1;
}
if (tmp->local_flag() && tmp->get_eref() == 0)
delete tmp;
}
return osig;
}
NetNet* NetEConst::synthesize(Design*des)
{
string path = des->local_symbol("SYNTH");
NetScope*scope = des->find_root_scope();
assert(scope);
string path = scope->name() + "." + scope->local_symbol();
unsigned width=expr_width();
NetNet*osig = new NetNet(0, path, NetNet::IMPLICIT, width);
for (unsigned idx = 0 ; idx < width; idx += 1) {
string oname = des->local_symbol(path);
NetConst *c = new NetConst(oname, value().get(idx));
connect(osig->pin(idx), c->pin(0));
des->add_node(c);
}
des->add_signal(osig);
NetNet*osig = new NetNet(scope, path, NetNet::IMPLICIT, width);
osig->local_flag(true);
NetConst*con = new NetConst(des->local_symbol(path), value());
for (unsigned idx = 0 ; idx < width; idx += 1)
connect(osig->pin(idx), con->pin(idx));
des->add_node(con);
return osig;
}
@@ -141,10 +401,15 @@ NetNet* NetEConst::synthesize(Design*des)
*/
NetNet* NetEUBits::synthesize(Design*des)
{
string path = des->local_symbol("SYNTH");
NetNet*isig = expr_->synthesize(des);
NetNet*osig = new NetNet(0, path, NetNet::IMPLICIT, isig->pin_count());
NetScope*scope = isig->scope();
assert(scope);
string path = des->local_symbol(scope->name());
NetNet*osig = new NetNet(scope, path, NetNet::IMPLICIT,
isig->pin_count());
osig->local_flag(true);
for (unsigned idx = 0 ; idx < osig->pin_count() ; idx += 1) {
string oname = des->local_symbol(path);
@@ -152,7 +417,7 @@ NetNet* NetEUBits::synthesize(Design*des)
switch (op()) {
case '~':
gate = new NetLogic(oname, 2, NetLogic::NOT);
gate = new NetLogic(scope, oname, 2, NetLogic::NOT);
break;
default:
assert(0);
@@ -163,25 +428,67 @@ NetNet* NetEUBits::synthesize(Design*des)
des->add_node(gate);
}
des->add_signal(osig);
return osig;
}
NetNet* NetEUReduce::synthesize(Design*des)
{
NetNet*isig = expr_->synthesize(des);
NetScope*scope = isig->scope();
assert(scope);
string path = des->local_symbol(scope->name());
NetNet*osig = new NetNet(scope, path, NetNet::IMPLICIT, 1);
osig->local_flag(true);
string oname = des->local_symbol(path);
NetLogic*gate;
switch (op()) {
case 'N':
case '!':
gate = new NetLogic(scope, oname, isig->pin_count()+1,
NetLogic::NOR);
break;
case '&':
gate = new NetLogic(scope, oname, isig->pin_count()+1,
NetLogic::AND);
break;
default:
cerr << get_line() << ": internal error: "
<< "Unable to synthesize " << *this << "." << endl;
return 0;
}
des->add_node(gate);
connect(gate->pin(0), osig->pin(0));
for (unsigned idx = 0 ; idx < isig->pin_count() ; idx += 1)
connect(gate->pin(1+idx), isig->pin(idx));
return osig;
}
NetNet* NetETernary::synthesize(Design *des)
{
string path = des->local_symbol("SYNTH");
NetNet*csig = cond_->synthesize(des);
NetNet*tsig = true_val_->synthesize(des);
NetNet*fsig = false_val_->synthesize(des);
string path = csig->scope()->name()+"."+csig->scope()->local_symbol();
assert(csig->pin_count() == 1);
assert(tsig->pin_count() == fsig->pin_count());
unsigned width=tsig->pin_count();
NetNet*osig = new NetNet(0, path, NetNet::IMPLICIT, width);
NetNet*osig = new NetNet(csig->scope(), path, NetNet::IMPLICIT, width);
osig->local_flag(true);
string oname = des->local_symbol(path);
NetMux *mux = new NetMux(oname, width, 2, 1);
NetMux *mux = new NetMux(csig->scope(), oname, width, 2, 1);
for (unsigned idx = 0 ; idx < width; idx += 1) {
connect(tsig->pin(idx), mux->pin_Data(idx, 1));
connect(fsig->pin(idx), mux->pin_Data(idx, 0));
@@ -189,17 +496,127 @@ NetNet* NetETernary::synthesize(Design *des)
}
des->add_node(mux);
connect(csig->pin(0), mux->pin_Sel(0));
des->add_signal(osig);
return osig;
}
/*
* When synthesizing a signal expressoin, 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.
*
* For example, if there is a reg foo, like so:
* reg [5:0] foo;
* and this expression node represents a part select foo[3:2], then
* create a temporary like so:
*
* foo
* +---+
* | 5 |
* +---+
* tmp | 4 |
* +---+ +---+
* | 1 | <---> | 3 |
* +---+ +---+
* | 0 | <---> | 2 |
* +---+ +---+
* | 1 |
* +---+
* | 0 |
* +---+
* The temporary is marked as a temporary and returned to the
* caller. This causes the caller to get only the selected part of the
* signal, and when it hooks up to tmp, it hooks up to the right parts
* of foo.
*/
NetNet* NetESignal::synthesize(Design*des)
{
return net_;
if ((lsi_ == 0) && (msi_ == (net_->pin_count() - 1)))
return net_;
assert(msi_ >= lsi_);
unsigned wid = msi_ - lsi_ + 1;
NetScope*scope = net_->scope();
assert(scope);
string name = scope->name() + "." + scope->local_symbol();
NetNet*tmp = new NetNet(scope, name, NetNet::NetNet::WIRE, wid);
tmp->local_flag(true);
for (unsigned idx = 0 ; idx < wid ; idx += 1)
connect(tmp->pin(idx), net_->pin(idx+lsi_));
return tmp;
}
/*
* $Log: expr_synth.cc,v $
* Revision 1.26 2001/08/31 22:59:48 steve
* synthesize the special case of compare with 0.
*
* Revision 1.25 2001/08/05 02:49:07 steve
* Properly synthesize part selects.
*
* Revision 1.24 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)
*
* Revision 1.23 2001/07/07 01:38:45 steve
* Put synthesized signals in proper scope.
*
* Revision 1.22 2001/06/15 04:14:18 steve
* Generate vvp code for GT and GE comparisons.
*
* Revision 1.21 2001/06/07 02:12:43 steve
* Support structural addition.
*
* Revision 1.20 2001/02/15 06:59:36 steve
* FreeBSD port has a maintainer now.
*
* Revision 1.19 2001/01/18 03:16:35 steve
* NetMux needs a scope. (PR#115)
*
* Revision 1.18 2000/11/29 23:16:18 steve
* Do not delete synthesized signals used in expressions.
*
* Revision 1.17 2000/11/29 05:24:00 steve
* synthesis for unary reduction ! and N operators.
*
* Revision 1.16 2000/11/29 02:09:52 steve
* Add support for || synthesis (PR#53)
*
* Revision 1.15 2000/10/07 19:45:43 steve
* Put logic devices into scopes.
*
* Revision 1.14 2000/05/02 00:58:12 steve
* Move signal tables to the NetScope class.
*
* Revision 1.13 2000/04/28 18:43:23 steve
* integer division in expressions properly get width.
*
* Revision 1.12 2000/04/20 00:28:03 steve
* Catch some simple identity compareoptimizations.
*
* Revision 1.11 2000/04/16 23:32:18 steve
* Synthesis of comparator in expressions.
*
* Connect the NetEvent and related classes
* together better.
*
* Revision 1.10 2000/02/23 02:56:54 steve
* Macintosh compilers do not support ident.
*
* Revision 1.9 2000/01/01 06:18:00 steve
* Handle synthesis of concatenation.
*
* Revision 1.8 1999/12/17 06:18:15 steve
* Rewrite the cprop functor to use the functor_t interface.
*
* Revision 1.7 1999/12/17 03:38:46 steve
* NetConst can now hold wide constants.
*
* Revision 1.6 1999/11/28 23:42:02 steve
* NetESignal object no longer need to be NetNode
* objects. Let them keep a pointer to NetNet objects.
+247 -15
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1999 Stephen Williams (steve@icarus.com)
* Copyright (c) 1999-2000 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,10 +16,14 @@
* 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: functor.cc,v 1.5 1999/12/01 06:06:16 steve Exp $"
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: functor.cc,v 1.25 2001/07/25 03:10:49 steve Exp $"
#endif
# include "config.h"
# include <iostream>
# include "functor.h"
# include "netlist.h"
@@ -27,6 +31,10 @@ functor_t::~functor_t()
{
}
void functor_t::event(class Design*, class NetEvent*)
{
}
void functor_t::signal(class Design*, class NetNet*)
{
}
@@ -35,21 +43,78 @@ void functor_t::process(class Design*, class NetProcTop*)
{
}
void functor_t::lpm_add_sub(class Design*, class NetAddSub*)
{
}
void functor_t::lpm_compare(class Design*, class NetCompare*)
{
}
void functor_t::lpm_const(class Design*, class NetConst*)
{
}
void functor_t::lpm_divide(class Design*, class NetDivide*)
{
}
void functor_t::lpm_modulo(class Design*, class NetModulo*)
{
}
void functor_t::lpm_ff(class Design*, class NetFF*)
{
}
void Design::functor(functor_t*fun)
void functor_t::lpm_logic(class Design*, class NetLogic*)
{
// apply to signals
}
void functor_t::lpm_mult(class Design*, class NetMult*)
{
}
void functor_t::lpm_mux(class Design*, class NetMux*)
{
}
void NetScope::run_functor(Design*des, functor_t*fun)
{
for (NetScope*cur = sub_ ; cur ; cur = cur->sib_) {
cur->run_functor(des, fun);
}
for (NetEvent*cur = events_ ; cur ; /* */) {
NetEvent*tmp = cur;
cur = cur->snext_;
fun->event(des, tmp);
}
// apply to signals. Each iteration, allow for the possibility
// that the current signal deletes itself.
if (signals_) {
unsigned count = 0;
NetNet*cur = signals_->sig_next_;
do {
NetNet*tmp = cur->sig_next_;
fun->signal(this, cur);
cur = tmp;
count += 1;
cur = cur->sig_next_;
} while (cur != signals_->sig_next_);
cur = signals_->sig_next_;
for (unsigned idx = 0 ; idx < count ; idx += 1) {
NetNet*tmp = cur->sig_next_;
fun->signal(des, cur);
cur = tmp;
}
}
}
void Design::functor(functor_t*fun)
{
// Scan the scopes
root_scope_->run_functor(this, fun);
// apply to processes
procs_idx_ = procs_;
@@ -61,12 +126,30 @@ void Design::functor(functor_t*fun)
// apply to nodes
if (nodes_) {
/* 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;
do {
NetNode*tmp = cur->node_next_;
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;
} while (cur != nodes_->node_next_);
} while (nodes_ && (cur != bar));
}
}
@@ -75,11 +158,51 @@ void NetNode::functor_node(Design*, functor_t*)
{
}
void NetAddSub::functor_node(Design*des, functor_t*fun)
{
fun->lpm_add_sub(des, this);
}
void NetCompare::functor_node(Design*des, functor_t*fun)
{
fun->lpm_compare(des, this);
}
void NetConst::functor_node(Design*des, functor_t*fun)
{
fun->lpm_const(des, this);
}
void NetDivide::functor_node(Design*des, functor_t*fun)
{
fun->lpm_divide(des, this);
}
void NetFF::functor_node(Design*des, functor_t*fun)
{
fun->lpm_ff(des, this);
}
void NetLogic::functor_node(Design*des, functor_t*fun)
{
fun->lpm_logic(des, this);
}
void NetModulo::functor_node(Design*des, functor_t*fun)
{
fun->lpm_modulo(des, this);
}
void NetMult::functor_node(Design*des, functor_t*fun)
{
fun->lpm_mult(des, this);
}
void NetMux::functor_node(Design*des, functor_t*fun)
{
fun->lpm_mux(des, this);
}
proc_match_t::~proc_match_t()
{
}
@@ -99,6 +222,48 @@ int NetAssign::match_proc(proc_match_t*that)
return that->assign(this);
}
int proc_match_t::assign_nb(NetAssignNB*)
{
return 0;
}
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);
}
int proc_match_t::condit(NetCondit*)
{
return 0;
@@ -109,18 +274,85 @@ int NetCondit::match_proc(proc_match_t*that)
return that->condit(this);
}
int proc_match_t::pevent(NetPEvent*)
int NetEvWait::match_proc(proc_match_t*that)
{
return that->event_wait(this);
}
int proc_match_t::event_wait(NetEvWait*)
{
return 0;
}
int NetPEvent::match_proc(proc_match_t*that)
{
return that->pevent(this);
}
/*
* $Log: functor.cc,v $
* 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)
*
* Revision 1.24 2000/11/19 20:48:30 steve
* Fix cases where signal iteration might die early.
*
* Revision 1.23 2000/11/18 04:53:04 steve
* Watch out in functor, it may delete the last signal.
*
* Revision 1.22 2000/09/17 21:26:15 steve
* Add support for modulus (Eric Aardoom)
*
* 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.
*
+81 -14
View File
@@ -1,7 +1,7 @@
#ifndef __functor_H
#define __functor_H
/*
* Copyright (c) 1999 Stephen Williams (steve@icarus.com)
* Copyright (c) 1999-2000 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
@@ -18,14 +18,21 @@
* 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: functor.h,v 1.3 1999/12/01 06:06:16 steve Exp $"
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: functor.h,v 1.17 2000/09/17 21:26:15 steve Exp $"
#endif
/*
* The functor is an object that can be applied to a design to
* transform it. This is different from the target_t, which can only
* scan the design but not transform it in any way.
*
* When a functor it scanning a process, signal or node, the functor
* is free to manipulate the list by deleting items, including the
* node being scanned. The Design class scanner knows how to handle
* the situation. However, if objects are added to the netlist, there
* is no guarantee that object will be scanned unless the functor is
* rerun.
*/
class Design;
@@ -35,38 +42,98 @@ class NetProcTop;
struct functor_t {
virtual ~functor_t();
/* Signals are scanned first. This is called once for each
signal in the design. */
/* Events are scanned here. */
virtual void event(class Design*des, class NetEvent*);
/* This is called once for each signal in the design. */
virtual void signal(class Design*des, class NetNet*);
/* This method is called for each process in the design. */
virtual void process(class Design*des, class NetProcTop*);
/* This method is called for each structural adder. */
virtual void lpm_add_sub(class Design*des, class NetAddSub*);
/* This method is called for each structural comparator. */
virtual void lpm_compare(class Design*des, class NetCompare*);
/* This method is called for each structural constant. */
virtual void lpm_const(class Design*des, class NetConst*);
/* This method is called for each structural constant. */
virtual void lpm_divide(class Design*des, class NetDivide*);
/* This method is called for each structural constant. */
virtual void lpm_modulo(class Design*des, class NetModulo*);
/* This method is called for each FF in the design. */
virtual void lpm_ff(class Design*des, class NetFF*);
/* Handle LPM combinational logic devices. */
virtual void lpm_logic(class Design*des, class NetLogic*);
/* This method is called for each multiplier. */
virtual void lpm_mult(class Design*des, class NetMult*);
/* This method is called for each MUX. */
virtual void lpm_mux(class Design*des, class NetMux*);
};
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 pevent(class NetPEvent*);
virtual int event_wait(class NetEvWait*);
virtual int block(class NetBlock*);
};
/*
* $Log: functor.h,v $
* Revision 1.3 1999/12/01 06:06:16 steve
* Redo synth to use match_proc_t scanner.
* Revision 1.17 2000/09/17 21:26:15 steve
* Add support for modulus (Eric Aardoom)
*
* Revision 1.2 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.16 2000/08/01 02:48:42 steve
* Support <= in synthesis of DFF and ram devices.
*
* Revision 1.1 1999/07/17 22:01:13 steve
* Add the functor interface for functor transforms.
* Revision 1.15 2000/07/16 04:56:07 steve
* Handle some edge cases during node scans.
*
* Revision 1.14 2000/07/15 05:13:44 steve
* Detect muxing Vz as a bufufN.
*
* 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
+39
View File
@@ -0,0 +1,39 @@
Throughout Icarus Verilog descriptions and source code, I use a
variety of terms and acronyms that might be specific to Icarus
Verilog, have an Icarus Verilog specific meaning, or just aren't
widely known. So here I define these terms.
LRM - Language Reference Manual
This is a generic acronym, but in the Verilog world we sometimes
mean *the* language reference manual, the IEEE1364 standard.
PLI - Programming Language Interface
This is a C API into Verilog simulators that is defined by the
IEEE1364. There are two major interfaces, sometimes called PLI 1
and PLI 2. PLI 2 is also often called VPI.
UDP - User Defined Primitive
These are objects that Verilog programmers define with the
"primitive" keyword. They are truth-table based devices. The
syntax for defining them is described in the LRM.
VPI -
This is the C API that is defined by the Verilog standard, and
that Icarus Verilog partially implements. See also PLI.
VVM - Verilog Virtual Machine
This is the Icarus Verilog runtime that works with the code
generator that generates C++.
VVP - Verilog Virtual Processor
This is the Icarus Verilog runtime that reads in custom code in a
form that I call "VVP Assembly". See the vvp/ directory for
documentation on that.
+346
View File
@@ -0,0 +1,346 @@
Icarus Verilog vs. IEEE1364
Copyright 2000 Stephen Williams
The IEEE1364 standard is the bible that defines the correctness of the
Icarus Verilog implementation and behavior of the compiled
program. The IEEE1364.1 is also referenced for matters of
synthesis. So the ultimate definition of right and wrong comes from
those documents.
That does not mean that a Verilog implementation is fully
constrained. The standard document allows for implementation specific
behavior that, when properly accounted for, does not effect the
intended semantics of the specified language. It is therefore possible
and common to write programs that produce different results when run
by different Verilog implementations.
STANDARDIZATION ISSUES
These are some issues where the IEEE1364 left unclear, unspecified or
simply wrong. I'll try to be precise as I can, and reference the
standard as needed. I've made implementation decisions for Icarus
Verilog, and I will make clear what those decisions are and how they
affect the language.
* OBJECTS CAN BE DECLARED ANYWHERE IN THE MODULE
Consider this module:
module sample1;
initial foo = 1;
reg foo;
wire tmp = bar;
initial #1 $display("foo = %b, bar = %b", foo, tmp);
endmodule
Notice that the ``reg foo;'' declaration is placed after the first
initial statement. It turns out that this is a perfectly legal module
according to the -1995 and -2000 versions of the standard. The
statement ``reg foo;'' is a module_item_declaration which is in turn a
module_item. The BNF in the appendix of IEEE1364-1995 treats all
module_item statements equally, so no order is imposed.
Furthermore, there is no text (that I can find) elsewhere in the
standard that imposes any ordering restriction. The sorts of
restrictions I would look for are "module_item_declarations must
appear before all other module_items" or "variables must be declared
textually before they are referenced." Such statements simply do not
exist. (Personally, I think it is fine that they don't.)
The closest is the rules for implicit declarations of variables that
are otherwise undeclared. In the above example, ``bar'' is implicitly
declared and is therefore a wire. However, although ``initial foo = 1;''
is written before foo is declared, foo *is* declared within the
module, and declared legally by the BNF of the standard.
Here is another example:
module sample2;
initial x.foo = 1;
test x;
initial #1 $display("foo = %b", x.foo);
endmodule
module test;
reg foo;
endmodule;
From this example one can clearly see that foo is once again declared
after its use in behavioral code. One also sees a forward reference of
an entire module. Once again, the standard places no restriction on
the order of module declarations in a source file, so this program is,
according to the standard, perfectly well formed.
Icarus Verilog interprets both of these examples according to "The
Standard As I Understand It." However, commercial tools in general
break down with these programs. In particular, the first example
may generate different errors depending on the tool. The most common
error is to claim that ``foo'' is declared twice, once (implicitly) as
a wire and once as a reg.
So the question now becomes, "Is the standard broken, or are the tools
limited?" Coverage of the standard seems to vary widely from tool to
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
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
of efficient compilers.
However, the existence hierarchical naming syntax as demonstrated in
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
ordering, by requiring that modules that are used be first defined.
* TASK AND FUNCTION PARAMETERS CANNOT HAVE EXPLICIT TYPES
Consider a function negate that wants to take a signed integer value
and return its negative:
function integer negate;
input [15:0] val;
negate = -val;
endfunction
This is not quite right, because the input is implicitly a reg type,
which is unsigned. The result, then, will always be a negative value,
even if a negative val is passed in.
It is possible to fix up this specific example to work properly with
the bit pattern of a 16bit number, but that is not the point. What's
needed is clarification on whether an input can be declared in the
port declaration as well as in the contained block declaration.
As I understand the situation, this should be allowed:
function integer negate;
input [15:0] val;
reg signed [15:0] val;
negate = -val;
endfunction
In the -1995 standard, the variable is already implicitly a reg if
declared within a function or task. However, in the -2000 standard
there is now (as in this example) a reason why one might want to
actually declare the type explicitly.
I think that a port *cannot* be declared as an integer or time type
(though the result can) because the range of the port declaration must
match the range of the integer/time declaration, but the range of
integers is unspecified. This, by the way, also applies to module
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
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.
* ROUNDING OF TIME
When the `timescale directive is present, the compiler is supposed to
round fractional times (after scaling) to the nearest integer. The
confusing bit here is that it is apparently conventional that if the
`timescale directive is *not* present, times are rounded towards zero
always.
* VALUE OF X IN PRIMITIVE OUTPUTS
The IEEE1364-1995 standard clearly states in Table 8-1 that the x
symbols is allowed in input columns, but is not allowed in
outputs. Furthermore, none of the examples have an x in the output of
a primitive. Table 8-1 in the IEEE1364-2000 also says the same thing.
However, the BNF clearly states that 0, 1, x and X are valid
output_symbol characters. The standard is self contradictory. So I
take it that x is allowed, as that is what Verilog-XL does.
* REPEAT LOOPS vs. REPEAT EVENT CONTROL
There seems to be ambiguity in how code like this should be parsed:
repeat (5) @(posedge clk) <statment>;
There are two valid interpretations of this code, from the
IEEE1364-1995 standard. One looks like this:
procedural_timing_control_statement ::=
delay_or_event_control statement_or_null
delay_or_event_control ::=
event_control
| repeat ( expression ) event_control
If this interpretation is used, then the statement <statement> should
be executed after the 5th posedge of clk. However, there is also this
interpretation:
loop_statement ::=
repeat ( expression ) statement
If *this* interpretation is used, then <statement> should be executed
5 times on the posedge of clk. The way the -1995 standard is written,
these are both equally valid interpretations of the example, yet they
produce very different results. The standard offers no guidance on how
to resolve this conflict, and the IEEE1364-2000 DRAFT does not improve
the situation.
Practice suggests that a repeat followed by an event control should be
interpreted as a loop head, and this is what Icarus Verilog does, as
well as all the other major Verilog tools, but the standard does not
say this.
* UNSIZED EXPRESSIONS AS PARAMETERS TO CONCATENATION {}
The Verilog standard clearly states in 4.1.14:
"Unsized constant numbers shall not be allowed in
concatenations. This is because the size of each
operand in the concatenation is needed to calculate
the complete size of the concatenation."
So for example the expression {1'b0, 16} is clearly illegal. It
also stands to reason that {1'b0, 15+1} is illegal, for exactly the
same justification. What is the size of the expression (15+1)?
Furthermore, it is reasonable to expect that (16) and (15+1) are
exactly the same so far as the compiler is concerned.
Unfortunately, Cadence seems to feel otherwise. In particular, it has
been reported that although {1'b0, 16} causes an error, {1'b0, 15+1}
is accepted. Further testing shows that any expression other then a
simple unsized constant is accepted there, even if all the operands of
all the operators that make up the expression are unsized integers.
This is a semantic problem. Icarus Verilog doesn't limit the size of
integer constants. This is valid as stated in 2.5.1 Note 3:
"The number of bits that make up an unsized number
(which is a simple decimal number or a number without
the size specification) shall be *at*least* 32."
[emphasis added]
Icarus Verilog will hold any integer constant, so the size will be as
large as it needs to be, whether that is 64bits, 128bits, or
more. With this in mind, what is the value of these expressions?
{'h1_00_00_00_00}
{'h1 << 32}
{'h0_00_00_00_01 << 32}
{'h5_00_00_00_00 + 1}
These examples show that the standard is justified in requiring that
the operands of concatenation have size. The dispute is what it takes
to cause an expression to have a size, and what that size is.
Verilog-XL claims that (16) does not have a size, but (15+1) does. The
size of the expression (15+1) is the size of the adder that is
created, but how wide is the adder when adding unsized constants?
One might note that the quote from section 4.1.14 says "Unsized
*constant*numbers* shall not be allowed." It does not say "Unsized
expressions...", so arguably accepting (15+1) or even (16+0) as an
operand to a concatenation is not a violation of the letter of the
law. However, the very next sentence of the quote expresses the
intent, and accepting (15+1) as having a more defined size then (16)
seems to be a violation of that intent.
Whatever a compiler decides the size is, the user has no way to
predict it, and the compiler should not have the right to treat (15+1)
any differently then (16). Therefore, Icarus Verilog takes the
position that such expressions are *unsized* and are not allowed as
operands to concatenations. Icarus Verilog will in general assume that
operations on unsized numbers produce unsized results. There are
exceptions when the operator itself does define a size, such as the
comparison operators or the reduction operators. Icarus Verilog will
generate appropriate error messages.
* MODULE INSTANCE WITH WRONG SIZE PORT LIST
A module declaration like this declares a module that takes three ports:
module three (a, b, c);
input a, b, c;
reg x;
endmodule
This is fine and obvious. It is also clear from the standard that
these are legal instantiations of this module:
three u1 (x,y,z);
three u2 ( ,y, );
three u3 ( , , );
three u4 (.b(y));
In some of the above examples, there are unconnected ports. In the
case of u4, the pass by name connects only port b, and leaves a and c
unconnected. u2 and u4 are the same thing, in fact, but using
positional or by-name syntax. The next example is a little less
obvious:
three u4 ();
The trick here is that strictly speaking, the parser cannot tell
whether this is a list of no pass by name ports (that is, all
unconnected) or an empty positional list. If this were an empty
positional list, then the wrong number of ports is given, but if it is
an empty by-name list, it is an obviously valid instantiation. So it
is fine to accept this case as valid.
These are more doubtful:
three u5(x,y);
three u6(,);
These are definitely positional port lists, and they are definitely
the wrong length. In this case, the standard is not explicit about
what to do about positional port lists in module instantiations,
except that the first is connected to the first, second to second,
etc. It does not say that the list must be the right length, but every
example of unconnected ports used by-name syntax, and every example of
ordered list has the right size list.
Icarus Verilog takes the (very weak) hint that ordered lists should be
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 $
$Log: ieee1364-notes.txt,v $
Revision 1.8 2001/08/01 05:17:31 steve
Accept empty port lists to module instantiation.
Revision 1.7 2001/02/17 05:27:31 steve
I allow function ports to have types.
Revision 1.6 2001/02/12 16:48:04 steve
Rant about bit widths.
Revision 1.5 2001/01/02 17:28:08 steve
Resolve repeat ambiguity in favor of loop.
Revision 1.4 2001/01/01 19:12:35 steve
repeat loops ambiguity.
Revision 1.3 2000/12/15 00:21:46 steve
rounding of time and x in primitives.
Revision 1.2 2000/11/19 22:03:04 steve
Integer parameter comments.
Revision 1.1 2000/07/23 18:06:31 steve
Document ieee1364 issues.
+97
View File
@@ -0,0 +1,97 @@
# The iverilog.conf configuration file provides to the iverilog driver
# strings based on switches that are passed by the user on the command
# line.
#
# Comments start from the hash (#) character and run to the end of the
# line.
#
# Conditions are a list of requirements between [] characters. For the
# set of patterns following a string to b activated, all the
# conditions must be true. Valid conditions are:
#
# -S -- The -S flag is passed to iverilog
# -t<string> -- The -t<string> parameters is passed to iverilog
#
#
# Patterns have a name and text. The name has the form <key> where the
# key is some key value that is required by iverilog. The commonly
# used keys are:
#
# <ivl>
# The string here is the command line needed to take the
# preprocessor output (ivlpp) and compile it with the
# target. All target types use this key.
#
# The pattern text includes %<code> substitutions. iverilog
# substitutes values for the %<code> sequences within the text.
#
# %B Substitute the base libdir, -B flag of iverilog.
#
# %f Substitute the -f flags from the command line.
#
# %s Substitute the start module (-s flag) from the user.
#
# %N Substitute the value of the -N<path> flag.
#
# %o Substitute the value of the -o<path> flag, or the default
# output path if there is no -o flag.
#
# %T Substitute min, typ or max depending on the -T flag from the
# command line.
#
#
# %W Substitute the ivl warning flags.
#
# %[<c><text>]
# This substitution pattern is magical, and is the only
# multicharacter pattern. This tests the code <c>, and
# substitutes <text> into the output only if <c> is true.
# The <text> may include further substitution strings, and is
# terminated by a ``]'' character.
# This is the null (no op) target. Thre is a synthesis version and a
# non-synthesis version. Normally, this does not matter, but this can
# 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 -- -
[-tnull]
<ivl>%B/ivl %[v-v] %W %[s-s%s] %[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 -- -
[-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 -- -
# 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 -- -
# 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 -- -
# --
# 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 -- -
+157
View File
@@ -0,0 +1,157 @@
EXPORTS
ivl_design_const
ivl_design_consts
ivl_design_flag
ivl_design_process
ivl_design_root
ivl_design_time_precision
ivl_const_bits
ivl_const_pin
ivl_const_pins
ivl_const_signed
ivl_event_any
ivl_event_basename
ivl_event_name
ivl_event_nany
ivl_event_neg
ivl_event_nneg
ivl_event_npos
ivl_event_pos
ivl_expr_type
ivl_expr_bits
ivl_expr_def
ivl_expr_lsi
ivl_expr_memory
ivl_expr_name
ivl_expr_opcode
ivl_expr_oper1
ivl_expr_oper2
ivl_expr_oper3
ivl_expr_parm
ivl_expr_parms
ivl_expr_repeat
ivl_expr_scope
ivl_expr_signal
ivl_expr_signed
ivl_expr_string
ivl_expr_uvalue
ivl_expr_width
ivl_logic_name
ivl_logic_basename
ivl_logic_scope
ivl_logic_type
ivl_logic_pin
ivl_logic_pins
ivl_logic_udp
ivl_lpm_basename
ivl_lpm_clk
ivl_lpm_data
ivl_lpm_datab
ivl_lpm_data2
ivl_lpm_enable
ivl_lpm_memory
ivl_lpm_name
ivl_lpm_q
ivl_lpm_scope
ivl_lpm_select
ivl_lpm_selects
ivl_lpm_size
ivl_lpm_type
ivl_lpm_width
ivl_lval_idx
ivl_lval_mem
ivl_lval_mux
ivl_lval_part_off
ivl_lval_pin
ivl_lval_pins
ivl_lval_sig
ivl_memory_basename
ivl_memory_name
ivl_memory_root
ivl_memory_size
ivl_memory_width
ivl_nexus_get_private
ivl_nexus_name
ivl_nexus_ptrs
ivl_nexus_ptr
ivl_nexus_set_private
ivl_nexus_ptr_con
ivl_nexus_ptr_drive0
ivl_nexus_ptr_drive1
ivl_nexus_ptr_pin
ivl_nexus_ptr_lpm
ivl_nexus_ptr_log
ivl_nexus_ptr_sig
ivl_scope_basename
ivl_scope_children
ivl_scope_def
ivl_scope_event
ivl_scope_events
ivl_scope_logs
ivl_scope_log
ivl_scope_lpms
ivl_scope_lpm
ivl_scope_mem
ivl_scope_mems
ivl_scope_name
ivl_scope_parent
ivl_scope_port
ivl_scope_ports
ivl_scope_sigs
ivl_scope_sig
ivl_scope_type
ivl_scope_tname
ivl_signal_attr
ivl_signal_pin
ivl_signal_pins
ivl_signal_port
ivl_signal_signed
ivl_signal_type
ivl_signal_name
ivl_signal_basename
ivl_process_scope
ivl_process_stmt
ivl_process_type
ivl_statement_type
ivl_stmt_block_count
ivl_stmt_block_stmt
ivl_stmt_call
ivl_stmt_case_count
ivl_stmt_case_expr
ivl_stmt_case_stmt
ivl_stmt_cond_expr
ivl_stmt_cond_false
ivl_stmt_cond_true
ivl_stmt_delay_expr
ivl_stmt_delay_val
ivl_stmt_event
ivl_stmt_lval
ivl_stmt_lvals
ivl_stmt_lwidth
ivl_stmt_name
ivl_stmt_parm
ivl_stmt_parm_count
ivl_stmt_rval
ivl_stmt_sub_stmt
ivl_udp_init
ivl_udp_name
ivl_udp_nin
ivl_udp_row
ivl_udp_rows
ivl_udp_sequ
+1187
View File
File diff suppressed because it is too large Load Diff
+13 -13
View File
@@ -18,7 +18,7 @@
# 59 Temple Place - Suite 330
# Boston, MA 02111-1307, USA
#
#ident "$Id: Makefile.in,v 1.6 1999/10/16 20:48:15 steve Exp $"
#ident "$Id: Makefile.in,v 1.12 2001/08/10 00:39:22 steve Exp $"
#
#
SHELL = /bin/sh
@@ -31,8 +31,8 @@ srcdir = @srcdir@
VPATH = $(srcdir)
bindir = $(exec_prefix)/bin
libdir = $(exec_prefix)/lib
bindir = @bindir@
libdir = @libdir@
includedir = $(prefix)/include
CC = @CC@
@@ -41,8 +41,8 @@ INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
CPPFLAGS = @CPPFLAGS@ @DEFS@
CFLAGS = @CFLAGS@
LDFLAGS = @LDFLAGS@
CFLAGS = @CFLAGS@ -I. -I$(srcdir)/..
LDFLAGS = @LDFLAGS@
all: ivlpp
@@ -52,24 +52,24 @@ clean:
O = main.o lexor.o parse.o
ivlpp: $O
$(CC) $(LDFLAGS) $O -o ivlpp
$(CC) $(LDFLAGS) $O -o ivlpp @EXTRALIBS@
lexor.c: lexor.lex
flex -s -olexor.c lexor.lex
flex -s -olexor.c $(srcdir)/lexor.lex
parse.h parse.c: parse.y
bison --verbose -t -d parse.y -o parse.c
bison --verbose -t -d -o parse.c $(srcdir)/parse.y
install: all installdirs $(bindir)/ivlpp
install: all installdirs $(libdir)/ivl/ivlpp
$(bindir)/ivlpp: ivlpp
$(INSTALL_PROGRAM) ./ivlpp $(bindir)/ivlpp
$(libdir)/ivl/ivlpp: ivlpp
$(INSTALL_PROGRAM) ./ivlpp $(libdir)/ivl/ivlpp
installdirs: ../mkinstalldirs
$(srcdir)/../mkinstalldirs $(bindir)
$(srcdir)/../mkinstalldirs $(libdir)/ivl
uninstall:
rm -f $(bindir)/ivlpp
rm -f $(libdir)/ivl/ivlpp
lexor.o: lexor.c parse.h globals.h
main.o: main.c globals.h
+14 -3
View File
@@ -18,14 +18,14 @@
* 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: globals.h,v 1.2 1999/09/05 22:33:18 steve Exp $"
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: globals.h,v 1.5 2000/09/13 22:33:13 steve Exp $"
#endif
# include <stdio.h>
extern void reset_lexor(FILE*out, char*paths[]);
extern void define_macro(const char*name, const char*value);
extern void define_macro(const char*name, const char*value, int keyword);
/* These variables contain the include directories to be searched when
an include directive in encountered. */
@@ -35,11 +35,22 @@ extern unsigned include_cnt;
/* This flag is true if #line directives are to be generated. */
extern int line_direct_flag;
extern unsigned error_count;
/* This is the entry to the parser. */
extern int yyparse();
/*
* $Log: globals.h,v $
* Revision 1.5 2000/09/13 22:33:13 steve
* undefined macros are null (with warnings.)
*
* Revision 1.4 2000/08/20 17:49:04 steve
* Clean up warnings and portability issues.
*
* Revision 1.3 2000/06/30 15:49:44 steve
* Handle errors from parser slightly differently.
*
* Revision 1.2 1999/09/05 22:33:18 steve
* Take multiple source files on the command line.
*
+70 -16
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)
#ident "$Id: lexor.lex,v 1.14 1999/10/08 17:27:56 steve Exp $"
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: lexor.lex,v 1.24 2001/07/25 03:10:50 steve Exp $"
#endif
# include "config.h"
# include <stdio.h>
# include <malloc.h>
# include <string.h>
@@ -35,6 +37,7 @@ static void output_init();
static void def_match();
static void def_start();
static void def_finish();
static void def_undefine();
static void do_define();
static int is_defined(const char*name);
@@ -84,6 +87,7 @@ static int comment_enter = 0;
%x PPDEFINE
%x CCOMMENT
%x CSTRING
%x ERROR_LINE
%x IFDEF_FALSE
%s IFDEF_TRUE
@@ -115,30 +119,59 @@ W [ \t\b\f]+
that follows it. when the directive ends, the do_include function
performs the include operation. */
^{W}?`include { BEGIN(PPINCLUDE); }
^{W}?`include { yy_push_state(PPINCLUDE); }
<PPINCLUDE>\"[^\"]*\" { include_filename(); }
<PPINCLUDE>[ \t\b\f] { ; }
<PPINCLUDE>\n { istack->lineno += 1; BEGIN(0); do_include(); }
/* Catch single-line comments that share the line with an include
directive. And while I'm at it, I might as well preserve the
comment in the output stream. */
<PPINCLUDE>"//".* { ECHO; }
/* These finish the include directive (EOF or EOL) so I revert the
lexor state and execute the inclusion. */
<PPINCLUDE>\n { istack->lineno += 1; yy_pop_state(); do_include(); }
<PPINCLUDE>\r\n { istack->lineno += 1; yy_pop_state(); do_include(); }
<PPINCLUDE>\n\r { istack->lineno += 1; yy_pop_state(); do_include(); }
<PPINCLUDE><<EOF>> { istack->lineno += 1; yy_pop_state(); do_include(); }
/* 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);
error_count += 1;
BEGIN(ERROR_LINE); }
/* Detect the define directive, and match the name. Match any
white space that might be found, as well. After I get the
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}? { BEGIN(PPDEFINE); def_start(); }
`define{W}[a-zA-Z_][a-zA-Z0-9_]*{W}? { yy_push_state(PPDEFINE); def_start(); }
<PPDEFINE>.*\n {
do_define();
<PPDEFINE>.* { do_define(); }
<PPDEFINE>(\n|"\r\n"|"\n\r") {
def_finish();
istack->lineno += 1;
fputc('\n', yyout);
BEGIN(0);
yy_pop_state();
}
`undef{W}[a-zA-Z][a-zA-Z0-9_]*{W}?.* { def_undefine(); }
<PPDEFINE><<EOF>> {
def_finish();
istack->lineno += 1;
fputc('\n', yyout);
yy_pop_state();
}
`undef{W}[a-zA-Z_][a-zA-Z0-9_]*{W}?.* { def_undefine(); }
/* Detect conditional compilation directives, and parse them. If I
@@ -150,7 +183,7 @@ 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_]*.* {
^{W}?`ifdef{W}[a-zA-Z_][a-zA-Z0-9_]*.* {
char*name = strchr(yytext, '`');
assert(name);
name += 6;
@@ -186,6 +219,9 @@ W [ \t\b\f]+
. { ECHO; }
\n { istack->lineno += 1; ECHO; }
/* Absorb the rest of the line when a broken directive is detected. */
<ERROR_LINE>.* { yy_pop_state(); }
%%
/* Defined macros are kept in this table for convenient lookup. As
`define directives are matched (and the do_define() function
@@ -194,6 +230,8 @@ W [ \t\b\f]+
struct define_t {
char*name;
char*value;
/* keywords don't get rescanned for fresh values. */
int keyword;
struct define_t*left, *right, *up;
};
@@ -233,8 +271,14 @@ static void def_match()
struct define_t*cur = def_lookup(yytext+1);
if (cur) {
struct include_stack_t*isp
= calloc(1, sizeof(struct include_stack_t));
struct include_stack_t*isp;
if (cur->keyword) {
fprintf(yyout, "%s", cur->value);
return;
}
isp = calloc(1, sizeof(struct include_stack_t));
isp->str = cur->value;
isp->next = istack;
istack->yybs = YY_CURRENT_BUFFER;
@@ -242,7 +286,9 @@ static void def_match()
yy_switch_to_buffer(yy_new_buffer(istack->file, YY_BUF_SIZE));
} else {
fprintf(yyout, "%s", yytext);
fprintf(stderr, "%s:%u: warning: macro %s undefined "
"(and assumed null) at this point.\n",
istack->path, istack->lineno, yytext);
}
}
@@ -253,11 +299,12 @@ static void def_start()
sscanf(yytext, "`define %s", def_name);
}
void define_macro(const char*name, const char*value)
void define_macro(const char*name, const char*value, int keyword)
{
struct define_t*def = malloc(sizeof(struct define_t));
def->name = strdup(name);
def->value = strdup(value);
def->keyword = keyword;
def->left = 0;
def->right = 0;
def->up = 0;
@@ -317,7 +364,14 @@ static void do_define()
*cp = 0;
}
define_macro(def_name, yytext);
define_macro(def_name, yytext, 0);
def_name[0] = 0;
}
static void def_finish()
{
if (def_name[0])
define_macro(def_name, "1", 0);
}
static void def_undefine()
@@ -522,7 +576,7 @@ static int yywrap()
if (line_direct_flag)
fprintf(yyout, "\n#line \"%s\" 0\n", istack->path);
yyrestart(isp->file);
yyrestart(istack->file);
return 0;
}
+70 -5
View File
@@ -16,10 +16,12 @@ 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)
#ident "$Id: main.c,v 1.4 1999/11/29 17:02:21 steve Exp $"
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: main.c,v 1.11 2001/07/25 03:10:50 steve Exp $"
#endif
# include "config.h"
const char NOTICE[] =
" This program is free software; you can redistribute it and/or modify\n"
" it under the terms of the GNU General Public License as published by\n"
@@ -39,6 +41,7 @@ const char NOTICE[] =
const char VERSION[] = "$Name: $ $State: Exp $";
# include <stdio.h>
# include <stdlib.h>
# include <malloc.h>
# include <unistd.h>
# include <string.h>
@@ -47,11 +50,19 @@ const char VERSION[] = "$Name: $ $State: Exp $";
#endif
# include "globals.h"
#if defined(__MINGW32__) && !defined(HAVE_GETOPT_H)
extern int getopt(int argc, char*argv[], const char*fmt);
extern int optind;
extern const char*optarg;
#endif
char**include_dir = 0;
unsigned include_cnt = 0;
int line_direct_flag = 0;
unsigned error_count = 0;
int main(int argc, char*argv[])
{
int opt;
@@ -59,11 +70,30 @@ int main(int argc, char*argv[])
char*out_path = 0;
FILE*out;
/* Define preprocessor keywords that I plan to just pass. */
define_macro("celldefine", "`celldefine", 1);
define_macro("default_nettype", "`default_nettype", 1);
define_macro("delay_mode_distributed", "`delay_mode_distributed", 1);
define_macro("delay_mode_unit", "`delay_mode_unit", 1);
define_macro("delay_mode_path", "`delay_mode_path", 1);
define_macro("disable_portfaults", "`disable_portfaults", 1);
define_macro("enable_portfaults", "`enable_portfaults", 1);
define_macro("endcelldefine", "`endcelldefine", 1);
define_macro("endprotect", "`endprotect", 1);
define_macro("nosuppress_faults", "`nosuppress_faults", 1);
define_macro("nounconnected_drive", "`nounconnected_drive", 1);
define_macro("protect", "`protect", 1);
define_macro("resetall", "`resetall", 1);
define_macro("suppress_faults", "`suppress_faults", 1);
define_macro("timescale", "`timescale", 1);
define_macro("unconnected_drive", "`unconnected_drive", 1);
define_macro("uselib", "`uselib", 1);
include_dir = malloc(sizeof(char*));
include_dir[0] = strdup(".");
include_cnt = 1;
while ((opt = getopt(argc, argv, "D:I:Lo:v")) != EOF) switch (opt) {
while ((opt = getopt(argc, argv, "D:I:K:Lo:v")) != EOF) switch (opt) {
case 'D': {
char*tmp = strdup(optarg);
@@ -73,7 +103,7 @@ int main(int argc, char*argv[])
else
val = "1";
define_macro(tmp, val);
define_macro(tmp, val, 0);
free(tmp);
break;
}
@@ -84,6 +114,15 @@ int main(int argc, char*argv[])
include_cnt += 1;
break;
case 'K': {
char*buf = malloc(strlen(optarg) + 2);
buf[0] = '`';
strcpy(buf+1, optarg);
define_macro(optarg, buf, 1);
free(buf);
break;
}
case 'L':
line_direct_flag = 1;
break;
@@ -115,6 +154,7 @@ int main(int argc, char*argv[])
fprintf(stderr, "\nUsage: %s [-v][-L][-I<dir>][-D<def>] <file>...\n"
" -D<def> - Predefine a value.\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"
" -o<fil> - Send the output to <fil>\n"
" -v - Print version information\n",
@@ -138,11 +178,36 @@ int main(int argc, char*argv[])
}
reset_lexor(out, argv+optind);
return yyparse();
if (yyparse()) return -1;
return error_count;
}
/*
* $Log: main.c,v $
* 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)
*
* Revision 1.10 2001/06/23 18:41:02 steve
* Include stdlib.h
*
* Revision 1.9 2001/05/20 18:08:07 steve
* local declares if the header is missing.
*
* Revision 1.8 2000/12/06 05:15:21 steve
* fix portfaults pass values.
*
* Revision 1.7 2000/09/13 22:33:13 steve
* undefined macros are null (with warnings.)
*
* Revision 1.6 2000/08/20 17:49:05 steve
* Clean up warnings and portability issues.
*
* Revision 1.5 2000/06/30 15:49:44 steve
* Handle errors from parser slightly differently.
*
* Revision 1.4 1999/11/29 17:02:21 steve
* include getopt if present.
*
+2 -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)
#ident "$Id: parse.y,v 1.1 1999/07/03 17:24:11 steve Exp $"
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: parse.y,v 1.2 2000/08/20 17:49:05 steve Exp $"
#endif
static void yyerror(const char*msg);
+394 -126
View File
@@ -1,7 +1,7 @@
%{
/*
* Copyright (c) 1998-1999 Stephen Williams ([email protected])
* Copyright (c) 1998-2000 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,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)
#ident "$Id: lexor.lex,v 1.38 1999/11/23 02:49:04 steve Exp $"
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: lexor.lex,v 1.62 2001/08/31 17:38:41 steve Exp $"
#endif
# include "config.h"
//# define YYSTYPE lexval
# include <iostream.h>
@@ -30,22 +32,57 @@
# 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
/*
* 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.
*/
extern YYLTYPE yylloc;
struct file_name_cell {
const char*text;
struct file_name_cell*next;
};
static struct file_name_cell*file_names = 0;
static const char* set_file_name(char*text)
{
struct file_name_cell*cur = file_names;
while (cur) {
if (strcmp(cur->text, text) == 0) {
delete[]text;
return cur->text;
}
cur = cur->next;
}
cur = new struct file_name_cell;
cur->text = text;
cur->next = file_names;
return text;
}
extern void pform_set_timescale(int, int);
static void reset_lexor();
static void line_directive();
static void line_directive2();
extern int check_identifier(const char*str, int len);
static verinum*make_sized_binary(const char*txt);
static verinum*make_sized_dec(const char*txt);
static verinum*make_unsized_dec(const char*txt);
static verinum*make_sized_octal(const char*txt);
static verinum*make_sized_hex(const char*txt);
static verinum*make_unsized_binary(const char*txt);
@@ -53,6 +90,8 @@ 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 void process_timescale(const char*txt);
static int comment_enter;
%}
@@ -93,10 +132,14 @@ W [ \t\b\f\r]+
"!==" { return K_CNE; }
"||" { return K_LOR; }
"&&" { return K_LAND; }
"&&&" { return K_TAND; }
"~|" { return K_NOR; }
"~^" { return K_NXOR; }
"^~" { return K_NXOR; }
"~&" { return K_NAND; }
"->" { return K_TRIGGER; }
"+:" { return K_PO_POS; }
"-:" { return K_PO_NEG; }
[}{;:\[\],()#=.@&!?<>%|^~+*/-] { return yytext[0]; }
@@ -106,6 +149,7 @@ W [ \t\b\f\r]+
<CSTRING>\n { BEGIN(0);
yylval.text = strdup(yytext);
VLerror(yylloc, "Missing close quote of string.");
yylloc.first_line += 1;
return STRING; }
<CSTRING>\" { BEGIN(0);
yylval.text = strdup(yytext);
@@ -113,72 +157,95 @@ W [ \t\b\f\r]+
return STRING; }
<CSTRING>. { yymore(); }
<UDPTABLE>\(\?0\) { return '_'; }
<UDPTABLE>\(\?1\) { return '+'; }
<UDPTABLE>\(\?x\) { return '%'; }
<UDPTABLE>\(\?\?\) { return '*'; }
<UDPTABLE>\(01\) { return 'r'; }
<UDPTABLE>\(0x\) { return 'P'; }
<UDPTABLE>\(10\) { return 'f'; }
<UDPTABLE>\(1x\) { return 'N'; }
<UDPTABLE>\(x0\) { return 'F'; }
<UDPTABLE>\(x1\) { return 'R'; }
<UDPTABLE>\(\?0\) { return '_'; }
<UDPTABLE>\(\?1\) { return '+'; }
<UDPTABLE>\(\?[xX]\) { return '%'; }
<UDPTABLE>\(\?\?\) { return '*'; }
<UDPTABLE>\(01\) { return 'r'; }
<UDPTABLE>\(0[xX]\) { return 'Q'; }
<UDPTABLE>\(0\?\) { return 'P'; }
<UDPTABLE>\(10\) { return 'f'; }
<UDPTABLE>\(1[xX]\) { return 'M'; }
<UDPTABLE>\(1\?\) { return 'N'; }
<UDPTABLE>\([xX]0\) { return 'F'; }
<UDPTABLE>\([xX]1\) { return 'R'; }
<UDPTABLE>\([xX]\?\) { return 'B'; }
<UDPTABLE>[bB] { return 'b'; }
<UDPTABLE>[lL] { return 'l'; /* IVL extension */ }
<UDPTABLE>[hH] { return 'h'; /* IVL extension */ }
<UDPTABLE>[fF] { return 'f'; }
<UDPTABLE>[rR] { return 'r'; }
<UDPTABLE>[xX] { return 'x'; }
<UDPTABLE>[pPnN01\?\*\-] { return yytext[0]; }
<UDPTABLE>[nN] { return 'n'; }
<UDPTABLE>[pP] { return 'p'; }
<UDPTABLE>[01\?\*\-] { return yytext[0]; }
[a-zA-Z_][a-zA-Z0-9$_]* {
int rc = check_identifier(yytext, yyleng);
int rc = lexor_keyword_code(yytext, yyleng);
if (rc == IDENTIFIER)
yylval.text = strdup(yytext);
else
yylval.text = 0;
return rc; }
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]+ {
yylval.text = strdup(yytext);
yylval.text = strdup(yytext+1);
return IDENTIFIER; }
\$([a-zA-Z0-9$_]+) {
if (strcmp(yytext,"$setuphold") == 0)
return K_Ssetuphold;
if (strcmp(yytext,"$attribute") == 0)
return KK_attribute;
if (strcmp(yytext,"$hold") == 0)
return K_Shold;
if (strcmp(yytext,"$period") == 0)
return K_Speriod;
if (strcmp(yytext,"$recovery") == 0)
return K_Srecovery;
if (strcmp(yytext,"$setup") == 0)
return K_Ssetup;
if (strcmp(yytext,"$width") == 0)
return K_Swidth;
yylval.text = strdup(yytext);
return SYSTEM_IDENTIFIER; }
\.{W}?[a-zA-Z_][a-zA-Z0-9$_]* {
\.{W}?(([a-zA-Z_][a-zA-Z0-9$_]*)|(\\[^ \t\b\f\r]+)) {
char*cp = yytext+1;
while (! (isalpha(*cp) || (*cp == '_')))
while ( (!(isalpha(*cp) || (*cp == '_'))) && (*cp != '\\'))
cp += 1;
if (*cp == '\\')
cp++;
yylval.text = strdup(cp);
return PORTNAME; }
[0-9][0-9_]*[ \t]*\'[dD][ \t]*[0-9][0-9_]* {
[0-9][0-9_]*[ \t]*\'[sS]?[dD][ \t]*[0-9][0-9_]* {
yylval.number = make_sized_dec(yytext);
return NUMBER; }
[0-9][0-9_]*[ \t]*\'[bB][ \t]*[0-1xzXZ_\?]+ {
[0-9][0-9_]*[ \t]*\'[sS]?[bB][ \t]*[0-1xzXZ_\?]+ {
yylval.number = make_sized_binary(yytext);
return NUMBER; }
[0-9][0-9_]*[ \t]*\'[oO][ \t]*[0-7xzXZ_\?]+ {
[0-9][0-9_]*[ \t]*\'[sS]?[oO][ \t]*[0-7xzXZ_\?]+ {
yylval.number = make_sized_octal(yytext);
return NUMBER; }
[0-9][0-9_]*[ \t]*\'[hH][ \t]*[0-9a-fA-FxzXZ_\?]+ {
[0-9][0-9_]*[ \t]*\'[sS]?[hH][ \t]*[0-9a-fA-FxzXZ_\?]+ {
yylval.number = make_sized_hex(yytext);
return NUMBER; }
\'d[ \t]*[0-9][0-9_]* { yylval.number = make_unsized_dec(yytext);
return NUMBER; }
\'[bB][ \t]*[0-1xzXZ_\?]+ { yylval.number = make_unsized_binary(yytext);
\'[sS]?[dD][ \t]*[0-9][0-9_]* { yylval.number = make_unsized_dec(yytext);
return NUMBER; }
\'[sS]?[bB][ \t]*[0-1xzXZ_\?]+ { yylval.number = make_unsized_binary(yytext);
return NUMBER; }
\'[oO][ \t]*[0-7xzXZ_\?]+ { yylval.number = make_unsized_octal(yytext);
\'[sS]?[oO][ \t]*[0-7xzXZ_\?]+ { yylval.number = make_unsized_octal(yytext);
return NUMBER; }
\'[hH][ \t]*[0-9a-fA-FxzXZ_\?]+ { yylval.number = make_unsized_hex(yytext);
\'[sS]?[hH][ \t]*[0-9a-fA-FxzXZ_\?]+ { yylval.number = make_unsized_hex(yytext);
return NUMBER; }
[0-9][0-9_]* {
@@ -198,6 +265,7 @@ W [ \t\b\f\r]+
}
yylval.number = new verinum(bits, nbits, false);
yylval.number->has_sign(true);
delete[]bits;
return NUMBER; }
@@ -212,11 +280,9 @@ W [ \t\b\f\r]+
/* Notice and handle the timescale directive. */
`timescale { BEGIN(PPTIMESCALE); }
<PPTIMESCALE>. { ; }
^{W}?`timescale { BEGIN(PPTIMESCALE); }
<PPTIMESCALE>.* { process_timescale(yytext); }
<PPTIMESCALE>\n {
cerr << yylloc.text << ":" << yylloc.first_line
<< ": Sorry, `timescale not supported." << endl;
yylloc.first_line += 1;
BEGIN(0); }
@@ -224,28 +290,28 @@ W [ \t\b\f\r]+
/* These are directives that I do not yet support. I think that IVL
should handle these, not an external preprocessor. */
^`celldefine{W}?.* { }
^`default_nettype{W}?.* { }
^`delay_mode_distributed{W}?.* { }
^`delay_mode_unit{W}?.* { }
^`delay_mode_path{W}?.* { }
^`disable_portfaults{W}?.* { }
^`enable_portfaults{W}?.* { }
^`endcelldefine{W}?.* { }
^`endprotect{W}?.* { }
^`nosuppress_faults{W}?.* { }
^`nounconnected_drive{W}?* { }
^`protect{W}?.* { }
^`resetall{W}?.* { }
^`suppress_faults{W}?.* { }
^`unconnected_drive{W}?* { }
^`uselib{W}?.* { }
^{W}?`celldefine{W}?.* { }
^{W}?`default_nettype{W}?.* { }
^{W}?`delay_mode_distributed{W}?.* { }
^{W}?`delay_mode_unit{W}?.* { }
^{W}?`delay_mode_path{W}?.* { }
^{W}?`disable_portfaults{W}?.* { }
^{W}?`enable_portfaults{W}?.* { }
^{W}?`endcelldefine{W}?.* { }
^{W}?`endprotect{W}?.* { }
^{W}?`nosuppress_faults{W}?.* { }
^{W}?`nounconnected_drive{W}?.* { }
^{W}?`protect{W}?.* { }
^{W}?`resetall{W}?.* { }
^{W}?`suppress_faults{W}?.* { }
^{W}?`unconnected_drive{W}?.* { }
^{W}?`uselib{W}?.* { }
/* These are directives that are not supported by me and should have
been handled by an external preprocessor such as ivlpp. */
^`define{W}?.* {
^{W}?`define{W}?.* {
cerr << yylloc.text << ":" << yylloc.first_line <<
": `define not supported. Use an external preprocessor."
<< endl;
@@ -312,22 +378,27 @@ void lex_end_table()
static verinum*make_binary_with_size(unsigned size, bool fixed, const char*ptr)
{
assert(tolower(*ptr) == 'b');
bool sign_flag = false;
verinum::V*bits = new verinum::V[size];
if (tolower(ptr[0]) == 's') {
ptr += 1;
sign_flag = true;
}
assert(tolower(*ptr) == 'b');
ptr += 1;
while (*ptr && ((*ptr == ' ') || (*ptr == '\t')))
ptr += 1;
unsigned idx = 0;
const char*eptr = ptr + strlen(ptr) - 1;
while ((eptr > ptr) && (idx < size)) {
if (*eptr == '_') {
eptr -= 1;
continue;
}
while ((eptr >= ptr) && (idx < size)) {
switch (*eptr) {
case '_':
break;
case '0':
bits[idx++] = verinum::V0;
break;
@@ -346,10 +417,22 @@ static verinum*make_binary_with_size(unsigned size, bool fixed, const char*ptr)
eptr -= 1;
}
/* If we filled up the expected number of bits, but there are
still characters of the number part left, then report a
warning that we are truncating. */
if ((idx >= size) && (eptr >= ptr))
cerr << yylloc.text << ":" << yylloc.first_line <<
": warning: Numeric binary constant ``" << ptr <<
"'' truncated to " << size << " bits." << endl;
// Zero-extend binary number, except that z or x is extended
// if it is the highest supplied digit.
while (idx < size) {
switch (ptr[1]) {
switch (ptr[0]) {
case '0':
case '1':
bits[idx++] = verinum::V0;
@@ -365,7 +448,10 @@ static verinum*make_binary_with_size(unsigned size, bool fixed, const char*ptr)
}
}
return new verinum(bits, size, fixed);
verinum*out = new verinum(bits, size, fixed);
delete[]bits;
out->has_sign(sign_flag);
return out;
}
static verinum*make_sized_binary(const char*txt)
@@ -376,16 +462,21 @@ static verinum*make_sized_binary(const char*txt)
ptr += 1;
assert(*ptr == '\'');
ptr += 1;
assert(tolower(*ptr) == 'b');
return make_binary_with_size(size, true, ptr);
}
static verinum*make_unsized_binary(const char*txt)
{
bool sign_flag = false;
const char*ptr = txt;
assert(*ptr == '\'');
ptr += 1;
if (tolower(*ptr) == 's') {
sign_flag = true;
ptr += 1;
}
assert(tolower(*ptr) == 'b');
while (*ptr && ((*ptr == 'b') || (*ptr == ' ') || (*ptr == '\t')))
ptr += 1;
@@ -420,100 +511,114 @@ static verinum*make_unsized_binary(const char*txt)
ptr += 1;
}
return new verinum(bits, size);
verinum*out = new verinum(bits, size);
out->has_sign(sign_flag);
delete[]bits;
return out;
}
static verinum*make_sized_octal(const char*txt)
{
bool sign_flag = false;
char*ptr;
unsigned size = strtoul(txt,&ptr,10);
while (*ptr && ((*ptr == ' ') || (*ptr == '\t')))
ptr += 1;
assert(*ptr == '\'');
ptr += 1;
assert(tolower(*ptr) == 'o');
/* We know from the size number how bit to make the verinom
if (tolower(*ptr) == 's') {
sign_flag = true;
ptr += 1;
}
assert(tolower(*ptr) == 'o');
ptr += 1;
/* We know from the size number how bit to make the verinum
array, so make it now. */
verinum::V*bits = new verinum::V[size];
verinum::V*bits = new verinum::V[(size+2)/3 * 3];
/* skip white space between size and the base token. */
while (*ptr && ((*ptr == ' ') || (*ptr == '\t')))
ptr += 1;
/* Find the end of the digits. ptr already points to the start. */
char*eptr = ptr + strlen(ptr);
/* From the last digit and forward, build up the number, least
significant bit first. This loop will not get the last few
bits if the size is not a multiple of 3. */
/* Get a pointer to the last character of the number string,
then work back from there (the least significant digit)
forward until I run out of digits or space to put them. */
char*eptr = ptr + strlen(ptr) - 1;
unsigned idx = 0;
while ((eptr > ptr) && ((idx/3) < (size/3))) switch (*--eptr) {
while ((eptr >= ptr) && (idx < size)) {
switch (*eptr) {
case 'x': case 'X':
bits[idx++] = verinum::Vx;
bits[idx++] = verinum::Vx;
bits[idx++] = verinum::Vx;
break;
case 'z': case 'Z': case '?':
bits[idx++] = verinum::Vz;
bits[idx++] = verinum::Vz;
bits[idx++] = verinum::Vz;
break;
default: {
unsigned val = *eptr - '0';
bits[idx++] = (val&1)? verinum::V1 : verinum::V0;
bits[idx++] = (val&2)? verinum::V1 : verinum::V0;
bits[idx++] = (val&4)? verinum::V1 : verinum::V0;
}
}
if ((eptr > ptr) && (idx < size)) switch (*--eptr) {
case 'x': case 'X':
for ( ; idx < size ; idx += 1)
bits[idx] = verinum::Vx;
break;
case 'z': case 'Z': case '?':
for ( ; idx < size ; idx += 1)
bits[idx] = verinum::Vz;
break;
default: {
unsigned val = *eptr - '0';
for ( ; idx < size ; idx += 1) {
bits[idx] = (val&1)? verinum::V1 : verinum::V0;
val >>= 1;
}
break;
}
} else {
// zero extend octal numbers
while (idx < size) switch (ptr[1]) {
case 'x': case 'X':
bits[idx++] = verinum::Vx;
break;
case 'z': case 'Z': case '?':
bits[idx++] = verinum::Vz;
case '0': case '1': case '2': case '3':
case '4': case '5': case '6': case '7':
{
unsigned val = *eptr - '0';
bits[idx++] = (val&1)? verinum::V1 : verinum::V0;
bits[idx++] = (val&2)? verinum::V1 : verinum::V0;
bits[idx++] = (val&4)? verinum::V1 : verinum::V0;
break;
}
case '_':
break;
default:
bits[idx++] = verinum::V0;
assert(0);
}
eptr -= 1;
}
return new verinum(bits, size, true);
/* If we filled up all the bits and there are still characters
in the number string, then we overflowed. Report a warning
that we are truncating. */
if ((idx >= size) && (eptr >= ptr))
cerr << yylloc.text << ":" << yylloc.first_line <<
": warning: Numeric octal constant ``" << ptr <<
"'' truncated to " << size << " bits." << endl;
/* If we did not fill up all the bits from the string, then
zero-extend the number. */
while (idx < size) switch (ptr[1]) {
case 'x': case 'X':
bits[idx++] = verinum::Vx;
break;
case 'z': case 'Z': case '?':
bits[idx++] = verinum::Vz;
break;
default:
bits[idx++] = verinum::V0;
}
verinum*out = new verinum(bits, size, true);
delete[]bits;
out->has_sign(sign_flag);
return out;
}
static verinum*make_unsized_octal(const char*txt)
{
bool sign_flag = false;
const char*ptr = txt;
assert(*ptr == '\'');
ptr += 1;
if (tolower(*ptr) == 's') {
sign_flag = true;
ptr += 1;
}
assert(tolower(*ptr) == 'o');
ptr += 1;
@@ -555,11 +660,15 @@ static verinum*make_unsized_octal(const char*txt)
ptr += 1;
}
return new verinum(bits, size);
verinum*out = new verinum(bits, size);
out->has_sign(sign_flag);
delete[]bits;
return out;
}
static verinum*make_sized_hex(const char*txt)
{
bool sign_flag = false;
char*ptr;
unsigned size = strtoul(txt,&ptr,10);
@@ -568,6 +677,12 @@ static verinum*make_sized_hex(const char*txt)
assert(*ptr == '\'');
ptr += 1;
if (tolower(*ptr) == 's') {
sign_flag = true;
ptr += 1;
}
assert(tolower(*ptr) == 'h');
ptr += 1;
@@ -622,7 +737,15 @@ static verinum*make_sized_hex(const char*txt)
eptr -= 1;
}
// zero extend octal numbers
/* If we filled up the expected number of bits, but there are
still characters of the number part left, then report a
warning that we are truncating. */
if ((idx >= size) && (eptr >= ptr))
cerr << yylloc.text << ":" << yylloc.first_line <<
": warning: Numeric hex constant ``" << ptr <<
"'' truncated to " << size << " bits." << endl;
// zero extend hex numbers
while (idx < size) switch (ptr[1]) {
case 'x': case 'X':
bits[idx++] = verinum::Vx;
@@ -634,14 +757,23 @@ static verinum*make_sized_hex(const char*txt)
bits[idx++] = verinum::V0;
}
return new verinum(bits, size, true);
verinum*out = new verinum(bits, size, true);
out->has_sign(sign_flag);
delete[]bits;
return out;
}
static verinum*make_unsized_hex(const char*txt)
{
bool sign_flag = false;
const char*ptr = txt;
assert(*ptr == '\'');
ptr += 1;
if (tolower(*ptr) == 's') {
sign_flag = true;
ptr += 1;
}
assert(tolower(*ptr) == 'h');
ptr += 1;
@@ -694,7 +826,10 @@ static verinum*make_unsized_hex(const char*txt)
ptr += 1;
}
return new verinum(bits, size);
verinum*out = new verinum(bits, size);
out->has_sign(sign_flag);
delete[]bits;
return out;
}
/*
@@ -703,15 +838,30 @@ static verinum*make_unsized_hex(const char*txt)
*/
static verinum*make_dec_with_size(unsigned size, bool fixed, const char*ptr)
{
bool signed_flag = false;
if (tolower(*ptr) == 's') {
signed_flag = true;
ptr += 1;
}
assert(tolower(*ptr) == 'd');
ptr += 1;
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 {
@@ -726,7 +876,18 @@ static verinum*make_dec_with_size(unsigned size, bool fixed, const char*ptr)
value /= 2;
}
return new verinum(bits, size, fixed);
/* If we run out of bits to hold the value, but there are
still valueable bits in the number, print a warning. */
if (value != 0)
cerr << yylloc.text << ":" << yylloc.first_line <<
": warning: Numeric decimal constant ``" << digits <<
"'' truncated to " << size << " bits." << endl;
verinum*out = new verinum(bits, size, fixed);
out->has_sign(signed_flag);
delete[]bits;
return out;
}
static verinum*make_sized_dec(const char*txt)
@@ -739,7 +900,6 @@ static verinum*make_sized_dec(const char*txt)
assert(*ptr == '\'');
ptr += 1;
assert(tolower(*ptr) == 'd');
return make_dec_with_size(size, true, ptr);
}
@@ -749,8 +909,111 @@ static verinum*make_unsized_dec(const char*txt)
return make_dec_with_size(INTEGER_WIDTH, false, txt+1);
}
/*
* The timescale parameter has the form:
* " <num> xs / <num> xs"
*/
static void process_timescale(const char*txt)
{
unsigned num;
const char*cp = txt + strspn(txt, " \t");
char*tmp;
const char*ctmp;
static int yywrap()
int unit = 0;
int prec = 0;
num = strtoul(cp, &tmp, 10);
if (num == 0) {
VLerror(yylloc, "Invalid timescale string.");
return;
}
while (num >= 10) {
unit += 1;
num /= 10;
}
if (num != 1) {
VLerror(yylloc, "Invalid timescale unit number.");
return;
}
cp = tmp;
cp += strspn(cp, " \t");
ctmp = cp + strcspn(cp, " \t/");
if (strncmp("s", cp, ctmp-cp) == 0) {
unit -= 0;
} else if (strncmp("ms", cp, ctmp-cp) == 0) {
unit -= 3;
} else if (strncmp("us", cp, ctmp-cp) == 0) {
unit -= 6;
} else if (strncmp("ns", cp, ctmp-cp) == 0) {
unit -= 9;
} else if (strncmp("ps", cp, ctmp-cp) == 0) {
unit -= 12;
} else if (strncmp("fs", cp, ctmp-cp) == 0) {
unit -= 15;
} else {
VLerror(yylloc, "Invalid timescale unit of measurement");
return;
}
cp = ctmp;
cp += strspn(cp, " \t/");
num = strtoul(cp, &tmp, 10);
if (num == 0) {
VLerror(yylloc, "Invalid timescale string.");
return;
}
assert(num);
while (num >= 10) {
prec += 1;
num /= 10;
}
if (num != 1) {
VLerror(yylloc, "Invalid timescale precision number.");
return;
}
cp = tmp;
cp += strspn(cp, " \t");
ctmp = cp + strcspn(cp, " \t\r");
if (strncmp("s", cp, ctmp-cp) == 0) {
prec -= 0;
} else if (strncmp("ms", cp, ctmp-cp) == 0) {
prec -= 3;
} else if (strncmp("us", cp, ctmp-cp) == 0) {
prec -= 6;
} else if (strncmp("ns", cp, ctmp-cp) == 0) {
prec -= 9;
} else if (strncmp("ps", cp, ctmp-cp) == 0) {
prec -= 12;
} else if (strncmp("fs", cp, ctmp-cp) == 0) {
prec -= 15;
} else {
VLerror(yylloc, "Invalid timescale precision units of measurement");
return;
}
pform_set_timescale(unit, prec);
}
int yywrap()
{
return 1;
}
@@ -773,8 +1036,7 @@ static void line_directive()
strncpy(buf, qt1, qt2-qt1);
buf[qt2-qt1] = 0;
delete[]yylloc.text;
yylloc.text = buf;
yylloc.text = set_file_name(buf);
qt2 += 1;
yylloc.first_line = strtoul(qt2,0,0);
@@ -801,13 +1063,19 @@ static void line_directive2()
strncpy(buf, qt1, qt2-qt1);
buf[qt2-qt1] = 0;
delete[]yylloc.text;
yylloc.text = buf;
yylloc.text = set_file_name(buf);
}
static void reset_lexor()
{
yyrestart(vl_input);
yylloc.first_line = 1;
yylloc.text = strdup(vl_file.c_str());
/* Start the file_names list. From here on, as I get a file
name, I will add it to this list. Only add the name if it
is not already in the list. */
file_names = new struct file_name_cell;
file_names->text = strdup(vl_file.c_str());
file_names->next = 0;
yylloc.text = file_names->text;
}
-230
View File
@@ -1,230 +0,0 @@
/* C code produced by gperf version 2.7 */
/* Command-line: gperf -o -i 1 -C -k 1-3,$ -L C -H keyword_hash -N check_identifier -tT lexor_keyword.gperf > lexor_keyword.cc */
#include "parse_misc.h"
#include "parse.h"
#include <string.h>
#define TOTAL_KEYWORDS 99
#define MIN_WORD_LENGTH 2
#define MAX_WORD_LENGTH 12
#define MIN_HASH_VALUE 7
#define MAX_HASH_VALUE 239
/* maximum key range = 233, duplicates = 0 */
#ifdef __GNUC__
__inline
#endif
static unsigned int
keyword_hash (const char *str, int len)
{
static const unsigned char asso_values[] =
{
240, 240, 240, 240, 240, 240, 240, 240, 240, 240,
240, 240, 240, 240, 240, 240, 240, 240, 240, 240,
240, 240, 240, 240, 240, 240, 240, 240, 240, 240,
240, 240, 240, 240, 240, 240, 240, 240, 240, 240,
240, 240, 240, 240, 240, 240, 240, 240, 126, 66,
240, 240, 240, 240, 240, 240, 240, 240, 240, 240,
240, 240, 240, 240, 240, 240, 240, 240, 240, 240,
240, 240, 240, 240, 240, 240, 240, 240, 240, 240,
240, 240, 240, 240, 240, 240, 240, 240, 240, 240,
240, 240, 240, 240, 240, 240, 240, 31, 11, 81,
1, 1, 81, 26, 11, 51, 11, 21, 81, 81,
1, 46, 16, 240, 1, 1, 6, 11, 36, 46,
21, 16, 6, 240, 240, 240, 240, 240, 240, 240,
240, 240, 240, 240, 240, 240, 240, 240, 240, 240,
240, 240, 240, 240, 240, 240, 240, 240, 240, 240,
240, 240, 240, 240, 240, 240, 240, 240, 240, 240,
240, 240, 240, 240, 240, 240, 240, 240, 240, 240,
240, 240, 240, 240, 240, 240, 240, 240, 240, 240,
240, 240, 240, 240, 240, 240, 240, 240, 240, 240,
240, 240, 240, 240, 240, 240, 240, 240, 240, 240,
240, 240, 240, 240, 240, 240, 240, 240, 240, 240,
240, 240, 240, 240, 240, 240, 240, 240, 240, 240,
240, 240, 240, 240, 240, 240, 240, 240, 240, 240,
240, 240, 240, 240, 240, 240, 240, 240, 240, 240,
240, 240, 240, 240, 240, 240, 240, 240, 240, 240,
240, 240, 240, 240, 240, 240
};
int hval = len;
hval += asso_values[(unsigned char)str[len - 1]];
hval += asso_values[(unsigned char)str[0]];
hval += asso_values[(unsigned char)str[1]];
if (len > 2)
hval += asso_values[(unsigned char)str[2]];
return hval ;
}
int
check_identifier (const char *str, int len)
{
static const struct { const char *name; int tokenType; } wordlist[] =
{
{""}, {""}, {""}, {""}, {""}, {""}, {""},
{"end", K_end},
{""}, {""}, {""},
{"endcase", K_endcase},
{"endtable", K_endtable},
{"endmodule", K_endmodule},
{"rtran", K_rtran},
{"endfunction", K_endfunction},
{"endprimitive", K_endprimitive},
{""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
{""}, {""}, {""},
{"endspecify", K_endspecify},
{"repeat", K_repeat},
{"endtask", K_endtask},
{""},
{"edge", K_edge},
{""}, {""},
{"negedge", K_negedge},
{"and", K_and},
{"nand", K_nand},
{""},
{"assign", K_assign},
{"specify", K_specify},
{"deassign", K_deassign},
{"tran", K_tran},
{"begin", K_begin},
{""}, {""}, {""}, {""},
{"event", K_event},
{"or", K_or},
{""},
{"nor", K_nor},
{""},
{"table", K_table},
{""}, {""},
{"reg", K_reg},
{"parameter", K_parameter},
{""}, {""},
{"disable", K_disable},
{"not", K_not},
{"task", K_task},
{"trior", K_trior},
{"triand", K_triand},
{"integer", K_integer},
{""}, {""}, {""}, {""},
{"posedge", K_posedge},
{"xor", K_xor},
{"xnor", K_xnor},
{""},
{"output", K_output},
{""}, {""},
{"primitive", K_primitive},
{"input", K_input},
{""},
{"strong1", K_strong1},
{"rtranif1", K_rtranif1},
{"wand", K_wand},
{""}, {""}, {""}, {""},
{"else", K_else},
{"rnmos", K_rnmos},
{"trireg", K_trireg},
{"release", K_release},
{""}, {""}, {""}, {""},
{"default", K_default},
{"wor", K_wor},
{""}, {""}, {""},
{"supply1", K_supply1},
{"function", K_function},
{"wire", K_wire},
{"rpmos", K_rpmos},
{""}, {""}, {""},
{"specparam", K_specparam},
{"inout", K_inout},
{""},
{"tranif1", K_tranif1},
{"tri", K_tri},
{"join", K_join},
{"while", K_while},
{""}, {""},
{"pulldown", K_pulldown},
{"case", K_case},
{"large", K_large},
{""}, {""},
{"scalered", K_scalered},
{""},
{"casez", K_casez},
{"notif1", K_notif1},
{""},
{"vectored", K_vectored},
{"tri1", K_tri1},
{""},
{"pullup", K_pullup},
{""},
{"for", K_for},
{"nmos", K_nmos},
{"force", K_force},
{"module", K_module},
{"forever", K_forever},
{""},
{"wait", K_wait},
{"casex", K_casex},
{""},
{"strong0", K_strong0},
{"rtranif0", K_rtranif0},
{"time", K_time},
{""}, {""}, {""}, {""},
{"pmos", K_pmos},
{"weak1", K_weak1},
{""}, {""}, {""},
{"fork", K_fork},
{""}, {""}, {""}, {""}, {""}, {""},
{"highz1", K_highz1},
{"supply0", K_supply0},
{""}, {""}, {""},
{"always", K_always},
{""}, {""}, {""},
{"rcmos", K_rcmos},
{"medium", K_medium},
{"tranif0", K_tranif0},
{"defparam", K_defparam},
{""}, {""},
{"bufif1", K_bufif1},
{""}, {""}, {""},
{"pull1", K_pull1},
{""}, {""}, {""}, {""}, {""},
{"notif0", K_notif0},
{""},
{"buf", K_buf},
{"tri0", K_tri0},
{""}, {""},
{"initial", K_initial},
{""}, {""}, {""}, {""}, {""}, {""}, {""},
{"small", K_small},
{""}, {""}, {""}, {""}, {""},
{"macromodule", K_macromodule},
{""}, {""}, {""},
{"weak0", K_weak0},
{""}, {""}, {""},
{"cmos", K_cmos},
{""},
{"if", K_if},
{""}, {""}, {""}, {""},
{"highz0", K_highz0},
{""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
{""}, {""}, {""}, {""}, {""},
{"bufif0", K_bufif0},
{""}, {""}, {""},
{"pull0", K_pull0}
};
if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
{
int key = keyword_hash (str, len);
if (key <= MAX_HASH_VALUE && key >= 0)
{
const char *s = wordlist[key].name;
if (*str == *s && !strcmp (str + 1, s + 1))
return wordlist[key].tokenType;
}
}
return IDENTIFIER;
}
+18 -5
View File
@@ -1,15 +1,14 @@
%{
/* Command-line: gperf -o -i 1 -C -k 1-3,$ -L C -H keyword_hash -N check_identifier -tT lexor_keyword.gperf */
#include "config.h"
#include "parse_misc.h"
#include "parse.h"
#include <string.h>
#include "lexor_keyword.h"
%}
struct Keywords {
char *name;
int tokenType;
} Keywords;
struct lexor_keyword { const char*name; int tokenType; };
%%
always, K_always
and, K_and
@@ -51,6 +50,7 @@ input, K_input
integer, K_integer
join, K_join
large, K_large
localparam, K_localparam
macromodule, K_macromodule
medium, K_medium
module, K_module
@@ -72,6 +72,8 @@ pull1, K_pull1
pulldown, K_pulldown
pullup, K_pullup
rcmos, K_rcmos
real, K_real
realtime, K_realtime
reg, K_reg
release, K_release
repeat, K_repeat
@@ -81,6 +83,7 @@ rtran, K_rtran
rtranif0, K_rtranif0
rtranif1, K_rtranif1
scalered, K_scalered
signed, K_signed
small, K_small
specify, K_specify
specparam, K_specparam
@@ -109,4 +112,14 @@ while, K_while
wire, K_wire
wor, K_wor
xnor, K_xnor
xor, K_xor
xor, K_xor
%%
int lexor_keyword_code(const char*str, unsigned nstr)
{
const struct lexor_keyword*rc = check_identifier(str, nstr);
if (rc == 0)
return IDENTIFIER;
else
return rc->tokenType;
}
+33
View File
@@ -0,0 +1,33 @@
#ifndef __lexor_keyword_H
#define __lexor_keyword_H
/*
* Copyright (c) 2000 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
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: lexor_keyword.h,v 1.1 2000/03/12 17:09:41 steve Exp $"
#endif
extern int lexor_keyword_code (const char*str, unsigned len);
/*
* $Log: lexor_keyword.h,v $
* Revision 1.1 2000/03/12 17:09:41 steve
* Support localparam.
*
*/
#endif
+178
View File
@@ -0,0 +1,178 @@
/*
* Copyright (c) 2000 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
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: link_const.cc,v 1.11 2001/08/25 23:50:03 steve Exp $"
#endif
# include "config.h"
# include "netlist.h"
# include "netmisc.h"
/*
* Scan the link for drivers. If there are only constant drivers, then
* the nexus has a known constant value. If there is a supply net,
* then the nexus again has a known constant value.
*/
bool link_drivers_constant(const Link&lnk)
{
const Nexus*nex = lnk.nexus();
bool flag = true;
for (const Link*cur = nex->first_nlink()
; cur ; cur = cur->next_nlink()) {
const NetNet*sig;
if (cur == &lnk)
continue;
if (cur->get_dir() == Link::INPUT)
continue;
/* If this is an input or inout port of a root module,
then the is probably not a constant value. I
certainly don't know what the value is, anyhow. This
can happen in cases like this:
module main(sig);
input sig;
endmodule
If main is a root module (it has no parent) then sig
is not constant because it connects to an unspecified
outside world. */
if (sig = dynamic_cast<const NetNet*>(cur->get_obj())) do {
if (sig->port_type() == NetNet::NOT_A_PORT)
break;
if (sig->port_type() == NetNet::POUTPUT)
break;
if (sig->scope()->parent())
break;
flag = false;
} while(0);
/* If the link is PASSIVE then it doesn't count as a
driver if its initial value is Vz. PASSIVE nodes
include wires and tri nets. */
if (cur->get_dir() == Link::PASSIVE)
continue;
if (! dynamic_cast<const NetConst*>(cur->get_obj()))
flag = false;
/* If there is a supply net, then this nexus will have a
constant value independent of any drivers. */
if (const NetNet*sig = dynamic_cast<const NetNet*>(cur->get_obj()))
switch (sig->type()) {
case NetNet::SUPPLY0:
case NetNet::SUPPLY1:
return true;
default:
break;
}
}
return flag;
}
verinum::V driven_value(const Link&lnk)
{
verinum::V val = lnk.get_init();
const Nexus*nex = lnk.nexus();
for (const Link*cur = nex->first_nlink()
; cur ; cur = cur->next_nlink()) {
const NetConst*obj;
const NetNet*sig;
if (obj = dynamic_cast<const NetConst*>(cur->get_obj())) {
val = obj->value(cur->get_pin());
} else if (sig = dynamic_cast<const NetNet*>(cur->get_obj())) {
if (sig->type() == NetNet::SUPPLY0)
return verinum::V0;
if (sig->type() == NetNet::SUPPLY1)
return verinum::V1;
}
}
return val;
}
/*
* $Log: link_const.cc,v $
* Revision 1.11 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.
*
* Change the vvp code generator to support multiple
* l-values, i.e. concatenations of part selects.
*
* Revision 1.10 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)
*
* Revision 1.9 2001/07/07 03:01:37 steve
* Detect and make available to t-dll the right shift.
*
* Revision 1.8 2001/02/16 03:27:07 steve
* links to root inputs are not constant.
*
* Revision 1.7 2000/11/20 01:41:12 steve
* Whoops, return the calculated constant value rom driven_value.
*
* Revision 1.6 2000/11/20 00:58:40 steve
* Add support for supply nets (PR#17)
*
* Revision 1.5 2000/07/14 06:12:57 steve
* Move inital value handling from NetNet to Nexus
* objects. This allows better propogation of inital
* values.
*
* Clean up constant propagation a bit to account
* for regs that are not really values.
*
* Revision 1.4 2000/06/25 19:59:42 steve
* Redesign Links to include the Nexus class that
* carries properties of the connected set of links.
*
* Revision 1.3 2000/05/14 17:55:04 steve
* Support initialization of FF Q value.
*
* Revision 1.2 2000/05/07 04:37:56 steve
* Carry strength values from Verilog source to the
* pform and netlist for gates.
*
* 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.1 2000/04/20 00:28:03 steve
* Catch some simple identity compareoptimizations.
*
*/
+246 -92
View File
@@ -1,6 +1,6 @@
const char COPYRIGHT[] =
"Copyright (c) 1998-1999 Stephen Williams ([email protected])";
"Copyright (c) 1998-2000 Stephen Williams ([email protected])";
/*
* This source code is free software; you can redistribute it
@@ -18,10 +18,12 @@ 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)
#ident "$Id: main.cc,v 1.26 1999/11/29 17:02:21 steve Exp $"
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: main.cc,v 1.47 2001/07/30 02:44:05 steve Exp $"
#endif
# include "config.h"
const char NOTICE[] =
" This program is free software; you can redistribute it and/or modify\n"
" it under the terms of the GNU General Public License as published by\n"
@@ -44,12 +46,29 @@ const char NOTICE[] =
# include <queue>
# include <map>
# include <unistd.h>
# include <stdlib.h>
#if defined(HAVE_TIMES)
# include <sys/times.h>
#endif
#if defined(HAVE_GETOPT_H)
# include <getopt.h>
#endif
# include "pform.h"
# include "netlist.h"
# include "target.h"
# include "compiler.h"
#if defined(__MINGW32__) && !defined(HAVE_GETOPT_H)
extern "C" int getopt(int argc, char*argv[], const char*fmt);
extern "C" int optind;
extern "C" const char*optarg;
#endif
#if defined(__CYGWIN32__) && !defined(HAVE_GETOPT_H)
extern "C" int getopt(int argc, char*argv[], const char*fmt);
extern "C" int optind;
extern "C" const char*optarg;
#endif
const char VERSION[] = "$Name: $ $State: Exp $";
@@ -58,6 +77,12 @@ string start_module = "";
map<string,string> flags;
/*
* These are the warning enable flags.
*/
bool warn_implicit = false;
static void parm_to_flagmap(const string&flag)
{
string key, value;
@@ -80,13 +105,10 @@ extern Design* elaborate(const map<string,Module*>&modules,
const string&root);
extern void cprop(Design*des);
extern void propinit(Design*des);
extern void sigfold(Design*des);
extern void synth(Design*des);
extern void nobufz(Design*des);
extern void syn_rules(Design*des);
extern void nodangle(Design*des);
extern void xnfio(Design*des);
extern void xnfsyn(Design*des);
typedef void (*net_func)(Design*);
static struct net_func_map {
@@ -94,13 +116,10 @@ static struct net_func_map {
void (*func)(Design*);
} func_table[] = {
{ "cprop", &cprop },
{ "nobufz", &nobufz },
{ "nodangle",&nodangle },
{ "propinit",&propinit },
{ "sigfold", &sigfold },
{ "synth", &synth },
{ "syn-rules", &syn_rules },
{ "xnfio", &xnfio },
{ "xnfsyn", &xnfsyn },
{ 0, 0 }
};
@@ -113,18 +132,58 @@ net_func name_to_net_func(const string&name)
return 0;
}
const char *net_func_to_name(const net_func func)
{
for (unsigned idx = 0 ; func_table[idx].name ; idx += 1)
if (func == func_table[idx].func)
return func_table[idx].name;
return "This cannot happen";
}
#if defined(HAVE_TIMES)
static double cycles_diff(struct tms *a, struct tms *b)
{
clock_t aa = a->tms_utime
+ a->tms_stime
+ a->tms_cutime
+ a->tms_cstime;
clock_t bb = b->tms_utime
+ b->tms_stime
+ b->tms_cutime
+ b->tms_cstime;
return (aa-bb)/(double)sysconf(_SC_CLK_TCK);
}
#else // ! defined(HAVE_TIMES)
// Provide dummies
struct tms { int x; };
inline static void times(struct tms *) { }
inline static double cycles_diff(struct tms *a, struct tms *b) { return 0; }
#endif // ! defined(HAVE_TIMES)
int main(int argc, char*argv[])
{
bool help_flag = false;
bool verbose_flag = false;
bool times_flag = false;
const char* net_path = 0;
const char* out_path = 0;
const char* pf_path = 0;
const char* warn_en = "";
int opt;
unsigned flag_errors = 0;
queue<net_func> net_func_queue;
while ((opt = getopt(argc, argv, "F:f:hN:o:P:s:t:v")) != EOF) switch (opt) {
struct tms cycles[5];
flags["VPI_MODULE_LIST"] = "system";
flags["-o"] = "a.out";
min_typ_max_flag = TYP;
min_typ_max_warn = 10;
while ((opt = getopt(argc, argv, "F:f:hm:N:o:P:p:s:T:t:VvW:")) != EOF) switch (opt) {
case 'F': {
net_func tmp = name_to_net_func(optarg);
if (tmp == 0) {
@@ -142,26 +201,57 @@ int main(int argc, char*argv[])
case 'h':
help_flag = true;
break;
case 'm':
flags["VPI_MODULE_LIST"] = flags["VPI_MODULE_LIST"]+","+optarg;
break;
case 'N':
net_path = optarg;
break;
case 'o':
out_path = optarg;
flags["-o"] = optarg;
break;
case 'P':
pf_path = optarg;
break;
case 'p':
parm_to_flagmap(optarg);
break;
case 's':
start_module = optarg;
break;
case 'T':
if (strcmp(optarg,"min") == 0) {
min_typ_max_flag = MIN;
min_typ_max_warn = 0;
} else if (strcmp(optarg,"typ") == 0) {
min_typ_max_flag = TYP;
min_typ_max_warn = 0;
} else if (strcmp(optarg,"max") == 0) {
min_typ_max_flag = MAX;
min_typ_max_warn = 0;
} else {
cerr << "Invalid argument (" << optarg << ") to -T flag."
<< endl;
flag_errors += 1;
}
break;
case 't':
target = optarg;
break;
case 'v':
verbose_flag = true;
# if defined(HAVE_TIMES)
times_flag = true;
# endif
break;
case 'V':
cout << "Icarus Verilog version " << VERSION << endl;
cout << COPYRIGHT << endl;
cout << endl << NOTICE << endl;
return 0;
case 'W':
warn_en = optarg;
break;
default:
flag_errors += 1;
break;
@@ -171,12 +261,33 @@ int main(int argc, char*argv[])
return flag_errors;
if (help_flag) {
cout << "Icarus Verilog version " << VERSION << endl <<
"usage: ivl <options> <file>\n"
"options:\n"
"\t-F <name> Apply netlist function <name>.\n"
"\t-h Print usage information, and exit.\n"
"\t-m <module> Load vpi module <module>.\n"
"\t-N <file> Dump the elaborated netlist to <file>.\n"
"\t-o <file> Write output to <file>.\n"
"\t-P <file> Write the parsed input to <file>.\n"
"\t-p <assign> Set a parameter value.\n"
"\t-s <module> Select the top-level module.\n"
"\t-T [min|typ|max] Select timing corner.\n"
"\t-t <name> Select target <name>.\n"
"\t-v Print progress indications"
#if defined(HAVE_TIMES)
" and execution times"
#endif
".\n"
"\t-V Print version and copyright information, and exit.\n"
;
cout << "Netlist functions:" << endl;
for (unsigned idx = 0 ; func_table[idx].name ; idx += 1)
cout << " " << func_table[idx].name << endl;
cout << "\t-F " << func_table[idx].name << endl;
cout << "Target types:" << endl;
for (unsigned idx = 0 ; target_table[idx] ; idx += 1)
cout << " " << target_table[idx]->name << endl;
cout << "\t-t " << target_table[idx]->name << endl;
return 0;
}
@@ -185,6 +296,21 @@ int main(int argc, char*argv[])
return 1;
}
/* Scan the warnings enable string for warning flags. */
for (const char*cp = warn_en ; *cp ; cp += 1) switch (*cp) {
case 'i':
warn_implicit = true;
break;
default:
break;
}
if (verbose_flag) {
if (times_flag)
times(cycles+0);
cout << "PARSING INPUT ..." << endl;
}
/* Parse the input. Make the pform. */
map<string,Module*> modules;
map<string,PUdp*> primitives;
@@ -210,6 +336,11 @@ int main(int argc, char*argv[])
return rc;
}
/* If the user did not give a specific module to start with,
then look for the single module that has no ports. If there
are multiple modules with no ports, then give up. */
if (start_module == "") {
for (map<string,Module*>::iterator mod = modules.begin()
; mod != modules.end()
@@ -226,29 +357,65 @@ int main(int argc, char*argv[])
}
}
/* Select a root module, and elaborate the design. */
/* If the previous attempt to find a start module failed, but
there is only one module, then just let the user get away
with it. */
if ((start_module == "") && (modules.size() == 1)) {
map<string,Module*>::iterator mod = modules.begin();
Module*cur = (*mod).second;
start_module = cur->get_name();
}
/* If there is *still* no guess for the root module, then give
up completely, and complain. */
if (start_module == "") {
cerr << "No top level modules, and no -s option." << endl;
return 1;
}
if (verbose_flag) {
if (times_flag) {
times(cycles+1);
cerr<<" ... done, "
<<cycles_diff(cycles+1, cycles+0)<<" seconds."<<endl;
}
cout << "ELABORATING DESIGN -s "<<start_module<<" ..." << endl;
}
/* On with the process of elaborating the module. */
Design*des = elaborate(modules, primitives, start_module);
if (des == 0) {
cerr << "Unable to elaborate module " << start_module <<
"." << endl;
cerr << start_module << ": error: "
<< "Unable to elaborate module." << endl;
return 1;
}
if (des->errors) {
cerr << des->errors << " error(s) elaborating design." << endl;
cerr << start_module << ": error: " << des->errors
<< " elaborating module." << endl;
return des->errors;
}
des->set_flags(flags);
if (verbose_flag) {
if (times_flag) {
times(cycles+2);
cerr<<" ... done, "
<<cycles_diff(cycles+2, cycles+1)<<" seconds."<<endl;
}
cout << "RUNNING FUNCTORS ..." << endl;
}
while (!net_func_queue.empty()) {
net_func func = net_func_queue.front();
net_func_queue.pop();
if (verbose_flag)
cerr<<" -F "<<net_func_to_name(func)<<endl;
func(des);
}
@@ -258,106 +425,93 @@ int main(int argc, char*argv[])
}
bool emit_rc;
if (out_path) {
ofstream out;
out.open(out_path);
if (! out.is_open()) {
cerr << "Unable to open " << out_path << " for writing."
<< endl;
return 1;
if (verbose_flag) {
if (times_flag) {
times(cycles+3);
cerr<<" ... done, "
<<cycles_diff(cycles+3, cycles+2)<<" seconds."<<endl;
}
emit_rc = emit(out, des, target);
} else {
emit_rc = emit(cout, des, target);
cout << "CODE GENERATION -t "<<target<<" ..." << endl;
}
bool emit_rc = emit(des, target);
if (!emit_rc) {
cerr << "internal error: Code generation had errors." << endl;
cerr << "error: Code generation had errors." << endl;
return 1;
}
if (verbose_flag) {
if (times_flag) {
times(cycles+4);
cerr<<" ... done, "
<<cycles_diff(cycles+4, cycles+3)<<" seconds."<<endl;
} else
cout << "DONE." << endl;
}
return 0;
}
/*
* $Log: main.cc,v $
* Revision 1.26 1999/11/29 17:02:21 steve
* include getopt if present.
* Revision 1.47 2001/07/30 02:44:05 steve
* Cleanup defines and types for mingw compile.
*
* Revision 1.25 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.46 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)
*
* Revision 1.24 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.45 2001/07/16 18:14:56 steve
* Reshuffle -v and -V flags of ivl. (Stephan Boettcher)
*
* Revision 1.23 1999/09/22 16:57:23 steve
* Catch parallel blocks in vvm emit.
* Revision 1.44 2001/07/03 04:09:24 steve
* Generate verbuse status messages (Stephan Boettcher)
*
* Revision 1.22 1999/08/03 04:14:49 steve
* Parse into pform arbitrarily complex module
* port declarations.
* Revision 1.43 2001/07/02 01:57:27 steve
* Add the -V flag, and some verbose messages.
*
* Revision 1.21 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.42 2001/06/23 18:41:02 steve
* Include stdlib.h
*
* Revision 1.20 1999/07/17 22:01:13 steve
* Add the functor interface for functor transforms.
* Revision 1.41 2001/05/20 17:35:05 steve
* declare getopt by hand in mingw32 compile.
*
* Revision 1.19 1999/07/10 23:29:21 steve
* pform even on parse errors.
* Revision 1.40 2001/01/20 19:02:05 steve
* Switch hte -f flag to the -p flag.
*
* Revision 1.18 1999/06/19 03:46:42 steve
* Add the -v switch.
* Revision 1.39 2000/11/22 20:48:32 steve
* Allow sole module to be a root.
*
* Revision 1.17 1999/06/17 05:33:12 steve
* Redundant declaration of pform_parse.
* Revision 1.38 2000/09/12 01:17:40 steve
* Version information for vlog_vpi_info.
*
* Revision 1.16 1999/06/15 03:44:53 steve
* Get rid of the STL vector template.
* Revision 1.37 2000/08/09 03:43:45 steve
* Move all file manipulation out of target class.
*
* Revision 1.15 1999/05/05 03:27:15 steve
* More intelligent selection of module to elaborate.
* Revision 1.36 2000/07/29 17:58:21 steve
* Introduce min:typ:max support.
*
* Revision 1.14 1999/04/23 04:34:32 steve
* Make debug output file parameters.
* Revision 1.35 2000/07/14 06:12:57 steve
* Move inital value handling from NetNet to Nexus
* objects. This allows better propogation of inital
* values.
*
* Revision 1.13 1999/02/01 00:26:49 steve
* Carry some line info to the netlist,
* Dump line numbers for processes.
* Elaborate prints errors about port vector
* width mismatch
* Emit better handles null statements.
* Clean up constant propagation a bit to account
* for regs that are not really values.
*
* Revision 1.12 1999/01/24 01:35:36 steve
* Support null target for generating no output.
* Revision 1.34 2000/05/13 20:55:47 steve
* Use yacc based synthesizer.
*
* Revision 1.11 1998/12/20 02:05:41 steve
* Function to calculate wire initial value.
* Revision 1.33 2000/05/08 05:29:43 steve
* no need for nobufz functor.
*
* Revision 1.10 1998/12/09 04:02:47 steve
* Support the include directive.
* Revision 1.32 2000/05/03 22:14:31 steve
* More features of ivl available through iverilog.
*
* Revision 1.9 1998/12/07 04:53:17 steve
* Generate OBUF or IBUF attributes (and the gates
* to garry them) where a wire is a pad. This involved
* figuring out enough of the netlist to know when such
* was needed, and to generate new gates and signales
* to handle what's missing.
*
* Revision 1.8 1998/12/02 04:37:13 steve
* Add the nobufz function to eliminate bufz objects,
* Object links are marked with direction,
* constant propagation is more careful will wide links,
* Signal folding is aware of attributes, and
* the XNF target can dump UDP objects based on LCA
* attributes.
* Revision 1.31 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.
*/
+63 -3
View File
@@ -16,10 +16,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: mangle.cc,v 1.2 1999/02/15 05:52:50 steve Exp $"
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: mangle.cc,v 1.7 2001/07/25 03:10:49 steve Exp $"
#endif
# include "config.h"
# include "target.h"
# include <strstream>
@@ -32,7 +34,7 @@ string mangle(const string&str)
string tmp = str;
while (tmp.length() > 0) {
size_t pos = tmp.find_first_of(".<");
size_t pos = tmp.find_first_of(".<\\[]/");
if (pos > tmp.length())
pos = tmp.length();
@@ -55,6 +57,48 @@ string mangle(const string&str)
tmp = tmp.substr(1);
res << "_";
break;
case '\\':
res << "$$";
tmp = tmp.substr(1);
break;
case '/':
res << "$sl$";
tmp = tmp.substr(1);
break;
case '[':
res << "$lb$";
tmp = tmp.substr(1);
break;
case ']':
res << "$rb$";
tmp = tmp.substr(1);
break;
}
}
res << ends;
return res.str();
}
string stresc(const string&str)
{
ostrstream res;
string tmp = str;
while (tmp.length() > 0) {
size_t pos = tmp.find_first_of("\\");
if (pos > tmp.length())
pos = tmp.length();
res << tmp.substr(0, pos);
if (pos >= tmp.length())
break;
tmp = tmp.substr(pos);
switch (tmp[0]) {
case '\\':
res << "\\\\";
tmp = tmp.substr(1);
break;
}
}
res << ends;
@@ -63,6 +107,22 @@ string mangle(const string&str)
/*
* $Log: mangle.cc,v $
* Revision 1.7 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)
*
* Revision 1.6 2001/04/22 23:09:46 steve
* More UDP consolidation from Stephan Boettcher.
*
* Revision 1.5 2000/12/11 01:06:24 steve
* Mangle [] characters. (PR#67)
*
* Revision 1.4 2000/10/25 23:21:37 steve
* mangle the backslash to a dollar.
*
* Revision 1.3 2000/02/23 02:56:54 steve
* Macintosh compilers do not support ident.
*
* Revision 1.2 1999/02/15 05:52:50 steve
* Mangle that handles device instance numbers.
*
+120
View File
@@ -0,0 +1,120 @@
MINGW PORT OF ICARUS VERILOG
Copyright 2001 Stephen Williams <[email protected]>
Icarus Verilog source can be compiled with the mingw C/C++ compilers
to get a Windows binary that does not require the posix compatibility
cruft of the Cygwin.dll library. The configure scripts automatically
detect that the compilers in use are the mingw compilers and will
configure the Makefiles appropriately.
However, the mingw tools do not include all the other tools around the
compiler, including the shell interpreter for the configure script,
bison, flex, gperf, etc. Therefore, you still need Cygwin to compile
Icarus Verilog, even if you don't need the Cygwin compilers.
* Install Cygwin
So, step 1 is "Download and Install Cygwin." See the web page
http://www.cygwin.com for instructions and the files to do
this. Cygwin *is* a kool package, and is worth having anyhow.
* Install mingw
The obvious step 2, then, is install the mingw compilers. These can be
found as the web page <http://www.mingw.org>.
* Unpack Icarus Verilog source
Most of the remaining steps are best done in a Cygwin window. When you
installed Cygwin, a start menu entry was created to allow you to start
up the Cygwin window. I'll use the string "$ " to represent a command
prompt in this window, because that is the usual bash prompt.
Anyhow, unpack the compressed tar file (.tar.gz) of the source with a
command like this:
$ gunzip -d verilog-20010630.tar.gz | tar xvf -
This will create a directory "verilog-20010630" that contains all the
source. Descend into that directory, as that is where we will work
from now on.
$ cd verilog-20010630
* Select the mingw compilers
In your cygwin window, if you type "which c++" you will get the
response path "/usr/bin/c++" which is the cygwin compiler. This is not
the one we want to use, however. Tell the shell where the mingw
compilers are by setting the search path like so:
$ PATH=/cygdrive/d/mingw/bin:$PATH
This assumes that you installed mingw in D:\mingw. The actual programs
are in the bin directory under the root. After this command, check
that you are now getting the right compilers with this "which"
command:
$ which c++
/cygdrive/d/mingw/bin/c++
Good!
* Configure Icarus Verilog
Now we are all set to configure and compile Icarus Verilog. Choose a
destination path where you will want to install the binaries. I chose
on my system the directory "D:\iverilog". This choice is not
permanent, so don't get too much angst over it. Just choose a name
without white space.
Now, configure the source to make the makefiles and configuration
details. Run this command:
$ ./configure --prefix=/cygdrive/d/iverilog
Substitute your chosen directory for the prefix. This will cause the
makefiles to build and the source code to configure. The configure
program will detect that this is a mingw environment and set things up
to build properly.
* Compile Icarus Verilog
This, believe it or not, should be the easy part:
$ make
It could take a while. Now is a good time to go get some coffee or
take a tea break.
* Install Icarus Verilog
If the compile ran OK, then next you install Icarus Verilog in the
directory you have chosen. This is how:
$ make install
This is part of what the configure program did for you. The Makefiles
now know to put the files under the D:\iverilog (or whatever directory
you chose) directory, and away you go.
* Running Icarus Verilog
Finally, put the D:\iverilog\bin directory in your Windows path, and
you should be able to run the iverilog and vvp commands to your
heart's content.
Currently, the iverilog.exe uses the path to itself to locate the
libraries and modules associated with itself. In other words, if you
execute the D:\iverilog\bin\iverilog.exe program, it will locate its
subparts in the D:\iverilog directory and subdirectories below
that. This means you can move the Icarus Verilog installation by
simply moving the root directory and all its contents.
+46
View File
@@ -0,0 +1,46 @@
#ifndef __named_H
#define __named_H
/*
* Copyright (c) 2000 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
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: named.h,v 1.2 2000/02/23 02:56:54 steve Exp $"
#endif
# include <string>
/*
* There are lots of places where names are attached to objects. This
* simple template expresses the lot.
*/
template <class T> struct named {
string name;
T parm;
};
/*
* $Log: named.h,v $
* Revision 1.2 2000/02/23 02:56:54 steve
* Macintosh compilers do not support ident.
*
* Revision 1.1 2000/01/09 05:50:49 steve
* Support named parameter override lists.
*
*/
#endif
+269
View File
@@ -0,0 +1,269 @@
/*
* Copyright (c) 2000 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
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: net_assign.cc,v 1.8 2001/08/25 23:50:03 steve Exp $"
#endif
# include "config.h"
# include "netlist.h"
/*
* NetAssign
*/
unsigned count_lval_width(const NetAssign_*idx)
{
unsigned wid = 0;
while (idx) {
wid += idx->lwidth();
idx = idx->more;
}
return wid;
}
NetAssign_::NetAssign_(NetNet*s)
: sig_(s), bmux_(0)
{
loff_ = 0;
lwid_ = sig_->pin_count();
sig_->incr_eref();
more = 0;
}
NetAssign_::~NetAssign_()
{
if (sig_) sig_->decr_eref();
assert( more == 0 );
if (bmux_) delete bmux_;
}
void NetAssign_::set_bmux(NetExpr*r)
{
assert(bmux_ == 0);
bmux_ = r;
}
const NetExpr* NetAssign_::bmux() const
{
return bmux_;
}
unsigned NetAssign_::lwidth() const
{
if (bmux_) return 1;
else return lwid_;
}
const char*NetAssign_::name() const
{
if (sig_) {
return sig_->name();
} else {
return "";
}
}
NetNet* NetAssign_::sig() const
{
assert(sig_);
return sig_;
}
void NetAssign_::set_part(unsigned lo, unsigned lw)
{
loff_ = lo;
lwid_ = lw;
assert(sig_->pin_count() >= (lo + lw));
}
unsigned NetAssign_::get_loff() const
{
return loff_;
}
NetAssignBase::NetAssignBase(NetAssign_*lv, NetExpr*rv)
: lval_(lv), rval_(rv)
{
}
NetAssignBase::~NetAssignBase()
{
if (rval_) delete rval_;
while (lval_) {
NetAssign_*tmp = lval_;
lval_ = tmp->more;
tmp->more = 0;
delete tmp;
}
}
NetExpr* NetAssignBase::rval()
{
return rval_;
}
const NetExpr* NetAssignBase::rval() const
{
return rval_;
}
void NetAssignBase::set_rval(NetExpr*r)
{
if (rval_) delete rval_;
rval_ = r;
}
NetAssign_* NetAssignBase::l_val(unsigned idx)
{
NetAssign_*cur = lval_;
while (idx > 0) {
if (cur == 0)
return cur;
cur = cur->more;
idx -= 1;
}
assert(idx == 0);
return cur;
}
const NetAssign_* NetAssignBase::l_val(unsigned idx) const
{
const NetAssign_*cur = lval_;
while (idx > 0) {
if (cur == 0)
return cur;
cur = cur->more;
idx -= 1;
}
assert(idx == 0);
return cur;
}
unsigned NetAssignBase::l_val_count() const
{
const NetAssign_*cur = lval_;
unsigned cnt = 0;
while (cur) {
cnt += 1;
cur = cur->more;
}
return cnt;
}
unsigned NetAssignBase::lwidth() const
{
unsigned sum = 0;
for (NetAssign_*cur = lval_ ; cur ; cur = cur->more)
sum += cur->lwidth();
return sum;
}
NetAssign::NetAssign(NetAssign_*lv, NetExpr*rv)
: NetAssignBase(lv, rv)
{
}
NetAssign::~NetAssign()
{
}
NetAssignNB::NetAssignNB(NetAssign_*lv, NetExpr*rv)
: NetAssignBase(lv, rv)
{
rise_time_ = 0;
fall_time_ = 0;
decay_time_ = 0;
}
NetAssignNB::~NetAssignNB()
{
}
void NetAssignNB::rise_time(unsigned t)
{
rise_time_ = t;
}
void NetAssignNB::fall_time(unsigned t)
{
fall_time_ = t;
}
void NetAssignNB::decay_time(unsigned t)
{
decay_time_ = t;
}
unsigned NetAssignNB::rise_time() const
{
return rise_time_;
}
unsigned NetAssignNB::fall_time() const
{
return fall_time_;
}
unsigned NetAssignNB::decay_time() const
{
return decay_time_;
}
/*
* $Log: net_assign.cc,v $
* Revision 1.8 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.
*
* Change the vvp code generator to support multiple
* l-values, i.e. concatenations of part selects.
*
* Revision 1.7 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)
*
* Revision 1.6 2000/10/18 20:04:39 steve
* Add ivl_lval_t and support for assignment l-values.
*
* Revision 1.5 2000/09/20 02:53:15 steve
* Correctly measure comples l-values of assignments.
*
* Revision 1.4 2000/09/10 02:18:16 steve
* elaborate complex l-values
*
* Revision 1.3 2000/09/07 00:06:53 steve
* encapsulate access to the l-value expected width.
*
* Revision 1.2 2000/09/02 23:40:13 steve
* Pull NetAssign_ creation out of constructors.
*
* Revision 1.1 2000/09/02 20:54:20 steve
* Rearrange NetAssign to make NetAssign_ separate.
*
*/
+558
View File
@@ -0,0 +1,558 @@
/*
* Copyright (c) 2000Stephen 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
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: net_design.cc,v 1.20 2001/07/25 03:10:49 steve Exp $"
#endif
# include "config.h"
# include <iostream>
/*
* This source file contains all the implementations of the Design
* class declared in netlist.h.
*/
# include "netlist.h"
# include "util.h"
# include <strstream>
Design:: Design()
: errors(0), root_scope_(0), nodes_(0), procs_(0), lcounter_(0)
{
procs_idx_ = 0;
des_precision_ = 0;
}
Design::~Design()
{
}
string Design::local_symbol(const string&path)
{
strstream res;
res << "_L" << (lcounter_++) << ends;
return path + "." + res.str();
}
void Design::set_precision(int val)
{
if (val < des_precision_)
des_precision_ = val;
}
int Design::get_precision() const
{
return des_precision_;
}
unsigned long Design::scale_to_precision(unsigned long val,
const NetScope*scope) const
{
int units = scope->time_unit();
assert( units >= des_precision_ );
while (units > des_precision_) {
units -= 1;
val *= 10;
}
return val;
}
NetScope* Design::make_root_scope(const string&root)
{
assert(root_scope_ == 0);
root_scope_ = new NetScope(0, root, NetScope::MODULE);
root_scope_->set_module_name(root.c_str());
return root_scope_;
}
NetScope* Design::find_root_scope()
{
assert(root_scope_);
return root_scope_;
}
const NetScope* Design::find_root_scope() const
{
assert(root_scope_);
return root_scope_;
}
/*
* This method locates a scope in the design, given its rooted
* heirarchical name. Each component of the key is used to scan one
* more step down the tree until the name runs out or the search
* fails.
*/
NetScope* Design::find_scope(const string&key) const
{
if (key == root_scope_->name())
return root_scope_;
string path = key;
string root = parse_first_name(path);
NetScope*cur = root_scope_;
if (root != cur->name())
return 0;
while (cur) {
string next = parse_first_name(path);
cur = cur->child(next);
if (path == "") return cur;
}
return cur;
}
/*
* This is a relative lookup of a scope by name. The starting point is
* the scope parameter is the place within which I start looking for
* the scope. If I do not find the scope within the passed scope,
* start looking in parent scopes until I find it, or I run out of
* parent scopes.
*/
NetScope* Design::find_scope(NetScope*scope, const string&name) const
{
assert(scope);
for ( ; scope ; scope = scope->parent()) {
string path = name;
string key = parse_first_name(path);
NetScope*cur = scope;
do {
cur = cur->child(key);
if (cur == 0) break;
key = parse_first_name(path);
} while (key != "");
if (cur) return cur;
}
// Last chance. Look for the name starting at the root.
return find_scope(name);
}
/*
* Find a parameter from within a specified context. If the name is
* not here, keep looking up until I run out of up to look at. The
* method works by scanning scopes, starting with the passed scope and
* working up towards the root, looking for the named parameter. The
* name in this case can be hierarchical, so there is an inner loop to
* follow the scopes of the name down to to key.
*/
const NetExpr* Design::find_parameter(const NetScope*scope,
const string&name) const
{
for ( ; scope ; scope = scope->parent()) {
string path = name;
string key = parse_first_name(path);
const NetScope*cur = scope;
while (path != "") {
cur = cur->child(key);
if (cur == 0) break;
key = parse_first_name(path);
}
if (cur == 0) continue;
if (const NetExpr*res = cur->get_parameter(key))
return res;
}
return 0;
}
/*
* This method runs through the scope, noticing the defparam
* statements that were collected during the elaborate_scope pass and
* applying them to the target parameters. The implementation actually
* works by using a specialized method from the NetScope class that
* does all the work for me.
*/
void Design::run_defparams()
{
root_scope_->run_defparams(this);
}
void NetScope::run_defparams(Design*des)
{
NetScope*cur = sub_;
while (cur) {
cur->run_defparams(des);
cur = cur->sib_;
}
map<string,NetExpr*>::const_iterator pp;
for (pp = defparams.begin() ; pp != defparams.end() ; pp ++ ) {
NetExpr*val = (*pp).second;
string path = (*pp).first;
string name = parse_last_name(path);
NetScope*targ_scope = des->find_scope(this, path);
if (targ_scope == 0) {
cerr << val->get_line() << ": warning: scope of " <<
path << "." << name << " not found." << endl;
continue;
}
val = targ_scope->set_parameter(name, val);
if (val == 0) {
cerr << val->get_line() << ": warning: parameter "
<< name << " not found in " << targ_scope->name()
<< "." << endl;
} else {
delete val;
}
}
}
void Design::evaluate_parameters()
{
root_scope_->evaluate_parameters(this);
}
void NetScope::evaluate_parameters(Design*des)
{
NetScope*cur = sub_;
while (cur) {
cur->evaluate_parameters(des);
cur = cur->sib_;
}
// Evaluate the parameter values. The parameter expressions
// have already been elaborated and replaced by the scope
// scanning code. Now the parameter expression can be fully
// evaluated, or it cannot be evaluated at all.
typedef map<string,NetExpr*>::iterator mparm_it_t;
for (mparm_it_t cur = parameters_.begin()
; cur != parameters_.end() ; cur ++) {
// Get the NetExpr for the parameter.
NetExpr*expr = (*cur).second;
assert(expr);
// If it's already a NetEConst, then this parameter is done.
if (dynamic_cast<const NetEConst*>(expr))
continue;
// Try to evaluate the expression.
NetExpr*nexpr = expr->eval_tree();
if (nexpr == 0) {
cerr << (*cur).second->get_line() << ": internal error: "
"unable to evaluate parm expression: " <<
*expr << endl;
des->errors += 1;
continue;
}
// The evaluate worked, replace the old expression with
// this constant value.
assert(nexpr);
delete expr;
(*cur).second = nexpr;
}
}
string Design::get_flag(const string&key) const
{
map<string,string>::const_iterator tmp = flags_.find(key);
if (tmp == flags_.end())
return "";
else
return (*tmp).second;
}
/*
* This method looks for a signal (reg, wire, whatever) starting at
* the specified scope. If the name is hierarchical, it is split into
* scope and name and the scope used to find the proper starting point
* for the real search.
*
* It is the job of this function to properly implement Verilog scope
* rules as signals are concerned.
*/
NetNet* Design::find_signal(NetScope*scope, const string&name)
{
assert(scope);
/* If the name has a path attached to it, parse it off and use
that to locate the desired starting scope. */
string path = name;
string key = parse_last_name(path);
if (path != "")
scope = find_scope(scope, path);
/* Now from the starting point, scan upwards until we find the
signal or we find a module boundary. */
while (scope) {
if (NetNet*net = scope->find_signal(key))
return net;
if (scope->type() == NetScope::MODULE)
break;
scope = scope->parent();
}
return 0;
}
NetMemory* Design::find_memory(NetScope*scope, const string&name)
{
assert(scope);
/* If the name has a path attached to it, parse it off and use
that to locate the desired scope. */
string path = name;
string key = parse_last_name(path);
if (path != "")
scope = find_scope(scope, path);
while (scope) {
if (NetMemory*mem = scope->find_memory(key))
return mem;
scope = scope->parent();
}
return 0;
}
void Design::find_symbol(NetScope*scope, const string&name,
NetNet*&sig, NetMemory*&mem)
{
sig = 0;
mem = 0;
/* If the name has a path attached to it, parse it off and use
that to locate the desired scope. Then locate the key
within that scope. */
string path = name;
string key = parse_last_name(path);
if (path != "")
scope = find_scope(scope, path);
/* If there is no path, then just search upwards for the key. */
while (scope) {
if (NetNet*cur = scope->find_signal(key)) {
sig = cur;
return;
}
if (NetMemory*cur = scope->find_memory(key)) {
mem = cur;
return;
}
scope = scope->parent();
}
}
NetFuncDef* Design::find_function(NetScope*scope, const string&name)
{
assert(scope);
NetScope*func = find_scope(scope, name);
if (func && (func->type() == NetScope::FUNC))
return func->func_def();
return 0;
}
NetFuncDef* Design::find_function(const string&key)
{
NetScope*func = find_scope(key);
if (func && (func->type() == NetScope::FUNC))
return func->func_def();
return 0;
}
NetScope* Design::find_task(NetScope*scope, const string&name)
{
NetScope*task = find_scope(scope, name);
if (task && (task->type() == NetScope::TASK))
return task;
return 0;
}
NetScope* Design::find_task(const string&key)
{
NetScope*task = find_scope(key);
if (task && (task->type() == NetScope::TASK))
return task;
return 0;
}
void Design::add_node(NetNode*net)
{
assert(net->design_ == 0);
if (nodes_ == 0) {
net->node_next_ = net;
net->node_prev_ = net;
} else {
net->node_next_ = nodes_->node_next_;
net->node_prev_ = nodes_;
net->node_next_->node_prev_ = net;
net->node_prev_->node_next_ = net;
}
nodes_ = net;
net->design_ = this;
}
void Design::del_node(NetNode*net)
{
assert(net->design_ == this);
if (nodes_ == net)
nodes_ = net->node_prev_;
if (nodes_ == net) {
nodes_ = 0;
} else {
net->node_next_->node_prev_ = net->node_prev_;
net->node_prev_->node_next_ = net->node_next_;
}
net->design_ = 0;
}
void Design::add_process(NetProcTop*pro)
{
pro->next_ = procs_;
procs_ = pro;
}
void Design::delete_process(NetProcTop*top)
{
assert(top);
if (procs_ == top) {
procs_ = top->next_;
} else {
NetProcTop*cur = procs_;
while (cur->next_ != top) {
assert(cur->next_);
cur = cur->next_;
}
cur->next_ = top->next_;
}
if (procs_idx_ == top)
procs_idx_ = top->next_;
delete top;
}
/*
* $Log: net_design.cc,v $
* Revision 1.20 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)
*
* Revision 1.19 2001/04/02 02:28:12 steve
* Generate code for task calls.
*
* Revision 1.18 2001/01/14 23:04:56 steve
* Generalize the evaluation of floating point delays, and
* get it working with delay assignment statements.
*
* Allow parameters to be referenced by hierarchical name.
*
* Revision 1.17 2000/12/16 01:45:48 steve
* Detect recursive instantiations (PR#2)
*
* Revision 1.16 2000/09/24 17:41:13 steve
* fix null pointer when elaborating undefined task.
*
* Revision 1.15 2000/08/26 00:54:03 steve
* Get at gate information for ivl_target interface.
*
* Revision 1.14 2000/08/12 17:59:48 steve
* Limit signal scope search at module boundaries.
*
* Revision 1.13 2000/07/30 18:25:43 steve
* Rearrange task and function elaboration so that the
* NetTaskDef and NetFuncDef functions are created during
* signal enaboration, and carry these objects in the
* NetScope class instead of the extra, useless map in
* the Design class.
*
* Revision 1.12 2000/07/23 02:41:32 steve
* Excessive assert.
*
* Revision 1.11 2000/07/22 22:09:03 steve
* Parse and elaborate timescale to scopes.
*
* Revision 1.10 2000/07/16 04:56:08 steve
* Handle some edge cases during node scans.
*
* Revision 1.9 2000/07/14 06:12:57 steve
* Move inital value handling from NetNet to Nexus
* objects. This allows better propogation of inital
* values.
*
* Clean up constant propagation a bit to account
* for regs that are not really values.
*
* Revision 1.8 2000/05/02 16:27:38 steve
* Move signal elaboration to a seperate pass.
*
* Revision 1.7 2000/05/02 03:13:31 steve
* Move memories to the NetScope object.
*
* Revision 1.6 2000/05/02 00:58:12 steve
* Move signal tables to the NetScope class.
*
* Revision 1.5 2000/04/28 16:50:53 steve
* Catch memory word parameters to tasks.
*
* Revision 1.4 2000/04/10 05:26:06 steve
* All events now use the NetEvent class.
*
* Revision 1.3 2000/03/11 03:25:52 steve
* Locate scopes in statements.
*
* Revision 1.2 2000/03/10 06:20:48 steve
* Handle defparam to partial hierarchical names.
*
* Revision 1.1 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.
*
*/
+518
View File
@@ -0,0 +1,518 @@
/*
* Copyright (c) 2000 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
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: net_event.cc,v 1.15 2001/07/25 03:10:49 steve Exp $"
#endif
# include "config.h"
# include "netlist.h"
NetEvent::NetEvent(const string&n)
: name_(0)
{
scope_ = 0;
snext_ = 0;
probes_ = 0;
trig_ = 0;
waitref_ = 0;
wlist_ = 0;
name_ = new char[n.length()+1];
strcpy(name_, n.c_str());
}
NetEvent::~NetEvent()
{
assert(waitref_ == 0);
if (scope_) scope_->rem_event(this);
while (probes_) {
NetEvProbe*tmp = probes_->enext_;
delete probes_;
probes_ = tmp;
}
delete[]name_;
}
const char* NetEvent::name() const
{
return name_;
}
string NetEvent::full_name() const
{
assert(scope_);
return scope_->name() + "." + name_;
}
const NetScope* NetEvent::scope() const
{
assert(scope_);
return scope_;
}
unsigned NetEvent::nprobe() const
{
unsigned cnt = 0;
NetEvProbe*cur = probes_;
while (cur) {
cnt += 1;
cur = cur->enext_;
}
return cnt;
}
NetEvProbe* NetEvent::probe(unsigned idx)
{
NetEvProbe*cur = probes_;
while (cur && idx) {
cur = cur->enext_;
idx -= 1;
}
return cur;
}
const NetEvProbe* NetEvent::probe(unsigned idx) const
{
NetEvProbe*cur = probes_;
while (cur && idx) {
cur = cur->enext_;
idx -= 1;
}
return cur;
}
unsigned NetEvent::ntrig() const
{
unsigned cnt = 0;
NetEvTrig*cur = trig_;
while (cur) {
cnt += 1;
cur = cur->enext_;
}
return cnt;
}
unsigned NetEvent::nwait() const
{
return waitref_;
}
/*
* A "similar" event is one that has an identical non-nil set of
* probes.
*/
NetEvent* NetEvent::find_similar_event()
{
if (probes_ == 0)
return 0;
struct table_s {
NetEvent*ev;
bool mark;
} *table;
//NetEvent**cand;
//bool*cflg;
unsigned max_cand = 0, ncand = 0;
NetEvProbe*cur = probes_;
/* Get an estimate of the number of candidate events there
are. To get it, count the number of probes that are
connected to my first probe. Since there is no more then
one NetEvent per NetEvProbe, this is the maximum number of
similar events possible.
Once we get that count, allocate the arrays needed to
account for these events. */
for (NetNode*idx = cur->next_node()
; idx && (idx != cur) ; idx = idx->next_node()) {
NetEvProbe*tmp = dynamic_cast<NetEvProbe*>(idx);
if (tmp == 0)
continue;
if (tmp->edge() != cur->edge())
continue;
max_cand += 1;
}
table = new struct table_s[max_cand];
/* First, locate all the candidate events from my first
probe. Look for all the NetEvProbe objects connected to my
probe (that are the same edge) and save the NetEvent that
that probe drives. */
for (NetNode*idx = cur->next_node()
; idx && (idx != cur) ; idx = idx->next_node()) {
NetEvProbe*tmp = dynamic_cast<NetEvProbe*>(idx);
if (tmp == 0)
continue;
if (tmp->edge() != cur->edge())
continue;
table[ncand++].ev = tmp->event();
assert(ncand <= max_cand);
}
/* All the events in the cand array are now known to connect
through at least one NetEvProbe. Now go through all my
remaining probes and check that each candidate event is
also connected (through a NetEvProbe) to me.
By the time I finish this scan, only NetEvents that have
equivilent NetEvProbes remain. These are candidates. The
events may have *more* NetEvProbes then me, I'll catch
those later. */
for (cur = cur->enext_ ; cur && ncand ; cur = cur->enext_) {
for (unsigned idx = 0 ; idx < ncand ; idx += 1)
table[idx].mark = false;
/* For this probe, look for other probes connected to it
and find the event connected to it. Mark that event
as connected to this probe. */
for (NetNode*idx = cur->next_node()
; idx && (idx != cur) ; idx = idx->next_node()) {
NetEvProbe*tmp = dynamic_cast<NetEvProbe*>(idx);
if (tmp == 0)
continue;
if (tmp->edge() != cur->edge())
continue;
for (unsigned srch = 0 ; srch < ncand ; srch += 1)
if (table[srch].ev == tmp->event()) {
table[srch].mark = true;
break;
}
}
/* Look for all the candidates that did not connect to
this probe (cflg is false) and eliminate them. */
for (unsigned idx = 0 ; idx < ncand ; ) {
if (table[idx].mark) {
idx += 1;
continue;
}
for (unsigned tmp = idx ; (tmp+1) < ncand ; tmp += 1)
table[tmp] = table[tmp+1];
ncand -= 1;
}
}
/* Scan the remaining candidates for a similar
NetEvent. Eliminate NetEvent objects that have more
NetEvProbe objects then I, because those have a proper
superset of my probes and were not eliminated by the
previous scan.
As soon as we find a similar event, we're done. */
for (unsigned idx = 0 ; idx < ncand ; idx += 1) {
if (table[idx].ev->nprobe() == nprobe()) {
NetEvent*res = table[idx].ev;
delete[]table;
return res;
}
}
/* Oops, fell off the list without finding a result. return nil. */
delete[]table;
return 0;
}
void NetEvent::replace_event(NetEvent*that)
{
while (wlist_) {
wlist_->obj->replace_event(this, that);
}
}
NetEvTrig::NetEvTrig(NetEvent*ev)
: event_(ev)
{
enext_ = event_->trig_;
event_->trig_ = this;
}
NetEvTrig::~NetEvTrig()
{
if (event_->trig_ == this) {
event_->trig_ = enext_;
} else {
NetEvTrig*cur = event_->trig_;
while (cur->enext_ != this) {
assert(cur->enext_);
cur = cur->enext_;
}
cur->enext_ = this->enext_;
}
}
const NetEvent* NetEvTrig::event() const
{
return event_;
}
NetEvProbe::NetEvProbe(const string&n, NetEvent*tgt,
edge_t t, unsigned p)
: NetNode(n, p), event_(tgt), edge_(t)
{
for (unsigned idx = 0 ; idx < p ; idx += 1) {
pin(idx).set_dir(Link::INPUT);
pin(idx).set_name("P", idx);
}
enext_ = event_->probes_;
event_->probes_ = this;
}
NetEvProbe::~NetEvProbe()
{
if (event_->probes_ == this) {
event_->probes_ = enext_;
} else {
NetEvProbe*cur = event_->probes_;
while (cur->enext_ != this) {
assert(cur->enext_);
cur = cur->enext_;
}
cur->enext_ = this->enext_;
}
}
NetEvProbe::edge_t NetEvProbe::edge() const
{
return edge_;
}
NetEvent* NetEvProbe::event()
{
return event_;
}
const NetEvent* NetEvProbe::event() const
{
return event_;
}
NetEvWait::NetEvWait(NetProc*pr)
: statement_(pr), nevents_(0), events_(0)
{
}
NetEvWait::~NetEvWait()
{
if (events_) {
for (unsigned idx = 0 ; idx < nevents_ ; idx += 1) {
NetEvent*tgt = events_[idx];
tgt->waitref_ -= 1;
struct NetEvent::wcell_*tmp = tgt->wlist_;
if (tmp->obj == this) {
tgt->wlist_ = tmp->next;
delete tmp;
} else {
assert(tmp->next);
while (tmp->next->obj != this) {
tmp = tmp->next;
assert(tmp->next);
}
tmp->next = tmp->next->next;
delete tmp;
}
}
delete[]events_;
}
delete statement_;
}
void NetEvWait::add_event(NetEvent*tgt)
{
assert(tgt);
if (nevents_ == 0) {
events_ = new NetEvent*[1];
} else {
NetEvent**tmp = new NetEvent*[nevents_+1];
for (unsigned idx = 0 ; idx < nevents_ ; idx += 1) {
tmp[idx] = events_[idx];
assert(tmp[idx] != tgt);
}
delete[]events_;
events_ = tmp;
}
events_[nevents_] = tgt;
nevents_ += 1;
// Remember to tell the NetEvent that there is someone
// pointing to it.
tgt->waitref_ += 1;
struct NetEvent::wcell_*tmp = new NetEvent::wcell_;
tmp->obj = this;
tmp->next = tgt->wlist_;
tgt->wlist_ = tmp;
}
void NetEvWait::replace_event(NetEvent*src, NetEvent*repl)
{
unsigned idx;
for (idx = 0 ; idx < nevents_ ; idx += 1) {
if (events_[idx] == src)
break;
}
assert(idx < nevents_);
/* First, remove me from the list held by the src NetEvent. */
assert(src->waitref_ > 0);
src->waitref_ -= 1;
struct NetEvent::wcell_*tmp = src->wlist_;
if (tmp->obj == this) {
src->wlist_ = tmp->next;
delete tmp;
} else {
assert(tmp->next);
while (tmp->next->obj != this) {
tmp = tmp->next;
assert(tmp->next);
}
tmp->next = tmp->next->next;
delete tmp;
}
events_[idx] = repl;
// Remember to tell the replacement NetEvent that there is
// someone pointing to it.
repl->waitref_ += 1;
tmp = new NetEvent::wcell_;
tmp->obj = this;
tmp->next = repl->wlist_;
repl->wlist_ = tmp;
}
unsigned NetEvWait::nevents() const
{
return nevents_;
}
const NetEvent* NetEvWait::event(unsigned idx) const
{
assert(idx < nevents_);
return events_[idx];
}
NetEvent* NetEvWait::event(unsigned idx)
{
assert(idx < nevents_);
return events_[idx];
}
NetProc* NetEvWait::statement()
{
return statement_;
}
/*
* $Log: net_event.cc,v $
* Revision 1.15 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)
*
* Revision 1.14 2001/03/29 02:52:19 steve
* Add const probe method to NetEvent.
*
* Revision 1.13 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.12 2000/12/15 17:45:07 steve
* Remove limits from the similar events search.
*
* Revision 1.11 2000/10/04 16:30:39 steve
* Use char8 instead of string to store name.
*
* Revision 1.10 2000/09/19 03:00:36 steve
* Typo stepping ot next probe in delete.
*
* Revision 1.9 2000/07/29 03:55:38 steve
* fix problem coalescing events w/ probes.
*
* Revision 1.8 2000/05/31 02:26:49 steve
* Globally merge redundant event objects.
*
* Revision 1.7 2000/05/27 19:33:23 steve
* Merge similar probes within a module.
*
* Revision 1.6 2000/04/18 04:50:20 steve
* Clean up unneeded NetEvent objects.
*
* Revision 1.5 2000/04/16 23:32:18 steve
* Synthesis of comparator in expressions.
*
* Connect the NetEvent and related classes
* together better.
*
* Revision 1.4 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.3 2000/04/12 04:23:58 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.2 2000/04/10 05:26:06 steve
* All events now use the NetEvent class.
*
* Revision 1.1 2000/04/04 03:20:15 steve
* Simulate named event trigger and waits.
*
*/
+131
View File
@@ -0,0 +1,131 @@
/*
* Copyright (c) 2000 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
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: net_force.cc,v 1.3 2001/07/25 03:10:49 steve Exp $"
#endif
# include "config.h"
/*
* This file contains implementatsion of the NetForce, NetRelease,
* NetCAssign and NetDeassign classes. These are similar or related in
* that they handle the procedural continuous assign and force
* statements.
*/
# include "netlist.h"
# include <assert.h>
/*
* Construct the procedural continuous assignment statement. This is a
* bit different from a normal assignment because the the lval is only
* intermittantly connected. The deassign in particular disconnects
* the signals when they are not being assigned anymore. Because of
* this, there is no other reference to the lval to make it stay put
* so we increment the eref.
*
* XXXX I'm not sure this is the right way. Perhaps I should create
* output pins to connect to the netlist? But that would cause the
* link ring to grow, and that is not quite correct either. Hmm...
*/
NetCAssign::NetCAssign(const string&n, NetNet*l)
: NetNode(n, l->pin_count()), lval_(l)
{
lval_->incr_eref();
for (unsigned idx = 0 ; idx < pin_count() ; idx += 1) {
pin(idx).set_dir(Link::INPUT);
pin(idx).set_name("I", idx);
}
}
NetCAssign::~NetCAssign()
{
lval_->decr_eref();
}
const Link& NetCAssign::lval_pin(unsigned idx) const
{
assert(idx < lval_->pin_count());
return lval_->pin(idx);
}
NetDeassign::NetDeassign(NetNet*l)
: lval_(l)
{
lval_->incr_eref();
}
NetDeassign::~NetDeassign()
{
lval_->decr_eref();
}
const NetNet*NetDeassign::lval() const
{
return lval_;
}
NetForce::NetForce(const string&n, NetNet*l)
: NetNode(n, l->pin_count()), lval_(l)
{
for (unsigned idx = 0 ; idx < pin_count() ; idx += 1) {
pin(idx).set_dir(Link::INPUT);
pin(idx).set_name("I", idx);
}
}
NetForce::~NetForce()
{
}
const Link& NetForce::lval_pin(unsigned idx) const
{
assert(idx < lval_->pin_count());
return lval_->pin(idx);
}
NetRelease::NetRelease(NetNet*l)
: lval_(l)
{
}
NetRelease::~NetRelease()
{
}
const NetNet*NetRelease::lval() const
{
return lval_;
}
/*
* $Log: net_force.cc,v $
* Revision 1.3 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)
*
* Revision 1.2 2000/05/12 01:22:41 steve
* NetCAssign needs to incr_eref its lval to lock it down.
*
* Revision 1.1 2000/05/11 23:37:27 steve
* Add support for procedural continuous assignment.
*
*/
+382
View File
@@ -0,0 +1,382 @@
/*
* Copyright (c) 2000 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
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: net_link.cc,v 1.5 2001/07/25 03:10:49 steve Exp $"
#endif
# include "config.h"
# include <iostream>
# include "netlist.h"
# include <strstream>
# include <string>
# include <typeinfo>
void connect(Link&l, Link&r)
{
assert(&l != &r);
assert(l.nexus_);
assert(r.nexus_);
/* If the links are already connected, then we're done. */
if (l.nexus_ == r.nexus_)
return;
Nexus*tmp = r.nexus_;
while (Link*cur = tmp->first_nlink()) {
tmp->unlink(cur);
l.nexus_->relink(cur);
}
assert(tmp->list_ == 0);
assert(l.is_linked(r));
delete tmp;
}
Link::Link()
: dir_(PASSIVE), drive0_(STRONG), drive1_(STRONG), init_(verinum::Vx),
inst_(0), next_(0), nexus_(0)
{
(new Nexus()) -> relink(this);
}
Link::~Link()
{
assert(nexus_);
Nexus*tmp = nexus_;
nexus_->unlink(this);
if (tmp->list_ == 0)
delete tmp;
}
Nexus* Link::nexus()
{
return nexus_;
}
const Nexus* Link::nexus() const
{
return nexus_;
}
void Link::set_dir(DIR d)
{
dir_ = d;
}
Link::DIR Link::get_dir() const
{
return dir_;
}
void Link::drive0(Link::strength_t str)
{
drive0_ = str;
}
void Link::drive1(Link::strength_t str)
{
drive1_ = str;
}
Link::strength_t Link::drive0() const
{
return drive0_;
}
Link::strength_t Link::drive1() const
{
return drive1_;
}
void Link::set_init(verinum::V val)
{
init_ = val;
}
verinum::V Link::get_init() const
{
return init_;
}
void Link::cur_link(NetObj*&net, unsigned &pin)
{
net = node_;
pin = pin_;
}
void Link::cur_link(const NetObj*&net, unsigned &pin) const
{
net = node_;
pin = pin_;
}
void Link::unlink()
{
assert(nexus_);
if (! is_linked())
return;
nexus_->unlink(this);
(new Nexus()) -> relink(this);
}
bool Link::is_equal(const Link&that) const
{
return (node_ == that.node_) && (pin_ == that.pin_);
}
bool Link::is_linked() const
{
if (next_)
return true;
if (nexus_->first_nlink() != this)
return true;
return false;
}
bool Link::is_linked(const Link&that) const
{
return nexus_ == that.nexus_;
}
Link* Link::next_nlink()
{
return next_;
}
const Link* Link::next_nlink() const
{
return next_;
}
const NetObj*Link::get_obj() const
{
return node_;
}
NetObj*Link::get_obj()
{
return node_;
}
unsigned Link::get_pin() const
{
return pin_;
}
void Link::set_name(const string&n, unsigned i)
{
name_ = n;
inst_ = i;
}
const string& Link::get_name() const
{
return name_;
}
unsigned Link::get_inst() const
{
return inst_;
}
Nexus::Nexus()
{
name_ = 0;
list_ = 0;
t_cookie_ = 0;
}
Nexus::~Nexus()
{
assert(list_ == 0);
if (name_)
delete[]name_;
}
verinum::V Nexus::get_init() const
{
assert(list_);
for (Link*cur = list_ ; cur ; cur = cur->next_) {
if (cur->get_dir() == Link::OUTPUT)
return verinum::Vx;
if ((cur->get_dir() == Link::PASSIVE)
&& (cur->get_init() != verinum::Vz))
return cur->get_init();
}
return verinum::Vz;
}
void Nexus::unlink(Link*that)
{
if (name_) {
delete[] name_;
name_ = 0;
}
assert(that);
if (list_ == that) {
list_ = that->next_;
that->next_ = 0;
that->nexus_ = 0;
return;
}
Link*cur = list_;
while (cur->next_ != that) {
assert(cur->next_);
cur = cur->next_;
}
cur->next_ = that->next_;
that->nexus_ = 0;
that->next_ = 0;
}
void Nexus::relink(Link*that)
{
if (name_) {
delete[] name_;
name_ = 0;
}
assert(that->nexus_ == 0);
assert(that->next_ == 0);
that->next_ = list_;
that->nexus_ = this;
list_ = that;
}
Link* Nexus::first_nlink()
{
return list_;
}
const Link* Nexus::first_nlink() const
{
return list_;
}
void* Nexus::t_cookie() const
{
return t_cookie_;
}
void* Nexus::t_cookie(void*val)const
{
void*tmp = t_cookie_;
t_cookie_ = val;
return tmp;
}
const char* Nexus::name() const
{
if (name_)
return name_;
const NetNet*sig = 0;
unsigned pin = 0;
for (const Link*cur = first_nlink()
; cur ; cur = cur->next_nlink()) {
const NetNet*cursig = dynamic_cast<const NetNet*>(cur->get_obj());
if (cursig == 0)
continue;
if (sig == 0) {
sig = cursig;
pin = cur->get_pin();
continue;
}
if ((cursig->pin_count() == 1) && (sig->pin_count() > 1))
continue;
if ((cursig->pin_count() > 1) && (sig->pin_count() == 1)) {
sig = cursig;
pin = cur->get_pin();
continue;
}
if (cursig->local_flag() && !sig->local_flag())
continue;
if (cursig->name() < sig->name())
continue;
sig = cursig;
pin = cur->get_pin();
}
if (sig == 0) {
const Link*lnk = first_nlink();
const NetObj*obj = lnk->get_obj();
pin = lnk->get_pin();
cerr << "internal error: No signal for nexus of " <<
obj->name() << " pin " << pin << "(" <<
lnk->get_name() << "<" << lnk->get_inst() << ">)"
" type=" << typeid(*obj).name() << "?" << endl;
}
assert(sig);
ostrstream tmp;
tmp << sig->name();
if (sig->pin_count() > 1)
tmp << "<" << pin << ">";
tmp << ends;
name_ = new char[strlen(tmp.str()) + 1];
strcpy(name_, tmp.str());
return name_;
}
/*
* $Log: net_link.cc,v $
* Revision 1.5 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)
*
* Revision 1.4 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.3 2000/08/26 00:54:03 steve
* Get at gate information for ivl_target interface.
*
* Revision 1.2 2000/07/14 06:12:57 steve
* Move inital value handling from NetNet to Nexus
* objects. This allows better propogation of inital
* values.
*
* Clean up constant propagation a bit to account
* for regs that are not really values.
*
* Revision 1.1 2000/06/25 19:59:42 steve
* Redesign Links to include the Nexus class that
* carries properties of the connected set of links.
*
*/
+107
View File
@@ -0,0 +1,107 @@
/*
* Copyright (c) 2000 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
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: net_modulo.cc,v 1.2 2001/07/25 03:10:49 steve Exp $"
#endif
# include "config.h"
# include <typeinfo>
# include <iostream>
# include <iomanip>
# include <cassert>
# include "netlist.h"
NetModulo::NetModulo(const string&n, unsigned wr,
unsigned wa, unsigned wb)
: NetNode(n, wr+wa+wb), width_r_(wr), width_a_(wa), width_b_(wb)
{
unsigned p = 0;
for (unsigned idx = 0 ; idx < width_r_ ; idx += 1, p += 1) {
pin(p).set_dir(Link::OUTPUT);
pin(p).set_name("Result", idx);
}
for (unsigned idx = 0 ; idx < width_a_ ; idx += 1, p += 1) {
pin(p).set_dir(Link::INPUT);
pin(p).set_name("DataA", idx);
}
for (unsigned idx = 0 ; idx < width_b_ ; idx += 1, p += 1) {
pin(p).set_dir(Link::INPUT);
pin(p).set_name("DataB", idx);
}
}
NetModulo::~NetModulo()
{
}
unsigned NetModulo::width_r() const
{
return width_r_;
}
unsigned NetModulo::width_a() const
{
return width_a_;
}
unsigned NetModulo::width_b() const
{
return width_b_;
}
Link& NetModulo::pin_Result(unsigned idx)
{
assert(idx < width_r_);
return pin(idx);
}
const Link& NetModulo::pin_Result(unsigned idx) const
{
assert(idx < width_r_);
return pin(idx);
}
Link& NetModulo::pin_DataA(unsigned idx)
{
assert(idx < width_a_);
return pin(idx+width_r_);
}
const Link& NetModulo::pin_DataA(unsigned idx) const
{
assert(idx < width_a_);
return pin(idx+width_r_);
}
Link& NetModulo::pin_DataB(unsigned idx)
{
assert(idx < width_b_);
return pin(idx+width_r_+width_a_);
}
const Link& NetModulo::pin_DataB(unsigned idx) const
{
assert(idx < width_b_);
return pin(idx+width_r_+width_a_);
}
+111
View File
@@ -0,0 +1,111 @@
/*
* Copyright (c) 2000 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
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: net_proc.cc,v 1.3 2001/07/25 03:10:49 steve Exp $"
#endif
# include "config.h"
# include "netlist.h"
# include <assert.h>
NetDisable::NetDisable(NetScope*tgt)
: target_(tgt)
{
}
NetDisable::~NetDisable()
{
}
const NetScope* NetDisable::target() const
{
return target_;
}
NetForever::NetForever(NetProc*p)
: statement_(p)
{
}
NetForever::~NetForever()
{
delete statement_;
}
NetPDelay::NetPDelay(unsigned long d, NetProc*st)
: delay_(d), expr_(0), statement_(st)
{
}
NetPDelay::NetPDelay(NetExpr*d, NetProc*st)
: delay_(0), expr_(d), statement_(st)
{
}
NetPDelay::~NetPDelay()
{
if (expr_) delete expr_;
}
unsigned long NetPDelay::delay() const
{
assert(expr_ == 0);
return delay_;
}
const NetExpr* NetPDelay::expr() const
{
return expr_;
}
NetRepeat::NetRepeat(NetExpr*e, NetProc*p)
: expr_(e), statement_(p)
{
}
NetRepeat::~NetRepeat()
{
delete expr_;
delete statement_;
}
const NetExpr* NetRepeat::expr() const
{
return expr_;
}
/*
* $Log: net_proc.cc,v $
* Revision 1.3 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)
*
* Revision 1.2 2000/07/27 05:13:44 steve
* Support elaboration of disable statements.
*
* Revision 1.1 2000/07/07 04:53:54 steve
* Add support for non-constant delays in delay statements,
* Support evaluating ! in constant expressions, and
* move some code from netlist.cc to net_proc.cc.
*
*/
+402
View File
@@ -0,0 +1,402 @@
/*
* Copyright (c) 2000 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
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: net_scope.cc,v 1.13 2001/07/25 03:10:49 steve Exp $"
#endif
# include "config.h"
# include "netlist.h"
# include <strstream>
/*
* The NetScope class keeps a scope tree organized. Each node of the
* scope tree points to its parent, its right sibling and its leftmost
* child. The root node has no parent or siblings. The node stores the
* name of the scope. The complete hierarchical name of the scope is
* formed by appending the path of scopes from the root to the scope
* in question.
*/
NetScope::NetScope(NetScope*up, const string&n, NetScope::TYPE t)
: type_(t), up_(up), sib_(0), sub_(0)
{
memories_ = 0;
signals_ = 0;
events_ = 0;
if (up) {
time_unit_ = up->time_unit();
time_prec_ = up->time_precision();
sib_ = up_->sub_;
up_->sub_ = this;
} else {
time_unit_ = 0;
time_prec_ = 0;
assert(t == MODULE);
}
switch (t) {
case NetScope::TASK:
task_ = 0;
break;
case NetScope::FUNC:
func_ = 0;
break;
case NetScope::MODULE:
module_name_ = 0;
break;
}
name_ = new char[n.length()+1];
strcpy(name_, n.c_str());
}
NetScope::~NetScope()
{
assert(sib_ == 0);
assert(sub_ == 0);
lcounter_ = 0;
delete[]name_;
if ((type_ == MODULE) && module_name_)
free(module_name_);
}
NetExpr* NetScope::set_parameter(const string&key, NetExpr*expr)
{
NetExpr*&ref = parameters_[key];
NetExpr* res = ref;
ref = expr;
return res;
}
NetExpr* NetScope::set_localparam(const string&key, NetExpr*expr)
{
NetExpr*&ref = localparams_[key];
NetExpr* res = ref;
ref = expr;
return res;
}
const NetExpr* NetScope::get_parameter(const string&key) const
{
map<string,NetExpr*>::const_iterator idx;
idx = parameters_.find(key);
if (idx != parameters_.end())
return (*idx).second;
idx = localparams_.find(key);
if (idx != localparams_.end())
return (*idx).second;
return 0;
}
NetScope::TYPE NetScope::type() const
{
return type_;
}
void NetScope::set_task_def(NetTaskDef*def)
{
assert( type_ == TASK );
assert( task_ == 0 );
task_ = def;
}
NetTaskDef* NetScope::task_def()
{
assert( type_ == TASK );
return task_;
}
const NetTaskDef* NetScope::task_def() const
{
assert( type_ == TASK );
return task_;
}
void NetScope::set_func_def(NetFuncDef*def)
{
assert( type_ == FUNC );
assert( func_ == 0 );
func_ = def;
}
NetFuncDef* NetScope::func_def()
{
assert( type_ == FUNC );
return func_;
}
const NetFuncDef* NetScope::func_def() const
{
assert( type_ == FUNC );
return func_;
}
void NetScope::set_module_name(const char*n)
{
assert(type_ == MODULE);
module_name_ = strdup(n);
}
const char* NetScope::module_name() const
{
assert(type_ == MODULE);
return module_name_;
}
void NetScope::time_unit(int val)
{
time_unit_ = val;
}
void NetScope::time_precision(int val)
{
time_prec_ = val;
}
int NetScope::time_unit() const
{
return time_unit_;
}
int NetScope::time_precision() const
{
return time_prec_;
}
const char* NetScope::basename() const
{
return name_;
}
string NetScope::name() const
{
if (up_)
return up_->name() + "." + name_;
else
return name_;
}
void NetScope::add_event(NetEvent*ev)
{
assert(ev->scope_ == 0);
ev->scope_ = this;
ev->snext_ = events_;
events_ = ev;
}
void NetScope::rem_event(NetEvent*ev)
{
assert(ev->scope_ == this);
ev->scope_ = 0;
if (events_ == ev) {
events_ = ev->snext_;
} else {
NetEvent*cur = events_;
while (cur->snext_ != ev) {
assert(cur->snext_);
cur = cur->snext_;
}
cur->snext_ = ev->snext_;
}
ev->snext_ = 0;
}
NetEvent* NetScope::find_event(const string&name)
{
for (NetEvent*cur = events_; cur ; cur = cur->snext_)
if (cur->name() == name)
return cur;
return 0;
}
void NetScope::add_signal(NetNet*net)
{
if (signals_ == 0) {
net->sig_next_ = net;
net->sig_prev_ = net;
} else {
net->sig_next_ = signals_->sig_next_;
net->sig_prev_ = signals_;
net->sig_next_->sig_prev_ = net;
net->sig_prev_->sig_next_ = net;
}
signals_ = net;
}
void NetScope::rem_signal(NetNet*net)
{
assert(net->scope() == this);
if (signals_ == net)
signals_ = net->sig_prev_;
if (signals_ == net) {
signals_ = 0;
} else {
net->sig_prev_->sig_next_ = net->sig_next_;
net->sig_next_->sig_prev_ = net->sig_prev_;
}
}
NetNet* NetScope::find_signal(const string&key)
{
if (signals_ == 0)
return 0;
string fulname = name()+"."+key;
NetNet*cur = signals_;
do {
if (cur->name() == fulname)
return cur;
cur = cur->sig_prev_;
} while (cur != signals_);
return 0;
}
void NetScope::add_memory(NetMemory*mem)
{
if (memories_ == 0) {
mem->snext_ = mem;
mem->sprev_ = mem;
} else {
mem->snext_ = memories_->snext_;
mem->sprev_ = memories_;
mem->snext_->sprev_ = mem;
mem->sprev_->snext_ = mem;
}
memories_ = mem;
mem->scope_ = this;
}
void NetScope::rem_memory(NetMemory*mem)
{
assert(mem->scope_ == this);
if (memories_ == mem)
memories_ = mem->sprev_;
if (memories_ == mem) {
memories_ = 0;
} else {
mem->sprev_->snext_ = mem->snext_;
mem->snext_->sprev_ = mem->sprev_;
}
mem->scope_ = 0;
}
NetMemory* NetScope::find_memory(const string&key)
{
if (memories_ == 0)
return 0;
string fulname = name()+"."+key;
NetMemory*cur = memories_;
do {
if (cur->name() == fulname)
return cur;
cur = cur->sprev_;
} while (cur != memories_);
return 0;
}
/*
* This method locates a child scope by name. The name is the simple
* name of the child, no heirarchy is searched.
*/
NetScope* NetScope::child(const string&name)
{
if (sub_ == 0) return 0;
NetScope*cur = sub_;
while (cur->name_ != name) {
if (cur->sib_ == 0) return 0;
cur = cur->sib_;
}
return cur;
}
const NetScope* NetScope::child(const string&name) const
{
if (sub_ == 0) return 0;
NetScope*cur = sub_;
while (cur->name_ != name) {
if (cur->sib_ == 0) return 0;
cur = cur->sib_;
}
return cur;
}
NetScope* NetScope::parent()
{
return up_;
}
const NetScope* NetScope::parent() const
{
return up_;
}
string NetScope::local_symbol()
{
strstream res;
res << "_s" << (lcounter_++) << ends;
return res.str();
}
/*
* $Log: net_scope.cc,v $
* Revision 1.13 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)
*
* Revision 1.12 2001/07/04 04:34:06 steve
* Scope-locals use _s instead of _l.
*
* Revision 1.11 2000/12/16 01:45:48 steve
* Detect recursive instantiations (PR#2)
*
* Revision 1.10 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.9 2000/08/27 15:51:50 steve
* t-dll iterates signals, and passes them to the
* target module.
*
* Some of NetObj should return char*, not string.
*
* Revision 1.8 2000/07/30 18:25:44 steve
* Rearrange task and function elaboration so that the
* NetTaskDef and NetFuncDef functions are created during
* signal enaboration, and carry these objects in the
* NetScope class instead of the extra, useless map in
* the Design class.
*/
+114
View File
@@ -0,0 +1,114 @@
/*
* Copyright (c) 2000 Stephen Williams (steve@icarus.com)
* Copyright (c) 2001 Stephan Boettcher <stephan@nevis.columbia.edu>
*
* 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: net_udp.cc,v 1.6 2001/07/25 03:10:49 steve Exp $"
#endif
# include "config.h"
# include "netlist.h"
NetUDP::NetUDP(NetScope*s, const string&n, unsigned pins, PUdp *u)
: NetNode(s, n, pins), udp(u)
{
pin(0).set_dir(Link::OUTPUT);
pin(0).set_name("O", 0);
for (unsigned idx = 1 ; idx < pins ; idx += 1) {
pin(idx).set_dir(Link::INPUT);
pin(idx).set_name("I", idx-1);
}
}
bool NetUDP::first(string&inp, char&out) const
{
table_idx = (unsigned) -1;
return next(inp, out);
}
bool NetUDP::next(string&inp, char&out) const
{
table_idx++;
if (table_idx >= udp->tinput.count())
return false;
if (is_sequential())
{
inp = string("") + udp->tcurrent[table_idx] + udp->tinput[table_idx];
assert(inp.length() == pin_count());
}
else
{
inp = udp->tinput[table_idx];
assert(inp.length() == (pin_count()-1));
}
out = udp->toutput[table_idx];
assert( (out == '0')
|| (out == '1')
|| (out == 'x')
|| (is_sequential() && (out == '-')));
return true;
}
char NetUDP::get_initial() const
{
assert (is_sequential());
switch (udp->initial)
{
case verinum::V0:
return '0';
case verinum::V1:
return '1';
case verinum::Vx:
case verinum::Vz:
return 'x';
}
assert(0);
return 'x';
}
/*
* $Log: net_udp.cc,v $
* Revision 1.6 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)
*
* Revision 1.5 2001/04/24 02:23:58 steve
* Support for UDP devices in VVP (Stephen Boettcher)
*
* Revision 1.4 2001/04/22 23:09:46 steve
* More UDP consolidation from Stephan Boettcher.
*
* Revision 1.3 2000/12/15 01:24:17 steve
* Accept x in outputs of primitive. (PR#84)
*
* Revision 1.2 2000/11/04 06:36:24 steve
* Apply sequential UDP rework from Stephan Boettcher (PR#39)
*
* Revision 1.1 2000/03/29 04:37:11 steve
* New and improved combinational primitives.
*
*/
+1128 -1500
View File
File diff suppressed because it is too large Load Diff
+1457 -716
View File
File diff suppressed because it is too large Load Diff
+77 -6
View File
@@ -16,7 +16,7 @@
* 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: netlist.txt,v 1.7 1999/11/28 23:42:02 steve Exp $"
#ident "$Id: netlist.txt,v 1.10 2000/07/23 18:06:15 steve Exp $"
Note that the netlist.h header contains detailed descriptions of how
@@ -60,13 +60,20 @@ changed during processing.
STRUCTURAL LINKS
The NetNode and NetNet classes contain arrays of Link objects, one
object per pin. Each pin is a single bit. The Link objects link
circularly to all the NetNode and NetNet objects' links that are
connected together in the design. This way, code that examines a node
object per pin. Each pin is a single bit. The Link objects link to all
the NetNode and NetNet objects' links that are connected together in
the design, and to a Nexus object. This way, code that examines a node
of the design can discover what is connected to each pin.
See the NetObj::Link class definition for a description of the link
methods.
The connected set of links also has common properties that are stored
or access from the Nexus object. All the Links that are connected
together are also connected to a single Nexus object. This object is
useful for accessing the properties and values that come from the
connected set of links. The Nexus object is also handy for iterating
over the connected set of Links.
See the Link class definition in netlist.h for a description of the link
methods, and the Nexus class for nexus global methods.
Currently, a link has 3 possible direction properties:
@@ -229,6 +236,29 @@ can operate globally, with optimizations freely crossing module
boundaries. This makes coding of netlist transform functions such as
constant propagation more effective and easier to write.
SCOPE REPRESENTATION IN NETLISTS
In spite of the literal flattening of the design, scope information is
preserved in the netlist, with the NetScope class. The Design class
keeps a single pointer to the root scope of the design. This is the
scope of the root module. Scopes that are then created within that
(or any nested) module are placed as children of the root scope, and
those children can have further children, and so on.
Each scope in the tree carries its own name, and its relationship to
its parent and children. This makes it possible to walk the tree of
scopes. In practice, the walking of the scopes is handled by recursive
methods.
Each scope also carries the parameters that are applicable to the
scope itself. The parameter expression (possibly evaluated) can be
located by name, given the scope object itself. The scan of the pform
to generate scopes also places the parameters that are declared in the
scope. Overrides are managed during the scan, and once the scan is
complete, defparam overrides are applied.
TASKS IN NETLISTS
The flattening of the design does not include tasks and named
@@ -239,7 +269,48 @@ recurse. (The elaboration process does reserve the right to flatten
some task calls. C++ programmers recognize this as inlining a task.)
TIME SCALE IN NETLISTS
The Design class and the NetScope classes carry time scale and
resolution information of the elaborated design. There is a global
resolution, and there are scope specific units and resolutions. Units
and resolutions are specified as signed integers, and interpreted as
the power of 10 of the value. For example, a resolution "-9" means
that "1" is 1ns (1e-9). The notation supports units from -128 to +127.
It is up to the back-ends to interpret "-4" as "100us".
Delays are expressed in the netlist by integers. The units of these
delays are always given in the units of the design precision. This
allows everything to work with integers, and generally places the
burden of scaling delays into elaboration. This is, after all, a
common task. The Design::get_precision() method gets the global design
precision.
Each NetScope also carries its local time_units and time_precision
values. These are filled in during scope elaboration and are used in
subsequent elaboration phases to arrange for scaling of delays. This
information can also be used by the code generator to scale times back
to the units of the scope, if that is desired.
$Log: netlist.txt,v $
Revision 1.10 2000/07/23 18:06:15 steve
Document time scale in netlists.
Revision 1.9 2000/07/14 06:12:57 steve
Move inital value handling from NetNet to Nexus
objects. This allows better propogation of inital
values.
Clean up constant propagation a bit to account
for regs that are not really values.
Revision 1.8 2000/03/08 04:36:54 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.7 1999/11/28 23:42:02 steve
NetESignal object no longer need to be NetNode
objects. Let them keep a pointer to NetNet objects.
+55
View File
@@ -0,0 +1,55 @@
/*
* Copyright (c) 2001 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
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: netmisc.cc,v 1.2 2001/07/25 03:10:49 steve Exp $"
#endif
# include "config.h"
# include "netlist.h"
# include "netmisc.h"
# include "PExpr.h"
NetExpr* elab_and_eval(Design*des, NetScope*scope, const PExpr*pe)
{
NetExpr*tmp = pe->elaborate_expr(des, scope);
if (tmp == 0)
return 0;
if (NetExpr*tmp2 = tmp->eval_tree()) {
delete tmp;
tmp = tmp2;
}
return tmp;
}
/*
* $Log: netmisc.cc,v $
* 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)
*
* Revision 1.1 2001/02/11 02:15:52 steve
* Add the netmisc.cc source file.
*
*/

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