Compare commits

...
660 Commits
Author SHA1 Message Date
steve e42775ea7f support toupper and tolower of file names. 2001-12-08 04:13:07 +00:00
steve a8c4729cf5 vpi_put_value of vpiIntVal for memory words. 2001-12-07 23:23:05 +00:00
steve c200c0c20e Support integer for function return value. 2001-12-07 05:03:13 +00:00
steve 4b174fd996 Forgot to evaluate UDP delays. 2001-12-06 05:04:49 +00:00
steve dbf5509f4f Support delays on UDP instances. 2001-12-06 04:44:11 +00:00
steve ec4f8c80d5 Support functor delays for gates and UDP devices.
(Stephan Boettcher)
2001-12-06 03:31:24 +00:00
steve c8319bcc02 Add ivl_logic_delay function to ivl_target. 2001-12-06 03:11:00 +00:00
steve 7bf480be9a Some bison versions choose different output names. 2001-12-06 02:55:24 +00:00
steve 2d3e85d941 Make sure fork labels are globally unique. 2001-12-05 05:41:20 +00:00
steve ab6c8cb4b8 Parser and pform use hierarchical names as hname_t
objects instead of encoded strings.
2001-12-03 04:47:14 +00:00
steve 33c7c47f73 Handle index identifiers in simple paths. 2001-12-01 02:42:39 +00:00
steve 64d7b1cee5 Support addresses in readmemh. 2001-12-01 02:40:10 +00:00
steve 0cebef872a Better synthesys of DFF w/ complex l-values. (Larry Doolittle) 2001-11-30 01:22:21 +00:00
steve 65f835f3eb Properly parse net_decl assignments with delays. 2001-11-29 17:37:51 +00:00
steve 8309c1f673 Preserve the text after ifdefs in the output. 2001-11-29 02:26:25 +00:00
steve e85347bf8b Handle part selects in l-values of DFF devices. 2001-11-29 01:58:18 +00:00
steve 86a4512848 Restore -Fxnfio to -txnf target. 2001-11-29 01:06:51 +00:00
steve 82831ea9a5 Use NetScope instead of string for scope path. 2001-11-22 06:20:59 +00:00
steve 98c145c3b6 Ignore foo and a.out. 2001-11-22 06:20:32 +00:00
steve a50fe36ef8 Ignore foo and a.out. 2001-11-22 04:44:23 +00:00
steve 7cbd710f7b Remove diag print. 2001-11-21 02:59:27 +00:00
steve 39ef2b7605 Pass list of file to ivlpp via temporary file. 2001-11-21 02:20:34 +00:00
steve da4901bb17 Close library files after parsing. 2001-11-20 23:36:34 +00:00
steve f28f5e01e5 Unary reduction operators are all 1-bit results. 2001-11-19 04:26:46 +00:00
steve e00aedd99b Handle padding out of logical values. 2001-11-19 04:25:46 +00:00
steve 9d1a81ce2c Handle division and modulus by zero while
evaluating run-time constants.
2001-11-19 02:54:12 +00:00
steve cfed3933fa Port close cropping behavior from mcrgb
Move window array reset to libmc.
2001-11-19 01:54:14 +00:00
steve 659624c71f Print typename is fallback expression node dump. 2001-11-19 01:46:38 +00:00
steve 6e0b77a8da Generate force code for variable l-values. 2001-11-18 01:28:18 +00:00
steve 54bb59ae99 Support compile on MacosX 10.1.1 (Timothy J. Wood) 2001-11-17 17:57:58 +00:00
steve cac941b272 More spelling. 2001-11-17 17:45:37 +00:00
steve 0be48388c2 Add support for +libext+ in command files. 2001-11-16 05:07:19 +00:00
steve d8970752b6 include stdlib.h for portability. 2001-11-16 04:22:27 +00:00
steve 08f0f5a1f7 DLL target support for force and release. 2001-11-14 03:28:49 +00:00
steve f8162be8c3 Describe +incdir and +define. 2001-11-14 03:28:15 +00:00
steve f50074de50 The +incdir+ plusarg can take multiple directores,
and add initial support for +define+ in the command file.
2001-11-13 03:30:26 +00:00
steve 9866fd01bd Support +incdir in command files, and ignore other
+args flags. Also ignore -a and -v flags.
2001-11-12 18:47:32 +00:00
steve d1ad10c90f More sophisticated command file parser. 2001-11-12 01:26:36 +00:00
steve 0045d7d1bf Remov XNF dead wood. 2001-11-11 00:10:05 +00:00
steve 4a74ae1795 Runtime support for functor delays. (Stephan Boettcher) 2001-11-10 18:07:11 +00:00
steve 4d0b840c26 Coerse input to inout when assigned to. 2001-11-10 02:08:49 +00:00
steve 0c7335a77d Spelling errors. 2001-11-09 03:43:26 +00:00
steve 7e8a538c20 Support $writememh 2001-11-09 03:39:21 +00:00
steve aca5afa95c Support vpiIntVal from memory. 2001-11-09 03:39:07 +00:00
steve 7793a49854 Remove string paths from PExpr elaboration. 2001-11-08 05:15:50 +00:00
steve 6bfbcbdcf7 elaborate_lnet uses scope instead of string path. 2001-11-07 04:26:46 +00:00
steve bf72f39fe9 eval_const uses scope instead of a string path. 2001-11-07 04:01:59 +00:00
steve fa23dafdae Use functor pointers where vvp_ipoint_t is unneeded. 2001-11-07 03:34:41 +00:00
steve 9572ddd7e8 Support more real arithmetic in delay constants. 2001-11-06 06:11:55 +00:00
steve 1ff36dc892 shift expressions can have definite widths. 2001-11-06 04:32:37 +00:00
steve bf9a8f5021 Code rearrange. (Stephan Boettcher) 2001-11-06 03:07:21 +00:00
steve 0c4bea473c Parse specparam parsepulse assignments. 2001-11-06 02:52:19 +00:00
steve 649428962e Pad limited r-values in continuous assignments. 2001-11-04 23:12:29 +00:00
steve cc5ddc0b6b MacOSX 10.1 updates. 2001-11-04 05:03:21 +00:00
steve b624b6002e Parse more [gosh darn] specify syntax. 2001-11-03 04:09:10 +00:00
steve af35736e04 initialize scope for %m in $fdisplay. 2001-11-02 05:56:47 +00:00
steve 58b5b583a7 Comment the scope type parser. 2001-11-02 05:43:11 +00:00
steve 9e385e6947 Implement split_node for symbol table (hendrik) 2001-11-02 04:48:03 +00:00
steve 560c003e03 make fork label into complete statemnt. 2001-11-01 19:31:40 +00:00
steve 1d045eea0d Catch ports that have no direction. 2001-11-01 05:21:26 +00:00
steve 7a0e73ef3d Handle procedural constant functor pointers. 2001-11-01 04:42:39 +00:00
steve 5d20dd63ec Generate code for deassign and cassign. 2001-11-01 04:26:57 +00:00
steve ab9a853d52 ivl_target support for cassign. 2001-11-01 04:25:31 +00:00
steve 82c0a2ebac Add force/cassign/release/deassign support. (Stephan Boettcher) 2001-11-01 03:00:19 +00:00
steve 75e78e86d3 ivl_target support for assign/deassign. 2001-10-31 05:24:52 +00:00
steve a75326e2e0 Rewrite the functor type to have fewer functor modes,
and use objects to manage the different types.
 (Stephan Boettcher)
2001-10-31 04:27:46 +00:00
steve b3e430c751 Give up if roots are missing. 2001-10-31 03:22:31 +00:00
steve faa3a62259 detect module ports not declared within the module. 2001-10-31 03:11:15 +00:00
steve 438605fad5 Account for new scope type syntax on scope. 2001-10-31 03:07:11 +00:00
steve 9505b586bf Generate IEEE1364-2000 line directives. 2001-10-30 21:53:27 +00:00
steve 40e7bc2450 line number in line directive is for the *next* line. 2001-10-30 21:46:56 +00:00
steve a9aaca1ffa Add ifndef support. 2001-10-30 20:48:55 +00:00
steve ce61d12f60 Stubs for assign/deassign for t-dll. 2001-10-30 02:52:07 +00:00
steve 874bab10e4 NetObj constructor finally requires a scope. 2001-10-28 01:14:53 +00:00
steve 21194c909a Propagate functor push, to make assign better. 2001-10-27 03:43:56 +00:00
steve 96a50d635d Minor rework of summation carry propagation (Stephan Boettcher) 2001-10-27 03:22:26 +00:00
steve 8c9e0bafa9 more specify syntax (Stehpan Boettcher) 2001-10-26 03:22:56 +00:00
steve b3bb79992a const/non-const warnings. (Stephan Boettcher) 2001-10-26 02:29:10 +00:00
steve 4e92501864 VPI support for callback to return values. 2001-10-25 04:19:53 +00:00
steve d83fb10774 The ! expression returns 0 to x and z values. 2001-10-24 05:06:54 +00:00
steve 5a6cca33a0 Write resolvers before the .functor (PR#300) 2001-10-24 03:43:45 +00:00
steve b2f6953259 npmos outputs have 3bit strengths, not 2. 2001-10-24 03:18:52 +00:00
steve b1f1f74920 Support bit selects of non-0 lsb for vectors. 2001-10-23 04:22:41 +00:00
steve 2adea8de48 Fix carry between works for %add instruction. 2001-10-23 03:49:13 +00:00
steve 859318becd The -s flag can now be repeated on the iverilog command. 2001-10-23 00:37:29 +00:00
steve 55fb219503 document the -y flag. 2001-10-23 00:36:54 +00:00
steve b01316ce12 Better error message for mising root module. 2001-10-22 23:26:37 +00:00
steve 1921e19635 fix constant overrun in | operands. 2001-10-22 15:31:21 +00:00
steve 990df42407 Handle activating tasks in another root. 2001-10-22 02:05:20 +00:00
steve 924b4e0062 unused idx warning. 2001-10-22 02:04:37 +00:00
steve 0e43dfb285 Remove useless code for drawing .var inputs. 2001-10-22 00:04:51 +00:00
steve 46621d3c83 wrong variable for clk input to memory. 2001-10-21 23:38:16 +00:00
steve fa95f7ff3b Kill const-nonconst warning. 2001-10-21 23:37:49 +00:00
steve e45546e6f3 Install pdf version of the man pages. 2001-10-21 21:59:49 +00:00
steve d79d48ffeb clean up API for restarting parser. 2001-10-21 20:18:56 +00:00
steve 467ecf5b33 Error messages for missing UDP port declarations. 2001-10-21 01:55:24 +00:00
steve 9f3e64e11a Module types in pform are char* instead of string. 2001-10-21 00:42:47 +00:00
steve 56954356db Catch and X division by 0. 2001-10-20 23:20:32 +00:00
steve 6466d02eda Add automatic module libraries. 2001-10-20 23:02:39 +00:00
steve 7a149a6943 Scope/module names are char* instead of string. 2001-10-20 05:21:51 +00:00
steve acf3a4ec16 Print memory usage information if requested (Stephan Boettcher) 2001-10-20 01:03:42 +00:00
steve 5c4b87675f Evaluate constant == when operands differ in width. 2001-10-20 00:11:24 +00:00
steve 83d3a60d5c Add trailing ; to fork-join out labels. 2001-10-19 23:52:36 +00:00
steve 3e4eb17b15 Another go at getting link of ivl.exe right. 2001-10-19 23:15:01 +00:00
steve 1075b28f26 export the ivl_design_roots function. 2001-10-19 23:14:46 +00:00
steve 943527c526 Fix memory fault with -c flag. 2001-10-19 23:10:08 +00:00
steve d350620315 Support multiple root modules (Philip Blundell) 2001-10-19 21:53:24 +00:00
steve 6fc556cefc Method to get the type_ member 2001-10-19 01:55:32 +00:00
steve 73283768a5 Support rnpmos devices. (Philip Blundell) 2001-10-18 17:30:25 +00:00
steve ce7d64f427 Evaluate string expressions (Philip Blundell) 2001-10-18 16:41:49 +00:00
steve 84b70be7ee Include HAVE_SYS_WAIT in config.h (PR#306) 2001-10-18 16:16:23 +00:00
steve 3924c51097 Support vpiVectorVal for signals. (Philip Blundell) 2001-10-18 04:52:31 +00:00
steve 4bb1bd4315 Get Division error into the division method! 2001-10-16 03:10:20 +00:00
steve 0164ad78be Catch division by zero in .arith/div. 2001-10-16 03:06:18 +00:00
steve 36e1eab3f4 Add arith/div object. 2001-10-16 02:47:37 +00:00
steve 177fa4062b Support IVL_LPM_DIVIDE for structural divide. 2001-10-16 02:19:26 +00:00
steve 821c68696d Generate %div instructions for binary /. 2001-10-16 01:27:17 +00:00
steve a3217db7b2 Add %div support (Anthony Bybell) 2001-10-16 01:26:54 +00:00
steve 42dab181cd Carry the type of the scope (Stephan Boettcher) 2001-10-15 02:58:27 +00:00
steve 98d71de50f sign warning. 2001-10-15 02:55:03 +00:00
steve c596e1cda1 Include scope information in VCD output. 2001-10-15 01:50:23 +00:00
steve 706f2ffc89 Support getting scope of scope, and scope of signals. 2001-10-15 01:49:50 +00:00
steve a7054a91e5 libiberty is needed for mingw, and useable under cygwin. 2001-10-14 19:54:05 +00:00
steve ad44b411fb Try appending .vpi to module names with directories. 2001-10-14 18:42:46 +00:00
steve f7fa2f1f4d More coverage of $dump related commands. 2001-10-14 18:32:06 +00:00
steve 2fcab15704 Forgot to propagate carry. 2001-10-14 17:36:18 +00:00
steve cfbad49d33 Very wide multiplication (Anthony Bybell) 2001-10-14 16:36:43 +00:00
steve 9dbcb32808 vvm support for pullup/down gates (PR#288) 2001-10-14 03:50:53 +00:00
steve 1b69bb5d2f Handle mode-42 functor init. 2001-10-14 03:41:58 +00:00
steve 2326672b3a Handle constant bits in arithmetic expressions. 2001-10-14 03:24:35 +00:00
steve 393a76d57a threshold of $width is optional. 2001-10-14 02:03:51 +00:00
steve 4b3b41cd79 Propogate strength-only changes from resolver. 2001-10-14 01:45:11 +00:00
steve eab5793dda Account for non-0 start address for memories (Stephan Boettcher) 2001-10-14 01:36:12 +00:00
steve 6cf2ddf541 M42 implementation of mode 2 (Stephan Boettcher) 2001-10-12 03:00:08 +00:00
steve ad6bbe539f functor lookup includes vpi signal search. 2001-10-12 02:53:47 +00:00
steve f12864f69e Propagate initial value of UDP. 2001-10-11 18:29:21 +00:00
steve b61c89c104 npmos devices pass strength. 2001-10-11 18:20:51 +00:00
steve 0def3c9983 Initialize attributes for bufz devices. 2001-10-11 00:13:19 +00:00
steve 9e5dc17c1d Detect execv failures. 2001-10-11 00:12:49 +00:00
steve 36d36d99f3 Generate BUF devices for bufz logic. 2001-10-11 00:12:28 +00:00
steve de985ac3fd Document the behavioral reduction or. 2001-10-10 04:48:12 +00:00
steve 245905aeda Support vectors as operands to logical and. 2001-10-10 04:47:43 +00:00
steve ac6caaf29e More make install details. 2001-10-09 23:05:10 +00:00
steve 3734b5e7f1 spec reference events can be identifiers. 2001-10-09 18:11:58 +00:00
steve 789efb9832 Collect functor reference handling into a single function. (Stephan Boettcher) 2001-10-09 16:57:47 +00:00
steve c7bc35ad75 get CFLAGS from configure 2001-10-09 16:50:17 +00:00
steve 5071ce8575 handle nmos and pmos devices. 2001-10-09 02:28:44 +00:00
steve 64ff74df37 Add the PMOS and NMOS functor types. 2001-10-09 02:28:16 +00:00
steve 181066311b Tasks can have sub-scopes. 2001-10-09 02:01:04 +00:00
steve 20ad433f8c Fix pr283: signal values before enddefinitions in vcd. (Stephan Boettcher) 2001-10-08 23:33:00 +00:00
steve 494b5ff1ee parameter names do not have defined size. 2001-10-07 03:38:08 +00:00
steve cbd501b865 Fix some Cygwin DLL handling. (Venkat Iyer) 2001-09-30 16:45:10 +00:00
steve 41384a0e41 Reduce VCD output by removing duplicates. (Stephan Boettcher) 2001-09-30 05:18:46 +00:00
steve 3854e12024 Fencepost error in memory writes. (Stephan Boettcher) 2001-09-29 20:55:42 +00:00
steve ff55af1e9e Check address is in range for set. (Stephan Boettcher) 2001-09-29 04:45:20 +00:00
steve bdf643ddb1 Generate code for unary minus (PR#272) 2001-09-29 04:37:44 +00:00
steve d46465845c Fix the size of unsized constant operants to compare (PR#274) 2001-09-29 01:53:22 +00:00
steve dd75595082 Handle short l-values to concatenation. 2001-09-20 03:46:38 +00:00
steve a73cfbc2b5 MacOS X compile time changes. (Timothy Wood) 2001-09-20 03:21:01 +00:00
steve 21c844363a Change UDP output only if table matches. 2001-09-19 04:10:40 +00:00
steve 3109906514 Detect C name mangling for dlsym. 2001-09-17 22:26:33 +00:00
steve 606eb2b3cd Support the cellref attribute. 2001-09-16 22:26:47 +00:00
steve e99059e001 Support attributes to logic gates. 2001-09-16 22:19:42 +00:00
steve cefbb635c1 Suppor the PAD attribute on signals. 2001-09-16 01:48:16 +00:00
steve b2b8b89cd8 Make configure detect malloc.h 2001-09-15 18:27:04 +00:00
steve 92760f2c5f Support != in virtex code generator. 2001-09-15 05:06:04 +00:00
steve 176be94be9 dead code. 2001-09-14 04:20:49 +00:00
steve 9fda809fa6 Add XOR and XNOR gates. 2001-09-14 04:17:20 +00:00
steve 3c8d598eed Elaborate == to NetCompare instead of XNOR and AND
gates. This allows code generators to generate
 better code in certain cases.
2001-09-14 04:16:52 +00:00
steve f2068e83d4 Generate code for identity comparators. 2001-09-14 04:15:46 +00:00
steve 5976e7078c Xilinx uses GROUND and VCC as pin names for the
GND and VCC devices.

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

 Fix initial clearing of vector by vector_to_array
2001-09-07 23:29:28 +00:00
steve acde444439 Separate the virtex and generic-edif code generators. 2001-09-06 04:28:39 +00:00
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
302 changed files with 43671 additions and 5087 deletions
+4
View File
@@ -10,6 +10,10 @@ ivl.exp
dep
configure
Makefile
check
check.cc
config.status
config.log
config.cache
config.h
dosify
+7 -1
View File
@@ -17,9 +17,11 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: Attrib.cc,v 1.1 2000/12/04 17:37:03 steve Exp $"
#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>
@@ -118,6 +120,10 @@ string Attrib::value(unsigned idx) const
/*
* $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.
*
+257
View File
@@ -0,0 +1,257 @@
/*
* 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: HName.cc,v 1.1 2001/12/03 04:47:14 steve Exp $"
#endif
# include "HName.h"
# include <iostream>
# include <string.h>
# include <malloc.h>
hname_t::hname_t()
{
item_ = 0;
count_ = 0;
}
hname_t::hname_t(const char*text)
{
item_ = strdup(text);
count_ = 1;
}
hname_t::hname_t(const hname_t&that)
{
count_ = that.count_;
switch (count_) {
case 0:
item_ = 0;
break;
case 1:
item_ = strdup(that.item_);
break;
default:
array_ = new char*[count_];
for (unsigned idx = 0 ; idx < count_ ; idx += 1)
array_[idx] = strdup(that.array_[idx]);
break;
}
}
hname_t::~hname_t()
{
switch (count_) {
case 0:
break;
case 1:
free(item_);
break;
default:
for (unsigned idx = 0 ; idx < count_ ; idx += 1)
free(array_[idx]);
delete[]array_;
break;
}
}
void hname_t::append(const char*text)
{
char**tmp;
switch (count_) {
case 0:
count_ = 1;
item_ = strdup(text);
break;
case 1:
count_ = 2;
tmp = new char*[2];
tmp[0] = item_;
tmp[1] = strdup(text);
array_ = tmp;
break;
default:
tmp = new char*[count_+1];
for (unsigned idx = 0 ; idx < count_ ; idx += 1)
tmp[idx] = array_[idx];
delete[]array_;
array_ = tmp;
array_[count_] = strdup(text);
count_ += 1;
}
}
void hname_t::prepend(const char*text)
{
char**tmp;
switch (count_) {
case 0:
count_ = 1;
item_ = strdup(text);
break;
case 1:
count_ = 2;
tmp = new char*[2];
tmp[0] = strdup(text);
tmp[1] = item_;
array_ = tmp;
break;
default:
tmp = new char*[count_+1];
tmp[0] = strdup(text);
for (unsigned idx = 0 ; idx < count_ ; idx += 1)
tmp[idx+1] = array_[idx];
delete[]array_;
array_ = tmp;
count_ += 1;
}
}
char* hname_t::remove_tail_name()
{
if (count_ == 0)
return 0;
if (count_ == 1) {
char*tmp = item_;
count_ = 0;
item_ = 0;
return tmp;
}
if (count_ == 2) {
char*tmp1 = array_[0];
char*tmp2 = array_[1];
delete[]array_;
count_ = 1;
item_ = tmp1;
return tmp2;
}
char*tmpo = array_[count_-1];
char**tmpa = new char*[count_-1];
for (unsigned idx = 0 ; idx < count_-1 ; idx += 1)
tmpa[idx] = array_[idx];
delete[]array_;
array_ = tmpa;
count_ -= 1;
return tmpo;
}
const char* hname_t::peek_name(unsigned idx) const
{
if (idx >= count_)
return 0;
if (count_ == 1)
return item_;
return array_[idx];
}
const char* hname_t::peek_tail_name() const
{
switch (count_) {
case 0:
return 0;
case 1:
return item_;
default:
return array_[count_-1];
}
}
bool operator < (const hname_t&l, const hname_t&r)
{
unsigned idx = 0;
const char*lc = l.peek_name(idx);
const char*rc = r.peek_name(idx);
while (lc && rc) {
int cmp = strcmp(lc, rc);
if (cmp < 0)
return true;
if (cmp > 0)
return false;
idx += 1;
lc = l.peek_name(idx);
rc = r.peek_name(idx);
}
if (lc && !rc)
return false;
if (rc && !lc)
return true;
// Must be ==
return false;
}
bool operator == (const hname_t&l, const hname_t&r)
{
unsigned idx = 0;
const char*lc = l.peek_name(idx);
const char*rc = r.peek_name(idx);
while (lc && rc) {
int cmp = strcmp(lc, rc);
if (cmp != 0)
return false;
idx += 1;
lc = l.peek_name(idx);
rc = r.peek_name(idx);
}
if (lc || rc)
return false;
// Must be ==
return true;
}
ostream& operator<< (ostream&out, const hname_t&that)
{
switch (that.count_) {
case 0:
out << "";
return out;
case 1:
out << that.item_;
return out;
default:
out << that.array_[0];
for (unsigned idx = 1 ; idx < that.count_ ; idx += 1)
out << "." << that.array_[idx];
return out;
}
}
/*
* $Log: HName.cc,v $
* Revision 1.1 2001/12/03 04:47:14 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
*
*/
+86
View File
@@ -0,0 +1,86 @@
#ifndef __HName_H
#define __HName_H
/*
* Copyright (c) 2001 Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: HName.h,v 1.1 2001/12/03 04:47:14 steve Exp $"
#endif
#ifdef HAVE_IOSFWD
# include <iosfwd>
#else
class ostream;
#endif
/*
* This class represents a Verilog hierarchical name. A hierarchical
* name is an ordered list of simple names.
*/
class hname_t {
public:
hname_t ();
explicit hname_t (const char*text);
hname_t (const hname_t&that);
~hname_t();
// This method adds a name to the end of the hierarchical
// path. This becomes a new base name.
void append(const char*text);
// This method adds a name to the *front* of the hierarchical
// path. The base name remains the same, unless this is the
// only component.
void prepend(const char*text);
// This method removes the tail name from the hierarchy, and
// returns a pointer to that tail name. That tail name now
// must be removed by the caller.
char* remove_tail_name();
// Return the given component in the hierarchical name. If the
// idx is too large, return 0.
const char*peek_name(unsigned idx) const;
const char*peek_tail_name() const;
friend ostream& operator<< (ostream&, const hname_t&);
private:
union {
char**array_;
char* item_;
};
unsigned count_;
private: // not implemented
hname_t& operator= (const hname_t&);
};
extern bool operator < (const hname_t&, const hname_t&);
extern bool operator == (const hname_t&, const hname_t&);
/*
* $Log: HName.h,v $
* Revision 1.1 2001/12/03 04:47:14 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
*
*/
#endif
+7 -1
View File
@@ -17,9 +17,11 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: LineInfo.cc,v 1.1 2000/11/30 17:31:42 steve Exp $"
#ident "$Id: LineInfo.cc,v 1.2 2001/07/25 03:10:48 steve Exp $"
#endif
# include "config.h"
# include "LineInfo.h"
# include <cstdio>
@@ -42,6 +44,10 @@ void LineInfo::set_line(const LineInfo&that)
/*
* $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.
*
+80 -18
View File
@@ -16,17 +16,19 @@
# 59 Temple Place - Suite 330
# Boston, MA 02111-1307, USA
#
#ident "$Id: Makefile.in,v 1.90 2001/01/14 23:04:55 steve Exp $"
#ident "$Id: Makefile.in,v 1.109 2001/12/06 02:55:24 steve Exp $"
#
#
SHELL = /bin/sh
VERSION = 0.3
VERSION = 0.5
prefix = @prefix@
exec_prefix = @exec_prefix@
srcdir = @srcdir@
SUBDIRS = @subdirs@
VPATH = $(srcdir)
bindir = @bindir@
@@ -35,6 +37,7 @@ includedir = $(prefix)/include
dllib=@DLLIB@
rdynamic=@rdynamic@
strip_dynamic=@strip_dynamic@
CC = @CC@
CXX = @CXX@
@@ -46,6 +49,7 @@ STRIP = @STRIP@
CPPFLAGS = @CPPFLAGS@ @DEFS@
CXXFLAGS = @CXXFLAGS@ -I. -I$(srcdir)
PICFLAGS = @PICFLAG@
LDFLAGS = @LDFLAGS@
# The TARGETS variable lists the target modules that can be build and
@@ -57,7 +61,8 @@ TARGETS += tgt-pal
endif
all: ivl@EXEEXT@
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
@@ -66,24 +71,36 @@ all: ivl@EXEEXT@
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 -Ivvm -Ivpi -Lvvm check.cc -lvvm -lvpip $(dllib)
$(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 lexor_keyword.cc ivl@EXEEXT@ libivl.a
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
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
@@ -98,29 +115,44 @@ O = main.o cprop.o design_dump.o dup_expr.o elaborate.o elab_expr.o \
elab_lval.o elab_net.o elab_anet.o elab_pexpr.o elab_scope.o \
elab_sig.o emit.o eval.o eval_rconst.o \
eval_tree.o expr_synth.o functor.o lexor.o lexor_keyword.o link_const.o \
mangle.o netlist.o net_assign.o \
load_module.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 util.o \
Attrib.o LineInfo.o Module.o PDelays.o PEvent.o \
verinum.o verireal.o target.o targets.o \
Attrib.o HName.o LineInfo.o Module.o PDelays.o PEvent.o \
PExpr.o PGate.o \
PTask.o PFunction.o PWire.o Statement.o \
$(FF) $(TT)
Makefile: Makefile.in config.status
Makefile: Makefile.in config.h.in config.status
./config.status
ifeq (@CYGWIN@,yes)
libvpi.a: vpithunk.o
rm -f $@
ar cvq $@ vpithunk.o
ranlib $@
# The vpithunk.c file (that makes up the libvpi.a library) needs to
# be make with PIC flags, because shared objects load it.
vpithunk.o: vpithunk.c
@[ -d dep ] || mkdir dep
$(CC) $(CPPFLAGS) $(CFLAGS) $(PICFLAGS) -MD -c $< -o $*.o
mv $*.d dep/$*.d
ifeq (@WIN32@,yes)
# Under Windows (mingw) I need to make the ivl.exe in two steps.
# The first step makes an ivl.exe that dlltool can use to make an
# export and import library, and the last link makes a, ivl.exe
# that really exports the things that the import library imports.
ivl@EXEEXT@: $O ivl.def
$(CXX) -o ivl@EXEEXT@ $O $(dllib) @EXTRALIBS@
dlltool --dllname ivl@EXEEXT@ --def ivl.def \
--output-lib libivl.a --output-exp ivl.exp
# $(CXX) -o ivl@EXEEXT@ -Wl,--base-file,ivl.base ivl.exp $O $(dllib)
# dlltool --dllname ivl@EXEEXT@ --base-file ivl.base \
# --output-exp ivl.exp --def ivl.def
$(CXX) -o ivl@EXEEXT@ ivl.exp $O $(dllib)
$(CXX) -o ivl@EXEEXT@ ivl.exp $O $(dllib) @EXTRALIBS@
else
ivl@EXEEXT@: $O
$(CXX) $(CXXFLAGS) $(rdynamic) $(LDFLAGS) -o ivl@EXEEXT@ $O $(dllib)
@@ -138,8 +170,8 @@ lexor.o: lexor.cc parse.h
parse.o: parse.cc
parse.h parse.cc: $(srcdir)/parse.y
bison --verbose -t -p VL -d $(srcdir)/parse.y -o parse.cc
mv parse.cc.h parse.h
bison --verbose -t -p VL -d -o parse.cc $(srcdir)/parse.y
mv parse.cc.h parse.h || mv parse.hh parse.h
syn-rules.cc: $(srcdir)/syn-rules.y
bison --verbose -p syn_ -o syn-rules.cc $(srcdir)/syn-rules.y
@@ -152,17 +184,24 @@ 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
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
$(libdir)/libvpi.a : ./libvpi.a
$(INSTALL_DATA) libvpi.a $(libdir)/libvpi.a
$(libdir)/ivl/ivl@EXEEXT@: ./ivl@EXEEXT@
$(INSTALL_PROGRAM) ./ivl@EXEEXT@ $(libdir)/ivl/ivl@EXEEXT@
$(STRIP) $(libdir)/ivl/ivl@EXEEXT@
$(STRIP) $(strip_dynamic) $(libdir)/ivl/ivl@EXEEXT@
$(libdir)/ivl/iverilog.conf: $(srcdir)/iverilog.conf
$(INSTALL_DATA) $(srcdir)/iverilog.conf $(libdir)/ivl/iverilog.conf
@@ -170,19 +209,42 @@ $(libdir)/ivl/iverilog.conf: $(srcdir)/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) $(includedir) $(libdir)/ivl
uninstall:
rm -f $(libdir)/ivl/ivl@EXEEXT@
rm -f $(bindir)/verilog
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)
+25 -7
View File
@@ -17,22 +17,29 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: Module.cc,v 1.14 2000/11/15 20:31:05 steve Exp $"
#ident "$Id: Module.cc,v 1.17 2001/12/03 04:47:14 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)
Module::Module(const char*name, const svector<Module::port_t*>*pp)
: name_(strdup(name))
{
if (pp)
ports_ = *pp;
}
Module::~Module()
{
free(name_);
}
void Module::add_gate(PGate*gate)
{
gates_.push_back(gate);
@@ -50,7 +57,7 @@ void Module::add_function(const string &name, PFunction *func)
PWire* Module::add_wire(PWire*wire)
{
PWire*&ep = wires_[wire->name()];
PWire*&ep = wires_[wire->path()];
if (ep) return ep;
assert(ep == 0);
@@ -95,9 +102,9 @@ unsigned Module::find_port(const string&name) const
}
PWire* Module::get_wire(const string&name) const
PWire* Module::get_wire(const hname_t&name) const
{
map<string,PWire*>::const_iterator obj = wires_.find(name);
map<hname_t,PWire*>::const_iterator obj = wires_.find(name);
if (obj == wires_.end())
return 0;
else
@@ -117,7 +124,7 @@ PGate* Module::get_gate(const string&name)
return 0;
}
const map<string,PWire*>& Module::get_wires() const
const map<hname_t,PWire*>& Module::get_wires() const
{
return wires_;
}
@@ -135,6 +142,17 @@ const list<PProcess*>& Module::get_behaviors() const
/*
* $Log: Module.cc,v $
* Revision 1.17 2001/12/03 04:47:14 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
*
* Revision 1.16 2001/10/20 05:21:51 steve
* Scope/module names are char* instead of string.
*
* Revision 1.15 2001/07/25 03:10:48 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
*
* Revision 1.14 2000/11/15 20:31:05 steve
* Fix warning about temporaries.
*
+22 -9
View File
@@ -19,13 +19,15 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: Module.h,v 1.21 2000/11/05 06:05:59 steve Exp $"
#ident "$Id: Module.h,v 1.24 2001/12/03 04:47:14 steve Exp $"
#endif
# include <list>
# include <map>
# include "svector.h"
# include "HName.h"
# include "named.h"
# include "LineInfo.h"
# include <string>
class PEvent;
class PExpr;
@@ -44,7 +46,7 @@ class NetScope;
* therefore the handle for grasping the described circuit.
*/
class Module {
class Module : public LineInfo {
/* The module ports are in general a vector of port_t
objects. Each port has a name and an ordered list of
@@ -58,7 +60,8 @@ class Module {
};
public:
explicit Module(const string&name, const svector<port_t*>*);
explicit Module(const char*name, const svector<port_t*>*);
~Module();
/* The module has parameters that are evaluated when the
@@ -71,7 +74,7 @@ class Module {
new parameters within the module, but may be used to set
values within this module (when instantiated) or in other
instantiated modules. */
map<string,PExpr*>defparms;
map<hname_t,PExpr*>defparms;
/* Parameters may be overridden at instantiation time;
the overrides do not contain explicit parameter names,
@@ -88,7 +91,7 @@ class Module {
set by the `timescale directive. */
int time_unit, time_precision;
const string&get_name() const { return name_; }
const char*mod_name() const { return name_; }
void add_gate(PGate*gate);
@@ -107,10 +110,10 @@ class Module {
// Find a wire by name. This is used for connecting gates to
// existing wires, etc.
PWire* get_wire(const string&name) const;
PWire* get_wire(const hname_t&name) const;
PGate* get_gate(const string&name);
const map<string,PWire*>& get_wires() const;
const map<hname_t,PWire*>& get_wires() const;
const list<PGate*>& get_gates() const;
const list<PProcess*>& get_behaviors() const;
@@ -122,13 +125,13 @@ class Module {
bool elaborate_sig(Design*, NetScope*scope) const;
private:
const string name_;
char* name_;
/* This is an array of port descriptors, which is in turn a
named array of PEident pointers. */
svector<port_t*> ports_;
map<string,PWire*> wires_;
map<hname_t,PWire*> wires_;
list<PGate*> gates_;
list<PProcess*> behaviors_;
map<string,PTask*> tasks_;
@@ -142,6 +145,16 @@ class Module {
/*
* $Log: Module.h,v $
* Revision 1.24 2001/12/03 04:47:14 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
*
* Revision 1.23 2001/10/31 03:11:15 steve
* detect module ports not declared within the module.
*
* Revision 1.22 2001/10/20 05:21:51 steve
* Scope/module names are char* instead of string.
*
* Revision 1.21 2000/11/05 06:05:59 steve
* Handle connectsion to internally unconnected modules (PR#38)
*
+17 -4
View File
@@ -17,9 +17,13 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: PDelays.cc,v 1.4 2001/01/20 02:15:50 steve Exp $"
#ident "$Id: PDelays.cc,v 1.7 2001/11/22 06:20:59 steve Exp $"
#endif
# include "config.h"
# include <iostream>
# include "PDelays.h"
# include "PExpr.h"
# include "verinum.h"
@@ -65,7 +69,7 @@ static unsigned long calculate_val(Design*des, const NetScope*scope,
delete dr;
} else {
verinum*dv = expr->eval_const(des, scope->name());
verinum*dv = expr->eval_const(des, scope);
if (dv == 0) {
cerr << expr->get_line() << ": sorry: non-constant "
<< "delays not supported here: " << *expr << endl;
@@ -82,12 +86,11 @@ static unsigned long calculate_val(Design*des, const NetScope*scope,
return val;
}
void PDelays::eval_delays(Design*des, const string&path,
void PDelays::eval_delays(Design*des, NetScope*scope,
unsigned long&rise_time,
unsigned long&fall_time,
unsigned long&decay_time) const
{
NetScope*scope = des->find_scope(path);
assert(scope);
int shift = scope->time_unit() - des->get_precision();
@@ -122,6 +125,16 @@ void PDelays::eval_delays(Design*des, const string&path,
/*
* $Log: PDelays.cc,v $
* Revision 1.7 2001/11/22 06:20:59 steve
* Use NetScope instead of string for scope path.
*
* Revision 1.6 2001/11/07 04:01:59 steve
* eval_const uses scope instead of a string path.
*
* Revision 1.5 2001/07/25 03:10:48 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
*
* Revision 1.4 2001/01/20 02:15:50 steve
* apologize for not supporting non-constant delays.
*
+6 -2
View File
@@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: PDelays.h,v 1.3 2001/01/16 02:44:17 steve Exp $"
#ident "$Id: PDelays.h,v 1.4 2001/11/22 06:20:59 steve Exp $"
#endif
# include "svector.h"
@@ -32,6 +32,7 @@ class ostream;
#endif
class Design;
class NetScope;
class PExpr;
/*
@@ -47,7 +48,7 @@ class PDelays {
void set_delay(PExpr*);
void set_delays(const svector<PExpr*>*del);
void eval_delays(Design*des, const string&path,
void eval_delays(Design*des, NetScope*scope,
unsigned long&rise_time,
unsigned long&fall_time,
unsigned long&decay_time) const;
@@ -66,6 +67,9 @@ ostream& operator << (ostream&o, const PDelays&);
/*
* $Log: PDelays.h,v $
* Revision 1.4 2001/11/22 06:20:59 steve
* Use NetScope instead of string for scope path.
*
* Revision 1.3 2001/01/16 02:44:17 steve
* Use the iosfwd header if available.
*
+7 -1
View File
@@ -17,9 +17,11 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: PEvent.cc,v 1.1 2000/04/01 19:31:57 steve Exp $"
#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)
@@ -38,6 +40,10 @@ string PEvent::name() const
/*
* $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.
*
+7 -2
View File
@@ -19,7 +19,7 @@
* 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 $"
#ident "$Id: PEvent.h,v 1.5 2001/12/03 04:47:14 steve Exp $"
#endif
# include "LineInfo.h"
@@ -30,7 +30,8 @@ class NetScope;
/*
* The PEvent class represents event objects. These are things that
* are declared in Verilog as ``event foo;''
* are declared in Verilog as ``event foo;'' The name passed to the
* constructure is the "foo" part of the declaration.
*/
class PEvent : public LineInfo {
@@ -52,6 +53,10 @@ class PEvent : public LineInfo {
/*
* $Log: PEvent.h,v $
* Revision 1.5 2001/12/03 04:47:14 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
*
* Revision 1.4 2001/01/16 02:44:18 steve
* Use the iosfwd header if available.
*
+49 -16
View File
@@ -17,9 +17,13 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: PExpr.cc,v 1.23 2001/01/14 23:04:55 steve Exp $"
#ident "$Id: PExpr.cc,v 1.28 2001/12/03 04:47:14 steve Exp $"
#endif
# include "config.h"
# include <iostream>
# include "PExpr.h"
# include "Module.h"
# include <typeinfo>
@@ -42,7 +46,7 @@ bool PExpr::is_constant(Module*) const
return false;
}
NetNet* PExpr::elaborate_net(Design*des, const string&path, unsigned,
NetNet* PExpr::elaborate_net(Design*des, NetScope*scope, unsigned,
unsigned long,
unsigned long,
unsigned long,
@@ -54,25 +58,34 @@ NetNet* PExpr::elaborate_net(Design*des, const string&path, unsigned,
return 0;
}
NetNet* PExpr::elaborate_lnet(Design*des, const string&path) const
NetNet* PExpr::elaborate_lnet(Design*des, NetScope*) const
{
cerr << get_line() << ": error: expression not valid in assign l-value: "
<< *this << endl;
return 0;
}
PEBinary::PEBinary(char op, PExpr*l, PExpr*r)
: op_(op), left_(l), right_(r)
{
}
PEBinary::~PEBinary()
{
}
bool PEBinary::is_constant(Module*mod) const
{
return left_->is_constant(mod) && right_->is_constant(mod);
}
PECallFunction::PECallFunction(const char*n, const svector<PExpr *> &parms)
: name_(n), parms_(parms)
PECallFunction::PECallFunction(const hname_t&n, const svector<PExpr *> &parms)
: path_(n), parms_(parms)
{
}
PECallFunction::PECallFunction(const char*n)
: name_(n)
PECallFunction::PECallFunction(const hname_t&n)
: path_(n)
{
}
@@ -138,8 +151,8 @@ bool PEFNumber::is_constant(Module*) const
return true;
}
PEIdent::PEIdent(const string&s)
: text_(s), msb_(0), lsb_(0), idx_(0)
PEIdent::PEIdent(const hname_t&s)
: path_(s), msb_(0), lsb_(0), idx_(0)
{
}
@@ -147,9 +160,9 @@ PEIdent::~PEIdent()
{
}
string PEIdent::name() const
const hname_t& PEIdent::path() const
{
return text_;
return path_;
}
/*
@@ -158,14 +171,17 @@ string PEIdent::name() const
*/
bool PEIdent::is_constant(Module*mod) const
{
map<string,PExpr*>::const_iterator cur;
if (mod == 0) return false;
cur = mod->parameters.find(text_);
if (cur != mod->parameters.end()) return true;
{ map<string,PExpr*>::const_iterator cur;
cur = mod->parameters.find(path_.peek_name(0));
if (cur != mod->parameters.end()) return true;
}
cur = mod->localparams.find(text_);
if (cur != mod->localparams.end()) return true;
{ map<string,PExpr*>::const_iterator cur;
cur = mod->localparams.find(path_.peek_name(0));
if (cur != mod->localparams.end()) return true;
}
return false;
}
@@ -251,6 +267,23 @@ bool PEUnary::is_constant(Module*m) const
/*
* $Log: PExpr.cc,v $
* Revision 1.28 2001/12/03 04:47:14 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
*
* Revision 1.27 2001/11/08 05:15:50 steve
* Remove string paths from PExpr elaboration.
*
* Revision 1.26 2001/11/07 04:26:46 steve
* elaborate_lnet uses scope instead of string path.
*
* Revision 1.25 2001/11/06 06:11:55 steve
* Support more real arithmetic in delay constants.
*
* Revision 1.24 2001/07/25 03:10:48 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
*
* 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.
+54 -212
View File
@@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: PExpr.h,v 1.48 2001/01/14 23:04:55 steve Exp $"
#ident "$Id: PExpr.h,v 1.53 2001/12/03 04:47:14 steve Exp $"
#endif
# include <string>
@@ -62,7 +62,7 @@ class PExpr : public LineInfo {
// This method elaborate the expression as gates, for use in a
// continuous assign or other wholly structural context.
virtual NetNet* elaborate_net(Design*des, const string&path,
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
unsigned lwidth,
unsigned long rise,
unsigned long fall,
@@ -77,7 +77,7 @@ class PExpr : public LineInfo {
// This method elaborates the expression as gates, but
// restricted for use as l-values of continuous assignments.
virtual NetNet* elaborate_lnet(Design*des, const string&path) const;
virtual NetNet* elaborate_lnet(Design*des, NetScope*scope) const;
// Expressions that can be in the l-value of procedural
// assignments can be elaborated with this method.
@@ -86,7 +86,7 @@ class PExpr : public LineInfo {
// This attempts to evaluate a constant expression, and return
// a verinum as a result. If the expression cannot be
// evaluated, return 0.
virtual verinum* eval_const(const Design*des, const string&path) const;
virtual verinum* eval_const(const Design*des, const NetScope*sc) const;
// This attempts to evaluate a constant expression as a
// decimal floating point. This is used when calculating delay
@@ -123,8 +123,8 @@ class PEConcat : public PExpr {
// continuous assignments.
virtual NetNet* elaborate_anet(Design*des, NetScope*scope) const;
virtual NetNet* elaborate_lnet(Design*des, const string&path) const;
virtual NetNet* elaborate_net(Design*des, const string&path,
virtual NetNet* elaborate_lnet(Design*des, NetScope*scope) const;
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
unsigned width,
unsigned long rise,
unsigned long fall,
@@ -182,7 +182,7 @@ class PEFNumber : public PExpr {
/* The eval_const method as applied to a floating point number
gets the *integer* value of the number. This accounts for
any rounding that is needed to get the value. */
virtual verinum* eval_const(const Design*des, const string&path) const;
virtual verinum* eval_const(const Design*des, const NetScope*sc) const;
/* This method returns the full floating point value. */
virtual verireal* eval_rconst(const Design*, const NetScope*) const;
@@ -202,7 +202,7 @@ class PEFNumber : public PExpr {
class PEIdent : public PExpr {
public:
explicit PEIdent(const string&s);
explicit PEIdent(const hname_t&s);
~PEIdent();
virtual void dump(ostream&) const;
@@ -211,13 +211,13 @@ class PEIdent : public PExpr {
virtual NetNet* elaborate_anet(Design*des, NetScope*scope) const;
// Identifiers are allowed (with restrictions) is assign l-values.
virtual NetNet* elaborate_lnet(Design*des, const string&path) const;
virtual NetNet* elaborate_lnet(Design*des, NetScope*scope) const;
// Identifiers are also allowed as procedural assignment l-values.
virtual NetAssign_* elaborate_lval(Design*des, NetScope*scope) const;
// Structural r-values are OK.
virtual NetNet* elaborate_net(Design*des, const string&path,
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
unsigned lwidth,
unsigned long rise,
unsigned long fall,
@@ -233,12 +233,13 @@ class PEIdent : public PExpr {
NetNet* elaborate_port(Design*des, NetScope*sc) const;
virtual bool is_constant(Module*) const;
verinum* eval_const(const Design*des, const string&path) const;
verinum* eval_const(const Design*des, const NetScope*sc) const;
verireal*eval_rconst(const Design*des, const NetScope*sc) const;
string name() const;
const hname_t& path() const;
private:
string text_;
hname_t path_;
public:
// Use these to support bit- and part-select operators.
@@ -249,7 +250,7 @@ class PEIdent : public PExpr {
// expression.
PExpr*idx_;
NetNet* elaborate_net_ram_(Design*des, const string&path,
NetNet* elaborate_net_ram_(Design*des, NetScope*scope,
NetMemory*mem, unsigned lwidth,
unsigned long rise,
unsigned long fall,
@@ -265,7 +266,7 @@ class PENumber : public PExpr {
const verinum& value() const;
virtual void dump(ostream&) const;
virtual NetNet* elaborate_net(Design*des, const string&path,
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
unsigned lwidth,
unsigned long rise,
unsigned long fall,
@@ -274,7 +275,8 @@ class PENumber : public PExpr {
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 verinum* eval_const(const Design*des, const NetScope*sc) const;
virtual verireal*eval_rconst(const Design*, const NetScope*) const;
virtual bool is_the_same(const PExpr*that) const;
virtual bool is_constant(Module*) const;
@@ -307,7 +309,7 @@ class PEUnary : public PExpr {
~PEUnary();
virtual void dump(ostream&out) const;
virtual NetNet* elaborate_net(Design*des, const string&path,
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
unsigned width,
unsigned long rise,
unsigned long fall,
@@ -316,7 +318,7 @@ class PEUnary : public PExpr {
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 verinum* eval_const(const Design*des, const NetScope*sc) const;
virtual bool is_constant(Module*) const;
@@ -328,13 +330,13 @@ class PEUnary : public PExpr {
class PEBinary : public PExpr {
public:
explicit PEBinary(char op, PExpr*l, PExpr*r)
: op_(op), left_(l), right_(r) { }
explicit PEBinary(char op, PExpr*l, PExpr*r);
~PEBinary();
virtual bool is_constant(Module*) const;
virtual void dump(ostream&out) const;
virtual NetNet* elaborate_net(Design*des, const string&path,
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
unsigned width,
unsigned long rise,
unsigned long fall,
@@ -343,7 +345,8 @@ class PEBinary : public PExpr {
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;
virtual verinum* eval_const(const Design*des, const NetScope*sc) const;
virtual verireal*eval_rconst(const Design*des, const NetScope*sc) const;
private:
char op_;
@@ -352,42 +355,42 @@ class PEBinary : public PExpr {
NetEBinary*elaborate_expr_base_(Design*, NetExpr*lp, NetExpr*rp) const;
NetNet* elaborate_net_add_(Design*des, const string&path,
NetNet* elaborate_net_add_(Design*des, NetScope*scope,
unsigned lwidth,
unsigned long rise,
unsigned long fall,
unsigned long decay) const;
NetNet* elaborate_net_bit_(Design*des, const string&path,
NetNet* elaborate_net_bit_(Design*des, NetScope*scope,
unsigned lwidth,
unsigned long rise,
unsigned long fall,
unsigned long decay) const;
NetNet* elaborate_net_cmp_(Design*des, const string&path,
NetNet* elaborate_net_cmp_(Design*des, NetScope*scope,
unsigned lwidth,
unsigned long rise,
unsigned long fall,
unsigned long decay) const;
NetNet* elaborate_net_div_(Design*des, const string&path,
NetNet* elaborate_net_div_(Design*des, NetScope*scope,
unsigned lwidth,
unsigned long rise,
unsigned long fall,
unsigned long decay) const;
NetNet* elaborate_net_mod_(Design*des, const string&path,
NetNet* elaborate_net_mod_(Design*des, NetScope*scope,
unsigned lwidth,
unsigned long rise,
unsigned long fall,
unsigned long decay) const;
NetNet* elaborate_net_log_(Design*des, const string&path,
NetNet* elaborate_net_log_(Design*des, NetScope*scope,
unsigned lwidth,
unsigned long rise,
unsigned long fall,
unsigned long decay) const;
NetNet* elaborate_net_mul_(Design*des, const string&path,
NetNet* elaborate_net_mul_(Design*des, NetScope*scope,
unsigned lwidth,
unsigned long rise,
unsigned long fall,
unsigned long decay) const;
NetNet* elaborate_net_shift_(Design*des, const string&path,
NetNet* elaborate_net_shift_(Design*des, NetScope*scope,
unsigned lwidth,
unsigned long rise,
unsigned long fall,
@@ -407,7 +410,7 @@ class PETernary : public PExpr {
virtual bool is_constant(Module*) const;
virtual void dump(ostream&out) const;
virtual NetNet* elaborate_net(Design*des, const string&path,
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
unsigned width,
unsigned long rise,
unsigned long fall,
@@ -416,7 +419,7 @@ class PETernary : public PExpr {
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;
virtual verinum* eval_const(const Design*des, const NetScope*sc) const;
private:
PExpr*expr_;
@@ -430,15 +433,15 @@ class PETernary : public PExpr {
*/
class PECallFunction : public PExpr {
public:
explicit PECallFunction(const char*n, const svector<PExpr *> &parms);
explicit PECallFunction(const char*n);
explicit PECallFunction(const hname_t&n, const svector<PExpr *> &parms);
explicit PECallFunction(const hname_t&n);
~PECallFunction();
virtual void dump(ostream &) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope) const;
private:
string name_;
hname_t path_;
svector<PExpr *> parms_;
NetExpr* elaborate_sfunc_(Design*des, NetScope*scope) const;
@@ -446,6 +449,22 @@ class PECallFunction : public PExpr {
/*
* $Log: PExpr.h,v $
* Revision 1.53 2001/12/03 04:47:14 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
*
* Revision 1.52 2001/11/08 05:15:50 steve
* Remove string paths from PExpr elaboration.
*
* Revision 1.51 2001/11/07 04:26:46 steve
* elaborate_lnet uses scope instead of string path.
*
* Revision 1.50 2001/11/07 04:01:59 steve
* eval_const uses scope instead of a string path.
*
* Revision 1.49 2001/11/06 06:11:55 steve
* Support more real arithmetic in delay constants.
*
* 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.
@@ -463,182 +482,5 @@ class PECallFunction : public PExpr {
*
* 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.
*
* Revision 1.24 1999/11/14 20:24:28 steve
* Add support for the LPM_CLSHIFT device.
*
* Revision 1.23 1999/11/05 21:45:19 steve
* Fix NetConst being set to zero width, and clean
* up elaborate_set_cmp_ for NetEBinary.
*
* Revision 1.22 1999/10/31 20:08:24 steve
* Include subtraction in LPM_ADD_SUB device.
*
* Revision 1.21 1999/10/31 04:11:27 steve
* Add to netlist links pin name and instance number,
* and arrange in vvm for pin connections by name
* and instance number.
*
* Revision 1.20 1999/09/25 02:57:29 steve
* Parse system function calls.
*
* Revision 1.19 1999/09/15 04:17:52 steve
* separate assign lval elaboration for error checking.
*
* Revision 1.18 1999/08/31 22:38:29 steve
* Elaborate and emit to vvm procedural functions.
*
* Revision 1.17 1999/08/01 21:18:55 steve
* elaborate rise/fall/decay for continuous assign.
*
* Revision 1.16 1999/07/31 19:14:47 steve
* Add functions up to elaboration (Ed Carter)
*
* Revision 1.15 1999/07/22 02:05:20 steve
* is_constant method for PEConcat.
*
* Revision 1.14 1999/07/17 19:50:59 steve
* netlist support for ternary operator.
*
* Revision 1.13 1999/06/16 03:13:29 steve
* More syntax parse with sorry stubs.
*
* Revision 1.12 1999/06/15 02:50:02 steve
* Add lexical support for real numbers.
*
* Revision 1.11 1999/06/10 04:03:52 steve
* Add support for the Ternary operator,
* Add support for repeat concatenation,
* Correct some seg faults cause by elaboration
* errors,
* Parse the casex anc casez statements.
*
* Revision 1.10 1999/06/09 03:00:05 steve
* Add support for procedural concatenation expression.
*
* Revision 1.9 1999/05/16 05:08:42 steve
* Redo constant expression detection to happen
* after parsing.
*
* Parse more operators and expressions.
*
* Revision 1.8 1999/05/10 00:16:57 steve
* Parse and elaborate the concatenate operator
* in structural contexts, Replace vector<PExpr*>
* and list<PExpr*> with svector<PExpr*>, evaluate
* constant expressions with parameters, handle
* memories as lvalues.
*
* Parse task declarations, integer types.
*
* Revision 1.7 1999/05/01 02:57:52 steve
* Handle much more complex event expressions.
*
* Revision 1.6 1999/04/29 02:16:26 steve
* Parse OR of event expressions.
*
* Revision 1.5 1999/04/19 01:59:36 steve
* Add memories to the parse and elaboration phases.
*
* Revision 1.4 1998/11/11 00:01:51 steve
* Check net ranges in declarations.
*
* Revision 1.3 1998/11/09 18:55:33 steve
* Add procedural while loops,
* Parse procedural for loops,
* Add procedural wait statements,
* Add constant nodes,
* Add XNOR logic gate,
* Make vvm output look a bit prettier.
*
* Revision 1.2 1998/11/07 17:05:05 steve
* Handle procedural conditional, and some
* of the conditional expressions.
*
* Elaborate signals and identifiers differently,
* allowing the netlist to hold signal information.
*
* Revision 1.1 1998/11/03 23:28:54 steve
* Introduce verilog to CVS.
*
*/
#endif
+7 -1
View File
@@ -17,9 +17,11 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: PFunction.cc,v 1.4 2001/01/13 22:20:08 steve Exp $"
#ident "$Id: PFunction.cc,v 1.5 2001/07/25 03:10:48 steve Exp $"
#endif
# include "config.h"
#include "PTask.h"
PFunction::PFunction()
@@ -52,6 +54,10 @@ 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.
*
+34 -7
View File
@@ -17,9 +17,11 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: PGate.cc,v 1.9 2000/05/06 15:41:56 steve Exp $"
#ident "$Id: PGate.cc,v 1.13 2001/11/22 06:20:59 steve Exp $"
#endif
# include "config.h"
# include "PGate.h"
# include "PExpr.h"
# include "verinum.h"
@@ -88,12 +90,12 @@ void PGate::elaborate_scope(Design*, NetScope*) const
* parameters. This method understands how to handle the different
* numbers of expressions.
*/
void PGate::eval_delays(Design*des, const string&path,
void PGate::eval_delays(Design*des, NetScope*scope,
unsigned long&rise_time,
unsigned long&fall_time,
unsigned long&decay_time) const
{
delay_.eval_delays(des, path, rise_time, fall_time, decay_time);
delay_.eval_delays(des, scope, rise_time, fall_time, decay_time);
}
PGAssign::PGAssign(svector<PExpr*>*pins)
@@ -140,17 +142,24 @@ void PGBuiltin::set_range(PExpr*msb, PExpr*lsb)
lsb_ = lsb;
}
PGModule::PGModule(const string&type, const string&name, svector<PExpr*>*pins)
: PGate(name, pins), type_(type), overrides_(0), pins_(0),
PGModule::PGModule(const char*type, const string&name, svector<PExpr*>*pins)
: PGate(name, pins), overrides_(0), pins_(0),
npins_(0), parms_(0), nparms_(0), msb_(0), lsb_(0)
{
type_ = strdup(type);
}
PGModule::PGModule(const string&type, const string&name,
PGModule::PGModule(const char*type, const string&name,
named<PExpr*>*pins, unsigned npins)
: PGate(name, 0), type_(type), overrides_(0), pins_(pins),
: PGate(name, 0), overrides_(0), pins_(pins),
npins_(npins), parms_(0), nparms_(0), msb_(0), lsb_(0)
{
type_ = strdup(type);
}
PGModule::~PGModule()
{
free(type_);
}
void PGModule::set_parameters(svector<PExpr*>*o)
@@ -176,8 +185,26 @@ void PGModule::set_range(PExpr*msb, PExpr*lsb)
lsb_ = lsb;
}
const char* PGModule::get_type()
{
return type_;
}
/*
* $Log: PGate.cc,v $
* Revision 1.13 2001/11/22 06:20:59 steve
* Use NetScope instead of string for scope path.
*
* Revision 1.12 2001/10/21 00:42:47 steve
* Module types in pform are char* instead of string.
*
* Revision 1.11 2001/10/19 01:55:32 steve
* Method to get the type_ member
*
* Revision 1.10 2001/07/25 03:10:48 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
*
* Revision 1.9 2000/05/06 15:41:56 steve
* Carry assignment strength to pform.
*
+27 -12
View File
@@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: PGate.h,v 1.18 2000/05/06 15:41:56 steve Exp $"
#ident "$Id: PGate.h,v 1.22 2001/11/22 06:20:59 steve Exp $"
#endif
# include "svector.h"
@@ -65,7 +65,7 @@ class PGate : public LineInfo {
const string& get_name() const { return name_; }
void eval_delays(Design*des, const string&path,
void eval_delays(Design*des, NetScope*scope,
unsigned long&rise_time,
unsigned long&fall_time,
unsigned long&decay_time) const;
@@ -82,7 +82,7 @@ class PGate : public LineInfo {
map<string,string> attributes;
virtual void dump(ostream&out) const;
virtual void elaborate(Design*des, const string&path) const;
virtual void elaborate(Design*des, NetScope*scope) const;
virtual void elaborate_scope(Design*des, NetScope*sc) const;
virtual bool elaborate_sig(Design*des, NetScope*scope) const;
@@ -116,7 +116,7 @@ class PGAssign : public PGate {
~PGAssign();
void dump(ostream&out) const;
virtual void elaborate(Design*des, const string&path) const;
virtual void elaborate(Design*des, NetScope*scope) const;
private:
};
@@ -153,7 +153,7 @@ class PGBuiltin : public PGate {
void set_range(PExpr*msb, PExpr*lsb);
virtual void dump(ostream&out) const;
virtual void elaborate(Design*, const string&path) const;
virtual void elaborate(Design*, NetScope*scope) const;
private:
Type type_;
@@ -173,15 +173,17 @@ class PGModule : public PGate {
public:
// If the binding of ports is by position, this constructor
// builds everything all at once.
explicit PGModule(const string&type, const string&name,
explicit PGModule(const char*type, const string&name,
svector<PExpr*>*pins);
// If the binding of ports is by name, this constructor takes
// the bindings and stores them for later elaboration.
explicit PGModule(const string&type, const string&name,
explicit PGModule(const char*type, const string&name,
named<PExpr*>*pins, unsigned npins);
~PGModule();
// Parameter overrides can come as an ordered list, or a set
// of named expressions.
void set_parameters(svector<PExpr*>*o);
@@ -192,12 +194,14 @@ class PGModule : public PGate {
void set_range(PExpr*msb, PExpr*lsb);
virtual void dump(ostream&out) const;
virtual void elaborate(Design*, const string&path) const;
virtual void elaborate(Design*, NetScope*scope) const;
virtual void elaborate_scope(Design*des, NetScope*sc) const;
virtual bool elaborate_sig(Design*des, NetScope*scope) const;
const char* get_type();
private:
string type_;
char* type_;
svector<PExpr*>*overrides_;
named<PExpr*>*pins_;
unsigned npins_;
@@ -210,15 +214,26 @@ class PGModule : public PGate {
PExpr*msb_;
PExpr*lsb_;
void elaborate_mod_(Design*, Module*mod, const string&path) const;
void elaborate_sudp_(Design*, PUdp *udp, const string&path) const;
void elaborate_cudp_(Design*, PUdp *udp, const string&path) const;
void elaborate_mod_(Design*, Module*mod, NetScope*scope) const;
void elaborate_udp_(Design*, PUdp *udp, NetScope*scope) const;
void elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const;
bool elaborate_sig_mod_(Design*des, NetScope*scope, Module*mod) const;
};
/*
* $Log: PGate.h,v $
* Revision 1.22 2001/11/22 06:20:59 steve
* Use NetScope instead of string for scope path.
*
* Revision 1.21 2001/10/21 00:42:47 steve
* Module types in pform are char* instead of string.
*
* Revision 1.20 2001/10/19 01:55:32 steve
* Method to get the type_ member
*
* Revision 1.19 2001/04/22 23:09:45 steve
* More UDP consolidation from Stephan Boettcher.
*
* Revision 1.18 2000/05/06 15:41:56 steve
* Carry assignment strength to pform.
*
+10 -2
View File
@@ -17,9 +17,11 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: PTask.cc,v 1.4 2001/01/13 22:20:08 steve Exp $"
#ident "$Id: PTask.cc,v 1.6 2001/07/25 03:10:48 steve Exp $"
#endif
# include "config.h"
# include "PTask.h"
PTask::PTask()
@@ -40,13 +42,19 @@ void PTask::set_ports(svector<PWire*>*p)
void PTask::set_statement(Statement*s)
{
assert(statement_ == 0);
assert(s != 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.
*
+5 -2
View File
@@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: PTask.h,v 1.10 2001/01/13 22:20:08 steve Exp $"
#ident "$Id: PTask.h,v 1.11 2001/11/22 06:20:59 steve Exp $"
#endif
# include "LineInfo.h"
@@ -52,7 +52,7 @@ class PTask : public LineInfo {
void elaborate_sig(Design*des, NetScope*scope) const;
// Elaborate the statement to finish off the task definition.
void elaborate(Design*des, const string&path) const;
void elaborate(Design*des, NetScope*scope) const;
void dump(ostream&, unsigned) const;
@@ -98,6 +98,9 @@ class PFunction : public LineInfo {
/*
* $Log: PTask.h,v $
* Revision 1.11 2001/11/22 06:20:59 steve
* Use NetScope instead of string for scope path.
*
* Revision 1.10 2001/01/13 22:20:08 steve
* Parse parameters within nested scopes.
*
+5 -2
View File
@@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: PUdp.h,v 1.4 2000/02/23 02:56:53 steve Exp $"
#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,9 @@ 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.
*
+30 -3
View File
@@ -17,14 +17,21 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: PWire.cc,v 1.5 2001/01/06 02:29:35 steve Exp $"
#ident "$Id: PWire.cc,v 1.7 2001/12/03 04:47:14 steve Exp $"
#endif
# include "config.h"
# include "PWire.h"
# include <assert.h>
PWire::PWire(const string&n, NetNet::Type t, NetNet::PortType pt)
: name_(n), type_(t), port_type_(pt), signed_(false), lidx_(0), ridx_(0)
PWire::PWire(const hname_t&n, NetNet::Type t, NetNet::PortType pt)
: hname_(n), type_(t), port_type_(pt), signed_(false), lidx_(0), ridx_(0)
{
}
PWire::PWire(char*n, NetNet::Type t, NetNet::PortType pt)
: hname_(n), type_(t), port_type_(pt), signed_(false), lidx_(0), ridx_(0)
{
}
@@ -32,6 +39,18 @@ NetNet::Type PWire::get_wire_type() const
{
return type_;
}
#if 0
string PWire::name() const
{
string name = hname_[0];
for (unsigned idx = 1 ; hname_[idx] ; idx += 1)
name = name + "." + hname_[idx];
}
#endif
const hname_t& PWire::path() const
{
return hname_;
}
bool PWire::set_wire_type(NetNet::Type t)
{
@@ -108,6 +127,14 @@ void PWire::set_memory_idx(PExpr*ldx, PExpr*rdx)
/*
* $Log: PWire.cc,v $
* Revision 1.7 2001/12/03 04:47:14 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
*
* Revision 1.6 2001/07/25 03:10:48 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
*
* Revision 1.5 2001/01/06 02:29:35 steve
* Support arrays of integers.
*
+16 -5
View File
@@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: PWire.h,v 1.10 2001/01/16 02:44:18 steve Exp $"
#ident "$Id: PWire.h,v 1.11 2001/12/03 04:47:14 steve Exp $"
#endif
# include "netlist.h"
@@ -40,14 +40,21 @@ class Design;
* Wires include nets, registers and ports. A net or register becomes
* a port by declaration, so ports are not seperate. The module
* identifies a port by keeping it in its port list.
*
* The hname parameter to the constructor is a hierarchical name. It
* is an array of strings starting with the root, running towards
* the base name, and terminated by a null pointer. The environment
* allocates the memory for me.
*/
class PWire : public LineInfo {
public:
PWire(const string&n, NetNet::Type t, NetNet::PortType pt);
PWire(const hname_t&hname, NetNet::Type t, NetNet::PortType pt);
PWire(char*name, NetNet::Type t, NetNet::PortType pt);
const string&name() const { return name_; }
// Return a hierarchical name.
//const string name() const;
const hname_t&path() const;
NetNet::Type get_wire_type() const;
bool set_wire_type(NetNet::Type);
@@ -70,7 +77,7 @@ class PWire : public LineInfo {
void elaborate_sig(Design*, NetScope*scope) const;
private:
string name_;
hname_t hname_;
NetNet::Type type_;
NetNet::PortType port_type_;
bool signed_;
@@ -92,6 +99,10 @@ class PWire : public LineInfo {
/*
* $Log: PWire.h,v $
* Revision 1.11 2001/12/03 04:47:14 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
*
* Revision 1.10 2001/01/16 02:44:18 steve
* Use the iosfwd header if available.
*
+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.
+80 -16
View File
@@ -12,11 +12,15 @@ home page at <http://www.icarus.com/eda/verilog>.
Icarus Verilog is not aimed at being a simulator in the traditional
sense, but a compiler that generates code employed by back-end
tools. These back- end tools currently include a simulator written in
C++ called VVM and an XNF (Xilinx Netlist Format) generator. See
"vvm.txt" and "xnf.txt" for further details on these back-end
processors. In the future, backends are expected for EDIF/LPM,
structural Verilog, VHDL, etc.
tools. These back-end tools currently include a simulator 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.
For instructions on how to run Icarus Verilog, see the ``iverilog''
man page.
2.0 Building/Installing Icarus Verilog From Source
@@ -32,7 +36,7 @@ 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. BSD based systems (i.e. NetBSD, FreeBSD)
typically have GNU make as the gmake program.
@@ -63,15 +67,47 @@ 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
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)
@@ -207,11 +243,16 @@ 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
@@ -223,6 +264,9 @@ Usage: ivl <options>... file
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
@@ -264,10 +308,12 @@ Usage: ivl <options>... file
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.
Normally, ivl will locate all the modules that are defined but
never instantiated, and use these as the design roots for
elaboration. This flag allows the choice of root module(s) to
be manually overridden. It can be used more than once on the
command line if multiple root modules are needed.
-T [min|typ|max]
Normally, ivl will select typ values from min:type:max
expressions and print a warning. This flag tells the compiler
@@ -277,8 +323,18 @@ Usage: ivl <options>... file
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.
-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.
-y <dir>
Add the specified directory to the library search path. If
missing modules are discovered during elaboration, ivl will
attempt to locate an implementation by searching the library
directories for a Verilog source file with the same name as
the module.
4.2 EXAMPLES
@@ -363,6 +419,7 @@ Verilog guidance, and especially testing from many people, including
Larry Doolittle <[email protected]>
Guy Hutchison <[email protected]>
Ales Hvezda <[email protected]>
Venkat Iyer <[email protected]>
Yasuhisa Kato <[email protected]>
James Lee <[email protected]>
Peter Monta <[email protected]>
@@ -388,7 +445,7 @@ 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}
*maintainer needed*
Ying-Chieh Liao <[email protected]>
Linux/{alpha,Intel} (RPMS)
Stephen Williams <[email protected]>
@@ -399,6 +456,9 @@ removed from the list) send e-mail to me.
Macintosh -- MacO/S
Yasuhisa Kato <[email protected]>
Mac O/S X
Timothy J. Wood <[email protected]>
NetBSD/*
Dan McMahill <[email protected]>
@@ -408,9 +468,13 @@ removed from the list) send e-mail to me.
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
+40 -103
View File
@@ -17,9 +17,11 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: Statement.cc,v 1.22 2000/07/26 05:08:07 steve Exp $"
#ident "$Id: Statement.cc,v 1.25 2001/12/03 04:47:14 steve Exp $"
#endif
# include "config.h"
# include "Statement.h"
# include "PExpr.h"
@@ -103,11 +105,20 @@ PBlock::~PBlock()
delete list_[idx];
}
PCallTask::PCallTask(const string&n, const svector<PExpr*>&p)
: name_(n), parms_(p)
PCallTask::PCallTask(const hname_t&n, const svector<PExpr*>&p)
: path_(n), parms_(p)
{
}
PCallTask::~PCallTask()
{
}
const hname_t& PCallTask::path() const
{
return path_;
}
PCase::PCase(NetCase::TYPE t, PExpr*ex, svector<PCase::Item*>*l)
: type_(t), expr_(ex), items_(l)
{
@@ -165,7 +176,7 @@ PDelayStatement::~PDelayStatement()
{
}
PDisable::PDisable(const string&sc)
PDisable::PDisable(const hname_t&sc)
: scope_(sc)
{
}
@@ -217,6 +228,17 @@ PForever::~PForever()
delete statement_;
}
PForStatement::PForStatement(PExpr*n1, PExpr*e1, PExpr*cond,
PExpr*n2, PExpr*e2, Statement*st)
: name1_(n1), expr1_(e1), cond_(cond), name2_(n2), expr2_(e2),
statement_(st)
{
}
PForStatement::~PForStatement()
{
}
PProcess::~PProcess()
{
delete statement_;
@@ -243,7 +265,7 @@ PRepeat::~PRepeat()
delete statement_;
}
PTrigger::PTrigger(const string&e)
PTrigger::PTrigger(const hname_t&e)
: event_(e)
{
}
@@ -252,6 +274,11 @@ PTrigger::~PTrigger()
{
}
PWhile::PWhile(PExpr*e1, Statement*st)
: cond_(e1), statement_(st)
{
}
PWhile::~PWhile()
{
delete cond_;
@@ -260,105 +287,15 @@ PWhile::~PWhile()
/*
* $Log: Statement.cc,v $
* Revision 1.22 2000/07/26 05:08:07 steve
* Parse disable statements to pform.
* Revision 1.25 2001/12/03 04:47:14 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
*
* Revision 1.21 2000/05/11 23:37:26 steve
* Add support for procedural continuous assignment.
*
* Revision 1.20 2000/04/22 04:20:19 steve
* Add support for force assignment.
*
* Revision 1.19 2000/04/12 04:23:57 steve
* Named events really should be expressed with PEIdent
* objects in the pform,
*
* Handle named events within the mix of net events
* and edges. As a unified lot they get caught together.
* wait statements are broken into more complex statements
* that include a conditional.
*
* Do not generate NetPEvent or NetNEvent objects in
* elaboration. NetEvent, NetEvWait and NetEvProbe
* take over those functions in the netlist.
*
* Revision 1.18 2000/04/01 19:31:57 steve
* Named events as far as the pform.
*
* Revision 1.17 2000/02/23 02:56:54 steve
* Macintosh compilers do not support ident.
*
* Revision 1.16 1999/09/29 18:36:02 steve
* Full case support
*
* Revision 1.15 1999/09/22 02:00:48 steve
* assignment with blocking event delay.
*
* Revision 1.14 1999/09/04 19:11:46 steve
* Add support for delayed non-blocking assignments.
*
* Revision 1.13 1999/09/02 01:59:27 steve
* Parse non-blocking assignment delays.
*
* Revision 1.12 1999/07/12 00:59:36 steve
* procedural blocking assignment delays.
*
* Revision 1.11 1999/06/24 04:24:18 steve
* Handle expression widths for EEE and NEE operators,
* add named blocks and scope handling,
* add registers declared in named blocks.
*
* Revision 1.10 1999/06/19 21:06:16 steve
* Elaborate and supprort to vvm the forever
* and repeat statements.
*
* Revision 1.9 1999/06/15 05:38:39 steve
* Support case expression lists.
*
* Revision 1.8 1999/06/13 23:51:16 steve
* l-value part select for procedural assignments.
*
* Revision 1.7 1999/06/06 20:45:38 steve
* Add parse and elaboration of non-blocking assignments,
* Replace list<PCase::Item*> with an svector version,
* Add integer support.
*
* Revision 1.6 1999/05/10 00:16:58 steve
* Parse and elaborate the concatenate operator
* in structural contexts, Replace vector<PExpr*>
* and list<PExpr*> with svector<PExpr*>, evaluate
* constant expressions with parameters, handle
* memories as lvalues.
*
* Parse task declarations, integer types.
*
* Revision 1.5 1999/02/03 04:20:11 steve
* Parse and elaborate the Verilog CASE statement.
*
* Revision 1.4 1999/01/25 05:45:56 steve
* Add the LineInfo class to carry the source file
* location of things. PGate, Statement and PProcess.
*
* elaborate handles module parameter mismatches,
* missing or incorrect lvalues for procedural
* assignment, and errors are propogated to the
* top of the elaboration call tree.
*
* Attach line numbers to processes, gates and
* assignment statements.
*
* Revision 1.3 1998/11/11 03:13:04 steve
* Handle while loops.
*
* Revision 1.2 1998/11/07 17:05:05 steve
* Handle procedural conditional, and some
* of the conditional expressions.
*
* Elaborate signals and identifiers differently,
* allowing the netlist to hold signal information.
*
* Revision 1.1 1998/11/03 23:28:55 steve
* Introduce verilog to CVS.
* Revision 1.24 2001/11/22 06:20:59 steve
* Use NetScope instead of string for scope path.
*
* Revision 1.23 2001/07/25 03:10:48 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
*/
+44 -139
View File
@@ -19,13 +19,14 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: Statement.h,v 1.29 2000/09/09 15:21:26 steve Exp $"
#ident "$Id: Statement.h,v 1.31 2001/12/03 04:47:14 steve Exp $"
#endif
# include <string>
# include "svector.h"
# include "PDelays.h"
# include "PExpr.h"
# include "HName.h"
# include "LineInfo.h"
class PExpr;
class Statement;
@@ -74,7 +75,7 @@ class Statement : public LineInfo {
virtual ~Statement() =0;
virtual void dump(ostream&out, unsigned ind) const;
virtual NetProc* elaborate(Design*des, const string&path) const;
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
virtual void elaborate_scope(Design*des, NetScope*scope) const;
};
@@ -113,11 +114,11 @@ class PAssign : public PAssign_ {
~PAssign();
virtual void dump(ostream&out, unsigned ind) const;
virtual NetProc* elaborate(Design*des, const string&path) const;
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
private:
NetProc*assign_to_memory_(class NetMemory*, PExpr*,
Design*des, const string&path) const;
Design*des, NetScope*scope) const;
};
class PAssignNB : public PAssign_ {
@@ -128,11 +129,11 @@ class PAssignNB : public PAssign_ {
~PAssignNB();
virtual void dump(ostream&out, unsigned ind) const;
virtual NetProc* elaborate(Design*des, const string&path) const;
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
private:
NetProc*assign_to_memory_(class NetMemory*, PExpr*,
Design*des, const string&path) const;
Design*des, NetScope*scope) const;
};
/*
@@ -154,11 +155,9 @@ class PBlock : public Statement {
BL_TYPE bl_type() const { return bl_type_; }
//unsigned size() const { return list_.count(); }
//const Statement*stat(unsigned idx) const { return list_[idx]; }
virtual void dump(ostream&out, unsigned ind) const;
virtual NetProc* elaborate(Design*des, const string&path) const;
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
virtual void elaborate_scope(Design*des, NetScope*scope) const;
private:
@@ -170,9 +169,10 @@ class PBlock : public Statement {
class PCallTask : public Statement {
public:
explicit PCallTask(const string&n, const svector<PExpr*>&parms);
explicit PCallTask(const hname_t&n, const svector<PExpr*>&parms);
~PCallTask();
string name() const { return name_; }
const hname_t& path() const;
unsigned nparms() const { return parms_.count(); }
@@ -187,13 +187,13 @@ class PCallTask : public Statement {
}
virtual void dump(ostream&out, unsigned ind) const;
virtual NetProc* elaborate(Design*des, const string&path) const;
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
private:
NetProc* elaborate_sys(Design*des, const string&path) const;
NetProc* elaborate_usr(Design*des, const string&path) const;
NetProc* elaborate_sys(Design*des, NetScope*scope) const;
NetProc* elaborate_usr(Design*des, NetScope*scope) const;
const string name_;
hname_t path_;
svector<PExpr*> parms_;
};
@@ -208,7 +208,7 @@ class PCase : public Statement {
PCase(NetCase::TYPE, PExpr*ex, svector<Item*>*);
~PCase();
virtual NetProc* elaborate(Design*des, const string&path) const;
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
virtual void elaborate_scope(Design*des, NetScope*scope) const;
virtual void dump(ostream&out, unsigned ind) const;
@@ -229,7 +229,7 @@ class PCAssign : public Statement {
explicit PCAssign(PExpr*l, PExpr*r);
~PCAssign();
virtual NetCAssign* elaborate(Design*des, const string&path) const;
virtual NetCAssign* elaborate(Design*des, NetScope*scope) const;
virtual void dump(ostream&out, unsigned ind) const;
private:
@@ -243,7 +243,7 @@ class PCondit : public Statement {
PCondit(PExpr*ex, Statement*i, Statement*e);
~PCondit();
virtual NetProc* elaborate(Design*des, const string&path) const;
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
virtual void elaborate_scope(Design*des, NetScope*scope) const;
virtual void dump(ostream&out, unsigned ind) const;
@@ -263,7 +263,7 @@ class PDeassign : public Statement {
explicit PDeassign(PExpr*l);
~PDeassign();
virtual NetDeassign* elaborate(Design*des, const string&path) const;
virtual NetDeassign* elaborate(Design*des, NetScope*scope) const;
virtual void dump(ostream&out, unsigned ind) const;
private:
@@ -277,7 +277,7 @@ class PDelayStatement : public Statement {
~PDelayStatement();
virtual void dump(ostream&out, unsigned ind) const;
virtual NetProc* elaborate(Design*des, const string&path) const;
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
virtual void elaborate_scope(Design*des, NetScope*scope) const;
private:
@@ -292,14 +292,14 @@ class PDelayStatement : public Statement {
class PDisable : public Statement {
public:
explicit PDisable(const string&sc);
explicit PDisable(const hname_t&sc);
~PDisable();
virtual void dump(ostream&out, unsigned ind) const;
virtual NetProc* elaborate(Design*des, const string&path) const;
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
private:
string scope_;
hname_t scope_;
};
/*
@@ -321,12 +321,12 @@ class PEventStatement : public Statement {
void set_statement(Statement*st);
virtual void dump(ostream&out, unsigned ind) const;
virtual NetProc* elaborate(Design*des, const string&path) const;
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
virtual void elaborate_scope(Design*des, NetScope*scope) const;
// This method is used to elaborate, but attach a previously
// elaborated statement to the event.
NetProc* elaborate_st(Design*des, const string&path, NetProc*st) const;
NetProc* elaborate_st(Design*des, NetScope*scope, NetProc*st) const;
private:
svector<PEEvent*>expr_;
@@ -339,7 +339,7 @@ class PForce : public Statement {
explicit PForce(PExpr*l, PExpr*r);
~PForce();
virtual NetProc* elaborate(Design*des, const string&path) const;
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
virtual void dump(ostream&out, unsigned ind) const;
private:
@@ -352,7 +352,7 @@ class PForever : public Statement {
explicit PForever(Statement*s);
~PForever();
virtual NetProc* elaborate(Design*des, const string&path) const;
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
virtual void elaborate_scope(Design*des, NetScope*scope) const;
virtual void dump(ostream&out, unsigned ind) const;
@@ -364,12 +364,10 @@ class PForStatement : public Statement {
public:
PForStatement(PExpr*n1, PExpr*e1, PExpr*cond,
PExpr*n2, PExpr*e2, Statement*st)
: name1_(n1), expr1_(e1), cond_(cond), name2_(n2), expr2_(e2),
statement_(st)
{ }
PExpr*n2, PExpr*e2, Statement*st);
~PForStatement();
virtual NetProc* elaborate(Design*des, const string&path) const;
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
virtual void elaborate_scope(Design*des, NetScope*scope) const;
virtual void dump(ostream&out, unsigned ind) const;
@@ -396,7 +394,7 @@ class PRepeat : public Statement {
explicit PRepeat(PExpr*expr, Statement*s);
~PRepeat();
virtual NetProc* elaborate(Design*des, const string&path) const;
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
virtual void elaborate_scope(Design*des, NetScope*scope) const;
virtual void dump(ostream&out, unsigned ind) const;
@@ -411,7 +409,7 @@ class PRelease : public Statement {
explicit PRelease(PExpr*l);
~PRelease();
virtual NetProc* elaborate(Design*des, const string&path) const;
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
virtual void dump(ostream&out, unsigned ind) const;
private:
@@ -425,24 +423,23 @@ class PRelease : public Statement {
class PTrigger : public Statement {
public:
explicit PTrigger(const string&ev);
explicit PTrigger(const hname_t&ev);
~PTrigger();
virtual NetProc* elaborate(Design*des, const string&path) const;
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
virtual void dump(ostream&out, unsigned ind) const;
private:
string event_;
hname_t event_;
};
class PWhile : public Statement {
public:
PWhile(PExpr*e1, Statement*st)
: cond_(e1), statement_(st) { }
PWhile(PExpr*e1, Statement*st);
~PWhile();
virtual NetProc* elaborate(Design*des, const string&path) const;
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
virtual void elaborate_scope(Design*des, NetScope*scope) const;
virtual void dump(ostream&out, unsigned ind) const;
@@ -453,6 +450,13 @@ class PWhile : public Statement {
/*
* $Log: Statement.h,v $
* Revision 1.31 2001/12/03 04:47:14 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
*
* Revision 1.30 2001/11/22 06:20:59 steve
* Use NetScope instead of string for scope path.
*
* Revision 1.29 2000/09/09 15:21:26 steve
* move lval elaboration to PExpr virtual methods.
*
@@ -480,104 +484,5 @@ class PWhile : public Statement {
* Do not generate NetPEvent or NetNEvent objects in
* elaboration. NetEvent, NetEvWait and NetEvProbe
* take over those functions in the netlist.
*
* Revision 1.23 2000/04/01 19:31:57 steve
* Named events as far as the pform.
*
* Revision 1.22 2000/03/11 03:25:51 steve
* Locate scopes in statements.
*
* Revision 1.21 2000/02/23 02:56:54 steve
* Macintosh compilers do not support ident.
*
* Revision 1.20 1999/09/29 18:36:02 steve
* Full case support
*
* Revision 1.19 1999/09/22 02:00:48 steve
* assignment with blocking event delay.
*
* Revision 1.18 1999/09/15 01:55:06 steve
* Elaborate non-blocking assignment to memories.
*
* Revision 1.17 1999/09/04 19:11:46 steve
* Add support for delayed non-blocking assignments.
*
* Revision 1.16 1999/09/02 01:59:27 steve
* Parse non-blocking assignment delays.
*
* Revision 1.15 1999/07/12 00:59:36 steve
* procedural blocking assignment delays.
*
* Revision 1.14 1999/07/03 02:12:51 steve
* Elaborate user defined tasks.
*
* Revision 1.13 1999/06/24 04:24:18 steve
* Handle expression widths for EEE and NEE operators,
* add named blocks and scope handling,
* add registers declared in named blocks.
*
* Revision 1.12 1999/06/19 21:06:16 steve
* Elaborate and supprort to vvm the forever
* and repeat statements.
*
* Revision 1.11 1999/06/15 05:38:39 steve
* Support case expression lists.
*
* Revision 1.10 1999/06/13 23:51:16 steve
* l-value part select for procedural assignments.
*
* Revision 1.9 1999/06/06 20:45:38 steve
* Add parse and elaboration of non-blocking assignments,
* Replace list<PCase::Item*> with an svector version,
* Add integer support.
*
* Revision 1.8 1999/05/10 00:16:58 steve
* Parse and elaborate the concatenate operator
* in structural contexts, Replace vector<PExpr*>
* and list<PExpr*> with svector<PExpr*>, evaluate
* constant expressions with parameters, handle
* memories as lvalues.
*
* Parse task declarations, integer types.
*
* Revision 1.7 1999/04/29 02:16:26 steve
* Parse OR of event expressions.
*
* Revision 1.6 1999/02/03 04:20:11 steve
* Parse and elaborate the Verilog CASE statement.
*
* Revision 1.5 1999/01/25 05:45:56 steve
* Add the LineInfo class to carry the source file
* location of things. PGate, Statement and PProcess.
*
* elaborate handles module parameter mismatches,
* missing or incorrect lvalues for procedural
* assignment, and errors are propogated to the
* top of the elaboration call tree.
*
* Attach line numbers to processes, gates and
* assignment statements.
*
* Revision 1.4 1998/11/11 03:13:04 steve
* Handle while loops.
*
* Revision 1.3 1998/11/09 18:55:33 steve
* Add procedural while loops,
* Parse procedural for loops,
* Add procedural wait statements,
* Add constant nodes,
* Add XNOR logic gate,
* Make vvm output look a bit prettier.
*
* Revision 1.2 1998/11/07 17:05:05 steve
* Handle procedural conditional, and some
* of the conditional expressions.
*
* Elaborate signals and identifiers differently,
* allowing the netlist to hold signal information.
*
* Revision 1.1 1998/11/03 23:28:56 steve
* Introduce verilog to CVS.
*
*/
#endif
+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
+16 -1
View File
@@ -19,9 +19,11 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: compiler.h,v 1.5 2000/10/31 17:49:02 steve Exp $"
#ident "$Id: compiler.h,v 1.7 2001/11/16 05:07:19 steve Exp $"
#endif
# include <list>
/*
* This defines constants and defaults for the compiler in general.
*/
@@ -66,8 +68,21 @@
/* Implicit definitions of wires. */
extern bool warn_implicit;
/* This is true if verbose output is requested. */
extern bool verbose_flag;
/* This is an ordered list of libraries to search. */
extern list<const char*>library_dirs;
extern list<const char*>library_suff;
/*
* $Log: compiler.h,v $
* Revision 1.7 2001/11/16 05:07:19 steve
* Add support for +libext+ in command files.
*
* Revision 1.6 2001/10/20 23:02:40 steve
* Add automatic module libraries.
*
* Revision 1.5 2000/10/31 17:49:02 steve
* Support time variables.
*
+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.
+60
View File
@@ -0,0 +1,60 @@
#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.3 2001/10/18 16:16:23 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_MALLOC_H
# undef HAVE_DLFCN_H
# undef HAVE_DL_H
# undef HAVE_FCHMOD
# undef HAVE_LIBREADLINE
# undef HAVE_SYS_WAIT_H
/*
* $Log: config.h.in,v $
* Revision 1.3 2001/10/18 16:16:23 steve
* Include HAVE_SYS_WAIT in config.h (PR#306)
*
* Revision 1.2 2001/09/15 18:27:04 steve
* Make configure detect malloc.h
*
* Revision 1.1 2001/07/25 03:10:48 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
*
*/
#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/"`
;;
+76 -4
View File
@@ -1,16 +1,41 @@
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_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)
AC_CHECK_HEADERS(getopt.h malloc.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)
# --
@@ -41,9 +66,20 @@ AC_CANONICAL_HOST
AC_CYGWIN
AC_EXEEXT
AC_SUBST(CYGWIN)
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){}
@@ -54,7 +90,7 @@ CC_LEADING_UNDERSCORE=no
CC_TRAILING_UNDERSCORE=no
output=`nm underscore.o|grep _underscore 2>&1`
if test ! -z "$output" -a -z "$CYGWIN" ; then
if test ! -z "$output" -a -z "$CYGWIN" -a -z "$MINGW32"; then
CC_LEADING_UNDERSCORE=yes
AC_DEFINE(NEED_LU)
fi
@@ -102,6 +138,26 @@ AC_SUBST(PICFLAG)
AC_MSG_RESULT($PICFLAG)
# mingw needs to link with libiberty.a, cygwin can tolerate it
AC_MSG_CHECKING("for extra libs needed")
EXTRALIBS=
case "${host}" in
*-*-cygwin*)
EXTRALIBS="-liberty"
;;
esac
AC_SUBST(EXTRALIBS)
AC_MSG_RESULT($EXTRALIBS)
# Darwin requires -no-cpp-precomp
case "${host}" in
*-*-darwin*)
CPPFLAGS="-no-cpp-precomp"
CFLAGS="-no-cpp-precomp"
;;
esac
# The -rdynamic flag is used by iverilog when compiling the target,
# to know how to export symbols of the main program to loadable modules
# that are brought in by -ldl
@@ -125,22 +181,37 @@ case "${host}" in
*-*-hpux*)
rdynamic="-E"
;;
*-*-darwin*)
rdynamic="-Wl,-all_load"
strip_dynamic="-SX"
;;
esac
AC_SUBST(rdynamic)
AC_MSG_RESULT($rdynamic)
AC_SUBST(strip_dynamic)
AC_MSG_RESULT($strip_dynamic)
AC_MSG_CHECKING("for shared library link flag")
shared=-shared
case "${host}" in
*-*-cygwin*)
shared="-mdll -Wl,--enable-auto-image-base"
shared="-shared -Wl,--enable-auto-image-base"
;;
*-*-hpux*)
shared="-b"
;;
*-*-darwin1.[0123])
shared="-bundle -undefined suppress"
;;
*-*-darwin*)
shared="-bundle -undefined suppress -flat_namespace"
;;
esac
AC_SUBST(shared)
@@ -148,5 +219,6 @@ 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)
+178 -25
View File
@@ -17,9 +17,11 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: cprop.cc,v 1.23 2000/12/30 03:11:15 steve Exp $"
#ident "$Id: cprop.cc,v 1.30 2001/10/28 01:14:53 steve Exp $"
#endif
# include "config.h"
# include "netlist.h"
# include "netmisc.h"
# include "functor.h"
@@ -38,12 +40,19 @@ struct cprop_functor : public functor_t {
unsigned count;
virtual void signal(Design*des, NetNet*obj);
virtual void lpm_add_sub(Design*des, NetAddSub*obj);
virtual void lpm_compare(Design*des, NetCompare*obj);
virtual void lpm_compare_eq_(Design*des, NetCompare*obj);
virtual void lpm_ff(Design*des, NetFF*obj);
virtual void lpm_logic(Design*des, NetLogic*obj);
virtual void lpm_mux(Design*des, NetMux*obj);
};
void cprop_functor::signal(Design*des, NetNet*obj)
{
}
void cprop_functor::lpm_add_sub(Design*des, NetAddSub*obj)
{
// For now, only additions are handled.
@@ -59,7 +68,7 @@ void cprop_functor::lpm_add_sub(Design*des, NetAddSub*obj)
&& (driven_value(obj->pin_DataA(0)) == verinum::V0)) {
NetAddSub*tmp = 0;
tmp = new NetAddSub(obj->name(), obj->width()-1);
tmp = new NetAddSub(obj->scope(), obj->name(), obj->width()-1);
//connect(tmp->pin_Aclr(), obj->pin_Aclr());
//connect(tmp->pin_Add_Sub(), obj->pin_Add_Sub());
//connect(tmp->pin_Clock(), obj->pin_Clock());
@@ -84,7 +93,7 @@ void cprop_functor::lpm_add_sub(Design*des, NetAddSub*obj)
&& (driven_value(obj->pin_DataB(0)) == verinum::V0)) {
NetAddSub*tmp = 0;
tmp = new NetAddSub(obj->name(), obj->width()-1);
tmp = new NetAddSub(obj->scope(), obj->name(), obj->width()-1);
//connect(tmp->pin_Aclr(), obj->pin_Aclr());
//connect(tmp->pin_Add_Sub(), obj->pin_Add_Sub());
//connect(tmp->pin_Clock(), obj->pin_Clock());
@@ -128,6 +137,111 @@ void cprop_functor::lpm_add_sub(Design*des, NetAddSub*obj)
}
void cprop_functor::lpm_compare(Design*des, NetCompare*obj)
{
if (obj->pin_AEB().is_linked()) {
assert( ! obj->pin_AGB().is_linked() );
assert( ! obj->pin_AGEB().is_linked() );
assert( ! obj->pin_ALB().is_linked() );
assert( ! obj->pin_ALEB().is_linked() );
assert( ! obj->pin_AGB().is_linked() );
assert( ! obj->pin_ANEB().is_linked() );
lpm_compare_eq_(des, obj);
return;
}
}
void cprop_functor::lpm_compare_eq_(Design*des, NetCompare*obj)
{
NetScope*scope = obj->scope();
/* First, look for the case where constant bits on matching A
and B inputs are different. This this is so, the device can
be completely eliminated and replaced with a constant 0. */
for (unsigned idx = 0 ; idx < obj->width() ; idx += 1) {
if (! link_drivers_constant(obj->pin_DataA(idx)))
continue;
if (! link_drivers_constant(obj->pin_DataB(idx)))
continue;
if (driven_value(obj->pin_DataA(idx)) ==
driven_value(obj->pin_DataB(idx)))
continue;
NetConst*zero = new NetConst(scope, obj->name(), verinum::V0);
connect(zero->pin(0), obj->pin_AEB());
delete obj;
des->add_node(zero);
count += 1;
return;
}
/* Still may need the gate. Run through the inputs again, and
look for pairs of constants. Those inputs can be removed. */
unsigned top = obj->width();
for (unsigned idx = 0 ; idx < top ; ) {
if (! link_drivers_constant(obj->pin_DataA(idx))) {
idx += 1;
continue;
}
if (! link_drivers_constant(obj->pin_DataB(idx))) {
idx += 1;
continue;
}
obj->pin_DataA(idx).unlink();
obj->pin_DataB(idx).unlink();
top -= 1;
for (unsigned jj = idx ; jj < top ; jj += 1) {
connect(obj->pin_DataA(jj), obj->pin_DataA(jj+1));
connect(obj->pin_DataB(jj), obj->pin_DataB(jj+1));
obj->pin_DataA(jj+1).unlink();
obj->pin_DataB(jj+1).unlink();
}
}
/* If we wound up disconnecting all the inputs, then remove
the device and replace it with a constant. */
if (top == 0) {
NetConst*one = new NetConst(scope, obj->name(), verinum::V1);
connect(one->pin(0), obj->pin_AEB());
delete obj;
des->add_node(one);
count += 1;
return;
}
/* If there is only one bit left, then replace the comparator
with a simple XOR gate. */
if (top == 1) {
NetLogic*tmp = new NetLogic(scope, obj->name(), 3,
NetLogic::XOR);
connect(tmp->pin(0), obj->pin_AEB());
connect(tmp->pin(1), obj->pin_DataA(0));
connect(tmp->pin(2), obj->pin_DataB(0));
delete obj;
des->add_node(tmp);
count += 1;
return;
}
if (top == obj->width())
return;
NetCompare*tmp = new NetCompare(scope, obj->name(), top);
connect(tmp->pin_AEB(), obj->pin_AEB());
for (unsigned idx = 0 ; idx < top ; idx += 1) {
connect(tmp->pin_DataA(idx), obj->pin_DataA(idx));
connect(tmp->pin_DataB(idx), obj->pin_DataB(idx));
}
delete obj;
des->add_node(tmp);
count += 1;
}
void cprop_functor::lpm_ff(Design*des, NetFF*obj)
{
// Look for and count unlinked FF outputs. Note that if the
@@ -182,6 +296,8 @@ void cprop_functor::lpm_ff(Design*des, NetFF*obj)
void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
{
NetScope*scope = obj->scope();
switch (obj->type()) {
case NetLogic::NAND:
@@ -223,10 +339,10 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
NetConst*tmp;
switch (obj->type()) {
case NetLogic::AND:
tmp = new NetConst(obj->name(), verinum::V0);
tmp = new NetConst(scope, obj->name(), verinum::V0);
break;
case NetLogic::NAND:
tmp = new NetConst(obj->name(), verinum::V1);
tmp = new NetConst(scope, obj->name(), verinum::V1);
break;
default:
assert(0);
@@ -248,10 +364,10 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
NetConst*tmp;
switch (obj->type()) {
case NetLogic::AND:
tmp = new NetConst(obj->name(), verinum::V1);
tmp = new NetConst(scope, obj->name(), verinum::V1);
break;
case NetLogic::NAND:
tmp = new NetConst(obj->name(), verinum::V0);
tmp = new NetConst(scope, obj->name(), verinum::V0);
break;
default:
assert(0);
@@ -271,7 +387,7 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
gate with a Vx. */
if (xs == (top-1)) {
NetConst*tmp;
tmp = new NetConst(obj->name(), verinum::Vx);
tmp = new NetConst(scope, obj->name(), verinum::Vx);
des->add_node(tmp);
tmp->pin(0).drive0(obj->pin(0).drive0());
tmp->pin(0).drive1(obj->pin(0).drive1());
@@ -288,12 +404,12 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
NetLogic*tmp;
switch (obj->type()) {
case NetLogic::AND:
tmp = new NetLogic(obj->scope(),
tmp = new NetLogic(scope,
obj->name(), 2,
NetLogic::BUF);
break;
case NetLogic::NAND:
tmp = new NetLogic(obj->scope(),
tmp = new NetLogic(scope,
obj->name(), 2,
NetLogic::NOT);
break;
@@ -314,7 +430,7 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
new [N]OR gate that has the right number of
inputs, connected in the right place. */
if (top < obj->pin_count()) {
NetLogic*tmp = new NetLogic(obj->scope(),
NetLogic*tmp = new NetLogic(scope,
obj->name(), top,
obj->type());
des->add_node(tmp);
@@ -369,10 +485,10 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
NetConst*tmp;
switch (obj->type()) {
case NetLogic::OR:
tmp = new NetConst(obj->name(), verinum::V1);
tmp = new NetConst(scope, obj->name(), verinum::V1);
break;
case NetLogic::NOR:
tmp = new NetConst(obj->name(), verinum::V0);
tmp = new NetConst(scope, obj->name(), verinum::V0);
break;
default:
assert(0);
@@ -394,10 +510,10 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
NetConst*tmp;
switch (obj->type()) {
case NetLogic::OR:
tmp = new NetConst(obj->name(), verinum::V0);
tmp = new NetConst(scope, obj->name(), verinum::V0);
break;
case NetLogic::NOR:
tmp = new NetConst(obj->name(), verinum::V1);
tmp = new NetConst(scope, obj->name(), verinum::V1);
break;
default:
assert(0);
@@ -419,12 +535,12 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
NetLogic*tmp;
switch (obj->type()) {
case NetLogic::OR:
tmp = new NetLogic(obj->scope(),
tmp = new NetLogic(scope,
obj->name(), 2,
NetLogic::BUF);
break;
case NetLogic::NOR:
tmp = new NetLogic(obj->scope(),
tmp = new NetLogic(scope,
obj->name(), 2,
NetLogic::NOT);
break;
@@ -445,7 +561,7 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
new [N]OR gate that has the right number of
inputs, connected in the right place. */
if (top < obj->pin_count()) {
NetLogic*tmp = new NetLogic(obj->scope(),
NetLogic*tmp = new NetLogic(scope,
obj->name(), top,
obj->type());
des->add_node(tmp);
@@ -540,7 +656,7 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
verinum::V out = obj->type()==NetLogic::XNOR
? verinum::V1
: verinum::V0;
NetConst*tmp = new NetConst(obj->name(), out);
NetConst*tmp = new NetConst(scope, obj->name(), out);
des->add_node(tmp);
tmp->pin(0).drive0(obj->pin(0).drive0());
@@ -568,11 +684,11 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
NetLogic*tmp;
if (obj->type() == NetLogic::XOR)
tmp = new NetLogic(obj->scope(),
tmp = new NetLogic(scope,
obj->name(), 2,
NetLogic::NOT);
else
tmp = new NetLogic(obj->scope(),
tmp = new NetLogic(scope,
obj->name(), 2,
NetLogic::BUF);
@@ -593,11 +709,11 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
NetLogic*tmp;
if (obj->type() == NetLogic::XOR)
tmp = new NetLogic(obj->scope(),
tmp = new NetLogic(scope,
obj->name(), 2,
NetLogic::BUF);
else
tmp = new NetLogic(obj->scope(),
tmp = new NetLogic(scope,
obj->name(), 2,
NetLogic::NOT);
@@ -615,7 +731,7 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
new XOR gate that has the right number of
inputs, connected in the right place. */
if (top < obj->pin_count()) {
NetLogic*tmp = new NetLogic(obj->scope(),
NetLogic*tmp = new NetLogic(scope,
obj->name(), top,
obj->type());
des->add_node(tmp);
@@ -783,7 +899,22 @@ void cprop_dc_functor::lpm_const(Design*des, NetConst*obj)
clnk->cur_link(cur, pin);
NetNet*tmp = dynamic_cast<NetNet*>(cur);
if (tmp && tmp->get_eref() > 0)
if (tmp == 0)
continue;
assert(tmp->scope());
// If the net has an eref, then there is an
// expression somewhere that reads this signal. So
// the constant does get read.
if (tmp->get_eref() > 0)
return;
// If the net is a port of the root module, then
// the constant may be driving something outside
// the design, so do not eliminate it.
if ((tmp->port_type() != NetNet::NOT_A_PORT)
&& (tmp->scope()->parent() == 0))
return;
}
@@ -811,6 +942,28 @@ void cprop(Design*des)
/*
* $Log: cprop.cc,v $
* Revision 1.30 2001/10/28 01:14:53 steve
* NetObj constructor finally requires a scope.
*
* Revision 1.29 2001/07/25 03:10:48 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
*
* Revision 1.28 2001/06/15 04:14:18 steve
* Generate vvp code for GT and GE comparisons.
*
* Revision 1.27 2001/06/07 02:12:43 steve
* Support structural addition.
*
* Revision 1.26 2001/02/18 01:07:32 steve
* check signals in the cprop functor.
*
* Revision 1.25 2001/02/16 03:27:31 steve
* Constant propagation for compare ==.
*
* Revision 1.24 2001/02/10 04:50:54 steve
* Catch constants driving root module ports. (PR#130)
*
* Revision 1.23 2000/12/30 03:11:15 steve
* Propagate initial value of constants into wires.
*
+2 -26
View File
@@ -6,41 +6,17 @@ To build using cygwin:
Prerequisites:
o Latest net release (1.1.4) of cygwin (sources.redhat.com/cygwin)
o autoconf version 2.13 (or later) from cygutils (cygutils.netpedia.net)
o cvs (1.10.8 or later) also from cygutils
Procedure:
o Get the source code - see the main icarus verilog page for how to
do this
o cd to the verilog directory
o autoconf
o autoconf.sh
o ./configure
o make
o make install
That's all that's needed. But there're two common problems during
the make phase. All steps are in the verilog directory.
1.
If gcc dies saying virtual memory exhausted while compiling parse.c
then recompile with -O1 or without -O flag and do these steps to
continue
o make CXXFLAGS='' parse.o
o make
2.
If gcc dies in the vpi directory while compiling vpi_systask.c with the
error, conflicting types for `_cygwin_dll_entry', then fix the line in
/usr/include/cygwin/cygwin_dll.h. Change the line:
int WINAPI _cygwin_dll_entry (HANDLE h, DWORD reason, void *ptr); \
to
int WINAPI _cygwin_dll_entry (HINSTANCE h, DWORD reason, void *ptr); \
Note the change from HANDLE to HINSTANCE. Then do
o make
That's all that's needed.
To build your own extensions - just include vpi_user.h and link with
a command like this:
+97 -87
View File
@@ -17,9 +17,11 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: design_dump.cc,v 1.110 2001/01/18 03:16:35 steve Exp $"
#ident "$Id: design_dump.cc,v 1.120 2001/12/03 04:47:14 steve Exp $"
#endif
# include "config.h"
/*
* This file contains all the dump methods of the netlist classes.
*/
@@ -75,6 +77,22 @@ void NetNet::dump_net(ostream&o, unsigned ind) const
o << " (local)";
if (signed_)
o << " signed";
switch (port_type_) {
case NetNet::NOT_A_PORT:
break;
case NetNet::PIMPLICIT:
o << " implicit-port?";
break;
case NetNet::PINPUT:
o << " input";
break;
case NetNet::POUTPUT:
o << " output";
break;
case NetNet::PINOUT:
o << " inout";
break;
}
o << " (eref=" << get_eref() << ")";
if (scope())
o << " scope=" << scope()->name();
@@ -219,15 +237,6 @@ void NetMux::dump_node(ostream&o, unsigned ind) const
dump_obj_attr(o, ind+4);
}
void NetAssign_::dump_node(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "Procedural assign (NetAssign_): " << name();
if (bmux())
o << "[" << *bmux() << "]";
o << endl;
dump_node_pins(o, ind+4);
}
void NetBUFZ::dump_node(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "NetBUFZ: " << name()
@@ -298,6 +307,12 @@ void NetLogic::dump_node(ostream&o, unsigned ind) const
case OR:
o << "or";
break;
case PULLDOWN:
o << "pulldown";
break;
case PULLUP:
o << "pullup";
break;
case RNMOS:
o << "rnmos";
break;
@@ -344,6 +359,7 @@ void NetTaskDef::dump(ostream&o, unsigned ind) const
for (unsigned idx = 0 ; idx < ports_.count() ; idx += 1) {
o << setw(ind+4) << "";
assert(ports_[idx]);
switch (ports_[idx]->port_type()) {
case NetNet::PINPUT:
o << "input ";
@@ -366,77 +382,12 @@ void NetTaskDef::dump(ostream&o, unsigned ind) const
o << setw(ind) << "" << "endtask" << endl;
}
void NetUDP::dump_sequ_(ostream&o, unsigned ind) const
{
string tmp = "";
for (unsigned idx = 0 ; idx < ind ; idx += 1)
tmp += " ";
o << tmp << "Sequential UDP" << " #(" << rise_time() <<
"," << fall_time() << "," << decay_time() << ") " << name() <<
endl;
for (FSM_::const_iterator ent = fsm_.begin()
; ent != fsm_.end() ; ent++) {
o << setw(ind+6) << "" << (*ent).first << " -->";
state_t_*st = (*ent).second;
assert((*ent).first[0] == st->out);
for (unsigned idx = 1 ; idx < pin_count() ; idx += 1) {
string tmp = (*ent).first;
if (st->pins[idx].zer) {
tmp[0] = st->pins[idx].zer->out;
tmp[idx] = '0';
o << " " << tmp;
}
if (st->pins[idx].one) {
tmp[0] = st->pins[idx].one->out;
tmp[idx] = '1';
o << " " << tmp;
}
if (st->pins[idx].xxx) {
tmp[0] = st->pins[idx].xxx->out;
tmp[idx] = 'x';
o << " " << tmp;
}
}
o << endl;
}
o << setw(ind+6) << "" << "initial value == " << init_ << endl;
dump_node_pins(o, ind+4);
dump_obj_attr(o, ind+4);
}
void NetUDP::dump_comb_(ostream&o, unsigned ind) const
{
assert(0);
}
void NetUDP::dump_node(ostream&o, unsigned ind) const
{
if (is_sequential())
dump_sequ_(o, ind);
else
dump_comb_(o, ind);
}
void NetUDP_COMB::dump_node(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "Combinational primitive: ";
o << setw(ind) << "" << "UDP (" << udp_name() << "): ";
o << " #(" << rise_time() << "," << fall_time() << "," << decay_time() <<
") " << name() << endl;
for (map<string,char>::const_iterator ent = cm_.begin()
; ent != cm_.end() ; ent++) {
o << setw(ind+6) << "" << (*ent).first << " --> " <<
(*ent).second << endl;
}
dump_node_pins(o, ind+4);
dump_obj_attr(o, ind+4);
}
@@ -457,16 +408,29 @@ void NetProcTop::dump(ostream&o, unsigned ind) const
statement_->dump(o, ind+2);
}
void NetAssign_::dump_lval(ostream&o) const
{
if (sig_) {
o << sig_->name();
if (bmux_) {
o << "[" << *bmux_ << "]";
} else {
o << "[" << (loff_+lwid_-1) << ":" << loff_ << "]";
}
} else {
o << "";
}
}
void NetAssignBase::dump_lval(ostream&o) const
{
o << "" << "{" << lval_->name();
if (lval_->bmux())
o << "[" << *lval_->bmux() << "]";
o << "{";
lval_->dump_lval(o);
for (NetAssign_*cur = lval_->more ; cur ; cur = cur->more) {
o << ", " << cur->name();
if (cur->bmux())
o << "[" << *cur->bmux() << "]";
o << ", ";
cur->dump_lval(o);
}
o << "}";
@@ -479,8 +443,10 @@ void NetAssign::dump(ostream&o, unsigned ind) const
dump_lval(o);
o << " = ";
#if 0
if (l_val(0)->rise_time())
o << "#" << l_val(0)->rise_time() << " ";
#endif
o << *rval() << ";" << endl;
}
@@ -490,8 +456,10 @@ void NetAssignNB::dump(ostream&o, unsigned ind) const
dump_lval(o);
o << " <= ";
#if 0
if (l_val(0)->rise_time())
o << "#" << l_val(0)->rise_time() << " ";
#endif
o << *rval() << ";" << endl;
}
@@ -732,7 +700,7 @@ void NetScope::dump(ostream&o) const
/* Dump the saved defparam assignments here. */
{
map<string,NetExpr*>::const_iterator pp;
map<hname_t,NetExpr*>::const_iterator pp;
for (pp = defparams.begin()
; pp != defparams.end() ; pp ++ ) {
o << " defparam " << (*pp).first << " = " <<
@@ -818,7 +786,7 @@ void NetProc::dump(ostream&o, unsigned ind) const
/* Dump an expression that noone wrote a dump method for. */
void NetExpr::dump(ostream&o) const
{
o << "(?)";
o << "(?" << typeid(*this).name() << "?)";
}
void NetEBinary::dump(ostream&o) const
@@ -916,10 +884,10 @@ void NetESFunc::dump(ostream&o) const
void NetESignal::dump(ostream&o) const
{
o << name();
o << name() << "[" << msi_<<":"<<lsi_ << "]";
}
void NetESubSignal::dump(ostream&o) const
void NetEBitSel::dump(ostream&o) const
{
sig_->dump(o);
o << "[";
@@ -977,7 +945,9 @@ void Design::dump(ostream&o) const
{
o << "DESIGN TIME PRECISION: 10e" << get_precision() << endl;
o << "SCOPES:" << endl;
root_scope_->dump(o);
for (list<NetScope*>::const_iterator scope = root_scopes_.begin();
scope != root_scopes_.end(); scope++)
(*scope)->dump(o);
o << "ELABORATED NODES:" << endl;
@@ -1000,6 +970,46 @@ void Design::dump(ostream&o) const
/*
* $Log: design_dump.cc,v $
* Revision 1.120 2001/12/03 04:47:14 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
*
* Revision 1.119 2001/11/19 01:46:38 steve
* Print typename is fallback expression node dump.
*
* Revision 1.118 2001/10/19 21:53:24 steve
* Support multiple root modules (Philip Blundell)
*
* Revision 1.117 2001/08/25 23:50:02 steve
* Change the NetAssign_ class to refer to the signal
* instead of link into the netlist. This is faster
* 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.116 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.115 2001/07/27 02:41:55 steve
* Fix binding of dangling function ports. do not elide them.
*
* Revision 1.114 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.113 2001/04/29 20:19:10 steve
* Add pullup and pulldown devices.
*
* Revision 1.112 2001/04/22 23:09:46 steve
* More UDP consolidation from Stephan Boettcher.
*
* Revision 1.111 2001/02/17 05:13:36 steve
* Check that the port really exists here.
*
* Revision 1.110 2001/01/18 03:16:35 steve
* NetMux needs a scope. (PR#115)
*
+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
@@ -1,6 +1,12 @@
a.out
Makefile
parse.c
parse.h
parse.output
lexor.c
cfparse.c
cfparse.h
cfparse.output
cflexor.c
foo.*
iverilog
+32 -8
View File
@@ -18,7 +18,7 @@
# 59 Temple Place - Suite 330
# Boston, MA 02111-1307, USA
#
#ident "$Id: Makefile.in,v 1.3 2001/01/09 03:11:27 steve Exp $"
#ident "$Id: Makefile.in,v 1.10 2001/11/17 17:57:58 steve Exp $"
#
#
SHELL = /bin/sh
@@ -46,35 +46,56 @@ INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
CPPFLAGS = @CPPFLAGS@ @DEFS@
CFLAGS = @CFLAGS@ -I.
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
rm -f cflexor.c cfparse.c cfparse.h cfparse.output
O = main.o build_string.o lexor.o parse.o
O = main.o build_string.o lexor.o parse.o cflexor.o cfparse.o
iverilog@EXEEXT@: $O
$(CC) $(LDFLAGS) $O -o iverilog@EXEEXT@
$(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 $(srcdir)/parse.y -o parse.c
bison --verbose -t -d -o parse.c $(srcdir)/parse.y
cflexor.c: cflexor.lex
flex -s -Pcf -ocflexor.c $(srcdir)/cflexor.lex
cfparse.h cfparse.c: cfparse.y
bison --verbose -t -d -o cfparse.c --name-prefix=cf $(srcdir)/cfparse.y
main.o: main.c globals.h
$(CC) $(CPPFLAGS) -c -DCXX='"@CXX@"' -DIVL_ROOT='"@libdir@/ivl"' -DIVL_INC='"@includedir@"' -DIVL_LIB='"@libdir@"' -DRDYNAMIC=\"$(rdynamic)\" -DDLLIB='"@DLLIB@"' $(srcdir)/main.c
$(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
cflexor.o: cflexor.c cfparse.h cfparse_misc.h globals.h
cfparse.o: cfparse.c globals.h cfparse_misc.h
iverilog.pdf: $(srcdir)/iverilog.man
man -t $(srcdir)/iverilog.man | ps2pdf - iverilog.pdf
install: all installdirs $(bindir)/iverilog@EXEEXT@ $(mandir)/man1/iverilog.1
ifeq (@WIN32@,yes)
INSTALL_DOC = $(prefix)/iverilog.pdf
INSTALL_DOCDIR =
all: iverilog.pdf
else
INSTALL_DOC = $(mandir)/man1/iverilog.1
INSTALL_DOCDIR = $(mandir)/man1
endif
install: all installdirs $(bindir)/iverilog@EXEEXT@ $(INSTALL_DOC)
$(bindir)/iverilog@EXEEXT@: ./iverilog@EXEEXT@
$(INSTALL_PROGRAM) ./iverilog@EXEEXT@ $(bindir)/iverilog@EXEEXT@
@@ -82,8 +103,11 @@ $(bindir)/iverilog@EXEEXT@: ./iverilog@EXEEXT@
$(mandir)/man1/iverilog.1: $(srcdir)/iverilog.man
$(INSTALL_DATA) $(srcdir)/iverilog.man $(mandir)/man1/iverilog.1
$(prefix)/iverilog.pdf: iverilog.pdf
$(INSTALL_DATA) iverilog.pdf $(prefix)/iverilog.pdf
installdirs: ../mkinstalldirs
$(srcdir)/../mkinstalldirs $(bindir) $(mandir)/man1
$(srcdir)/../mkinstalldirs $(bindir) $(INSTALL_DOCDIR)
uninstall:
rm -f $(bindir)/iverilog@EXEEXT@
+33 -1
View File
@@ -17,9 +17,11 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: build_string.c,v 1.2 2000/10/28 03:45:47 steve Exp $"
#ident "$Id: build_string.c,v 1.6 2001/11/16 05:07:19 steve Exp $"
#endif
# include "config.h"
# include "globals.h"
# include <string.h>
# include <assert.h>
@@ -51,6 +53,7 @@ int build_string(char*output, size_t olen, const char*pattern)
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,
@@ -126,6 +129,22 @@ int build_string(char*output, size_t olen, const char*pattern)
olen -= strlen(warning_flags);
break;
case 'y':
if (library_flags) {
strcpy(output, library_flags);
output += strlen(library_flags);
olen -= strlen(library_flags);
}
break;
case 'Y':
if (library_flags2) {
strcpy(output, library_flags2);
output += strlen(library_flags2);
olen -= strlen(library_flags2);
}
break;
}
pattern += 1;
@@ -141,6 +160,19 @@ int build_string(char*output, size_t olen, const char*pattern)
/*
* $Log: build_string.c,v $
* Revision 1.6 2001/11/16 05:07:19 steve
* Add support for +libext+ in command files.
*
* Revision 1.5 2001/10/20 23:02:40 steve
* Add automatic module libraries.
*
* Revision 1.4 2001/07/25 03:10:50 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
*
* 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.
*
+133
View File
@@ -0,0 +1,133 @@
%{
/*
* Copyright (c) 2001 Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: cflexor.lex,v 1.5 2001/12/08 04:13:07 steve Exp $"
#endif
# include "cfparse.h"
# include "cfparse_misc.h"
# include "globals.h"
# include <string.h>
/*
* Lexical location information is passed in the yylloc variable to th
* parser. The file names, strings, are kept in a list so that I can
* re-use them. The set_file_name function will return a pointer to
* the name as it exists in the list (and delete the passed string.)
* If the name is new, it will be added to the list.
*/
YYLTYPE yylloc;
static int comment_enter;
%}
%x CCOMMENT
%x LCOMMENT
%x PLUS_ARGS
%%
/* Accept C++ style comments. */
"//".* { comment_enter = YY_START; BEGIN(LCOMMENT); }
<LCOMMENT>. { yymore(); }
<LCOMMENT>\n { yylloc.first_line += 1; BEGIN(comment_enter); }
/* Accept C style comments. */
"/*" { comment_enter = YY_START; BEGIN(CCOMMENT); }
<CCOMMENT>. { yymore(); }
<CCOMMENT>\n { yylloc.first_line += 1; yymore(); }
<CCOMMENT>"*/" { BEGIN(comment_enter); }
/* Accept shell type comments. */
^"#".* { ; }
/* Skip white space. */
[ \t\f\r] { ; }
/* Skip line ends, but also count the line. */
\n { yylloc.first_line += 1; }
"+define+" { BEGIN(PLUS_ARGS); return TOK_DEFINE; }
"+incdir+" { BEGIN(PLUS_ARGS); return TOK_INCDIR; }
"+libext+" { BEGIN(PLUS_ARGS); return TOK_LIBEXT; }
/* If it is not any known plus-flag, return the generic form. */
"+"[^\n \t\b\f\r+]* {
cflval.text = strdup(yytext);
BEGIN(PLUS_ARGS);
return TOK_PLUSWORD; }
/* Once in PLUS_ARGS mode, words are delimited by +
characters. White space and line end terminate PLUS_ARGS mode,
but + terminates only the word. */
<PLUS_ARGS>[^\n \t\b\f\r+]* {
cflval.text = strdup(yytext);
return TOK_PLUSARG; }
/* Within plusargs, this is a delimiter. */
<PLUS_ARGS>"+" { }
/* White space end plus_args mode. */
<PLUS_ARGS>[ \t\b\f\r] { BEGIN(0); }
<PLUS_ARGS>\n {
yylloc.first_line += 1;
BEGIN(0); }
/* Notice the -a flag. */
"-a" { return TOK_Da; }
/* Notice the -v flag. */
"-v" { return TOK_Dv; }
/* Notice the -y flag. */
"-y" { return TOK_Dy; }
/* This rule matches paths and strings that may be file names. This
is a little bit tricky, as we don't want to mistake a comment for
a string word. */
"/"[^\*\/].* { cflval.text = strdup(yytext);
return TOK_STRING; }
[^/\n \t\b\r+-].* { cflval.text = strdup(yytext);
return TOK_STRING; }
/* Fallback match. */
. { return yytext[0]; }
%%
int yywrap()
{
return 1;
}
void cfreset(FILE*fd, const char*path)
{
yyin = fd;
yyrestart(fd);
yylloc.first_line = 1;
yylloc.text = (char*)path;
}
+187
View File
@@ -0,0 +1,187 @@
%{
/*
* Copyright (c) 20001 Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: cfparse.y,v 1.5 2001/12/08 04:13:07 steve Exp $"
#endif
# include "globals.h"
# include <ctype.h>
/*
* This flag is set to 0, 1 or 2 if file names are to be translated to
* uppercase(1) or lowercase(2).
*/
static int setcase_filename_flag = 0;
static void translate_file_name(char*text)
{
switch (setcase_filename_flag) {
case 0:
break;
case 1:
while (*text) {
*text = toupper(*text);
text += 1;
}
break;
case 2:
while (*text) {
*text = tolower(*text);
text += 1;
}
break;
}
}
%}
%union {
char*text;
};
%token TOK_Da TOK_Dv TOK_Dy
%token TOK_DEFINE TOK_INCDIR TOK_LIBEXT
%token <text> TOK_PLUSARG TOK_PLUSWORD TOK_STRING
%%
start
:
| item_list
;
item_list
: item_list item
| item
;
item
/* Absent any other matching, a token string is taken to be the name
of a source file. Add the file to the file list. */
: TOK_STRING
{ translate_file_name($1);
process_file_name($1);
free($1);
}
/* The -a flag is completely ignored. */
| TOK_Da { }
/* The -v <libfile> flag is ignored, and the <libfile> is processed
as an ordinary source file. */
| TOK_Dv TOK_STRING
{ translate_file_name($2);
process_file_name($2);
fprintf(stderr, "%s:%u: Ignoring -v in front of %s\n",
@1.text, @1.first_line, $2);
free($2);
}
/* This rule matches "-y <path>" sequences. This does the same thing
as -y on the command line, so add the path to the library
directory list. */
| TOK_Dy TOK_STRING
{ process_library_switch($2);
free($2);
}
| TOK_DEFINE TOK_PLUSARG
{ process_define($2);
free($2);
}
/* The +incdir token introduces a list of +<path> arguments that are
the include directories to search. */
| TOK_INCDIR inc_args
/* The +libext token introduces a list of +<ext> arguments that
become individual -Y flags to ivl. */
| TOK_LIBEXT libext_args
/* The +<word> tokens that are not otherwise matched, are
ignored. The skip_args rule arranges for all the argument words
to be consumed. */
| TOK_PLUSWORD skip_args
{ fprintf(stderr, "%s:%u: Ignoring %s\n",
@1.text, @1.first_line, $1);
free($1);
}
| TOK_PLUSWORD
{ if (strcmp($1, "+toupper-filenames") == 0) {
setcase_filename_flag = 1;
} else if (strcmp($1, "+tolower-filenames") == 0) {
setcase_filename_flag = 2;
} else {
fprintf(stderr, "%s:%u: Ignoring %s\n",
@1.text, @1.first_line, $1);
}
free($1);
}
;
/* inc_args are +incdir+ arguments in order. */
inc_args
: inc_args inc_arg
| inc_arg
;
inc_arg : TOK_PLUSARG
{ process_include_dir($1);
free($1);
}
;
/* inc_args are +incdir+ arguments in order. */
libext_args
: libext_args libext_arg
| libext_arg
;
libext_arg : TOK_PLUSARG
{ process_library2_switch($1);
free($1);
}
;
/* skip_args are arguments to a +word flag that is not otherwise
parsed. This rule matches them and releases the strings, so that
they can be safely ignored. */
skip_args
: skip_args skip_arg
| skip_arg
;
skip_arg : TOK_PLUSARG
{ free($1);
}
;
%%
int yyerror(const char*msg)
{
}
+37
View File
@@ -0,0 +1,37 @@
#ifndef __cfparse_misc_H
#define __cfparse_misc_H
/*
* Copyright (c) 2001 Picture Elements, Inc.
* 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: cfparse_misc.h,v 1.2 2001/11/12 18:47:32 steve Exp $"
#endif
/*
* $Log: cfparse_misc.h,v $
* Revision 1.2 2001/11/12 18:47:32 steve
* Support +incdir in command files, and ignore other
* +args flags. Also ignore -a and -v flags.
*
* Revision 1.1 2001/11/12 01:26:36 steve
* More sophisticated command file parser.
*
*/
#endif
+46 -3
View File
@@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: globals.h,v 1.3 2000/11/09 21:58:00 steve Exp $"
#ident "$Id: globals.h,v 1.10 2001/11/16 05:07:19 steve Exp $"
#endif
# include <stddef.h>
@@ -42,8 +42,8 @@ extern const char*npath;
/* This is the name of the output file that the user selected. */
extern const char*opath;
/* This pointer is set if there was a -s<value> parameter. */
extern const char*start;
/* This pointer is set if there were -s<value> parameters. */
extern char*start;
/* This flag is true if the -S flag was used on the command line. */
extern int synth_flag;
@@ -51,14 +51,57 @@ extern int synth_flag;
/* This is the name of the selected target. */
extern const char*targ;
/* Add the name to the list of source files. */
extern void process_file_name(const char*name);
/* Add the name to the list of library directories. */
extern void process_library_switch(const char*name);
extern void process_library2_switch(const char*name);
/* Add a new include file search directory */
extern void process_include_dir(const char*name);
/* Add a new -D define. */
extern void process_define(const char*name);
/* -v */
extern int verbose_flag;
extern char warning_flags[];
/* -y and -Y flags from the command line. */
extern char* library_flags;
extern char* library_flags2;
extern const char*lookup_pattern(const char*key);
extern int build_string(char*out, size_t olen, const char*pattern);
/*
* $Log: globals.h,v $
* Revision 1.10 2001/11/16 05:07:19 steve
* Add support for +libext+ in command files.
*
* Revision 1.9 2001/11/13 03:30:26 steve
* The +incdir+ plusarg can take multiple directores,
* and add initial support for +define+ in the command file.
*
* Revision 1.8 2001/11/12 18:47:32 steve
* Support +incdir in command files, and ignore other
* +args flags. Also ignore -a and -v flags.
*
* Revision 1.7 2001/11/12 01:26:36 steve
* More sophisticated command file parser.
*
* Revision 1.6 2001/10/23 00:37:30 steve
* The -s flag can now be repeated on the iverilog command.
*
* Revision 1.5 2001/10/20 23:02:40 steve
* Add automatic module libraries.
*
* Revision 1.4 2001/07/03 04:09:25 steve
* Generate verbuse status messages (Stephan Boettcher)
*
* Revision 1.3 2000/11/09 21:58:00 steve
* Remember to include the -S condition.
*
+108 -23
View File
@@ -1,18 +1,21 @@
.TH iverilog 1 "$Date: 2001/01/20 19:02:05 $" Version "$Date: 2001/01/20 19:02:05 $"
.TH iverilog 1 "$Date: 2001/12/08 04:13:07 $" Version "$Date: 2001/12/08 04:13:07 $"
.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
[-ESv] [-Cpath] [-ccmdfile] [-Dmacro[=defn]] [-pflag=value]
[-Iincludedir] [-mmodule] [-Nfile] [-ooutputfilename] [-stopmodule]
[-ttype] [-Tmin/typ/max] [-Wclass] [-ypath] sourcefile
.SH DESCRIPTION
.PP
\fIiverilog\fP is a compiler that translates Verilog source code into
executable programs for simulation, or other netlist formats for
further processing. The currenty supported targets are \fIvvm\fP (for
executable simulation) and \fIxnf\fP for synthesis. Other target
types are added as code generators are implemented.
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
@@ -20,7 +23,7 @@ types are added as code generators are implemented.
.TP 8
.B -B\fIbase\fP
The \fIiverilog\fP program uses external programs to preprocess and
compile the verilog source. Normally, the path used to locate these
compile the Verilog source. Normally, the path used to locate these
tools is built into the \fIiverilog\fP program. However, the \fB-B\fP
switch allows the user to select a different set of programs. The path
given is used to locate \fIivlpp\fP, \fIivl\fP and the VPI modules.
@@ -29,9 +32,7 @@ given is used to locate \fIivlpp\fP, \fIivl\fP and the VPI modules.
This flag specifies an input file that contains a list of Verilog
source files. This is similar to the \fIcommand file\fP of other
Verilog simulators, in that it is a file that contains the file names
instead of taking them on the command line. The command file may
contain C-style comments (/*-*/) or shell-style comments (# to the end
of the line.)
instead of taking them on the command line. See \fBCommand Files\fP below.
.TP 8
.B -C\fIpath\fP
This flag selects the driver configuration file to use. Normally, the
@@ -53,10 +54,10 @@ Defines macro \fImacro\fP as \fIdefn\fP.
Preprocess the Verilog source, but do not compile it. The output file
is the Verilog input, but with file inclusions and macro references
expanded and removed. This is useful, for example, to preprocess
verilog source for use by other compilers.
Verilog source for use by other compilers.
.TP 8
.B -I\fIincludedir\fP
Append directory \fIincludepdir\fP to list of directoriess searched
Append directory \fIincludedir\fP to list of directories searched
for Verilog include files. The \fB-I\fP switch may be used many times
to specify several directories to search, the directories are searched
in the order they appear on the command line.
@@ -64,7 +65,7 @@ in the order they appear on the command line.
.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 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
@@ -91,9 +92,10 @@ netlist format, the \fB-S\fP switch is unnecessary and has no effect.
.TP 8
.B -s \fItopmodule\fP
Specify the top level module to elaborate. Icarus Verilog will by default
choose the only module that has no ports. However, this simplistic
heuristic is often not sufficient, and sometimes not what is wanted
anyhow.
choose modules that are not instantiated in any other modules, but
sometimes that is not sufficient, or instantiates too many modules. If
the user specifies one or more root modules with \fB-s\fP flags, then
they will be used as root modules instead.
.TP 8
.B -T\fImin|typ|max\fP
Use this switch to select min, typ or max times from min:typ:max
@@ -113,9 +115,28 @@ 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
section below for descriptions of the different warning groups. If
multiple \fB-W\fP switches are used, the warning set is the union of
all the requested classes.
.TP 8
.B -y\fIlibdir\fP
Append the directory to the library module search path. When the
compiler finds an undefined module, it looks in these directories for
files with the right name.
.SH MODULE LIBRARIES
The Icarus Verilog compiler supports module libraries as directories
that contain Verilog source files. During elaboration, the compiler
notices the instantiation of undefined module types. If the user
specifies library search directories, the compiler will search the
directory for files with the name of the missing module type. If it
finds such a file, it loads it as a Verilog source file, they tries
again to elaborate the module.
Library module files should contain only a single module, but this is
not a requirement. Library modules may reference other modules in the
library or in the main design.
.SH TARGETS
@@ -129,15 +150,26 @@ The null target causes no code to be generated. It is useful for
checking the syntax of the Verilog source.
.TP 8
.B vvm
This is the default. 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.
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 \fBvvp\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 intended 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
@@ -150,24 +182,76 @@ This enables all supported warning categories.
.TP 8
.B implicit
This enables warnings for creation of implicit declarations. For
example, if a scaler wire X is used but not declared in the Verilog
example, if a scalar wire X is used but not declared in the Verilog
source, this will print a warning at its first use.
.SH "COMMAND FILES"
The command file allows the user to place source file names and
certain command line switches into a text file instead of on a long
command line. Command files can include C or C++ style comments, as
well as # comments, if the # starts the line.
.TP 8
.I "file name"
A simple file name or file path is taken to be the name of a Verilog
source file. The path starts with the first non-white-space character.
.TP 8
.B -y\ \fIlibdir\fP
A \fB-y\fP token prefixes a library directory in the command file,
exactly like it does on the command line. The parameter to the \fB-y\fP
flag may be on the same line or the next non-comment line.
.TP 8
.B +incdir+\fIincludedir\fP
The \fB+incdir+\fP token in command files gives directories to search
for include files in much the same way that \fB-I\fP flags work on the
command line. The difference is that multiple \fI+includedir\fP
directories are valid parameters to a single \fB+incdir+\fP token,
although you may also have multiple \fB+incdir+\fP lines.
.TP 8
.B +libext+\fIext\fP
The \fB+libext\fP token in command files fives file extensions to try
when looking for a library file. This is useful in conjunction with
\fB-y\fP flags to list suffixes to try in each directory before moving
on to the next library directory.
.TP 8
.B +define+\fINAME\fP=\fIvalue\fP
The \fB+define+\fP token is the same as the \fB-D\fP option on the
command line. The value part of the token is optional.
.TP 8
.B +toupper-filename\fP
This token causes file names after this in the command file to be
translated to uppercase. This helps with situations where a directory
has passed through a DOS machine, and in the process the file names
become munged.
.TP 8
.B +tolower-filename\fP
This is similar to the \fB+toupper-filename\fP hack described above.
.SH 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:
verilog hello.v
iverilog hello.v
To compile hello.v to an executable file called hello:
verilog -o hello hello.v
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
verilog -txnf -ohello.xnf hello.v
iverilog -txnf -ohello.xnf hello.v
.SH "AUTHOR"
@@ -175,6 +259,7 @@ To compile hello.v to a file in XNF-format called hello.xnf
Steve Williams ([email protected])
.SH SEE ALSO
vvp(1),
.BR "<http://www.icarus.com/eda/verilog/>"
.SH COPYRIGHT
+3 -1
View File
@@ -19,9 +19,11 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: lexor.lex,v 1.4 2000/12/15 02:00:11 steve Exp $"
#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"
+340 -181
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2000 Stephen Williams ([email protected])
* 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
@@ -16,16 +16,17 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: main.c,v 1.8 2001/02/01 17:12:22 steve Exp $"
#endif
#ident "$Id: main.c,v 1.31 2001/11/21 02:20:34 steve Exp $"
# include "config.h"
const char HELP[] =
"Usage: iverilog [-ESv] [-c <path>] [-Dmacro[=defn]]
[-p flag=value] [-I<dir>] [-m module]
[-o <output>] [-s top_module] [-t<type>]
[-W class] source_file(s)
See man page for details.";
"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] [-y dir] [-Y suf] source_file(s)\n"
"See man page for details.";
#define MAXSIZE 4096
@@ -36,12 +37,32 @@ See man page for details.";
#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
@@ -52,32 +73,50 @@ See man page for details.";
# include "globals.h"
const char*base = IVL_ROOT;
#ifdef __MINGW32__
const char sep = '\\';
#else
const char sep = '/';
#endif
extern void cfreset(FILE*fd, const char*path);
const char*base = 0;
const char*mtm = 0;
const char*opath = "a.out";
const char*opath = "a.out" EXEEXT;
const char*npath = 0;
const char*targ = "vvm";
const char*start = 0;
const char*targ = "vvp";
char warning_flags[16] = "";
char *library_flags = 0;
char *library_flags2 = 0;
char*inc_list = 0;
char*def_list = 0;
char*mod_list = 0;
char*command_filename = 0;
char*start = 0;
char*f_list = 0;
/* These are used to collect the list of file names that will be
passed to ivlpp. Keep the list in a file because it can be a long
list. */
char*source_path = 0;
FILE*source_file = 0;
unsigned source_count = 0;
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
@@ -99,6 +138,16 @@ static int t_default(char*cmd, unsigned ncmd)
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);
@@ -107,7 +156,13 @@ static int t_default(char*cmd, unsigned ncmd)
rc = system(cmd);
remove(source_path);
if (rc != 0) {
if (rc == 127) {
fprintf(stderr, "Failed to execute: %s\n", cmd);
return 1;
}
if (WIFEXITED(rc))
return WEXITSTATUS(rc);
@@ -138,12 +193,26 @@ static int t_vvm(char*cmd, unsigned ncmd)
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);
remove(source_path);
if (rc != 0) {
if (WIFEXITED(rc)) {
fprintf(stderr, "errors translating Verilog program.\n");
@@ -154,10 +223,27 @@ static int t_vvm(char*cmd, unsigned ncmd)
}
}
sprintf(tmp, "%s " RDYNAMIC " -fno-exceptions -o %s -I%s "
"-L%s %s.cc -lvvm -lvpip %s", CXX, opath, IVL_INC, IVL_LIB,
opath, DLLIB);
#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);
@@ -178,70 +264,6 @@ static int t_vvm(char*cmd, unsigned ncmd)
return 0;
}
static int t_xnf(char*cmd, unsigned ncmd)
{
int rc;
sprintf(tmp, " | %s/ivl %s -o %s -txnf -Fcprop -Fsynth -Fsyn-rules "
"-Fnodangle -Fxnfio", base, warning_flags, opath);
rc = strlen(tmp);
cmd = realloc(cmd, ncmd+rc+1);
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)
{
@@ -257,6 +279,68 @@ static void process_warning_switch(const char*name)
}
}
void process_library_switch(const char *name)
{
if (library_flags) {
library_flags = realloc(library_flags,
strlen(library_flags) + strlen(name) + 5);
strcat(library_flags, " -y ");
} else {
library_flags = malloc(strlen(name) + 4);
strcpy(library_flags, "-y ");
}
strcat(library_flags, name);
}
void process_library2_switch(const char *name)
{
if (library_flags2) {
library_flags2 = realloc(library_flags2,
strlen(library_flags2) + strlen(name) + 5);
strcat(library_flags2, " -Y ");
} else {
library_flags2 = malloc(strlen(name) + 4);
strcpy(library_flags2, "-Y ");
}
strcat(library_flags2, name);
}
void process_include_dir(const char *name)
{
if (inc_list == 0) {
inc_list = malloc(strlen(" -I")+strlen(name)+1);
strcpy(inc_list, " -I");
strcat(inc_list, name);
} else {
inc_list = realloc(inc_list, strlen(inc_list)
+ strlen(" -I")
+ strlen(name) + 1);
strcat(inc_list, " -I");
strcat(inc_list, name);
}
}
void process_define(const char*name)
{
if (def_list == 0) {
def_list = malloc(strlen(" -D")+strlen(name)+1);
strcpy(def_list, " -D");
strcat(def_list, name);
} else {
def_list = realloc(def_list, strlen(def_list)
+ strlen(" -D")
+ strlen(name) + 1);
strcat(def_list, " -D");
strcat(def_list, name);
}
}
void process_file_name(const char*name)
{
fprintf(source_file, "%s\n", name);
source_count += 1;
}
int main(int argc, char **argv)
{
const char*config_path = 0;
@@ -266,7 +350,49 @@ int main(int argc, char **argv)
int opt, idx;
char*cp;
while ((opt = getopt(argc, argv, "B:C:c:D:Ef:hI:m:N::o:p:Ss:T:t:vW:")) != EOF) {
#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
source_path = strdup(tmpnam(0));
assert(source_path);
source_file = fopen(source_path, "w");
assert(source_file);
while ((opt = getopt(argc, argv, "B:C:c:D:Ef:hI:m:N::o:p:Ss:T:t:vW:y:")) != EOF) {
switch (opt) {
case 'B':
@@ -277,20 +403,10 @@ int main(int argc, char **argv)
break;
case 'c':
command_filename = malloc(strlen(optarg)+1);
strcat(command_filename, optarg);
strcpy(command_filename, optarg);
break;
case 'D':
if (def_list == 0) {
def_list = malloc(strlen(" -D")+strlen(optarg)+1);
strcpy(def_list, " -D");
strcat(def_list, optarg);
} else {
def_list = realloc(def_list, strlen(def_list)
+ strlen(" -D")
+ strlen(optarg) + 1);
strcat(def_list, " -D");
strcat(def_list, optarg);
}
process_define(optarg);
break;
case 'E':
e_flag = 1;
@@ -316,18 +432,9 @@ int main(int argc, char **argv)
return 1;
case 'I':
if (inc_list == 0) {
inc_list = malloc(strlen(" -I")+strlen(optarg)+1);
strcpy(inc_list, " -I");
strcat(inc_list, optarg);
} else {
inc_list = realloc(inc_list, strlen(inc_list)
+ strlen(" -I")
+ strlen(optarg) + 1);
strcat(inc_list, " -I");
strcat(inc_list, optarg);
}
process_include_dir(optarg);
break;
case 'm':
if (mod_list == 0) {
mod_list = malloc(strlen(" -m")+strlen(optarg)+1);
@@ -354,7 +461,18 @@ int main(int argc, char **argv)
synth_flag = 1;
break;
case 's':
start = optarg;
if (start) {
static const char *s = " -s ";
size_t l = strlen(start);
start = realloc(start, l + strlen(optarg) + strlen(s) + 1);
strcpy(start + l, s);
strcpy(start + l + strlen(s), optarg);
} else {
static const char *s = "-s ";
start = malloc(strlen(optarg) + strlen(s) + 1);
strcpy(start, s);
strcpy(start + strlen(s), optarg);
}
break;
case 'T':
if (strcmp(optarg,"min") == 0) {
@@ -378,13 +496,46 @@ int main(int argc, char **argv)
case 'W':
process_warning_switch(optarg);
break;
case 'y':
process_library_switch(optarg);
break;
case 'Y':
process_library2_switch(optarg);
break;
case '?':
default:
return 1;
}
}
if ((optind == argc) && !command_filename) {
if (command_filename) {
int rc;
if (( fp = fopen(command_filename, "r")) == NULL ) {
fprintf(stderr, "%s: Can't open %s\n",
argv[0], command_filename);
return 1;
}
cfreset(fp, command_filename);
rc = cfparse();
if (rc != 0) {
fprintf(stderr, "%s: error reading command file\n",
command_filename);
return 1;
}
}
/* Finally, process all the remaining words on the command
line as file names. */
for (idx = optind ; idx < argc ; idx += 1)
process_file_name(argv[idx]);
fclose(source_file);
source_file = 0;
if (source_count == 0) {
fprintf(stderr, "%s: No input files.\n", argv[0]);
fprintf(stderr, "%s\n", HELP);
return 1;
@@ -398,18 +549,22 @@ int main(int argc, char **argv)
if (config_path) {
strcpy(path, config_path);
} else {
sprintf(path, "%s/iverilog.conf", base);
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/ivlpp %s%s", base,
sprintf(tmp, "%s%civlpp %s%s -f%s ", base,sep,
verbose_flag?" -v":"",
e_flag?"":" -L");
e_flag?"":" -L", source_path);
ncmd = strlen(tmp);
cmd = malloc(ncmd + 1);
@@ -427,56 +582,6 @@ int main(int argc, char **argv)
ncmd += strlen(def_list);
}
/* If user supplied a command file, retain its contents -- this
process supersedes command line source files. */
if (command_filename != 0) {
if (( fp = fopen(command_filename, "r")) == NULL ) {
fprintf(stderr, "%s: Can't open %s\n",
argv[0], command_filename);
return 1;
} else {
/* Process file and skip over commented-out lines.
Skips over c-like comment as well as '//' or
'#' lines. */
sprintf(tmp, "");
while (fgets(line, MAXSIZE, fp) != NULL) {
if ( strstr(line, "*/") != NULL ) {
inside_c_comment = 0;
continue;
}
if (inside_c_comment || (strstr(line, "/*") != NULL)) {
inside_c_comment = 1;
continue;
}
if ( (line[0] != '/' || line[1] != '/')
&& line[0] != '#' ) {
strcat (tmp, " ");
strncat (tmp, line, (strlen(line)-1));
}
}
fclose(fp);
}
cmd = realloc(cmd, ncmd+strlen(tmp)+1);
strcpy(cmd+ncmd, tmp);
ncmd += strlen(tmp);
} else {
/* Add all verilog source files to the preprocess
command line. */
for (idx = optind ; idx < argc ; idx += 1) {
sprintf(tmp, " %s", argv[idx]);
cmd = realloc(cmd, ncmd+strlen(tmp)+1);
strcpy(cmd+ncmd, tmp);
ncmd += strlen(tmp);
}
}
/* If the -E flag was given on the command line, then all we
do is run the preprocessor and put the output where the
@@ -494,6 +599,7 @@ int main(int argc, char **argv)
printf("preprocess: %s\n", cmd);
rc = system(cmd);
remove(source_path);
if (rc != 0) {
if (WIFEXITED(rc)) {
fprintf(stderr, "errors preprocessing Verilog program.\n");
@@ -509,8 +615,6 @@ int main(int argc, char **argv)
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);
}
@@ -520,29 +624,84 @@ int main(int argc, char **argv)
/*
* $Log: main.c,v $
* Revision 1.31 2001/11/21 02:20:34 steve
* Pass list of file to ivlpp via temporary file.
*
* Revision 1.30 2001/11/16 05:07:19 steve
* Add support for +libext+ in command files.
*
* Revision 1.29 2001/11/13 03:30:26 steve
* The +incdir+ plusarg can take multiple directores,
* and add initial support for +define+ in the command file.
*
* Revision 1.28 2001/11/12 18:47:32 steve
* Support +incdir in command files, and ignore other
* +args flags. Also ignore -a and -v flags.
*
* Revision 1.27 2001/11/12 01:26:36 steve
* More sophisticated command file parser.
*
* Revision 1.26 2001/11/11 00:10:05 steve
* Remov XNF dead wood.
*
* Revision 1.25 2001/10/23 00:37:30 steve
* The -s flag can now be repeated on the iverilog command.
*
* Revision 1.24 2001/10/20 23:02:40 steve
* Add automatic module libraries.
*
* Revision 1.23 2001/10/19 23:10:08 steve
* Fix memory fault with -c flag.
*
* Revision 1.22 2001/10/11 00:12:49 steve
* Detect execv failures.
*
* Revision 1.21 2001/07/25 03:10:50 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
*
* 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.
*
* Revision 1.6 2001/01/20 02:15:51 steve
* apologize for not supporting non-constant delays.
*
* Revision 1.5 2000/11/30 02:50:54 steve
* Add command file (-c) support from Nadim Shaikli.
*
* Revision 1.4 2000/10/28 17:28:16 steve
* Split vpip for everybody.
*
* Revision 1.3 2000/10/28 03:47:25 steve
* Use the conf file to generate the vvm ivl string.
*
* 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.
*
*/
+6 -1
View File
@@ -18,11 +18,16 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: parse.y,v 1.2 2000/11/09 21:58:00 steve Exp $"
#ident "$Id: parse.y,v 1.4 2001/09/15 18:27:04 steve Exp $"
#endif
# include "config.h"
# include <stdio.h>
#ifdef HAVE_MALLOC_H
# include <malloc.h>
#endif
# include <stdlib.h>
# include "globals.h"
+38 -2
View File
@@ -17,9 +17,11 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: dup_expr.cc,v 1.4 2000/05/07 18:20:07 steve Exp $"
#ident "$Id: dup_expr.cc,v 1.6 2001/11/19 01:54:14 steve Exp $"
#endif
# include "config.h"
# include "netlist.h"
# include <cassert>
@@ -32,14 +34,48 @@ NetEScope* NetEScope::dup_expr() const
NetESFunc* NetESFunc::dup_expr() const
{
NetESFunc*tmp = new NetESFunc(name_, expr_width(), nparms());
for (unsigned idx = 0 ; idx < nparms() ; idx += 1)
assert(tmp);
for (unsigned idx = 0 ; idx < nparms() ; idx += 1) {
assert(tmp->parm(idx));
tmp->parm(idx, tmp->parm(idx)->dup_expr());
}
return tmp;
}
NetESignal* NetESignal::dup_expr() const
{
NetESignal*tmp = new NetESignal(net_, msi_, lsi_);
assert(tmp);
tmp->expr_width(expr_width());
return tmp;
}
NetETernary* NetETernary::dup_expr() const
{
NetETernary*tmp = new NetETernary(cond_->dup_expr(),
true_val_->dup_expr(),
false_val_->dup_expr());
return tmp;
}
NetEUnary* NetEUnary::dup_expr() const
{
NetEUnary*tmp = new NetEUnary(op_, expr_->dup_expr());
assert(tmp);
return tmp;
}
/*
* $Log: dup_expr.cc,v $
* Revision 1.6 2001/11/19 01:54:14 steve
* Port close cropping behavior from mcrgb
* Move window array reset to libmc.
*
* Revision 1.5 2001/07/25 03:10:48 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
*
* 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.
+15 -5
View File
@@ -17,9 +17,11 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: elab_anet.cc,v 1.2 2001/01/06 02:29:36 steve Exp $"
#ident "$Id: elab_anet.cc,v 1.4 2001/12/03 04:47:14 steve Exp $"
#endif
# include "config.h"
/*
* The elaborate_anet methods elaborate expressions that are intended
* to be the left side of procedural continuous assignments.
@@ -102,10 +104,10 @@ NetNet* PEConcat::elaborate_anet(Design*des, NetScope*scope) const
NetNet* PEIdent::elaborate_anet(Design*des, NetScope*scope) const
{
NetNet*sig = des->find_signal(scope, text_);
NetNet*sig = des->find_signal(scope, path_);
if (sig == 0) {
if (NetMemory*mem = des->find_memory(scope, text_)) {
if (NetMemory*mem = des->find_memory(scope, path_)) {
cerr << get_line() << ": error: memories not allowed "
<< "on left side of procedural continuous "
<< "asignment." << endl;
@@ -113,7 +115,7 @@ NetNet* PEIdent::elaborate_anet(Design*des, NetScope*scope) const
return 0;
}
cerr << get_line() << ": error: reg ``" << text_ << "'' "
cerr << get_line() << ": error: reg ``" << path_ << "'' "
<< "is undefined in this scope." << endl;
des->errors += 1;
return 0;
@@ -125,7 +127,7 @@ NetNet* PEIdent::elaborate_anet(Design*des, NetScope*scope) const
break;
default:
cerr << get_line() << ": error: " << text_ << " is not "
cerr << get_line() << ": error: " << path_ << " is not "
<< "a reg in this context." << endl;
des->errors += 1;
return 0;
@@ -147,6 +149,14 @@ NetNet* PEIdent::elaborate_anet(Design*des, NetScope*scope) const
/*
* $Log: elab_anet.cc,v $
* Revision 1.4 2001/12/03 04:47:14 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
*
* Revision 1.3 2001/07/25 03:10:48 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
*
* Revision 1.2 2001/01/06 02:29:36 steve
* Support arrays of integers.
*
+172 -148
View File
@@ -17,12 +17,16 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: elab_expr.cc,v 1.34 2001/01/14 23:04:55 steve Exp $"
#ident "$Id: elab_expr.cc,v 1.46 2001/12/03 04:47:14 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
{
@@ -41,6 +45,9 @@ NetExpr* PExpr::elaborate_expr(Design*des, NetScope*) const
*/
NetEBinary* PEBinary::elaborate_expr(Design*des, NetScope*scope) const
{
assert(left_);
assert(right_);
NetExpr*lp = left_->elaborate_expr(des, scope);
NetExpr*rp = right_->elaborate_expr(des, scope);
if ((lp == 0) || (rp == 0)) {
@@ -49,6 +56,7 @@ NetEBinary* PEBinary::elaborate_expr(Design*des, NetScope*scope) const
return 0;
}
/* If either expression can be evaluated ahead of time, then
do so. This can prove helpful later. */
{ NetExpr*tmp;
@@ -57,6 +65,7 @@ NetEBinary* PEBinary::elaborate_expr(Design*des, NetScope*scope) const
delete lp;
lp = tmp;
}
tmp = rp->eval_tree();
if (tmp) {
delete rp;
@@ -145,18 +154,66 @@ NetEBinary* PEBinary::elaborate_expr_base_(Design*des,
return tmp;
}
/*
* 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
{
unsigned wid = 32;
if (name_ == "$time")
if (strcmp(path_.peek_name(0), "$time") == 0)
wid = 64;
NetESFunc*fun = new NetESFunc(name_, wid, parms_.count());
for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) {
/* 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(path_.peek_name(0), 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];
NetExpr*tmp = expr->elaborate_expr(des, scope);
fun->parm(idx, tmp);
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 "
<< path_.peek_name(0)
<< " 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;
@@ -164,19 +221,19 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope) const
NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope) const
{
if (name_[0] == '$')
if (path_.peek_name(0)[0] == '$')
return elaborate_sfunc_(des, scope);
NetFuncDef*def = des->find_function(scope, name_);
NetFuncDef*def = des->find_function(scope, path_);
if (def == 0) {
cerr << get_line() << ": error: No function " << name_ <<
cerr << get_line() << ": error: No function " << path_ <<
" in this context (" << scope->name() << ")." << endl;
des->errors += 1;
return 0;
}
assert(def);
NetScope*dscope = des->find_scope(def->name());
NetScope*dscope = def->scope();
assert(dscope);
/* How many parameters have I got? Normally the size of the
@@ -188,6 +245,22 @@ NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope) const
if ((parms_count == 1) && (parms_[0] == 0))
parms_count = 0;
if (dscope->type() != NetScope::FUNC) {
cerr << get_line() << ": error: Attempt to call scope "
<< dscope->name() << " as a function." << endl;
des->errors += 1;
return 0;
}
if ((parms_count+1) != dscope->func_def()->port_count()) {
cerr << get_line() << ": error: Function " << dscope->name()
<< " expects " << (dscope->func_def()->port_count()-1)
<< " parameters, you passed " << parms_count << "."
<< endl;
des->errors += 1;
return 0;
}
svector<NetExpr*> parms (parms_count);
/* Elaborate the input expressions for the function. This is
@@ -195,22 +268,39 @@ NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope) const
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];
assert(tmp);
parms[idx] = tmp->elaborate_expr(des, scope);
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 " << path_
<< " 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. */
function code assigns to this signal to return a value.
NetNet*res = des->find_signal(dscope, name_);
dscope, in this case, is the scope of the function, so the
return value is the name within that scope. */
NetNet*res = dscope->find_signal(dscope->basename());
if (res == 0) {
cerr << get_line() << ": internal error: Unable to locate "
"function return value for " << name_ << " in " <<
"function return value for " << path_ << " in " <<
def->name() << "." << endl;
des->errors += 1;
return 0;
@@ -219,7 +309,7 @@ NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope) 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;
}
@@ -231,17 +321,21 @@ NetExpr* PEConcat::elaborate_expr(Design*des, NetScope*scope) const
/* If there is a repeat expression, then evaluate the constant
value and set the repeat count. */
if (repeat_) {
verinum*vrep = repeat_->eval_const(des, scope->name());
if (vrep == 0) {
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 = vrep->as_ulong();
delete vrep;
repeat = rep->value().as_ulong();
}
/* Make the empty concat expression. */
@@ -277,19 +371,18 @@ NetExpr* PEFNumber::elaborate_expr(Design*des, NetScope*scope) const
NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope) const
{
assert(text_[0] != '$');
assert(path_.peek_name(0)[0] != '$');
//string name = path+"."+text_;
assert(scope);
// If the identifier name is a parameter name, then return
// a reference to the parameter expression.
if (const NetExpr*ex = des->find_parameter(scope, text_)) {
if (const NetExpr*ex = des->find_parameter(scope, path_)) {
NetExpr*tmp;
if (dynamic_cast<const NetExpr*>(ex))
tmp = ex->dup_expr();
else
tmp = new NetEParam(des, scope, text_);
tmp = new NetEParam(des, scope, path_);
tmp->set_line(*this);
return tmp;
@@ -297,7 +390,7 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope) const
// If the identifier names a signal (a register or wire)
// then create a NetESignal node to handle it.
if (NetNet*net = des->find_signal(scope, text_)) {
if (NetNet*net = des->find_signal(scope, path_)) {
// If this is a part select of a signal, then make a new
// temporary signal that is connected to just the
@@ -305,8 +398,8 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope) const
// the foo[msb:lsb] expression in the original.
if (lsb_) {
assert(msb_);
verinum*lsn = lsb_->eval_const(des, scope->name());
verinum*msn = msb_->eval_const(des, scope->name());
verinum*lsn = lsb_->eval_const(des, scope);
verinum*msn = msb_->eval_const(des, scope);
if ((lsn == 0) || (msn == 0)) {
cerr << get_line() << ": error: "
"Part select expresions must be "
@@ -359,15 +452,9 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope) const
return 0;
}
string tname = des->local_symbol(scope->name());
NetTmp*tsig = new NetTmp(scope, tname, wid);
// 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);
NetESignal*tmp = new NetESignal(net,
net->sb_to_idx(msv),
net->sb_to_idx(lsv));
tmp->set_line(*this);
return tmp;
@@ -377,7 +464,7 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope) const
// to the part select, so that I save the effort of
// making a mux part in the netlist.
verinum*msn;
if (msb_ && (msn = msb_->eval_const(des, scope->name()))) {
if (msb_ && (msn = msb_->eval_const(des, scope))) {
assert(idx_ == 0);
unsigned long msv = msn->as_ulong();
unsigned idx = net->sb_to_idx(msv);
@@ -390,10 +477,7 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope) const
return 0;
}
string tname = des->local_symbol(scope->name());
NetTmp*tsig = new NetTmp(scope, tname);
connect(tsig->pin(0), net->pin(idx));
NetESignal*tmp = new NetESignal(tsig);
NetESignal*tmp = new NetESignal(net, idx, idx);
tmp->set_line(*this);
return tmp;
@@ -406,7 +490,7 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope) const
// device to mux the bit in the net.
if (msb_) {
NetExpr*ex = msb_->elaborate_expr(des, scope);
NetESubSignal*ss = new NetESubSignal(node, ex);
NetEBitSel*ss = new NetEBitSel(node, ex);
ss->set_line(*this);
return ss;
}
@@ -420,7 +504,7 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope) const
// If the identifier names a memory, then this is a
// memory reference and I must generate a NetEMemory
// object to handle it.
if (NetMemory*mem = des->find_memory(scope, text_)) {
if (NetMemory*mem = des->find_memory(scope, path_)) {
if (msb_ == 0) {
NetEMemory*node = new NetEMemory(mem);
node->set_line(*this);
@@ -449,8 +533,20 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope) const
return node;
}
// Finally, if this is a scope name, then return that.
if (NetScope*nsc = des->find_scope(text_)) {
// 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 ((path_.peek_name(1) == 0))
if (NetScope*nsc = scope->child(path_.peek_name(0))) {
NetEScope*tmp = new NetEScope(nsc);
tmp->set_line(*this);
return tmp;
}
// NOTE: This search pretty much assumes that text_ is a
// complete hierarchical name, since there is no mention of
// the current scope in the call to find_scope.
if (NetScope*nsc = des->find_scope(path_)) {
NetEScope*tmp = new NetEScope(nsc);
tmp->set_line(*this);
return tmp;
@@ -458,7 +554,7 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope) const
// I cannot interpret this identifier. Error message.
cerr << get_line() << ": error: Unable to bind wire/reg/memory "
"`" << text_ << "' in `" << scope->name() << "'" << endl;
"`" << path_ << "' in `" << scope->name() << "'" << endl;
des->errors += 1;
return 0;
}
@@ -540,122 +636,50 @@ NetEUnary* PEUnary::elaborate_expr(Design*des, NetScope*scope) const
tmp->set_line(*this);
break;
}
return tmp;
}
/*
* $Log: elab_expr.cc,v $
* 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.46 2001/12/03 04:47:14 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
*
* Allow parameters to be referenced by hierarchical name.
* Revision 1.45 2001/11/19 02:54:12 steve
* Handle division and modulus by zero while
* evaluating run-time constants.
*
* Revision 1.33 2001/01/13 22:20:08 steve
* Parse parameters within nested scopes.
* Revision 1.44 2001/11/19 01:54:14 steve
* Port close cropping behavior from mcrgb
* Move window array reset to libmc.
*
* Revision 1.32 2001/01/02 04:21:13 steve
* Support a bunch of unary operators in parameter expressions.
* Revision 1.43 2001/11/07 04:01:59 steve
* eval_const uses scope instead of a string path.
*
* Revision 1.31 2000/12/10 22:01:35 steve
* Support decimal constants in behavioral delays.
* Revision 1.42 2001/07/29 22:22:40 steve
* support local reference to scope in expressions.
*
* Revision 1.30 2000/11/29 05:24:00 steve
* synthesis for unary reduction ! and N operators.
* 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.29 2000/09/26 05:05:58 steve
* Detect indefinite widths where definite widths are required.
* 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.28 2000/09/24 17:41:13 steve
* fix null pointer when elaborating undefined task.
* Revision 1.39 2001/06/30 21:28:35 steve
* Detect parameter mismatches.
*
* Revision 1.27 2000/08/26 01:31:29 steve
* Handle out of range part select expressions.
* Revision 1.38 2001/06/23 19:53:03 steve
* Look up functor return register with tail of name.
*
* Revision 1.26 2000/05/19 01:55:09 steve
* Catch part select of memories as an error.
*
* Revision 1.25 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.24 2000/05/04 03:37:58 steve
* Add infrastructure for system functions, move
* $time to that structure and add $random.
*
* Revision 1.23 2000/05/02 03:13:30 steve
* Move memories to the NetScope object.
*
* Revision 1.22 2000/05/02 00:58:11 steve
* Move signal tables to the NetScope class.
*
* Revision 1.21 2000/04/28 18:43:23 steve
* integer division in expressions properly get width.
*
* Revision 1.20 2000/03/29 04:06:28 steve
* Forgot to return elaborate result (Dan Nelsen)
*
* Revision 1.19 2000/03/20 16:57:22 steve
* select correct bit when reg has non-zero lsb.
*
* Revision 1.18 2000/03/12 18:22:11 steve
* Binary and unary operators in parameter expressions.
*
* Revision 1.17 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.16 2000/02/23 02:56:54 steve
* Macintosh compilers do not support ident.
*
* Revision 1.15 2000/01/13 03:35:35 steve
* Multiplication all the way to simulation.
*
* Revision 1.14 2000/01/01 06:18:00 steve
* Handle synthesis of concatenation.
*
* Revision 1.13 1999/12/12 06:03:14 steve
* Allow memories without indices in expressions.
*
* Revision 1.12 1999/11/30 04:54:01 steve
* Match scope names as last resort.
*
* Revision 1.11 1999/11/28 23:42:02 steve
* NetESignal object no longer need to be NetNode
* objects. Let them keep a pointer to NetNet objects.
*
* Revision 1.10 1999/11/27 19:07:57 steve
* Support the creation of scopes.
*
* Revision 1.9 1999/11/21 17:35:37 steve
* Memory name lookup handles scopes.
*
* Revision 1.8 1999/11/10 02:52:24 steve
* Create the vpiMemory handle type.
*
* Revision 1.7 1999/10/18 00:02:21 steve
* Catch unindexed memory reference.
*
* Revision 1.6 1999/09/30 02:43:02 steve
* Elaborate ~^ and ~| operators.
*
* Revision 1.5 1999/09/30 00:48:49 steve
* Cope with errors during ternary operator elaboration.
*
* Revision 1.4 1999/09/29 22:57:10 steve
* Move code to elab_expr.cc
*
* Revision 1.3 1999/09/25 02:57:30 steve
* Parse system function calls.
*
* Revision 1.2 1999/09/21 00:13:40 steve
* Support parameters that reference other paramters.
*
* Revision 1.1 1999/09/20 02:21:10 steve
* Elaborate parameters in phases.
* Revision 1.37 2001/04/06 02:28:02 steve
* Generate vvp code for functions with ports.
*
* 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.
*/
+58 -61
View File
@@ -17,12 +17,16 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: elab_lval.cc,v 1.11 2001/01/10 03:13:23 steve Exp $"
#ident "$Id: elab_lval.cc,v 1.17 2001/12/03 04:47:14 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.
@@ -63,17 +67,14 @@
*/
NetAssign_* PExpr::elaborate_lval(Design*des, NetScope*scope) const
{
NetNet*ll = elaborate_net(des, scope->name(), 0, 0, 0, 0);
NetNet*ll = elaborate_net(des, scope, 0, 0, 0, 0);
if (ll == 0) {
cerr << get_line() << ": Assignment l-value too complex."
<< endl;
return 0;
}
NetAssign_*lv = new NetAssign_(scope->local_symbol(), ll->pin_count());
for (unsigned idx = 0 ; idx < ll->pin_count() ; idx += 1)
connect(lv->pin(idx), ll->pin(idx));
des->add_node(lv);
NetAssign_*lv = new NetAssign_(ll);
return lv;
}
@@ -112,42 +113,15 @@ NetAssign_* PEConcat::elaborate_lval(Design*des, NetScope*scope) const
assert(tmp);
/* If adjacent l-values in the concatenation are not bit
selects, then merge them into a single NetAssign_
object.
If we cannot merge, then just link the new one to the
previous one. */
/* Link the new l-value to the previous one. */
if (res && (res->bmux() == 0) && (tmp->bmux() == 0)) {
unsigned wid1 = tmp->pin_count();
unsigned wid2 = res->pin_count() + tmp->pin_count();
NetAssign_*tmp2 = new NetAssign_(res->name(), wid2);
NetAssign_*last = tmp;
while (last->more)
last = last->more;
assert(tmp->more == 0);
tmp2->more = res->more;
res->more = 0;
for (unsigned idx = 0 ; idx < wid1 ; idx += 1)
connect(tmp2->pin(idx), tmp->pin(idx));
for (unsigned idx = 0 ; idx < res->pin_count() ; idx += 1)
connect(tmp2->pin(idx+wid1), res->pin(idx));
delete res;
delete tmp;
res = tmp2;
des->add_node(res);
} else {
NetAssign_*last = tmp;
while (last->more)
last = last->more;
last->more = res;
res = tmp;
}
last->more = res;
res = tmp;
}
return res;
@@ -161,16 +135,16 @@ NetAssign_* PEIdent::elaborate_lval(Design*des, NetScope*scope) const
{
/* Get the signal referenced by the identifier, and make sure
it is a register. (Wires are not allows in this context. */
NetNet*reg = des->find_signal(scope, name());
NetNet*reg = des->find_signal(scope, path_);
if (reg == 0) {
NetMemory*mem = des->find_memory(scope, name());
NetMemory*mem = des->find_memory(scope, path_);
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() <<
<< path_ << "'' in ``" << scope->name() <<
"''" << endl;
}
des->errors += 1;
@@ -179,7 +153,7 @@ NetAssign_* PEIdent::elaborate_lval(Design*des, NetScope*scope) const
assert(reg);
if (reg->type() != NetNet::REG) {
cerr << get_line() << ": error: " << name() <<
cerr << get_line() << ": error: " << path_ <<
" is not a reg/integer/time in " << scope->name() <<
"." << endl;
des->errors += 1;
@@ -194,7 +168,7 @@ NetAssign_* PEIdent::elaborate_lval(Design*des, NetScope*scope) const
two bit select expressions, and both must be
constant. Evaluate them and pass the results back to
the caller. */
verinum*vl = lsb_->eval_const(des, scope->name());
verinum*vl = lsb_->eval_const(des, scope);
if (vl == 0) {
cerr << lsb_->get_line() << ": error: "
"Part select expressions must be constant: "
@@ -202,7 +176,7 @@ NetAssign_* PEIdent::elaborate_lval(Design*des, NetScope*scope) const
des->errors += 1;
return 0;
}
verinum*vm = msb_->eval_const(des, scope->name());
verinum*vm = msb_->eval_const(des, scope);
if (vl == 0) {
cerr << msb_->get_line() << ": error: "
"Part select expressions must be constant: "
@@ -223,7 +197,7 @@ NetAssign_* PEIdent::elaborate_lval(Design*des, NetScope*scope) const
expression it not constant, then return the
expression as a mux. */
assert(lsb_ == 0);
verinum*v = msb_->eval_const(des, scope->name());
verinum*v = msb_->eval_const(des, scope);
if (v == 0) {
NetExpr*m = msb_->elaborate_expr(des, scope);
assert(m);
@@ -255,13 +229,9 @@ NetAssign_* PEIdent::elaborate_lval(Design*des, NetScope*scope) const
if (mux) {
/* If there is a non-constant bit select, make a
NetAssign_ the width of the target reg and attach a
NetAssign_ to the target reg and attach a
bmux to select the target bit. */
unsigned wid = reg->pin_count();
lv = new NetAssign_(des->local_symbol(scope->name()), wid);
for (unsigned idx = 0 ; idx < wid ; idx += 1)
connect(lv->pin(idx), reg->pin(idx));
lv = new NetAssign_(reg);
lv->set_bmux(mux);
@@ -274,8 +244,6 @@ NetAssign_* PEIdent::elaborate_lval(Design*des, NetScope*scope) const
unsigned moff = reg->sb_to_idx(msb);
unsigned wid = moff - loff + 1;
lv = new NetAssign_(des->local_symbol(scope->name()), wid);
if (moff < loff) {
cerr << get_line() << ": error: part select "
<< reg->name() << "[" << msb<<":"<<lsb<<"]"
@@ -284,28 +252,57 @@ NetAssign_* PEIdent::elaborate_lval(Design*des, NetScope*scope) const
return 0;
}
if (wid > reg->pin_count()) {
cerr << get_line() << ": error: part select "
/* 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;
}
assert(moff < reg->pin_count());
for (unsigned idx = 0 ; idx < wid ; idx += 1)
connect(lv->pin(idx), reg->pin(idx+loff));
lv = new NetAssign_(reg);
lv->set_part(loff, wid);
assert(moff < reg->pin_count());
}
des->add_node(lv);
return lv;
}
/*
* $Log: elab_lval.cc,v $
* Revision 1.17 2001/12/03 04:47:14 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
*
* Revision 1.16 2001/11/08 05:15:50 steve
* Remove string paths from PExpr elaboration.
*
* Revision 1.15 2001/11/07 04:01:59 steve
* eval_const uses scope instead of a string path.
*
* Revision 1.14 2001/08/25 23:50:02 steve
* Change the NetAssign_ class to refer to the signal
* instead of link into the netlist. This is faster
* 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)
*
+273 -481
View File
File diff suppressed because it is too large Load Diff
+42 -9
View File
@@ -17,12 +17,16 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: elab_pexpr.cc,v 1.8 2001/01/14 23:04:56 steve Exp $"
#ident "$Id: elab_pexpr.cc,v 1.12 2001/12/03 04:47:14 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: "
@@ -73,7 +77,7 @@ NetEConcat* PEConcat::elaborate_pexpr(Design*des, NetScope*scope) const
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());
verinum*vrep = repeat_->eval_const(des, scope);
if (vrep == 0) {
cerr << get_line() << ": error: "
"concatenation repeat expression cannot be evaluated."
@@ -97,7 +101,22 @@ NetEConcat* PEConcat::elaborate_pexpr(Design*des, NetScope*scope) const
assert(parms_[idx]);
NetExpr*ex = parms_[idx]->elaborate_pexpr(des, scope);
if (ex == 0) continue;
ex->set_line(*parms_[idx]);
if (! ex->has_width()) {
cerr << ex->get_line() << ": error: operand of "
<< "concatenation has indefinite width: "
<< *ex << endl;
des->errors += 1;
} else if (ex->expr_width() == 0) {
cerr << ex->get_line() << ": internal error: "
<< "Operand of concatenation has no width: "
<< *ex << endl;
des->errors += 1;
}
tmp->set(idx, ex);
}
@@ -117,25 +136,25 @@ NetExpr*PEFNumber::elaborate_pexpr(Design*des, NetScope*scope) const
*/
NetExpr*PEIdent::elaborate_pexpr(Design*des, NetScope*scope) const
{
string path = text_;
string name = parse_last_name(path);
hname_t path = path_;
char*name = path.remove_tail_name();
NetScope*pscope = scope;
if (path != "")
if (path.peek_name(0))
pscope = des->find_scope(scope, path);
assert(pscope);
const NetExpr*ex = pscope->get_parameter(name);
if (ex == 0) {
cerr << get_line() << ": error: identifier ``" << text_ <<
cerr << get_line() << ": error: identifier ``" << path_ <<
"'' is not a parameter in " << scope->name() << "." << endl;
des->errors += 1;
delete name;
return 0;
}
NetExpr*res = new NetEParam(des, pscope, name);
NetExpr*res = new NetEParam(des, pscope, hname_t(name));
assert(res);
delete name;
return res;
}
@@ -199,6 +218,20 @@ NetExpr*PEUnary::elaborate_pexpr (Design*des, NetScope*scope) const
/*
* $Log: elab_pexpr.cc,v $
* Revision 1.12 2001/12/03 04:47:14 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
*
* Revision 1.11 2001/11/07 04:01:59 steve
* eval_const uses scope instead of a string path.
*
* Revision 1.10 2001/10/07 03:38:08 steve
* parameter names do not have defined size.
*
* Revision 1.9 2001/07/25 03:10:49 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
*
* 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.
+45 -13
View File
@@ -17,9 +17,13 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: elab_scope.cc,v 1.7 2000/12/16 01:45:48 steve Exp $"
#ident "$Id: elab_scope.cc,v 1.12 2001/12/03 04:47:14 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
@@ -51,6 +55,7 @@ bool Module::elaborate_scope(Design*des, NetScope*scope) const
// place of the elaborated expression.
typedef map<string,PExpr*>::const_iterator mparm_it_t;
typedef map<hname_t,PExpr*>::const_iterator hparm_it_t;
// This loop scans the parameters in the module, and creates
@@ -108,7 +113,7 @@ bool Module::elaborate_scope(Design*des, NetScope*scope) const
// here becuase the parameter receiving the assignment may be
// in a scope not discovered by this pass.
for (mparm_it_t cur = defparms.begin()
for (hparm_it_t cur = defparms.begin()
; cur != defparms.end() ; cur ++ ) {
PExpr*ex = (*cur).second;
@@ -130,7 +135,7 @@ bool Module::elaborate_scope(Design*des, NetScope*scope) const
for (tasks_it_t cur = tasks_.begin()
; cur != tasks_.end() ; cur ++ ) {
NetScope*task_scope = new NetScope(scope, (*cur).first,
NetScope*task_scope = new NetScope(scope, (*cur).first.c_str(),
NetScope::TASK);
(*cur).second->elaborate_scope(des, task_scope);
}
@@ -145,7 +150,7 @@ bool Module::elaborate_scope(Design*des, NetScope*scope) const
for (funcs_it_t cur = funcs_.begin()
; cur != funcs_.end() ; cur ++ ) {
NetScope*func_scope = new NetScope(scope, (*cur).first,
NetScope*func_scope = new NetScope(scope, (*cur).first.c_str(),
NetScope::FUNC);
(*cur).second->elaborate_scope(des, func_scope);
}
@@ -191,16 +196,21 @@ bool Module::elaborate_scope(Design*des, NetScope*scope) const
void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const
{
if (get_name() == "") {
cerr << get_line() << ": error: Instantiation of module "
<< mod->mod_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())) {
if (NetScope*tmp = sc->child(get_name())) {
cerr << get_line() << ": error: Instance/Scope name " <<
get_name() << " already used in this context." <<
endl;
@@ -216,11 +226,11 @@ void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const
if (scn->type() != NetScope::MODULE)
continue;
if (mod->get_name() != scn->module_name())
if (strcmp(mod->mod_name(), scn->module_name()) != 0)
continue;
cerr << get_line() << ": error: You cannot instantiate "
<< "module " << mod->get_name() << " within itself." << endl;
<< "module " << mod->mod_name() << " within itself." << endl;
cerr << get_line() << ": : The offending instance is "
<< sc->name() << "." << get_name() << " within "
@@ -231,8 +241,8 @@ void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const
}
// Create the new scope as a MODULE with my name.
NetScope*my_scope = new NetScope(sc, get_name(), NetScope::MODULE);
my_scope->set_module_name(mod->get_name().c_str());
NetScope*my_scope = new NetScope(sc, get_name().c_str(), NetScope::MODULE);
my_scope->set_module_name(mod->mod_name());
// Set time units and precision.
my_scope->time_unit(mod->time_unit);
@@ -297,7 +307,9 @@ void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const
/*
* The isn't really able to create new scopes, but it does create the
* event name in the current scope, so can be done during the
* elaborate_scope scan.
* elaborate_scope scan. Note that the name_ of the PEvent object has
* no hierarchy, but neither does the NetEvent, until it is stored in
* the NetScope object.
*/
void PEvent::elaborate_scope(Design*des, NetScope*scope) const
{
@@ -313,6 +325,9 @@ void PFunction::elaborate_scope(Design*des, NetScope*scope) const
void PTask::elaborate_scope(Design*des, NetScope*scope) const
{
assert(scope->type() == NetScope::TASK);
if (statement_)
statement_->elaborate_scope(des, scope);
}
@@ -335,7 +350,7 @@ void PBlock::elaborate_scope(Design*des, NetScope*scope) const
NetScope*my_scope = scope;
if (name_ != "") {
my_scope = new NetScope(scope, name_, bl_type_==BL_PAR
my_scope = new NetScope(scope, name_.c_str(), bl_type_==BL_PAR
? NetScope::FORK_JOIN
: NetScope::BEGIN_END);
}
@@ -444,6 +459,23 @@ void PWhile::elaborate_scope(Design*des, NetScope*scope) const
/*
* $Log: elab_scope.cc,v $
* Revision 1.12 2001/12/03 04:47:14 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
*
* Revision 1.11 2001/10/20 05:21:51 steve
* Scope/module names are char* instead of string.
*
* Revision 1.10 2001/10/09 02:01:04 steve
* Tasks can have sub-scopes.
*
* Revision 1.9 2001/07/25 03:10:49 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
*
* 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)
*
+152 -45
View File
@@ -17,15 +17,20 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: elab_sig.cc,v 1.10 2001/01/13 22:20:08 steve Exp $"
#ident "$Id: elab_sig.cc,v 1.18 2001/12/03 04:47:14 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"
/*
@@ -34,7 +39,7 @@
* within the port_t that have a matching name.
*/
static bool signal_is_in_port(const svector<Module::port_t*>&ports,
const string&name)
const hname_t&name)
{
for (unsigned idx = 0 ; idx < ports.count() ; idx += 1) {
@@ -48,7 +53,7 @@ static bool signal_is_in_port(const svector<Module::port_t*>&ports,
// together that form the port.
for (unsigned cc = 0 ; cc < pp->expr.count() ; cc += 1) {
assert(pp->expr[cc]);
if (pp->expr[cc]->name() == name)
if (pp->expr[cc]->path() == name)
return true;
}
}
@@ -62,22 +67,60 @@ bool Module::elaborate_sig(Design*des, NetScope*scope) const
// Get all the explicitly declared wires of the module and
// start the signals list with them.
const map<string,PWire*>&wl = get_wires();
const map<hname_t,PWire*>&wl = get_wires();
for (map<string,PWire*>::const_iterator wt = wl.begin()
// Scan all the ports of the module, and make sure that each
// is connected to wires that have port declarations.
for (unsigned idx = 0 ; idx < ports_.count() ; idx += 1) {
Module::port_t*pp = ports_[idx];
if (pp == 0)
continue;
map<hname_t,PWire*>::const_iterator wt;
for (unsigned cc = 0 ; cc < pp->expr.count() ; cc += 1) {
hname_t port_path (pp->expr[cc]->path());
wt = wl.find(port_path);
if (wt == wl.end()) {
cerr << get_line() << ": error: "
<< "Port " << pp->expr[cc]->path() << " ("
<< (idx+1) << ") of module " << name_
<< " is not declared within module." << endl;
des->errors += 1;
continue;
}
if ((*wt).second->get_port_type() == NetNet::NOT_A_PORT) {
cerr << get_line() << ": error: "
<< "Port " << pp->expr[cc]->path() << " ("
<< (idx+1) << ") of module " << name_
<< " has no direction declaration."
<< endl;
des->errors += 1;
}
}
}
for (map<hname_t,PWire*>::const_iterator wt = wl.begin()
; wt != wl.end()
; wt ++ ) {
PWire*cur = (*wt).second;
cur->elaborate_sig(des, scope);
NetNet*sig = scope->find_signal_in_child(cur->path());
// If this wire is a signal of the module (as opposed to
// a port of a function) and is a port, then check that
// the module knows about it.
NetNet*sig = scope->find_signal(cur->name());
// the module knows about it. We know that the signal is
// the name of a signal within a subscope of a module
// (a task, a function, etc.) if the name for the PWire
// has hierarchy.
if (sig && (sig->scope() == scope)
&& (cur->get_port_type() != NetNet::NOT_A_PORT)) {
string name = (*wt).first;
hname_t name = (*wt).first;
if (! signal_is_in_port(ports_, name)) {
@@ -87,6 +130,33 @@ bool Module::elaborate_sig(Design*des, NetScope*scope) const
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->path() << " 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->path() << " 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
@@ -189,12 +259,13 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const
name. We know by design that the port name is given
as two components: <func>.<port>. */
string pname = (*ports_)[idx]->name();
string ppath = parse_first_name(pname);
hname_t path = (*ports_)[idx]->path();
string pname = path.peek_name(1);
string ppath = path.peek_name(0);
if (ppath != scope->basename()) {
cerr << get_line() << ": internal error: function "
<< "port " << (*ports_)[idx]->name()
<< "port " << (*ports_)[idx]->path()
<< " has wrong name for function "
<< scope->name() << "." << endl;
des->errors += 1;
@@ -237,16 +308,15 @@ void PTask::elaborate_sig(Design*des, NetScope*scope) const
name. We know by design that the port name is given
as two components: <task>.<port>. */
string pname = (*ports_)[idx]->name();
string ppath = parse_first_name(pname);
assert(pname != "");
hname_t path = (*ports_)[idx]->path();
assert(path.peek_name(0) && path.peek_name(1));
/* check that the current scope really does have the
name of the first component of the task port name. Do
this by looking up the task scope in the parent of
the current scope. */
if (scope->parent()->child(ppath) != scope) {
cerr << "internal error: task scope " << ppath
if (scope->parent()->child(path.peek_name(0)) != scope) {
cerr << "internal error: task scope " << path
<< " not the same as scope " << scope->name()
<< "?!" << endl;
return;
@@ -255,11 +325,11 @@ void PTask::elaborate_sig(Design*des, NetScope*scope) const
/* Find the signal for the port. We know by definition
that it is in the scope of the task, so look only in
the scope. */
NetNet*tmp = scope->find_signal(pname);
NetNet*tmp = scope->find_signal(path.peek_name(1));
if (tmp == 0) {
cerr << get_line() << ": internal error: "
<< "Could not find port " << pname
<< "Could not find port " << path.peek_name(1)
<< " in scope " << scope->name() << endl;
scope->dump(cerr);
}
@@ -288,19 +358,14 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
/* The parser may produce hierarchical names for wires. I here
follow the scopes down to the base where I actually want to
elaborate the NetNet object. */
string basename = name_;
for (;;) {
string p = parse_first_name(basename);
if (basename == "") {
basename = p;
break;
}
scope = scope->child(p);
assert(scope);
{ hname_t tmp_path = hname_;
free(tmp_path.remove_tail_name());
for (unsigned idx = 0 ; tmp_path.peek_name(idx) ; idx += 1) {
scope = scope->child(tmp_path.peek_name(idx));
assert(scope);
}
}
const string path = scope->name();
NetNet::Type wtype = type_;
if (wtype == NetNet::IMPLICIT)
wtype = NetNet::WIRE;
@@ -310,6 +375,7 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
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());
@@ -320,27 +386,35 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
here. I will resolve the values later. */
for (unsigned idx = 0 ; idx < msb_.count() ; idx += 1) {
verinum*mval = msb_[idx]->eval_const(des,path);
if (mval == 0) {
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;
}
verinum*lval = lsb_[idx]->eval_const(des, path);
if (lval == 0) {
cerr << lsb_[idx]->get_line() << ": error: "
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;
}
mnum[idx] = mval->as_long();
lnum[idx] = lval->as_long();
delete mval;
delete lval;
lnum[idx] = tmp->value().as_long();
delete texpr;
}
/* Make sure all the values for msb and lsb match by
@@ -350,7 +424,7 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
cerr << get_line() << ": error: Inconsistent width, "
"[" << mnum[idx] << ":" << lnum[idx] << "]"
" vs. [" << mnum[0] << ":" << lnum[0] << "]"
" for signal ``" << basename << "''" << endl;
" for signal ``" << hname_ << "''" << endl;
des->errors += 1;
return;
}
@@ -371,13 +445,13 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
// If the register has indices, then this is a
// memory. Create the memory object.
verinum*lval = lidx_->eval_const(des, path);
verinum*rval = ridx_->eval_const(des, path);
verinum*lval = lidx_->eval_const(des, scope);
verinum*rval = ridx_->eval_const(des, scope);
if ((lval == 0) || (rval == 0)) {
cerr << get_line() << ": internal error: There is "
<< "a problem evaluating indices for ``"
<< basename << "''." << endl;
<< hname_.peek_tail_name() << "''." << endl;
des->errors += 1;
return;
}
@@ -385,16 +459,22 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
assert(lval);
assert(rval);
string name = scope->name();
name = name + "." + hname_.peek_tail_name();
long lnum = lval->as_long();
long rnum = rval->as_long();
delete lval;
delete rval;
NetMemory*sig = new NetMemory(scope, path+"."+basename,
wid, lnum, rnum);
NetMemory*sig = new NetMemory(scope, name, wid, lnum, rnum);
} else {
NetNet*sig = new NetNet(scope, path + "." +basename, wtype, msb, lsb);
/* Make a hierarchical make for the signal. */
string name = scope->name();
name = name + "." + hname_.peek_tail_name();
NetNet*sig = new NetNet(scope, name, wtype, msb, lsb);
sig->set_line(*this);
sig->port_type(port_type_);
sig->set_signed(get_signed());
@@ -404,6 +484,33 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
/*
* $Log: elab_sig.cc,v $
* Revision 1.18 2001/12/03 04:47:14 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
*
* Revision 1.17 2001/11/07 04:01:59 steve
* eval_const uses scope instead of a string path.
*
* Revision 1.16 2001/11/01 05:21:26 steve
* Catch ports that have no direction.
*
* Revision 1.15 2001/10/31 03:11:15 steve
* detect module ports not declared within the module.
*
* Revision 1.14 2001/07/25 03:10:49 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
*
* 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.
*
+383 -481
View File
File diff suppressed because it is too large Load Diff
+50 -19
View File
@@ -17,9 +17,13 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: emit.cc,v 1.55 2000/11/04 01:54:01 steve Exp $"
#ident "$Id: emit.cc,v 1.63 2001/10/19 21:53:24 steve Exp $"
#endif
# include "config.h"
# include <iostream>
/*
* The emit function is called to generate the output required of the
* target.
@@ -41,12 +45,6 @@ bool NetLogic::emit_node(struct target_t*tgt) const
return true;
}
bool NetUDP_COMB::emit_node(struct target_t*tgt) const
{
tgt->udp_comb(this);
return true;
}
bool NetUDP::emit_node(struct target_t*tgt) const
{
tgt->udp(this);
@@ -59,12 +57,6 @@ bool NetAddSub::emit_node(struct target_t*tgt) const
return true;
}
bool NetAssign_::emit_node(struct target_t*tgt) const
{
tgt->net_assign(this);
return true;
}
bool NetCaseCmp::emit_node(struct target_t*tgt) const
{
tgt->net_case_cmp(this);
@@ -354,10 +346,10 @@ void NetScope::emit_defs(struct target_t*tgt) const
break;
case FUNC:
tgt->func_def(this->func_def());
tgt->func_def(this);
break;
case TASK:
tgt->task_def(this->task_def());
tgt->task_def(this);
break;
}
@@ -377,7 +369,9 @@ bool Design::emit(struct target_t*tgt) const
return false;
// enumerate the scopes
root_scope_->emit_scope(tgt);
for (list<NetScope*>::const_iterator scope = root_scopes_.begin();
scope != root_scopes_.end(); scope++)
(*scope)->emit_scope(tgt);
// emit nodes
@@ -391,14 +385,18 @@ bool Design::emit(struct target_t*tgt) const
// emit task and function definitions
root_scope_->emit_defs(tgt);
for (list<NetScope*>::const_iterator scope = root_scopes_.begin();
scope != root_scopes_.end(); scope++)
(*scope)->emit_defs(tgt);
// emit the processes
for (const NetProcTop*idx = procs_ ; idx ; idx = idx->next_)
rc = rc && idx->emit(tgt);
tgt->end_design(this);
if (tgt->end_design(this) != 0)
rc = false;
return rc;
}
@@ -448,7 +446,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);
}
@@ -476,6 +474,39 @@ bool emit(const Design*des, const char*type)
/*
* $Log: emit.cc,v $
* Revision 1.63 2001/10/19 21:53:24 steve
* Support multiple root modules (Philip Blundell)
*
* Revision 1.62 2001/08/25 23:50:02 steve
* Change the NetAssign_ class to refer to the signal
* instead of link into the netlist. This is faster
* 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.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.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.59 2001/04/22 23:09:46 steve
* More UDP consolidation from Stephan Boettcher.
*
* Revision 1.58 2001/04/06 02:28:02 steve
* Generate vvp code for functions with ports.
*
* Revision 1.57 2001/04/02 02:28:12 steve
* Generate code for task calls.
*
* Revision 1.56 2001/03/27 03:31:06 steve
* Support error code from target_t::end_design method.
*
* Revision 1.55 2000/11/04 01:54:01 steve
* Modifications in support of gcc 2.96
*
+37 -72
View File
@@ -17,28 +17,31 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: eval.cc,v 1.19 2001/01/27 05:41:48 steve Exp $"
#ident "$Id: eval.cc,v 1.24 2001/12/03 04:47:15 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
verinum* PExpr::eval_const(const Design*, const NetScope*) const
{
return 0;
}
verinum* PEBinary::eval_const(const Design*des, const string&path) const
verinum* PEBinary::eval_const(const Design*des, const NetScope*scope) const
{
verinum*l = left_->eval_const(des, path);
verinum*l = left_->eval_const(des, scope);
if (l == 0) return 0;
verinum*r = right_->eval_const(des, path);
verinum*r = right_->eval_const(des, scope);
if (r == 0) {
delete l;
return 0;
}
verinum*res;
switch (op_) {
@@ -110,11 +113,10 @@ verinum* PEBinary::eval_const(const Design*des, const string&path) const
* Evaluate an identifier as a constant expression. This is only
* possible if the identifier is that of a parameter.
*/
verinum* PEIdent::eval_const(const Design*des, const string&path) const
verinum* PEIdent::eval_const(const Design*des, const NetScope*scope) const
{
const NetScope*scope = des->find_scope(path);
assert(scope);
const NetExpr*expr = des->find_parameter(scope, text_);
const NetExpr*expr = des->find_parameter(scope, path_);
if (expr == 0)
return 0;
@@ -123,7 +125,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;
path_ << "'' in this scope: " << scope->name() << endl;
return 0;
}
@@ -132,20 +134,20 @@ 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
verinum* PEFNumber::eval_const(const Design*, const NetScope*) const
{
long val = value_->as_long();
return new verinum(val);
}
verinum* PENumber::eval_const(const Design*, const string&) const
verinum* PENumber::eval_const(const Design*, const NetScope*) const
{
return new verinum(value());
}
verinum* PETernary::eval_const(const Design*des, const string&path) const
verinum* PETernary::eval_const(const Design*des, const NetScope*scope) const
{
verinum*test = expr_->eval_const(des, path);
verinum*test = expr_->eval_const(des, scope);
if (test == 0)
return 0;
@@ -153,9 +155,9 @@ verinum* PETernary::eval_const(const Design*des, const string&path) const
delete test;
switch (bit) {
case verinum::V0:
return fal_->eval_const(des, path);
return fal_->eval_const(des, scope);
case verinum::V1:
return tru_->eval_const(des, path);
return tru_->eval_const(des, scope);
default:
return 0;
// XXXX It is possible to handle this case if both fal_
@@ -163,9 +165,9 @@ verinum* PETernary::eval_const(const Design*des, const string&path) const
}
}
verinum* PEUnary::eval_const(const Design*des, const string&path) const
verinum* PEUnary::eval_const(const Design*des, const NetScope*scope) const
{
verinum*val = expr_->eval_const(des, path);
verinum*val = expr_->eval_const(des, scope);
if (val == 0)
return 0;
@@ -194,6 +196,23 @@ verinum* PEUnary::eval_const(const Design*des, const string&path) const
/*
* $Log: eval.cc,v $
* Revision 1.24 2001/12/03 04:47:15 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
*
* Revision 1.23 2001/11/07 04:01:59 steve
* eval_const uses scope instead of a string path.
*
* Revision 1.22 2001/11/06 06:11:55 steve
* Support more real arithmetic in delay constants.
*
* Revision 1.21 2001/07/25 03:10:49 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
*
* 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)
*
@@ -211,59 +230,5 @@ verinum* PEUnary::eval_const(const Design*des, const string&path) const
*
* Revision 1.15 2000/09/07 22:38:13 steve
* Support unary + and - in constants.
*
* Revision 1.14 2000/03/08 04:36:53 steve
* Redesign the implementation of scopes and parameters.
* I now generate the scopes and notice the parameters
* in a separate pass over the pform. Once the scopes
* are generated, I can process overrides and evalutate
* paremeters before elaboration begins.
*
* Revision 1.13 2000/02/23 02:56:54 steve
* Macintosh compilers do not support ident.
*
* Revision 1.12 1999/11/30 04:48:17 steve
* Handle evaluation of ternary during elaboration.
*
* Revision 1.11 1999/11/28 23:42:02 steve
* NetESignal object no longer need to be NetNode
* objects. Let them keep a pointer to NetNet objects.
*
* Revision 1.10 1999/11/21 20:03:24 steve
* Handle multiply in constant expressions.
*
* Revision 1.9 1999/10/08 17:48:09 steve
* Support + in constant expressions.
*
* Revision 1.8 1999/09/20 02:21:10 steve
* Elaborate parameters in phases.
*
* Revision 1.7 1999/09/18 01:52:48 steve
* Remove spurious message.
*
* Revision 1.6 1999/09/16 04:18:15 steve
* elaborate concatenation repeats.
*
* Revision 1.5 1999/08/06 04:05:28 steve
* Handle scope of parameters.
*
* Revision 1.4 1999/07/17 19:51:00 steve
* netlist support for ternary operator.
*
* Revision 1.3 1999/05/30 01:11:46 steve
* Exressions are trees that can duplicate, and not DAGS.
*
* Revision 1.2 1999/05/10 00:16:58 steve
* Parse and elaborate the concatenate operator
* in structural contexts, Replace vector<PExpr*>
* and list<PExpr*> with svector<PExpr*>, evaluate
* constant expressions with parameters, handle
* memories as lvalues.
*
* Parse task declarations, integer types.
*
* Revision 1.1 1998/11/03 23:28:58 steve
* Introduce verilog to CVS.
*
*/
+56 -1
View File
@@ -17,9 +17,11 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: eval_rconst.cc,v 1.1 2001/01/14 23:04:56 steve Exp $"
#ident "$Id: eval_rconst.cc,v 1.4 2001/11/07 04:01:59 steve Exp $"
#endif
# include "config.h"
# include "PExpr.h"
verireal* PExpr::eval_rconst(const Design*, const NetScope*) const
@@ -34,8 +36,61 @@ verireal* PEFNumber::eval_rconst(const Design*, const NetScope*) const
return res;
}
verireal* PENumber::eval_rconst(const Design*, const NetScope*) const
{
verireal*res = new verireal(value_->as_long());
return res;
}
verireal* PEBinary::eval_rconst(const Design*des, const NetScope*scope) const
{
verireal*lef = left_->eval_rconst(des, scope);
verireal*rig = right_->eval_rconst(des, scope);
verireal*res = 0;
switch (op_) {
case '*':
if (lef == 0)
break;
if (rig == 0)
break;
res = new verireal;
*res = (*lef) * (*rig);
break;
default:
break;
}
delete lef;
delete rig;
return res;
}
verireal* PEIdent::eval_rconst(const Design*des, const NetScope*scope) const
{
verinum* val = eval_const(des, scope);
if (val == 0)
return 0;
verireal*res = new verireal(val->as_long());
delete val;
return res;
}
/*
* $Log: eval_rconst.cc,v $
* Revision 1.4 2001/11/07 04:01:59 steve
* eval_const uses scope instead of a string path.
*
* Revision 1.3 2001/11/06 06:11:55 steve
* Support more real arithmetic in delay constants.
*
* Revision 1.2 2001/07/25 03:10:49 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
*
* 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.
+267 -56
View File
@@ -17,9 +17,13 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: eval_tree.cc,v 1.21 2001/01/14 23:04:56 steve Exp $"
#ident "$Id: eval_tree.cc,v 1.30 2001/12/03 04:47:15 steve Exp $"
#endif
# include "config.h"
# include <iostream>
# include "netlist.h"
NetExpr* NetExpr::eval_tree()
@@ -112,11 +116,11 @@ NetEConst* NetEBBits::eval_tree()
if (lwid < rwid)
for (unsigned idx = lwid ; idx < rwid ; idx += 1)
res.set(idx, lval.get(idx));
res.set(idx, rval.get(idx));
if (rwid < lwid)
for (unsigned idx = rwid ; idx < lwid ; idx += 1)
res.set(idx, rval.get(idx));
res.set(idx, lval.get(idx));
break;
}
@@ -148,19 +152,78 @@ NetEConst* NetEBComp::eval_eqeq_()
const verinum&lv = l->value();
const verinum&rv = r->value();
if (lv.len() < rv.len())
return 0;
unsigned s_len = lv.len();
if (rv.len() < s_len) s_len = rv.len();
verinum result(verinum::V1, 1);
for (unsigned idx = 0 ; idx < lv.len(); idx += 1) {
for (unsigned idx = 0 ; idx < s_len; idx += 1) {
if (lv[idx] != rv[idx])
result = verinum::V0;
}
// If one operand was wider than the other, check that the
// remaining bits are all zero
if (lv.len() > s_len) {
for (unsigned idx = s_len; idx < lv.len(); idx += 1) {
if (lv[idx] != 0)
result = verinum::V0;
}
}
if (rv.len() > s_len) {
for (unsigned idx = s_len; idx < rv.len(); idx += 1) {
if (rv[idx] != 0)
result = verinum::V0;
}
}
return new NetEConst(result);
}
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_);
@@ -205,6 +268,92 @@ NetEConst* NetEBComp::eval_leeq_()
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_);
@@ -349,6 +498,9 @@ NetEConst* NetEBComp::eval_tree()
case 'e': // Equality (==)
return eval_eqeq_();
case 'G': // >=
return eval_gteq_();
case 'L': // <=
return eval_leeq_();
@@ -358,14 +510,41 @@ NetEConst* NetEBComp::eval_tree()
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;
}
@@ -544,6 +723,18 @@ NetEConst* 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);
@@ -573,7 +764,8 @@ NetExpr* NetEParam::eval_tree()
return 0;
assert(scope_);
const NetExpr*expr = scope_->get_parameter(name_);
assert(name_.peek_name(1) == 0);
const NetExpr*expr = scope_->get_parameter(name_.peek_name(0));
if (expr == 0) {
cerr << get_line() << ": internal error: Unable to match "
<< "parameter " << name_ << " in scope "
@@ -601,7 +793,7 @@ NetExpr* NetEParam::eval_tree()
// The result can be saved as the value of the parameter for
// future reference, and return a copy to the caller.
scope_->set_parameter(name_, res);
scope_->set_parameter(name_.peek_name(0), res);
return res->dup_expr();
}
@@ -616,48 +808,49 @@ NetExpr* NetETernary::eval_tree()
{
NetExpr*tmp;
/* Evaluate the cond_ to a constant. If it already is a
constant, then there is nothing to do. */
assert(cond_);
if (0 == dynamic_cast<NetEConst*>(cond_)) {
tmp = cond_->eval_tree();
if (tmp != 0) {
delete cond_;
cond_ = tmp;
}
}
assert(true_val_);
if (0 == dynamic_cast<NetEConst*>(true_val_)) {
tmp = true_val_->eval_tree();
if (tmp != 0) {
delete true_val_;
true_val_ = tmp;
}
}
assert(false_val_);
if (0 == dynamic_cast<NetEConst*>(false_val_)) {
tmp = false_val_->eval_tree();
if (tmp != 0) {
delete false_val_;
false_val_ = tmp;
}
}
NetEConst*c = dynamic_cast<NetEConst*>(cond_);
if (c == 0) {
tmp = cond_->eval_tree();
c = dynamic_cast<NetEConst*>(tmp);
if (c == 0)
return 0;
if (c == 0)
return 0;
assert(cond_ != c);
delete cond_;
cond_ = c;
}
/* If the condition is 1 or 0, return the true or false
expression. Try to evaluate the expression down as far as
we can. */
if (c->value().get(0) == verinum::V1) {
tmp = dynamic_cast<NetEConst*>(true_val_);
if (tmp) return tmp->dup_expr();
tmp = true_val_->eval_tree();
if (tmp) {
delete true_val_;
true_val_ = tmp;
}
if (c->value().get(0) == verinum::V1)
return true_val_->dup_expr();
}
if (c->value().get(0) == verinum::V0) {
tmp = dynamic_cast<NetEConst*>(false_val_);
if (tmp) return tmp->dup_expr();
tmp = false_val_->eval_tree();
if (tmp) {
delete false_val_;
false_val_ = tmp;
}
if (c->value().get(0) == verinum::V0)
return false_val_->dup_expr();
}
/* Here we have a more complex case. We need to evaluate both
@@ -665,27 +858,14 @@ NetExpr* NetETernary::eval_tree()
build up a constant result. */
NetEConst*t = dynamic_cast<NetEConst*>(true_val_);
if (t == 0) {
tmp = true_val_->eval_tree();
t = dynamic_cast<NetEConst*>(tmp);
if (t == 0)
return 0;
delete true_val_;
true_val_ = t;
}
if (t == 0)
return 0;
NetEConst*f = dynamic_cast<NetEConst*>(false_val_);
if (f == 0) {
tmp = false_val_->eval_tree();
f = dynamic_cast<NetEConst*>(tmp);
if (f == 0)
return 0;
if (f == 0)
return 0;
delete false_val_;
false_val_ = f;
}
unsigned size = t->expr_width();
assert(size == f->expr_width());
@@ -708,6 +888,7 @@ NetExpr* NetETernary::eval_tree()
void NetEUnary::eval_expr_()
{
assert(expr_);
if (dynamic_cast<NetEConst*>(expr_))
return;
@@ -751,7 +932,6 @@ NetEConst* NetEUnary::eval_tree()
}
default:
delete rval;
return 0;
}
}
@@ -822,6 +1002,37 @@ NetEConst* NetEUReduce::eval_tree()
/*
* $Log: eval_tree.cc,v $
* Revision 1.30 2001/12/03 04:47:15 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
*
* Revision 1.29 2001/11/19 01:54:14 steve
* Port close cropping behavior from mcrgb
* Move window array reset to libmc.
*
* Revision 1.28 2001/10/22 15:31:21 steve
* fix constant overrun in | operands.
*
* Revision 1.27 2001/10/20 00:11:24 steve
* Evaluate constant == when operands differ in width.
*
* Revision 1.26 2001/07/25 03:10:49 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
*
* 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.
+167 -18
View File
@@ -17,11 +17,15 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: expr_synth.cc,v 1.19 2001/01/18 03:16:35 steve Exp $"
#ident "$Id: expr_synth.cc,v 1.29 2001/11/29 01:58:18 steve Exp $"
#endif
# include "netlist.h"
# include "config.h"
# include <iostream>
# include "netlist.h"
# include "netmisc.h"
NetNet* NetExpr::synthesize(Design*des)
{
@@ -38,17 +42,17 @@ 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();
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));
@@ -83,6 +87,17 @@ NetNet* NetEBBits::synthesize(Design*des)
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(scope, path, NetNet::IMPLICIT,
lsig->pin_count());
@@ -124,6 +139,50 @@ NetNet* NetEBBits::synthesize(Design*des)
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);
@@ -135,6 +194,9 @@ NetNet* NetEBComp::synthesize(Design*des)
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);
@@ -164,7 +226,7 @@ NetNet* NetEBComp::synthesize(Design*des)
}
NetCompare*dev = new NetCompare(des->local_symbol(path), width);
NetCompare*dev = new NetCompare(scope, des->local_symbol(path), width);
des->add_node(dev);
for (unsigned idx = 0 ; idx < lsig->pin_count() ; idx += 1)
@@ -291,27 +353,36 @@ NetNet* NetEBLogic::synthesize(Design*des)
NetNet* NetEConcat::synthesize(Design*des)
{
NetScope*scope = des->find_root_scope();
assert(scope);
assert(repeat_ == 1);
/* First, synthesize the operands. */
NetNet**tmp = new NetNet*[parms_.count()];
for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1)
tmp[idx] = parms_[idx]->synthesize(des);
string path = des->local_symbol("SYNTH");
assert(tmp[0]);
NetScope*scope = tmp[0]->scope();
assert(scope);
/* Make a NetNet object to carry the output vector. */
string path = scope->name() + "." + scope->local_symbol();
NetNet*osig = new NetNet(scope, path, NetNet::IMPLICIT, expr_width());
osig->local_flag(true);
/* Connect the output vector to the operands. */
unsigned obit = 0;
for (unsigned idx = parms_.count() ; idx > 0 ; idx -= 1) {
NetNet*tmp = parms_[idx-1]->synthesize(des);
for (unsigned bit = 0 ; bit < tmp->pin_count() ; bit += 1) {
connect(osig->pin(obit), tmp->pin(bit));
assert(tmp[idx-1]);
for (unsigned bit = 0; bit < tmp[idx-1]->pin_count(); bit += 1) {
connect(osig->pin(obit), tmp[idx-1]->pin(bit));
obit += 1;
}
if (tmp->local_flag() && tmp->get_eref() == 0)
delete tmp;
if (tmp[idx-1]->local_flag() && tmp[idx-1]->get_eref() == 0)
delete tmp[idx-1];
}
delete[]tmp;
return osig;
}
@@ -320,12 +391,12 @@ NetNet* NetEConst::synthesize(Design*des)
NetScope*scope = des->find_root_scope();
assert(scope);
string path = des->local_symbol("SYNTH");
string path = scope->name() + "." + scope->local_symbol();
unsigned width=expr_width();
NetNet*osig = new NetNet(scope, path, NetNet::IMPLICIT, width);
osig->local_flag(true);
NetConst*con = new NetConst(des->local_symbol(path), value());
NetConst*con = new NetConst(scope, des->local_symbol(path), value());
for (unsigned idx = 0 ; idx < width; idx += 1)
connect(osig->pin(idx), con->pin(idx));
@@ -413,11 +484,12 @@ NetNet* NetEUReduce::synthesize(Design*des)
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();
@@ -437,13 +509,90 @@ NetNet* NetETernary::synthesize(Design *des)
return osig;
}
/*
* When synthesizing a signal expression, it is usually fine to simply
* return the NetNet that it refers to. If this is a part select,
* though, a bit more work needs to be done. Return a temporary that
* represents the connections to the selected bits.
*
* 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.29 2001/11/29 01:58:18 steve
* Handle part selects in l-values of DFF devices.
*
* Revision 1.28 2001/10/28 01:14:53 steve
* NetObj constructor finally requires a scope.
*
* Revision 1.27 2001/10/20 05:21:51 steve
* Scope/module names are char* instead of string.
*
* Revision 1.26 2001/08/31 22:59:48 steve
* synthesize the special case of compare with 0.
*
* 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)
*
+15 -2
View File
@@ -17,9 +17,13 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: functor.cc,v 1.24 2000/11/19 20:48:30 steve Exp $"
#ident "$Id: functor.cc,v 1.26 2001/10/19 21:53:24 steve Exp $"
#endif
# include "config.h"
# include <iostream>
# include "functor.h"
# include "netlist.h"
@@ -110,7 +114,9 @@ void NetScope::run_functor(Design*des, functor_t*fun)
void Design::functor(functor_t*fun)
{
// Scan the scopes
root_scope_->run_functor(this, fun);
for (list<NetScope*>::const_iterator scope = root_scopes_.begin();
scope != root_scopes_.end(); scope++)
(*scope)->run_functor(this, fun);
// apply to processes
procs_idx_ = procs_;
@@ -282,6 +288,13 @@ int proc_match_t::event_wait(NetEvWait*)
/*
* $Log: functor.cc,v $
* Revision 1.26 2001/10/19 21:53:24 steve
* Support multiple root modules (Philip Blundell)
*
* Revision 1.25 2001/07/25 03:10:49 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
*
* Revision 1.24 2000/11/19 20:48:30 steve
* Fix cases where signal iteration might die early.
*
+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.
+130 -1
View File
@@ -139,6 +139,13 @@ 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
@@ -197,9 +204,131 @@ well as all the other major Verilog tools, but the standard does not
say this.
* UNSIZED EXPRESSIONS AS PARAMETERS TO CONCATENATION {}
$Id: ieee1364-notes.txt,v 1.5 2001/01/02 17:28:08 steve Exp $
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.
+22 -6
View File
@@ -43,6 +43,9 @@
#
# %W Substitute the ivl warning flags.
#
# %y Substitute all the -y flags here.
# %Y Substitute all the -Y flags here.
#
# %[<c><text>]
# This substitution pattern is magical, and is the only
# multicharacter pattern. This tests the code <c>, and
@@ -56,10 +59,20 @@
# be useful and interesting if the -N flag is included.
[-tnull -S]
<ivl>%B/ivl %W %[s-s%s] %[N-N%N] %[T-T%T] -tdll -fDLL=%B/null.tgt -- -
<ivl>%B/ivl %[v-v] %y %Y %W %s %[N-N%N] %[T-T%T] -tdll -fDLL=%B/null.tgt -Fsynth -Fsyn-rules -- -
[-tnull]
<ivl>%B/ivl %W %[s-s%s] %[N-N%N] %[T-T%T] -tdll -fDLL=%B/null.tgt -- -
<ivl>%B/ivl %[v-v] %y %Y %W %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] %y %Y %W %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] %y %Y %W %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
@@ -68,17 +81,20 @@
# on the result.
[-tvvm]
<ivl>%B/ivl %W %[s-s%s] %[N-N%N] %[T-T%T] -tvvm -Fcprop -Fnodangle -fVPI_MODULE_PATH=%B %f %m -o%o.cc -- -
<ivl>%B/ivl %[v-v] %y %Y %W %s %[N-N%N] %[T-T%T] -tvvm -Fcprop -Fnodangle -fVPI_MODULE_PATH=%B %f %m -o%o.cc -- -
# -- (not supported yet)
# This is the XNF code generator.
[-txnf]
<ivl>%B/ivl %[s-s%s] %[N-N%N] %[T-T%T] -tvvm -Fsynth -Fsyn-rules -Fcprop -Fnodangle -o%o -- -
<ivl>%B/ivl %y %Y %[v-v] %s %[N-N%N] %[T-T%T] -txnf -Fsynth -Fsyn-rules -Fxnfio -Fcprop -Fnodangle -o%o -- -
# And this is another XNF code generator, under development.
[-tfpga]
<ivl>%B/ivl %y %Y %[v-v] %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 %[s-s%s] %[N-N%N] %[T-T%T] -tdll -fDLL=%B/pal.tgt -Fsynth -Fsyn-rules -Fcprop -Fnodangle -o%o -- -
<ivl>%B/ivl %y %Y %[v-v] %s %[N-N%N] %[T-T%T] -tdll -fDLL=%B/pal.tgt -Fsynth -Fsyn-rules -Fcprop -Fnodangle -o%o -- -
+77 -6
View File
@@ -1,16 +1,32 @@
EXPORTS
ivl_design_const
ivl_design_consts
ivl_design_flag
ivl_design_process
ivl_design_root
ivl_design_roots
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
@@ -19,44 +35,82 @@ 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_attr
ivl_logic_delay
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_lpm_ff
ivl_lpm_ff_clk
ivl_lpm_ff_data
ivl_lpm_ff_q
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
@@ -66,26 +120,43 @@ 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_type
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_nexus
ivl_stmt_nexus_count
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
+554 -64
View File
@@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: ivl_target.h,v 1.34 2001/01/15 22:05:14 steve Exp $"
#ident "$Id: ivl_target.h,v 1.89 2001/12/06 03:11:00 steve Exp $"
#endif
#ifdef __cplusplus
@@ -61,6 +61,11 @@ _BEGIN_DECL
* This object represents the entire elaborated design. Various
* global properties and methods are available from this.
*
* ivl_event_t
* This object represents an event node. An event node stands for
* named events written explicitly in the Verilog, and net events
* that are implicit when @ statements are used.
*
* ivl_expr_t
* This object represents a node of an expression. If the
* expression has sub-expressions, they can be accessed from
@@ -77,12 +82,6 @@ _BEGIN_DECL
* device nodes. This object carries a few base properties
* (including a type) including a handle to the specific type.
*
* All the ivl_lpm_*_t objects are derived from this type, and
* there are methods to get one from the other.
*
* ivl_lpm_ff_t
* This is a flip-flop.
*
* ivl_net_logic_t
* This object represents various built in logic devices. In fact,
* this includes just about every directional device that has a
@@ -123,19 +122,20 @@ _BEGIN_DECL
* they include the instance name of the module that contains them.
*/
typedef struct ivl_design_s *ivl_design_t;
typedef struct ivl_event_s *ivl_event_t;
typedef struct ivl_expr_s *ivl_expr_t;
typedef struct ivl_lpm_s *ivl_lpm_t;
typedef struct ivl_lpm_ff_s *ivl_lpm_ff_t;
typedef struct ivl_lval_s *ivl_lval_t;
typedef struct ivl_net_const_s*ivl_net_const_t;
typedef struct ivl_net_event_s*ivl_net_event_t;
typedef struct ivl_net_logic_s*ivl_net_logic_t;
typedef struct ivl_udp_s *ivl_udp_t;
typedef struct ivl_net_probe_s*ivl_net_probe_t;
typedef struct ivl_nexus_s *ivl_nexus_t;
typedef struct ivl_nexus_ptr_s*ivl_nexus_ptr_t;
typedef struct ivl_process_s *ivl_process_t;
typedef struct ivl_scope_s *ivl_scope_t;
typedef struct ivl_signal_s *ivl_signal_t;
typedef struct ivl_memory_s *ivl_memory_t;
typedef struct ivl_statement_s*ivl_statement_t;
/*
@@ -144,43 +144,78 @@ typedef struct ivl_statement_s*ivl_statement_t;
* changes and additions to the enumerations.
*/
typedef enum ivl_drive_e {
IVL_DR_HiZ = 0,
IVL_DR_SMALL = 1,
IVL_DR_MEDIUM = 2,
IVL_DR_WEAK = 3,
IVL_DR_LARGE = 4,
IVL_DR_PULL = 5,
IVL_DR_STRONG = 6,
IVL_DR_SUPPLY = 7
} ivl_drive_t;
/* This is the type of an ivl_expr_t object. */
typedef enum ivl_expr_type_e {
IVL_EX_NONE = 0,
IVL_EX_BITSEL,
IVL_EX_BINARY,
IVL_EX_CONCAT,
IVL_EX_MEMORY,
IVL_EX_NUMBER,
IVL_EX_SCOPE,
IVL_EX_SFUNC,
IVL_EX_SIGNAL,
IVL_EX_STRING,
IVL_EX_SUBSIG,
IVL_EX_TERNARY,
IVL_EX_UFUNC,
IVL_EX_ULONG,
IVL_EX_UNARY
} ivl_expr_type_t;
/* This is the type code for an ivl_net_logic_t object. */
typedef enum ivl_logic_e {
IVL_LO_NONE = 0,
IVL_LO_AND,
IVL_LO_BUF,
IVL_LO_BUFIF0,
IVL_LO_BUFIF1,
IVL_LO_BUFZ,
IVL_LO_NAND,
IVL_LO_NMOS,
IVL_LO_NOR,
IVL_LO_NOT,
IVL_LO_NOTIF0,
IVL_LO_NOTIF1,
IVL_LO_OR,
IVL_LO_RNMOS,
IVL_LO_RPMOS,
IVL_LO_PMOS,
IVL_LO_XNOR,
IVL_LO_XOR
IVL_LO_NONE = 0,
IVL_LO_AND = 1,
IVL_LO_BUF = 2,
IVL_LO_BUFIF0 = 3,
IVL_LO_BUFIF1 = 4,
IVL_LO_BUFZ = 5,
IVL_LO_NAND = 6,
IVL_LO_NMOS = 7,
IVL_LO_NOR = 8,
IVL_LO_NOT = 9,
IVL_LO_NOTIF0 = 10,
IVL_LO_NOTIF1 = 11,
IVL_LO_OR = 12,
IVL_LO_PULLDOWN = 13,
IVL_LO_PULLUP = 14,
IVL_LO_RNMOS = 15,
IVL_LO_RPMOS = 16,
IVL_LO_PMOS = 17,
IVL_LO_XNOR = 18,
IVL_LO_XOR = 19,
IVL_LO_EEQ = 20,
IVL_LO_UDP = 21
} ivl_logic_t;
/* This is the type of an LPM object. */
typedef enum ivl_lpm_type_e {
IVL_LPM_FF
IVL_LPM_ADD = 0,
IVL_LPM_CMP_EQ = 10,
IVL_LPM_CMP_GE = 1,
IVL_LPM_CMP_GT = 2,
IVL_LPM_CMP_NE = 11,
IVL_LPM_DIVIDE = 12,
IVL_LPM_FF = 3,
IVL_LPM_MULT = 4,
IVL_LPM_MUX = 5,
IVL_LPM_SHIFTL = 6,
IVL_LPM_SHIFTR = 7,
IVL_LPM_SUB = 8,
IVL_LPM_RAM = 9
} ivl_lpm_type_t;
/* Processes are initial or always blocks with a statement. This is
@@ -232,12 +267,25 @@ typedef enum ivl_statement_type_e {
IVL_ST_NONE = 0,
IVL_ST_NOOP = 1,
IVL_ST_ASSIGN,
IVL_ST_ASSIGN_NB,
IVL_ST_BLOCK,
IVL_ST_CASE,
IVL_ST_CASEX,
IVL_ST_CASEZ,
IVL_ST_CASSIGN,
IVL_ST_CONDIT,
IVL_ST_DEASSIGN,
IVL_ST_DELAY,
IVL_ST_DELAYX,
IVL_ST_DISABLE,
IVL_ST_FORCE,
IVL_ST_FOREVER,
IVL_ST_FORK,
IVL_ST_RELEASE,
IVL_ST_REPEAT,
IVL_ST_STASK,
IVL_ST_TRIGGER,
IVL_ST_UTASK,
IVL_ST_WAIT,
IVL_ST_WHILE
} ivl_statement_type_t;
@@ -278,12 +326,23 @@ typedef int (ivl_scope_f)(ivl_scope_t net, void*cd);
* A design has a root named scope that is an instance of the top
* level module in the design. This is a hook for naming the
* design, or for starting the scope scan.
*
* ivl_design_time_precision
* A design as a time precision. This is the size in seconds (a
* signed power of 10) of a simulation tick.
*/
extern const char* ivl_design_flag(ivl_design_t des, const char*key);
extern int ivl_design_process(ivl_design_t des,
ivl_process_f fun, void*cd);
extern ivl_scope_t ivl_design_root(ivl_design_t des);
extern void ivl_design_roots(ivl_design_t des,
ivl_scope_t **scopes,
unsigned int *nscopes);
extern int ivl_design_time_precision(ivl_design_t des);
extern unsigned ivl_design_consts(ivl_design_t des);
extern ivl_net_const_t ivl_design_const(ivl_design_t, unsigned idx);
/*
* These methods apply to ivl_net_const_t objects.
@@ -293,6 +352,31 @@ extern ivl_nexus_t ivl_const_pin(ivl_net_const_t net, unsigned idx);
extern unsigned ivl_const_pins(ivl_net_const_t net);
extern int ivl_const_signed(ivl_net_const_t net);
/* EVENTS
*
* Events are a unification of named events and implicit events
* generated by the @ statements.
*
* ivl_event_name
* ivl_event_basename
*
* ivl_event_edge
* Return the edge type for the event. If this is a named event
* that has no network input, then the edge is IVL_EDGE_NONE.
*/
extern const char* ivl_event_name(ivl_event_t net);
extern const char* ivl_event_basename(ivl_event_t net);
extern unsigned ivl_event_nany(ivl_event_t net);
extern ivl_nexus_t ivl_event_any(ivl_event_t net, unsigned idx);
extern unsigned ivl_event_nneg(ivl_event_t net);
extern ivl_nexus_t ivl_event_neg(ivl_event_t net, unsigned idx);
extern unsigned ivl_event_npos(ivl_event_t net);
extern ivl_nexus_t ivl_event_pos(ivl_event_t net, unsigned idx);
/* EXPRESSIONS
*
* These methods operate on expression objects from the
@@ -321,29 +405,51 @@ extern ivl_expr_type_t ivl_expr_type(ivl_expr_t net);
/* IVL_EX_NUMBER */
extern const char* ivl_expr_bits(ivl_expr_t net);
/* IVL_EX_SIGNAL, IVL_EX_SFUNC */
/* IVL_EX_UFUNC */
extern ivl_scope_t ivl_expr_def(ivl_expr_t net);
/* IVL_EX_SIGNAL */
extern unsigned ivl_expr_lsi(ivl_expr_t net);
/* IVL_EX_SIGNAL, IVL_EX_SFUNC, IVL_EX_MEMORY */
extern const char* ivl_expr_name(ivl_expr_t net);
/* IVL_EX_BINARY */
/* IVL_EX_BINARY IVL_EX_UNARY */
extern char ivl_expr_opcode(ivl_expr_t net);
/* IVL_EX_BINARY */
/* IVL_EX_BINARY IVL_EX_BITSEL IVL_EX_UNARY, IVL_EX_MEMORY IVL_EX_TERNARY */
extern ivl_expr_t ivl_expr_oper1(ivl_expr_t net);
/* IVL_EX_BINARY */
/* IVL_EX_BINARY IVL_EX_TERNARY */
extern ivl_expr_t ivl_expr_oper2(ivl_expr_t net);
/* */
/* IVL_EX_TERNARY */
extern ivl_expr_t ivl_expr_oper3(ivl_expr_t net);
/* IVL_EX_CONCAT */
/* IVL_EX_CONCAT IVL_EX_UFUNC */
extern ivl_expr_t ivl_expr_parm(ivl_expr_t net, unsigned idx);
/* IVL_EX_CONCAT */
/* IVL_EX_CONCAT IVL_EX_SFUNC IVL_EX_UFUNC */
extern unsigned ivl_expr_parms(ivl_expr_t net);
/* IVL_EX_CONCAT */
extern unsigned ivl_expr_repeat(ivl_expr_t net);
/* IVL_EX_SCOPE */
extern ivl_scope_t ivl_expr_scope(ivl_expr_t net);
/* IVL_EX_BITSEL */
extern ivl_signal_t ivl_expr_signal(ivl_expr_t net);
/* any expression */
extern int ivl_expr_signed(ivl_expr_t net);
/* IVL_EX_STRING */
extern const char* ivl_expr_string(ivl_expr_t net);
/* IVL_EX_ULONG */
extern unsigned long ivl_expr_uvalue(ivl_expr_t net);
/* any expression */
extern unsigned ivl_expr_width(ivl_expr_t net);
/*
* Memory.
*
*/
extern const char*ivl_memory_name(ivl_memory_t net);
extern const char*ivl_memory_basename(ivl_memory_t net);
extern int ivl_memory_root(ivl_memory_t net);
extern unsigned ivl_memory_size(ivl_memory_t net);
extern unsigned ivl_memory_width(ivl_memory_t net);
extern ivl_memory_t ivl_expr_memory(ivl_expr_t net);
/* LOGIC
* These types and functions support manipulation of logic gates. The
* ivl_logic_t enumeration identifies the various kinds of gates that
@@ -363,21 +469,55 @@ extern unsigned ivl_expr_width(ivl_expr_t net);
* ivl_logic_basename
* This is the name of the gate without the scope part.
*
* ivl_logic_scope
* This is the scope that directly contains the logic device.
*
* ivl_logic_pins
* ivl_logic_pin
*
* ivl_logic_attr
* Return the value of a specific attribute, given the key name as
* a string. If the key is not defined, then return 0 (null).
*/
extern const char* ivl_logic_name(ivl_net_logic_t net);
extern const char* ivl_logic_basename(ivl_net_logic_t net);
extern ivl_scope_t ivl_logic_scope(ivl_net_logic_t net);
extern ivl_logic_t ivl_logic_type(ivl_net_logic_t net);
extern ivl_nexus_t ivl_logic_pin(ivl_net_logic_t net, unsigned pin);
extern unsigned ivl_logic_pins(ivl_net_logic_t net);
extern ivl_udp_t ivl_logic_udp(ivl_net_logic_t net);
extern unsigned ivl_logic_delay(ivl_net_logic_t net, unsigned transition);
extern const char* ivl_logic_attr(ivl_net_logic_t net, const char*key);
/* UDP
*
*/
extern unsigned ivl_udp_sequ(ivl_udp_t net);
extern unsigned ivl_udp_nin(ivl_udp_t net);
extern unsigned ivl_udp_init(ivl_udp_t net);
extern const char* ivl_udp_row(ivl_udp_t net, unsigned idx);
extern unsigned ivl_udp_rows(ivl_udp_t net);
extern const char* ivl_udp_name(ivl_udp_t net);
/* LPM
* These functions support access to the properties of LPM devices.
* These functions support access to the properties of LPM
* devices. LPM devices are a variety of devices that handle more
* complex structural semantics.
*
* These are the functions that apply to all LPM devices:
*
* ivl_lpm_name
* Return the name of the device.
* ivl_lpm_basename
* Return the name of the device. The name is the name of the
* device with the scope part, and the basename is without the scope.
*
* ivl_lpm_scope
* LPM devices exist within a scope. Return the scope that contains
* this device.
*
* ivl_lpm_type
* Return the ivl_lpm_type_t of the secific LPM device.
@@ -386,34 +526,97 @@ extern unsigned ivl_logic_pins(ivl_net_logic_t net);
* Return the width of the LPM device. What this means depends on
* the LPM type, but it generally has to do with the width of the
* output data path.
*
*
* These functions apply to a subset of the LPM devices, or may have
* varying meaning depending on the device:
*
* ivl_lpm_data
* Return the input data nexus for device types that have a single
* input vector. This is also used to the get nexa of the first
* vector for devices that have more inputs.
*
* ivl_lpm_datab
* Return the input data nexis for device types that have a second
* input vector. For example, arithmetic devices are like this.
*
* ivl_lpm_q
* Return the output data nexus for device types that have a single
* output vector. This is most devices, it turns out.
*
* ivl_lpm_selects
* This is the size of the select input for a LPM_MUX device, or the
* address bus width of an LPM_RAM.
*
* ivl_lpm_size
* In addition to a width, some devices have a size. The size is
* often the number of inputs per out, i.e. the number of inputs
* per bit for a MUX.
*/
extern const char* ivl_lpm_name(ivl_lpm_t net);
extern const char* ivl_lpm_basename(ivl_lpm_t net);
extern ivl_scope_t ivl_lpm_scope(ivl_lpm_t net);
extern ivl_lpm_type_t ivl_lpm_type(ivl_lpm_t net);
extern unsigned ivl_lpm_width(ivl_lpm_t net);
/*
* These are cast functions for the ivl_lpm_t. They cast the object to
* the requested type, checking for errors along the way.
*/
extern ivl_lpm_ff_t ivl_lpm_ff(ivl_lpm_t net);
extern ivl_nexus_t ivl_lpm_ff_clk(ivl_lpm_ff_t net);
extern ivl_nexus_t ivl_lpm_ff_data(ivl_lpm_ff_t net, unsigned idx);
extern ivl_nexus_t ivl_lpm_ff_q(ivl_lpm_ff_t net, unsigned idx);
/* IVL_LPM_FF IVL_LPM_RAM */
extern ivl_nexus_t ivl_lpm_clk(ivl_lpm_t net);
/* IVL_LPM_FF IVL_LPM_RAM */
extern ivl_nexus_t ivl_lpm_enable(ivl_lpm_t net);
/* IVL_LPM_ADD IVL_LPM_FF IVL_LPM_MULT IVL_LPM_RAM IVL_LPM_SUB */
extern ivl_nexus_t ivl_lpm_data(ivl_lpm_t net, unsigned idx);
/* IVL_LPM_ADD IVL_LPM_MULT IVL_LPM_SUB */
extern ivl_nexus_t ivl_lpm_datab(ivl_lpm_t net, unsigned idx);
/* IVL_LPM_MUX */
extern ivl_nexus_t ivl_lpm_data2(ivl_lpm_t net, unsigned sdx, unsigned idx);
/* IVL_LPM_ADD IVL_LPM_FF IVL_LPM_MULT IVL_LPM_RAM IVL_LPM_SUB */
extern ivl_nexus_t ivl_lpm_q(ivl_lpm_t net, unsigned idx);
/* IVL_LPM_MUX IVL_LPM_RAM */
extern unsigned ivl_lpm_selects(ivl_lpm_t net);
/* IVL_LPM_MUX IVL_LPM_RAM */
extern ivl_nexus_t ivl_lpm_select(ivl_lpm_t net, unsigned idx);
/* IVL_LPM_MUX */
extern unsigned ivl_lpm_size(ivl_lpm_t net);
/* IVL_LPM_RAM */
extern ivl_memory_t ivl_lpm_memory(ivl_lpm_t net);
/* LVAL
* The l-values of assignments are concatenation of ivl_lval_t
* objects. Each l-value has a bunch of connections (in the form of
* ivl_nexus_t objects) and possibly a mux expression. The compiler
* takes care of part selects and nested concatenations. The
* ivl_stmt_lval function pulls ivl_lval_t objects out of the
* statement.
* objects. Each lvi_lval_t object is an assignment to a var or a
* memory, through a bit select, part select or word select.
*
* Var lvals are things like assignments to a part select or a bit
* select. Assignment to the whole variable is a special case of a
* part select, as is a bit select with a constant expression. The
* ivl_lval_pins statement returns the width of the part select for
* the lval. The ivl_lval_pin function returns the nexus to the N-th
* bit of the part select. The compiler takes care of positioning the
* part select so that ivl_lval_pin(net, 0) is the proper bit in the
* signal.
*
* ivl_lval_mux
* If the l-value includes a bit select expression, this method
* returns an ivl_expr_t that represents that
* expression. Otherwise, it returns 0.
* expression. Otherwise, it returns 0.
*
* ivl_lval_mem
* If the l-value is a memory, this method returns an
* ivl_memory_t that represents that memory. Otherwise, it
* returns 0.
*
* ivl_lval_sig
* If the l-value is a variable, this method returns the signal
* object that is the target of the assign.
*
* ivl_lval_part_off
* The part select of the signal is based here. This is the
* canonical index of bit-0 of the part select.
*
* ivl_lval_idx
* If the l-value is a memory, this method returns an
* ivl_expr_t that represents the index expression. Otherwise, it
* returns 0.
*
* ivl_lval_pin
* Return an ivl_nexus_t for the connection of the ivl_lval_t.
@@ -423,9 +626,12 @@ extern ivl_nexus_t ivl_lpm_ff_q(ivl_lpm_ff_t net, unsigned idx);
*/
extern ivl_expr_t ivl_lval_mux(ivl_lval_t net);
extern ivl_expr_t ivl_lval_idx(ivl_lval_t net);
extern ivl_memory_t ivl_lval_mem(ivl_lval_t net);
extern unsigned ivl_lval_part_off(ivl_lval_t net);
extern unsigned ivl_lval_pins(ivl_lval_t net);
extern ivl_nexus_t ivl_lval_pin(ivl_lval_t net, unsigned idx);
extern ivl_signal_t ivl_lval_sig(ivl_lval_t net);
/* NEXUS
* connections of signals and nodes is handled by single-bit
@@ -446,6 +652,14 @@ extern ivl_nexus_t ivl_lval_pin(ivl_lval_t net, unsigned idx);
* ivl_nexus_ptr
* Return a nexus pointer given the nexus and an index.
*
* ivl_nexus_set_private
* ivl_nexus_get_private
* The target module often needs to associate data with a nexus for
* later use when the nexus is encountered associated with a
* device. These methods allow the code generator to store to or
* retrieve from a nexus a void* of private data. This pointer is
* guaranteed to be 0 before the target module is invoked.
*
* Once an ivl_nexus_ptr_t is selected by the ivl_nexus_ptr method,
* the properties of the pointer can be accessed by the following
* methods:
@@ -460,6 +674,22 @@ extern ivl_nexus_t ivl_lval_pin(ivl_lval_t net, unsigned idx);
* nexus. The problem is that LPM devices do not have a pinout per
* se, the pins all have specific names.
*
* ivl_nexus_ptr_con
* If this is a pointer to a magic constant device, then this
* returns the net_const object.
*
* ivl_nexus_ptr_drive0
* ivl_nexus_ptr_drive1
* These are the 0 and 1 strength values for the devices. For most
* devices, these values are fixed by the description in the
* original source, with the default as IVL_DR_STRONG. For pins
* that are input only, drive0 and drive1 are both IVL_DR_HiZ.
*
* The strength of strength-aware devices (such as nmos devices)
* does not really matter, as long at the output is not
* IVL_DR_HiZ. Testing for HiZ drivers is how code generators
* detect inputs.
*
* ivl_nexus_ptr_log
* If the target object is an ivl_net_logic_t, this method returns
* the object. Otherwise, this method returns 0.
@@ -477,12 +707,18 @@ extern const char* ivl_nexus_name(ivl_nexus_t net);
extern unsigned ivl_nexus_ptrs(ivl_nexus_t net);
extern ivl_nexus_ptr_t ivl_nexus_ptr(ivl_nexus_t net, unsigned idx);
extern void ivl_nexus_set_private(ivl_nexus_t net, void*data);
extern void* ivl_nexus_get_private(ivl_nexus_t net);
extern ivl_drive_t ivl_nexus_ptr_drive0(ivl_nexus_ptr_t net);
extern ivl_drive_t ivl_nexus_ptr_drive1(ivl_nexus_ptr_t net);
extern unsigned ivl_nexus_ptr_pin(ivl_nexus_ptr_t net);
extern ivl_net_const_t ivl_nexus_ptr_con(ivl_nexus_ptr_t net);
extern ivl_net_logic_t ivl_nexus_ptr_log(ivl_nexus_ptr_t net);
extern ivl_lpm_t ivl_nexus_ptr_lpm(ivl_nexus_ptr_t net);
extern ivl_signal_t ivl_nexus_ptr_sig(ivl_nexus_ptr_t net);
/* SCOPE
* Scopes of various sort have these properties. Use these methods to
* access them. Scopes come to exist in the elaborated design
@@ -502,14 +738,38 @@ extern ivl_signal_t ivl_nexus_ptr_sig(ivl_nexus_ptr_t net);
* If the scope has no children, this method will return 0 and
* otherwise do nothing.
*
* ivl_scope_def
* Task definition scopes carry a task definition, in the form of
* a statement. This method accesses that definition.
*
* ivl_scope_event
* ivl_scope_events
* Scopes have 0 or more event objects in them.
*
* ivl_scope_log
* ivl_scope_logs
* Scopes have 0 or more logic devices in them. A logic device is
* represented by ivl_logic_t.
*
* ivl_scope_name
* ivl_scope_basename
* Every scope has a hierarchical name. This name is also a prefix
* of all the names of objects contained within the scope.
* of all the names of objects contained within the scope. The
* ivl_scope_basename is the name of the scope without the included
* hierarchy.
*
* ivl_scope_parent
* If this is a non-root scope, then the parent is the scope that
* contains this scope. Otherwise, the parent is nil.
*
* ivl_scope_port
* ivl_scope_ports
* Scopes that are functions or tasks have ports defined by
* signals. These methods access the ports by name.
*
* If this scope represents a function, then the ports list
* includes the return value, as port 0. The remaining ports are
* the input ports in order.
*
* ivl_scope_sig
* ivl_scope_sigs
@@ -527,11 +787,22 @@ extern ivl_signal_t ivl_nexus_ptr_sig(ivl_nexus_ptr_t net);
extern int ivl_scope_children(ivl_scope_t net,
ivl_scope_f func, void*cd);
extern ivl_statement_t ivl_scope_def(ivl_scope_t net);
extern unsigned ivl_scope_events(ivl_scope_t net);
extern ivl_event_t ivl_scope_event(ivl_scope_t net, unsigned idx);
extern unsigned ivl_scope_logs(ivl_scope_t net);
extern ivl_net_logic_t ivl_scope_log(ivl_scope_t net, unsigned idx);
extern unsigned ivl_scope_lpms(ivl_scope_t net);
extern ivl_lpm_t ivl_scope_lpm(ivl_scope_t, unsigned idx);
extern unsigned ivl_scope_mems(ivl_scope_t net);
extern ivl_memory_t ivl_scope_mem(ivl_scope_t net, unsigned idx);
extern const char* ivl_scope_name(ivl_scope_t net);
extern const char* ivl_scope_basename(ivl_scope_t net);
extern ivl_scope_t ivl_scope_parent(ivl_scope_t net);
extern unsigned ivl_scope_ports(ivl_scope_t net);
extern ivl_signal_t ivl_scope_port(ivl_scope_t net, unsigned idx);
extern unsigned ivl_scope_sigs(ivl_scope_t net);
extern ivl_signal_t ivl_scope_sig(ivl_scope_t net, unsigned idx);
extern ivl_scope_type_t ivl_scope_type(ivl_scope_t net);
@@ -558,7 +829,13 @@ extern const char* ivl_scope_tname(ivl_scope_t net);
* port direction. If the signal is not a port, it returns
* IVL_SIP_NONE.
*
* ivl_signal_signed
* A signal, which is a vector, may be signed. In Verilog 2000, any
* net or variable may be signed. This function returns true if the
* signal is signed.
*
* ivl_signal_type
* Return the type of the signal, i.e. reg, wire, tri0, et al.
*
* ivl_signal_name
* This function returns the fully scoped hierarchical name for the
@@ -578,6 +855,7 @@ extern const char* ivl_scope_tname(ivl_scope_t net);
extern ivl_nexus_t ivl_signal_pin(ivl_signal_t net, unsigned idx);
extern unsigned ivl_signal_pins(ivl_signal_t net);
extern ivl_signal_port_t ivl_signal_port(ivl_signal_t net);
extern int ivl_signal_signed(ivl_signal_t net);
extern ivl_signal_type_t ivl_signal_type(ivl_signal_t net);
extern const char* ivl_signal_name(ivl_signal_t net);
extern const char* ivl_signal_basename(ivl_signal_t net);
@@ -593,12 +871,18 @@ extern const char* ivl_signal_attr(ivl_signal_t net, const char*key);
* The ivl_process_type function gets the type of the process,
* an "inital" or "always" statement.
*
* A process is placed in a scope. The statement within the process
* operates within the scope of the process unless there are calls
* outside the scope.
*
* The ivl_process_stmt function gets the statement that forms the
* process. See the statement related functions for how to manipulate
* statements.
*/
extern ivl_process_type_t ivl_process_type(ivl_process_t net);
extern ivl_scope_t ivl_process_scope(ivl_process_t net);
extern ivl_statement_t ivl_process_stmt(ivl_process_t net);
/*
@@ -620,36 +904,62 @@ extern ivl_statement_type_t ivl_statement_type(ivl_statement_t net);
* statement types can be passed to the function.
*/
/* IVL_ST_BLOCK */
/* IVL_ST_BLOCK, IVL_ST_FORK */
extern unsigned ivl_stmt_block_count(ivl_statement_t net);
/* IVL_ST_BLOCK */
/* IVL_ST_BLOCK, IVL_ST_FORK */
extern ivl_statement_t ivl_stmt_block_stmt(ivl_statement_t net, unsigned i);
/* IVL_ST_CONDIT */
/* IVL_ST_UTASK IVL_ST_DISABLE */
extern ivl_scope_t ivl_stmt_call(ivl_statement_t net);
/* IVL_ST_CASE */
extern unsigned ivl_stmt_case_count(ivl_statement_t net);
/* IVL_ST_CASE */
extern ivl_expr_t ivl_stmt_case_expr(ivl_statement_t net, unsigned i);
/* IVL_ST_CASE */
extern ivl_statement_t ivl_stmt_case_stmt(ivl_statement_t net, unsigned i);
/* IVL_ST_CONDIT IVL_ST_CASE IVL_ST_REPEAT IVL_ST_WHILE */
extern ivl_expr_t ivl_stmt_cond_expr(ivl_statement_t net);
/* IVL_ST_CONDIT */
extern ivl_statement_t ivl_stmt_cond_false(ivl_statement_t net);
/* IVL_ST_CONDIT */
extern ivl_statement_t ivl_stmt_cond_true(ivl_statement_t net);
/* IVL_ST_ASSIGN IVL_ST_ASSIGN_NB IVL_ST_DELAYX */
extern ivl_expr_t ivl_stmt_delay_expr(ivl_statement_t net);
/* IVL_ST_DELAY */
extern unsigned long ivl_stmt_delay_val(ivl_statement_t net);
/* IVL_ST_ASSIGN */
/* IVL_ST_WAIT */
extern ivl_event_t ivl_stmt_event(ivl_statement_t net);
/* IVL_ST_ASSIGN IVL_ST_ASSIGN_NB IVL_ST_CASSIGN IVL_ST_DEASSIGN
IVL_ST_FORCE IVL_ST_RELEASE */
extern ivl_lval_t ivl_stmt_lval(ivl_statement_t net, unsigned idx);
/* IVL_ST_ASSIGN */
/* IVL_ST_ASSIGN IVL_ST_ASSIGN_NB IVL_ST_CASSIGN IVL_ST_DEASSIGN
IVL_ST_FORCE IVL_ST_RELEASE */
extern unsigned ivl_stmt_lvals(ivl_statement_t net);
/* IVL_ST_ASSIGN */
/* IVL_ST_ASSIGN IVL_ST_ASSIGN_NB */
extern unsigned ivl_stmt_lwidth(ivl_statement_t net);
/* IVL_ST_STASK */
extern const char* ivl_stmt_name(ivl_statement_t net);
/* IVL_ST_CASSIGN IVL_ST_FORCE */
extern ivl_nexus_t ivl_stmt_nexus(ivl_statement_t net, unsigned idx);
extern unsigned ivl_stmt_nexus_count(ivl_statement_t net);
/* IVL_ST_STASK */
extern ivl_expr_t ivl_stmt_parm(ivl_statement_t net, unsigned idx);
/* IVL_ST_STASK */
extern unsigned ivl_stmt_parm_count(ivl_statement_t net);
/* IVL_ST_ASSIGN */
/* IVL_ST_ASSIGN IVL_ST_ASSIGN_NB */
extern ivl_expr_t ivl_stmt_rval(ivl_statement_t net);
/* IVL_ST_DELAY, IVL_ST_WAIT, IVL_ST_WHILE */
/* IVL_ST_DELAY, IVL_ST_DELAYX, IVL_ST_FOREVER, IVL_ST_REPEAT
IVL_ST_WAIT, IVL_ST_WHILE */
extern ivl_statement_t ivl_stmt_sub_stmt(ivl_statement_t net);
#if defined(__MINGW32__) || defined (__CYGWIN32__)
# define DLLEXPORT __declspec(dllexport)
#else
# define DLLEXPORT
#endif
extern DLLEXPORT int target_design(ivl_design_t des);
/* target_design
@@ -667,6 +977,186 @@ _END_DECL
/*
* $Log: ivl_target.h,v $
* Revision 1.89 2001/12/06 03:11:00 steve
* Add ivl_logic_delay function to ivl_target.
*
* Revision 1.88 2001/11/14 03:28:49 steve
* DLL target support for force and release.
*
* Revision 1.87 2001/11/01 04:25:31 steve
* ivl_target support for cassign.
*
* Revision 1.86 2001/10/31 05:24:52 steve
* ivl_target support for assign/deassign.
*
* Revision 1.85 2001/10/19 21:53:24 steve
* Support multiple root modules (Philip Blundell)
*
* Revision 1.84 2001/10/16 02:19:27 steve
* Support IVL_LPM_DIVIDE for structural divide.
*
* Revision 1.83 2001/09/30 16:45:10 steve
* Fix some Cygwin DLL handling. (Venkat Iyer)
*
* Revision 1.82 2001/09/16 22:19:42 steve
* Support attributes to logic gates.
*
* Revision 1.81 2001/09/09 22:21:57 steve
* pin down some enumerated constants.
*
* Revision 1.80 2001/09/01 01:57:31 steve
* Make constants available through the design root
*
* Revision 1.79 2001/08/31 22:58:39 steve
* Support DFF CE inputs.
*
* Revision 1.78 2001/08/28 04:07:17 steve
* Add some ivl_target convenience functions.
*
* Revision 1.77 2001/08/25 23:50:03 steve
* Change the NetAssign_ class to refer to the signal
* instead of link into the netlist. This is faster
* and uses less space. Make the NetAssignNB carry
* the delays instead of the NetAssign_ lval objects.
*
* Change the vvp code generator to support multiple
* l-values, i.e. concatenations of part selects.
*
* Revision 1.76 2001/08/10 00:40:45 steve
* tgt-vvp generates code that skips nets as inputs.
*
* Revision 1.75 2001/07/27 04:51:44 steve
* Handle part select expressions as variants of
* NetESignal/IVL_EX_SIGNAL objects, instead of
* creating new and useless temporary signals.
*
* Revision 1.74 2001/07/27 02:41:55 steve
* Fix binding of dangling function ports. do not elide them.
*
* Revision 1.73 2001/07/22 00:17:49 steve
* Support the NetESubSignal expressions in vvp.tgt.
*
* Revision 1.72 2001/07/19 04:55:06 steve
* Support calculated delays in vvp.tgt.
*
* Revision 1.71 2001/07/04 22:59:25 steve
* handle left shifter in dll output.
*
* Revision 1.70 2001/06/30 23:03:16 steve
* support fast programming by only writing the bits
* that are listed in the input file.
*
* Revision 1.69 2001/06/19 03:01:10 steve
* Add structural EEQ gates (Stephan Boettcher)
*
* Revision 1.68 2001/06/16 23:45:05 steve
* Add support for structural multiply in t-dll.
* Add code generators and vvp support for both
* structural and behavioral multiply.
*
* Revision 1.67 2001/06/16 02:41:41 steve
* Generate code to support memory access in continuous
* assignment statements. (Stephan Boettcher)
*
* Revision 1.66 2001/06/15 04:14:18 steve
* Generate vvp code for GT and GE comparisons.
*
* Revision 1.65 2001/06/07 03:09:37 steve
* support subtraction in tgt-vvp.
*
* Revision 1.64 2001/06/07 02:12:43 steve
* Support structural addition.
*
* Revision 1.63 2001/05/20 01:06:16 steve
* stub ivl_expr_parms for sfunctions.
*
* Revision 1.62 2001/05/17 04:37:02 steve
* Behavioral ternary operators for vvp.
*
* Revision 1.61 2001/05/12 03:18:44 steve
* Make sure LPM devices have drives on outputs.
*
* Revision 1.60 2001/05/08 23:59:33 steve
* Add ivl and vvp.tgt support for memories in
* expressions and l-values. (Stephan Boettcher)
*
* Revision 1.59 2001/05/08 04:13:12 steve
* sort enumeration values.
*
* Revision 1.58 2001/05/06 17:48:20 steve
* Support memory objects. (Stephan Boettcher)
*
* Revision 1.57 2001/04/29 23:17:38 steve
* Carry drive strengths in the ivl_nexus_ptr_t, and
* handle constant devices in targets.'
*
* Revision 1.56 2001/04/29 20:19:10 steve
* Add pullup and pulldown devices.
*
* Revision 1.55 2001/04/26 05:12:02 steve
* Implement simple MUXZ for ?: operators.
*
* Revision 1.54 2001/04/22 23:09:46 steve
* More UDP consolidation from Stephan Boettcher.
*
* Revision 1.53 2001/04/21 00:55:46 steve
* Generate code for disable.
*
* Revision 1.52 2001/04/15 02:58:11 steve
* vvp support for <= with internal delay.
*
* Revision 1.51 2001/04/07 19:24:36 steve
* Add the disable statemnent.
*
* Revision 1.50 2001/04/06 02:28:02 steve
* Generate vvp code for functions with ports.
*
* Revision 1.49 2001/04/05 03:20:57 steve
* Generate vvp code for the repeat statement.
*
* Revision 1.48 2001/04/05 01:12:27 steve
* Get signed compares working correctly in vvp.
*
* Revision 1.47 2001/04/04 04:50:35 steve
* Support forever loops in the tgt-vvp target.
*
* Revision 1.46 2001/04/03 04:50:37 steve
* Support non-blocking assignments.
*
* Revision 1.45 2001/04/02 02:28:12 steve
* Generate code for task calls.
*
* Revision 1.44 2001/04/02 00:28:35 steve
* Support the scope expression node.
*
* Revision 1.43 2001/04/01 06:52:27 steve
* support the NetWhile statement.
*
* Revision 1.42 2001/04/01 04:38:17 steve
* dead cruft.
*
* Revision 1.41 2001/04/01 01:48:21 steve
* Redesign event information to support arbitrary edge combining.
*
* Revision 1.40 2001/03/31 17:36:38 steve
* Generate vvp code for case statements.
*
* Revision 1.39 2001/03/30 05:49:52 steve
* Generate code for fork/join statements.
*
* Revision 1.38 2001/03/29 02:52:39 steve
* Add unary ~ operator to tgt-vvp.
*
* Revision 1.37 2001/03/28 06:07:39 steve
* Add the ivl_event_t to ivl_target, and use that to generate
* .event statements in vvp way ahead of the thread that uses it.
*
* Revision 1.36 2001/03/27 06:27:40 steve
* Generate code for simple @ statements.
*
* Revision 1.35 2001/03/20 01:44:13 steve
* Put processes in the proper scope.
*
* Revision 1.34 2001/01/15 22:05:14 steve
* Declare ivl_scope_type functions.
*
+5 -5
View File
@@ -18,7 +18,7 @@
# 59 Temple Place - Suite 330
# Boston, MA 02111-1307, USA
#
#ident "$Id: Makefile.in,v 1.9 2001/01/09 03:11:28 steve Exp $"
#ident "$Id: Makefile.in,v 1.12 2001/08/10 00:39:22 steve Exp $"
#
#
SHELL = /bin/sh
@@ -41,8 +41,8 @@ INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
CPPFLAGS = @CPPFLAGS@ @DEFS@
CFLAGS = @CFLAGS@ -I.
LDFLAGS = @LDFLAGS@
CFLAGS = @CFLAGS@ -I. -I$(srcdir)/..
LDFLAGS = @LDFLAGS@
all: ivlpp
@@ -52,13 +52,13 @@ 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 $(srcdir)/lexor.lex
parse.h parse.c: parse.y
bison --verbose -t -d $(srcdir)/parse.y -o parse.c
bison --verbose -t -d -o parse.c $(srcdir)/parse.y
install: all installdirs $(libdir)/ivl/ivlpp
+6 -6
View File
@@ -49,7 +49,7 @@ valid options include:
flags as needed.
-L
Generate #line directives. The ivl compiler understands
Generate `line directives. The ivl compiler understands
these directives and uses them to keep track of the
current line of the original source file. This makes error
messages more meaningful.
@@ -89,17 +89,17 @@ proper will not reflect the actual line numbers in the source file.
To handle this situation, the preprocessor can generate line
directives. These directives are lines of the form:
#line <name> <num>
`line <num> <name> <level>
where <name> is the file name in double-quotes and <num> is the line
number in the file. The parser changes the filename and line number
counters in such a way that the next line is line number <num>+1 in
counters in such a way that the next line is line number <num> in
the file named <name>. For example:
#line "foo.vl" 5
`line 6 "foo.vl" 0
// I am on line 6 in file foo.vl.
The preprocessor generates a #line directive every time it switches
files. That includes starting an included file (#line "foo.vlh" 0) or
The preprocessor generates a `line directive every time it switches
files. That includes starting an included file (`line 1 "foo.vlh" 1) or
returning to the including file.
+32 -14
View File
@@ -19,11 +19,16 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: lexor.lex,v 1.23 2001/01/29 22:48:10 steve Exp $"
#ident "$Id: lexor.lex,v 1.28 2001/11/29 02:26:25 steve Exp $"
#endif
# include "config.h"
# include <stdio.h>
#ifdef HAVE_MALLOC_H
# include <malloc.h>
#endif
# include <stdlib.h>
# include <string.h>
# include <assert.h>
@@ -181,12 +186,11 @@ W [ \t\b\f]+
condition that stacks on top of the IFDEF_FALSE so that output is
not accidentally turned on within nested ifdefs. */
^{W}?`ifdef{W}[a-zA-Z_][a-zA-Z0-9_]*.* {
^{W}?`ifdef{W}[a-zA-Z_][a-zA-Z0-9_]* {
char*name = strchr(yytext, '`');
assert(name);
name += 6;
name += strspn(name, " \t\b\f");
name[strcspn(name, " \t\b\f")] = 0;
if (is_defined(name)) {
yy_push_state(IFDEF_TRUE);
@@ -195,16 +199,30 @@ W [ \t\b\f]+
}
}
<IFDEF_FALSE,IFDEF_SUPR>^{W}?`ifdef{W}.* { yy_push_state(IFDEF_SUPR); }
^{W}?`ifndef{W}[a-zA-Z_][a-zA-Z0-9_]* {
char*name = strchr(yytext, '`');
assert(name);
name += 7;
name += strspn(name, " \t\b\f");
<IFDEF_TRUE>{W}?`else.* { BEGIN(IFDEF_FALSE); }
<IFDEF_FALSE>{W}?`else.* { BEGIN(IFDEF_TRUE); }
<IFDEF_SUPR>{W}?`else.* { }
if (!is_defined(name)) {
yy_push_state(IFDEF_TRUE);
} else {
yy_push_state(IFDEF_FALSE);
}
}
<IFDEF_FALSE,IFDEF_SUPR>^{W}?`ifdef{W}.* { yy_push_state(IFDEF_SUPR); }
<IFDEF_FALSE,IFDEF_SUPR>^{W}?`ifndef{W}.* { yy_push_state(IFDEF_SUPR); }
<IFDEF_TRUE>{W}?`else { BEGIN(IFDEF_FALSE); }
<IFDEF_FALSE>{W}?`else { BEGIN(IFDEF_TRUE); }
<IFDEF_SUPR>{W}?`else { }
<IFDEF_FALSE,IFDEF_SUPR>. { }
<IFDEF_FALSE,IFDEF_SUPR>\n { istack->lineno += 1; fputc('\n', yyout); }
<IFDEF_FALSE,IFDEF_TRUE,IFDEF_SUPR>^{W}?`endif.* {
<IFDEF_FALSE,IFDEF_TRUE,IFDEF_SUPR>^{W}?`endif {
yy_pop_state();
}
@@ -475,7 +493,7 @@ static void def_undefine()
static void output_init()
{
if (line_direct_flag)
fprintf(yyout, "#line \"%s\" 0\n", istack->path);
fprintf(yyout, "`line 1 \"%s\" 0\n", istack->path);
}
static void include_filename()
@@ -519,8 +537,8 @@ static void do_include()
yy_switch_to_buffer(yy_new_buffer(istack->file, YY_BUF_SIZE));
if (line_direct_flag && istack->path)
fprintf(yyout, "\n#line \"%s\" %u\n",
istack->path, istack->lineno);
fprintf(yyout, "\n`line %u \"%s\" 1\n",
istack->lineno+1, istack->path);
}
/*
@@ -572,7 +590,7 @@ static int yywrap()
}
if (line_direct_flag)
fprintf(yyout, "\n#line \"%s\" 0\n", istack->path);
fprintf(yyout, "\n`line 1 \"%s\" 0\n", istack->path);
yyrestart(istack->file);
return 0;
@@ -585,8 +603,8 @@ static int yywrap()
yy_switch_to_buffer(istack->yybs);
if (line_direct_flag && istack->path && !line_mask_flag)
fprintf(yyout, "\n#line \"%s\" %u\n",
istack->path, istack->lineno);
fprintf(yyout, "\n`line %u \"%s\" 2\n",
istack->lineno+1, istack->path);
return 0;
}
+116 -9
View File
@@ -17,9 +17,11 @@ const char COPYRIGHT[] =
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: main.c,v 1.8 2000/12/06 05:15:21 steve Exp $"
#ident "$Id: main.c,v 1.14 2001/11/21 02:59:27 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,7 +41,10 @@ const char NOTICE[] =
const char VERSION[] = "$Name: $ $State: Exp $";
# include <stdio.h>
# include <stdlib.h>
#ifdef HAVE_MALLOC_H
# include <malloc.h>
#endif
# include <unistd.h>
# include <string.h>
#if defined(HAVE_GETOPT_H)
@@ -47,6 +52,34 @@ 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
/*
* Keep in source_list an array of pointers to file names. The array
* is terminated by a pointer to null.
*/
static char**source_list = 0;
static unsigned source_cnt = 0;
void add_source_file(const char*name)
{
if (source_list == 0) {
source_list = calloc(2, sizeof(char*));
source_list[0] = strdup(name);
source_list[1] = 0;
source_cnt = 1;
} else {
source_list = realloc(source_list, sizeof(char*) * (source_cnt+2));
source_list[source_cnt+0] = strdup(name);
source_list[source_cnt+1] = 0;
source_cnt += 1;
}
}
char**include_dir = 0;
unsigned include_cnt = 0;
@@ -54,9 +87,42 @@ int line_direct_flag = 0;
unsigned error_count = 0;
/*
* This function reads from a file a list of file names. Each name
* starts with the first non-space character, and ends with the last
* non-space character. Spaces in the middle are OK.
*/
static int flist_read_names(const char*path)
{
char line_buf[2048];
FILE*fd = fopen(path, "r");
if (fd == 0) {
fprintf(stderr, "%s: unable to open for reading.\n", path);
return 1;
}
while (fgets(line_buf, sizeof line_buf, fd) != 0) {
char*cp = line_buf + strspn(line_buf, " \t\r\b\f");
char*tail = cp + strlen(cp);
while (tail > cp) {
if (! isspace(tail[-1]))
break;
tail -= 1;
tail[0] = 0;
}
if (cp < tail)
add_source_file(cp);
}
return 0;
}
int main(int argc, char*argv[])
{
int opt;
int opt, idx;
const char*flist_path = 0;
unsigned flag_errors = 0;
char*out_path = 0;
FILE*out;
@@ -84,7 +150,7 @@ int main(int argc, char*argv[])
include_dir[0] = strdup(".");
include_cnt = 1;
while ((opt = getopt(argc, argv, "D:I:K:Lo:v")) != EOF) switch (opt) {
while ((opt = getopt(argc, argv, "D:f:I:K:Lo:v")) != EOF) switch (opt) {
case 'D': {
char*tmp = strdup(optarg);
@@ -99,6 +165,14 @@ int main(int argc, char*argv[])
break;
}
case 'f':
if (flist_path) {
fprintf(stderr, "%s: duplicate -f flag\n", argv[0]);
flag_errors += 1;
}
flist_path = optarg;
break;
case 'I':
include_dir = realloc(include_dir, (include_cnt+1)*sizeof(char*));
include_dir[include_cnt] = strdup(optarg);
@@ -138,12 +212,10 @@ int main(int argc, char*argv[])
break;
}
if (optind == argc)
flag_errors += 1;
if (flag_errors) {
fprintf(stderr, "\nUsage: %s [-v][-L][-I<dir>][-D<def>] <file>...\n"
" -D<def> - Predefine a value.\n"
" -f<fil> - Read the sources listed in the file\n"
" -I<dir> - Add an include file search directory\n"
" -K<def> - Define a keyword macro that I just pass\n"
" -L - Emit line number directives\n"
@@ -153,6 +225,21 @@ int main(int argc, char*argv[])
return flag_errors;
}
/* Collect the file names on the command line in the source
file list, then if there is a file list, read more file
names from there. */
for (idx = optind ; idx < argc ; idx += 1)
add_source_file(argv[idx]);
if (flist_path) {
int rc = flist_read_names(flist_path);
if (rc != 0)
return rc;
}
/* Figure out what to use for an output file. Write to stdout
if no path is specified. */
if (out_path) {
out = fopen(out_path, "w");
if (out == 0) {
@@ -163,13 +250,14 @@ int main(int argc, char*argv[])
out = stdout;
}
if (argv[optind] == 0) {
if (source_cnt == 0) {
fprintf(stderr, "%s: No input files given.\n", argv[0]);
return 1;
}
reset_lexor(out, argv+optind);
/* Pass to the lexical analyzer the list of input file, and
start the parser. */
reset_lexor(out, source_list);
if (yyparse()) return -1;
return error_count;
@@ -177,6 +265,25 @@ int main(int argc, char*argv[])
/*
* $Log: main.c,v $
* Revision 1.14 2001/11/21 02:59:27 steve
* Remove diag print.
*
* Revision 1.13 2001/11/21 02:20:35 steve
* Pass list of file to ivlpp via temporary file.
*
* Revision 1.12 2001/09/15 18:27:04 steve
* Make configure detect malloc.h
*
* Revision 1.11 2001/07/25 03:10:50 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
*
* 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.
*
+59 -42
View File
@@ -19,21 +19,22 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: lexor.lex,v 1.54 2000/12/12 06:13:44 steve Exp $"
#ident "$Id: lexor.lex,v 1.67 2001/12/03 04:47:15 steve Exp $"
#endif
# include "config.h"
//# define YYSTYPE lexval
# include <iostream.h>
# include "compiler.h"
# include "parse_misc.h"
# include "parse_api.h"
# include "parse.h"
# include <ctype.h>
# include <string.h>
# include "lexor_keyword.h"
extern FILE*vl_input;
extern string vl_file;
# define YY_USER_INIT reset_lexor();
# define yylval VLlval
@@ -75,13 +76,12 @@ static const char* set_file_name(char*text)
extern void pform_set_timescale(int, int);
static void reset_lexor();
void reset_lexor();
static void line_directive();
static void line_directive2();
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);
@@ -131,11 +131,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]; }
@@ -158,49 +161,60 @@ W [ \t\b\f\r]+
<UDPTABLE>\(\?[xX]\) { return '%'; }
<UDPTABLE>\(\?\?\) { return '*'; }
<UDPTABLE>\(01\) { return 'r'; }
<UDPTABLE>\(0[xX]\) { return 'P'; }
<UDPTABLE>\(0[xX]\) { return 'Q'; }
<UDPTABLE>\(0\?\) { return 'P'; }
<UDPTABLE>\(10\) { return 'f'; }
<UDPTABLE>\(1[xX]\) { return 'N'; }
<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 = lexor_keyword_code(yytext, yyleng);
if (rc == IDENTIFIER)
if (rc == IDENTIFIER) {
yylval.text = strdup(yytext);
else
if (strncmp(yylval.text,"PATHPULSE$", 10) == 0)
rc = PATHPULSE_IDENTIFIER;
} else {
yylval.text = 0;
}
return rc;
}
[a-zA-Z_][a-zA-Z0-9$_]*(\.[a-zA-Z_][a-zA-Z0-9$_]*)+ {
yylval.text = strdup(yytext);
return HIDENTIFIER; }
\\[^ \t\b\f\r]+ {
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$_]* {
char*cp = yytext+1;
while (! (isalpha(*cp) || (*cp == '_')))
cp += 1;
yylval.text = strdup(cp);
return PORTNAME; }
[0-9][0-9_]*[ \t]*\'[sS]?[dD][ \t]*[0-9][0-9_]* {
yylval.number = make_sized_dec(yytext);
return NUMBER; }
@@ -255,7 +269,7 @@ W [ \t\b\f\r]+
/* Notice and handle the timescale directive. */
`timescale { BEGIN(PPTIMESCALE); }
^{W}?`timescale { BEGIN(PPTIMESCALE); }
<PPTIMESCALE>.* { process_timescale(yytext); }
<PPTIMESCALE>\n {
yylloc.first_line += 1;
@@ -265,28 +279,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;
@@ -721,7 +735,7 @@ static verinum*make_sized_hex(const char*txt)
"'' truncated to " << size << " bits." << endl;
// zero extend hex numbers
while (idx < size) switch (ptr[1]) {
while (idx < size) switch (ptr[0]) {
case 'x': case 'X':
bits[idx++] = verinum::Vx;
break;
@@ -1024,6 +1038,8 @@ static void line_directive2()
cp += strspn(cp, " ");
yylloc.first_line = strtoul(cp,&cp,10);
yylloc.first_line -= 1;
cp += strspn(cp, " ");
if (*cp == 0) return;
@@ -1041,7 +1057,8 @@ static void line_directive2()
yylloc.text = set_file_name(buf);
}
static void reset_lexor()
extern FILE*vl_input;
void reset_lexor()
{
yyrestart(vl_input);
yylloc.first_line = 1;
+1
View File
@@ -1,6 +1,7 @@
%{
/* 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>
+53 -6
View File
@@ -17,9 +17,11 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: link_const.cc,v 1.7 2000/11/20 01:41:12 steve Exp $"
#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"
@@ -35,18 +37,44 @@ bool link_drivers_constant(const Link&lnk)
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. This is pertinant
because REGs are PASSIVE but can receive values from
procedural assignments. */
if ((cur->get_dir() == Link::PASSIVE)
&& (cur->get_init() == verinum::Vz))
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()))
@@ -95,6 +123,25 @@ verinum::V driven_value(const Link&lnk)
/*
* $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.
*
+78
View File
@@ -0,0 +1,78 @@
/*
* 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)
#ident "$Id: load_module.cc,v 1.4 2001/11/20 23:36:34 steve Exp $"
#endif
# include "config.h"
# include "util.h"
# include "parse_api.h"
# include "compiler.h"
# include <iostream.h>
const char dir_character = '/';
bool load_module(const char*type)
{
char path[4096];
for (list<const char*>::iterator cur = library_dirs.begin()
; cur != library_dirs.end()
; cur ++ ) {
for (list<const char*>::iterator suf = library_suff.begin()
; suf != library_suff.end()
; suf ++ ) {
sprintf(path, "%s%c%s%s", *cur, dir_character, type, *suf);
FILE*file = fopen(path, "r");
if (file == 0)
continue;
if (verbose_flag) {
cerr << "Loading library file " << path << "." << endl;
}
pform_parse(path, file);
fclose(file);
return true;
}
}
return false;
}
/*
* $Log: load_module.cc,v $
* Revision 1.4 2001/11/20 23:36:34 steve
* Close library files after parsing.
*
* Revision 1.3 2001/11/16 05:07:19 steve
* Add support for +libext+ in command files.
*
* Revision 1.2 2001/10/22 02:05:21 steve
* Handle activating tasks in another root.
*
* Revision 1.1 2001/10/20 23:02:40 steve
* Add automatic module libraries.
*
*/
+37
View File
@@ -0,0 +1,37 @@
This file describes the procedure to build and install Icarus Verilog on Mac OS X. I assume that you have experience with Unix and Terminal.app.
1) Obtain and install a libdl compatibility library.
If you don't already have /usr/local/lib/libdl.{a,dylib} and /usr/local/include/dlfcn.h, you can obtain the source for a compatibility layer from at least one of two places:
http://download.sourceforge.net/fink/dlcompat-20010831.tar.gz
http://www.omnigroup.com/~bungi/dlcompat-20010831.tar.gz
Unpack this tar file and read the README and Makefile. Install the library according to the instructions. Installation in /usr/local is strongly recommended since otherwise autoconf very likely won't be able to find it.
2) Make sure you have a copy of the 'gperf' tool. This does not come with the Mac OS X 10.1 developer tools, so you probably don't. You can check with:
% which gperf
If not found, grab a gperf source package and install it.
ftp://ftp.gnu.org/gnu/gperf/gperf-2.7.2.tar.gz
3) Configure, build and install the Icarus Verilog sources as normal.
The only change you need to make here is to use a configure command like:
% CC="cc -no-cpp-precomp" ./configure
This assumes you are using 'sh', 'zsh', or 'bash'. If you are using 'csh' or 'tcsh', then you'll want something like:
% setenv CC "cc -no-cpp-precomp"
% ./configure
You can, of course, add other configure options.
4) Done!
+229 -48
View File
@@ -19,9 +19,11 @@ const char COPYRIGHT[] =
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: main.cc,v 1.40 2001/01/20 19:02:05 steve Exp $"
#ident "$Id: main.cc,v 1.51 2001/11/16 05:07:19 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"
@@ -42,28 +44,53 @@ const char NOTICE[] =
# include <iostream.h>
# include <fstream>
# include <queue>
# include <list>
# 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 "parse_api.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 $";
const char*target = "null";
string start_module = "";
map<string,string> flags;
list<const char*> library_dirs;
list<const char*> library_suff;
/*
* These are the warning enable flags.
*/
bool warn_implicit = false;
/*
* Verbose messages enabled.
*/
bool verbose_flag = false;
static void parm_to_flagmap(const string&flag)
{
@@ -82,9 +109,7 @@ static void parm_to_flagmap(const string&flag)
}
extern Design* elaborate(const map<string,Module*>&modules,
const map<string,PUdp*>&primitives,
const string&root);
extern Design* elaborate(list <const char*>root);
extern void cprop(Design*des);
extern void synth(Design*des);
@@ -114,23 +139,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 times_flag = false;
const char* net_path = 0;
const char* pf_path = 0;
const char* warn_en = "";
int opt;
unsigned flag_errors = 0;
queue<net_func> net_func_queue;
list<const char*> roots;
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:vW:")) != EOF) switch (opt) {
while ((opt = getopt(argc, argv, "F:f:hm:N:o:P:p:s:T:t:VvW:Y:y:")) != EOF) switch (opt) {
case 'F': {
net_func tmp = name_to_net_func(optarg);
if (tmp == 0) {
@@ -164,7 +224,7 @@ int main(int argc, char*argv[])
parm_to_flagmap(optarg);
break;
case 's':
start_module = optarg;
roots.push_back(optarg);
break;
case 'T':
if (strcmp(optarg,"min") == 0) {
@@ -186,6 +246,12 @@ int main(int argc, char*argv[])
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;
@@ -193,6 +259,12 @@ int main(int argc, char*argv[])
case 'W':
warn_en = optarg;
break;
case 'y':
library_dirs.push_back(optarg);
break;
case 'Y':
library_suff.push_back(optarg);
break;
default:
flag_errors += 1;
break;
@@ -202,12 +274,35 @@ 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"
"\t-y <dir> Add directory to library search path.\n"
"\t-Y <suf> Add suffix string library search path.\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;
}
@@ -216,6 +311,12 @@ int main(int argc, char*argv[])
return 1;
}
/* If there were no -Y flags, then create a minimal library
suffix search list. */
if (library_suff.empty()) {
library_suff.push_back(".v");
}
/* Scan the warnings enable string for warning flags. */
for (const char*cp = warn_en ; *cp ; cp += 1) switch (*cp) {
case 'i':
@@ -225,22 +326,26 @@ int main(int argc, char*argv[])
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;
int rc = pform_parse(argv[optind], modules, primitives);
int rc = pform_parse(argv[optind]);
if (pf_path) {
ofstream out (pf_path);
out << "PFORM DUMP MODULES:" << endl;
for (map<string,Module*>::iterator mod = modules.begin()
; mod != modules.end()
for (map<string,Module*>::iterator mod = pform_modules.begin()
; mod != pform_modules.end()
; mod ++ ) {
pform_dump(out, (*mod).second);
}
out << "PFORM DUMP PRIMITIVES:" << endl;
for (map<string,PUdp*>::iterator idx = primitives.begin()
; idx != primitives.end()
for (map<string,PUdp*>::iterator idx = pform_primitives.begin()
; idx != pform_primitives.end()
; idx ++ ) {
(*idx).second->dump(out);
}
@@ -251,65 +356,89 @@ int main(int argc, char*argv[])
}
/* 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 the user did not give specific module(s) to start with,
then look for modules that are not instantiated anywhere. */
if (start_module == "") {
for (map<string,Module*>::iterator mod = modules.begin()
; mod != modules.end()
; mod ++ ) {
Module*cur = (*mod).second;
if (cur->port_count() == 0)
if (start_module == "") {
start_module = cur->get_name();
} else {
cerr << "More then 1 top level module."
<< endl;
return 1;
if (roots.empty()) {
map<string,bool> mentioned_p;
map<string,Module*>::iterator mod;
if (verbose_flag)
cout << "LOCATING TOP-LEVEL MODULES..." << endl << " ";
for (mod = pform_modules.begin()
; mod != pform_modules.end()
; mod++) {
list<PGate*> gates = (*mod).second->get_gates();
list<PGate*>::const_iterator gate;
for (gate = gates.begin(); gate != gates.end(); gate++) {
PGModule *mod = dynamic_cast<PGModule*>(*gate);
if (mod) {
// Note that this module has been instantiated
mentioned_p[mod->get_type()] = true;
}
}
}
for (mod = pform_modules.begin()
; mod != pform_modules.end()
; mod++) {
if (mentioned_p[(*mod).second->mod_name()] == false) {
if (verbose_flag)
cout << " " << (*mod).second->mod_name();
roots.push_back((*mod).second->mod_name());
}
}
if (verbose_flag)
cout << endl;
}
/* 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 == "") {
if (roots.empty()) {
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" << endl;
}
/* On with the process of elaborating the module. */
Design*des = elaborate(modules, primitives, start_module);
Design*des = elaborate(roots);
if (des == 0) {
cerr << start_module << ": error: "
<< "Unable to elaborate module." << endl;
cerr << "Elaboration failed" << endl;
return 1;
}
if (des->errors) {
cerr << start_module << ": error: " << des->errors
<< " elaborating module." << endl;
cerr << des->errors
<< " error(s) during elaboration." << 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);
}
@@ -319,17 +448,69 @@ int main(int argc, char*argv[])
}
if (verbose_flag) {
if (times_flag) {
times(cycles+3);
cerr<<" ... done, "
<<cycles_diff(cycles+3, cycles+2)<<" seconds."<<endl;
}
cout << "CODE GENERATION -t "<<target<<" ..." << endl;
}
bool emit_rc = emit(des, target);
if (!emit_rc) {
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.51 2001/11/16 05:07:19 steve
* Add support for +libext+ in command files.
*
* Revision 1.50 2001/10/20 23:02:40 steve
* Add automatic module libraries.
*
* Revision 1.49 2001/10/20 05:21:51 steve
* Scope/module names are char* instead of string.
*
* Revision 1.48 2001/10/19 21:53:24 steve
* Support multiple root modules (Philip Blundell)
*
* Revision 1.47 2001/07/30 02:44:05 steve
* Cleanup defines and types for mingw compile.
*
* 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.45 2001/07/16 18:14:56 steve
* Reshuffle -v and -V flags of ivl. (Stephan Boettcher)
*
* Revision 1.44 2001/07/03 04:09:24 steve
* Generate verbuse status messages (Stephan Boettcher)
*
* Revision 1.43 2001/07/02 01:57:27 steve
* Add the -V flag, and some verbose messages.
*
* Revision 1.42 2001/06/23 18:41:02 steve
* Include stdlib.h
*
* Revision 1.41 2001/05/20 17:35:05 steve
* declare getopt by hand in mingw32 compile.
*
* Revision 1.40 2001/01/20 19:02:05 steve
* Switch hte -f flag to the -p flag.
*
+41 -2
View File
@@ -17,9 +17,11 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: mangle.cc,v 1.5 2000/12/11 01:06:24 steve Exp $"
#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();
@@ -59,6 +61,10 @@ string mangle(const string&str)
res << "$$";
tmp = tmp.substr(1);
break;
case '/':
res << "$sl$";
tmp = tmp.substr(1);
break;
case '[':
res << "$lb$";
tmp = tmp.substr(1);
@@ -73,8 +79,41 @@ string mangle(const string&str)
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;
return res.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)
*
+127
View File
@@ -0,0 +1,127 @@
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 a little tricky, however, because
the tools like "strip", "ranlib" and etc. that come with Mingw do not
understand the Cygwin style paths that are in the makefile. To get
around that problem, first remove the Mingw from your path before
doing the next step. An easy way to do that is to open a fresh Cygwin
window.
When you are ready, install like this:
$ make install
This is part of what the configure program did for you. The Makefiles
now know to put the files under the D:\iverilog (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.
+83 -9
View File
@@ -17,9 +17,11 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: net_assign.cc,v 1.6 2000/10/18 20:04:39 steve Exp $"
#ident "$Id: net_assign.cc,v 1.8 2001/08/25 23:50:03 steve Exp $"
#endif
# include "config.h"
# include "netlist.h"
/*
@@ -36,19 +38,18 @@ unsigned count_lval_width(const NetAssign_*idx)
return wid;
}
NetAssign_::NetAssign_(const string&n, unsigned w)
: NetNode(n, w), bmux_(0)
NetAssign_::NetAssign_(NetNet*s)
: sig_(s), bmux_(0)
{
for (unsigned idx = 0 ; idx < pin_count() ; idx += 1) {
pin(idx).set_dir(Link::OUTPUT);
pin(idx).set_name("P", idx);
}
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_;
}
@@ -67,7 +68,34 @@ const NetExpr* NetAssign_::bmux() const
unsigned NetAssign_::lwidth() const
{
if (bmux_) return 1;
else return pin_count();
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)
@@ -165,14 +193,60 @@ 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.
*
+104 -100
View File
@@ -17,9 +17,13 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: net_design.cc,v 1.18 2001/01/14 23:04:56 steve Exp $"
#ident "$Id: net_design.cc,v 1.23 2001/12/03 04:47:15 steve Exp $"
#endif
# include "config.h"
# include <iostream>
/*
* This source file contains all the implementations of the Design
* class declared in netlist.h.
@@ -30,7 +34,7 @@
# include <strstream>
Design:: Design()
: errors(0), root_scope_(0), nodes_(0), procs_(0), lcounter_(0)
: errors(0), nodes_(0), procs_(0), lcounter_(0)
{
procs_idx_ = 0;
des_precision_ = 0;
@@ -73,24 +77,29 @@ unsigned long Design::scale_to_precision(unsigned long val,
return val;
}
NetScope* Design::make_root_scope(const string&root)
NetScope* Design::make_root_scope(const char*root)
{
assert(root_scope_ == 0);
NetScope *root_scope_;
root_scope_ = new NetScope(0, root, NetScope::MODULE);
root_scope_->set_module_name(root.c_str());
root_scope_->set_module_name(root);
root_scopes_.push_back(root_scope_);
return root_scope_;
}
NetScope* Design::find_root_scope()
{
assert(root_scope_);
return root_scope_;
assert(root_scopes_.front());
return root_scopes_.front();
}
const NetScope* Design::find_root_scope() const
list<NetScope*> Design::find_root_scopes()
{
assert(root_scope_);
return root_scope_;
return root_scopes_;
}
const list<NetScope*> Design::find_root_scopes() const
{
return root_scopes_;
}
/*
@@ -99,25 +108,28 @@ const NetScope* Design::find_root_scope() const
* more step down the tree until the name runs out or the search
* fails.
*/
NetScope* Design::find_scope(const string&key) const
NetScope* Design::find_scope(const hname_t&path) const
{
if (key == root_scope_->name())
return root_scope_;
for (list<NetScope*>::const_iterator scope = root_scopes_.begin()
; scope != root_scopes_.end(); scope++) {
string path = key;
string root = parse_first_name(path);
NetScope*cur = *scope;
if (strcmp(path.peek_name(0), cur->basename()) != 0)
continue;
NetScope*cur = root_scope_;
if (root != cur->name())
return 0;
unsigned hidx = 1;
while (cur) {
const char*name = path.peek_name(hidx);
if (name == 0)
return cur;
cur = cur->child(name);
hidx += 1;
}
while (cur) {
string next = parse_first_name(path);
cur = cur->child(next);
if (path == "") return cur;
}
return cur;
return 0;
}
/*
@@ -127,26 +139,27 @@ NetScope* Design::find_scope(const string&key) const
* 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
NetScope* Design::find_scope(NetScope*scope, const hname_t&path) const
{
assert(scope);
for ( ; scope ; scope = scope->parent()) {
string path = name;
string key = parse_first_name(path);
unsigned hidx = 0;
const char*key = path.peek_name(hidx);
NetScope*cur = scope;
do {
cur = cur->child(key);
if (cur == 0) break;
key = parse_first_name(path);
} while (key != "");
hidx += 1;
key = path.peek_name(hidx);
} while (key);
if (cur) return cur;
}
// Last chance. Look for the name starting at the root.
return find_scope(name);
return find_scope(path);
}
/*
@@ -158,22 +171,23 @@ NetScope* Design::find_scope(NetScope*scope, const string&name) const
* follow the scopes of the name down to to key.
*/
const NetExpr* Design::find_parameter(const NetScope*scope,
const string&name) const
const hname_t&path) const
{
for ( ; scope ; scope = scope->parent()) {
string path = name;
string key = parse_first_name(path);
unsigned hidx = 0;
const NetScope*cur = scope;
while (path != "") {
cur = cur->child(key);
if (cur == 0) break;
key = parse_first_name(path);
while (path.peek_name(hidx+1)) {
cur = cur->child(path.peek_name(hidx));
if (cur == 0)
break;
hidx += 1;
}
if (cur == 0) continue;
if (cur == 0)
continue;
if (const NetExpr*res = cur->get_parameter(key))
if (const NetExpr*res = cur->get_parameter(path.peek_name(hidx)))
return res;
}
@@ -190,7 +204,9 @@ const NetExpr* Design::find_parameter(const NetScope*scope,
*/
void Design::run_defparams()
{
root_scope_->run_defparams(this);
for (list<NetScope*>::const_iterator scope = root_scopes_.begin();
scope != root_scopes_.end(); scope++)
(*scope)->run_defparams(this);
}
void NetScope::run_defparams(Design*des)
@@ -201,16 +217,18 @@ void NetScope::run_defparams(Design*des)
cur = cur->sib_;
}
map<string,NetExpr*>::const_iterator pp;
map<hname_t,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);
hname_t path = (*pp).first;
char*name = path.remove_tail_name();
NetScope*targ_scope = des->find_scope(this, path);
if (targ_scope == 0) {
cerr << val->get_line() << ": warning: scope of " <<
path << "." << name << " not found." << endl;
delete[]name;
continue;
}
@@ -222,12 +240,16 @@ void NetScope::run_defparams(Design*des)
} else {
delete val;
}
delete[]name;
}
}
void Design::evaluate_parameters()
{
root_scope_->evaluate_parameters(this);
for (list<NetScope*>::const_iterator scope = root_scopes_.begin();
scope != root_scopes_.end(); scope++)
(*scope)->evaluate_parameters(this);
}
void NetScope::evaluate_parameters(Design*des)
@@ -294,87 +316,52 @@ string Design::get_flag(const string&key) const
* 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)
NetNet* Design::find_signal(NetScope*scope, hname_t path)
{
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 != "")
char*key = path.remove_tail_name();
if (path.peek_name(0))
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))
if (NetNet*net = scope->find_signal(key)) {
delete key;
return net;
}
if (scope->type() == NetScope::MODULE)
break;
scope = scope->parent();
}
delete key;
return 0;
}
NetMemory* Design::find_memory(NetScope*scope, const string&name)
NetMemory* Design::find_memory(NetScope*scope, hname_t path)
{
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 != "")
char*key = path.remove_tail_name();
if (path.peek_name(0))
scope = find_scope(scope, path);
while (scope) {
if (NetMemory*mem = scope->find_memory(key))
if (NetMemory*mem = scope->find_memory(key)) {
delete key;
return mem;
}
scope = scope->parent();
}
delete key;
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)
NetFuncDef* Design::find_function(NetScope*scope, const hname_t&name)
{
assert(scope);
NetScope*func = find_scope(scope, name);
@@ -384,7 +371,7 @@ NetFuncDef* Design::find_function(NetScope*scope, const string&name)
return 0;
}
NetFuncDef* Design::find_function(const string&key)
NetFuncDef* Design::find_function(const hname_t&key)
{
NetScope*func = find_scope(key);
if (func && (func->type() == NetScope::FUNC))
@@ -393,20 +380,20 @@ NetFuncDef* Design::find_function(const string&key)
return 0;
}
NetTaskDef* Design::find_task(NetScope*scope, const string&name)
NetScope* Design::find_task(NetScope*scope, const hname_t&name)
{
NetScope*task = find_scope(scope, name);
if (task && (task->type() == NetScope::TASK))
return task->task_def();
return task;
return 0;
}
NetTaskDef* Design::find_task(const string&key)
NetScope* Design::find_task(const hname_t&key)
{
NetScope*task = find_scope(key);
if (task && (task->type() == NetScope::TASK))
return task->task_def();
return task;
return 0;
}
@@ -473,6 +460,23 @@ void Design::delete_process(NetProcTop*top)
/*
* $Log: net_design.cc,v $
* Revision 1.23 2001/12/03 04:47:15 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
*
* Revision 1.22 2001/10/20 05:21:51 steve
* Scope/module names are char* instead of string.
*
* Revision 1.21 2001/10/19 21:53:24 steve
* Support multiple root modules (Philip Blundell)
*
* 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.
+35 -3
View File
@@ -17,9 +17,11 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: net_event.cc,v 1.12 2000/12/15 17:45:07 steve Exp $"
#ident "$Id: net_event.cc,v 1.16 2001/10/28 01:14:53 steve Exp $"
#endif
# include "config.h"
# include "netlist.h"
NetEvent::NetEvent(const string&n)
@@ -58,6 +60,12 @@ string NetEvent::full_name() const
return scope_->name() + "." + name_;
}
const NetScope* NetEvent::scope() const
{
assert(scope_);
return scope_;
}
unsigned NetEvent::nprobe() const
{
unsigned cnt = 0;
@@ -80,6 +88,16 @@ NetEvProbe* NetEvent::probe(unsigned idx)
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;
@@ -265,9 +283,9 @@ const NetEvent* NetEvTrig::event() const
return event_;
}
NetEvProbe::NetEvProbe(const string&n, NetEvent*tgt,
NetEvProbe::NetEvProbe(NetScope*s, const string&n, NetEvent*tgt,
edge_t t, unsigned p)
: NetNode(n, p), event_(tgt), edge_(t)
: NetNode(s, n, p), event_(tgt), edge_(t)
{
for (unsigned idx = 0 ; idx < p ; idx += 1) {
pin(idx).set_dir(Link::INPUT);
@@ -433,6 +451,20 @@ NetProc* NetEvWait::statement()
/*
* $Log: net_event.cc,v $
* Revision 1.16 2001/10/28 01:14:53 steve
* NetObj constructor finally requires a scope.
*
* 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.
*
+30 -5
View File
@@ -17,9 +17,11 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: net_force.cc,v 1.2 2000/05/12 01:22:41 steve Exp $"
#ident "$Id: net_force.cc,v 1.6 2001/11/14 03:28: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
@@ -42,8 +44,8 @@
* 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)
NetCAssign::NetCAssign(NetScope*s, const string&n, NetNet*l)
: NetNode(s, n, l->pin_count()), lval_(l)
{
lval_->incr_eref();
for (unsigned idx = 0 ; idx < pin_count() ; idx += 1) {
@@ -57,6 +59,11 @@ NetCAssign::~NetCAssign()
lval_->decr_eref();
}
const NetNet* NetCAssign::lval() const
{
return lval_;
}
const Link& NetCAssign::lval_pin(unsigned idx) const
{
assert(idx < lval_->pin_count());
@@ -79,8 +86,8 @@ const NetNet*NetDeassign::lval() const
return lval_;
}
NetForce::NetForce(const string&n, NetNet*l)
: NetNode(n, l->pin_count()), lval_(l)
NetForce::NetForce(NetScope*s, const string&n, NetNet*l)
: NetNode(s, n, l->pin_count()), lval_(l)
{
for (unsigned idx = 0 ; idx < pin_count() ; idx += 1) {
pin(idx).set_dir(Link::INPUT);
@@ -98,6 +105,11 @@ const Link& NetForce::lval_pin(unsigned idx) const
return lval_->pin(idx);
}
const NetNet* NetForce::lval() const
{
return lval_;
}
NetRelease::NetRelease(NetNet*l)
: lval_(l)
{
@@ -115,6 +127,19 @@ const NetNet*NetRelease::lval() const
/*
* $Log: net_force.cc,v $
* Revision 1.6 2001/11/14 03:28:49 steve
* DLL target support for force and release.
*
* Revision 1.5 2001/10/31 05:24:52 steve
* ivl_target support for assign/deassign.
*
* Revision 1.4 2001/10/28 01:14:53 steve
* NetObj constructor finally requires a scope.
*
* 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.
*
+9 -1
View File
@@ -17,9 +17,13 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: net_link.cc,v 1.4 2000/10/06 23:46:50 steve Exp $"
#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>
@@ -350,6 +354,10 @@ const char* Nexus::name() const
/*
* $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
+5 -3
View File
@@ -17,9 +17,11 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: net_modulo.cc,v 1.1 2000/09/17 21:26:15 steve Exp $"
#ident "$Id: net_modulo.cc,v 1.3 2001/10/28 01:14:53 steve Exp $"
#endif
# include "config.h"
# include <typeinfo>
# include <iostream>
# include <iomanip>
@@ -28,9 +30,9 @@
# include "netlist.h"
NetModulo::NetModulo(const string&n, unsigned wr,
NetModulo::NetModulo(NetScope*s, const string&n, unsigned wr,
unsigned wa, unsigned wb)
: NetNode(n, wr+wa+wb), width_r_(wr), width_a_(wa), width_b_(wb)
: NetNode(s, 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) {
+7 -1
View File
@@ -17,9 +17,11 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: net_proc.cc,v 1.2 2000/07/27 05:13:44 steve Exp $"
#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>
@@ -93,6 +95,10 @@ const NetExpr* NetRepeat::expr() const
/*
* $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.
*
+57 -29
View File
@@ -17,9 +17,11 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: net_scope.cc,v 1.11 2000/12/16 01:45:48 steve Exp $"
#ident "$Id: net_scope.cc,v 1.16 2001/12/03 04:47:15 steve Exp $"
#endif
# include "config.h"
# include "netlist.h"
# include <strstream>
@@ -32,7 +34,7 @@
* in question.
*/
NetScope::NetScope(NetScope*up, const string&n, NetScope::TYPE t)
NetScope::NetScope(NetScope*up, const char*n, NetScope::TYPE t)
: type_(t), up_(up), sib_(0), sub_(0)
{
memories_ = 0;
@@ -61,8 +63,8 @@ NetScope::NetScope(NetScope*up, const string&n, NetScope::TYPE t)
module_name_ = 0;
break;
}
name_ = new char[n.length()+1];
strcpy(name_, n.c_str());
name_ = new char[strlen(n)+1];
strcpy(name_, n);
}
NetScope::~NetScope()
@@ -222,10 +224,10 @@ void NetScope::rem_event(NetEvent*ev)
}
NetEvent* NetScope::find_event(const string&name)
NetEvent* NetScope::find_event(const hname_t&name)
{
for (NetEvent*cur = events_; cur ; cur = cur->snext_)
if (cur->name() == name)
if (strcmp(cur->name(), name.peek_tail_name()) == 0)
return cur;
return 0;
@@ -259,6 +261,11 @@ void NetScope::rem_signal(NetNet*net)
}
}
/*
* This method looks for a signal within the current scope. The name
* is assumed to be the base name of the signal, so no sub-scopes are
* searched.
*/
NetNet* NetScope::find_signal(const string&key)
{
if (signals_ == 0)
@@ -274,6 +281,27 @@ NetNet* NetScope::find_signal(const string&key)
return 0;
}
/*
* This method searches for the signal within this scope. If the path
* has hierarchy, I follow the child scopes until I get the base name,
* and look for the key in the deepest scope.
*/
NetNet* NetScope::find_signal_in_child(const hname_t&path)
{
NetScope*cur = this;
unsigned idx = 0;
while (path.peek_name(idx+1)) {
cur = cur->child(path.peek_name(idx));
if (cur == 0)
return 0;
idx += 1;
}
return cur->find_signal(path.peek_name(idx));
}
void NetScope::add_memory(NetMemory*mem)
{
if (memories_ == 0) {
@@ -362,13 +390,35 @@ const NetScope* NetScope::parent() const
string NetScope::local_symbol()
{
strstream res;
res << "_l" << (lcounter_++) << ends;
res << "_s" << (lcounter_++) << ends;
return res.str();
}
string NetScope::local_hsymbol()
{
return name() + "." + local_symbol();
}
/*
* $Log: net_scope.cc,v $
* Revision 1.16 2001/12/03 04:47:15 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
*
* Revision 1.15 2001/11/08 05:15:50 steve
* Remove string paths from PExpr elaboration.
*
* Revision 1.14 2001/10/20 05:21:51 steve
* Scope/module names are char* instead of string.
*
* 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)
*
@@ -389,27 +439,5 @@ string NetScope::local_symbol()
* signal enaboration, and carry these objects in the
* NetScope class instead of the extra, useless map in
* the Design class.
*
* Revision 1.7 2000/07/22 22:09:03 steve
* Parse and elaborate timescale to scopes.
*
* Revision 1.6 2000/05/02 03:13:31 steve
* Move memories to the NetScope object.
*
* Revision 1.5 2000/05/02 00:58:12 steve
* Move signal tables to the NetScope class.
*
* Revision 1.4 2000/04/18 04:50:20 steve
* Clean up unneeded NetEvent objects.
*
* Revision 1.3 2000/04/10 05:26:06 steve
* All events now use the NetEvent class.
*
* Revision 1.2 2000/04/09 17:04:56 steve
* uninitialized event_ list.
*
* Revision 1.1 2000/04/04 03:20:15 steve
* Simulate named event trigger and waits.
*
*/
+59 -152
View File
@@ -1,5 +1,6 @@
/*
* 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
@@ -17,128 +18,15 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: net_udp.cc,v 1.3 2000/12/15 01:24:17 steve Exp $"
#ident "$Id: net_udp.cc,v 1.6 2001/07/25 03:10:49 steve Exp $"
#endif
# include "config.h"
# include "netlist.h"
bool NetUDP::set_table(const string&input, char output)
{
assert((output == '0') || (output == '1')
|| (is_sequential() && (output == '-')));
cm_[input] = output;
if (is_sequential()) {
assert(input.length() == pin_count());
/* XXXX Need to check to make sure that the input vector
contains a legal combination of characters. */
return sequ_glob_(input, output);
} else {
assert(input.length() == (pin_count()-1));
/* XXXX Need to check to make sure that the input vector
contains a legal combination of characters. In
combinational UDPs, only 0, 1, x, and ? are allowed. */
return true;
}
}
void NetUDP::cleanup_table()
{
for (FSM_::iterator idx = fsm_.begin() ; idx != fsm_.end() ; idx++) {
string str = (*idx).first;
state_t_*st = (*idx).second;
assert(str[0] == st->out);
for (unsigned pin = 0 ; pin < pin_count() ; pin += 1) {
if (st->pins[pin].zer && st->pins[pin].zer->out == 'x')
st->pins[pin].zer = 0;
if (st->pins[pin].one && st->pins[pin].one->out == 'x')
st->pins[pin].one = 0;
if (st->pins[pin].xxx && st->pins[pin].xxx->out == 'x')
st->pins[pin].xxx = 0;
}
}
for (FSM_::iterator idx = fsm_.begin() ; idx != fsm_.end() ; ) {
FSM_::iterator cur = idx;
idx ++;
state_t_*st = (*cur).second;
if (st->out != 'x')
continue;
for (unsigned pin = 0 ; pin < pin_count() ; pin += 1) {
if (st->pins[pin].zer)
goto break_label;
if (st->pins[pin].one)
goto break_label;
if (st->pins[pin].xxx)
goto break_label;
}
//delete st;
fsm_.erase(cur);
break_label:;
}
}
char NetUDP::table_lookup(const string&from, char to, unsigned pin) const
{
assert(pin <= pin_count());
assert(from.length() == pin_count());
FSM_::const_iterator idx = fsm_.find(from);
if (idx == fsm_.end())
return 'x';
state_t_*next;
switch (to) {
case '0':
next = (*idx).second->pins[pin].zer;
break;
case '1':
next = (*idx).second->pins[pin].one;
break;
case 'x':
next = (*idx).second->pins[pin].xxx;
break;
default:
assert(0);
next = 0;
}
return next? next->out : 'x';
}
void NetUDP::set_initial(char val)
{
assert(is_sequential());
assert((val == '0') || (val == '1') || (val == 'x'));
init_ = val;
}
NetUDP::state_t_* NetUDP::find_state_(const string&str)
{
map<string,state_t_*>::iterator cur = fsm_.find(str);
if (cur != fsm_.end())
return (*cur).second;
state_t_*st = fsm_[str];
if (st == 0) {
st = new state_t_(pin_count());
st->out = str[0];
fsm_[str] = st;
}
return st;
}
NetUDP_COMB::NetUDP_COMB(const string&n, unsigned pins, bool sequ)
: NetNode(n, pins), sequential_(sequ)
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);
@@ -148,52 +36,71 @@ NetUDP_COMB::NetUDP_COMB(const string&n, unsigned pins, bool sequ)
}
}
bool NetUDP_COMB::set_table(const string&input, char output)
bool NetUDP::first(string&inp, char&out) const
{
if ((output != '0') && (output != '1') && (output != 'x'))
return false;
table_idx = (unsigned) -1;
return next(inp, out);
}
bool NetUDP::next(string&inp, char&out) const
{
table_idx++;
assert((output == '0') || (output == '1') || (output == 'x'));
assert(input.length() == (pin_count()-1));
if (table_idx >= udp->tinput.count())
return false;
/* XXXX Need to check to make sure that the input vector
contains a legal combination of characters. In
combinational UDPs, only 0, 1, x, and ? are allowed. */
cm_[input] = output;
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));
}
return true;
out = udp->toutput[table_idx];
assert( (out == '0')
|| (out == '1')
|| (out == 'x')
|| (is_sequential() && (out == '-')));
return true;
}
void NetUDP_COMB::cleanup_table()
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';
}
bool NetUDP_COMB::first(string&inp, char&out) const
{
idx_ = cm_.begin();
if (idx_ == cm_.end())
return false;
inp = (*idx_).first;
out = (*idx_).second;
return true;
}
bool NetUDP_COMB::next(string&inp, char&out) const
{
idx_ ++;
if (idx_ == cm_.end())
return false;
inp = (*idx_).first;
out = (*idx_).second;
return true;
}
/*
* $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)
*
+257 -237
View File
@@ -17,9 +17,13 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: netlist.cc,v 1.154 2001/01/18 03:16:35 steve Exp $"
#ident "$Id: netlist.cc,v 1.178 2001/12/03 04:47:15 steve Exp $"
#endif
# include "config.h"
# include <iostream>
# include <cassert>
# include <typeinfo>
# include "netlist.h"
@@ -159,8 +163,8 @@ Link* find_next_output(Link*lnk)
return 0;
}
NetObj::NetObj(const string&n, unsigned np)
: scope_(0), npins_(np), delay1_(0), delay2_(0), delay3_(0)
NetObj::NetObj(NetScope*s, const string&n, unsigned np)
: scope_(s), npins_(np), delay1_(0), delay2_(0), delay3_(0)
{
name_ = new char[n.length()+1];
strcpy(name_, n.c_str());
@@ -172,11 +176,11 @@ NetObj::NetObj(const string&n, unsigned np)
}
}
NetObj::NetObj(NetScope*s, const string&n, unsigned np)
NetObj::NetObj(NetScope*s, const char*n, unsigned np)
: scope_(s), npins_(np), delay1_(0), delay2_(0), delay3_(0)
{
name_ = new char[n.length()+1];
strcpy(name_, n.c_str());
name_ = new char[strlen(n)+1];
strcpy(name_, n);
pins_ = new Link[npins_];
for (unsigned idx = 0 ; idx < npins_ ; idx += 1) {
@@ -249,12 +253,12 @@ const Link& NetObj::pin(unsigned idx) const
return pins_[idx];
}
NetNode::NetNode(const string&n, unsigned npins)
: NetObj(n, npins), node_next_(0), node_prev_(0), design_(0)
NetNode::NetNode(NetScope*s, const string&n, unsigned npins)
: NetObj(s, n, npins), node_next_(0), node_prev_(0), design_(0)
{
}
NetNode::NetNode(NetScope*s, const string&n, unsigned npins)
NetNode::NetNode(NetScope*s, const char*n, unsigned npins)
: NetObj(s, n, npins), node_next_(0), node_prev_(0), design_(0)
{
}
@@ -303,16 +307,21 @@ NetNet::NetNet(NetScope*s, const string&n, Type t, unsigned npins)
assert(s);
verinum::V init_value = verinum::Vz;
Link::DIR dir = Link::PASSIVE;
switch (t) {
case REG:
case IMPLICIT_REG:
init_value = verinum::Vx;
dir = Link::OUTPUT;
break;
case SUPPLY0:
init_value = verinum::V0;
dir = Link::OUTPUT;
break;
case SUPPLY1:
init_value = verinum::V1;
dir = Link::OUTPUT;
break;
default:
break;
@@ -320,6 +329,7 @@ NetNet::NetNet(NetScope*s, const string&n, Type t, unsigned npins)
for (unsigned idx = 0 ; idx < npins ; idx += 1) {
pin(idx).set_name("P", idx);
pin(idx).set_dir(dir);
pin(idx).set_init(init_value);
}
@@ -335,16 +345,21 @@ NetNet::NetNet(NetScope*s, const string&n, Type t, long ms, long ls)
assert(s);
verinum::V init_value = verinum::Vz;
Link::DIR dir = Link::PASSIVE;
switch (t) {
case REG:
case IMPLICIT_REG:
init_value = verinum::Vx;
dir = Link::OUTPUT;
break;
case SUPPLY0:
init_value = verinum::V0;
dir = Link::OUTPUT;
break;
case SUPPLY1:
init_value = verinum::V1;
dir = Link::OUTPUT;
break;
default:
break;
@@ -352,6 +367,7 @@ NetNet::NetNet(NetScope*s, const string&n, Type t, long ms, long ls)
for (unsigned idx = 0 ; idx < pin_count() ; idx += 1) {
pin(idx).set_name("P", idx);
pin(idx).set_dir(dir);
pin(idx).set_init(init_value);
}
@@ -492,7 +508,7 @@ const NetScope* NetProcTop::scope() const
* ...
*/
NetFF::NetFF(NetScope*s, const string&n, unsigned wid)
NetFF::NetFF(NetScope*s, const char*n, unsigned wid)
: NetNode(s, n, 8 + 2*wid)
{
pin_Clock().set_dir(Link::INPUT);
@@ -620,8 +636,8 @@ const Link& NetFF::pin_Q(unsigned w) const
* 7 -- DataB[0]
* 8 -- Result[0]
*/
NetAddSub::NetAddSub(const string&n, unsigned w)
: NetNode(n, w*3+6)
NetAddSub::NetAddSub(NetScope*s, const string&n, unsigned w)
: NetNode(s, n, w*3+6)
{
pin(0).set_dir(Link::INPUT); pin(0).set_name("Add_Sub", 0);
pin(1).set_dir(Link::INPUT); pin(1).set_name("Aclr", 0);
@@ -709,8 +725,9 @@ const Link& NetAddSub::pin_Result(unsigned idx) const
* 3+W -- Result(0)
* 3+2W -- Distance(0)
*/
NetCLShift::NetCLShift(const string&n, unsigned width, unsigned width_dist)
: NetNode(n, 3+2*width+width_dist), width_(width), width_dist_(width_dist)
NetCLShift::NetCLShift(NetScope*s, const string&n,
unsigned width, unsigned width_dist)
: NetNode(s, n, 3+2*width+width_dist), width_(width), width_dist_(width_dist)
{
pin(0).set_dir(Link::INPUT); pin(0).set_name("Direction", 0);
pin(1).set_dir(Link::OUTPUT); pin(1).set_name("Underflow", 0);
@@ -810,8 +827,8 @@ const Link& NetCLShift::pin_Distance(unsigned idx) const
return pin(3+2*width_+idx);
}
NetCompare::NetCompare(const string&n, unsigned wi)
: NetNode(n, 8+2*wi), width_(wi)
NetCompare::NetCompare(NetScope*s, const string&n, unsigned wi)
: NetNode(s, n, 8+2*wi), width_(wi)
{
pin(0).set_dir(Link::INPUT); pin(0).set_name("Aclr");
pin(1).set_dir(Link::INPUT); pin(1).set_name("Clock");
@@ -938,9 +955,9 @@ const Link& NetCompare::pin_DataB(unsigned idx) const
return pin(8+width_+idx);
}
NetDivide::NetDivide(const string&n, unsigned wr,
NetDivide::NetDivide(NetScope*sc, const string&n, unsigned wr,
unsigned wa, unsigned wb)
: NetNode(n, wr+wa+wb), width_r_(wr), width_a_(wa), width_b_(wb)
: NetNode(sc, 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) {
@@ -1012,10 +1029,10 @@ const Link& NetDivide::pin_DataB(unsigned idx) const
return pin(idx+width_r_+width_a_);
}
NetMult::NetMult(const string&n, unsigned wr, unsigned wa, unsigned wb,
unsigned ws)
: NetNode(n, 2+wr+wa+wb+ws), width_r_(wr), width_a_(wa), width_b_(wb),
width_s_(ws)
NetMult::NetMult(NetScope*sc, const string&n, unsigned wr,
unsigned wa, unsigned wb, unsigned ws)
: NetNode(sc, n, 2+wr+wa+wb+ws), width_r_(wr), width_a_(wa), width_b_(wb),
width_s_(ws)
{
pin(0).set_dir(Link::INPUT); pin(0).set_name("Aclr", 0);
pin(1).set_dir(Link::INPUT); pin(1).set_name("Clock", 0);
@@ -1242,8 +1259,8 @@ const Link& NetMux::pin_Data(unsigned w, unsigned s) const
}
NetRamDq::NetRamDq(const string&n, NetMemory*mem, unsigned awid)
: NetNode(n, 3+2*mem->width()+awid), mem_(mem), awidth_(awid)
NetRamDq::NetRamDq(NetScope*s, const string&n, NetMemory*mem, unsigned awid)
: NetNode(s, n, 3+2*mem->width()+awid), mem_(mem), awidth_(awid)
{
pin(0).set_dir(Link::INPUT); pin(0).set_name("InClock", 0);
pin(1).set_dir(Link::INPUT); pin(1).set_name("OutClock", 0);
@@ -1554,8 +1571,8 @@ void NetCase::set_case(unsigned idx, NetExpr*e, NetProc*p)
items_[idx].guard->set_width(expr_->expr_width());
}
NetCaseCmp::NetCaseCmp(const string&n)
: NetNode(n, 3)
NetCaseCmp::NetCaseCmp(NetScope*s, const string&n)
: NetNode(s, n, 3)
{
pin(0).set_dir(Link::OUTPUT); pin(0).set_name("O",0);
pin(1).set_dir(Link::INPUT); pin(1).set_name("I",0);
@@ -1604,8 +1621,8 @@ NetProc* NetCondit::else_clause()
return else_;
}
NetConst::NetConst(const string&n, verinum::V v)
: NetNode(n, 1)
NetConst::NetConst(NetScope*s, const string&n, verinum::V v)
: NetNode(s, n, 1)
{
pin(0).set_dir(Link::OUTPUT);
pin(0).set_name("O", 0);
@@ -1613,8 +1630,8 @@ NetConst::NetConst(const string&n, verinum::V v)
value_[0] = v;
}
NetConst::NetConst(const string&n, const verinum&val)
: NetNode(n, val.len())
NetConst::NetConst(NetScope*s, const string&n, const verinum&val)
: NetNode(s, n, val.len())
{
value_ = new verinum::V[pin_count()];
for (unsigned idx = 0 ; idx < pin_count() ; idx += 1) {
@@ -1708,7 +1725,7 @@ const NetExpr* NetSTask::parm(unsigned idx) const
return parms_[idx];
}
NetEUFunc::NetEUFunc(NetFuncDef*def, NetESignal*res, svector<NetExpr*>&p)
NetEUFunc::NetEUFunc(NetScope*def, NetESignal*res, svector<NetExpr*>&p)
: func_(def), result_(res), parms_(p)
{
expr_width(result_->expr_width());
@@ -1741,7 +1758,7 @@ const NetExpr* NetEUFunc::parm(unsigned idx) const
return parms_[idx];
}
const NetFuncDef* NetEUFunc::definition() const
const NetScope* NetEUFunc::func() const
{
return func_;
}
@@ -1752,7 +1769,7 @@ NetEUFunc* NetEUFunc::dup_expr() const
return 0;
}
NetUTask::NetUTask(NetTaskDef*def)
NetUTask::NetUTask(NetScope*def)
: task_(def)
{
}
@@ -1761,6 +1778,16 @@ NetUTask::~NetUTask()
{
}
const string NetUTask::name() const
{
return task_->name();
}
const NetScope* NetUTask::task() const
{
return task_;
}
NetExpr::NetExpr(unsigned w)
: width_(w)
{
@@ -1780,21 +1807,15 @@ bool NetExpr::has_width() const
return true;
}
/*
* Create a bitwise operator node from the opcode and the left and
* right expressions. Don't worry about the width of the expression
* yet, we'll get that from the l-value, whatever that turns out to
* be.
*/
NetEBAdd::NetEBAdd(char op, NetExpr*l, NetExpr*r)
: NetEBinary(op, l, r)
{
if (l->expr_width() > r->expr_width())
r->set_width(l->expr_width());
if (r->expr_width() > l->expr_width())
l->set_width(r->expr_width());
if (l->expr_width() < r->expr_width())
r->set_width(l->expr_width());
if (r->expr_width() < l->expr_width())
l->set_width(r->expr_width());
if (r->expr_width() > l->expr_width())
expr_width(r->expr_width());
else
@@ -1812,32 +1833,20 @@ NetEBAdd* NetEBAdd::dup_expr() const
return result;
}
/*
* Create a bitwise operator node from the opcode and the left and
* right expressions. Don't worry about the width of the expression
* yet, we'll get that from the l-value, whatever that turns out to
* be. However, if we don't, our default will be the width of the
* largest operand.
*/
NetEBBits::NetEBBits(char op, NetExpr*l, NetExpr*r)
: NetEBinary(op, l, r)
{
/* First try to naturally adjust the size of the
expressions to match. */
if (l->expr_width() > r->expr_width())
r->set_width(l->expr_width());
if (r->expr_width() > l->expr_width())
l->set_width(r->expr_width());
if (l->expr_width() < r->expr_width())
r->set_width(l->expr_width());
if (r->expr_width() < l->expr_width())
l->set_width(r->expr_width());
/* If the expressions cannot be matched, pad them to fit. */
if (l->expr_width() > r->expr_width())
right_ = pad_to_width(r, l->expr_width());
if (r->expr_width() > l->expr_width())
left_ = pad_to_width(l, r->expr_width());
assert(left_->expr_width() == right_->expr_width());
expr_width(left_->expr_width());
expr_width(r->expr_width());
else
expr_width(l->expr_width());
}
NetEBBits::~NetEBBits()
@@ -1851,9 +1860,42 @@ NetEBBits* NetEBBits::dup_expr() const
return result;
}
/*
* Create a comparison operator with two sub-expressions.
*
* Handle the special case of an unsized constant on the left or right
* side by resizing the number to match the other
* expression. Otherwise, the netlist will have to allow the
* expressions to have different widths.
*/
NetEBComp::NetEBComp(char op, NetExpr*l, NetExpr*r)
: NetEBinary(op, l, r)
{
if (NetEConst*tmp = dynamic_cast<NetEConst*>(r)) do {
if (tmp->has_width())
break;
if (tmp->expr_width() == l->expr_width())
break;
tmp->set_width(l->expr_width());
} while (0);
if (NetEConst*tmp = dynamic_cast<NetEConst*>(l)) do {
if (tmp->has_width())
break;
if (tmp->expr_width() == r->expr_width())
break;
tmp->set_width(r->expr_width());
} while (0);
expr_width(1);
}
@@ -1900,6 +1942,11 @@ NetEBinary::~NetEBinary()
delete right_;
}
bool NetEBinary::has_width() const
{
return left_->has_width() && right_->has_width();
}
NetEBinary* NetEBinary::dup_expr() const
{
assert(0);
@@ -1949,6 +1996,11 @@ NetEBShift::~NetEBShift()
{
}
bool NetEBShift::has_width() const
{
return left_->has_width();
}
NetEBShift* NetEBShift::dup_expr() const
{
NetEBShift*result = new NetEBShift(op_, left_->dup_expr(),
@@ -1981,8 +2033,9 @@ NetEConcat* NetEConcat::dup_expr() const
NetEConcat*dup = new NetEConcat(parms_.count(), repeat_);
for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1)
if (parms_[idx]) {
assert(parms_[idx]->dup_expr());
dup->parms_[idx] = parms_[idx]->dup_expr();
NetExpr*tmp = parms_[idx]->dup_expr();
assert(tmp);
dup->parms_[idx] = tmp;
}
@@ -2070,7 +2123,7 @@ NetEParam::NetEParam()
{
}
NetEParam::NetEParam(Design*d, NetScope*s, const string&n)
NetEParam::NetEParam(Design*d, NetScope*s, const hname_t&n)
: des_(d), scope_(s), name_(n)
{
}
@@ -2079,6 +2132,11 @@ NetEParam::~NetEParam()
{
}
bool NetEParam::has_width() const
{
return false;
}
NetEParam* NetEParam::dup_expr() const
{
return new NetEParam(des_, scope_, name_);
@@ -2152,6 +2210,18 @@ NetExpr* NetESFunc::parm(unsigned idx)
NetESignal::NetESignal(NetNet*n)
: NetExpr(n->pin_count()), net_(n)
{
msi_ = n->pin_count() - 1;
lsi_ = 0;
net_->incr_eref();
set_line(*n);
}
NetESignal::NetESignal(NetNet*n, unsigned m, unsigned l)
: NetExpr(m - l + 1), net_(n)
{
assert(m >= l);
msi_ = m;
lsi_ = l;
net_->incr_eref();
set_line(*n);
}
@@ -2171,22 +2241,33 @@ bool NetESignal::has_sign() const
return net_->get_signed();
}
unsigned NetESignal::pin_count() const
unsigned NetESignal::bit_count() const
{
return net_->pin_count();
return msi_ - lsi_ + 1;
}
Link& NetESignal::pin(unsigned idx)
Link& NetESignal::bit(unsigned idx)
{
return net_->pin(idx);
assert(idx <= (msi_ - lsi_));
return net_->pin(idx + lsi_);
}
NetESignal* NetESignal::dup_expr() const
const NetNet* NetESignal::sig() const
{
assert(0);
return net_;
}
NetESubSignal::NetESubSignal(NetESignal*sig, NetExpr*ex)
unsigned NetESignal::lsi() const
{
return lsi_;
}
unsigned NetESignal::msi() const
{
return msi_;
}
NetEBitSel::NetEBitSel(NetESignal*sig, NetExpr*ex)
: sig_(sig), idx_(ex)
{
// This supports mux type indexing of an expression, so the
@@ -2194,17 +2275,22 @@ NetESubSignal::NetESubSignal(NetESignal*sig, NetExpr*ex)
expr_width(1);
}
NetESubSignal::~NetESubSignal()
NetEBitSel::~NetEBitSel()
{
delete idx_;
}
string NetESubSignal::name() const
string NetEBitSel::name() const
{
return sig_->name();
}
NetESubSignal* NetESubSignal::dup_expr() const
const NetNet* NetEBitSel::sig() const
{
return sig_->sig();
}
NetEBitSel* NetEBitSel::dup_expr() const
{
assert(0);
}
@@ -2237,14 +2323,14 @@ const NetExpr* NetETernary::false_expr() const
return false_val_;
}
NetETernary* NetETernary::dup_expr() const
{
assert(0);
}
NetEUnary::NetEUnary(char op, NetExpr*ex)
: NetExpr(ex->expr_width()), op_(op), expr_(ex)
{
switch (op_) {
case '!':
expr_width(1);
break;
}
}
NetEUnary::~NetEUnary()
@@ -2252,11 +2338,6 @@ NetEUnary::~NetEUnary()
delete expr_;
}
NetEUnary* NetEUnary::dup_expr() const
{
assert(0);
}
NetEUBits::NetEUBits(char op, NetExpr*ex)
: NetEUnary(op, ex)
{
@@ -2324,155 +2405,94 @@ const NetProc*NetTaskDef::proc() const
return proc_;
}
/*
* This method takes the input string, which contains exactly one
* edge, and connects it to the correct output state. The output state
* will be generated if needed, and the value compared.
*/
bool NetUDP::set_sequ_(const string&input, char output)
{
if (output == '-')
output = input[0];
string frm = input;
string to = input;
to[0] = output;
unsigned edge = frm.find_first_not_of("01x");
assert(frm.find_last_not_of("01x") == edge);
switch (input[edge]) {
case 'r':
frm[edge] = '0';
to[edge] = '1';
break;
case 'R':
frm[edge] = 'x';
to[edge] = '1';
break;
case 'f':
frm[edge] = '1';
to[edge] = '0';
break;
case 'F':
frm[edge] = 'x';
to[edge] = '0';
break;
case 'P':
frm[edge] = '0';
to[edge] = 'x';
break;
case 'N':
frm[edge] = '1';
to[edge] = 'x';
break;
default:
assert(0);
}
state_t_*sfrm = find_state_(frm);
state_t_*sto = find_state_(to);
switch (to[edge]) {
case '0':
// Notice that I might have caught this edge already
if (sfrm->pins[edge].zer != sto) {
assert(sfrm->pins[edge].zer == 0);
sfrm->pins[edge].zer = sto;
}
break;
case '1':
// Notice that I might have caught this edge already
if (sfrm->pins[edge].one != sto) {
assert(sfrm->pins[edge].one == 0);
sfrm->pins[edge].one = sto;
}
break;
case 'x':
// Notice that I might have caught this edge already
if (sfrm->pins[edge].xxx != sto) {
assert(sfrm->pins[edge].xxx == 0);
sfrm->pins[edge].xxx = sto;
}
break;
}
return true;
}
bool NetUDP::sequ_glob_(string input, char output)
{
for (unsigned idx = 0 ; idx < input.length() ; idx += 1)
switch (input[idx]) {
case '0':
case '1':
case 'x':
case 'r':
case 'R':
case 'f':
case 'F':
case 'P':
case 'N':
break;
case '?': // Iterate over all the levels
input[idx] = '0';
sequ_glob_(input, output);
input[idx] = '1';
sequ_glob_(input, output);
input[idx] = 'x';
sequ_glob_(input, output);
return true;
case 'n': // Iterate over (n) edges
input[idx] = 'f';
sequ_glob_(input, output);
input[idx] = 'F';
sequ_glob_(input, output);
input[idx] = 'N';
sequ_glob_(input, output);
return true;
case 'p': // Iterate over (p) edges
input[idx] = 'r';
sequ_glob_(input, output);
input[idx] = 'R';
sequ_glob_(input, output);
input[idx] = 'P';
sequ_glob_(input, output);
return true;
case '_': // Iterate over (?0) edges
input[idx] = 'f';
sequ_glob_(input, output);
input[idx] = 'F';
sequ_glob_(input, output);
return true;
case '*': // Iterate over all the edges
input[idx] = 'r';
sequ_glob_(input, output);
input[idx] = 'R';
sequ_glob_(input, output);
input[idx] = 'f';
sequ_glob_(input, output);
input[idx] = 'F';
sequ_glob_(input, output);
input[idx] = 'P';
sequ_glob_(input, output);
input[idx] = 'N';
sequ_glob_(input, output);
return true;
default:
assert(0);
}
return set_sequ_(input, output);
}
/*
* $Log: netlist.cc,v $
* Revision 1.178 2001/12/03 04:47:15 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
*
* Revision 1.177 2001/11/19 04:26:46 steve
* Unary reduction operators are all 1-bit results.
*
* Revision 1.176 2001/11/19 01:54:14 steve
* Port close cropping behavior from mcrgb
* Move window array reset to libmc.
*
* Revision 1.175 2001/11/06 04:32:37 steve
* shift expressions can have definite widths.
*
* Revision 1.174 2001/10/28 01:14:53 steve
* NetObj constructor finally requires a scope.
*
* Revision 1.173 2001/10/16 02:19:27 steve
* Support IVL_LPM_DIVIDE for structural divide.
*
* Revision 1.172 2001/10/07 03:38:08 steve
* parameter names do not have defined size.
*
* Revision 1.171 2001/09/29 01:53:22 steve
* Fix the size of unsized constant operants to compare (PR#274)
*
* Revision 1.170 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.169 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.168 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.167 2001/07/22 00:17:49 steve
* Support the NetESubSignal expressions in vvp.tgt.
*
* Revision 1.166 2001/07/07 03:01:37 steve
* Detect and make available to t-dll the right shift.
*
* Revision 1.165 2001/07/04 22:59:25 steve
* handle left shifter in dll output.
*
* Revision 1.164 2001/07/01 00:27:34 steve
* Make NetFF constructor take const char* for the name.
*
* Revision 1.163 2001/06/16 23:45:05 steve
* Add support for structural multiply in t-dll.
* Add code generators and vvp support for both
* structural and behavioral multiply.
*
* Revision 1.162 2001/06/15 04:14:18 steve
* Generate vvp code for GT and GE comparisons.
*
* Revision 1.161 2001/06/07 02:12:43 steve
* Support structural addition.
*
* Revision 1.160 2001/04/22 23:09:46 steve
* More UDP consolidation from Stephan Boettcher.
*
* Revision 1.159 2001/04/06 02:28:02 steve
* Generate vvp code for functions with ports.
*
* Revision 1.158 2001/04/02 02:28:12 steve
* Generate code for task calls.
*
* Revision 1.157 2001/02/10 21:20:38 steve
* Binary operators with operands of indefinite width
* has itself an indefinite width.
*
* Revision 1.156 2001/02/08 01:10:30 steve
* Remove dead code.
*
* Revision 1.155 2001/02/07 21:47:13 steve
* Fix expression widths for rvalues and parameters (PR#131,132)
*
* Revision 1.154 2001/01/18 03:16:35 steve
* NetMux needs a scope. (PR#115)
*
+273 -148
View File
@@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: netlist.h,v 1.195 2001/01/18 03:16:35 steve Exp $"
#ident "$Id: netlist.h,v 1.227 2001/12/03 04:47:15 steve Exp $"
#endif
/*
@@ -30,7 +30,9 @@
*/
# include <string>
# include <map>
# include <list>
# include "verinum.h"
# include "HName.h"
# include "LineInfo.h"
# include "svector.h"
# include "Attrib.h"
@@ -79,8 +81,8 @@ class NetObj {
public:
public:
explicit NetObj(const string&n, unsigned npins);
explicit NetObj(NetScope*s, const string&n, unsigned npins);
explicit NetObj(NetScope*s, const char*n, unsigned npins);
virtual ~NetObj();
NetScope* scope();
@@ -281,7 +283,7 @@ class NetNode : public NetObj {
public:
explicit NetNode(NetScope*s, const string&n, unsigned npins);
explicit NetNode(const string&n, unsigned npins);
explicit NetNode(NetScope*s, const char*n, unsigned npins);
virtual ~NetNode();
@@ -394,7 +396,7 @@ class NetNet : public NetObj, public LineInfo {
class NetAddSub : public NetNode {
public:
NetAddSub(const string&n, unsigned width);
NetAddSub(NetScope*s, const string&n, unsigned width);
~NetAddSub();
// Get the width of the device (that is, the width of the
@@ -428,7 +430,8 @@ class NetAddSub : public NetNode {
class NetCLShift : public NetNode {
public:
NetCLShift(const string&n, unsigned width, unsigned width_dist);
NetCLShift(NetScope*s, const string&n, unsigned width,
unsigned width_dist);
~NetCLShift();
unsigned width() const;
@@ -459,6 +462,10 @@ class NetCLShift : public NetNode {
/*
* This class supports the LPM_COMPARE device.
*
* The width of the device is the width of the inputs. If one of the
* inputs is narrower then the other, it is up to the generator to
* make sure all the data pins are properly driven.
*
* NOTE: This is not the same as the device used to support case
* compare. Case comparisons handle Vx and Vz values, whereas this
* device need not.
@@ -466,7 +473,7 @@ class NetCLShift : public NetNode {
class NetCompare : public NetNode {
public:
NetCompare(const string&n, unsigned width);
NetCompare(NetScope*scope, const string&n, unsigned width);
~NetCompare();
unsigned width() const;
@@ -516,7 +523,8 @@ class NetCompare : public NetNode {
class NetDivide : public NetNode {
public:
NetDivide(const string&n, unsigned width, unsigned wa, unsigned wb);
NetDivide(NetScope*scope, const string&n,
unsigned width, unsigned wa, unsigned wb);
~NetDivide();
unsigned width_r() const;
@@ -554,7 +562,8 @@ class NetDivide : public NetNode {
class NetModulo : public NetNode {
public:
NetModulo(const string&n, unsigned width, unsigned wa, unsigned wb);
NetModulo(NetScope*s, const string&n,
unsigned width, unsigned wa, unsigned wb);
~NetModulo();
unsigned width_r() const;
@@ -586,7 +595,7 @@ class NetModulo : public NetNode {
class NetFF : public NetNode {
public:
NetFF(NetScope*s, const string&n, unsigned width);
NetFF(NetScope*s, const char*n, unsigned width);
~NetFF();
unsigned width() const;
@@ -632,8 +641,8 @@ class NetMemory {
// This is the width (in bits) of a single memory position.
unsigned width() const { return width_; }
NetScope*scope();
const NetScope*scope() const;
// NetScope*scope();
const NetScope*scope() const { return scope_; };
// This is the number of memory positions.
unsigned count() const;
@@ -674,8 +683,8 @@ class NetMemory {
class NetMult : public NetNode {
public:
NetMult(const string&n, unsigned width, unsigned wa, unsigned wb,
unsigned width_s =0);
NetMult(NetScope*sc, const string&n, unsigned width,
unsigned wa, unsigned wb, unsigned width_s =0);
~NetMult();
// Get the width of the device bussed inputs. There are these
@@ -767,7 +776,7 @@ class NetMux : public NetNode {
class NetRamDq : public NetNode {
public:
NetRamDq(const string&name, NetMemory*mem, unsigned awid);
NetRamDq(NetScope*s, const string&name, NetMemory*mem, unsigned awid);
~NetRamDq();
unsigned width() const;
@@ -843,9 +852,14 @@ class NetExpr : public LineInfo {
// This returns true if the expression has a definite
// width. This is generally true, but in some cases the
// expression is amorphous and desires a width from its
// environment.
// environment. For example, 'd5 has indefinite width, but
// 5'd5 has a definite width.
// This method is only really used within concatenation
// expressions to check validity.
virtual bool has_width() const;
// This method evaluates the expression and returns an
// equivilent expression that is reduced as far as compile
// time knows how. Essentially, this is designed to fold
@@ -945,7 +959,7 @@ class NetBUFZ : public NetNode {
class NetCaseCmp : public NetNode {
public:
explicit NetCaseCmp(const string&n);
explicit NetCaseCmp(NetScope*s, const string&n);
~NetCaseCmp();
virtual void dump_node(ostream&, unsigned ind) const;
@@ -963,8 +977,8 @@ class NetCaseCmp : public NetNode {
class NetConst : public NetNode {
public:
explicit NetConst(const string&n, verinum::V v);
explicit NetConst(const string&n, const verinum&val);
explicit NetConst(NetScope*s, const string&n, verinum::V v);
explicit NetConst(NetScope*s, const string&n, const verinum&val);
~NetConst();
verinum::V value(unsigned idx) const;
@@ -986,12 +1000,17 @@ class NetConst : public NetNode {
* 0 -- output
* 1 -- input data
* 2 -- enable
*
* The pullup and pulldown gates have no inputs at all, and pin0 is
* the output 1 or 0, depending on the gate type. It is the strength
* of that value that is important.
*/
class NetLogic : public NetNode {
public:
enum TYPE { AND, BUF, BUFIF0, BUFIF1, NAND, NMOS, NOR, NOT, NOTIF0,
NOTIF1, OR, RNMOS, RPMOS, PMOS, XNOR, XOR };
enum TYPE { AND, BUF, BUFIF0, BUFIF1, NAND, NMOS, NOR, NOT,
NOTIF0, NOTIF1, OR, PULLDOWN, PULLUP, RNMOS, RPMOS,
PMOS, XNOR, XOR };
explicit NetLogic(NetScope*s, const string&n, unsigned pins, TYPE t);
@@ -1016,12 +1035,6 @@ class NetLogic : public NetNode {
* In any case, pin 0 is an output, and all the remaining pins are
* inputs.
*
* The sequential truth table is canonically represented as a finite state
* machine with the current state representing the inputs and the
* current output, and the next state carrying the new output value to
* use. All the outgoing transitions from a state represent a single
* edge.
*
* Set_table takes as input a string with one letter per pin. The
* parser translates the written sequences to one of these. The
* valid characters are:
@@ -1037,8 +1050,8 @@ class NetLogic : public NetNode {
* It also takes one of the following glob letters to represent more
* then one item.
*
* p -- 01, 0x or x1
* n -- 10, 1x or x0
* p -- 01, 0x or x1 // check this with the lexer
* n -- 10, 1x or x0 // check this with the lexer
* ? -- 0, 1, or x
* * -- any edge
* + -- 01 or x1
@@ -1059,99 +1072,35 @@ class NetLogic : public NetNode {
* 1 are listed.
*
*/
class NetUDP_COMB : public NetNode {
#include "PUdp.h"
class NetUDP : public NetNode {
public:
explicit NetUDP_COMB(const string&n, unsigned pins, bool sequ = false);
explicit NetUDP(NetScope*s, const string&n, unsigned pins, PUdp*u);
virtual bool emit_node(struct target_t*) const;
virtual void dump_node(ostream&, unsigned ind) const;
/* append a new truth table row. */
bool set_table(const string&input, char output);
/* After the primitive is built up, this method is called to
clean up redundancies, and possibly optimize the table. */
void cleanup_table();
/* Use these methods to scan the truth table of the
device. "first" returns the first item in the table, and
"next" returns the next item in the table. The method will
return false when the scan is done. */
bool first(string&inp, char&out) const;
bool next(string&inp, char&out) const;
unsigned rows() const { return udp->tinput.count(); }
bool is_sequential() const { return sequential_; }
protected:
// A combinational primitive is more simply represented as a
// simple map of input signals to a single output.
typedef map<string,char> CM_;
CM_ cm_;
unsigned nin() const { return pin_count()-1; }
bool is_sequential() const { return udp->sequential; }
string udp_name() const { return udp->name_; }
char get_initial() const;
private:
bool sequential_;
mutable CM_::const_iterator idx_;
mutable unsigned table_idx;
PUdp *udp;
};
class NetUDP : public NetUDP_COMB {
public:
explicit NetUDP(const string&n, unsigned pins, bool sequ = true)
: NetUDP_COMB(n, pins, sequ), init_('x') {};
virtual bool emit_node( struct target_t*) const;
virtual void dump_node(ostream&, unsigned ind) const;
/* return false if the entry conflicts with an existing
entry. In any case, the new output overrides. */
bool set_table(const string&input, char output);
void cleanup_table();
/* Return the next output from the passed state. Each letter
of the input string represents the pin of the same
position. */
char table_lookup(const string&from, char to, unsigned pin) const;
void set_initial(char);
char get_initial() const { return init_; }
private:
char init_;
struct state_t_;
struct pin_t_ {
state_t_*zer;
state_t_*one;
state_t_*xxx;
explicit pin_t_() : zer(0), one(0), xxx(0) { }
};
struct state_t_ {
char out;
pin_t_*pins;
state_t_(unsigned n) : out(0), pins(new pin_t_[n]) {}
~state_t_() { delete[]pins; }
};
typedef map<string,state_t_*> FSM_;
FSM_ fsm_;
bool set_sequ_(const string&in, char out);
bool sequ_glob_(string, char out);
state_t_*find_state_(const string&);
void dump_sequ_(ostream&o, unsigned ind) const;
void dump_comb_(ostream&o, unsigned ind) const;
};
/* =========
* A process is a behavioral-model description. A process is a
* statement that may be compound. the various statement types may
@@ -1215,10 +1164,10 @@ class NetProc : public LineInfo {
* should know that this is not a guarantee.
*/
class NetAssign_ : public NetNode {
class NetAssign_ {
public:
NetAssign_(const string&n, unsigned w);
NetAssign_(NetNet*sig);
~NetAssign_();
// If this expression exists, then only a single bit is to be
@@ -1226,21 +1175,32 @@ class NetAssign_ : public NetNode {
// the pin that gets the value.
const NetExpr*bmux() const;
unsigned get_loff() const;
void set_bmux(NetExpr*);
void set_part(unsigned loff, unsigned wid);
// Get the width of the r-value that this node expects. This
// method accounts for the presence of the mux, so it not
// nexessarily the same as the pin_count().
// necessarily the same as the pin_count().
unsigned lwidth() const;
virtual bool emit_node(struct target_t*) const;
virtual void dump_node(ostream&, unsigned ind) const;
// Get the name of the underlying object.
const char*name() const;
NetNet* sig() const;
// This pointer is for keeping simple lists.
NetAssign_* more;
void dump_lval(ostream&o) const;
private:
NetNet *sig_;
NetExpr*bmux_;
unsigned loff_;
unsigned lwid_;
};
class NetAssignBase : public NetProc {
@@ -1264,6 +1224,7 @@ class NetAssignBase : public NetProc {
// accounts for any grouping of NetAssign_ objects that might happen.
unsigned lwidth() const;
// This dumps all the lval structures.
void dump_lval(ostream&) const;
private:
@@ -1289,12 +1250,23 @@ class NetAssignNB : public NetAssignBase {
explicit NetAssignNB(NetAssign_*lv, NetExpr*rv);
~NetAssignNB();
void rise_time(unsigned);
void fall_time(unsigned);
void decay_time(unsigned);
unsigned rise_time() const;
unsigned fall_time() const;
unsigned decay_time() const;
virtual bool emit_proc(struct target_t*) const;
virtual int match_proc(struct proc_match_t*);
virtual void dump(ostream&, unsigned ind) const;
private:
unsigned rise_time_;
unsigned fall_time_;
unsigned decay_time_;
};
/*
@@ -1444,7 +1416,7 @@ class NetCase : public NetProc {
class NetCAssign : public NetProc, public NetNode {
public:
explicit NetCAssign(const string&n, NetNet*l);
explicit NetCAssign(NetScope*s, const string&n, NetNet*l);
~NetCAssign();
const Link& lval_pin(unsigned) const;
@@ -1454,6 +1426,8 @@ class NetCAssign : public NetProc, public NetNode {
virtual void dump_node(ostream&, unsigned ind) const;
virtual bool emit_node(struct target_t*) const;
const NetNet*lval() const;
private:
NetNet*lval_;
@@ -1554,7 +1528,10 @@ class NetDisable : public NetProc {
*
* Once an object of this type exists, behavioral code can wait on the
* event or trigger the event. Event waits refer to this object, as do
* the event trigger statements.
* the event trigger statements. The NetEvent class may have a name and
* a scope. The name is a simple name (no hierarchy) and the scope is
* the NetScope that contains the object. The socpe member is written
* by the NetScope object when the NetEvent is stored.
*
* The NetEvWait class represents a thread wait for an event. When
* this statement is executed, it starts waiting on the
@@ -1591,6 +1568,7 @@ class NetEvent : public LineInfo {
// Get information about probes connected to me.
unsigned nprobe() const;
NetEvProbe* probe(unsigned);
const NetEvProbe* probe(unsigned) const;
// Return the number of NetEvWait nodes that reference me.
unsigned nwait() const;
@@ -1688,8 +1666,8 @@ class NetEvProbe : public NetNode {
public:
enum edge_t { ANYEDGE, POSEDGE, NEGEDGE };
explicit NetEvProbe(const string&n, NetEvent*tgt,
edge_t t, unsigned p);
explicit NetEvProbe(NetScope*s, const string&n,
NetEvent*tgt, edge_t t, unsigned p);
~NetEvProbe();
edge_t edge() const;
@@ -1719,11 +1697,13 @@ class NetEvProbe : public NetNode {
class NetForce : public NetProc, public NetNode {
public:
explicit NetForce(const string&n, NetNet*l);
explicit NetForce(NetScope*s, const string&n, NetNet*l);
~NetForce();
const Link& lval_pin(unsigned) const;
const NetNet*lval() const;
virtual void dump(ostream&, unsigned ind) const;
virtual bool emit_proc(struct target_t*) const;
virtual void dump_node(ostream&, unsigned ind) const;
@@ -1934,7 +1914,7 @@ class NetTaskDef {
class NetEUFunc : public NetExpr {
public:
NetEUFunc(NetFuncDef*, NetESignal*, svector<NetExpr*>&);
NetEUFunc(NetScope*, NetESignal*, svector<NetExpr*>&);
~NetEUFunc();
const string name() const;
@@ -1943,7 +1923,7 @@ class NetEUFunc : public NetExpr {
unsigned parm_count() const;
const NetExpr* parm(unsigned idx) const;
const NetFuncDef* definition() const;
const NetScope* func() const;
virtual bool set_width(unsigned);
virtual void dump(ostream&) const;
@@ -1952,7 +1932,7 @@ class NetEUFunc : public NetExpr {
virtual NetEUFunc*dup_expr() const;
private:
NetFuncDef*func_;
NetScope*func_;
NetESignal*result_;
svector<NetExpr*> parms_;
@@ -1969,16 +1949,18 @@ class NetEUFunc : public NetExpr {
class NetUTask : public NetProc {
public:
NetUTask(NetTaskDef*);
NetUTask(NetScope*);
~NetUTask();
const string& name() const { return task_->name(); }
const string name() const;
const NetScope* task() const;
virtual bool emit_proc(struct target_t*) const;
virtual void dump(ostream&, unsigned ind) const;
private:
NetTaskDef*task_;
NetScope*task_;
};
/*
@@ -2078,6 +2060,11 @@ class NetEBinary : public NetExpr {
virtual bool set_width(unsigned w);
// A binary expression node only has a definite
// self-determinable width if the operands both have definite
// widths.
virtual bool has_width() const;
virtual NetEBinary* dup_expr() const;
virtual void expr_scan(struct expr_scan_t*) const;
@@ -2182,7 +2169,10 @@ class NetEBComp : public NetEBinary {
private:
NetEConst*eval_eqeq_();
NetEConst*eval_less_();
NetEConst*eval_leeq_();
NetEConst*eval_gt_();
NetEConst*eval_gteq_();
NetEConst*eval_neeq_();
NetEConst*eval_eqeqeq_();
NetEConst*eval_neeqeq_();
@@ -2241,6 +2231,11 @@ class NetEBShift : public NetEBinary {
~NetEBShift();
virtual bool set_width(unsigned w);
// A shift expression only needs the left expression to have a
// definite width to give the expression a definite width.
virtual bool has_width() const;
virtual NetEBShift* dup_expr() const;
virtual NetEConst* eval_tree();
@@ -2294,10 +2289,11 @@ class NetEConcat : public NetExpr {
class NetEParam : public NetExpr {
public:
NetEParam();
NetEParam(class Design*des, NetScope*scope, const string&name);
NetEParam(class Design*des, NetScope*scope, const hname_t&name);
~NetEParam();
virtual bool set_width(unsigned w);
virtual bool has_width() const;
virtual void expr_scan(struct expr_scan_t*) const;
virtual NetExpr* eval_tree();
virtual NetEParam* dup_expr() const;
@@ -2307,7 +2303,7 @@ class NetEParam : public NetExpr {
private:
Design*des_;
NetScope*scope_;
string name_;
hname_t name_;
};
@@ -2453,6 +2449,7 @@ class NetEUReduce : public NetEUnary {
NetEUReduce(char op, NetExpr*ex);
~NetEUReduce();
virtual bool set_width(unsigned w);
virtual NetNet* synthesize(Design*);
virtual NetEConst* eval_tree();
@@ -2479,6 +2476,8 @@ class NetEMemory : public NetExpr {
virtual void expr_scan(struct expr_scan_t*) const;
virtual void dump(ostream&) const;
const NetMemory*memory() const { return mem_; };
private:
NetMemory*mem_;
NetExpr* idx_;
@@ -2490,12 +2489,16 @@ class NetEMemory : public NetExpr {
* structural signal.
*
* A signal shows up as a node in the netlist so that structural
* activity can invoke the expression.
* activity can invoke the expression. This node also supports part
* select by indexing a range of the NetNet that is associated with
* it. The msi() is the mose significant index, and lsi() the least
* significant index.
*/
class NetESignal : public NetExpr {
public:
NetESignal(NetNet*n);
NetESignal(NetNet*n, unsigned msi, unsigned lsi);
~NetESignal();
// a NetESignal expression is signed if the NetNet that it
@@ -2510,36 +2513,44 @@ class NetESignal : public NetExpr {
// These methods actually reference the properties of the
// NetNet object that I point to.
unsigned pin_count() const;
Link& pin(unsigned idx);
unsigned bit_count() const;
Link& bit(unsigned idx);
const NetNet* sig() const;
unsigned msi() const;
unsigned lsi() const;
virtual void expr_scan(struct expr_scan_t*) const;
virtual void dump(ostream&) const;
private:
NetNet*net_;
unsigned msi_;
unsigned lsi_;
};
/*
* An expression that takes a portion of a signal is represented as
* An expression that takes a bit of a signal is represented as
* one of these. For example, ``foo[x+5]'' is a signal and x+5 is an
* expression to select a single bit from that signal. I can't just
* make a new NetESignal node connected to the single net because the
* expression may vary during execution, so the structure is not known
* at compile (elaboration) time.
*/
class NetESubSignal : public NetExpr {
class NetEBitSel : public NetExpr {
public:
NetESubSignal(NetESignal*sig, NetExpr*ex);
~NetESubSignal();
NetEBitSel(NetESignal*sig, NetExpr*ex);
~NetEBitSel();
string name() const;
const NetExpr*index() const { return idx_; }
virtual bool set_width(unsigned);
NetESubSignal* dup_expr() const;
const NetNet* sig() const;
NetEBitSel* dup_expr() const;
virtual void expr_scan(struct expr_scan_t*) const;
virtual void dump(ostream&) const;
@@ -2560,7 +2571,7 @@ class NetScope {
public:
enum TYPE { MODULE, TASK, FUNC, BEGIN_END, FORK_JOIN };
NetScope(NetScope*up, const string&name, TYPE t);
NetScope(NetScope*up, const char*name, TYPE t);
~NetScope();
/* Parameters exist within a scope, and these methods allow
@@ -2578,7 +2589,7 @@ class NetScope {
void add_event(NetEvent*);
void rem_event(NetEvent*);
NetEvent*find_event(const string&name);
NetEvent*find_event(const hname_t&name);
/* These methods manage signals. The add_ and rem_signal
@@ -2590,6 +2601,7 @@ class NetScope {
void rem_signal(NetNet*);
NetNet* find_signal(const string&name);
NetNet* find_signal_in_child(const hname_t&name);
/* ... and these methods manage memory the same way as signals
@@ -2647,6 +2659,9 @@ class NetScope {
/* This method generates a non-hierarchical name that is
guaranteed to be unique within this scope. */
string local_symbol();
/* This method generates a hierarchical name that is
guaranteed to be unique globally. */
string local_hsymbol();
void dump(ostream&) const;
void emit_scope(struct target_t*tgt) const;
@@ -2661,7 +2676,7 @@ class NetScope {
assignments from the scope pass to the parameter evaluation
step. After that, it is not used. */
map<string,NetExpr*>defparams;
map<hname_t,NetExpr*>defparams;
private:
TYPE type_;
@@ -2711,11 +2726,11 @@ class Design {
string get_flag(const string&key) const;
NetScope* make_root_scope(const string&name);
NetScope* make_root_scope(const char*name);
NetScope* find_root_scope();
list<NetScope*> find_root_scopes();
const NetScope* find_root_scope() const;
const list<NetScope*> find_root_scopes() const;
/* Attempt to set the precision to the specified value. If the
precision is already more precise, the keep the precise
@@ -2730,18 +2745,18 @@ class Design {
unsigned long scale_to_precision(unsigned long, const NetScope*)const;
/* look up a scope. If no starting scope is passed, then the
path name string is taken as an absolute scope
name. Otherwise, the scope is located starting at the
passed scope and working up if needed. */
NetScope* find_scope(const string&path) const;
NetScope* find_scope(NetScope*, const string&path) const;
path is taken as an absolute scope name. Otherwise, the
scope is located starting at the passed scope and working
up if needed. */
NetScope* find_scope(const hname_t&path) const;
NetScope* find_scope(NetScope*, const hname_t&path) const;
// PARAMETERS
/* This method searches for a parameter, starting in the given
scope. This method handles the upward searches that the
NetScope class itself does not support. */
const NetExpr*find_parameter(const NetScope*, const string&name) const;
const NetExpr*find_parameter(const NetScope*, const hname_t&path) const;
void run_defparams();
void evaluate_parameters();
@@ -2751,10 +2766,10 @@ class Design {
this method, unlike the NetScope::find_signal method,
handles global name binding. */
NetNet*find_signal(NetScope*scope, const string&name);
NetNet*find_signal(NetScope*scope, hname_t path);
// Memories
NetMemory* find_memory(NetScope*scope, const string&name);
NetMemory* find_memory(NetScope*scope, hname_t path);
/* This is a more general lookup that finds the named signal
or memory, whichever is first in the search path. */
@@ -2762,12 +2777,12 @@ class Design {
NetNet*&sig, NetMemory*&mem);
// Functions
NetFuncDef* find_function(NetScope*scope, const string&key);
NetFuncDef* find_function(const string&path);
NetFuncDef* find_function(NetScope*scope, const hname_t&key);
NetFuncDef* find_function(const hname_t&path);
// Tasks
NetTaskDef* find_task(NetScope*scope, const string&name);
NetTaskDef* find_task(const string&key);
NetScope* find_task(NetScope*scope, const hname_t&name);
NetScope* find_task(const hname_t&key);
// NODES
void add_node(NetNode*);
@@ -2792,7 +2807,7 @@ class Design {
private:
// Keep a tree of scopes. The NetScope class handles the wide
// tree and per-hop searches for me.
NetScope*root_scope_;
list<NetScope*>root_scopes_;
// List the nodes in the design
NetNode*nodes_;
@@ -2852,6 +2867,116 @@ extern ostream& operator << (ostream&, NetNet::Type);
/*
* $Log: netlist.h,v $
* Revision 1.227 2001/12/03 04:47:15 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
*
* Revision 1.226 2001/11/29 01:58:18 steve
* Handle part selects in l-values of DFF devices.
*
* Revision 1.225 2001/11/19 04:26:46 steve
* Unary reduction operators are all 1-bit results.
*
* Revision 1.224 2001/11/14 03:28:49 steve
* DLL target support for force and release.
*
* Revision 1.223 2001/11/09 03:43:26 steve
* Spelling errors.
*
* Revision 1.222 2001/11/08 05:15:51 steve
* Remove string paths from PExpr elaboration.
*
* Revision 1.221 2001/11/06 04:32:37 steve
* shift expressions can have definite widths.
*
* Revision 1.220 2001/10/31 05:24:52 steve
* ivl_target support for assign/deassign.
*
* Revision 1.219 2001/10/28 01:14:53 steve
* NetObj constructor finally requires a scope.
*
* Revision 1.218 2001/10/20 05:21:51 steve
* Scope/module names are char* instead of string.
*
* Revision 1.217 2001/10/19 21:53:24 steve
* Support multiple root modules (Philip Blundell)
*
* Revision 1.216 2001/10/16 02:19:27 steve
* Support IVL_LPM_DIVIDE for structural divide.
*
* Revision 1.215 2001/10/07 03:38:08 steve
* parameter names do not have defined size.
*
* Revision 1.214 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.213 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.212 2001/07/22 00:17:49 steve
* Support the NetESubSignal expressions in vvp.tgt.
*
* Revision 1.211 2001/07/04 22:59:25 steve
* handle left shifter in dll output.
*
* Revision 1.210 2001/07/01 00:27:34 steve
* Make NetFF constructor take const char* for the name.
*
* Revision 1.209 2001/06/16 23:45:05 steve
* Add support for structural multiply in t-dll.
* Add code generators and vvp support for both
* structural and behavioral multiply.
*
* Revision 1.208 2001/06/15 04:14:18 steve
* Generate vvp code for GT and GE comparisons.
*
* Revision 1.207 2001/06/07 02:12:43 steve
* Support structural addition.
*
* Revision 1.206 2001/05/08 23:59:33 steve
* Add ivl and vvp.tgt support for memories in
* expressions and l-values. (Stephan Boettcher)
*
* Revision 1.205 2001/04/29 20:19:10 steve
* Add pullup and pulldown devices.
*
* Revision 1.204 2001/04/24 02:23:58 steve
* Support for UDP devices in VVP (Stephen Boettcher)
*
* Revision 1.203 2001/04/22 23:09:46 steve
* More UDP consolidation from Stephan Boettcher.
*
* Revision 1.202 2001/04/06 02:28:02 steve
* Generate vvp code for functions with ports.
*
* Revision 1.201 2001/04/02 02:28:12 steve
* Generate code for task calls.
*
* Revision 1.200 2001/03/29 02:52:01 steve
* Add const probe method to NetEvent.
*
* Revision 1.199 2001/02/15 06:59:36 steve
* FreeBSD port has a maintainer now.
*
* Revision 1.198 2001/02/10 21:20:38 steve
* Binary operators with operands of indefinite width
* has itself an indefinite width.
*
* Revision 1.197 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.196 2001/02/09 05:44:23 steve
* support evaluation of constant < in expressions.
*
* Revision 1.195 2001/01/18 03:16:35 steve
* NetMux needs a scope. (PR#115)
*
+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.
*
*/
+16 -29
View File
@@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: netmisc.h,v 1.10 2000/11/20 00:58:40 steve Exp $"
#ident "$Id: netmisc.h,v 1.12 2001/02/15 06:59:36 steve Exp $"
#endif
# include "netlist.h"
@@ -31,7 +31,7 @@
* enough.
*/
extern NetExpr*pad_to_width(NetExpr*expr, unsigned wid);
extern NetNet*pad_to_width(Design*des, const string&p, NetNet*n, unsigned w);
extern NetNet*pad_to_width(Design*des, NetNet*n, unsigned w);
/*
* This local function returns true if all the the possible drivers of
@@ -54,9 +54,23 @@ extern verinum::V driven_value(const Link&lnk);
*/
extern unsigned count_lval_width(const class NetAssign_*first);
/*
* This function elaborates an expression, and tries to evaluate it
* right away. It is useful for those places where the user is
* supposed to supply a constant expression.
*/
class PExpr;
extern NetExpr* elab_and_eval(Design*des, NetScope*scope, const PExpr*pe);
/*
* $Log: netmisc.h,v $
* Revision 1.12 2001/02/15 06:59:36 steve
* FreeBSD port has a maintainer now.
*
* 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 2000/11/20 00:58:40 steve
* Add support for supply nets (PR#17)
*
@@ -69,32 +83,5 @@ extern unsigned count_lval_width(const class NetAssign_*first);
*
* Revision 1.7 2000/05/14 17:55:04 steve
* Support initialization of FF Q value.
*
* Revision 1.6 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.5 2000/04/20 00:28:03 steve
* Catch some simple identity compareoptimizations.
*
* Revision 1.4 2000/03/16 19:03:03 steve
* 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.
*
* Revision 1.3 2000/02/23 02:56:55 steve
* Macintosh compilers do not support ident.
*
* Revision 1.2 2000/02/16 03:58:27 steve
* Fix up width matching in structural bitwise operators.
*
* Revision 1.1 1999/09/29 00:42:51 steve
* Allow expanding of additive operators.
*
*/
#endif
+23 -1
View File
@@ -17,9 +17,11 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: nodangle.cc,v 1.10 2000/11/19 20:48:53 steve Exp $"
#ident "$Id: nodangle.cc,v 1.13 2001/07/27 02:41:55 steve Exp $"
#endif
# include "config.h"
/*
* This functor scans the design looking for dangling objects and
* excess local signals. These deletions are not necessarily required
@@ -58,6 +60,16 @@ void nodangle_f::signal(Design*des, NetNet*sig)
if (sig->get_eref() > 0)
return;
/* Cannot delete the ports of tasks or functions. There are
too many places where they are referenced. */
if ((sig->port_type() != NetNet::NOT_A_PORT)
&& (sig->scope()->type() == NetScope::TASK))
return;
if ((sig->port_type() != NetNet::NOT_A_PORT)
&& (sig->scope()->type() == NetScope::FUNC))
return;
/* Check to see if the signal is completely unconnected. If
all the bits are unlinked, then delete it. */
unsigned unlinked = 0;
@@ -118,6 +130,16 @@ void nodangle(Design*des)
/*
* $Log: nodangle.cc,v $
* Revision 1.13 2001/07/27 02:41:55 steve
* Fix binding of dangling function ports. do not elide them.
*
* Revision 1.12 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.11 2001/02/17 05:14:35 steve
* Cannot elide task ports.
*
* Revision 1.10 2000/11/19 20:48:53 steve
* Killing some signals might make others killable.
*
+23 -5
View File
@@ -17,9 +17,11 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: pad_to_width.cc,v 1.5 2000/05/02 00:58:12 steve Exp $"
#ident "$Id: pad_to_width.cc,v 1.9 2001/10/28 01:14:53 steve Exp $"
#endif
# include "config.h"
# include "netlist.h"
# include "netmisc.h"
@@ -45,19 +47,22 @@ NetExpr*pad_to_width(NetExpr*expr, unsigned wid)
return expr;
}
NetNet*pad_to_width(Design*des, const string&path, NetNet*net, unsigned wid)
NetNet*pad_to_width(Design*des, NetNet*net, unsigned wid)
{
NetScope*scope = des->find_scope(path);
NetScope*scope = net->scope();
const string path = scope->name();
assert(scope);
if (net->pin_count() >= wid)
return net;
verinum pad(verinum::V0, wid - net->pin_count());
NetConst*con = new NetConst(des->local_symbol(path), pad);
NetConst*con = new NetConst(scope,
path + "." + scope->local_symbol(),
pad);
des->add_node(con);
NetNet*tmp = new NetNet(scope, des->local_symbol(path),
NetNet*tmp = new NetNet(scope, path + "." + scope->local_symbol(),
NetNet::WIRE, wid);
tmp->local_flag(true);
@@ -71,6 +76,19 @@ NetNet*pad_to_width(Design*des, const string&path, NetNet*net, unsigned wid)
/*
* $Log: pad_to_width.cc,v $
* Revision 1.9 2001/10/28 01:14:53 steve
* NetObj constructor finally requires a scope.
*
* Revision 1.8 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.7 2001/02/16 03:25:09 steve
* Missing . in names generated from scope locals.
*
* Revision 1.6 2001/02/15 06:59:36 steve
* FreeBSD port has a maintainer now.
*
* Revision 1.5 2000/05/02 00:58:12 steve
* Move signal tables to the NetScope class.
*
+291 -115
View File
@@ -19,9 +19,11 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: parse.y,v 1.118 2001/01/14 23:04:56 steve Exp $"
#ident "$Id: parse.y,v 1.140 2001/12/07 05:03:13 steve Exp $"
#endif
# include "config.h"
# include "parse_misc.h"
# include "pform.h"
@@ -43,6 +45,8 @@ static struct str_pair_t decl_strength = { PGate::STRONG, PGate::STRONG };
char*text;
list<char*>*texts;
hname_t*hier;
list<string>*strings;
struct str_pair_t drive;
@@ -76,15 +80,22 @@ static struct str_pair_t decl_strength = { PGate::STRONG, PGate::STRONG };
Statement*statement;
svector<Statement*>*statement_list;
struct { svector<PExpr*>*range; NetNet::Type ntype; } range_type;
struct { svector<PExpr*>*range; svector<PExpr*>*delay; } range_delay;
net_decl_assign_t*net_decl_assign;
verinum* number;
verireal* realtime;
};
%token <text> HIDENTIFIER IDENTIFIER PORTNAME SYSTEM_IDENTIFIER STRING
%token <text> IDENTIFIER SYSTEM_IDENTIFIER STRING
%token <text> PATHPULSE_IDENTIFIER
%token <number> NUMBER
%token <realtime> REALTIME
%token K_LE K_GE K_EG K_EQ K_NE K_CEQ K_CNE K_LS K_RS K_SG
%token K_PO_POS K_PO_NEG
%token K_LOR K_LAND K_NAND K_NOR K_NXOR K_TRIGGER
%token K_always K_and K_assign K_begin K_buf K_bufif0 K_bufif1 K_case
%token K_casex K_casez K_cmos K_deassign K_default K_defparam K_disable
@@ -104,6 +115,7 @@ static struct str_pair_t decl_strength = { PGate::STRONG, PGate::STRONG };
%token K_trior K_trireg K_vectored K_wait K_wand K_weak0 K_weak1
%token K_while K_wire
%token K_wor K_xnor K_xor
%token K_Shold K_Speriod K_Srecovery K_Ssetup K_Swidth K_Ssetuphold
%token KK_attribute
@@ -115,11 +127,11 @@ static struct str_pair_t decl_strength = { PGate::STRONG, PGate::STRONG };
%type <wires> udp_port_decl udp_port_decls
%type <statement> udp_initial udp_init_opt
%type <text> identifier register_variable
%type <hier> identifier
%type <text> register_variable
%type <texts> register_variable_list list_of_variables
%type <text> net_decl_assign
%type <texts> net_decl_assigns
%type <net_decl_assign> net_decl_assign net_decl_assigns
%type <mport> port port_opt port_reference port_reference_list
%type <mports> list_of_ports list_of_ports_opt
@@ -149,13 +161,16 @@ static struct str_pair_t decl_strength = { PGate::STRONG, PGate::STRONG };
%type <porttype> port_type
%type <parmvalue> parameter_value_opt
%type <exprs> range_or_type_opt
%type <range_type> range_or_type_opt
%type <event_expr> event_expression_list
%type <event_expr> event_expression
%type <event_statement> event_control
%type <statement> statement statement_opt
%type <statement_list> statement_list
%type <range_delay> range_delay
%token K_TAND
%right '?' ':'
%left K_LOR
%left K_LAND
@@ -319,7 +334,7 @@ defparam_assign
delete tmp;
tmp = 0;
}
pform_set_defparam($1, $3);
pform_set_defparam(*$1, $3);
delete $1;
}
;
@@ -412,7 +427,7 @@ delay_value_simple
}
}
| IDENTIFIER
{ PEIdent*tmp = new PEIdent($1);
{ PEIdent*tmp = new PEIdent(hname_t($1));
tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line);
$$ = tmp;
@@ -479,7 +494,7 @@ dr_strength1
event_control
: '@' IDENTIFIER
{ PEIdent*tmpi = new PEIdent($2);
{ PEIdent*tmpi = new PEIdent(hname_t($2));
tmpi->set_file(@2.text);
tmpi->set_lineno(@2.first_line);
delete[]$2;
@@ -806,21 +821,21 @@ expr_primary
delete $1;
}
| identifier
{ PEIdent*tmp = new PEIdent($1);
{ PEIdent*tmp = new PEIdent(*$1);
tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line);
$$ = tmp;
delete $1;
}
| SYSTEM_IDENTIFIER
{ PECallFunction*tmp = new PECallFunction($1);
{ PECallFunction*tmp = new PECallFunction(hname_t($1));
tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line);
$$ = tmp;
delete $1
}
| identifier '[' expression ']'
{ PEIdent*tmp = new PEIdent($1);
{ PEIdent*tmp = new PEIdent(*$1);
tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line);
tmp->msb_ = $3;
@@ -828,7 +843,7 @@ expr_primary
$$ = tmp;
}
| identifier '[' expression ':' expression ']'
{ PEIdent*tmp = new PEIdent($1);
{ PEIdent*tmp = new PEIdent(*$1);
tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line);
tmp->msb_ = $3;
@@ -837,13 +852,14 @@ expr_primary
$$ = tmp;
}
| identifier '(' expression_list ')'
{ PECallFunction*tmp = new PECallFunction($1, *$3);
{ PECallFunction*tmp = new PECallFunction(*$1, *$3);
tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line);
delete $1;
$$ = tmp;
}
| SYSTEM_IDENTIFIER '(' expression_list ')'
{ PECallFunction*tmp = new PECallFunction($1, *$3);
{ PECallFunction*tmp = new PECallFunction(hname_t($1), *$3);
tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line);
$$ = tmp;
@@ -1002,13 +1018,21 @@ gatetype
| K_rtranif1 { $$ = PGBuiltin::RTRANIF1; }
;
/* A general identifier is a hierarchical name, with the right most
name the base of the identifier. This rule builds up a
hierarchical name from left to right. */
identifier
: IDENTIFIER
{ $$ = $1; }
| HIDENTIFIER
{ $$ = $1;
{ $$ = new hname_t($1);
delete $1;
}
| identifier '.' IDENTIFIER
{ hname_t * tmp = $1;
tmp->append($3);
delete $3;
$$ = tmp;
}
;
list_of_ports
: port_opt
@@ -1048,14 +1072,14 @@ list_of_variables
expression meets the constraints of continuous assignments. */
lavalue
: identifier
{ PEIdent*tmp = new PEIdent($1);
{ PEIdent*tmp = new PEIdent(*$1);
tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line);
delete $1;
$$ = tmp;
}
| identifier '[' expression ']'
{ PEIdent*tmp = new PEIdent($1);
{ PEIdent*tmp = new PEIdent(*$1);
PExpr*sel = $3;
if (! pform_expression_is_constant(sel)) {
yyerror(@2, "error: Bit select in lvalue must "
@@ -1070,7 +1094,7 @@ lavalue
$$ = tmp;
}
| identifier range
{ PEIdent*tmp = new PEIdent($1);
{ PEIdent*tmp = new PEIdent(*$1);
assert($2->count() == 2);
tmp->msb_ = (*$2)[0];
tmp->lsb_ = (*$2)[1];
@@ -1093,14 +1117,14 @@ lavalue
procedural assignment. This rule handles only procedural assignments. */
lpvalue
: identifier
{ PEIdent*tmp = new PEIdent($1);
{ PEIdent*tmp = new PEIdent(*$1);
tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line);
delete $1;
$$ = tmp;
}
| identifier '[' expression ']'
{ PEIdent*tmp = new PEIdent($1);
{ PEIdent*tmp = new PEIdent(*$1);
tmp->msb_ = $3;
tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line);
@@ -1109,7 +1133,7 @@ lpvalue
$$ = tmp;
}
| identifier '[' expression ':' expression ']'
{ PEIdent*tmp = new PEIdent($1);
{ PEIdent*tmp = new PEIdent(*$1);
tmp->msb_ = $3;
tmp->lsb_ = $5;
tmp->set_file(@1.text);
@@ -1147,16 +1171,16 @@ assign_list
;
module
: K_module IDENTIFIER list_of_ports_opt ';'
{ pform_startmodule($2, $3);
: module_start IDENTIFIER list_of_ports_opt ';'
{ pform_startmodule($2, $3, @1.text, @1.first_line);
}
module_item_list
K_endmodule
{ pform_endmodule($2);
delete $2;
}
| K_module IDENTIFIER list_of_ports_opt ';'
{ pform_startmodule($2, $3);
| module_start IDENTIFIER list_of_ports_opt ';'
{ pform_startmodule($2, $3, @1.text, @1.first_line);
}
K_endmodule
{ pform_endmodule($2);
@@ -1164,15 +1188,26 @@ module
}
;
module_start : K_module | K_macromodule ;
range_delay : range_opt delay3_opt
{ $$.range = $1; $$.delay = $2; }
;
module_item
: net_type range_opt list_of_variables ';'
{ pform_makewire(@1, $2, $3, $1);
: net_type range_delay list_of_variables ';'
{ pform_makewire(@1, $2.range, $3, $1);
if ($2.delay != 0) {
yyerror(@2, "sorry: net delays not supported.");
delete $2.delay;
}
}
| net_type range_opt net_decl_assigns ';'
{ pform_makewire(@1, $2, $3, $1);
| net_type range_delay net_decl_assigns ';'
{ pform_makewire(@1, $2.range, $2.delay, $3, $1);
}
| net_type drive_strength { decl_strength = $2;} net_decl_assigns ';'
{ pform_makewire(@1, 0, $4, $1);
{ pform_makewire(@1, 0, 0, $4, $1);
/* The strengths are handled in the
net_decl_assigns using the decl_strength that I
set in the rule. Right here, just restore the
@@ -1180,18 +1215,20 @@ module_item
decl_strength.str0 = PGate::STRONG;
decl_strength.str1 = PGate::STRONG;
}
| K_trireg charge_strength_opt range_opt delay3_opt list_of_variables ';'
| K_trireg charge_strength_opt range_delay list_of_variables ';'
{ yyerror(@1, "sorry: trireg nets not supported.");
delete $3;
delete $3.range;
delete $3.delay;
}
| port_type range_opt list_of_variables ';'
{ pform_set_port_type($3, $2, $1);
| port_type range_delay list_of_variables ';'
{ pform_set_port_type(@1, $3, $2.range, $1);
}
| port_type range_opt error ';'
| port_type range_delay error ';'
{ yyerror(@3, "error: Invalid variable list"
" in port declaration.");
if ($2) delete $2;
if ($2.range) delete $2.range;
if ($2.delay) delete $2.delay;
yyerrok;
}
| block_item_decl
@@ -1229,6 +1266,14 @@ module_item
{ pform_makegates(PGBuiltin::PULLDOWN, decl_strength, 0, $2);
}
| K_pullup '(' dr_strength1 ')' gate_instance_list ';'
{ pform_makegates(PGBuiltin::PULLUP, $3, 0, $5);
}
| K_pulldown '(' dr_strength0 ')' gate_instance_list ';'
{ pform_makegates(PGBuiltin::PULLDOWN, $3, 0, $5);
}
/* This rule handles instantiations of modules and user defined
primitives. These devices to not have delay lists or strengths,
but then can have parameter lists. */
@@ -1288,24 +1333,33 @@ module_item
tmp->set_lineno(@1.first_line);
tmp->set_ports($6);
tmp->set_statement($7);
pform_set_function($3, $2, tmp);
pform_set_function($3, $2.ntype, $2.range, tmp);
pform_pop_scope();
delete $3;
}
/* specify blocks are parsed but ignored. */
| K_specify K_endspecify
{ /* empty lists are legal syntax. */ }
| K_specify specify_item_list K_endspecify
{
}
| K_specify error K_endspecify
{ yyerror(@1, "error: syntax error in specify block");
yyerrok;
}
/* These rules match various errors that the user can type into
module items. These rules try to catch them at a point where a
reasonable error message can be produced. */
| error
| error ';'
{ yyerror(@1, "error: invalid module item. "
"Did you forget an initial or always?");
yyerrok;
}
| K_assign error '=' expression ';'
@@ -1355,32 +1409,23 @@ module_item_list
net_decl_assign
: IDENTIFIER '=' expression
{ PEIdent*id = new PEIdent($1);
PGAssign*tmp = pform_make_pgassign(id, $3, 0, decl_strength);
tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line);
$$ = $1;
}
| delay1 IDENTIFIER '=' expression
{ PEIdent*id = new PEIdent($2);
PGAssign*tmp = pform_make_pgassign(id, $4, $1,
decl_strength);
tmp->set_file(@2.text);
tmp->set_lineno(@2.first_line);
$$ = $2;
{ net_decl_assign_t*tmp = new net_decl_assign_t;
tmp->next = tmp;
tmp->name = $1;
tmp->expr = $3;
$$ = tmp;
}
;
net_decl_assigns
: net_decl_assigns ',' net_decl_assign
{ list<char*>*tmp = $1;
tmp->push_back($3);
{ net_decl_assign_t*tmp = $1;
$3->next = tmp->next;
tmp->next = $3;
$$ = tmp;
}
| net_decl_assign
{ list<char*>*tmp = new list<char*>;
tmp->push_back($1);
$$ = tmp;
{ $$ = $1;
}
;
@@ -1502,18 +1547,18 @@ parameter_value_opt
;
parameter_value_byname
: PORTNAME '(' expression ')'
: '.' IDENTIFIER '(' expression ')'
{ portname_t*tmp = new portname_t;
tmp->name = $1;
tmp->parm = $3;
free($1);
tmp->name = $2;
tmp->parm = $4;
free($2);
$$ = tmp;
}
| PORTNAME '(' ')'
| '.' IDENTIFIER '(' ')'
{ portname_t*tmp = new portname_t;
tmp->name = $1;
tmp->name = $2;
tmp->parm = 0;
free($1);
free($2);
$$ = tmp;
}
;
@@ -1552,12 +1597,12 @@ port
/* This syntax attaches an external name to the port reference so
that the caller can bind by name to non-trivial port
references. The port_t object gets its PWire from the
port_reference, but its name from the PORTNAME. */
port_reference, but its name from the IDENTIFIER. */
| PORTNAME '(' port_reference ')'
{ Module::port_t*tmp = $3;
tmp->name = $1;
delete $1;
| '.' IDENTIFIER '(' port_reference ')'
{ Module::port_t*tmp = $4;
tmp->name = $2;
delete $2;
$$ = tmp;
}
@@ -1574,10 +1619,10 @@ port
/* This attaches a name to a port reference contatenation list so
that parameter passing be name is possible. */
| PORTNAME '(' '{' port_reference_list '}' ')'
{ Module::port_t*tmp = $4;
tmp->name = $1;
delete $1;
| '.' IDENTIFIER '(' '{' port_reference_list '}' ')'
{ Module::port_t*tmp = $5;
tmp->name = $2;
delete $2;
$$ = tmp;
}
;
@@ -1602,7 +1647,7 @@ port_reference
: IDENTIFIER
{ Module::port_t*ptmp = new Module::port_t;
PEIdent*tmp = new PEIdent($1);
PEIdent*tmp = new PEIdent(hname_t($1));
tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line);
ptmp->name = $1;
@@ -1613,7 +1658,7 @@ port_reference
}
| IDENTIFIER '[' expression ':' expression ']'
{ PEIdent*wtmp = new PEIdent($1);
{ PEIdent*wtmp = new PEIdent(hname_t($1));
wtmp->set_file(@1.text);
wtmp->set_lineno(@1.first_line);
if (!pform_expression_is_constant($3)) {
@@ -1635,7 +1680,7 @@ port_reference
}
| IDENTIFIER '[' expression ']'
{ PEIdent*tmp = new PEIdent($1);
{ PEIdent*tmp = new PEIdent(hname_t($1));
tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line);
if (!pform_expression_is_constant($3)) {
@@ -1654,7 +1699,7 @@ port_reference
| IDENTIFIER '[' error ']'
{ yyerror(@1, "error: invalid port bit select");
Module::port_t*ptmp = new Module::port_t;
PEIdent*wtmp = new PEIdent($1);
PEIdent*wtmp = new PEIdent(hname_t($1));
wtmp->set_file(@1.text);
wtmp->set_lineno(@1.first_line);
ptmp->name = $1;
@@ -1682,26 +1727,26 @@ port_reference_list
looking for the ports of a module declaration. */
port_name
: PORTNAME '(' expression ')'
: '.' IDENTIFIER '(' expression ')'
{ portname_t*tmp = new portname_t;
tmp->name = $1;
tmp->parm = $3;
delete $1;
tmp->name = $2;
tmp->parm = $4;
delete $2;
$$ = tmp;
}
| PORTNAME '(' error ')'
{ yyerror(@3, "error: invalid port connection expression.");
| '.' IDENTIFIER '(' error ')'
{ yyerror(@4, "error: invalid port connection expression.");
portname_t*tmp = new portname_t;
tmp->name = $1;
tmp->name = $2;
tmp->parm = 0;
delete $1;
delete $2;
$$ = tmp;
}
| PORTNAME '(' ')'
| '.' IDENTIFIER '(' ')'
{ portname_t*tmp = new portname_t;
tmp->name = $1;
tmp->name = $2;
tmp->parm = 0;
delete $1;
delete $2;
$$ = tmp;
}
;
@@ -1735,7 +1780,7 @@ range
(*tmp)[0] = $2;
if (!pform_expression_is_constant($4))
yyerror(@4, "error: msb of range must be constant.");
yyerror(@4, "error: lsb of range must be constant.");
(*tmp)[1] = $4;
@@ -1748,14 +1793,14 @@ range_opt
| { $$ = 0; }
;
/* This is used to express the retur type of a function. */
/* This is used to express the return type of a function. */
range_or_type_opt
: range { $$ = $1; }
| K_integer { $$ = 0; }
| K_real { $$ = 0; }
| K_realtime { $$ = 0; }
| K_time { $$ = 0; }
| { $$ = 0; }
: range { $$.range = $1; $$.ntype = NetNet::REG; }
| K_integer { $$.range = 0; $$.ntype = NetNet::IMPLICIT_REG; }
| K_real { $$.range = 0; $$.ntype = NetNet::IMPLICIT; }
| K_realtime { $$.range = 0; $$.ntype = NetNet::IMPLICIT; }
| K_time { $$.range = 0; $$.ntype = NetNet::IMPLICIT; }
| { $$.range = 0; $$.ntype = NetNet::IMPLICIT; }
;
/* The register_variable rule is matched only when I am parsing
@@ -1802,18 +1847,52 @@ register_variable_list
specify_item
: K_specparam specparam_list ';'
| specify_simple_path '=' '(' delay_value ')' ';'
| specify_simple_path_decl ';'
{
}
| specify_simple_path '=' '(' delay_value ',' delay_value ')' ';'
| specify_edge_path_decl ';'
{
}
| specify_simple_path '=' '(' delay_value ',' delay_value ',' delay_value ')' ';'
| K_if '(' expression ')' specify_simple_path_decl ';'
{
}
| specify_simple_path '=' delay_value_simple ';'
| K_if '(' expression ')' specify_edge_path_decl ';'
{
}
| K_Shold '(' spec_reference_event ',' spec_reference_event
',' expression spec_notifier_opt ')' ';'
{ delete $7;
}
| K_Speriod '(' spec_reference_event ',' expression
spec_notifier_opt ')' ';'
{ delete $5;
}
| K_Srecovery '(' spec_reference_event ',' spec_reference_event
',' expression spec_notifier_opt ')' ';'
{ delete $7;
}
| K_Ssetup '(' spec_reference_event ',' spec_reference_event
',' expression spec_notifier_opt ')' ';'
{ delete $7;
}
| K_Ssetuphold '(' spec_reference_event ',' spec_reference_event
',' expression ',' expression spec_notifier_opt ')' ';'
{ delete $7;
delete $9;
}
| K_Swidth '(' spec_reference_event ',' expression ',' expression
spec_notifier_opt ')' ';'
{ delete $5;
delete $7;
}
| K_Swidth '(' spec_reference_event ',' expression ')' ';'
{ delete $5;
}
;
specify_delay_value_list
: delay_value { }
| specify_delay_value_list ',' delay_value { }
;
specify_item_list
@@ -1821,9 +1900,50 @@ specify_item_list
| specify_item_list specify_item
;
specify_edge_path_decl
: specify_edge_path '=' '(' specify_delay_value_list ')'
;
specify_edge_path
: '(' K_posedge specify_path_identifiers spec_polarity K_EG IDENTIFIER ')'
| '(' K_posedge specify_path_identifiers spec_polarity K_EG '(' expr_primary polarity_operator expression ')' ')'
| '(' K_posedge specify_path_identifiers spec_polarity K_SG IDENTIFIER ')'
| '(' K_posedge specify_path_identifiers spec_polarity K_SG '(' expr_primary polarity_operator expression ')' ')'
| '(' K_negedge specify_path_identifiers spec_polarity K_EG IDENTIFIER ')'
| '(' K_negedge specify_path_identifiers spec_polarity K_EG '(' expr_primary polarity_operator expression ')' ')'
| '(' K_negedge specify_path_identifiers spec_polarity K_SG IDENTIFIER ')'
| '(' K_negedge specify_path_identifiers spec_polarity K_SG '(' expr_primary polarity_operator expression ')' ')'
;
polarity_operator
: K_PO_POS
| K_PO_NEG
| ':'
;
specify_simple_path_decl
: specify_simple_path '=' '(' specify_delay_value_list ')'
| specify_simple_path '=' delay_value_simple
| specify_simple_path '=' '(' error ')'
{ yyerror(@2, "Syntax error in delay value list.");
yyerrok;
}
;
specify_simple_path
: '(' IDENTIFIER spec_polarity K_EG IDENTIFIER ')'
| '(' IDENTIFIER spec_polarity K_SG IDENTIFIER ')'
: '(' specify_path_identifiers spec_polarity K_EG expression ')'
| '(' specify_path_identifiers spec_polarity K_SG expression ')'
| '(' error ')'
{ yyerror(@2, "Invalid simple path");
yyerrok;
}
;
specify_path_identifiers
: IDENTIFIER { }
| IDENTIFIER '[' expr_primary ']' { }
| specify_path_identifiers ',' IDENTIFIER { }
| specify_path_identifiers ',' IDENTIFIER '[' expr_primary ']' { }
;
specparam
@@ -1831,6 +1951,21 @@ specparam
{ delete $1;
delete $3;
}
| IDENTIFIER '=' expression ':' expression ':' expression
{ delete $1;
delete $3;
delete $5;
delete $7;
}
| PATHPULSE_IDENTIFIER '=' '(' expression ')'
{ delete $1;
delete $4;
}
| PATHPULSE_IDENTIFIER '=' '(' expression ',' expression ')'
{ delete $1;
delete $4;
delete $6;
}
;
specparam_list
@@ -1840,6 +1975,43 @@ specparam_list
spec_polarity: '+' | '-' | ;
spec_reference_event
: K_posedge expression
{ delete $2; }
| K_negedge expression
{ delete $2; }
| K_posedge expr_primary K_TAND expression
{ delete $2;
delete $4;
}
| K_negedge expr_primary K_TAND expression
{ delete $2;
delete $4;
}
| expr_primary
{ delete $1; }
;
spec_notifier_opt
: /* empty */
{ }
| spec_notifier
{ }
;
spec_notifier
: ','
{ }
| ',' identifier
{ delete $2; }
| spec_notifier ','
{ }
| spec_notifier ',' identifier
{ delete $3;
}
| IDENTIFIER
{ delete $1; }
;
statement
@@ -1951,14 +2123,14 @@ statement
}
| K_disable identifier ';'
{ PDisable*tmp = new PDisable($2);
{ PDisable*tmp = new PDisable(*$2);
tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line);
delete $2;
$$ = tmp;
}
| K_TRIGGER IDENTIFIER ';'
{ PTrigger*tmp = new PTrigger($2);
{ PTrigger*tmp = new PTrigger(hname_t($2));
tmp->set_file(@2.text);
tmp->set_lineno(@2.first_line);
delete $2;
@@ -2139,7 +2311,7 @@ statement
$$ = tmp;
}
| SYSTEM_IDENTIFIER '(' expression_list ')' ';'
{ PCallTask*tmp = new PCallTask($1, *$3);
{ PCallTask*tmp = new PCallTask(hname_t($1), *$3);
tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line);
delete $1;
@@ -2148,14 +2320,14 @@ statement
}
| SYSTEM_IDENTIFIER ';'
{ svector<PExpr*>pt (0);
PCallTask*tmp = new PCallTask($1, pt);
PCallTask*tmp = new PCallTask(hname_t($1), pt);
tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line);
delete $1;
$$ = tmp;
}
| identifier '(' expression_list ')' ';'
{ PCallTask*tmp = new PCallTask($1, *$3);
{ PCallTask*tmp = new PCallTask(*$1, *$3);
tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line);
delete $1;
@@ -2164,7 +2336,7 @@ statement
}
| identifier ';'
{ svector<PExpr*>pt (0);
PCallTask*tmp = new PCallTask($1, pt);
PCallTask*tmp = new PCallTask(*$1, pt);
tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line);
delete $1;
@@ -2308,7 +2480,7 @@ udp_sequ_entry
udp_initial
: K_initial IDENTIFIER '=' NUMBER ';'
{ PExpr*etmp = new PENumber($4);
PEIdent*itmp = new PEIdent($2);
PEIdent*itmp = new PEIdent(hname_t($2));
PAssign*atmp = new PAssign(itmp, etmp);
atmp->set_file(@2.text);
atmp->set_lineno(@2.first_line);
@@ -2350,12 +2522,17 @@ udp_input_sym
| '%' { $$ = '%'; }
| 'f' { $$ = 'f'; }
| 'F' { $$ = 'F'; }
| 'l' { $$ = 'l'; }
| 'h' { $$ = 'H'; }
| 'B' { $$ = 'B'; }
| 'r' { $$ = 'r'; }
| 'R' { $$ = 'R'; }
| 'M' { $$ = 'M'; }
| 'n' { $$ = 'n'; }
| 'N' { $$ = 'N'; }
| 'p' { $$ = 'p'; }
| 'P' { $$ = 'P'; }
| 'Q' { $$ = 'Q'; }
| '_' { $$ = '_'; }
| '+' { $$ = '+'; }
;
@@ -2374,14 +2551,12 @@ udp_port_decl
{ PWire*pp = new PWire($2, NetNet::IMPLICIT, NetNet::POUTPUT);
svector<PWire*>*tmp = new svector<PWire*>(1);
(*tmp)[0] = pp;
delete $2;
$$ = tmp;
}
| K_reg IDENTIFIER ';'
{ PWire*pp = new PWire($2, NetNet::REG, NetNet::PIMPLICIT);
svector<PWire*>*tmp = new svector<PWire*>(1);
(*tmp)[0] = pp;
delete $2;
$$ = tmp;
}
;
@@ -2418,7 +2593,8 @@ udp_primitive
udp_init_opt
udp_body
K_endprimitive
{ pform_make_udp($2, $4, $7, $9, $8);
{ pform_make_udp($2, $4, $7, $9, $8,
@2.text, @2.first_line);
delete[]$2;
}
;
+57
View File
@@ -0,0 +1,57 @@
#ifndef __parse_api_H
#define __parse_api_H
/*
* 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)
#ident "$Id: parse_api.h,v 1.1 2001/10/21 20:18:56 steve Exp $"
#endif
# include <stdio.h>
# include <string>
# include <map>
class Module;
class PUdp;
/*
* These are maps of the modules and primitives parsed from the
* Verilog source into pform for elaboration. The parser adds modules
* to these maps as it compiles modules in the verilog source.
*/
extern map<string,Module*> pform_modules;
extern map<string,PUdp*> pform_primitives;
/*
* This code actually invokes the parser to make modules. The first
* parameter is the name of the file that is to be parsed. The
* optional second parameter is the opened descriptor for the file. If
* the descriptor is 0 (or skipped) then the function will attempt to
* open the file on its own.
*/
extern int pform_parse(const char*path, FILE*file =0);
extern string vl_file;
/*
* $Log: parse_api.h,v $
* Revision 1.1 2001/10/21 20:18:56 steve
* clean up API for restarting parser.
*
*/
#endif
+7 -1
View File
@@ -17,9 +17,11 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: parse_misc.cc,v 1.4 2000/02/23 02:56:55 steve Exp $"
#ident "$Id: parse_misc.cc,v 1.5 2001/07/25 03:10:49 steve Exp $"
#endif
# include "config.h"
# include "parse_misc.h"
# include <iostream.h>
@@ -58,6 +60,10 @@ int VLwrap()
/*
* $Log: parse_misc.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/02/23 02:56:55 steve
* Macintosh compilers do not support ident.
*
+307 -206
View File
@@ -17,12 +17,15 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: pform.cc,v 1.73 2001/01/15 00:47:01 steve Exp $"
#ident "$Id: pform.cc,v 1.87 2001/12/07 05:03:13 steve Exp $"
#endif
# include "config.h"
# include "compiler.h"
# include "pform.h"
# include "parse_misc.h"
# include "parse_api.h"
# include "PEvent.h"
# include "PUdp.h"
# include <list>
@@ -31,6 +34,9 @@
# include <typeinfo>
# include <strstream>
map<string,Module*> pform_modules;
map<string,PUdp*> pform_primitives;
/*
* The lexor accesses the vl_* variables.
*/
@@ -45,15 +51,34 @@ static int pform_time_prec = 0;
/*
* The scope stack and the following functions handle the processing
* of scope. As I enter a scope, the push function is called, and as I
* leave a scope the pop function is called.
* leave a scope the pop function is called. Entering tasks, functions
* and named blocks causes scope to be pushed and popped. The module
* name is not included it this scope stack.
*
* The top module is not included in the scope list.
* The hier_name function, therefore, returns the name path of a
* function relative the current function.
*/
struct scope_name_t {
string name;
struct scope_name_t*next;
};
static scope_name_t*scope_stack = 0;
static hname_t scope_stack;
void pform_push_scope(char*name)
{
scope_stack.append(name);
}
void pform_pop_scope()
{
char*tmp = scope_stack.remove_tail_name();
assert(tmp);
free(tmp);
}
static hname_t hier_name(const char*tail)
{
hname_t name = scope_stack;
name.append(tail);
return name;
}
void pform_set_timescale(int unit, int prec)
{
@@ -62,34 +87,6 @@ void pform_set_timescale(int unit, int prec)
pform_time_prec = prec;
}
void pform_push_scope(const string&name)
{
scope_name_t*cur = new scope_name_t;
cur->name = name;
cur->next = scope_stack;
scope_stack = cur;
}
void pform_pop_scope()
{
assert(scope_stack);
scope_name_t*cur = scope_stack;
scope_stack = cur->next;
delete cur;
}
static string scoped_name(string name)
{
scope_name_t*cur = scope_stack;
while (cur) {
name = cur->name + "." + name;
cur = cur->next;
}
return name;
}
static map<string,Module*> vl_modules;
static map<string,PUdp*> vl_primitives;
/*
* This function evaluates delay expressions. The result should be a
@@ -106,7 +103,8 @@ static unsigned long evaluate_delay(PExpr*delay)
return pp->value().as_ulong();
}
void pform_startmodule(const string&name, svector<Module::port_t*>*ports)
void pform_startmodule(const char*name, svector<Module::port_t*>*ports,
const char*file, unsigned lineno)
{
assert( pform_cur_module == 0 );
@@ -121,14 +119,18 @@ void pform_startmodule(const string&name, svector<Module::port_t*>*ports)
pform_cur_module = new Module(name, ports);
pform_cur_module->time_unit = pform_time_unit;
pform_cur_module->time_precision = pform_time_prec;
pform_cur_module->set_file(file);
pform_cur_module->set_lineno(lineno);
delete ports;
}
void pform_endmodule(const string&name)
void pform_endmodule(const char*name)
{
assert(pform_cur_module);
assert(name == pform_cur_module->get_name());
vl_modules[name] = pform_cur_module;
assert(strcmp(name, pform_cur_module->mod_name()) == 0);
pform_modules[name] = pform_cur_module;
pform_cur_module = 0;
}
@@ -158,7 +160,7 @@ PExpr* pform_select_mtm_expr(PExpr*min, PExpr*typ, PExpr*max)
case MAX:
res = max;
delete min;
delete max;
delete typ;
break;
}
@@ -185,8 +187,10 @@ PExpr* pform_select_mtm_expr(PExpr*min, PExpr*typ, PExpr*max)
void pform_make_udp(const char*name, list<string>*parms,
svector<PWire*>*decl, list<string>*table,
Statement*init_expr)
Statement*init_expr,
const char*file, unsigned lineno)
{
unsigned local_errors = 0;
assert(parms->size() > 0);
/* Put the declarations into a map, so that I can check them
@@ -196,9 +200,9 @@ void pform_make_udp(const char*name, list<string>*parms,
map<string,PWire*> defs;
for (unsigned idx = 0 ; idx < decl->count() ; idx += 1) {
string pname = (*decl)[idx]->name();
PWire*cur = defs[pname];
if (PWire*cur = defs[pname]) {
hname_t pname = (*decl)[idx]->path();
if (PWire*cur = defs[pname.peek_name(0)]) {
bool rc = true;
assert((*decl)[idx]);
if ((*decl)[idx]->get_port_type() != NetNet::PIMPLICIT) {
@@ -211,34 +215,98 @@ void pform_make_udp(const char*name, list<string>*parms,
}
} else {
defs[pname] = (*decl)[idx];
defs[pname.peek_name(0)] = (*decl)[idx];
}
}
/* Put the parameters into a vector of wire descriptions. Look
in the map for the definitions of the name. */
in the map for the definitions of the name. In this loop,
the parms list in the list of ports in the port list of the
UDP declaration, and the defs map maps that name to a
PWire* created by an input or output declaration. */
svector<PWire*> pins (parms->size());
svector<string> pin_names (parms->size());
{ list<string>::iterator cur;
unsigned idx;
for (cur = parms->begin(), idx = 0
; cur != parms->end()
; idx++, cur++) {
pins[idx] = defs[*cur];
pin_names[idx] = *cur;
}
}
/* Check that the output is an output and the inputs are
inputs. I can also make sure that only the single output is
declared a register, if anything. */
declared a register, if anything. The possible errors are:
-- an input port (not the first) is missing an input
declaration.
-- An input port is declared output.
*/
assert(pins.count() > 0);
assert(pins[0]);
assert(pins[0]->get_port_type() == NetNet::POUTPUT);
do {
if (pins[0] == 0) {
cerr << file<<":"<<lineno << ": error: "
<< "Output port of primitive " << name
<< " missing output declaration." << endl;
cerr << file<<":"<<lineno << ": : "
<< "Try: output " << pin_names[0] << ";"
<< endl;
error_count += 1;
local_errors += 1;
break;
}
if (pins[0]->get_port_type() != NetNet::POUTPUT) {
cerr << file<<":"<<lineno << ": error: "
<< "The first port of a primitive"
<< " must be an output." << endl;
cerr << file<<":"<<lineno << ": : "
<< "Try: output " << pin_names[0] << ";"
<< endl;
error_count += 1;
local_errors += 1;
break;;
}
} while (0);
for (unsigned idx = 1 ; idx < pins.count() ; idx += 1) {
assert(pins[idx]);
assert(pins[idx]->get_port_type() == NetNet::PINPUT);
if (pins[idx] == 0) {
cerr << file<<":"<<lineno << ": error: "
<< "Port " << (idx+1)
<< " of primitive " << name << " missing"
<< " input declaration." << endl;
cerr << file<<":"<<lineno << ": : "
<< "Try: input " << pin_names[idx] << ";"
<< endl;
error_count += 1;
local_errors += 1;
continue;
}
if (pins[idx]->get_port_type() != NetNet::PINPUT) {
cerr << file<<":"<<lineno << ": error: "
<< "Port " << (idx+1)
<< " of primitive " << name << " in an input port"
<< " with an output declaration." << endl;
cerr << file<<":"<<lineno << ": : "
<< "Try: input " << pin_names[idx] << ";"
<< endl;
error_count += 1;
local_errors += 1;
continue;
}
assert(pins[idx]->get_wire_type() != NetNet::REG);
}
if (local_errors > 0) {
delete parms;
delete decl;
delete table;
delete init_expr;
return;
}
/* Interpret and check the table entry strings, to make sure
they correspond to the inputs, output and output type. Make
@@ -285,7 +353,7 @@ void pform_make_udp(const char*name, list<string>*parms,
assert(id);
// XXXX
assert(id->name() == pins[0]->name());
//assert(id->name() == pins[0]->name());
const PENumber*np = dynamic_cast<const PENumber*>(pa->rval());
assert(np);
@@ -294,7 +362,7 @@ void pform_make_udp(const char*name, list<string>*parms,
}
// Put the primitive into the primitives table
if (vl_primitives[name]) {
if (pform_primitives[name]) {
VLerror("UDP primitive already exists.");
} else {
@@ -306,16 +374,17 @@ void pform_make_udp(const char*name, list<string>*parms,
// Make the port list for the UDP
for (unsigned idx = 0 ; idx < pins.count() ; idx += 1)
udp->ports[idx] = pins[idx]->name();
udp->ports[idx] = pins[idx]->path().peek_name(0);
udp->tinput = input;
udp->tcurrent = current;
udp->toutput = output;
udp->initial = init;
vl_primitives[name] = udp;
pform_primitives[name] = udp;
}
/* Delete the excess tables and lists from the parser. */
delete parms;
delete decl;
@@ -335,7 +404,7 @@ static void pform_set_net_range(const char*name,
assert(range);
assert(range->count() == 2);
PWire*cur = pform_cur_module->get_wire(scoped_name(name));
PWire*cur = pform_cur_module->get_wire(hier_name(name));
if (cur == 0) {
VLerror("error: name is not a valid net.");
return;
@@ -436,20 +505,13 @@ void pform_makegates(PGBuiltin::Type type,
* functions handle the instantaions of modules (and UDP objects) by
* making PGModule objects.
*/
static void pform_make_modgate(const string&type,
static void pform_make_modgate(const char*type,
const string&name,
struct parmvalue_t*overrides,
svector<PExpr*>*wires,
PExpr*msb, PExpr*lsb,
const char*fn, unsigned ln)
{
if (name == "") {
cerr << fn << ":" << ln << ": Instantiation of " << type
<< " module requires an instance name." << endl;
error_count += 1;
return;
}
PGModule*cur = new PGModule(type, name, wires);
cur->set_file(fn);
cur->set_lineno(ln);
@@ -474,20 +536,13 @@ static void pform_make_modgate(const string&type,
pform_cur_module->add_gate(cur);
}
static void pform_make_modgate(const string&type,
static void pform_make_modgate(const char*type,
const string&name,
struct parmvalue_t*overrides,
svector<portname_t*>*bind,
PExpr*msb, PExpr*lsb,
const char*fn, unsigned ln)
{
if (name == "") {
cerr << fn << ":" << ln << ": Instantiation of " << type
<< " module requires an instance name." << endl;
error_count += 1;
return;
}
unsigned npins = bind->count();
named<PExpr*>*pins = new named<PExpr*>[npins];
for (unsigned idx = 0 ; idx < npins ; idx += 1) {
@@ -521,7 +576,7 @@ static void pform_make_modgate(const string&type,
pform_cur_module->add_gate(cur);
}
void pform_make_modgates(const string&type,
void pform_make_modgates(const char*type,
struct parmvalue_t*overrides,
svector<lgate>*gates)
{
@@ -616,9 +671,9 @@ void pform_make_pgassign_list(svector<PExpr*>*alist,
* BTF-B14.
*/
void pform_make_reginit(const struct vlltype&li,
const string&name, PExpr*expr)
const char*name, PExpr*expr)
{
const string sname = scoped_name(name);
const hname_t sname = hier_name(name);
PWire*cur = pform_cur_module->get_wire(sname);
if (cur == 0) {
VLerror(li, "internal error: reginit to non-register?");
@@ -639,21 +694,49 @@ void pform_make_reginit(const struct vlltype&li,
pform_cur_module->add_behavior(top);
}
void pform_makewire(const vlltype&li, const string&nm,
/*
* This function makes a single signal (a wire, a reg, etc) as
* requested by the parser. The name is unscoped, so I attach the
* current scope to it (with the scoped_name function) and I try to
* resolve it with an existing PWire in the scope.
*
* The wire might already exist because of an implicit declaration in
* a module port, i.e.:
*
* module foo (bar...
*
* reg bar;
*
* The output (or other port direction indicator) may or may not have
* been seen already, so I do not do any cheching with it yet. But I
* do check to see if the name has already been declared, as this
* function is called for every declaration.
*/
void pform_makewire(const vlltype&li, const char*nm,
NetNet::Type type)
{
const string name = scoped_name(nm);
hname_t name = hier_name(nm);
PWire*cur = pform_cur_module->get_wire(name);
if (cur) {
if (cur->get_wire_type() != NetNet::IMPLICIT) {
if ((cur->get_wire_type() != NetNet::IMPLICIT)
&& (cur->get_wire_type() != NetNet::IMPLICIT_REG)) {
strstream msg;
msg << name << " previously defined at " <<
cur->get_line() << "." << ends;
VLerror(msg.str());
} else {
bool rc = cur->set_wire_type(type);
assert(rc);
if (rc == false) {
strstream msg;
msg << name << " definition conflicts with "
<< "definition at " << cur->get_line()
<< "." << ends;
VLerror(msg.str());
}
}
cur->set_file(li.text);
cur->set_lineno(li.first_line);
return;
}
@@ -683,12 +766,48 @@ void pform_makewire(const vlltype&li,
delete range;
}
void pform_set_port_type(const string&nm, NetNet::PortType pt)
void pform_makewire(const vlltype&li,
svector<PExpr*>*range,
svector<PExpr*>*delay,
net_decl_assign_t*decls,
NetNet::Type type)
{
const string name = scoped_name(nm);
net_decl_assign_t*first = decls->next;
decls->next = 0;
struct str_pair_t str;
str.str0 = PGate::STRONG;
str.str1 = PGate::STRONG;
while (first) {
net_decl_assign_t*next = first->next;
pform_makewire(li, first->name, type);
if (range)
pform_set_net_range(first->name, range, false);
hname_t name = hier_name(first->name);
PWire*cur = pform_cur_module->get_wire(name);
if (cur != 0) {
PEIdent*lval = new PEIdent(hname_t(first->name));
pform_make_pgassign(lval, first->expr, delay, str);
}
free(first->name);
delete first;
first = next;
}
}
void pform_set_port_type(const char*nm, NetNet::PortType pt,
const char*file, unsigned lineno)
{
hname_t name = hier_name(nm);
PWire*cur = pform_cur_module->get_wire(name);
if (cur == 0) {
cur = new PWire(name, NetNet::IMPLICIT, pt);
cur->set_file(file);
cur->set_lineno(lineno);
pform_cur_module->add_wire(cur);
}
@@ -747,7 +866,7 @@ svector<PWire*>*pform_make_task_ports(NetNet::PortType pt,
; cur != names->end() ; cur ++ ) {
char*txt = *cur;
string name = scoped_name(txt);
hname_t name = hier_name(txt);
/* Look for a preexisting wire. If it exists, set the
port direction. If not, create it. */
@@ -788,23 +907,48 @@ void pform_set_task(const string&name, PTask*task)
* with the trappings that are discovered after the basic function
* name is parsed.
*/
void pform_set_function(const string&name, svector<PExpr*>*ra, PFunction *func)
void pform_set_function(const char*name, NetNet::Type ntype,
svector<PExpr*>*ra, PFunction *func)
{
PWire*out = new PWire(name+"."+name, NetNet::REG, NetNet::POUTPUT);
if (ntype == NetNet::IMPLICIT)
ntype = NetNet::REG;
/* Form into path_return a hierarchical name for the synthetic
return value for the function. The return value is the same
name as the function, so if the function name is "foo", the
wire is "foo.foo". */
hname_t path_return (name);
path_return.append(name);
PWire*out = new PWire(path_return, ntype, NetNet::POUTPUT);
if (ra) {
assert(ra->count() == 2);
out->set_range((*ra)[0], (*ra)[1]);
delete ra;
}
/* If the return type of the function is INTEGER, then convert
it to a signed reg, and generate a range for it. The
parse.y uses IMPLICIT_REG as a signal that this is an
integer, because there is no such thing as
NetNet::INTEGER. */
if (ntype == NetNet::IMPLICIT_REG) {
out->set_wire_type(NetNet::REG);
out->set_signed(true);
out->set_range(new PENumber(new verinum(INTEGER_WIDTH-1, INTEGER_WIDTH)),
new PENumber(new verinum(0UL, INTEGER_WIDTH)));
}
pform_cur_module->add_wire(out);
func->set_output(out);
pform_cur_module->add_function(name, func);
}
void pform_set_attrib(const string&name, const string&key, const string&value)
void pform_set_attrib(const char*name, const string&key, const string&value)
{
PWire*cur = pform_cur_module->get_wire(name);
if (PWire*cur = pform_cur_module->get_wire(name)) {
hname_t path (name);
if (PWire*cur = pform_cur_module->get_wire(path)) {
cur->attributes[key] = value;
} else if (PGate*cur = pform_cur_module->get_gate(name)) {
@@ -823,8 +967,8 @@ void pform_set_attrib(const string&name, const string&key, const string&value)
void pform_set_type_attrib(const string&name, const string&key,
const string&value)
{
map<string,PUdp*>::const_iterator udp = vl_primitives.find(name);
if (udp == vl_primitives.end()) {
map<string,PUdp*>::const_iterator udp = pform_primitives.find(name);
if (udp == pform_primitives.end()) {
VLerror("type name is not (yet) defined.");
return;
}
@@ -836,9 +980,9 @@ void pform_set_type_attrib(const string&name, const string&key,
* This function attaches a memory index range to an existing
* register. (The named wire must be a register.
*/
void pform_set_reg_idx(const string&name, PExpr*l, PExpr*r)
void pform_set_reg_idx(const char*name, PExpr*l, PExpr*r)
{
PWire*cur = pform_cur_module->get_wire(scoped_name(name));
PWire*cur = pform_cur_module->get_wire(hier_name(name));
if (cur == 0) {
VLerror("internal error: name is not a valid memory for index.");
return;
@@ -860,13 +1004,14 @@ void pform_set_localparam(const string&name, PExpr*expr)
pform_cur_module->localparams[name] = expr;
}
void pform_set_defparam(const string&name, PExpr*expr)
void pform_set_defparam(const hname_t&name, PExpr*expr)
{
assert(expr);
pform_cur_module->defparms[name] = expr;
}
void pform_set_port_type(list<char*>*names,
void pform_set_port_type(const struct vlltype&li,
list<char*>*names,
svector<PExpr*>*range,
NetNet::PortType pt)
{
@@ -874,7 +1019,7 @@ void pform_set_port_type(list<char*>*names,
; cur != names->end()
; cur ++ ) {
char*txt = *cur;
pform_set_port_type(txt, pt);
pform_set_port_type(txt, pt, li.text, li.first_line);
if (range)
pform_set_net_range(txt, range, false);
free(txt);
@@ -887,7 +1032,7 @@ void pform_set_port_type(list<char*>*names,
static void pform_set_reg_integer(const char*nm)
{
string name = scoped_name(nm);
hname_t name = hier_name(nm);
PWire*cur = pform_cur_module->get_wire(name);
if (cur == 0) {
cur = new PWire(name, NetNet::REG, NetNet::NOT_A_PORT);
@@ -919,7 +1064,7 @@ void pform_set_reg_integer(list<char*>*names)
static void pform_set_reg_time(const char*nm)
{
string name = scoped_name(nm);
hname_t name = hier_name(nm);
PWire*cur = pform_cur_module->get_wire(name);
if (cur == 0) {
cur = new PWire(name, NetNet::REG, NetNet::NOT_A_PORT);
@@ -974,35 +1119,89 @@ PProcess* pform_make_behavior(PProcess::Type type, Statement*st)
FILE*vl_input = 0;
int pform_parse(const char*path, map<string,Module*>&modules,
map<string,PUdp*>&prim)
extern void reset_lexor();
int pform_parse(const char*path, FILE*file)
{
vl_file = path;
if (strcmp(path, "-") == 0)
vl_input = stdin;
else
vl_input = fopen(path, "r");
if (vl_input == 0) {
cerr << "Unable to open " <<vl_file << "." << endl;
return 11;
if (file == 0) {
if (strcmp(path, "-") == 0)
vl_input = stdin;
else
vl_input = fopen(path, "r");
if (vl_input == 0) {
cerr << "Unable to open " <<vl_file << "." << endl;
return 11;
}
} else {
vl_input = file;
}
reset_lexor();
error_count = 0;
warn_count = 0;
int rc = VLparse();
if (file == 0)
fclose(vl_input);
if (rc) {
cerr << "I give up." << endl;
error_count += 1;
}
modules = vl_modules;
prim = vl_primitives;
return error_count;
}
/*
* $Log: pform.cc,v $
* Revision 1.87 2001/12/07 05:03:13 steve
* Support integer for function return value.
*
* Revision 1.86 2001/12/03 04:47:15 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
*
* Revision 1.85 2001/11/29 17:37:51 steve
* Properly parse net_decl assignments with delays.
*
* Revision 1.84 2001/11/10 02:08:49 steve
* Coerse input to inout when assigned to.
*
* Revision 1.83 2001/10/31 03:11:15 steve
* detect module ports not declared within the module.
*
* Revision 1.82 2001/10/21 01:55:24 steve
* Error messages for missing UDP port declarations.
*
* Revision 1.81 2001/10/21 00:42:48 steve
* Module types in pform are char* instead of string.
*
* Revision 1.80 2001/10/20 23:02:40 steve
* Add automatic module libraries.
*
* Revision 1.79 2001/10/20 05:21:51 steve
* Scope/module names are char* instead of string.
*
* Revision 1.78 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.77 2001/05/25 02:21:34 steve
* Detect input and input ports declared as reg.
*
* Revision 1.76 2001/05/20 15:03:25 steve
* Deleted wrong time when -Tmax is selected.
*
* Revision 1.75 2001/04/28 23:18:08 steve
* UDP instances need not have user supplied names.
*
* Revision 1.74 2001/02/17 05:15:33 steve
* Allow task ports to be given real types.
*
* Revision 1.73 2001/01/15 00:47:01 steve
* Pass scope type information to the target module.
*
@@ -1027,103 +1226,5 @@ int pform_parse(const char*path, map<string,Module*>&modules,
*
* Revision 1.67 2000/11/30 17:31:42 steve
* Change LineInfo to store const C strings.
*
* Revision 1.66 2000/10/31 17:49:02 steve
* Support time variables.
*
* Revision 1.65 2000/10/31 17:00:04 steve
* Remove C++ string from variable lists.
*
* Revision 1.64 2000/09/13 16:32:26 steve
* Error message for invalid variable list.
*
* Revision 1.63 2000/07/29 17:58:21 steve
* Introduce min:typ:max support.
*
* Revision 1.62 2000/07/22 22:09:04 steve
* Parse and elaborate timescale to scopes.
*
* Revision 1.61 2000/05/23 16:03:13 steve
* Better parsing of expressions lists will empty expressoins.
*
* Revision 1.60 2000/05/16 04:05:16 steve
* Module ports are really special PEIdent
* expressions, because a name can be used
* many places in the port list.
*
* Revision 1.59 2000/05/08 05:30:20 steve
* Deliver gate output strengths to the netlist.
*
* Revision 1.58 2000/05/06 15:41:57 steve
* Carry assignment strength to pform.
*
* Revision 1.57 2000/04/01 19:31:57 steve
* Named events as far as the pform.
*
* Revision 1.56 2000/03/12 17:09:41 steve
* Support localparam.
*
* Revision 1.55 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.54 2000/02/23 02:56:55 steve
* Macintosh compilers do not support ident.
*
* Revision 1.53 2000/02/18 05:15:03 steve
* Catch module instantiation arrays.
*
* Revision 1.52 2000/01/09 05:50:49 steve
* Support named parameter override lists.
*
* Revision 1.51 2000/01/02 01:59:28 steve
* Forgot to handle no overrides at all.
*
* Revision 1.50 2000/01/01 23:47:58 steve
* Fix module parameter override syntax.
*
* Revision 1.49 1999/12/30 19:06:14 steve
* Support reg initial assignment syntax.
*
* Revision 1.48 1999/12/11 05:45:41 steve
* Fix support for attaching attributes to primitive gates.
*
* Revision 1.47 1999/11/23 01:04:57 steve
* A file name of - means standard input.
*
* Revision 1.46 1999/09/30 01:22:37 steve
* Handle declaration of integers (including scope) in functions.
*
* Revision 1.45 1999/09/21 00:58:33 steve
* Get scope right when setting the net range.
*
* Revision 1.44 1999/09/17 02:06:26 steve
* Handle unconnected module ports.
*
* Revision 1.43 1999/09/15 01:55:06 steve
* Elaborate non-blocking assignment to memories.
*
* Revision 1.42 1999/09/10 05:02:09 steve
* Handle integers at task parameters.
*
* Revision 1.41 1999/08/31 22:38:29 steve
* Elaborate and emit to vvm procedural functions.
*
* Revision 1.40 1999/08/27 15:08:37 steve
* continuous assignment lists.
*
* Revision 1.39 1999/08/25 22:22:41 steve
* elaborate some aspects of functions.
*
* Revision 1.38 1999/08/23 16:48:39 steve
* Parameter overrides support from Peter Monta
* AND and XOR support wide expressions.
*
* Revision 1.37 1999/08/03 04:14:49 steve
* Parse into pform arbitrarily complex module
* port declarations.
*/
+60 -16
View File
@@ -19,10 +19,11 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: pform.h,v 1.45 2000/12/11 00:31:43 steve Exp $"
#ident "$Id: pform.h,v 1.54 2001/12/07 05:03:13 steve Exp $"
#endif
# include "netlist.h"
# include "HName.h"
# include "named.h"
# include "Module.h"
# include "Statement.h"
@@ -85,6 +86,12 @@ struct parmvalue_t {
struct str_pair_t { PGate::strength_t str0, str1; };
struct net_decl_assign_t {
char*name;
PExpr*expr;
struct net_decl_assign_t*next;
};
/* The lgate is gate instantiation information. */
struct lgate {
lgate(int =0)
@@ -110,46 +117,57 @@ struct lgate {
* are to apply to the scope of that module. The endmodule causes the
* pform to close up and finish the named module.
*/
extern void pform_startmodule(const string&, svector<Module::port_t*>*);
extern void pform_endmodule(const string&);
extern void pform_startmodule(const char*, svector<Module::port_t*>*,
const char*file, unsigned lineno);
extern void pform_endmodule(const char*);
extern void pform_make_udp(const char*name, list<string>*parms,
svector<PWire*>*decl, list<string>*table,
Statement*init);
Statement*init,
const char*file, unsigned lineno);
/*
* Enter/exit name scopes.
* Enter/exit name scopes. The push_scope function pushes the scope
* name string onto the scope hierarchy. The pop pulls it off and
* deletes it. Thus, the string pushed must be allocated.
*/
extern void pform_push_scope(const string&name);
extern void pform_push_scope(char*name);
extern void pform_pop_scope();
/*
* The makewire functions announce to the pform code new wires. These
* go into a module that is currently opened.
*/
extern void pform_makewire(const struct vlltype&li, const string&name,
extern void pform_makewire(const struct vlltype&li, const char*name,
NetNet::Type type = NetNet::IMPLICIT);
extern void pform_makewire(const struct vlltype&li,
svector<PExpr*>*range,
list<char*>*names,
NetNet::Type type);
extern void pform_makewire(const struct vlltype&li,
svector<PExpr*>*range,
svector<PExpr*>*delay,
net_decl_assign_t*assign_list,
NetNet::Type type);
extern void pform_make_reginit(const struct vlltype&li,
const string&name, PExpr*expr);
extern void pform_set_port_type(list<char*>*names, svector<PExpr*>*,
const char*name, PExpr*expr);
extern void pform_set_port_type(const struct vlltype&li,
list<char*>*names, svector<PExpr*>*,
NetNet::PortType);
extern void pform_set_net_range(list<char*>*names, svector<PExpr*>*, bool);
extern void pform_set_reg_idx(const string&name, PExpr*l, PExpr*r);
extern void pform_set_reg_idx(const char*name, PExpr*l, PExpr*r);
extern void pform_set_reg_integer(list<char*>*names);
extern void pform_set_reg_time(list<char*>*names);
extern void pform_set_task(const string&, PTask*);
extern void pform_set_function(const string&, svector<PExpr*>*, PFunction*);
extern void pform_set_attrib(const string&name, const string&key,
extern void pform_set_function(const char*, NetNet::Type,
svector<PExpr*>*, PFunction*);
extern void pform_set_attrib(const char*name, const string&key,
const string&value);
extern void pform_set_type_attrib(const string&name, const string&key,
const string&value);
extern void pform_set_parameter(const string&name, PExpr*expr);
extern void pform_set_localparam(const string&name, PExpr*expr);
extern void pform_set_defparam(const string&name, PExpr*expr);
extern void pform_set_defparam(const hname_t&name, PExpr*expr);
extern PProcess* pform_make_behavior(PProcess::Type, Statement*);
extern svector<PWire*>* pform_make_udp_input_ports(list<char*>*);
@@ -168,7 +186,7 @@ extern void pform_makegates(PGBuiltin::Type type,
svector<PExpr*>*delay,
svector<lgate>*gates);
extern void pform_make_modgates(const string&type,
extern void pform_make_modgates(const char*type,
struct parmvalue_t*overrides,
svector<lgate>*gates);
@@ -196,12 +214,38 @@ extern svector<PWire*>*pform_make_task_ports(NetNet::PortType pt,
* parses the source file and places all the modules it finds into the
* mod list. The dump function dumps a module to the output stream.
*/
extern int pform_parse(const char*path, map<string,Module*>&mod,
map<string,PUdp*>&prim);
extern void pform_dump(ostream&out, Module*mod);
/*
* $Log: pform.h,v $
* Revision 1.54 2001/12/07 05:03:13 steve
* Support integer for function return value.
*
* Revision 1.53 2001/12/03 04:47:15 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
*
* Revision 1.52 2001/11/29 17:37:51 steve
* Properly parse net_decl assignments with delays.
*
* Revision 1.51 2001/11/10 02:08:49 steve
* Coerse input to inout when assigned to.
*
* Revision 1.50 2001/10/31 03:11:15 steve
* detect module ports not declared within the module.
*
* Revision 1.49 2001/10/21 01:55:25 steve
* Error messages for missing UDP port declarations.
*
* Revision 1.48 2001/10/21 00:42:48 steve
* Module types in pform are char* instead of string.
*
* Revision 1.47 2001/10/20 23:02:40 steve
* Add automatic module libraries.
*
* Revision 1.46 2001/10/20 05:21:51 steve
* Scope/module names are char* instead of string.
*
* Revision 1.45 2000/12/11 00:31:43 steve
* Add support for signed reg variables,
* simulate in t-vvm signed comparisons.
+21 -10
View File
@@ -17,9 +17,11 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: pform_dump.cc,v 1.66 2001/01/13 22:20:08 steve Exp $"
#ident "$Id: pform_dump.cc,v 1.68 2001/12/03 04:47:15 steve Exp $"
#endif
# include "config.h"
/*
* This file provides the pform_dump function, that dumps the module
* passed as a parameter. The dump is as much as possible in Verilog
@@ -97,7 +99,7 @@ void PEConcat::dump(ostream&out) const
void PECallFunction::dump(ostream &out) const
{
out << name_ << "(";
out << path_ << "(";
if (parms_.count() > 0) {
if (parms_[0]) parms_[0]->dump(out);
@@ -140,7 +142,7 @@ void PENumber::dump(ostream&out) const
void PEIdent::dump(ostream&out) const
{
out << text_;
out << path_;
if (msb_) {
out << "[" << *msb_;
if (lsb_) {
@@ -232,7 +234,7 @@ void PWire::dump(ostream&out) const
out << " [" << *msb_[idx] << "]";
}
out << " " << name_;
out << " " << hname_;
// If the wire has indices, dump them.
if (lidx_ || ridx_) {
@@ -442,7 +444,7 @@ void PBlock::dump(ostream&out, unsigned ind) const
void PCallTask::dump(ostream&out, unsigned ind) const
{
out << setw(ind) << "" << name_;
out << setw(ind) << "" << path_;
if (parms_.count() > 0) {
out << "(";
@@ -585,12 +587,12 @@ void PForStatement::dump(ostream&out, unsigned ind) const
void PFunction::dump(ostream&out, unsigned ind) const
{
out << setw(ind) << "" << "output " << out_->name() << ";" << endl;
out << setw(ind) << "" << "output " << out_->path() << ";" << endl;
if (ports_)
for (unsigned idx = 0 ; idx < ports_->count() ; idx += 1) {
out << setw(ind) << "";
out << "input ";
out << (*ports_)[idx]->name() << ";" << endl;
out << (*ports_)[idx]->path() << ";" << endl;
}
if (statement_)
@@ -627,7 +629,7 @@ void PTask::dump(ostream&out, unsigned ind) const
out << "inout ";
break;
}
out << (*ports_)[idx]->name() << ";" << endl;
out << (*ports_)[idx]->path() << ";" << endl;
}
if (statement_)
@@ -684,6 +686,7 @@ void Module::dump(ostream&out) const
}
typedef map<string,PExpr*>::const_iterator parm_iter_t;
typedef map<hname_t,PExpr*>::const_iterator parm_hiter_t;
for (parm_iter_t cur = parameters.begin()
; cur != parameters.end() ; cur ++) {
out << " parameter " << (*cur).first << " = ";
@@ -702,7 +705,7 @@ void Module::dump(ostream&out) const
out << "/* ERROR */;" << endl;
}
for (parm_iter_t cur = defparms.begin()
for (parm_hiter_t cur = defparms.begin()
; cur != defparms.end() ; cur ++) {
out << " defparam " << (*cur).first << " = ";
if ((*cur).second)
@@ -719,7 +722,7 @@ void Module::dump(ostream&out) const
}
// Iterate through and display all the wires.
for (map<string,PWire*>::const_iterator wire = wires_.begin()
for (map<hname_t,PWire*>::const_iterator wire = wires_.begin()
; wire != wires_.end()
; wire ++ ) {
@@ -811,6 +814,14 @@ void PUdp::dump(ostream&out) const
/*
* $Log: pform_dump.cc,v $
* Revision 1.68 2001/12/03 04:47:15 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
*
* Revision 1.67 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.66 2001/01/13 22:20:08 steve
* Parse parameters within nested scopes.
*

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