Compare commits

...
604 Commits
Author SHA1 Message Date
steve 87e813766a Detect and ignore specify edge expressions 2007-06-14 03:50:00 +00:00
steve e24e77660f Detect and use the nan function. 2007-06-13 01:03:57 +00:00
steve 8ec6d9983d Put instantiated modules in the proper generated scope. 2007-06-12 04:05:45 +00:00
steve ae82eccdc4 handle constant inf values. 2007-06-12 02:36:58 +00:00
steve fa18d9bc01 Do not propogate until initialized. 2007-06-12 02:25:00 +00:00
steve 16ec4cb685 displan pmos gates. 2007-06-12 02:23:40 +00:00
steve 6f08f92ffc Prepare for snapshot 20070608 2007-06-09 01:06:51 +00:00
steve 0a38499941 Properly handle signed conversion to real 2007-06-07 03:20:15 +00:00
steve 55f8e5d364 int vs long expressions on 64bit arch (ldoolitt) 2007-06-05 21:52:22 +00:00
steve b631268f56 Error resiliency (ldoolitt) 2007-06-05 21:35:51 +00:00
steve 1a8ffe2a9c More standard PLI_BYTE8. 2007-06-05 21:32:30 +00:00
steve e4bcc87dc1 Upward names may reference modules by module_name. 2007-06-05 04:18:09 +00:00
steve 34111a25cb Bring in .SFT file automatically if -m used. 2007-06-05 01:56:12 +00:00
steve 8fd42fbf61 Build errors in picky GCC compilers. 2007-06-04 19:14:06 +00:00
steve 129a064e1a Handle bit/part select of array words in nets. 2007-06-04 02:19:07 +00:00
steve c7d97f4146 Properly evaluate scope path expressions. 2007-06-02 03:42:12 +00:00
steve 1f9a246c6d Fix warning (ldolittle) 2007-05-31 18:36:06 +00:00
steve 17fd3bae15 Missing return value to perm_string dump 2007-05-31 18:35:50 +00:00
steve 29aa68302e Add elsif support (Martin Whitaker) 2007-05-30 23:21:20 +00:00
steve 8dcd09797f Fix uninitialized lineno variable. 2007-05-25 18:21:39 +00:00
steve ddd36ecb6c Rework the heirarchical identifier parse syntax and pform
to handle more general combinations of heirarch and bit selects.
2007-05-24 04:07:11 +00:00
steve 67b1eee7ce Better configuration messages (Alan Feldstein) 2007-05-16 23:59:12 +00:00
steve 629c6e9a40 Fix hname_t use of space for 1 perm_string. 2007-05-16 19:12:33 +00:00
steve 6ea1337be0 Trace file line buffer must be static. 2007-05-08 22:01:26 +00:00
steve b981c81d37 Rework hname_t to use perm_strings. 2007-04-26 03:06:21 +00:00
steve 210e28e571 Prepare for 20070421 snapshot. 2007-04-22 00:32:07 +00:00
steve f6ad90f8d3 Rename assign_list to cont_assign_list. 2007-04-21 04:45:36 +00:00
steve 890f592eec Fix detect of signal that is an array. 2007-04-21 03:20:47 +00:00
steve f9c1c02f8d Add support for -v flag in command file. 2007-04-19 02:52:53 +00:00
steve 26f47c26f0 Handle arrayed strength-aware net devices. 2007-04-19 01:19:06 +00:00
steve c0496ea648 Add support for multiple command files. (Cary R.) 2007-04-18 03:23:38 +00:00
steve 498d8fe6ad Add support for Gg and Ee formats. 2007-04-18 02:40:20 +00:00
steve dafc653935 Put to iverilog wiki for further notes. 2007-04-18 02:36:13 +00:00
steve 401faef5b8 Fix vpi_get_value vpiRealVal of signed constants. 2007-04-18 01:57:07 +00:00
steve 22efa9f066 Fix elaboration of multiply of two constants. 2007-04-18 01:40:49 +00:00
steve 583abb7f49 Fix handling calls to tasks in combinational always block 2007-04-17 04:34:23 +00:00
steve fe65ae8db0 Support part select of array words in net contexts. 2007-04-17 04:18:10 +00:00
steve cc48a6c8d7 Fix argument count in function error message. 2007-04-17 04:17:47 +00:00
steve 36471e9f96 Properly ignore unsupported ifnone. 2007-04-16 01:10:07 +00:00
steve 427d5664ef Fix missing zero if time value is exactly 0. 2007-04-16 00:47:12 +00:00
steve 253fdc6232 Fix scanf to abort on failed matches. 2007-04-16 00:09:58 +00:00
steve 79fdb2b243 Attach line number information to task calls. 2007-04-15 20:45:40 +00:00
steve 089bdefad1 Fix div/mod calculation that caused a hang for some divisions. 2007-04-15 02:07:24 +00:00
steve 8ed1a010f7 Allow bit/part select of vectors in continuous assignments. 2007-04-15 01:37:29 +00:00
steve 9931e4c013 Finish up part select of array words. 2007-04-14 04:43:01 +00:00
steve acdb278b97 Handle system functions with no arguments. 2007-04-14 03:27:51 +00:00
steve d3a54547aa Properly account for tri0 connected to otherwise open mux input. 2007-04-14 03:10:51 +00:00
steve f621448ced Parse edge sensitive paths without edge specifier. 2007-04-13 02:34:35 +00:00
steve 2229825783 fix handling of unary reduction logic in certain nets. 2007-04-12 05:21:54 +00:00
steve fb7ce1d330 Support for vpi_get_value of scaler values. (ravi@bluespec) 2007-04-12 04:45:52 +00:00
steve ff7625cd9c nexus vectors of VT_BOOL objects. (ravi@bluespec) 2007-04-12 04:40:37 +00:00
steve 8f9738719b Add support for vpiSize on system task handle. ([email protected]) 2007-04-12 04:33:39 +00:00
steve 31914c7fcd vpip_make_binary_const cannot free the string passed in to it. 2007-04-12 04:25:58 +00:00
steve abaeb1e702 Add printtimescale (caryr) 2007-04-12 02:50:51 +00:00
steve 513fa72d99 Cleanup timeformat argument checking. 2007-04-10 04:56:26 +00:00
steve 65baeaed8f vpi_free_object doesnot free callback out from under runtime. 2007-04-10 04:32:05 +00:00
steve fbc731d19e Allow nexus aliases to array words. 2007-04-10 03:40:04 +00:00
steve 5047a3add3 variable arrays generated without writing a record for each word. 2007-04-10 01:26:15 +00:00
steve d3588b4e23 More strict use of PLI_BYTE8 type. 2007-04-09 22:49:33 +00:00
steve 33e5f22cf1 Handle evaluate of addition of real valued constants. 2007-04-07 04:46:18 +00:00
steve af913e7eb1 Allow implicit wires in assign l-value. 2007-04-05 03:09:50 +00:00
steve dd995b3409 Probe of case statement inputs can skip nul statements. 2007-04-05 01:53:52 +00:00
steve a863b2390c Remove useless assert 2007-04-04 02:31:57 +00:00
steve c5524b4acf t-dll should not canonicalize word addresses, elaboration already does it. 2007-04-04 01:50:38 +00:00
steve d883979fd8 Seperate arrayness from word count 2007-04-02 01:12:34 +00:00
steve 37111eb4a8 Tighter parsing of statement lists and expression lists. 2007-04-01 23:02:03 +00:00
steve bd1b00ca29 Improve port mismatch error message. 2007-04-01 23:01:10 +00:00
steve 0168502bbb Get offsets into indexed part selects correct. 2007-04-01 05:28:26 +00:00
steve ea74940be4 Fix that save expression lookaside always clears cached variable values. 2007-04-01 05:26:17 +00:00
steve 8856c07d88 More efficient allocate of ivl_nexus_t objects. 2007-03-26 20:32:47 +00:00
steve 9e21880cdc Handle part select of array words. 2007-03-26 19:23:13 +00:00
steve fe8da0bf14 Remove pretense of general use for t_cookie. 2007-03-26 18:17:50 +00:00
steve fe02214fcc do not calculate nexus name unless needed. 2007-03-26 16:51:48 +00:00
steve 611d2c81b3 Spelling fixes from Larry 2007-03-22 16:08:14 +00:00
steve 96443f1338 Clear lookaside even if source bit is a constant. 2007-03-20 04:26:56 +00:00
steve 32fb919b00 Replace some asserts with ivl_asserts. 2007-03-14 05:06:49 +00:00
steve 72ec3a2c09 VPI tasks take PLI_BYTE* by the standard. 2007-03-14 04:05:51 +00:00
steve a50ec29ad9 Elaborate scopes of modules instantated in generate loops. 2007-03-08 06:11:35 +00:00
steve d9efe3312e Limit the calculated widths of constants. 2007-03-08 05:30:02 +00:00
steve 29b4d5a46e document the +integer-width plus-arg. 2007-03-08 03:06:47 +00:00
steve f23a5bfa96 Make integer width controllable. 2007-03-07 04:24:59 +00:00
steve 74ac5dbf58 Cast to remove ambiguities calling pow function. 2007-03-07 03:55:42 +00:00
steve ae88f5cc68 Lint fixes. 2007-03-07 00:38:15 +00:00
steve 760f2182ba Support signed function return values. 2007-03-06 05:22:49 +00:00
steve e6fa72c318 Handle processes within generate loops. 2007-03-05 05:59:10 +00:00
steve 8c434ca6fa Update spec file to be more suse compliant. 2007-03-04 20:49:49 +00:00
steve 6f810e0dba Assert that modpath finds a delay. 2007-03-04 06:26:58 +00:00
steve b68f17483e UDP schedules its output instead of pushing it. 2007-03-04 06:26:33 +00:00
steve 606751dbfd Check that path source/destination are ports. 2007-03-03 05:56:55 +00:00
steve fc9a90c9e0 Add support for edge sensitive spec paths. 2007-03-02 06:13:22 +00:00
steve b21390b228 Better error message when operating on array. 2007-03-02 01:55:36 +00:00
steve 1352eada12 Improved buildrequires and clean (Günter Dannoritzer) 2007-03-02 01:30:47 +00:00
steve 243cf94165 Add support for conditional specify delay paths. 2007-03-01 06:19:38 +00:00
steve e789b3a5cf Snapshot 20070227 2007-02-28 01:34:42 +00:00
steve bb02da0319 Better error message around repeat concatenation syntax. 2007-02-27 06:10:16 +00:00
steve 0946f40c7b Detect and warn about lval array index out fo bounds. 2007-02-27 05:14:38 +00:00
steve 80a2b05733 Do not assign to words constant-indexed out of range. 2007-02-27 05:13:34 +00:00
steve 6804732b9e Spelling fixes (larry doolittle) 2007-02-26 19:49:48 +00:00
steve d6969b719a Prevent lost of width while calculation address. 2007-02-26 01:51:40 +00:00
steve d2ba78559a Process Verilog escape sequences much earlier. 2007-02-25 23:08:24 +00:00
steve 1f54f128c1 Handle unary minus of real valued expressions. 2007-02-20 05:58:36 +00:00
steve 2c32a81d91 Improved version of pr1639064 patch handles huge values. (larry doolittle) 2007-02-19 01:45:56 +00:00
steve cd5b1b111c Fix print of integers as real. <larry Doolittle> 2007-02-18 06:01:25 +00:00
steve 9d4fc92df5 Get page size from sysconf. 2007-02-16 23:30:14 +00:00
steve 45307f6144 Handle type of ternary expressions properly. 2007-02-14 05:59:46 +00:00
steve 92c36f152d Treat BOOL and LOGIC the same according to VPI functions. 2007-02-14 05:59:24 +00:00
steve 4f74d9df98 Add the mov/wr opcode. 2007-02-14 05:58:14 +00:00
steve 0137832003 Include types for ternary and string in dump. 2007-02-14 05:57:51 +00:00
steve 189532c5bf Hande specparam with min/myp/max values. 2007-02-13 04:39:25 +00:00
steve 7d2d87f7c6 NAND output is inverted once AFTER AND is calculated. 2007-02-12 05:08:27 +00:00
steve 521f66f040 Get padding right when loading array word into big vector. 2007-02-12 04:37:58 +00:00
steve c1c2381261 Parse all specify paths to pform. 2007-02-12 01:52:21 +00:00
steve 97234cb7ca Lexor handle escaped slash in strings. 2007-02-09 05:19:04 +00:00
steve 3fd80b09f0 Administrative/Makefile fixes, mostly for windows. (Cary R.) 2007-02-06 05:07:31 +00:00
steve 2b3acfb344 Expression lookaside cannot hold complex expressions 2007-02-06 04:43:53 +00:00
steve 326329d497 Set some missing local flags. 2007-02-05 01:42:31 +00:00
steve d958a4a5af Handle relink of continuous assignment. 2007-02-05 01:08:10 +00:00
steve 7d42c50253 Lookaside is invalid when working a new scope. 2007-02-02 04:48:49 +00:00
steve 6d91be5b19 Use inttypes.h instead of stdint.h for portability. 2007-02-02 04:33:00 +00:00
steve d52f41535f Ternary output node is local. 2007-02-01 19:06:06 +00:00
steve a623502ece More generous handling of errors in blocks. 2007-02-01 05:52:24 +00:00
steve d22e9713f7 Error message better reflects more general reality. 2007-02-01 05:25:26 +00:00
steve 5869d7d879 Include type in signal create message. 2007-02-01 05:24:08 +00:00
steve 074a6a44e3 Detect and report arrays without index in net contexts. 2007-02-01 03:14:33 +00:00
steve 85ceea7358 Fix missing check for thread bits width in ADDI 2007-01-31 22:28:55 +00:00
steve b2e1db6adb Add method to bind assertions to verilog source lines. 2007-01-31 04:21:10 +00:00
steve 05efaa6427 Treat VPI argument array with constant index specially. 2007-01-30 05:28:23 +00:00
steve cfe2198e5e Types of task/function arguments set in multiple steps. 2007-01-29 02:07:34 +00:00
steve d175eb17f1 Clarify the use of ivl_scope_def for not-functions. 2007-01-29 01:52:51 +00:00
steve 2de8bafb5c Fix padding of x when literal is sized and unsigned. 2007-01-27 05:36:11 +00:00
steve 8e1c7e2891 More literal implementation of inertial delay model. 2007-01-26 05:15:41 +00:00
steve 8ae6240947 Snapshot 20070123 2007-01-24 01:24:47 +00:00
steve f77d803aeb Clean up elaboration of for-loop increment expression. 2007-01-21 04:26:36 +00:00
steve 4b829bf04f Get argument widths right for shift results. 2007-01-20 02:10:45 +00:00
steve 17a508047b Better size error details. 2007-01-20 02:09:54 +00:00
steve b350b14f93 DLL API changes for windows. 2007-01-19 23:49:33 +00:00
steve ca9da51a79 Precalculate constant power expressions, and constant function arguments. 2007-01-19 05:42:40 +00:00
steve 98417cb03a Fix calculation of verinum pow operation. 2007-01-19 05:42:04 +00:00
steve f07257067a Handle real constants in vector expressions. 2007-01-19 05:24:53 +00:00
steve e4d7eda02a Fix missing data_type mark for array words. 2007-01-19 04:26:24 +00:00
steve 4d8164945e Fix missing passive setting for array word pins. 2007-01-19 04:25:37 +00:00
steve c0954349e4 Fix bad lookaside references in vvp thread code generator. 2007-01-19 02:30:19 +00:00
steve e89b9fc25e Do not match array words in expression lookaside. 2007-01-18 00:59:48 +00:00
steve 11a83c352d Add missing array source files to CVS. 2007-01-18 00:24:10 +00:00
steve d8d7673d27 Fix typo is hello_vpi.c example. 2007-01-17 05:35:48 +00:00
steve 6f3ddce7c4 Dead code for memories in scopes. 2007-01-17 05:00:12 +00:00
steve f5a7ee0736 Remove dead code related to memories. 2007-01-17 04:39:18 +00:00
steve 91d84e7dc7 Major rework of array handling. Memories are replaced with the
more general concept of arrays. The NetMemory and NetEMemory
 classes are removed from the ivl core program, and the IVL_LPM_RAM
 lpm type is removed from the ivl_target API.
2007-01-16 05:44:14 +00:00
steve 5c3b2f4193 Snapshot 20061210 2006-12-10 17:18:56 +00:00
steve 0ae45e5644 Fix build error overloading pow function. 2006-12-10 17:15:48 +00:00
steve 296c2a575a Snapshot 20061209 2006-12-09 20:07:58 +00:00
steve 316422d93b Handle vpiRealVal reads of signals, and real anyedge events. 2006-12-09 19:06:53 +00:00
steve 2c7d2effd1 Fix an uninitialized variable warning. 2006-12-09 01:59:35 +00:00
steve 4fb5556d1c Handle very wide signed divide. 2006-12-08 19:56:09 +00:00
steve 2eeea7003e @* without inputs is an error. 2006-12-08 04:09:41 +00:00
steve d7de70bdeb Prevent name clash when processing parameter in net. 2006-12-08 03:43:26 +00:00
steve 078019ddec Parse the case of module arrays with port binding by name. 2006-12-06 05:32:36 +00:00
steve b4c3e8208f Parse bit selects in $setuphold notifiers. 2006-12-03 04:46:51 +00:00
steve 2f9a3e90ae Handle comments in file names. 2006-11-30 06:00:28 +00:00
steve 4f8a7ea84a Use new vvp_fun_XXX in place of old functor table for NAND/NOR/XNOR/EEQ. 2006-11-28 05:57:20 +00:00
steve a3da90aa4a Dump nand logic. 2006-11-28 05:56:41 +00:00
steve 48029ed8e5 Fix crash handling constant true conditional. 2006-11-27 02:01:07 +00:00
steve 94f07d16e3 Fix compile time eval of condition expresion to do reduction OR of vectors. 2006-11-26 07:10:30 +00:00
steve 041091cfac Fix nexus widths for direct link assign and ternary nets. 2006-11-26 06:29:16 +00:00
steve 0af4ea7cbe Better document the .scope record. 2006-11-23 23:02:36 +00:00
steve d6f98599f8 Do not intertangle modpaths due to references to input nets. 2006-11-23 22:42:48 +00:00
steve 2ac30824ac Fix spurious event from net8 that is forced. 2006-11-22 06:10:05 +00:00
steve 64b4e2fa01 Get the .event input from the signal instead of the signal input. 2006-11-22 06:09:08 +00:00
steve f5a204720d Support part writes into part select nodes. 2006-11-16 01:11:26 +00:00
steve 21522c90bc Process delay paths in second path over signals. 2006-11-10 05:44:44 +00:00
steve 34b5a31ff4 Add test_width methods for PETernary and PEString. 2006-11-10 04:54:26 +00:00
steve c339dc4bbc Remove last bits of relax_width methods, and use test_width
to calculate the width of an r-value expression that may
 contain unsized numbers.
2006-11-04 06:19:24 +00:00
steve ed5d3188b3 Fix padding of constant eval of NetESelect. 2006-11-04 06:16:27 +00:00
steve 8e379bd634 Handle dup of pad as well as normal select. 2006-11-04 06:10:13 +00:00
steve 841378426f Updates for Cygwin portability (pr1585922) 2006-10-30 22:45:36 +00:00
steve 2302693201 Expression widths with unsized literals are pseudo-infinite width. 2006-10-30 05:44:49 +00:00
steve 2a8b960b06 More detailed internal error message. 2006-10-15 03:25:57 +00:00
steve 0e102a94b2 Fix rendering of signed numbers in real expressions. 2006-10-10 23:54:28 +00:00
steve 168b3f2743 Fix packaging of man directories. 2006-10-09 18:56:17 +00:00
steve 0d71b1cc18 Prepare for 20061009 snapshot. 2006-10-09 18:31:56 +00:00
steve ec23bb0367 Remove dead code. 2006-10-05 01:37:34 +00:00
steve 26e2e85ffa Handle non-constant delays on indexed non-blocking assignments. 2006-10-05 01:23:53 +00:00
steve 4af28e2b77 no-specify turns of specparam elaboration. 2006-10-03 15:33:49 +00:00
steve 69cd007a71 Support real valued specify delays, properly scaled. 2006-10-03 05:06:00 +00:00
steve cbe1a6a3ca Save dep_path because arg space is overrun. 2006-10-02 18:16:18 +00:00
steve 1a0d48c346 Fix handling of dep path in new argument passing method. 2006-10-02 18:15:47 +00:00
steve 549f226c6e Modpath is input to net, draw .modpath to account. 2006-10-01 23:51:15 +00:00
steve e1f712356f Allow rosync events to create new rosync events. 2006-09-29 16:55:04 +00:00
steve 6593b603ad Modpath delay chooses correct delay for edge. 2006-09-29 03:57:01 +00:00
steve 852d10500d Man files go into /usr/share/man. 2006-09-29 01:32:17 +00:00
steve 44ca0fe798 rwsync callback fixes from Ben Staveley (with modifications.) 2006-09-29 01:24:34 +00:00
steve 35ce5f3e2a Improved mingw.txt instructions. 2006-09-28 23:45:20 +00:00
steve d6be82f748 Support selective control of specify and xtypes features. 2006-09-28 04:35:18 +00:00
steve 7e3ea2ffe8 Allow specparams as constants in expressions. 2006-09-28 00:29:49 +00:00
steve b658a3b41f Missing PSpec.cc file. 2006-09-26 19:48:40 +00:00
steve d3ceae7ee0 Accept .cpp source. 2006-09-26 18:54:42 +00:00
steve 0edb5a7547 Basic support for specify timing. 2006-09-23 04:57:19 +00:00
steve ceb6bf4afd Correct return code for vpi_put_userdata. 2006-09-22 22:33:00 +00:00
steve 0e2c6544b9 Proper error message when logic array pi count is bad. 2006-09-22 22:14:27 +00:00
steve b4893dc16f Configure scripts in general need canonical host. 2006-09-22 22:13:07 +00:00
steve f49039a3d6 Missing declaration for Windows. 2006-09-22 15:15:27 +00:00
steve 3617f0346e Bring ivl.def up to date. 2006-09-20 22:31:57 +00:00
steve f20191e6f5 tgt-verilog is not buildable for now. 2006-09-20 22:31:45 +00:00
steve 182734fd4d Remove dead code. 2006-09-20 22:31:23 +00:00
steve 431eee16e4 Do not pass -D__ICARUS__ to ivlpp. 2006-09-20 22:30:52 +00:00
steve 92cb1d4e2d Use elab_and_eval for bit select expressions. 2006-09-19 23:00:15 +00:00
steve 6f34dfc8e5 Scanf formats for character and string. 2006-08-12 04:16:07 +00:00
steve 2c7e96caec scanf support for real values. 2006-08-12 03:38:12 +00:00
steve 54c7ef72cb Snapshot 20060809 2006-08-10 01:23:29 +00:00
steve 50800fd3a1 Add support for real valued modulus. 2006-08-09 05:19:08 +00:00
steve fc0695beb6 Handle 64bit delay constants. 2006-08-08 05:11:37 +00:00
steve 00891db0d2 Fix typo in initialize of new event_time cell. 2006-08-06 18:17:00 +00:00
steve 898b0e0365 Support release of a for/linked reg. 2006-08-04 04:37:37 +00:00
steve 382c4d74fd Add the scanf functions. 2006-08-03 05:06:04 +00:00
steve 5bcf083662 Better comments for vpi_fopen function. 2006-08-03 05:05:31 +00:00
steve 1bd530c144 Fix infinite loop padding binary string to result. 2006-08-03 05:05:06 +00:00
steve 82a85131a8 Use compiletf to check arguments. 2006-08-03 05:02:46 +00:00
steve 49b65e86fe Add support for power in constant expressions. 2006-07-31 03:50:17 +00:00
steve 06d6ac4b33 Fix/implement signed right shift. 2006-07-30 02:51:35 +00:00
steve 2037650080 Pass depfiles through temp defines file. 2006-07-26 00:11:40 +00:00
steve 61f3a84557 Pass defines and includes through temp file. 2006-07-26 00:02:48 +00:00
steve ed70db84ce Handle real valued literals in net contexts. 2006-07-08 21:48:46 +00:00
steve 5348ac14a5 Delay object supports real valued delays. 2006-07-08 21:48:00 +00:00
steve aab6fefd8a Fix context determined with of constants. 2006-07-07 04:06:37 +00:00
steve 1b8e2a17c7 Change the Copyright tag to License. 2006-06-24 05:21:07 +00:00
steve 33a391cb71 Sign extend operands of signed addition. 2006-06-20 05:06:47 +00:00
steve bcc08112aa Snapshot 20060618 2006-06-18 23:56:23 +00:00
steve 80f30be9d0 Add support for system functions in continuous assignments. 2006-06-18 04:15:50 +00:00
steve 71faebd6df Make elaborate_expr methods aware of the width that the context
requires of it. In the process, fix sizing of the width of unary
 minus is context determined sizes.
2006-06-02 04:48:49 +00:00
steve 53ae1f29c9 Fix broken subtraction of small constants. 2006-06-01 03:54:51 +00:00
steve 857b3e15b6 Fix handling of ternary-to-bufif0 constant propagation. 2006-05-24 04:32:57 +00:00
steve 019d61f633 Get self-determined unary - width right. 2006-05-19 04:44:55 +00:00
steve d37b6599f4 eval_const is not strict. 2006-05-19 04:07:24 +00:00
steve 68e52ce6b7 Synchronous primitives only follow edges. 2006-05-18 05:13:45 +00:00
steve 4c885f65e1 Error message if concat expression cannot evaluate. 2006-05-17 16:49:30 +00:00
steve f0e114d59f Lexor os never interactive. 2006-05-17 04:15:12 +00:00
steve aaaa042f73 Add port list format for task arguments. 2006-05-11 03:26:57 +00:00
steve 044da54b41 Be more stubborn about widths. 2006-05-02 04:29:42 +00:00
steve a8b86ea3bb More explicit datatype setup. 2006-05-01 20:47:58 +00:00
steve e98aad1e9b Cleaner rule for parse.h and parse.cc 2006-05-01 20:47:29 +00:00
steve 1ef91f800f Forgot to invert nand output. 2006-05-01 20:47:03 +00:00
steve a19efe181b Install stub target. 2006-05-01 18:48:24 +00:00
steve 81bfbd1549 Reduce steps to make logic output. 2006-05-01 18:44:08 +00:00
steve dc2898cc73 fix net type of multiply output. 2006-05-01 05:40:21 +00:00
steve 0c9fb766b6 Get the data type of part select results right. 2006-04-30 05:17:48 +00:00
steve 10f8c66f4a Dump *all* the reduction operator gates. 2006-04-30 05:16:53 +00:00
steve 56f70ec702 Include math.h with lround implementation. 2006-04-28 15:44:37 +00:00
steve 949054e000 lround takes double, not float. 2006-04-28 15:40:30 +00:00
steve 47b72c3b74 Handle padding of MUX net results. 2006-04-28 05:09:51 +00:00
steve a2c036d5ab Allow concatenations as arguments to inout ports. 2006-04-28 04:28:35 +00:00
steve 0d17e57656 Dump indexes of ident expressions 2006-04-28 04:19:31 +00:00
steve fd94268315 Detect missing lround function. 2006-04-27 05:04:59 +00:00
steve 36039e13ec schedule takes relative, not absolute, time. 2006-04-27 04:38:00 +00:00
steve a702f99c04 Dump function type as string. 2006-04-27 04:26:38 +00:00
steve 4493e3f928 Chop down assign r-values that elaborate too wide. 2006-04-26 04:43:50 +00:00
steve 3727052000 Include bit value in assertion message. 2006-04-26 04:39:23 +00:00
steve 39ff233cf1 Detect the presence of stdint.h 2006-04-25 22:41:10 +00:00
steve 58118bddc5 Warning when file is inadequate for requested range. 2006-04-25 05:00:12 +00:00
steve c2ff3d501c Fix support for indexed part select in continuous assign l-values. 2006-04-24 05:15:07 +00:00
steve 46d86ad276 Get tail counts right in nested concatenations. 2006-04-22 04:27:36 +00:00
steve 4dd1308eb0 Parse specify ifnone statements. 2006-04-17 04:35:49 +00:00
steve a978bb1e14 Cleanup lval part select handling. 2006-04-16 00:54:04 +00:00
steve 707af782b3 Fix part selects in l-values. 2006-04-16 00:15:43 +00:00
steve fc5cf55400 Use elab_and_eval to evaluate genvar expressions. 2006-04-12 05:05:03 +00:00
steve 6a74a090f0 Configure for stub. 2006-04-10 03:07:07 +00:00
steve c448b75f2c fpga target is not installed. 2006-04-10 03:05:54 +00:00
steve aed885ecc5 Add support for generate loops w/ wires and gates. 2006-04-10 02:40:18 +00:00
steve d365c144a8 Snapshot 20060409 2006-04-10 00:54:42 +00:00
steve f001d0001a Add support for generate loops w/ wires and gates. 2006-04-10 00:37:42 +00:00
steve decfbff2b1 Clean up index expression error message. 2006-04-10 00:32:14 +00:00
steve 3e45f4302b Be more accepting of the protect directive. 2006-03-30 05:44:36 +00:00
steve 77a0d7f4db task/function ports can have types. 2006-03-30 05:22:34 +00:00
steve e8efa6df53 Fix instance arrays indexed by overridden parameters. 2006-03-30 01:49:07 +00:00
steve 276f2d0032 Accept attributes in front of module instantiations. 2006-03-25 02:42:58 +00:00
steve 13a660b591 Get rid of excess PESTring:: prefix within class declaration. 2006-03-25 02:36:26 +00:00
steve f4a44df2cc Support more parameter syntax. 2006-03-18 22:53:38 +00:00
steve 5b3ba8c306 Properly handle signedness in compare. 2006-03-18 22:52:27 +00:00
steve 8defa4bcd0 Syntax for carrying sign with parameter. 2006-03-18 22:51:10 +00:00
steve dabdcf0fc9 const/non-const clash. 2006-03-15 19:15:34 +00:00
steve 8ff70410ab Handle multiple part/bi devices connected together. 2006-03-15 05:52:20 +00:00
steve 6f46d12e07 Add support for logic parameters. 2006-03-08 05:29:42 +00:00
steve 5f5a6b5396 Cleanup vpi_const to use vec4 values. 2006-03-06 05:43:15 +00:00
steve 1b911ad87a Add support for memory value change callbacks. 2006-03-05 05:45:58 +00:00
steve b0b614ae0e Some trivial log message improvements. 2006-02-22 03:08:53 +00:00
steve 9c16c34422 Put strings for reg objects. 2006-02-21 05:31:54 +00:00
steve 170e57d662 Callbacks for named event triggers. 2006-02-21 04:57:26 +00:00
steve 065f342278 Remove dead code. 2006-02-21 03:19:03 +00:00
steve a721586acb Get vpiVectorVal from memory words. 2006-02-21 02:56:49 +00:00
steve 50ad415c0d Support string values for memory words. 2006-02-21 02:39:27 +00:00
steve 4ba2afbbe1 Use g++ linker if there are C++ source files. 2006-02-21 02:38:44 +00:00
steve d3f89e0d4f Clean up makefiles to remove unsupported targets. 2006-02-15 18:42:42 +00:00
steve 457cf15b3b Snapshot 20060215 2006-02-15 18:00:33 +00:00
steve d0de678d57 real-to-integer conversions round, not truncate. 2006-02-02 05:48:45 +00:00
steve fa6e4a69a6 Parse more cases of (*). 2006-02-02 05:21:45 +00:00
steve d434dd7296 Allow part selects of memory words in l-values. 2006-02-02 02:43:57 +00:00
steve 3158e2caa1 Snapshot 20060124 2006-01-25 02:16:11 +00:00
steve e1ce72e245 Support wide divide nodes. 2006-01-03 06:19:31 +00:00
steve 368c27c9e4 Handle complex net node delays. 2006-01-03 05:22:14 +00:00
steve a4116efd57 Fix the return type of a synthesized divide. 2006-01-03 05:15:33 +00:00
steve 58f182a159 Node delays can be more general expressions in structural contexts. 2006-01-02 05:33:19 +00:00
steve b7861fa6e8 Require explicit delay node from source. 2006-01-02 05:32:06 +00:00
steve 1721799050 Document binary expression use. 2005-12-22 15:44:29 +00:00
steve df226c5d13 pad_to_width handles signed expressions. 2005-12-22 15:43:47 +00:00
steve e9bf00dff6 Pad part selects 2005-12-22 15:42:22 +00:00
steve c071cc1bbe More detailed check of binary expressions. 2005-12-22 15:38:33 +00:00
steve 101b373293 Allow constant concat expressions. 2005-12-07 04:04:23 +00:00
steve 5cf64dfa70 Include stdint.h if it is present. 2005-12-07 03:43:30 +00:00
steve 1021e5acc8 Fixes for stubborn compilers. 2005-12-05 21:21:18 +00:00
steve 4f7e7a2296 Some systems donot have stding.h? 2005-12-05 21:20:55 +00:00
steve 0c73f209de Be more careful with double types. 2005-12-05 21:19:55 +00:00
steve 0873c52474 vpi_signal supports vvp_fun_signal_vec types. 2005-11-30 00:42:14 +00:00
steve 64d46630e0 Snapshot 20051127 2005-11-27 17:53:28 +00:00
steve 8ed504b064 Fix for stubborn compiler. 2005-11-27 17:01:56 +00:00
steve 6161904bf8 Fix type safety warning from gcc. 2005-11-27 16:47:14 +00:00
steve 908955c72c Handle bit select of parameter with ranges. 2005-11-27 05:56:20 +00:00
steve bab70ccbed Handle indexed l-value to force. 2005-11-26 17:23:17 +00:00
steve 2b8fd28a95 Force instruction that can be indexed. 2005-11-26 17:16:05 +00:00
steve 0e044d6684 More precise about r-value width of constants. 2005-11-26 00:35:42 +00:00
steve 7efa6be236 stop/continue messages go through MCD for logging. 2005-11-25 18:35:38 +00:00
steve 35951510c5 Put vec8 and vec4 nets into seperate net classes. 2005-11-25 17:55:26 +00:00
steve 3f108f08ed Dump IVL_ST_DELAYX statements. 2005-11-20 15:58:53 +00:00
steve 244844c067 Document the IVL_ST_DELAY statements. 2005-11-20 15:58:25 +00:00
steve b416ae047b Fix compile warning. 2005-11-14 22:11:52 +00:00
steve c02b3b8ac6 Reorganize signal part select handling, and add support for
indexed part selects.

 Expand expression constant propagation to eliminate extra
 sums in certain cases.
2005-11-10 13:28:11 +00:00
steve bebcc05aab Handle very wide % and / operations using expanded vector2 support. 2005-11-10 13:27:16 +00:00
steve 8d49abf967 Document the MUXZ functor. 2005-11-10 13:25:31 +00:00
steve c87223170b Prepare for snapshot 20051012 2005-10-13 03:04:06 +00:00
steve 8e2898e51a Fix compile of net/real aliases. 2005-10-12 17:28:07 +00:00
steve 9c8c541f5d MUX nodes get inputs from nets, not from net inputs,
Detect and draw alias nodes to reduce net size and
 handle force confusion.
2005-10-12 17:26:17 +00:00
steve 3cdf655c79 force l-values do not support bit/part select. 2005-10-12 17:26:01 +00:00
steve 560c5a2584 Add alias nodes. 2005-10-12 17:23:15 +00:00
steve c75f0a930e Remove the $ from signal labels. They do not help. 2005-10-11 18:54:10 +00:00
steve bb3f3c1f46 Remove obsolete vvp_memory_label function. 2005-10-11 18:30:50 +00:00
steve 07f345da4d Logical or/and return VT_LOGIC type. 2005-10-11 16:15:52 +00:00
steve fb22bcc96b Remove dead dram_input_from_net and lpm_inputs_a_b 2005-10-10 04:16:13 +00:00
steve 2842a65fd1 Make sure the new size sticks in resize method. 2005-10-04 04:41:07 +00:00
steve a652719876 Add support for indexed select attached to parameters. 2005-10-04 04:09:25 +00:00
steve 16dc3ab4d4 Error message for invalid for-loop index variable. 2005-09-27 04:51:37 +00:00
steve cf85c19f7b Simplify NexusSet set handling. 2005-09-25 23:40:11 +00:00
steve 01a6dd61ca Support put_value of string values. 2005-09-21 01:04:59 +00:00
steve bf8b085159 Clean up compiler warnings. 2005-09-20 18:34:01 +00:00
steve ee22550047 Lazy processing of vvp_fun_part functor. 2005-09-20 00:51:53 +00:00
steve 2b07c7a685 Prevent some excess scheduling of logic propagation events. 2005-09-19 22:47:28 +00:00
steve be73be8c98 Spelling patches from Larry. 2005-09-19 21:45:35 +00:00
steve e2a1b90b12 Use lazy eval of BUF/NOT/OR/XOR gates. 2005-09-19 21:45:09 +00:00
steve d22d88923d Fix warnings about uninitialized variables. 2005-09-19 20:18:20 +00:00
steve 2729d6cd2e Include vvp_config.h instead of config.h 2005-09-19 20:17:59 +00:00
steve 21af0dbe3f Fix data type of parameters to logic. 2005-09-19 15:21:09 +00:00
steve c4d8ab8509 Improve loading of part selects when easy. 2005-09-17 04:01:32 +00:00
steve 988a0a7048 Add the load/v.p instruction. 2005-09-17 04:01:01 +00:00
steve 672aa61ae7 More robust use of precalculated expressions, and
Separate lookaside for written variables that can
 also be reused.
2005-09-17 01:01:00 +00:00
steve 7235706923 Make sure div, mod and mult nodes have line number info. 2005-09-15 23:04:09 +00:00
steve a256613fa6 Fix bug configuring NetModulo pins. 2005-09-15 22:54:47 +00:00
steve 5ec7dde52f Use iostream instead of stdio. 2005-09-15 22:54:04 +00:00
steve 19a1ae8d4f Preserve precalculated expressions when possible. 2005-09-15 02:50:13 +00:00
steve 14d79a655e Better reuse of IVL_EX_SELECT expressions. 2005-09-15 02:49:47 +00:00
steve 293976bacc Spelling fixes. 2005-09-15 02:30:09 +00:00
steve 4dfdc147c5 fit type elaboration of logical not. 2005-09-14 15:15:44 +00:00
steve c946f27d9b Add b0 and b1 edges to parser. 2005-09-14 15:01:07 +00:00
steve 9fd16575d9 Support bool expressions and compares handle them optimally. 2005-09-14 02:53:13 +00:00
steve b9c0b8aa79 Add an extensions.txt file. 2005-09-14 02:51:13 +00:00
steve 65584e6dde Add word integer compares. 2005-09-14 02:50:07 +00:00
steve c39976fbf1 Generate code to handle real valued muxes. 2005-09-01 04:11:37 +00:00
steve 4902c222fb Check operand types for compatibility. 2005-09-01 04:10:47 +00:00
steve ad761069c7 Support MUXR functors. 2005-09-01 04:08:47 +00:00
steve b69f59f2ec Handle memory references is continuous assignments. 2005-08-31 05:07:31 +00:00
steve 3ff2488d4f Clean up a few overflowed shifts. 2005-08-30 00:49:42 +00:00
steve efd7825964 minor correction to address check in of_MOV1XZ 2005-08-30 00:49:21 +00:00
steve 70f146924a Safe handling of C left shift. 2005-08-29 04:46:52 +00:00
steve 7c19eb51e7 Minor cleanup. 2005-08-29 04:46:13 +00:00
steve 6f839aa5df Eliminate int to vvp_bit4_t casts. 2005-08-29 02:38:50 +00:00
steve dac11c2468 Handle synthesis of fully packed case statements. 2005-08-27 04:32:08 +00:00
steve 5cf2ce6499 Fix bit destination address in of_AND 2005-08-27 03:28:57 +00:00
steve 73453996a9 Be more cautios about accessing out-of-range bits. 2005-08-27 03:28:16 +00:00
steve bc489a7761 Bring threads into the vvp_vector4_t structure. 2005-08-27 02:34:42 +00:00
steve 4a8be3db9c Implement bi-directional part selects. 2005-08-06 17:58:16 +00:00
steve 8232b621f1 Fix parse errors related to pr766. 2005-07-27 14:54:51 +00:00
steve 4cbffc6b77 bufif enable is LOGIC. 2005-07-15 19:22:52 +00:00
steve 9a16e030b5 Match data type of PV select input/output. 2005-07-15 04:13:25 +00:00
steve d353ddb660 Get output type correct for binary mux (ternary) expression. 2005-07-15 00:42:02 +00:00
steve bc9f286954 More debug information. 2005-07-15 00:41:09 +00:00
steve fde4ff72f6 Display as version 0.9.devel 2005-07-14 23:38:43 +00:00
steve a8d49921ee gcc4 compile errors. 2005-07-14 23:34:18 +00:00
steve 9cae53988a Dump function call expression node. 2005-07-14 16:15:13 +00:00
steve 559a1fd359 Remove the .word statement. 2005-07-13 04:58:29 +00:00
steve 5bfdd52391 Handle functions with real values. 2005-07-13 04:52:31 +00:00
steve b094ccc3f7 Functions get type from their output signal. 2005-07-13 04:51:36 +00:00
steve b9799cf6ec Remove NetVariable and ivl_variable_t structures. 2005-07-11 16:56:50 +00:00
steve 75ad90534b Generalize signals to carry types. 2005-07-07 16:22:49 +00:00
steve 3ac79c294a Implement real valued signals and arith nodes. 2005-07-06 04:29:25 +00:00
steve e7f3340513 Remove reference to SystemVerilog. 2005-06-28 04:25:55 +00:00
steve 60b9121c6c Make vector2 multiply more portable. 2005-06-27 21:13:14 +00:00
steve e3f300f4c2 AND functor explicitly knows its width. 2005-06-26 21:08:38 +00:00
steve 1c6be44724 More verbose debugging of part select width errors. 2005-06-26 21:08:11 +00:00
steve 6bf7556d65 Check width of part select based on direction. 2005-06-26 18:09:24 +00:00
steve c46f978dbb Fix uninitialzied attr pointers for UDP devices. 2005-06-26 18:08:46 +00:00
steve 9cac88330b AND gates propogate through scheduler, not directly. 2005-06-26 18:06:29 +00:00
steve de1dd2f2b3 Make bit masks of vector4_t 64bit aware. 2005-06-26 01:57:22 +00:00
steve 6c8e1f7834 inline the vvp_send_vec4_pv function. 2005-06-24 02:16:42 +00:00
steve b58705b829 Inline more simple stuff, and more vector4_t by const reference for performance. 2005-06-22 18:30:12 +00:00
steve 7091915b73 Reduce vvp_vector4 copies by using const references. 2005-06-22 00:04:48 +00:00
steve 5513974b78 Optimize vvp_scalar_t handling, and fun_buf Z handling. 2005-06-21 22:48:23 +00:00
steve ad78af2f91 Inline some commonly called vvp_vector4_t methods. 2005-06-20 01:28:14 +00:00
steve 1b30bac9f3 Optimize the LOAD_VEC implementation. 2005-06-19 18:42:00 +00:00
steve 66a579dd67 Handle signed display of unsigned signals. 2005-06-18 15:55:21 +00:00
steve 094dd7e4de threads member for waitable_hook_s needs initailizing. 2005-06-17 23:47:02 +00:00
steve 3b91db96cd Support set of IntVal to memory words. 2005-06-17 05:13:07 +00:00
steve 657ac8168e Debug messages. 2005-06-17 05:06:47 +00:00
steve a79fee39e9 Watch out for signed constants in magnitude compare. 2005-06-17 05:05:53 +00:00
steve 4cc421b3b7 Make functors know their own width. 2005-06-17 03:46:52 +00:00
steve 290c604c62 Fix bit offsets when processing lval concatenation. 2005-06-15 01:33:33 +00:00
steve 466ab5c2c7 Resolv do not propogate inputs that do not change. 2005-06-15 00:47:15 +00:00
steve 4ba195282d gcc3/4 compile errors. 2005-06-14 19:13:43 +00:00
steve cd14ee77ae Add the assign_v0_d instruction. 2005-06-14 01:44:09 +00:00
steve 21c7abf090 Accomodate fussy compilers. 2005-06-14 00:42:06 +00:00
steve 4413dd3c81 Fix compile errors. 2005-06-13 23:22:37 +00:00
steve 73f3589ea6 use NetPartSelect to shrink part from high bits. 2005-06-13 23:22:14 +00:00
steve 9278dad244 Make synthesized padding vector-aware. 2005-06-13 22:26:03 +00:00
steve a0dce80eba Document ivl_logic_delay function. 2005-06-13 22:25:37 +00:00
steve af5f713c0f Dump delays for logic devices. 2005-06-13 22:20:38 +00:00
steve 80cac983c6 More unified vec4 to hex string functions. 2005-06-13 00:54:04 +00:00
steve f5ba93eeb6 Remove unused ft_MOS truth tables. 2005-06-12 21:56:16 +00:00
steve 668781788b Support resistive mos devices. 2005-06-12 15:13:37 +00:00
steve 86729f52ca Remove functor classes, no longer needed. 2005-06-12 01:42:20 +00:00
steve fb8ddbbfde Remove useless references to functor.h 2005-06-12 01:25:27 +00:00
steve 2736859d8f Remove useless references to functor.h 2005-06-12 01:10:26 +00:00
steve a59f3b1fa6 Implement nmos and pmos devices. 2005-06-12 00:44:49 +00:00
steve dd4f765b06 Remove unneeded references to functor.h 2005-06-11 18:11:18 +00:00
steve f465bca305 UD delays use delay node. 2005-06-11 16:21:08 +00:00
steve cb967c10fe Handle all edge types of a synchronous UDP. 2005-06-11 02:04:48 +00:00
steve 3607fb584d Support UDP initial values. 2005-06-09 05:04:45 +00:00
steve 77792dcc2f Support sequential UDP devices. 2005-06-09 04:12:30 +00:00
steve 2f7ec71a78 Support %force/link 2005-06-02 16:03:47 +00:00
steve 42433f4df9 Add support for notif0/1 gates.
Make delay nodes support inertial delay.
 Add the %force/link instruction.
2005-06-02 16:02:11 +00:00
steve aa2e178667 Handle event/or with specific, efficient nodes. 2005-05-25 05:44:51 +00:00
steve 015d280c6a Handle assignments to part-select l-values. 2005-05-24 02:31:18 +00:00
steve 739a1839ed Do sign extension of structuran nets. 2005-05-24 01:44:27 +00:00
steve b6fd4f610b Add a sign-extension node. 2005-05-24 01:43:27 +00:00
steve 06e08dbdf0 Make sure comparison widths match. 2005-05-19 03:51:38 +00:00
steve 28168e0f57 Fixup structural GT comparators. 2005-05-18 03:46:01 +00:00
steve 7796c8bcfb Parameters cannot have their width changed. 2005-05-17 20:56:55 +00:00
steve 82be4ab189 Detect bit selects that need special handling. 2005-05-17 20:55:42 +00:00
steve 3a8e2e688d Clean up definition of vvp_vector4_t insertion into ostream. 2005-05-17 20:54:56 +00:00
steve 037ab9efe9 Document real behavior of set/v instruction. 2005-05-17 20:54:00 +00:00
steve d6a89a40cf Clean up instruction type reverences to bits. 2005-05-17 20:51:06 +00:00
steve 3bd09d1470 synthesis of Logic and shifts using vector gates. 2005-05-15 04:47:00 +00:00
steve d0ade1d082 Debug text. 2005-05-15 04:45:50 +00:00
steve fcb02ee9c2 Disable obsolete logic constant fixup code. 2005-05-15 04:44:30 +00:00
steve 870395e627 Move functor delays to vvp_delay_fun object. 2005-05-14 19:43:23 +00:00
steve c701fb615b Give buffers support for simple delays. 2005-05-13 05:13:12 +00:00
steve adbe734b6c Some debug messages. 2005-05-13 05:12:39 +00:00
steve c34e44dad0 Make sig-eq-constant optimization more effective. 2005-05-10 05:10:40 +00:00
steve 5a2dd3393f Skip assign if index is invalid. 2005-05-09 00:38:12 +00:00
steve ed78c5b677 Force part base out of bounds if index is invalid. 2005-05-09 00:36:58 +00:00
steve 7dd0d255a6 Add support for variable part select. 2005-05-08 23:40:14 +00:00
steve 48aa0f0075 Better handle assignment to bit/part select. 2005-05-07 03:16:31 +00:00
steve 5277124c76 Implement non-blocking part assign. 2005-05-07 03:15:42 +00:00
steve f6da64e2ec ostream insert for vvp_vector4_t objects. 2005-05-07 03:14:50 +00:00
steve 06816e79fe Clarify internal delays for assignments. 2005-05-07 03:14:00 +00:00
steve a1d899112a Include delay expressions for assignments in dump. 2005-05-07 03:13:30 +00:00
steve d548c9a5f8 Handle synthesis of concatenation expressions. 2005-05-06 00:25:13 +00:00
steve 2894cdefc7 Add cassign/link instruction. 2005-05-01 22:05:21 +00:00
steve df271c9fa3 Link signals that are source of procedural continuous assign. 2005-05-01 22:04:12 +00:00
steve 99aff5f10b Remove dead functor code. 2005-04-28 04:59:53 +00:00
steve e9bf021f6c vvp_fun_signal eliminates duplicate propagations. 2005-04-25 04:42:17 +00:00
steve aed8474944 Reimplement basic asynchronous processes. 2005-04-25 01:35:58 +00:00
steve af7e196518 synthesis of add and unary get vector widths right. 2005-04-25 01:30:31 +00:00
steve 365cfedd55 Update DFF support to new data flow. 2005-04-24 23:44:01 +00:00
steve f884652c19 Add DFF nodes. 2005-04-24 20:07:25 +00:00
steve 6244dc1194 Make logic aware of strength. 2005-04-13 06:35:11 +00:00
steve a3f696cd06 Add vvp driver functor for logic outputs,
Add ostream output operators for debugging.
2005-04-13 06:34:20 +00:00
steve 061fdf5a0d scalars with 0-drivers are hiZ by definition. 2005-04-09 06:00:58 +00:00
steve fe91ebe77c Default behavior for recv_vec8 methods. 2005-04-09 05:30:38 +00:00
steve e8a6835d36 Make clear that memory addresses are cannonical. 2005-04-08 04:52:31 +00:00
steve 800e2c6a17 All memory addresses are signed. 2005-04-08 04:51:16 +00:00
steve 29fa9e7321 Don not give to make_add express an unwanted width. 2005-04-08 04:50:31 +00:00
steve 65c7ec00e7 Rework NetRamDq and IVL_LPM_RAM nodes. 2005-04-06 05:29:08 +00:00
steve d62661257a Generate the right coes for unconnected UDP port. 2005-04-04 05:29:53 +00:00
steve c5cf77dc7e Support row level wildcards. 2005-04-04 05:13:59 +00:00
steve 20d3a8508e Remove dead fvectors class. 2005-04-03 06:13:34 +00:00
steve f16b69c1e5 Remove dead fvectors class. 2005-04-03 06:13:34 +00:00
steve 573e07225d Rework the vvp_delay_t class. 2005-04-03 05:45:51 +00:00
steve 236ff2b278 Clean up handle of UDPs. 2005-04-01 06:04:30 +00:00
steve b7ef2fcb0a Reimplement combinational UDPs. 2005-04-01 06:02:45 +00:00
steve becda0e26c popen must be matched by pclose. 2005-03-22 15:53:48 +00:00
steve d8a456bd67 The indexed set can write a vector, not just a bit. 2005-03-22 05:18:34 +00:00
steve 8184dfaed8 Handle wide operands to logical AND. 2005-03-19 06:59:53 +00:00
steve ca488dff4e Handle LPM shifts. 2005-03-19 06:23:49 +00:00
steve 23925b636e vvp.conf files are generated. 2005-03-18 02:57:23 +00:00
steve 53da6e9a33 Add support for LPM_UFUNC user defined functions. 2005-03-18 02:56:03 +00:00
steve 0f914bf35a UPdate elabrate continuous assighn of string to net. 2005-03-13 01:26:48 +00:00
steve f556452403 Handle function/task port vectors. 2005-03-12 23:45:33 +00:00
steve ab1ca54df2 Update support for LPM_MOD. 2005-03-12 06:43:35 +00:00
steve bae8507c90 Implement .arith/mod. 2005-03-12 06:42:28 +00:00
steve 313502f360 Implement VPI access to signal strengths,
Fix resolution of ambiguous drive pairs,
 Fix spelling of scalar.
2005-03-12 04:27:42 +00:00
steve 1c5b4881d7 Handle case inequality in netlists. 2005-03-09 05:52:03 +00:00
steve 53af2949b4 Generate code for new form of memory ports. 2005-03-09 04:53:40 +00:00
steve 789c95b1c1 reimplement memory ports. 2005-03-09 04:52:40 +00:00
steve 72240c460e Remove dead code from scheduler. 2005-03-06 17:25:03 +00:00
steve 8e135a1020 Non blocking assign to memory words. 2005-03-06 17:07:48 +00:00
steve 0fb1fd36ee Handle memory words in l-value concatenations. 2005-03-05 05:47:42 +00:00
steve e7c2e06260 Check that lead.mv vector width matches word. 2005-03-05 05:45:18 +00:00
steve 73997f813c Get read width of unitialized memory words right. 2005-03-05 05:44:32 +00:00
steve 75af32bd3c Get base address from word ranges that VPI user passed. 2005-03-05 05:43:03 +00:00
steve 4ccbb4f0b2 Get rval width right for arguments into task calls. 2005-03-05 05:38:33 +00:00
steve 85286cc086 Rearrange how memories are supported as vvp_vector4 arrays. 2005-03-03 04:33:10 +00:00
steve 04604188df Clock compression fix from Tony. 2005-02-19 16:45:01 +00:00
steve f7dc4307bd Fix duplicate delete from pr1073. 2005-02-19 16:44:38 +00:00
steve 257e1f9516 Support shifts and divide. 2005-02-19 02:43:38 +00:00
steve 5fe5d9184d Handle signed divide. 2005-02-19 02:41:23 +00:00
steve 589eb1d315 Implement .arith/div. 2005-02-19 01:32:52 +00:00
steve 2fcaac4060 Support constant part select writes to l-values, and large part select reads from signals. 2005-02-15 07:12:55 +00:00
steve 4051f7d986 Handle bitmux lvalues for constant r-values. 2005-02-14 05:00:11 +00:00
steve 02d0719529 l-value input may be a vector. 2005-02-14 04:58:50 +00:00
steve aaf35ab1a9 Handle bit selects in l-values to assignments. 2005-02-14 01:51:39 +00:00
steve c5e7e2ec0a Signals may receive part vectors from %set/x0
instructions. Re-implement the %set/x0 to do
 just that. Remove the useless %set/x0/x instruction.
2005-02-14 01:50:23 +00:00
steve ff067bb959 tri0 and tri1 resolvers must replace HiZ with 0/1 after resolution. 2005-02-13 05:26:30 +00:00
steve 1d7235b4f1 Replace supply nets with wires connected to pullup/down supply devices. 2005-02-13 01:15:07 +00:00
steve 97e0723bd1 Cleanup unused truth tables. 2005-02-12 23:05:25 +00:00
steve d4eb4d38bc Implement a-b muxes as vector devices 2005-02-12 22:54:29 +00:00
steve d00e3fc9a9 Check IVL_LPM_MUX configuration. 2005-02-12 22:53:41 +00:00
steve 9ec00e1288 Fix copyright notice. 2005-02-12 22:52:45 +00:00
steve 85d9ebded8 Implement the vvp_fun_muxz functor. 2005-02-12 22:50:52 +00:00
steve d74177634c Restructure NetMux devices to pass vectors.
Generate NetMux devices from ternary expressions,
 Reduce NetMux devices to bufif when appropriate.
2005-02-12 06:25:40 +00:00
steve eca4f4fa97 Draw C4 and C8 constants to account for strength. 2005-02-12 06:25:15 +00:00
steve 6b7b82758a Check nexus widths of IVL_LO_ nodes. 2005-02-12 06:17:43 +00:00
steve 355ead0002 Add debug dumps for vectors, and fix vvp_scaler_t make from BIT4_X values. 2005-02-12 06:13:22 +00:00
steve 4fce321900 Support C8 constants. 2005-02-12 03:27:18 +00:00
steve 2e6d2f8e98 Support scheduling vvp_vector8_t objects. 2005-02-12 03:26:14 +00:00
steve 55b5bf9d39 distinguish between single port namy instances, and single instances many sub-ports. 2005-02-10 04:56:58 +00:00
steve 1979fca239 Get the C4 width right for undriven nexa. 2005-02-10 04:55:45 +00:00
steve a0583ef124 Simplify vvp_scaler strength representation. 2005-02-10 04:54:41 +00:00
steve ee5bb5fcaf Add the NetRepeat node, and code generator support. 2005-02-08 00:12:36 +00:00
steve ca1bbc79a3 Add .repeat functor and BIFIF functors. 2005-02-07 22:42:42 +00:00
steve e74127e1fc Support .concat with arbitrary input counts. 2005-02-04 05:13:57 +00:00
steve b48abb2148 Add wide .arith/mult, and vvp_vector2_t vectors. 2005-02-04 05:13:02 +00:00
steve 97f83ffbe3 laborate reduction gates into LPM_RED_ nodes. 2005-02-03 04:56:20 +00:00
steve 018014368b Add support for reduction logic gates. 2005-02-03 04:55:13 +00:00
steve 20be0351ae Elaborate unary subtract and NOT in netlist
contexts, and concatenation too.
2005-01-30 05:20:38 +00:00
steve 68a788221e Support LPM_SUB 2005-01-30 05:09:04 +00:00
steve 84b3e8e2dc Get .arith/sub working. 2005-01-30 05:06:49 +00:00
steve e6cdd32c19 Clarify width argument to NetNet constructor. 2005-01-30 01:43:48 +00:00
steve c23a35a033 Debug messages for PGAssign elaboration. 2005-01-30 01:42:05 +00:00
steve 609b6a7baa Netlist boolean expressions generate gate vectors. 2005-01-29 18:46:18 +00:00
steve 0609c5f18c Use scheduler to initialize constant functor inputs. 2005-01-29 17:53:25 +00:00
steve d51503ffd8 move AND to buitin instead of table. 2005-01-29 17:52:06 +00:00
steve 7625a6c3e7 Check width of constant attached to nexus. 2005-01-29 16:47:52 +00:00
steve 695718d691 Clarify width of nexus. 2005-01-29 16:47:20 +00:00
steve e04fb5c083 Elaborate parameter reference to desired width without concats. 2005-01-29 16:46:22 +00:00
steve 07f64bc603 Support interactive mode even without readline. 2005-01-29 06:29:17 +00:00
steve bf3679b7d4 Add the -s flag to start up interactive. 2005-01-29 06:28:19 +00:00
steve ade5bdcafe Integrate pr1072 fix from v0_8-branch. 2005-01-29 00:37:06 +00:00
steve 7250337941 Integrate fixes from 0.8 branch. 2005-01-28 19:39:03 +00:00
steve 99ace10774 Simplified NetMult and IVL_LPM_MULT. 2005-01-28 05:39:33 +00:00
steve 6be34bba4d Special handling of constant shift 0. 2005-01-28 05:37:48 +00:00
steve a5b431ad20 Show the lpm_mult device. 2005-01-28 05:36:18 +00:00
steve a121e703f3 Add vector4 implementation of .arith/mult. 2005-01-28 05:34:25 +00:00
steve dfb7c7ba6f Remove the NetEBitSel and combine all bit/part select
behavior into the NetESelect node and IVL_EX_SELECT
 ivl_target expression type.
2005-01-24 05:28:30 +00:00
steve edeb9d8eca Part selects are done in the compiler, not here. 2005-01-24 05:08:02 +00:00
steve 14f557e6f4 Check widths of ternary expressions. 2005-01-24 05:05:25 +00:00
steve 25de448d34 Remove obsolete NetSubnet class. 2005-01-22 18:16:00 +00:00
steve cb4e0d4724 stub dump signed flags of magnitude compare. 2005-01-22 17:36:59 +00:00
steve 6a23f16860 .cmp/x supports signed magnitude compare. 2005-01-22 17:36:15 +00:00
steve a4710f375e LPM_CMP_NE/EQ are vectored devices. 2005-01-22 16:22:13 +00:00
steve 6c5e840617 Implement vectored CMP_EQ and NE 2005-01-22 16:21:11 +00:00
steve e28636776a Change case compare from logic to an LPM node. 2005-01-22 01:06:55 +00:00
steve b86fdd6bbc Implement the .cmp/eeq LPM node. 2005-01-22 01:06:20 +00:00
steve 1d1dda5a5d Implement the %load/x instruction. 2005-01-22 00:58:22 +00:00
steve 3222031970 Add missing concat.cc to cvs 2005-01-22 00:01:09 +00:00
steve bf6a5d0f50 Implement LPM_COMPARE nodes as two-input vector functors. 2005-01-16 04:20:32 +00:00
steve 1c3668ea7f Reimplement comparators as vvp_vector4_t nodes. 2005-01-16 04:19:08 +00:00
steve ead2481793 Fix elaboration of == compared to constants. 2005-01-13 00:23:10 +00:00
steve fcaaec0464 More robust input code generation for LPM_ADD. 2005-01-12 05:31:50 +00:00
steve 4d139b58aa Properly pad vector widths in pgassign. 2005-01-12 03:17:36 +00:00
steve 8c18c9152d More complete drawing of concat inputs. 2005-01-12 03:16:35 +00:00
steve 399dfe5c44 Handle concatenations with up to 16 inputs. 2005-01-10 01:42:59 +00:00
steve 9e94afe399 Use PartSelect/PV and VP to handle part selects through ports. 2005-01-09 20:16:00 +00:00
steve 6c711ee4d8 Merge $fopen robustness fix from 0.8 2005-01-09 20:12:22 +00:00
steve 9735b0e8b3 Add the .part/pv node and related functionality. 2005-01-09 20:11:15 +00:00
steve d5c33420ab vvp_fun_signal propagates vvp_vector8_t vectors when appropriate. 2005-01-01 02:12:34 +00:00
steve 34a14b983b Implement .resolv functors, and stub signals recv_vec8 method. 2004-12-31 06:00:06 +00:00
steve d1e2538aba No need to draw BUF or BUFZ tables. 2004-12-31 05:57:25 +00:00
steve 8bfc75d1ee Add specific BUFZ functor. 2004-12-31 05:56:36 +00:00
steve b1b93f860c Fix uninitialized fun pointer for resolver nodes. 2004-12-31 05:54:46 +00:00
steve 8f2d679c8a Unify elaboration of l-values for all proceedural assignments,
including assing, cassign and force.

 Generate NetConcat devices for gate outputs that feed into a
 vector results. Use this to hande gate arrays. Also let gate
 arrays handle vectors of gates when the outputs allow for it.
2004-12-29 23:55:43 +00:00
steve 83423c978b Generate code for the .concat functors, from NetConcat objects.
Generate C<> constants of correct widths for functor arguments.
2004-12-29 23:52:09 +00:00
steve 1674d692b7 Add the part concatenation node (.concat).
Add a vvp_event_anyedge class to handle the special
 case of .event statements of edge type. This also
 frees the posedge/negedge types to handle all 4 inputs.

 Implement table functor recv_vec4 method to receive
 and process vectors.
2004-12-29 23:45:13 +00:00
steve 7166598ed0 Fix missing output propagation of part node. 2004-12-29 23:44:39 +00:00
steve 5eb25e44e1 Add ivl_event_scope, and better document ivl_event_X methods. 2004-12-18 18:56:18 +00:00
steve 59566158c4 Better detail on event trigger and wait statements. 2004-12-18 18:55:08 +00:00
steve e11ac0b1d8 Use %set/v to trigger events. 2004-12-18 18:53:26 +00:00
steve 8939467ac5 Rework named events and event/or. 2004-12-18 18:52:44 +00:00
steve 26d97558c4 Replace single release with release/net and release/reg. 2004-12-17 04:47:47 +00:00
steve 59bac26f4f Implement release functionality. 2004-12-17 04:46:40 +00:00
steve 78dda42493 Add the force/v instruction. 2004-12-15 17:17:42 +00:00
steve 36f36bd2ac Add basic force/release capabilities. 2004-12-15 17:16:08 +00:00
steve 0193daa436 Display the release statement details. 2004-12-15 17:11:13 +00:00
steve 4444079409 Fixup force statement elaboration. 2004-12-15 17:10:40 +00:00
steve 3947d7dd33 Force r-value padded to width. 2004-12-15 17:09:11 +00:00
steve 7973dad9f5 Arrange statement dumping in new source files. 2004-12-12 18:15:06 +00:00
steve d19e76a193 Fix r-value width of continuous assign. 2004-12-12 18:13:39 +00:00
steve ffedf32476 cassign and deassign handle concatenated l-values. 2004-12-11 05:43:30 +00:00
steve 527ddea811 Add stub conf files to cvs. 2004-12-11 04:22:35 +00:00
steve 65e9b6be12 Rework of internals to carry vectors through nexus instead
of single bits. Make the ivl, tgt-vvp and vvp initial changes
 down this path.
2004-12-11 02:31:25 +00:00
269 changed files with 39348 additions and 18904 deletions
+1
View File
@@ -17,6 +17,7 @@ configure
Makefile
check
check.cc
check.vvp
config.status
config.log
config.cache
+5 -2
View File
@@ -104,7 +104,7 @@ module may not be needed as long as the ``-s <name>'' switch is
given.
So when you send a test case, ask yourself "Can poor overworked Steve
invoke the error without any Verilog other then what is included?" And
invoke the error without any Verilog other than what is included?" And
while we are at it, please place a copyright notice in your test
program and include a GPL license statement if you can. Your test
program may find its way into the test suite, and the notices will
@@ -160,8 +160,11 @@ I must insist that any copyright material submitted for inclusion
include the GPL license notice as shown in the rest of the source.
$Id: BUGS.txt,v 1.4 2003/02/19 04:36:31 steve Exp $
$Id: BUGS.txt,v 1.5 2007/03/22 16:08:14 steve Exp $
$Log: BUGS.txt,v $
Revision 1.5 2007/03/22 16:08:14 steve
Spelling fixes from Larry
Revision 1.4 2003/02/19 04:36:31 steve
Notes on hte bug database.
+58 -186
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: HName.cc,v 1.5 2002/11/02 03:27:52 steve Exp $"
#ident "$Id: HName.cc,v 1.8 2007/06/02 03:42:12 steve Exp $"
#endif
# include "config.h"
@@ -29,235 +29,107 @@
# include <malloc.h>
#endif
hname_t::hname_t()
{
item_ = 0;
count_ = 0;
number_ = INT_MIN;
}
hname_t::hname_t(const char*text)
hname_t::hname_t(perm_string text)
{
item_ = strdup(text);
count_ = 1;
name_ = text;
number_ = INT_MIN;
}
hname_t::hname_t(perm_string text, int num)
{
name_ = text;
number_ = num;
}
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;
}
name_ = that.name_;
number_ = that.number_;
}
hname_t& hname_t::operator = (const hname_t&that)
{
name_ = that.name_;
number_ = that.number_;
return *this;
}
hname_t::~hname_t()
{
switch (count_) {
case 0:
break;
case 1:
free(item_);
break;
default:
for (unsigned idx = 0 ; idx < count_ ; idx += 1)
free(array_[idx]);
delete[]array_;
break;
}
}
unsigned hname_t::component_count() const
perm_string hname_t::peek_name(void) const
{
return count_;
return name_;
}
void hname_t::append(const char*text)
bool hname_t::has_number() const
{
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;
}
return number_ != INT_MIN;
}
void hname_t::prepend(const char*text)
int hname_t::peek_number() const
{
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];
}
return number_;
}
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)
int cmp = strcmp(l.peek_name(), r.peek_name());
if (cmp < 0) return true;
if (cmp > 0) return false;
if (l.has_number() && r.has_number())
return l.peek_number() < r.peek_number();
else
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 (l.peek_name() == r.peek_name()) {
if (l.has_number() && r.has_number())
return l.peek_number() == r.peek_number();
else
return true;
}
if (lc || rc)
return false;
// Must be ==
return true;
return false;
}
bool operator != (const hname_t&l, const hname_t&r)
{ return ! (l==r); }
ostream& operator<< (ostream&out, const hname_t&that)
{
switch (that.count_) {
case 0:
if (that.peek_name() == 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;
}
out << that.peek_name();
if (that.has_number())
out << "[" << that.peek_number() << "]";
return out;
}
/*
* $Log: HName.cc,v $
* Revision 1.8 2007/06/02 03:42:12 steve
* Properly evaluate scope path expressions.
*
* Revision 1.7 2007/05/16 19:12:33 steve
* Fix hname_t use of space for 1 perm_string.
*
* Revision 1.6 2007/04/26 03:06:21 steve
* Rework hname_t to use perm_strings.
*
* Revision 1.5 2002/11/02 03:27:52 steve
* Allow named events to be referenced by
* hierarchical names.
+31 -33
View File
@@ -1,7 +1,7 @@
#ifndef __HName_H
#define __HName_H
/*
* Copyright (c) 2001 Stephen Williams ([email protected])
* Copyright (c) 2001-2007 Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -19,10 +19,11 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: HName.h,v 1.4 2002/11/02 03:27:51 steve Exp $"
#ident "$Id: HName.h,v 1.7 2007/06/02 03:42:12 steve Exp $"
#endif
# include <iostream>
# include "StringHeap.h"
#ifdef __GNUC__
#if __GNUC__ > 2
using namespace std;
@@ -30,59 +31,56 @@ using namespace std;
#endif
/*
* This class represents a Verilog hierarchical name. A hierarchical
* name is an ordered list of simple names.
* This class represents a component of a Verilog hierarchical name. A
* hierarchical component contains a name string (prepresented here
* with a perm_string) and an optional signed number. This signed
* number is used if the scope is part of an array, for example an
* array of module instances or a loop generated scope.
*/
class hname_t {
public:
hname_t ();
explicit hname_t (const char*text);
explicit hname_t (perm_string text);
explicit hname_t (perm_string text, int num);
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);
hname_t& operator= (const hname_t&);
// 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);
// Return the string part of the hname_t.
perm_string peek_name(void) const;
// This method removes the tail name from the hierarchy, and
// returns a pointer to that tail name. That tail name now
// must be removed by the caller.
char* remove_tail_name();
// Return the given component in the hierarchical name. If the
// idx is too large, return 0.
const char*peek_name(unsigned idx) const;
const char*peek_tail_name() const;
// Return the number of components in the hierarchical
// name. If this is a simple name, this will return 1.
unsigned component_count() const;
friend ostream& operator<< (ostream&, const hname_t&);
bool has_number() const;
int peek_number() const;
private:
union {
char**array_;
char* item_;
};
unsigned count_;
perm_string name_;
// If the number is anything other then INT_MIN, then this is
// the numeric part of the name. Otherwise, it is not part of
// the name at all.
int number_;
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&);
extern bool operator != (const hname_t&, const hname_t&);
extern ostream& operator<< (ostream&, const hname_t&);
/*
* $Log: HName.h,v $
* Revision 1.7 2007/06/02 03:42:12 steve
* Properly evaluate scope path expressions.
*
* Revision 1.6 2007/05/16 19:12:33 steve
* Fix hname_t use of space for 1 perm_string.
*
* Revision 1.5 2007/04/26 03:06:21 steve
* Rework hname_t to use perm_strings.
*
* Revision 1.4 2002/11/02 03:27:51 steve
* Allow named events to be referenced by
* hierarchical names.
+6 -1
View File
@@ -19,11 +19,13 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: LineInfo.h,v 1.7 2003/01/17 05:49:03 steve Exp $"
#ident "$Id: LineInfo.h,v 1.8 2005/06/14 19:13:43 steve Exp $"
#endif
# include <string>
using namespace std;
/*
* This class holds line information for an internal object.
*
@@ -52,6 +54,9 @@ class LineInfo {
/*
* $Log: LineInfo.h,v $
* Revision 1.8 2005/06/14 19:13:43 steve
* gcc3/4 compile errors.
*
* Revision 1.7 2003/01/17 05:49:03 steve
* Use stringstream in place of sprintf.
*
+26 -36
View File
@@ -16,7 +16,7 @@
# 59 Temple Place - Suite 330
# Boston, MA 02111-1307, USA
#
#ident "$Id: Makefile.in,v 1.169 2004/10/13 22:01:34 steve Exp $"
#ident "$Id: Makefile.in,v 1.181 2007/05/24 04:07:11 steve Exp $"
#
#
SHELL = /bin/sh
@@ -25,7 +25,7 @@ SHELL = /bin/sh
# by the compiler. It reflects the assigned version number for the
# product as a whole. Most components also print the CVS Name: token
# in order to get a more automatic version stamp as well.
VERSION = 0.8
VERSION = 0.9.devel
prefix = @prefix@
exec_prefix = @exec_prefix@
@@ -43,7 +43,6 @@ mandir = @mandir@
libdir64 = @libdir64@
dllib=@DLLIB@
strip_dynamic=@strip_dynamic@
CC = @CC@
CXX = @CXX@
@@ -51,7 +50,6 @@ INSTALL = @INSTALL@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
STRIP = @STRIP@
LEX = @LEX@
YACC = @YACC@
@@ -60,21 +58,15 @@ CXXFLAGS = -Wall @CXXFLAGS@
PICFLAGS = @PICFLAG@
LDFLAGS = @rdynamic@ @LDFLAGS@
# The TARGETS variable lists the target modules that can be build and
# installed. Some of them depend on external things, so are only
# compiled if the prerequisites are installed.
TARGETS = tgt-null
all: dep ivl@EXEEXT@
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) $@); done
for tgt in $(TARGETS); do (cd $$tgt ; $(MAKE) $@); done
for dir in ivlpp tgt-verilog tgt-stub; \
for dir in ivlpp ; \
do (cd $$dir ; $(MAKE) $@); done
cd driver ; $(MAKE) VERSION=$(VERSION) $@
# In the windows world, the installer will need a dosify program to
# dosify text files.
ifeq (@WIN32@,yes)
ifeq (@MING32@,yes)
all: dep dosify.exe
dosify.exe: dosify.c
$(CC) -o dosify.exe dosify.c
@@ -90,36 +82,37 @@ check: all
clean:
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) $@); done
for tgt in $(TARGETS); do (cd $$tgt ; $(MAKE) $@); done
for dir in vpi ivlpp tgt-verilog tgt-stub driver; \
for dir in vpi ivlpp tgt-verilog tgt-pal driver driver-vpi; \
do (cd $$dir ; $(MAKE) $@); done
rm -f *.o parse.cc parse.cc.output parse.h lexor.cc
rm -f ivl.exp iverilog-vpi.pdf iverilog-vpi.ps parse.output
rm -f syn-rules.output dosify.exe ivl@EXEEXT@ check.vvp
rm -f lexor_keyword.cc libivl.a libvpi.a iverilog-vpi syn-rules.cc*
rm -rf dep ivl@EXEEXT@
rm -rf dep
distclean: clean
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) $@); done
for tgt in $(TARGETS); do (cd $$tgt ; $(MAKE) $@); done
for dir in vpi ivlpp tgt-verilog tgt-stub driver; \
for dir in vpi ivlpp tgt-verilog tgt-pal driver driver-vpi; \
do (cd $$dir ; $(MAKE) $@); done
rm -f Makefile config.status config.log config.cache config.h
rm -f _pli_types.h
TT = t-dll.o t-dll-api.o t-dll-expr.o t-dll-proc.o t-xnf.o
FF = cprop.o nodangle.o synth.o synth2.o syn-rules.o xnfio.o
TT = t-dll.o t-dll-api.o t-dll-expr.o t-dll-proc.o
FF = cprop.o nodangle.o synth.o synth2.o syn-rules.o
O = main.o async.o design_dump.o dup_expr.o elaborate.o elab_expr.o \
elab_lval.o elab_net.o elab_anet.o elab_pexpr.o elab_scope.o \
elab_lval.o elab_net.o elab_pexpr.o elab_scope.o \
elab_sig.o emit.o eval.o eval_attrib.o \
eval_tree.o expr_synth.o functor.o lexor.o lexor_keyword.o link_const.o \
load_module.o netlist.o netmisc.o net_assign.o \
net_design.o net_event.o net_expr.o net_force.o net_func.o \
net_link.o net_modulo.o net_nex_input.o net_nex_output.o \
net_proc.o net_scope.o net_udp.o net_variable.o pad_to_width.o \
parse.o parse_misc.o pform.o pform_dump.o \
net_proc.o net_scope.o net_udp.o pad_to_width.o \
parse.o parse_misc.o pform.o pform_dump.o pform_types.o \
set_width.o symbol_search.o sync.o sys_funcs.o \
verinum.o verireal.o target.o targets.o \
Attrib.o HName.o LineInfo.o Module.o PData.o PDelays.o PEvent.o \
PExpr.o PGate.o \
Attrib.o HName.o LineInfo.o Module.o PDelays.o PEvent.o \
PExpr.o PGate.o PGenerate.o PSpec.o \
PTask.o PUdp.o PFunction.o PWire.o Statement.o StringHeap.o \
$(FF) $(TT)
@@ -136,11 +129,10 @@ 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@ ivl.exp $O $(dllib) @EXTRALIBS@
$(CXX) $(LDFLAGS) -o ivl@EXEEXT@ ivl.exp $O $(dllib) @EXTRALIBS@
else
ivl@EXEEXT@: $O
$(CXX) $(LDFLAGS) -o ivl@EXEEXT@ $O $(dllib)
endif
ifeq (@MINGW32@,yes)
@@ -150,6 +142,9 @@ all: dep iverilog-vpi
iverilog-vpi: iverilog-vpi.sh
sed -e 's;@SHARED@;@shared@;' -e 's;@PIC@;@PICFLAG@;' \
-e 's;@IVCC@;$(CC);' \
-e 's;@IVCXX@;$(CXX);' \
-e 's;@IVCFLAGS@;$(CXXFLAGS);' \
-e 's;@INCLUDEDIR@;@includedir@;' \
-e 's;@LIBDIR64@;@libdir64@;' \
-e 's;@VPIDIR1@;@vpidir1@;' -e 's;@VPIDIR2@;@vpidir2@;' \
@@ -169,10 +164,8 @@ lexor.o: lexor.cc parse.h
parse.o: parse.cc
parse.cc: $(srcdir)/parse.y
parse.cc parse.h: $(srcdir)/parse.y
$(YACC) --verbose -t -p VL -d -o parse.cc $(srcdir)/parse.y
parse.h: parse.cc
mv parse.cc.h parse.h 2>/dev/null || mv parse.hh parse.h
syn-rules.cc: $(srcdir)/syn-rules.y
@@ -192,7 +185,7 @@ iverilog-vpi.ps: $(srcdir)/iverilog-vpi.man
iverilog-vpi.pdf: iverilog-vpi.ps
ps2pdf iverilog-vpi.ps iverilog-vpi.pdf
ifeq (@WIN32@,yes)
ifeq (@MING32@,yes)
INSTALL_DOC = $(prefix)/iverilog-vpi.pdf $(mandir)/man1/iverilog-vpi.1
INSTALL_DOCDIR = $(mandir)/man1
all: dep iverilog-vpi.pdf
@@ -209,9 +202,8 @@ endif
XNF_INSTALL = $(libdir)/ivl/xnf.conf $(libdir)/ivl/xnf-s.conf
install: all installdirs $(libdir)/ivl/ivl@EXEEXT@ $(includedir)/ivl_target.h $(includedir)/_pli_types.h $(includedir)/vpi_user.h $(includedir)/acc_user.h $(includedir)/veriuser.h $(WIN32_INSTALL) $(INSTALL_DOC) $(XNF_INSTALL)
install: all installdirs $(libdir)/ivl/ivl@EXEEXT@ $(includedir)/ivl_target.h $(includedir)/_pli_types.h $(includedir)/vpi_user.h $(includedir)/acc_user.h $(includedir)/veriuser.h $(WIN32_INSTALL) $(INSTALL_DOC)
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) $@); done
for tgt in $(TARGETS); do (cd $$tgt ; $(MAKE) $@); done
for dir in vpi ivlpp driver; \
do (cd $$dir ; $(MAKE) $@); done
@@ -220,7 +212,6 @@ $(bindir)/iverilog-vpi: ./iverilog-vpi
$(libdir)/ivl/ivl@EXEEXT@: ./ivl@EXEEXT@
$(INSTALL_PROGRAM) ./ivl@EXEEXT@ $(libdir)/ivl/ivl@EXEEXT@
$(STRIP) $(strip_dynamic) $(libdir)/ivl/ivl@EXEEXT@
$(libdir)/ivl/xnf-s.conf: $(srcdir)/xnf-s.conf
$(INSTALL_DATA) $(srcdir)/xnf-s.conf $(libdir)/ivl/xnf-s.conf
@@ -275,17 +266,16 @@ installdirs: mkinstalldirs
uninstall:
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) $@); done
for tgt in $(TARGETS); do (cd $$tgt ; $(MAKE) $@); done
for dir in vpi ivlpp driver; \
do (cd $$dir ; $(MAKE) $@); done
for f in xnf.conf xnf-s.conf ivl; \
for f in xnf.conf xnf-s.conf ivl@EXEEXT@; \
do rm -f $(libdir)/ivl/$$f; done
-rmdir $(libdir)/ivl
for f in verilog iverilog-vpi gverilog@EXEEXT@; \
do rm -f $(bindir)/$$f; done
for f in ivl_target.h vpi_user.h _pli_types.h acc_user.h veriuser.h; \
do rm -f $(includedir)/$$f; done
rm -f $(mandir)/man1/iverilog-vpi.1
rm -f $(mandir)/man1/iverilog-vpi.1 $(prefix)/iverilog-vpi.pdf
-include $(patsubst %.o, dep/%.d, $O)
+11 -8
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: Module.cc,v 1.25 2004/10/04 01:10:51 steve Exp $"
#ident "$Id: Module.cc,v 1.27 2007/05/24 04:07:11 steve Exp $"
#endif
# include "config.h"
@@ -31,6 +31,7 @@
Module::Module(perm_string n)
: name_(n)
{
library_flag = false;
default_nettype = NetNet::NONE;
}
@@ -110,9 +111,9 @@ unsigned Module::find_port(const char*name) const
}
PWire* Module::get_wire(const hname_t&name) const
PWire* Module::get_wire(const pform_name_t&name) const
{
map<hname_t,PWire*>::const_iterator obj = wires_.find(name);
map<pform_name_t,PWire*>::const_iterator obj = wires_.find(name);
if (obj == wires_.end())
return 0;
else
@@ -132,11 +133,6 @@ PGate* Module::get_gate(perm_string name)
return 0;
}
const map<hname_t,PWire*>& Module::get_wires() const
{
return wires_;
}
const list<PGate*>& Module::get_gates() const
{
return gates_;
@@ -150,6 +146,13 @@ const list<PProcess*>& Module::get_behaviors() const
/*
* $Log: Module.cc,v $
* Revision 1.27 2007/05/24 04:07:11 steve
* Rework the heirarchical identifier parse syntax and pform
* to handle more general combinations of heirarch and bit selects.
*
* Revision 1.26 2007/04/19 02:52:53 steve
* Add support for -v flag in command file.
*
* Revision 1.25 2004/10/04 01:10:51 steve
* Clean up spurious trailing white space.
*
+38 -45
View File
@@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: Module.h,v 1.37 2004/06/13 04:56:53 steve Exp $"
#ident "$Id: Module.h,v 1.43 2007/05/24 04:07:11 steve Exp $"
#endif
# include <list>
@@ -30,11 +30,13 @@
# include "named.h"
# include "LineInfo.h"
# include "netlist.h"
class PData;
# include "pform_types.h"
class PEvent;
class PExpr;
class PEIdent;
class PGate;
class PGenerate;
class PSpecPath;
class PTask;
class PFunction;
class PWire;
@@ -67,6 +69,12 @@ class Module : public LineInfo {
explicit Module(perm_string name);
~Module();
/* Initially false. This is set to true if the module has been
declared as a library module. This makes the module
ineligible for being chosen as an implicit root. It has no
other effect. */
bool library_flag;
NetNet::Type default_nettype;
/* The module has parameters that are evaluated when the
@@ -91,7 +99,7 @@ class Module : public LineInfo {
new parameters within the module, but may be used to set
values within this module (when instantiated) or in other
instantiated modules. */
map<hname_t,PExpr*>defparms;
map<pform_name_t,PExpr*>defparms;
/* Parameters may be overridden at instantiation time;
the overrides do not contain explicit parameter names,
@@ -108,15 +116,22 @@ class Module : public LineInfo {
/* Keep a table of named events declared in the module. */
map<perm_string,PEvent*>events;
/* Keep a table of datum variables declared in the module. */
map<hname_t,PData*>datum;
map<perm_string,PExpr*> attributes;
/* These are the timescale for this module. The default is
set by the `timescale directive. */
int time_unit, time_precision;
/* The module has a list of genvars that may be used in
various generate schemes. */
list<perm_string> genvars;
/* the module has a list of generate schemes that appear in
the module definition. These are used at elaboration time. */
list<PGenerate*> generate_schemes;
list<PSpecPath*> specify_paths;
perm_string mod_name() const { return name_; }
void add_gate(PGate*gate);
@@ -136,24 +151,24 @@ class Module : public LineInfo {
// Find a wire by name. This is used for connecting gates to
// existing wires, etc.
PWire* get_wire(const hname_t&name) const;
PWire* get_wire(const pform_name_t&name) const;
PGate* get_gate(perm_string name);
const map<hname_t,PWire*>& get_wires() const;
const list<PGate*>& get_gates() const;
const list<PProcess*>& get_behaviors() const;
void dump(ostream&out) const;
bool elaborate(Design*, NetScope*scope) const;
bool elaborate_scope(Design*, NetScope*scope) const;
typedef map<perm_string,NetExpr*> replace_t;
bool elaborate_scope(Design*, NetScope*scope, const replace_t&rep) const;
bool elaborate_sig(Design*, NetScope*scope) const;
private:
perm_string name_;
map<hname_t,PWire*> wires_;
map<pform_name_t,PWire*> wires_;
list<PGate*> gates_;
list<PProcess*> behaviors_;
map<perm_string,PTask*> tasks_;
@@ -167,45 +182,23 @@ class Module : public LineInfo {
/*
* $Log: Module.h,v $
* Revision 1.37 2004/06/13 04:56:53 steve
* Add support for the default_nettype directive.
* Revision 1.43 2007/05/24 04:07:11 steve
* Rework the heirarchical identifier parse syntax and pform
* to handle more general combinations of heirarch and bit selects.
*
* Revision 1.36 2004/05/25 19:21:06 steve
* More identifier lists use perm_strings.
* Revision 1.42 2007/04/19 02:52:53 steve
* Add support for -v flag in command file.
*
* Revision 1.35 2004/02/20 18:53:33 steve
* Addtrbute keys are perm_strings.
* Revision 1.41 2006/09/23 04:57:19 steve
* Basic support for specify timing.
*
* Revision 1.34 2004/02/20 06:22:56 steve
* parameter keys are per_strings.
* Revision 1.40 2006/04/10 00:37:42 steve
* Add support for generate loops w/ wires and gates.
*
* Revision 1.33 2004/02/18 17:11:54 steve
* Use perm_strings for named langiage items.
* Revision 1.39 2006/03/30 01:49:07 steve
* Fix instance arrays indexed by overridden parameters.
*
* Revision 1.32 2003/06/20 00:53:19 steve
* Module attributes from the parser
* through to elaborated form.
*
* Revision 1.31 2003/06/13 19:10:45 steve
* Properly manage real variables in subscopes.
*
* Revision 1.30 2003/03/06 04:37:12 steve
* lex_strings.add module names earlier.
*
* Revision 1.29 2003/02/27 06:45:11 steve
* specparams as far as pform.
*
* Revision 1.28 2003/01/26 21:15:58 steve
* Rework expression parsing and elaboration to
* accommodate real/realtime values and expressions.
*
* Revision 1.27 2002/08/19 02:39:16 steve
* Support parameters with defined ranges.
*
* Revision 1.26 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.25 2002/05/19 23:37:28 steve
* Parse port_declaration_lists from the 2001 Standard.
* Revision 1.38 2005/07/11 16:56:50 steve
* Remove NetVariable and ivl_variable_t structures.
*/
#endif
-63
View File
@@ -1,63 +0,0 @@
#ifndef __PData_H
#define __PData_H
/*
* Copyright (c) 2003 Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: PData.h,v 1.1 2003/01/26 21:15:58 steve Exp $"
#endif
# include "HName.h"
# include "netlist.h"
# include "LineInfo.h"
/*
* The PData object represents declaration of atomic datum such as
* real and realtime variables. These are variables that cannot be bit
* or part selected, but can be used in expressions.
*/
class PData : public LineInfo {
public:
PData(const hname_t&hname);
~PData();
// Return a hierarchical name.
const hname_t&name() const;
void elaborate_scope(Design*des, NetScope*scope) const;
map<string,PExpr*> attributes;
private:
hname_t hname_;
private:
PData(const PData&);
PData& operator= (const PData&);
};
/*
* $Log: PData.h,v $
* Revision 1.1 2003/01/26 21:15:58 steve
* Rework expression parsing and elaboration to
* accommodate real/realtime values and expressions.
*
*/
#endif
+52 -15
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: PDelays.cc,v 1.11 2003/06/21 01:21:42 steve Exp $"
#ident "$Id: PDelays.cc,v 1.15 2006/07/08 21:48:46 steve Exp $"
#endif
# include "config.h"
@@ -62,11 +62,10 @@ void PDelays::set_delays(const svector<PExpr*>*del, bool df)
delete_flag_ = df;
}
static unsigned long calculate_val(Design*des, NetScope*scope,
const PExpr*expr)
static NetExpr*calculate_val(Design*des, NetScope*scope, const PExpr*expr)
{
NetExpr*dex = expr->elaborate_expr(des, scope);
NetExpr*dex = expr->elaborate_expr(des, scope, -1, false);
if (NetExpr*tmp = dex->eval_tree()) {
delete dex;
dex = tmp;
@@ -85,7 +84,9 @@ static unsigned long calculate_val(Design*des, NetScope*scope,
delay = 0;
delete tmp;
return delay;
NetEConst*tmp2 = new NetEConst(verinum(delay));
tmp2->set_line(*expr);
return tmp2;
}
@@ -96,35 +97,57 @@ static unsigned long calculate_val(Design*des, NetScope*scope,
des->scale_to_precision(fn.as_ulong(), scope);
delete tmp;
return delay;
NetEConst*tmp2 = new NetEConst(verinum(delay));
tmp2->set_line(*expr);
return tmp2;
}
/* Oops, cannot evaluate down to a constant. Error message. */
delete dex;
/* Oops, cannot evaluate down to a constant. */
return dex;
}
cerr << expr->get_line() << ": sorry: non-constant "
<< "delays not supported here: " << *expr << endl;
des->errors += 1;
return 0;
static NetExpr* make_delay_nets(Design*des, NetExpr*expr)
{
if (dynamic_cast<NetESignal*> (expr))
return expr;
if (dynamic_cast<NetEConst*> (expr))
return expr;
NetNet*sig = expr->synthesize(des);
if (sig == 0) {
cerr << expr->get_line() << ": error: Expression " << *expr
<< " is not suitable for delay expression." << endl;
return 0;
}
expr = new NetESignal(sig);
return expr;
}
void PDelays::eval_delays(Design*des, NetScope*scope,
unsigned long&rise_time,
unsigned long&fall_time,
unsigned long&decay_time) const
NetExpr*&rise_time,
NetExpr*&fall_time,
NetExpr*&decay_time,
bool as_nets_flag) const
{
assert(scope);
if (delay_[0]) {
rise_time = calculate_val(des, scope, delay_[0]);
if (as_nets_flag)
rise_time = make_delay_nets(des, rise_time);
if (delay_[1]) {
fall_time = calculate_val(des, scope, delay_[1]);
if (as_nets_flag)
fall_time = make_delay_nets(des, fall_time);
if (delay_[2]) {
decay_time = calculate_val(des, scope, delay_[2]);
if (as_nets_flag)
decay_time = make_delay_nets(des, decay_time);
} else {
if (rise_time < fall_time)
@@ -146,6 +169,20 @@ void PDelays::eval_delays(Design*des, NetScope*scope,
/*
* $Log: PDelays.cc,v $
* Revision 1.15 2006/07/08 21:48:46 steve
* Handle real valued literals in net contexts.
*
* Revision 1.14 2006/06/02 04:48:49 steve
* Make elaborate_expr methods aware of the width that the context
* requires of it. In the process, fix sizing of the width of unary
* minus is context determined sizes.
*
* Revision 1.13 2006/01/03 05:22:14 steve
* Handle complex net node delays.
*
* Revision 1.12 2006/01/02 05:33:19 steve
* Node delays can be more general expressions in structural contexts.
*
* Revision 1.11 2003/06/21 01:21:42 steve
* Harmless fixup of warnings.
*
+12 -4
View File
@@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: PDelays.h,v 1.7 2002/08/12 01:34:58 steve Exp $"
#ident "$Id: PDelays.h,v 1.9 2006/01/03 05:22:14 steve Exp $"
#endif
# include "svector.h"
@@ -34,6 +34,7 @@ using namespace std;
class Design;
class NetScope;
class NetExpr;
class PExpr;
/*
@@ -53,9 +54,10 @@ class PDelays {
void set_delays(const svector<PExpr*>*del, bool delete_flag=true);
void eval_delays(Design*des, NetScope*scope,
unsigned long&rise_time,
unsigned long&fall_time,
unsigned long&decay_time) const;
NetExpr*&rise_time,
NetExpr*&fall_time,
NetExpr*&decay_time,
bool as_nets_flag =false) const;
void dump_delays(ostream&out) const;
@@ -72,6 +74,12 @@ ostream& operator << (ostream&o, const PDelays&);
/*
* $Log: PDelays.h,v $
* Revision 1.9 2006/01/03 05:22:14 steve
* Handle complex net node delays.
*
* Revision 1.8 2006/01/02 05:33:19 steve
* Node delays can be more general expressions in structural contexts.
*
* Revision 1.7 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
+67 -16
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: PExpr.cc,v 1.35 2004/10/04 01:10:51 steve Exp $"
#ident "$Id: PExpr.cc,v 1.39 2007/05/24 04:07:11 steve Exp $"
#endif
# include "config.h"
@@ -53,6 +53,14 @@ NetNet* PExpr::elaborate_lnet(Design*des, NetScope*, bool) const
return 0;
}
NetNet* PExpr::elaborate_bi_net(Design*des, NetScope*) const
{
cerr << get_line() << ": error: "
<< "expression not valid as argument to inout port: "
<< *this << endl;
return 0;
}
PEBinary::PEBinary(char op, PExpr*l, PExpr*r)
: op_(op), left_(l), right_(r)
{
@@ -67,13 +75,44 @@ bool PEBinary::is_constant(Module*mod) const
return left_->is_constant(mod) && right_->is_constant(mod);
}
PECallFunction::PECallFunction(const hname_t&n, const svector<PExpr *> &parms)
PEBComp::PEBComp(char op, PExpr*l, PExpr*r)
: PEBinary(op, l, r)
{
}
PEBComp::~PEBComp()
{
}
PEBShift::PEBShift(char op, PExpr*l, PExpr*r)
: PEBinary(op, l, r)
{
}
PEBShift::~PEBShift()
{
}
PECallFunction::PECallFunction(const pform_name_t&n, const svector<PExpr *> &parms)
: path_(n), parms_(parms)
{
}
PECallFunction::PECallFunction(const hname_t&n)
: path_(n)
static pform_name_t pn_from_ps(perm_string n)
{
name_component_t tmp_name (n);
pform_name_t tmp;
tmp.push_back(tmp_name);
return tmp;
}
PECallFunction::PECallFunction(perm_string n, const svector<PExpr*>&parms)
: path_(pn_from_ps(n)), parms_(parms)
{
}
PECallFunction::PECallFunction(perm_string n)
: path_(pn_from_ps(n))
{
}
@@ -139,33 +178,32 @@ bool PEFNumber::is_constant(Module*) const
return true;
}
PEIdent::PEIdent(const hname_t&s)
: path_(s), msb_(0), lsb_(0), idx_(0)
PEIdent::PEIdent(const pform_name_t&that)
: path_(that)
{
}
PEIdent::PEIdent(perm_string s)
{
path_.push_back(name_component_t(s));
}
PEIdent::~PEIdent()
{
}
const hname_t& PEIdent::path() const
{
return path_;
}
/*
* An identifier can be in a constant expression if (and only if) it is
* a parameter.
*
* NOTE: This test does not work if the name is hierarchical!
*/
bool PEIdent::is_constant(Module*mod) const
{
if (mod == 0) return false;
/* This is a work-around for map not matching < even when
there is a perm_string operator that can do the comprare.
The real fix is to make the path_ carry perm_strings. */
perm_string tmp = perm_string::literal(path_.peek_name(0));
/* */
perm_string tmp = path_.back().name;
{ map<perm_string,Module::param_expr_t>::const_iterator cur;
cur = mod->parameters.find(tmp);
@@ -262,6 +300,19 @@ bool PEUnary::is_constant(Module*m) const
/*
* $Log: PExpr.cc,v $
* Revision 1.39 2007/05/24 04:07:11 steve
* Rework the heirarchical identifier parse syntax and pform
* to handle more general combinations of heirarch and bit selects.
*
* Revision 1.38 2006/10/30 05:44:49 steve
* Expression widths with unsized literals are pseudo-infinite width.
*
* Revision 1.37 2005/10/04 04:09:25 steve
* Add support for indexed select attached to parameters.
*
* Revision 1.36 2005/08/06 17:58:16 steve
* Implement bi-directional part selects.
*
* Revision 1.35 2004/10/04 01:10:51 steve
* Clean up spurious trailing white space.
*
+368 -114
View File
@@ -19,13 +19,15 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: PExpr.h,v 1.66 2004/10/04 01:10:51 steve Exp $"
#ident "$Id: PExpr.h,v 1.90 2007/06/04 19:14:06 steve Exp $"
#endif
# include <string>
# include <vector>
# include "netlist.h"
# include "verinum.h"
# include "LineInfo.h"
# include "pform_types.h"
class Design;
class Module;
@@ -50,11 +52,38 @@ class PExpr : public LineInfo {
virtual void dump(ostream&) const;
// Procedural elaboration of the expression. Set the
// bare_memory_ok flag if the result is allowed to be a
// NetEMemory without an index.
// This method tests the width that the expression wants to
// be. It is used by elaboration of assignments to figure out
// the width of the expression.
//
// The "min" is the width of the local context, so it the
// minimum width that this function should return. Initially
// this is the same as the lval width.
//
// The "lval" is the width of the destination where this
// result is going to go. This can be used to constrain the
// amount that an expression can reasonably expand. For
// example, there is no point expanding an addition to beyond
// the lval. This extra bit of information allows the
// expression to optimize itself a bit. If the lval==0, then
// the subexpression should not make l-value related
// optimizations.
//
// The unsigned_flag is set to true if the expression is
// unsized and therefore expandable. This happens if a
// sub-expression is an unsized literal. Some expressions make
// special use of that.
virtual unsigned test_width(Design*des, NetScope*scope,
unsigned min, unsigned lval,
bool&unsized_flag) const;
// Procedural elaboration of the expression. The expr_width is
// the width of the context of the expression (i.e. the
// l-value width of an assignment) or -1 if the expression is
// self-determinted. The sys_task_arg flag is true if
// expressions are allowed to be incomplete.
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
bool sys_task_arg =false) const;
int expr_width, bool sys_task_arg) const;
// Elaborate expressions that are the r-value of parameter
// assignments. This elaboration follows the restrictions of
@@ -66,30 +95,37 @@ class PExpr : public LineInfo {
// continuous assign or other wholly structural context.
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
unsigned lwidth,
unsigned long rise,
unsigned long fall,
unsigned long decay,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay,
Link::strength_t drive0 =Link::STRONG,
Link::strength_t drive1 =Link::STRONG)
const;
// This method elaborates the expression as NetNet objects. It
// only allows regs suitable for procedural continuous assignments.
virtual NetNet* elaborate_anet(Design*des, NetScope*scope) const;
// This method elaborates the expression as gates, but
// restricted for use as l-values of continuous assignments.
virtual NetNet* elaborate_lnet(Design*des, NetScope*scope,
bool implicit_net_ok =false) const;
// This is similar to elaborate_lnet, except that the
// expression is evaluated to be bi-directional. This is
// useful for arguments to inout ports of module instances and
// ports of tran primitives.
virtual NetNet* elaborate_bi_net(Design*des, NetScope*scope) const;
// Expressions that can be in the l-value of procedural
// assignments can be elaborated with this method.
virtual NetAssign_* elaborate_lval(Design*des, NetScope*scope) const;
// assignments can be elaborated with this method. If the
// is_force flag is true, then the set of valid l-value types
// is slightly modified to accomodate the Verilog force
// statement
virtual NetAssign_* elaborate_lval(Design*des,
NetScope*scope,
bool is_force) const;
// This attempts to evaluate a constant expression, and return
// a verinum as a result. If the expression cannot be
// evaluated, return 0.
virtual verinum* eval_const(const Design*des, const NetScope*sc) const;
virtual verinum* eval_const(Design*des, NetScope*sc) const;
// This method returns true if that expression is the same as
// this expression. This method is used for comparing
@@ -115,27 +151,31 @@ class PEConcat : public PExpr {
PEConcat(const svector<PExpr*>&p, PExpr*r =0);
~PEConcat();
virtual verinum* eval_const(Design*des, NetScope*sc) const;
virtual void dump(ostream&) const;
// Concatenated Regs can be on the left of procedural
// continuous assignments.
virtual NetNet* elaborate_anet(Design*des, NetScope*scope) const;
virtual NetNet* elaborate_lnet(Design*des, NetScope*scope,
bool implicit_net_ok =false) const;
virtual NetNet* elaborate_bi_net(Design*des, NetScope*scope) const;
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
unsigned width,
unsigned long rise,
unsigned long fall,
unsigned long decay,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay,
Link::strength_t drive0,
Link::strength_t drive1) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
bool sys_task_arg =false) const;
int expr_width, bool sys_task_arg) const;
virtual NetEConcat*elaborate_pexpr(Design*des, NetScope*) const;
virtual NetAssign_* elaborate_lval(Design*des, NetScope*scope) const;
virtual NetAssign_* elaborate_lval(Design*des,
NetScope*scope,
bool is_force) const;
virtual bool is_constant(Module*) const;
private:
NetNet* elaborate_lnet_common_(Design*des, NetScope*scope,
bool implicit_net_ok,
bool bidirectional_flag) const;
private:
svector<PExpr*>parms_;
PExpr*repeat_;
@@ -182,15 +222,23 @@ 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 NetScope*sc) const;
virtual verinum* eval_const(Design*des, NetScope*sc) const;
/* A PEFNumber is a constant, so this returns true. */
virtual bool is_constant(Module*) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
bool sys_task_arg =false) const;
int expr_width, bool sys_task_arg) const;
virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
unsigned lwidth,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay,
Link::strength_t drive0,
Link::strength_t drive1) const;
virtual void dump(ostream&) const;
private:
@@ -200,32 +248,41 @@ class PEFNumber : public PExpr {
class PEIdent : public PExpr {
public:
explicit PEIdent(const hname_t&s);
explicit PEIdent(perm_string);
explicit PEIdent(const pform_name_t&);
~PEIdent();
virtual void dump(ostream&) const;
// Add another name to the string of heirarchy that is the
// current identifier.
void append_name(perm_string);
// Regs can be on the left of procedural continuous assignments
virtual NetNet* elaborate_anet(Design*des, NetScope*scope) const;
virtual void dump(ostream&) const;
virtual unsigned test_width(Design*des, NetScope*scope,
unsigned min, unsigned lval,
bool&unsized_flag) const;
// Identifiers are allowed (with restrictions) is assign l-values.
virtual NetNet* elaborate_lnet(Design*des, NetScope*scope,
bool implicit_net_ok =false) const;
virtual NetNet* elaborate_bi_net(Design*des, NetScope*scope) const;
// Identifiers are also allowed as procedural assignment l-values.
virtual NetAssign_* elaborate_lval(Design*des, NetScope*scope) const;
virtual NetAssign_* elaborate_lval(Design*des,
NetScope*scope,
bool is_force) const;
// Structural r-values are OK.
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
unsigned lwidth,
unsigned long rise,
unsigned long fall,
unsigned long decay,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay,
Link::strength_t drive0,
Link::strength_t drive1) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
bool sys_task_arg =false) const;
int expr_width, bool sys_task_arg) const;
virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
// Elaborate the PEIdent as a port to a module. This method
@@ -233,39 +290,86 @@ 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 NetScope*sc) const;
verinum* eval_const(Design*des, NetScope*sc) const;
const hname_t& path() const;
const pform_name_t& path() const { return path_; }
private:
hname_t path_;
pform_name_t path_;
private:
// Common functions to calculate parts of part/bit selects.
bool calculate_parts_(Design*, NetScope*, long&msb, long&lsb) const;
bool calculate_up_do_width_(Design*, NetScope*, unsigned long&wid) const;
private:
NetAssign_*elaborate_lval_net_word_(Design*, NetScope*, NetNet*) const;
bool elaborate_lval_net_part_(Design*, NetScope*, NetAssign_*) const;
bool elaborate_lval_net_idx_up_(Design*, NetScope*, NetAssign_*) const;
bool elaborate_lval_net_idx_do_(Design*, NetScope*, NetAssign_*) const;
private:
NetExpr*elaborate_expr_param(Design*des,
NetScope*scope,
const NetExpr*par,
NetScope*found,
const NetExpr*par_msb,
const NetExpr*par_lsb) const;
NetExpr*elaborate_expr_net(Design*des,
NetScope*scope,
NetNet*net,
NetScope*found,
bool sys_task_arg) const;
NetExpr*elaborate_expr_net_word_(Design*des,
NetScope*scope,
NetNet*net,
NetScope*found,
bool sys_task_arg) const;
NetExpr*elaborate_expr_net_part_(Design*des,
NetScope*scope,
NetESignal*net,
NetScope*found) const;
NetExpr*elaborate_expr_net_idx_up_(Design*des,
NetScope*scope,
NetESignal*net,
NetScope*found) const;
NetExpr*elaborate_expr_net_idx_do_(Design*des,
NetScope*scope,
NetESignal*net,
NetScope*found) const;
NetExpr*elaborate_expr_net_bit_(Design*des,
NetScope*scope,
NetESignal*net,
NetScope*found) const;
public:
// Use these to support bit- and part-select operators.
PExpr*msb_;
PExpr*lsb_;
// If this is a reference to a memory, this is the index
// expression.
PExpr*idx_;
NetNet* elaborate_net_ram_(Design*des, NetScope*scope,
NetMemory*mem, unsigned lwidth,
unsigned long rise,
unsigned long fall,
unsigned long decay) const;
NetNet* elaborate_net_array_(Design*des, NetScope*scope,
NetNet*sig, unsigned lwidth,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay,
Link::strength_t drive0,
Link::strength_t drive1) const;
NetNet* elaborate_net_bitmux_(Design*des, NetScope*scope,
NetNet*sig,
unsigned long rise,
unsigned long fall,
unsigned long decay,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay,
Link::strength_t drive0,
Link::strength_t drive1) const;
private:
NetAssign_* elaborate_mem_lval_(Design*des, NetScope*scope,
NetMemory*mem) const;
NetNet* elaborate_lnet_common_(Design*des, NetScope*scope,
bool implicit_net_ok,
bool bidirectional_flag) const;
NetNet*make_implicit_net_(Design*des, NetScope*scope) const;
bool eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
unsigned&midx, unsigned&lidx) const;
NetNet*process_select_(Design*des, NetScope*scope, NetNet*sig) const;
};
@@ -278,19 +382,25 @@ class PENumber : public PExpr {
const verinum& value() const;
virtual void dump(ostream&) const;
virtual unsigned test_width(Design*des, NetScope*scope,
unsigned min, unsigned lval,
bool&unsized_flag) const;
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
unsigned lwidth,
unsigned long rise,
unsigned long fall,
unsigned long decay,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay,
Link::strength_t drive0,
Link::strength_t drive1) const;
virtual NetEConst*elaborate_expr(Design*des, NetScope*,
bool sys_task_arg =false) const;
int expr_width, bool) const;
virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
virtual NetAssign_* elaborate_lval(Design*des, NetScope*scope) const;
virtual NetAssign_* elaborate_lval(Design*des,
NetScope*scope,
bool is_force) const;
virtual verinum* eval_const(const Design*des, const NetScope*sc) const;
virtual verinum* eval_const(Design*des, NetScope*sc) const;
virtual bool is_the_same(const PExpr*that) const;
virtual bool is_constant(Module*) const;
@@ -314,17 +424,22 @@ class PEString : public PExpr {
string value() const;
virtual void dump(ostream&) const;
virtual unsigned test_width(Design*des, NetScope*scope,
unsigned min, unsigned lval,
bool&unsized_flag) const;
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
unsigned width,
unsigned long rise,
unsigned long fall,
unsigned long decay,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay,
Link::strength_t drive0,
Link::strength_t drive1) const;
virtual NetEConst*elaborate_expr(Design*des, NetScope*,
bool sys_task_arg =false) const;
int expr_width, bool) const;
virtual NetEConst*elaborate_pexpr(Design*des, NetScope*sc) const;
verinum* PEString::eval_const(const Design*, const NetScope*) const;
verinum* eval_const(Design*, NetScope*) const;
virtual bool is_constant(Module*) const;
@@ -339,17 +454,18 @@ class PEUnary : public PExpr {
~PEUnary();
virtual void dump(ostream&out) const;
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
unsigned width,
unsigned long rise,
unsigned long fall,
unsigned long decay,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay,
Link::strength_t drive0,
Link::strength_t drive1) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
bool sys_task_arg =false) const;
int expr_width, bool sys_task_arg) const;
virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
virtual verinum* eval_const(const Design*des, const NetScope*sc) const;
virtual verinum* eval_const(Design*des, NetScope*sc) const;
virtual bool is_constant(Module*) const;
@@ -367,65 +483,100 @@ class PEBinary : public PExpr {
virtual bool is_constant(Module*) const;
virtual void dump(ostream&out) const;
virtual unsigned test_width(Design*des, NetScope*scope,
unsigned min, unsigned lval,
bool&unsized_flag) const;
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
unsigned width,
unsigned long rise,
unsigned long fall,
unsigned long decay,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay,
Link::strength_t drive0,
Link::strength_t drive1) const;
virtual NetEBinary*elaborate_expr(Design*des, NetScope*,
bool sys_task_arg =false) const;
int expr_width, bool sys_task_arg) const;
virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
virtual verinum* eval_const(const Design*des, const NetScope*sc) const;
virtual verinum* eval_const(Design*des, NetScope*sc) const;
private:
protected:
char op_;
PExpr*left_;
PExpr*right_;
NetEBinary*elaborate_expr_base_(Design*, NetExpr*lp, NetExpr*rp) const;
NetEBinary*elaborate_expr_base_(Design*, NetExpr*lp, NetExpr*rp, int use_wid) const;
NetEBinary*elaborate_eval_expr_base_(Design*, NetExpr*lp, NetExpr*rp, int use_wid) const;
private:
NetNet* elaborate_net_add_(Design*des, NetScope*scope,
unsigned lwidth,
unsigned long rise,
unsigned long fall,
unsigned long decay) const;
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay) const;
NetNet* elaborate_net_bit_(Design*des, NetScope*scope,
unsigned lwidth,
unsigned long rise,
unsigned long fall,
unsigned long decay) const;
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay) const;
NetNet* elaborate_net_cmp_(Design*des, NetScope*scope,
unsigned lwidth,
unsigned long rise,
unsigned long fall,
unsigned long decay) const;
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay) const;
NetNet* elaborate_net_div_(Design*des, NetScope*scope,
unsigned lwidth,
unsigned long rise,
unsigned long fall,
unsigned long decay) const;
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay) const;
NetNet* elaborate_net_mod_(Design*des, NetScope*scope,
unsigned lwidth,
unsigned long rise,
unsigned long fall,
unsigned long decay) const;
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay) const;
NetNet* elaborate_net_log_(Design*des, NetScope*scope,
unsigned lwidth,
unsigned long rise,
unsigned long fall,
unsigned long decay) const;
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay) const;
NetNet* elaborate_net_mul_(Design*des, NetScope*scope,
unsigned lwidth,
unsigned long rise,
unsigned long fall,
unsigned long decay) const;
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay) const;
NetNet* elaborate_net_shift_(Design*des, NetScope*scope,
unsigned lwidth,
unsigned long rise,
unsigned long fall,
unsigned long decay) const;
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay) const;
};
/*
* Here are a few specilized classes for handling specific binary
* operators.
*/
class PEBComp : public PEBinary {
public:
explicit PEBComp(char op, PExpr*l, PExpr*r);
~PEBComp();
virtual unsigned test_width(Design*des, NetScope*scope,
unsigned min, unsigned lval,
bool&flag) const;
NetEBinary* elaborate_expr(Design*des, NetScope*scope,
int expr_width, bool sys_task_arg) const;
};
class PEBShift : public PEBinary {
public:
explicit PEBShift(char op, PExpr*l, PExpr*r);
~PEBShift();
virtual unsigned test_width(Design*des, NetScope*scope,
unsigned min, unsigned lval, bool&flag) const;
};
/*
@@ -441,17 +592,21 @@ class PETernary : public PExpr {
virtual bool is_constant(Module*) const;
virtual void dump(ostream&out) const;
virtual unsigned test_width(Design*des, NetScope*scope,
unsigned min, unsigned lval,
bool&unsized_flag) const;
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
unsigned width,
unsigned long rise,
unsigned long fall,
unsigned long decay,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay,
Link::strength_t drive0,
Link::strength_t drive1) const;
virtual NetETernary*elaborate_expr(Design*des, NetScope*,
bool sys_task_arg =false) const;
int expr_width, bool sys_task_arg) const;
virtual NetETernary*elaborate_pexpr(Design*des, NetScope*sc) const;
virtual verinum* eval_const(const Design*des, const NetScope*sc) const;
virtual verinum* eval_const(Design*des, NetScope*sc) const;
private:
PExpr*expr_;
@@ -466,32 +621,131 @@ class PETernary : public PExpr {
*/
class PECallFunction : public PExpr {
public:
explicit PECallFunction(const hname_t&n, const svector<PExpr *> &parms);
explicit PECallFunction(const hname_t&n);
explicit PECallFunction(const pform_name_t&n, const svector<PExpr *> &parms);
// Call of system function (name is not heirarchical)
explicit PECallFunction(perm_string n, const svector<PExpr *> &parms);
explicit PECallFunction(perm_string n);
~PECallFunction();
virtual void dump(ostream &) const;
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
unsigned width,
unsigned long rise,
unsigned long fall,
unsigned long decay,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay,
Link::strength_t drive0,
Link::strength_t drive1) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
bool sys_task_arg =false) const;
int expr_wid, bool sys_task_arg) const;
private:
hname_t path_;
pform_name_t path_;
svector<PExpr *> parms_;
bool check_call_matches_definition_(Design*des, NetScope*dscope) const;
NetExpr* elaborate_sfunc_(Design*des, NetScope*scope) const;
NetNet* elaborate_net_sfunc_(Design*des, NetScope*scope,
unsigned width,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay,
Link::strength_t drive0,
Link::strength_t drive1) const;
};
/*
* $Log: PExpr.h,v $
* Revision 1.90 2007/06/04 19:14:06 steve
* Build errors in picky GCC compilers.
*
* Revision 1.89 2007/06/04 02:19:07 steve
* Handle bit/part select of array words in nets.
*
* Revision 1.88 2007/05/24 04:07:11 steve
* Rework the heirarchical identifier parse syntax and pform
* to handle more general combinations of heirarch and bit selects.
*
* Revision 1.87 2007/01/16 05:44:14 steve
* Major rework of array handling. Memories are replaced with the
* more general concept of arrays. The NetMemory and NetEMemory
* classes are removed from the ivl core program, and the IVL_LPM_RAM
* lpm type is removed from the ivl_target API.
*
* Revision 1.86 2006/11/10 04:54:26 steve
* Add test_width methods for PETernary and PEString.
*
* Revision 1.85 2006/11/04 06:19:24 steve
* Remove last bits of relax_width methods, and use test_width
* to calculate the width of an r-value expression that may
* contain unsized numbers.
*
* Revision 1.84 2006/10/30 05:44:49 steve
* Expression widths with unsized literals are pseudo-infinite width.
*
* Revision 1.83 2006/06/18 04:15:50 steve
* Add support for system functions in continuous assignments.
*
* Revision 1.82 2006/06/02 04:48:49 steve
* Make elaborate_expr methods aware of the width that the context
* requires of it. In the process, fix sizing of the width of unary
* minus is context determined sizes.
*
* Revision 1.81 2006/04/28 04:28:35 steve
* Allow concatenations as arguments to inout ports.
*
* Revision 1.80 2006/04/16 00:54:04 steve
* Cleanup lval part select handling.
*
* Revision 1.79 2006/04/16 00:15:43 steve
* Fix part selects in l-values.
*
* Revision 1.78 2006/03/25 02:36:26 steve
* Get rid of excess PESTring:: prefix within class declaration.
*
* Revision 1.77 2006/02/02 02:43:57 steve
* Allow part selects of memory words in l-values.
*
* Revision 1.76 2006/01/02 05:33:19 steve
* Node delays can be more general expressions in structural contexts.
*
* Revision 1.75 2005/12/07 04:04:23 steve
* Allow constant concat expressions.
*
* Revision 1.74 2005/11/27 17:01:56 steve
* Fix for stubborn compiler.
*
* Revision 1.73 2005/11/27 05:56:20 steve
* Handle bit select of parameter with ranges.
*
* Revision 1.72 2005/11/10 13:28:11 steve
* Reorganize signal part select handling, and add support for
* indexed part selects.
*
* Expand expression constant propagation to eliminate extra
* sums in certain cases.
*
* Revision 1.71 2005/10/04 04:09:25 steve
* Add support for indexed select attached to parameters.
*
* Revision 1.70 2005/08/06 17:58:16 steve
* Implement bi-directional part selects.
*
* Revision 1.69 2005/07/07 16:22:49 steve
* Generalize signals to carry types.
*
* Revision 1.68 2005/01/09 20:16:00 steve
* Use PartSelect/PV and VP to handle part selects through ports.
*
* Revision 1.67 2004/12/29 23:55:43 steve
* Unify elaboration of l-values for all proceedural assignments,
* including assing, cassign and force.
*
* Generate NetConcat devices for gate outputs that feed into a
* vector results. Use this to hande gate arrays. Also let gate
* arrays handle vectors of gates when the outputs allow for it.
*
* Revision 1.66 2004/10/04 01:10:51 steve
* Clean up spurious trailing white space.
*
+65 -2
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: PGate.cc,v 1.16 2004/02/18 17:11:54 steve Exp $"
#ident "$Id: PGate.cc,v 1.18 2006/01/03 05:22:14 steve Exp $"
#endif
# include "config.h"
@@ -90,12 +90,69 @@ 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, NetScope*scope,
NetExpr*&rise_expr,
NetExpr*&fall_expr,
NetExpr*&decay_expr,
bool as_net_flag) const
{
delay_.eval_delays(des, scope,
rise_expr, fall_expr, decay_expr,
as_net_flag);
}
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, scope, rise_time, fall_time, decay_time);
NetExpr*rise_expr, *fall_expr, *decay_expr;
delay_.eval_delays(des, scope, rise_expr, fall_expr, decay_expr);
if (rise_expr == 0) {
rise_time = 0;
fall_time = 0;
decay_time = 0;
}
if (NetEConst*tmp = dynamic_cast<NetEConst*> (rise_expr)) {
rise_time = tmp->value().as_ulong();
} else {
cerr << get_line() << ": error: Delay expressions must be "
<< "constant here." << endl;
cerr << get_line() << ": : Cannot calculate "
<< *rise_expr << endl;
des->errors += 1;
rise_time = 0;
}
if (NetEConst*tmp = dynamic_cast<NetEConst*> (fall_expr)) {
fall_time = tmp->value().as_ulong();
} else {
if (fall_expr != rise_expr) {
cerr << get_line() << ": error: Delay expressions must be "
<< "constant here." << endl;
cerr << get_line() << ": : Cannot calculate "
<< *rise_expr << endl;
}
des->errors += 1;
fall_time = 0;
}
if (NetEConst*tmp = dynamic_cast<NetEConst*> (decay_expr)) {
decay_time = tmp->value().as_ulong();
} else {
cerr << get_line() << ": error: Delay expressions must be "
<< "constant here." << endl;
cerr << get_line() << ": : Cannot calculate "
<< *rise_expr << endl;
des->errors += 1;
decay_time = 0;
}
}
PGAssign::PGAssign(svector<PExpr*>*pins)
@@ -191,6 +248,12 @@ perm_string PGModule::get_type()
/*
* $Log: PGate.cc,v $
* Revision 1.18 2006/01/03 05:22:14 steve
* Handle complex net node delays.
*
* Revision 1.17 2006/01/02 05:33:19 steve
* Node delays can be more general expressions in structural contexts.
*
* Revision 1.16 2004/02/18 17:11:54 steve
* Use perm_strings for named langiage items.
*
+26 -5
View File
@@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: PGate.h,v 1.29 2004/10/04 01:10:52 steve Exp $"
#ident "$Id: PGate.h,v 1.32 2006/04/10 00:37:42 steve Exp $"
#endif
# include "svector.h"
@@ -66,11 +66,23 @@ class PGate : public LineInfo {
perm_string get_name() const { return name_; }
// This method evaluates the delays all the way to an
// integer. If the delay is non-constant, then set the times
// to 0, print an error message and mark an error to the
// design.
void eval_delays(Design*des, NetScope*scope,
unsigned long&rise_time,
unsigned long&fall_time,
unsigned long&decay_time) const;
// This evaluates the delays as far as possible, but returns
// an expression, and do not signal errors.
void eval_delays(Design*des, NetScope*scope,
NetExpr*&rise_time,
NetExpr*&fall_time,
NetExpr*&decay_time,
bool as_net_flag =false) const;
unsigned pin_count() const { return pins_? pins_->count() : 0; }
const PExpr*pin(unsigned idx) const { return (*pins_)[idx]; }
@@ -82,7 +94,7 @@ class PGate : public LineInfo {
map<perm_string,PExpr*> attributes;
virtual void dump(ostream&out) const;
virtual void dump(ostream&out, unsigned ind =4) 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 +128,7 @@ class PGAssign : public PGate {
explicit PGAssign(svector<PExpr*>*pins, svector<PExpr*>*dels);
~PGAssign();
void dump(ostream&out) const;
void dump(ostream&out, unsigned ind =4) const;
virtual void elaborate(Design*des, NetScope*scope) const;
private:
@@ -153,7 +165,7 @@ class PGBuiltin : public PGate {
Type type() const { return type_; }
void set_range(PExpr*msb, PExpr*lsb);
virtual void dump(ostream&out) const;
virtual void dump(ostream&out, unsigned ind =4) const;
virtual void elaborate(Design*, NetScope*scope) const;
private:
@@ -196,7 +208,7 @@ class PGModule : public PGate {
// method to pass the range to the pform.
void set_range(PExpr*msb, PExpr*lsb);
virtual void dump(ostream&out) const;
virtual void dump(ostream&out, unsigned ind =4) 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;
@@ -227,6 +239,15 @@ class PGModule : public PGate {
/*
* $Log: PGate.h,v $
* Revision 1.32 2006/04/10 00:37:42 steve
* Add support for generate loops w/ wires and gates.
*
* Revision 1.31 2006/01/03 05:22:14 steve
* Handle complex net node delays.
*
* Revision 1.30 2006/01/02 05:33:19 steve
* Node delays can be more general expressions in structural contexts.
*
* Revision 1.29 2004/10/04 01:10:52 steve
* Clean up spurious trailing white space.
*
+63
View File
@@ -0,0 +1,63 @@
/*
* Copyright (c) 2006 Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: PGenerate.cc,v 1.4 2007/06/02 03:42:12 steve Exp $"
#endif
# include "PGenerate.h"
# include "PWire.h"
PGenerate::PGenerate(unsigned id)
: id_number(id)
{
parent = 0;
}
PGenerate::~PGenerate()
{
}
PWire* PGenerate::add_wire(PWire*wire)
{
PWire*&ep = wires[wire->path()];
if (ep) return ep;
assert(ep == 0);
ep = wire;
return wire;
}
PWire* PGenerate::get_wire(const pform_name_t&name) const
{
map<pform_name_t,PWire*>::const_iterator obj = wires.find(name);
if (obj == wires.end())
return 0;
else
return (*obj).second;
}
void PGenerate::add_gate(PGate*gate)
{
gates.push_back(gate);
}
void PGenerate::add_behavior(PProcess*proc)
{
behaviors.push_back(proc);
}
+100
View File
@@ -0,0 +1,100 @@
#ifndef __PGenerate_H
#define __PGenerate_H
/*
* Copyright (c) 2006 Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: PGenerate.h,v 1.4 2007/06/02 03:42:12 steve Exp $"
#endif
# include "LineInfo.h"
# include "StringHeap.h"
# include "HName.h"
# include <list>
# include <map>
# include "pform_types.h"
class Design;
class NetScope;
class PExpr;
class PProcess;
class PGate;
class PWire;
/*
* This represents a generate scheme.
*/
class PGenerate : public LineInfo {
public:
PGenerate(unsigned id_number);
~PGenerate();
// Generate schemes have an ID number, for when the scope is
// implicit.
const unsigned id_number;
perm_string scope_name;
enum scheme_t {GS_NONE, GS_LOOP, GS_CONDIT};
scheme_t scheme_type;
// generate loops have an index variable and three
// expressions: for (index = <init>; <test>; index=<step>)
perm_string loop_index;
PExpr*loop_init;
PExpr*loop_test;
PExpr*loop_step;
map<pform_name_t,PWire*>wires;
PWire* add_wire(PWire*);
PWire* get_wire(const pform_name_t&name) const;
list<PGate*> gates;
void add_gate(PGate*);
list<PProcess*> behaviors;
void add_behavior(PProcess*behave);
list<PGenerate*> generates;
PGenerate*parent;
// This method is called by the elaboration of a module to
// generate scopes. the container is the scope that is to
// contain the generated scope.
bool generate_scope(Design*des, NetScope*container);
bool elaborate_sig(Design*des) const;
bool elaborate(Design*des) const;
void dump(ostream&out, unsigned indent) const;
private:
bool generate_scope_loop_(Design*des, NetScope*container);
// These are the scopes created by generate_scope.
list<NetScope*>scope_list_;
// internal function called on each scope generated by this scheme.
bool elaborate_sig_(Design*des, NetScope*scope) const;
bool elaborate_(Design*des, NetScope*scope) const;
private: // not implemented
PGenerate(const PGenerate&);
PGenerate& operator= (const PGenerate&);
};
#endif
+8 -24
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2003 Stephen Williams (steve@icarus.com)
* Copyright (c) 2006 Stephen Williams <steve@icarus.com>
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -17,34 +17,18 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: PData.cc,v 1.2 2003/11/10 20:11:01 steve Exp $"
#ident "$Id: PSpec.cc,v 1.2 2007/02/12 01:52:21 steve Exp $"
#endif
# include "config.h"
# include "PData.h"
# include "PSpec.h"
PData::PData(const hname_t&h)
: hname_(h)
PSpecPath::PSpecPath(unsigned src_cnt, unsigned dst_cnt)
: conditional(false), condition(0), edge(0),
src(src_cnt), dst(dst_cnt),
data_source_expression(0)
{
}
PData::~PData()
PSpecPath::~PSpecPath()
{
}
const hname_t&PData::name() const
{
return hname_;
}
/*
* $Log: PData.cc,v $
* Revision 1.2 2003/11/10 20:11:01 steve
* missing include of config.h
*
* Revision 1.1 2003/01/26 21:15:58 steve
* Rework expression parsing and elaboration to
* accommodate real/realtime values and expressions.
*
*/
+79
View File
@@ -0,0 +1,79 @@
#ifndef __PSpec_H
#define __PSpec_H
/*
* Copyright (c) 2006 Stephen Williams <[email protected]>
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: PSpec.h,v 1.3 2007/04/13 02:34:35 steve Exp $"
#endif
# include "LineInfo.h"
# include "StringHeap.h"
# include <vector>
class PExpr;
/*
* The PSpecPath is the parse of a specify path, which is in its most
* general form <path> = <delays>. The <delays> are collected into the
* "delays" vector in all cases, and the variety is in the other
* members.
*
* All paths also have a list of source names in the src vector, and a
* list of destination names in the dst vector. These pairs are the
* actual paths.
*
* If the path is a simple path, then:
* condition == nil
* edge == 0
* data_source_expression == nil
*
* If the path is conditional, then conditional == true and condition
* is the condition expression. If the condition expression is nil,
* then this is an ifnone conditional path.
*
* If data_source_expression != nil, then the path is edge sensitive
* and the edge might not be 0.
*/
class PSpecPath : public LineInfo {
public:
PSpecPath(unsigned src_cnt, unsigned dst_cnt);
~PSpecPath();
void elaborate(class Design*des, class NetScope*scope) const;
void dump(std::ostream&out, unsigned ind) const;
public:
// Condition expression, if present.
bool conditional;
class PExpr* condition;
// Edge specification (-1==negedge, 0 = no edge, 1==posedge)
int edge;
// Ordered set of source nodes of a path
std::vector<perm_string> src;
// Ordered set of destination nodes of a path
std::vector<perm_string> dst;
// Data source expression
class PExpr* data_source_expression;
std::vector<class PExpr*>delays;
};
#endif
+5 -1
View File
@@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: PTask.h,v 1.13 2004/05/31 23:34:36 steve Exp $"
#ident "$Id: PTask.h,v 1.14 2007/03/06 05:22:49 steve Exp $"
#endif
# include "LineInfo.h"
@@ -35,6 +35,7 @@ class PExpr;
enum PTaskFuncEnum {
PTF_NONE,
PTF_REG,
PTF_REG_S,
PTF_INTEGER,
PTF_REAL,
PTF_REALTIME,
@@ -117,6 +118,9 @@ class PFunction : public LineInfo {
/*
* $Log: PTask.h,v $
* Revision 1.14 2007/03/06 05:22:49 steve
* Support signed function return values.
*
* Revision 1.13 2004/05/31 23:34:36 steve
* Rewire/generalize parsing an elaboration of
* function return values to allow for better
+38 -17
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1999 Stephen Williams ([email protected])
* Copyright (c) 1999-2007 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
@@ -17,26 +17,19 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: PWire.cc,v 1.10 2002/08/12 01:34:58 steve Exp $"
#ident "$Id: PWire.cc,v 1.14 2007/05/24 04:07:11 steve Exp $"
#endif
# include "config.h"
# include "PWire.h"
# include <assert.h>
PWire::PWire(const hname_t&n, NetNet::Type t, NetNet::PortType pt)
: hname_(n), type_(t), port_type_(pt), signed_(false), isint_(false),
lidx_(0), ridx_(0)
{
if (t == NetNet::INTEGER) {
type_ = NetNet::REG;
signed_ = true;
isint_ = true;
}
}
PWire::PWire(char*n, NetNet::Type t, NetNet::PortType pt)
: hname_(n), type_(t), port_type_(pt), signed_(false), isint_(false),
PWire::PWire(const pform_name_t&n,
NetNet::Type t,
NetNet::PortType pt,
ivl_variable_type_t dt)
: hname_(n), type_(t), port_type_(pt), data_type_(dt),
signed_(false), isint_(false),
lidx_(0), ridx_(0)
{
if (t == NetNet::INTEGER) {
@@ -51,7 +44,7 @@ NetNet::Type PWire::get_wire_type() const
return type_;
}
const hname_t& PWire::path() const
const pform_name_t& PWire::path() const
{
return hname_;
}
@@ -108,6 +101,19 @@ bool PWire::set_port_type(NetNet::PortType pt)
}
}
bool PWire::set_data_type(ivl_variable_type_t dt)
{
if (data_type_ != IVL_VT_NO_TYPE)
if (data_type_ != dt)
return false;
else
return true;
assert(data_type_ == IVL_VT_NO_TYPE);
data_type_ = dt;
return true;
}
void PWire::set_signed(bool flag)
{
signed_ = flag;
@@ -133,13 +139,28 @@ void PWire::set_memory_idx(PExpr*ldx, PExpr*rdx)
{
assert(lidx_ == 0);
assert(ridx_ == 0);
assert(type_ == NetNet::REG);
lidx_ = ldx;
ridx_ = rdx;
}
/*
* $Log: PWire.cc,v $
* Revision 1.14 2007/05/24 04:07:11 steve
* Rework the heirarchical identifier parse syntax and pform
* to handle more general combinations of heirarch and bit selects.
*
* Revision 1.13 2007/04/26 03:06:21 steve
* Rework hname_t to use perm_strings.
*
* Revision 1.12 2007/01/16 05:44:14 steve
* Major rework of array handling. Memories are replaced with the
* more general concept of arrays. The NetMemory and NetEMemory
* classes are removed from the ivl core program, and the IVL_LPM_RAM
* lpm type is removed from the ivl_target API.
*
* Revision 1.11 2005/07/07 16:22:49 steve
* Generalize signals to carry types.
*
* Revision 1.10 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
+32 -46
View File
@@ -1,7 +1,7 @@
#ifndef __PWire_H
#define __PWire_H
/*
* Copyright (c) 1998-2000 Stephen Williams ([email protected])
* Copyright (c) 1998-2007 Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -19,13 +19,14 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: PWire.h,v 1.17 2004/02/20 18:53:33 steve Exp $"
#ident "$Id: PWire.h,v 1.21 2007/05/24 04:07:11 steve Exp $"
#endif
# include "netlist.h"
# include "LineInfo.h"
# include <map>
# include "svector.h"
# include "StringHeap.h"
#ifdef HAVE_IOSFWD
# include <iosfwd>
@@ -42,18 +43,21 @@ class Design;
* 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.
* is the name of the wire within a module, so does not include the
* current scope or any instances. Modules contain all the wires, so
* from that perspective, sub-scopes within the module are a part of
* the wire name.
*/
class PWire : public LineInfo {
public:
PWire(const hname_t&hname, NetNet::Type t, NetNet::PortType pt);
PWire(char*name, NetNet::Type t, NetNet::PortType pt);
PWire(const pform_name_t&hname,
NetNet::Type t,
NetNet::PortType pt,
ivl_variable_type_t dt);
// Return a hierarchical name.
const hname_t&path() const;
const pform_name_t&path() const;
NetNet::Type get_wire_type() const;
bool set_wire_type(NetNet::Type);
@@ -65,6 +69,9 @@ class PWire : public LineInfo {
bool get_signed() const;
bool get_isint() const;
bool set_data_type(ivl_variable_type_t dt);
ivl_variable_type_t get_data_type() const;
void set_range(PExpr*msb, PExpr*lsb);
void set_memory_idx(PExpr*ldx, PExpr*rdx);
@@ -72,14 +79,15 @@ class PWire : public LineInfo {
map<perm_string,PExpr*> attributes;
// Write myself to the specified stream.
void dump(ostream&out) const;
void dump(ostream&out, unsigned ind=4) const;
void elaborate_sig(Design*, NetScope*scope) const;
NetNet* elaborate_sig(Design*, NetScope*scope) const;
private:
hname_t hname_;
pform_name_t hname_;
NetNet::Type type_;
NetNet::PortType port_type_;
ivl_variable_type_t data_type_;
bool signed_;
bool isint_; // original type of integer
@@ -100,6 +108,19 @@ class PWire : public LineInfo {
/*
* $Log: PWire.h,v $
* Revision 1.21 2007/05/24 04:07:11 steve
* Rework the heirarchical identifier parse syntax and pform
* to handle more general combinations of heirarch and bit selects.
*
* Revision 1.20 2007/04/26 03:06:22 steve
* Rework hname_t to use perm_strings.
*
* Revision 1.19 2006/04/10 00:37:42 steve
* Add support for generate loops w/ wires and gates.
*
* Revision 1.18 2005/07/07 16:22:49 steve
* Generalize signals to carry types.
*
* Revision 1.17 2004/02/20 18:53:33 steve
* Addtrbute keys are perm_strings.
*
@@ -130,40 +151,5 @@ class PWire : public LineInfo {
*
* Revision 1.10 2001/01/16 02:44:18 steve
* Use the iosfwd header if available.
*
* Revision 1.9 2000/12/11 00:31:43 steve
* Add support for signed reg variables,
* simulate in t-vvm signed comparisons.
*
* Revision 1.8 2000/05/02 16:27:38 steve
* Move signal elaboration to a seperate pass.
*
* Revision 1.7 2000/02/23 02:56:54 steve
* Macintosh compilers do not support ident.
*
* Revision 1.6 1999/11/27 19:07:57 steve
* Support the creation of scopes.
*
* Revision 1.5 1999/06/17 05:34:42 steve
* Clean up interface of the PWire class,
* Properly match wire ranges.
*
* Revision 1.4 1999/06/02 15:38:46 steve
* Line information with nets.
*
* Revision 1.3 1999/04/19 01:59:36 steve
* Add memories to the parse and elaboration phases.
*
* Revision 1.2 1998/11/23 00:20:22 steve
* NetAssign handles lvalues as pin links
* instead of a signal pointer,
* Wire attributes added,
* Ability to parse UDP descriptions added,
* XNF generates EXT records for signals with
* the PAD attribute.
*
* Revision 1.1 1998/11/03 23:28:55 steve
* Introduce verilog to CVS.
*
*/
#endif
+17 -51
View File
@@ -114,7 +114,7 @@ configure script that modify its behavior:
If you are building for Linux/AMD64 (a.k.a x86_64) then to get the
most out of your install, first make sure you have both 64bit and
32bit development libraries installed. Then configure with this
somewhat more compilcated command:
somewhat more complicated command:
./configure libdir64='$(prefix)/lib64' vpidir1=vpi64 vpidir2=. --enable-vvp32
@@ -359,7 +359,8 @@ constructs.
Icarus Verilog includes some features that are not part of the
IEEE1364 standard, but have well defined meaning, and also sometimes
gives nonstandard (but extended) meanings to some features of the
language that are defined.
language that are defined. See the "extensions.txt" documentation for
more details.
$is_signed(<expr>)
This system function returns 1 if the expression contained is
@@ -470,6 +471,20 @@ language that are defined.
combinational always blocks to be triggered when the values in
the sensitivity list are initialized by initial threads.
Nets with Types
Icarus Verilog support an extension syntax that allows nets
and regs to be explicitly typed. The currently supported types
are logic, bool and real. This implies that "logic" and "bool"
are new keywords. Typical syntax is:
wire real foo = 1.0;
reg logic bar, bat;
... and so forth. The syntax can be turned off by using the
-g2 flag to iverilog, and turned on explicitly with the -g2x
flag to iverilog.
6.0 CREDITS
Except where otherwise noted, Icarus Verilog, ivl and ivlpp are
@@ -479,52 +494,3 @@ Verilog guidance, and especially testing from many people. Testers in
particular include a larger community of people interested in a GPL
Verilog for Linux.
6.1 PORT MAINTAINERS
This is a list of people who have created ports and precompiled
packages for various operating systems. These folks have graciously
taken on the task of building Icarus Verilog on their systems and
bundled it into neat packages.(+) If you want to be added to the list (or
removed from the list) send e-mail to me.
FreeBSD/{Intel,alpha}
Ying-Chieh Liao <[email protected]>
Linux/{alpha,AMD64,Intel} (RPMS)
Stephen Williams <[email protected]>
Linux/* (.debs)
Hamish Moffatt <[email protected]>
Macintosh -- MacO/S
Yasuhisa Kato <[email protected]>
Mac O/S X
Timothy J. Wood <[email protected]>
NetBSD/*
Dan McMahill <[email protected]>
Solaris/SPARC packages (.pkg)
Dan McMahill <[email protected]>
Cygwin32/*
Venkat Iyer <[email protected]>
Mingw32
Venkat Iyer <[email protected]>
(+) These are not the only systems where Icarus Verilog has been run,
just the systems where precompiled binaries are publicly available.
6.2 TEST SUITE MANAGER
Steve Wilson <[email protected]> has taken on the large task of managing
the test suite. He has maintained the regression test scripts, the
driver list, received submissions from myself and others, and has
written a great many tests on his own. Any compiler writer, for any
language, will tell you that the test suite is at least as important
as the compiler code itself.
+15 -5
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: Statement.cc,v 1.29 2004/02/18 17:11:54 steve Exp $"
#ident "$Id: Statement.cc,v 1.30 2007/05/24 04:07:11 steve Exp $"
#endif
# include "config.h"
@@ -107,16 +107,22 @@ PBlock::~PBlock()
delete list_[idx];
}
PCallTask::PCallTask(const hname_t&n, const svector<PExpr*>&p)
PCallTask::PCallTask(const pform_name_t&n, const svector<PExpr*>&p)
: path_(n), parms_(p)
{
}
PCallTask::PCallTask(perm_string n, const svector<PExpr*>&p)
: parms_(p)
{
path_.push_back(name_component_t(n));
}
PCallTask::~PCallTask()
{
}
const hname_t& PCallTask::path() const
const pform_name_t& PCallTask::path() const
{
return path_;
}
@@ -178,7 +184,7 @@ PDelayStatement::~PDelayStatement()
{
}
PDisable::PDisable(const hname_t&sc)
PDisable::PDisable(const pform_name_t&sc)
: scope_(sc)
{
}
@@ -273,7 +279,7 @@ PRepeat::~PRepeat()
delete statement_;
}
PTrigger::PTrigger(const hname_t&e)
PTrigger::PTrigger(const pform_name_t&e)
: event_(e)
{
}
@@ -295,6 +301,10 @@ PWhile::~PWhile()
/*
* $Log: Statement.cc,v $
* Revision 1.30 2007/05/24 04:07:11 steve
* Rework the heirarchical identifier parse syntax and pform
* to handle more general combinations of heirarch and bit selects.
*
* Revision 1.29 2004/02/18 17:11:54 steve
* Use perm_strings for named langiage items.
*
+29 -9
View File
@@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: Statement.h,v 1.40 2004/02/20 18:53:33 steve Exp $"
#ident "$Id: Statement.h,v 1.44 2007/05/24 04:07:11 steve Exp $"
#endif
# include <string>
@@ -36,6 +36,7 @@ class Design;
class NetAssign_;
class NetCAssign;
class NetDeassign;
class NetForce;
class NetScope;
/*
@@ -54,6 +55,8 @@ class PProcess : public LineInfo {
virtual ~PProcess();
bool elaborate(Design*des, NetScope*scope) const;
Type type() const { return type_; }
Statement*statement() { return statement_; }
@@ -170,10 +173,11 @@ class PBlock : public Statement {
class PCallTask : public Statement {
public:
explicit PCallTask(const hname_t&n, const svector<PExpr*>&parms);
explicit PCallTask(const pform_name_t&n, const svector<PExpr*>&parms);
explicit PCallTask(perm_string n, const svector<PExpr*>&parms);
~PCallTask();
const hname_t& path() const;
const pform_name_t& path() const;
unsigned nparms() const { return parms_.count(); }
@@ -194,7 +198,7 @@ class PCallTask : public Statement {
NetProc* elaborate_sys(Design*des, NetScope*scope) const;
NetProc* elaborate_usr(Design*des, NetScope*scope) const;
hname_t path_;
pform_name_t path_;
svector<PExpr*> parms_;
};
@@ -293,14 +297,14 @@ class PDelayStatement : public Statement {
class PDisable : public Statement {
public:
explicit PDisable(const hname_t&sc);
explicit PDisable(const pform_name_t&sc);
~PDisable();
virtual void dump(ostream&out, unsigned ind) const;
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
private:
hname_t scope_;
pform_name_t scope_;
};
/*
@@ -345,7 +349,7 @@ class PForce : public Statement {
explicit PForce(PExpr*l, PExpr*r);
~PForce();
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
virtual NetForce* elaborate(Design*des, NetScope*scope) const;
virtual void dump(ostream&out, unsigned ind) const;
private:
@@ -393,6 +397,7 @@ class PNoop : public Statement {
public:
PNoop() { }
~PNoop() { }
};
class PRepeat : public Statement {
@@ -429,14 +434,14 @@ class PRelease : public Statement {
class PTrigger : public Statement {
public:
explicit PTrigger(const hname_t&ev);
explicit PTrigger(const pform_name_t&ev);
~PTrigger();
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
virtual void dump(ostream&out, unsigned ind) const;
private:
hname_t event_;
pform_name_t event_;
};
class PWhile : public Statement {
@@ -456,6 +461,21 @@ class PWhile : public Statement {
/*
* $Log: Statement.h,v $
* Revision 1.44 2007/05/24 04:07:11 steve
* Rework the heirarchical identifier parse syntax and pform
* to handle more general combinations of heirarch and bit selects.
*
* Revision 1.43 2007/03/05 05:59:10 steve
* Handle processes within generate loops.
*
* Revision 1.42 2005/12/05 21:21:18 steve
* Fixes for stubborn compilers.
*
* Revision 1.41 2004/12/11 02:31:25 steve
* Rework of internals to carry vectors through nexus instead
* of single bits. Make the ivl, tgt-vvp and vvp initial changes
* down this path.
*
* Revision 1.40 2004/02/20 18:53:33 steve
* Addtrbute keys are perm_strings.
*
+6 -1
View File
@@ -19,12 +19,14 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: StringHeap.h,v 1.5 2004/02/18 17:11:54 steve Exp $"
#ident "$Id: StringHeap.h,v 1.6 2005/06/14 19:13:43 steve Exp $"
#endif
# include "config.h"
# include <string>
using namespace std;
class perm_string {
public:
@@ -120,6 +122,9 @@ class StringHeapLex : private StringHeap {
/*
* $Log: StringHeap.h,v $
* Revision 1.6 2005/06/14 19:13:43 steve
* gcc3/4 compile errors.
*
* Revision 1.5 2004/02/18 17:11:54 steve
* Use perm_strings for named langiage items.
*
+6 -3
View File
@@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: _pli_types.h.in,v 1.7 2003/11/12 02:38:44 steve Exp $"
#ident "$Id: _pli_types.h.in,v 1.8 2007/06/05 21:32:30 steve Exp $"
#endif
# undef HAVE_INTTYPES_H
@@ -42,7 +42,7 @@ typedef int32_t PLI_INT32;
typedef signed short PLI_INT16;
typedef unsigned short PLI_UINT16;
typedef signed char PLI_BYTE8;
typedef char PLI_BYTE8;
typedef unsigned char PLI_UBYTE8;
# define PLI_UINT64_FMT PRIu64
@@ -84,12 +84,15 @@ typedef signed int PLI_INT32;
typedef unsigned int PLI_UINT32;
typedef signed short PLI_INT16;
typedef unsigned short PLI_UINT16;
typedef signed char PLI_BYTE8;
typedef char PLI_BYTE8;
typedef unsigned char PLI_UBYTE8;
#endif
/*
* $Log: _pli_types.h.in,v $
* Revision 1.8 2007/06/05 21:32:30 steve
* More standard PLI_BYTE8.
*
* Revision 1.7 2003/11/12 02:38:44 steve
* Clean up manual definitions of PLI_UINT64_FMT.
*
Vendored
+3 -3
View File
@@ -14,7 +14,7 @@
AC_DEFUN([AX_CPP_IDENT],
[AC_CACHE_CHECK([for ident support in C compiler], ax_cv_cpp_ident,
[AC_TRY_COMPILE([
#ident "$Id: aclocal.m4,v 1.6 2004/10/04 01:10:52 steve Exp $"
#ident "$Id: aclocal.m4,v 1.7 2007/05/16 23:59:12 steve Exp $"
],[while (0) {}],
[AS_VAR_SET(ax_cv_cpp_ident, yes)],
[AS_VAR_SET(ax_cv_cpp_ident, no)])])
@@ -48,7 +48,7 @@ AC_DEFUN([AX_C_UNDERSCORES_LEADING],
[AS_VAR_SET(ax_cv_c_underscores_leading, yes)],
[AS_VAR_SET(ax_cv_c_underscores_leading, no)])])
if test $ax_cv_c_underscores_leading = yes -a "$CYGWIN" != "yes" -a "$MINGW32" != "yes"; then
AC_DEFINE(NEED_LU)
AC_DEFINE([NEED_LU], [1], [Symbol names in object files produced by C compiler have leading underscores.])
fi
])# AX_C_UNDERSCORES_LEADING
@@ -63,7 +63,7 @@ AC_DEFUN([AX_C_UNDERSCORES_TRAILING],
[AS_VAR_SET(ax_cv_c_underscores_trailing, yes)],
[AS_VAR_SET(ax_cv_c_underscores_trailing, no)])])
if test $ax_cv_c_underscores_trailing = yes; then
AC_DEFINE(NEED_TU)
AC_DEFINE([NEED_TU], [1], [Symbol names in object files produced by C compiler have trailing underscores.])
fi
])# AX_C_UNDERSCORES_TRAILING
+3 -3
View File
@@ -7,12 +7,12 @@
# to just run this script to autoconf wherever needed.
#
echo "Autoconf in root..."
autoconf
autoconf -f
for dir in vpip vpi vvp tgt-vvp tgt-fpga libveriuser cadpli
for dir in vpip vpi vvp tgt-vvp tgt-fpga tgt-stub libveriuser cadpli
do
echo "Autoconf in $dir..."
( cd ./$dir ; autoconf --include=.. )
( cd ./$dir ; autoconf -f --include=.. )
done
echo "Precompiling lexor_keyword.gperf"
+5 -6
View File
@@ -16,7 +16,7 @@
# 59 Temple Place - Suite 330
# Boston, MA 02111-1307, USA
#
#ident "$Id: Makefile.in,v 1.11 2004/10/04 01:09:07 steve Exp $"
#ident "$Id: Makefile.in,v 1.13 2007/02/06 05:07:31 steve Exp $"
#
#
SHELL = /bin/sh
@@ -35,8 +35,6 @@ includedir = $(prefix)/include
vpidir = @libdir@/ivl/@vpidir1@
strip_dynamic=@strip_dynamic@
CC = @CC@
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
@@ -45,7 +43,6 @@ INSTALL_DATA = @INSTALL_DATA@
CPPFLAGS = @ident_support@ -I$(srcdir) -I$(srcdir)/.. -I.. @CPPFLAGS@ @DEFS@ @PICFLAG@
CFLAGS = -Wall @CFLAGS@
LDFLAGS = @LDFLAGS@
STRIP = @STRIP@
SHARED = @shared@
@@ -55,7 +52,7 @@ ifeq (@enable_vvp32@,yes)
vpidir32 = $(libdir)/ivl/@vpidir2@
ALL32 = all32
INSTALL32 = install32
UNINSTALL32 = uninistall32
UNINSTALL32 = uninstall32
include $(srcdir)/enable_vvp32.mk
endif
@@ -74,7 +71,7 @@ dep:
O = cadpli.o
SYSTEM_VPI_LDFLAGS = -L../vvp -lvpi
ifeq (@WIN32@,yes)
ifeq (@MING32@,yes)
SYSTEM_VPI_LDFLAGS += @EXTRALIBS@
endif
@@ -98,6 +95,8 @@ installdirs: ../mkinstalldirs
uninstall: $(UNINSTALL32)
rm -f $(vpidir)/cadpli.vpl
uninstall32:
ifeq (@enable_vvp32@,yes)
include $(srcdir)/enable_vvp32.mk
endif
+1 -1
View File
@@ -37,7 +37,7 @@ AC_SUBST(DLLIB)
AX_CPP_PRECOMP
# Compiler option for position independent code, needed whan making shared objects.
# Compiler option for position independent code, needed when making shared objects.
AX_C_PICFLAG
# Linker option used when compiling the target
+47 -10
View File
@@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: compiler.h,v 1.26 2004/10/04 01:10:52 steve Exp $"
#ident "$Id: compiler.h,v 1.33 2007/04/19 02:52:53 steve Exp $"
#endif
# include <list>
@@ -32,11 +32,8 @@
*/
/* The INTEGER_WIDTH is the default width of integer variables, and
the presumed width of unsigned literal numbers. */
#ifndef INTEGER_WIDTH
# define INTEGER_WIDTH 32
#endif
/* The integer_width is the width of integer variables. */
extern unsigned integer_width;
/* The TIME_WIDTH is the width of time variables. */
#ifndef TIME_WIDTH
@@ -84,6 +81,7 @@ extern bool verbose_flag;
extern bool debug_scopes;
extern bool debug_eval_tree;
extern bool debug_elaborate;
extern bool debug_synth2;
/* Path to a directory useful for finding subcomponents. */
extern const char*basedir;
@@ -93,28 +91,46 @@ extern list<const char*>library_suff;
extern int build_library_index(const char*path, bool key_case_sensitive);
/* This is the generation of Verilog that the compiler is asked to
support. */
support. Then there are also more detailed controls for more
specific language features. */
enum generation_t {
GN_VER1995 = 1,
GN_VER2001 = 2,
GN_SYSVER30 = 3,
GN_VER2001X = 3,
GN_DEFAULT = 3
};
extern generation_t generation_flag;
extern bool gn_cadence_types_flag;
/* These functions test that specific features are enabled. */
inline bool gn_cadence_types_enabled()
{ return gn_cadence_types_flag && generation_flag==GN_VER2001X; }
/* If this flag is true, then elaborate specify blocks. If this flag
is false, then skip elaboration of specify behavior. */
extern bool gn_specify_blocks_flag;
/* This is the string to use to invoke the preprocessor. */
extern char*ivlpp_string;
extern map<perm_string,unsigned> missing_modules;
/* Files that are library files are in this map. The lexor compares
file names as it processes `line directives, and if the file name
matches an entry in this table, it will turn on the
library_active_flag so that modules know that they are in a
library. */
extern map<string,bool> library_file_map;
/*
* the lex_strings are perm_strings made up of tokens from the source
* file. Identifiers are so likely to be used many times that it makes
* much sense to use a StringHeapLex to hold them.
*/
extern StringHeapLex lex_strings;
extern StringHeap misc_strings;
/*
* system task/function listings.
@@ -126,7 +142,7 @@ extern StringHeapLex lex_strings;
*/
struct sfunc_return_type {
const char* name;
NetExpr::TYPE type;
ivl_variable_type_t type;
unsigned wid;
int signed_flag;
};
@@ -136,6 +152,27 @@ extern int load_sys_func_table(const char*path);
/*
* $Log: compiler.h,v $
* Revision 1.33 2007/04/19 02:52:53 steve
* Add support for -v flag in command file.
*
* Revision 1.32 2007/03/07 04:24:59 steve
* Make integer width controllable.
*
* Revision 1.31 2006/09/28 04:35:18 steve
* Support selective control of specify and xtypes features.
*
* Revision 1.30 2005/07/11 16:56:50 steve
* Remove NetVariable and ivl_variable_t structures.
*
* Revision 1.29 2005/07/07 16:22:49 steve
* Generalize signals to carry types.
*
* Revision 1.28 2005/06/28 04:25:55 steve
* Remove reference to SystemVerilog.
*
* Revision 1.27 2005/04/24 23:44:01 steve
* Update DFF support to new data flow.
*
* Revision 1.26 2004/10/04 01:10:52 steve
* Clean up spurious trailing white space.
*
+9 -1
View File
@@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: config.h.in,v 1.11 2004/10/04 01:10:52 steve Exp $"
#ident "$Id: config.h.in,v 1.12 2007/02/02 04:33:00 steve Exp $"
#endif
#if defined(__cplusplus)
@@ -37,6 +37,7 @@
# undef HAVE_TIMES
# undef HAVE_IOSFWD
# undef HAVE_GETOPT_H
# undef HAVE_INTTYPES_H
# undef HAVE_LIBIBERTY_H
# undef HAVE_MALLOC_H
# undef HAVE_DLFCN_H
@@ -48,8 +49,15 @@
# undef HAVE_SYS_WAIT_H
# undef WORDS_BIGENDIAN
#ifdef HAVE_INTTYPES_H
# include <inttypes.h>
#endif
/*
* $Log: config.h.in,v $
* Revision 1.12 2007/02/02 04:33:00 steve
* Use inttypes.h instead of stdint.h for portability.
*
* Revision 1.11 2004/10/04 01:10:52 steve
* Clean up spurious trailing white space.
*
+5 -4
View File
@@ -66,7 +66,7 @@ AC_TRY_LINK(
#include <sys/times.h>
,{clock_t a = times(0)/sysconf(_SC_CLK_TCK);},
do_times=yes
AC_DEFINE(HAVE_TIMES,1),
AC_DEFINE([HAVE_TIMES], [1], [The times system call is available in the host operating system.]),
do_times=no
)
AC_MSG_RESULT($do_times)
@@ -93,7 +93,7 @@ AC_C_BIGENDIAN
AX_LD_EXTRALIBS
# Compiler option for position independent code, needed whan making shared objects.
# Compiler option for position independent code, needed when making shared objects.
# CFLAGS inherited by cadpli/Makefile?
AX_C_PICFLAG
@@ -141,6 +141,7 @@ AC_SUBST(vpidir1)
AC_SUBST(vpidir2)
AC_MSG_RESULT(${vpidir1} ${vpidir2})
AC_CONFIG_SUBDIRS(vvp vpi tgt-vvp tgt-fpga libveriuser cadpli)
# XXX disable tgt-fpga for the moment
AC_CONFIG_SUBDIRS(vvp vpi tgt-stub tgt-null tgt-vvp libveriuser cadpli)
AC_OUTPUT(Makefile ivlpp/Makefile driver/Makefile driver-vpi/Makefile tgt-null/Makefile tgt-stub/Makefile tgt-verilog/Makefile tgt-pal/Makefile)
AC_OUTPUT(Makefile ivlpp/Makefile driver/Makefile driver-vpi/Makefile tgt-null/Makefile tgt-verilog/Makefile tgt-pal/Makefile)
+132 -189
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998-2003 Stephen Williams ([email protected])
* Copyright (c) 1998-2005 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
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: cprop.cc,v 1.47 2004/02/20 18:53:34 steve Exp $"
#ident "$Id: cprop.cc,v 1.56 2007/03/07 00:38:15 steve Exp $"
#endif
# include "config.h"
@@ -55,86 +55,6 @@ void cprop_functor::signal(Design*des, NetNet*obj)
void cprop_functor::lpm_add_sub(Design*des, NetAddSub*obj)
{
// For now, only additions are handled.
if (obj->attribute(perm_string::literal("LPM_Direction")) != verinum("ADD"))
return;
// If the low bit on the A side is 0, then eliminate it from
// the adder, and pass the B side directly to the
// result. Don't reduce the adder smaller then a 1-bit
// adder. These will be eliminated later.
while ((obj->width() > 1)
&& obj->pin_DataA(0).nexus()->drivers_constant()
&& (obj->pin_DataA(0).nexus()->driven_value() == verinum::V0)) {
NetAddSub*tmp = 0;
tmp = new NetAddSub(obj->scope(), obj->name(), obj->width()-1);
//connect(tmp->pin_Aclr(), obj->pin_Aclr());
//connect(tmp->pin_Add_Sub(), obj->pin_Add_Sub());
//connect(tmp->pin_Clock(), obj->pin_Clock());
//connect(tmp->pin_Cin(), obj->pin_Cin());
connect(tmp->pin_Cout(), obj->pin_Cout());
//connect(tmp->pin_Overflow(), obj->pin_Overflow());
for (unsigned idx = 0 ; idx < tmp->width() ; idx += 1) {
connect(tmp->pin_DataA(idx), obj->pin_DataA(idx+1));
connect(tmp->pin_DataB(idx), obj->pin_DataB(idx+1));
connect(tmp->pin_Result(idx), obj->pin_Result(idx+1));
}
connect(obj->pin_Result(0), obj->pin_DataB(0));
delete obj;
des->add_node(tmp);
obj = tmp;
count += 1;
}
// Now do the same thing on the B side.
while ((obj->width() > 1)
&& obj->pin_DataB(0).nexus()->drivers_constant()
&& (obj->pin_DataB(0).nexus()->driven_value() == verinum::V0)) {
NetAddSub*tmp = 0;
tmp = new NetAddSub(obj->scope(), obj->name(), obj->width()-1);
//connect(tmp->pin_Aclr(), obj->pin_Aclr());
//connect(tmp->pin_Add_Sub(), obj->pin_Add_Sub());
//connect(tmp->pin_Clock(), obj->pin_Clock());
//connect(tmp->pin_Cin(), obj->pin_Cin());
connect(tmp->pin_Cout(), obj->pin_Cout());
//connect(tmp->pin_Overflow(), obj->pin_Overflow());
for (unsigned idx = 0 ; idx < tmp->width() ; idx += 1) {
connect(tmp->pin_DataA(idx), obj->pin_DataA(idx+1));
connect(tmp->pin_DataB(idx), obj->pin_DataB(idx+1));
connect(tmp->pin_Result(idx), obj->pin_Result(idx+1));
}
connect(obj->pin_Result(0), obj->pin_DataA(0));
delete obj;
des->add_node(tmp);
obj = tmp;
count += 1;
}
// If the adder is only 1 bit wide, then replace it with the
// simple logic gate.
if (obj->width() == 1) {
NetLogic*tmp;
if (obj->pin_Cout().is_linked()) {
tmp = new NetLogic(obj->scope(),
obj->scope()->local_symbol(),
3, NetLogic::AND);
connect(tmp->pin(0), obj->pin_Cout());
connect(tmp->pin(1), obj->pin_DataA(0));
connect(tmp->pin(2), obj->pin_DataB(0));
des->add_node(tmp);
}
tmp = new NetLogic(obj->scope(), obj->name(), 3, NetLogic::XOR);
connect(tmp->pin(0), obj->pin_Result(0));
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;
}
}
void cprop_functor::lpm_compare(Design*des, NetCompare*obj)
@@ -153,6 +73,8 @@ void cprop_functor::lpm_compare(Design*des, NetCompare*obj)
void cprop_functor::lpm_compare_eq_(Design*des, NetCompare*obj)
{
#if 0
/* XXXX Need to reimplement this code to account for vectors. */
NetScope*scope = obj->scope();
unsigned const_count = 0;
@@ -248,7 +170,7 @@ void cprop_functor::lpm_compare_eq_(Design*des, NetCompare*obj)
with a simple XOR gate. */
if (top == 1) {
NetLogic*tmp = new NetLogic(scope, obj->name(), 3,
NetLogic::XNOR);
NetLogic::XNOR, 1);
connect(tmp->pin(0), obj->pin_AEB());
connect(tmp->pin(1), obj->pin_DataA(0));
connect(tmp->pin(2), obj->pin_DataB(0));
@@ -271,6 +193,7 @@ void cprop_functor::lpm_compare_eq_(Design*des, NetCompare*obj)
delete obj;
des->add_node(tmp);
count += 1;
#endif
}
void cprop_functor::lpm_ff(Design*des, NetFF*obj)
@@ -278,63 +201,30 @@ void cprop_functor::lpm_ff(Design*des, NetFF*obj)
// Look for and count unlinked FF outputs. Note that if the
// Data and Q pins are connected together, they can be removed
// from the circuit, since it doesn't do anything.
unsigned unlinked_count = 0;
for (unsigned idx = 0 ; idx < obj->width() ; idx += 1) {
if (connected(obj->pin_Data(idx), obj->pin_Q(idx))
&& (! obj->pin_Sclr().is_linked())
&& (! obj->pin_Sset().is_linked())
&& (! obj->pin_Aclr().is_linked())
&& (! obj->pin_Aset().is_linked())) {
obj->pin_Data(idx).unlink();
obj->pin_Q(idx).unlink();
}
if (! obj->pin_Q(idx).is_linked())
unlinked_count += 1;
}
// If the entire FF is unlinked, remove the whole thing.
if (unlinked_count == obj->width()) {
if (connected(obj->pin_Data(), obj->pin_Q())
&& (! obj->pin_Sclr().is_linked())
&& (! obj->pin_Sset().is_linked())
&& (! obj->pin_Aclr().is_linked())
&& (! obj->pin_Aset().is_linked())) {
obj->pin_Data().unlink();
obj->pin_Q().unlink();
delete obj;
count += 1;
return;
}
// If some of the FFs are unconnected, make a new FF array
// that does not include the useless FF devices.
if (unlinked_count > 0) {
NetFF*tmp = new NetFF(obj->scope(), obj->name(),
obj->width()-unlinked_count);
connect(tmp->pin_Clock(), obj->pin_Clock());
connect(tmp->pin_Enable(), obj->pin_Enable());
connect(tmp->pin_Aload(), obj->pin_Aload());
connect(tmp->pin_Aset(), obj->pin_Aset());
connect(tmp->pin_Aclr(), obj->pin_Aclr());
connect(tmp->pin_Sload(), obj->pin_Sload());
connect(tmp->pin_Sset(), obj->pin_Sset());
connect(tmp->pin_Sclr(), obj->pin_Sclr());
unsigned tidx = 0;
for (unsigned idx = 0 ; idx < obj->width() ; idx += 1)
if (obj->pin_Q(idx).is_linked()) {
connect(tmp->pin_Data(tidx), obj->pin_Data(idx));
connect(tmp->pin_Q(tidx), obj->pin_Q(idx));
tidx += 1;
}
assert(tidx == obj->width() - unlinked_count);
delete obj;
des->add_node(tmp);
count += 1;
return;
}
}
void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
{
#if 0
NetScope*scope = obj->scope();
#endif
switch (obj->type()) {
#if 0
/* XXXX This old code assumed that the individual bit
slices could be replaced with different gates. They
cannot when the device takes atomic vectors, so this
needs to be rewritten. XXXX */
case NetLogic::NAND:
case NetLogic::AND: {
unsigned top = obj->pin_count();
@@ -449,12 +339,12 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
case NetLogic::AND:
tmp = new NetLogic(scope,
obj->name(), 2,
NetLogic::BUF);
NetLogic::BUF, 1);
break;
case NetLogic::NAND:
tmp = new NetLogic(scope,
obj->name(), 2,
NetLogic::NOT);
NetLogic::NOT, 1);
break;
default:
assert(0);
@@ -480,7 +370,7 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
if (top < obj->pin_count()) {
NetLogic*tmp = new NetLogic(scope,
obj->name(), top,
obj->type());
obj->type(), 1);
tmp->rise_time(obj->rise_time());
tmp->fall_time(obj->fall_time());
tmp->decay_time(obj->decay_time());
@@ -497,7 +387,12 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
}
break;
}
#endif
#if 0
/* XXXX This old code assumed that the individual bit
slices could be replaced with different gates. They
cannot when the device takes atomic vectors, so this
needs to be rewritten. XXXX */
case NetLogic::NOR:
case NetLogic::OR: {
@@ -597,12 +492,12 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
case NetLogic::OR:
tmp = new NetLogic(scope,
obj->name(), 2,
NetLogic::BUF);
NetLogic::BUF, 1);
break;
case NetLogic::NOR:
tmp = new NetLogic(scope,
obj->name(), 2,
NetLogic::NOT);
NetLogic::NOT, 1);
break;
default:
assert(0);
@@ -619,7 +514,7 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
delete obj;
count += 1;
return;
}
v }
/* Finally, this cleans up the gate by creating a
new [N]OR gate that has the right number of
@@ -627,7 +522,7 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
if (top < obj->pin_count()) {
NetLogic*tmp = new NetLogic(scope,
obj->name(), top,
obj->type());
obj->type(), 1);
tmp->rise_time(obj->rise_time());
tmp->fall_time(obj->fall_time());
tmp->decay_time(obj->decay_time());
@@ -644,7 +539,12 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
}
break;
}
#endif
#if 0
/* XXXX This old code assumed that the individual bit
slices could be replaced with different gates. They
cannot when the device takes atomic vectors, so this
needs to be rewritten. XXXX */
case NetLogic::XNOR:
case NetLogic::XOR: {
unsigned top = obj->pin_count();
@@ -766,11 +666,11 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
if (obj->type() == NetLogic::XOR)
tmp = new NetLogic(scope,
obj->name(), 2,
NetLogic::NOT);
NetLogic::NOT, 1);
else
tmp = new NetLogic(scope,
obj->name(), 2,
NetLogic::BUF);
NetLogic::BUF, 1);
tmp->rise_time(obj->rise_time());
tmp->fall_time(obj->fall_time());
@@ -795,11 +695,11 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
if (obj->type() == NetLogic::XOR)
tmp = new NetLogic(scope,
obj->name(), 2,
NetLogic::BUF);
NetLogic::BUF, 1);
else
tmp = new NetLogic(scope,
obj->name(), 2,
NetLogic::NOT);
NetLogic::NOT, 1);
tmp->rise_time(obj->rise_time());
tmp->fall_time(obj->fall_time());
@@ -821,7 +721,7 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
if (top < obj->pin_count()) {
NetLogic*tmp = new NetLogic(scope,
obj->name(), top,
obj->type());
obj->type(), 1);
des->add_node(tmp);
tmp->pin(0).drive0(obj->pin(0).drive0());
tmp->pin(0).drive1(obj->pin(0).drive1());
@@ -834,12 +734,54 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
}
break;
}
#endif
default:
break;
}
}
static void replace_with_bufif(Design*des, NetMux*obj, NetLogic::TYPE type)
{
NetScope*scope = obj->scope();
NetLogic*tmp = new NetLogic(obj->scope(),
scope->local_symbol(),
3, type, obj->width());
des->add_node(tmp);
connect(obj->pin_Result(), tmp->pin(0));
connect(obj->pin_Data(type==NetLogic::BUFIF0? 0 : 1), tmp->pin(1));
if (obj->width() == 1) {
/* Special case that the expression is 1 bit
wide. Connect the select directly to the enable. */
connect(obj->pin_Sel(), tmp->pin(2));
} else {
/* General case that the expression is arbitrarily
wide. Replicate the enable signal (which we
assume is 1 bit wide) to match the expression,
and connect the enable vector to the enable
input of the gate. */
NetReplicate*rtmp = new NetReplicate(scope,
scope->local_symbol(),
obj->width(),
obj->width());
des->add_node(rtmp);
connect(obj->pin_Sel(), rtmp->pin(1));
connect(tmp->pin(2), rtmp->pin(0));
NetNet*rsig = new NetNet(scope, scope->local_symbol(),
NetNet::WIRE, obj->width());
rsig->local_flag(true);
rsig->data_type(IVL_VT_LOGIC);
connect(tmp->pin(2), rsig->pin(0));
}
delete obj;
}
/*
* This detects the case where the mux selects between a value and
* Vz. In this case, replace the device with a bufif with the sel
@@ -856,66 +798,36 @@ void cprop_functor::lpm_mux(Design*des, NetMux*obj)
NetMux with an array of BUFIF1 devices, with the enable
connected to the select input. */
bool flag = true;
for (unsigned idx = 0 ; idx < obj->width() ; idx += 1) {
if (! obj->pin_Data(idx, 0).nexus()->drivers_constant()) {
flag = false;
break;
}
if (obj->pin_Data(idx, 0).nexus()->driven_value() != verinum::Vz) {
flag = false;
break;
}
if (! obj->pin_Data(0).nexus()->drivers_constant()) {
flag = false;
}
if (flag && obj->pin_Data(0).nexus()->driven_value() != verinum::Vz) {
flag = false;
}
if (flag) {
NetScope*scope = obj->scope();
for (unsigned idx = 0 ; idx < obj->width() ; idx += 1) {
NetLogic*tmp = new NetLogic(obj->scope(),
scope->local_symbol(),
3, NetLogic::BUFIF1);
connect(obj->pin_Result(idx), tmp->pin(0));
connect(obj->pin_Data(idx,1), tmp->pin(1));
connect(obj->pin_Sel(0), tmp->pin(2));
des->add_node(tmp);
}
replace_with_bufif(des, obj, NetLogic::BUFIF1);
count += 1;
delete obj;
return;
}
/* If instead the second input is all constant Vz, replace the
NetMux with an array of BUFIF0 devices. */
flag = true;
for (unsigned idx = 0 ; idx < obj->width() ; idx += 1) {
if (! obj->pin_Data(idx, 1).nexus()->drivers_constant()) {
flag = false;
break;
}
if (! obj->pin_Data(1).nexus()->drivers_constant()) {
flag = false;
}
if (obj->pin_Data(idx, 1).nexus()->driven_value() != verinum::Vz) {
flag = false;
break;
}
if (flag && obj->pin_Data(1).nexus()->driven_value() != verinum::Vz) {
flag = false;
}
if (flag) {
NetScope*scope = obj->scope();
for (unsigned idx = 0 ; idx < obj->width() ; idx += 1) {
NetLogic*tmp = new NetLogic(obj->scope(),
scope->local_symbol(),
3, NetLogic::BUFIF0);
connect(obj->pin_Result(idx), tmp->pin(0));
connect(obj->pin_Data(idx,0), tmp->pin(1));
connect(obj->pin_Sel(0), tmp->pin(2));
des->add_node(tmp);
}
replace_with_bufif(des, obj, NetLogic::BUFIF0);
count += 1;
delete obj;
return;
}
}
@@ -1038,6 +950,37 @@ void cprop(Design*des)
/*
* $Log: cprop.cc,v $
* Revision 1.56 2007/03/07 00:38:15 steve
* Lint fixes.
*
* Revision 1.55 2006/05/24 04:32:57 steve
* Fix handling of ternary-to-bufif0 constant propagation.
*
* Revision 1.54 2005/07/15 19:22:52 steve
* bufif enable is LOGIC.
*
* Revision 1.53 2005/05/15 04:44:30 steve
* Disable obsolete logic constant fixup code.
*
* Revision 1.52 2005/04/24 23:44:01 steve
* Update DFF support to new data flow.
*
* Revision 1.51 2005/02/12 22:52:45 steve
* Fix copyright notice.
*
* Revision 1.50 2005/02/12 06:25:40 steve
* Restructure NetMux devices to pass vectors.
* Generate NetMux devices from ternary expressions,
* Reduce NetMux devices to bufif when appropriate.
*
* Revision 1.49 2005/01/16 04:20:32 steve
* Implement LPM_COMPARE nodes as two-input vector functors.
*
* Revision 1.48 2004/12/11 02:31:25 steve
* Rework of internals to carry vectors through nexus instead
* of single bits. Make the ivl, tgt-vvp and vvp initial changes
* down this path.
*
* Revision 1.47 2004/02/20 18:53:34 steve
* Addtrbute keys are perm_strings.
*
+364 -134
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: design_dump.cc,v 1.149 2004/10/04 01:10:52 steve Exp $"
#ident "$Id: design_dump.cc,v 1.176 2007/06/02 03:42:12 steve Exp $"
#endif
# include "config.h"
@@ -29,7 +29,8 @@
# include <iostream>
# include <iomanip>
# include "netlist.h"
# include "compiler.h"
# include "ivl_assert.h"
static ostream& operator<< (ostream&o, NetBlock::Type t)
{
@@ -68,13 +69,77 @@ ostream& operator << (ostream&o, Link::strength_t str)
return o;
}
ostream& operator << (ostream&o, ivl_variable_type_t val)
{
switch (val) {
case IVL_VT_VOID:
o << "void";
break;
case IVL_VT_NO_TYPE:
o << "<no_type>";
break;
case IVL_VT_REAL:
o << "real";
break;
case IVL_VT_BOOL:
o << "bool";
break;
case IVL_VT_LOGIC:
o << "logic";
break;
}
return o;
}
static inline void dump_scope_path(ostream&o, const NetScope*scope)
{
if (const NetScope*parent = scope->parent()) {
dump_scope_path(o, parent);
o << ".";
}
const hname_t name = scope->fullname();
o << name.peek_name();
if (name.has_number())
o << "[" << name.peek_number() << "]";
}
ostream& operator <<(ostream&o, struct __ScopePathManip marg)
{
if (marg.scope != 0)
dump_scope_path(o, marg.scope);
return o;
}
void NetDelaySrc::dump(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "specify delay";
if (posedge_) o << " posedge";
if (negedge_) o << " negedge";
o << " src "
<< "(" << transition_delays_[IVL_PE_01]
<< "," << transition_delays_[IVL_PE_10]
<< "," << transition_delays_[IVL_PE_0z]
<< "/" << transition_delays_[IVL_PE_z1]
<< "," << transition_delays_[IVL_PE_1z]
<< "," << transition_delays_[IVL_PE_z0]
<< "/" << transition_delays_[IVL_PE_0x]
<< "," << transition_delays_[IVL_PE_x1]
<< "," << transition_delays_[IVL_PE_1x]
<< "/" << transition_delays_[IVL_PE_x0]
<< "," << transition_delays_[IVL_PE_xz]
<< "," << transition_delays_[IVL_PE_zx]
<< "): " << endl;
dump_node_pins(o, ind+4);
}
/* Dump a net. This can be a wire or register. */
void NetNet::dump_net(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << type() << ": " << name() << "[" <<
pin_count() << "]";
o << setw(ind) << "" << type() << ": " << name()
<< "[" << s0_ << ":" << e0_ << " count=" << pin_count() << "]";
if (local_flag_)
o << " (local)";
o << " " << data_type_;
if (signed_)
o << " signed";
switch (port_type_) {
@@ -95,9 +160,11 @@ void NetNet::dump_net(ostream&o, unsigned ind) const
}
o << " (eref=" << peek_eref() << ", lref=" << peek_lref() << ")";
if (scope())
o << " scope=" << scope()->name();
o << " #(" << rise_time() << "," << fall_time() << "," <<
decay_time() << ") init=";
o << " scope=" << scope_path(scope());
o << " #(" << rise_time() << "," << fall_time() << ","
<< decay_time() << ") vector_width=" << vector_width()
<< " pin_count=" << pin_count()
<< " init=";
for (unsigned idx = pin_count() ; idx > 0 ; idx -= 1)
o << pin(idx-1).get_init();
@@ -114,23 +181,15 @@ void NetNet::dump_net(ostream&o, unsigned ind) const
o << setw(ind+4) << "" << "[" << idx << "]: " << nex
<< " " << nex->name() << endl;
}
for (unsigned idx = 0 ; idx < delay_paths_.size() ; idx += 1) {
const NetDelaySrc*cur = delay_paths_[idx];
cur->dump(o, ind+4);
}
dump_obj_attr(o, ind+4);
}
void NetSubnet::dump_net(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "** " << name() << " is a NetSubnet **"
<< endl;
NetNet::dump_net(o, ind);
}
void NetMemory::dump(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << name_ << "[" << width_ << "] " <<
"[" << idxh_ << ":" << idxl_ << "]" << endl;
}
/* Dump a NetNode and its pins. Dump what I know about the netnode on
the first line, then list all the pins, with the name of the
connected signal. */
@@ -189,16 +248,20 @@ void NetObj::dump_obj_attr(ostream&o, unsigned ind) const
void NetAddSub::dump_node(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "Adder (NetAddSub): " << name() << endl;
o << setw(ind) << "" << "Adder (NetAddSub): " << name()
<< " width=" << width() << " pin_count=" << pin_count()
<< endl;
dump_node_pins(o, ind+4);
dump_obj_attr(o, ind+4);
}
void NetCAssign::dump_node(ostream&o, unsigned ind) const
void NetArrayDq::dump_node(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "Procedural continuous assign (NetCAssign): "
<< name() << endl;
o << setw(ind) << "" << "NetArrayDq: " << name()
<< " array=" << mem_->name()
<< endl;
dump_node_pins(o, ind+4);
dump_obj_attr(o, ind+4);
}
void NetCLShift::dump_node(ostream&o, unsigned ind) const
@@ -216,6 +279,16 @@ void NetCompare::dump_node(ostream&o, unsigned ind) const
dump_obj_attr(o, ind+4);
}
void NetConcat::dump_node(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "NetConcat: "
<< name()
<< " scope=" << scope_path(scope())
<< " width=" << width_ << endl;
dump_node_pins(o, ind+4);
dump_obj_attr(o, ind+4);
}
void NetDivide::dump_node(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "NET_DIVIDE (NetDivide): " << name() << endl;
@@ -223,12 +296,6 @@ void NetDivide::dump_node(ostream&o, unsigned ind) const
dump_obj_attr(o, ind+4);
}
void NetForce::dump_node(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "force " << lval_->name() << endl;
dump_node_pins(o, ind+4);
}
void NetMult::dump_node(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "LPM_MULT (NetMult): " << name() << endl;
@@ -239,7 +306,8 @@ void NetMult::dump_node(ostream&o, unsigned ind) const
void NetMux::dump_node(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "Multiplexer (NetMux): " << name()
<< " scope=" << scope()->name() << endl;
<< " width=" << width_ << " swidth=" << swidth_ << " size=" << size_
<< " scope=" << scope_path(scope()) << endl;
dump_node_pins(o, ind+4);
dump_obj_attr(o, ind+4);
}
@@ -247,22 +315,26 @@ void NetMux::dump_node(ostream&o, unsigned ind) const
void NetBUFZ::dump_node(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "NetBUFZ: " << name()
<< " scope=" << (scope()? scope()->name() : "")
<< " scope=" << scope_path(scope())
<< " delay=(" << rise_time() << "," << fall_time() << "," <<
decay_time() << ")" << endl;
decay_time() << ") width=" << width() << endl;
dump_node_pins(o, ind+4);
}
void NetCaseCmp::dump_node(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "case compare === : " << name() << endl;
if (eeq_)
o << setw(ind) << "" << "case compare === : " << name() << endl;
else
o << setw(ind) << "" << "case compare !== : " << name() << endl;
dump_node_pins(o, ind+4);
}
void NetConst::dump_node(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "constant ";
for (unsigned idx = pin_count() ; idx > 0 ; idx -= 1)
o << setw(ind) << "" << "constant " << width_ << "'b";
for (unsigned idx = width_ ; idx > 0 ; idx -= 1)
o << value_[idx-1];
o << ": " << name() << endl;
dump_node_pins(o, ind+4);
@@ -271,13 +343,20 @@ void NetConst::dump_node(ostream&o, unsigned ind) const
void NetFF::dump_node(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "LPM_FF: " << name()
<< " scope=" << (scope()? scope()->name() : "")
<< " scope=" << scope_path(scope())
<< " aset_value=" << aset_value_ << endl;
dump_node_pins(o, ind+4);
dump_obj_attr(o, ind+4);
}
void NetLiteral::dump_node(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "constant real " << real_
<< ": " << name() << endl;
dump_node_pins(o, ind+4);
}
void NetLogic::dump_node(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "logic: ";
@@ -339,7 +418,7 @@ void NetLogic::dump_node(ostream&o, unsigned ind) const
}
o << " #(" << rise_time()
<< "," << fall_time() << "," << decay_time() << ") " << name()
<< " scope=" << (scope()? scope()->name() : "")
<< " scope=" << scope_path(scope())
<< endl;
dump_node_pins(o, ind+4);
@@ -353,17 +432,88 @@ void NetModulo::dump_node(ostream&o, unsigned ind) const
dump_obj_attr(o, ind+4);
}
void NetRamDq::dump_node(ostream&o, unsigned ind) const
void NetPartSelect::dump_node(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "LPM_RAM_DQ (" << mem_->name() << "): "
<< name() << endl;
const char*pt = "";
switch (dir_) {
case VP:
pt = "VP";
break;
case PV:
pt = "PV";
break;
case BI:
pt = "BI";
break;
}
o << setw(ind) << "" << "NetPartSelect(" << pt << "): "
<< name() << " off=" << off_ << " wid=" << wid_ <<endl;
dump_node_pins(o, ind+4);
dump_obj_attr(o, ind+4);
}
void NetReplicate::dump_node(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "NetReplicate: "
<< name() << " wid=" << width_ << ", repeat_=" << repeat_
<< ", input wid=" << width_/repeat_ << endl;
dump_node_pins(o, ind+4);
dump_obj_attr(o, ind+4);
}
void NetSignExtend::dump_node(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "NetSignExtend: "
<< name() << " output width=" << width_ << endl;
dump_node_pins(o, ind+4);
dump_obj_attr(o, ind+4);
}
void NetUReduce::dump_node(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "reduction logic: ";
switch (type_) {
case NONE:
o << "NONE";
break;
case AND:
o << "and";
break;
case OR:
o << "or";
break;
case XOR:
o << "xor";
break;
case NAND:
o << "nand";
break;
case NOR:
o << "nor";
break;
case XNOR:
o << "xnor";
break;
}
o << " #(" << rise_time()
<< "," << fall_time() << "," << decay_time() << ") " << name()
<< " scope=" << scope_path(scope())
<< endl;
dump_node_pins(o, ind+4);
dump_obj_attr(o, ind+4);
}
void NetSysFunc::dump_node(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << def_->name << "(...)" << endl;
dump_node_pins(o, ind+4);
dump_obj_attr(o, ind+4);
}
void NetUserFunc::dump_node(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << def_->name() << "(";
o << setw(ind) << "" << scope_path(def_) << "(";
o << ")" << endl;
dump_node_pins(o, ind+4);
dump_obj_attr(o, ind+4);
@@ -371,7 +521,7 @@ void NetUserFunc::dump_node(ostream&o, unsigned ind) const
void NetTaskDef::dump(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "task " << name_ << ";" << endl;
o << setw(ind) << "" << "task " << scope_path(scope_) << ";" << endl;
for (unsigned idx = 0 ; idx < ports_.count() ; idx += 1) {
o << setw(ind+4) << "";
@@ -413,11 +563,11 @@ void NetProcTop::dump(ostream&o, unsigned ind) const
switch (type_) {
case NetProcTop::KINITIAL:
o << "initial /* " << get_line() << " in "
<< scope_->name() << " */" << endl;
<< scope_path(scope_) << " */" << endl;
break;
case NetProcTop::KALWAYS:
o << "always /* " << get_line() << " in "
<< scope_->name() << " */" << endl;
<< scope_path(scope_) << " */" << endl;
break;
}
@@ -433,22 +583,12 @@ void NetAssign_::dump_lval(ostream&o) const
{
if (sig_) {
o << sig_->name();
if (bmux_) {
o << "[" << *bmux_ << "]";
} else {
o << "[" << (loff_+lwid_-1) << ":" << loff_ << "]";
if (word_) {
o << "[word=" << *word_ << "]";
}
if (base_) {
o << "[" << *base_ << " +: " << lwid_ << "]";
}
} else if (mem_) {
// Is there an obvious way to flag memories in the dump
// as different from the _real_ bit mux case?
// o << "**memory**";
o << mem_->name() << "[";
if (bmux_) o << *bmux_;
else o << "**oops**";
o << "]";
} else if (var_) {
o << "<real " << var_->basename() << ">";
} else {
o << "";
}
@@ -474,10 +614,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
if (const NetExpr*de = get_delay())
o << "#(" << *de << ") ";
o << *rval() << ";" << endl;
}
@@ -487,10 +627,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
if (const NetExpr*de = get_delay())
o << "#(" << *de << ") ";
o << *rval() << ";" << endl;
}
@@ -509,7 +649,7 @@ void NetBlock::dump(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << type_;
if (subscope_)
o << " : " << subscope_->name();
o << " : " << scope_path(subscope_);
o << endl;
if (last_) {
@@ -557,8 +697,9 @@ void NetCase::dump(ostream&o, unsigned ind) const
void NetCAssign::dump(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "cassign " << lval_->name() << " = "
<< name() << ";" << endl;
o << setw(ind) << "" << "cassign ";
dump_lval(o);
o << " = " << *rval() << "; /* " << get_line() << " */" << endl;
}
void NetCondit::dump(ostream&o, unsigned ind) const
@@ -578,13 +719,14 @@ void NetCondit::dump(ostream&o, unsigned ind) const
void NetDeassign::dump(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "deassign " << lval_->name() << "; "
<< "/* " << get_line() << " */" << endl;
o << setw(ind) << "" << "deassign ";
dump_lval(o);
o << "; /* " << get_line() << " */" << endl;
}
void NetDisable::dump(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "disable " << target_->name() << "; "
o << setw(ind) << "" << "disable " << scope_path(target_) << "; "
<< "/* " << get_line() << " */" << endl;
}
@@ -603,7 +745,7 @@ void NetEvProbe::dump_node(ostream&o, unsigned ind) const
o << "negedge ";
break;
}
o << setw(ind) << "" << "-> " << event_->full_name() << "; " << endl;
o << setw(ind) << "" << "-> " << event_->name() << "; " << endl;
dump_node_pins(o, ind+4);
dump_obj_attr(o, ind+4);
}
@@ -616,11 +758,13 @@ void NetEvTrig::dump(ostream&o, unsigned ind) const
void NetEvWait::dump(ostream&o, unsigned ind) const
{
assert(nevents() > 0);
o << setw(ind) <<"" << "@(" << event(0)->full_name();
o << setw(ind) <<"" << "@(";
if (nevents() > 0)
o << event(0)->name();
for (unsigned idx = 1 ; idx < nevents() ; idx += 1)
o << " or " << event(idx)->full_name();
o << " or " << event(idx)->name();
o << ") // " << get_line() << endl;
@@ -632,8 +776,9 @@ void NetEvWait::dump(ostream&o, unsigned ind) const
void NetForce::dump(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "force " << lval_->name() << " = "
<< name() << ";" << endl;
o << setw(ind) << "" << "force ";
dump_lval(o);
o << " = " << *rval() << "; /* " << get_line() << " */" << endl;
}
void NetForever::dump(ostream&o, unsigned ind) const
@@ -644,14 +789,10 @@ void NetForever::dump(ostream&o, unsigned ind) const
void NetFuncDef::dump(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "function " << scope_->name() << endl;
o << setw(ind) << "" << "function " << scope_path(scope_) << endl;
if (result_sig_)
o << setw(ind+2) << "" << "Return signal: "
<< result_sig_->name() << endl;
if (result_var_)
o << setw(ind+2) << "" << "Return variable: "
<< result_var_->basename() << endl;
if (statement_)
statement_->dump(o, ind+2);
else
@@ -677,12 +818,9 @@ void NetPDelay::dump(ostream&o, unsigned ind) const
void NetRelease::dump(ostream&o, unsigned ind) const
{
if (lval_)
o << setw(ind) << "" << "release " << lval_->name() << "; "
<< "/* " << get_line() << " */" << endl;
else
o << setw(ind) << "" << "release (null); "
<< "/* " << get_line() << " */" << endl;
o << setw(ind) << "" << "release ";
dump_lval(o);
o << "; /* " << get_line() << " */" << endl;
}
void NetRepeat::dump(ostream&o, unsigned ind) const
@@ -694,7 +832,7 @@ void NetRepeat::dump(ostream&o, unsigned ind) const
void NetScope::dump(ostream&o) const
{
/* This is a constructed hierarchical name. */
o << name();
o << scope_path(this);
switch (type_) {
case BEGIN_END:
@@ -712,6 +850,9 @@ void NetScope::dump(ostream&o) const
case TASK:
o << " task";
break;
case GENBLOCK:
o << " generate block";
break;
}
o << endl;
@@ -749,7 +890,7 @@ void NetScope::dump(ostream&o) const
/* Dump the saved defparam assignments here. */
{
map<hname_t,NetExpr*>::const_iterator pp;
map<pform_name_t,NetExpr*>::const_iterator pp;
for (pp = defparams.begin()
; pp != defparams.end() ; pp ++ ) {
o << " defparam " << (*pp).first << " = " <<
@@ -757,15 +898,11 @@ void NetScope::dump(ostream&o) const
}
}
for (NetVariable*cur = vars_ ; cur ; cur = cur->snext_) {
o << " real " << cur->basename() << " // "
<< cur->get_line() << endl;
}
/* Dump the events in this scope. */
for (NetEvent*cur = events_ ; cur ; cur = cur->snext_) {
o << " event " << cur->name() << "; nprobe="
<< cur->nprobe() << " // " << cur->get_line() << endl;
<< cur->nprobe() << " scope=" << scope_path(cur->scope())
<< " // " << cur->get_line() << endl;
}
// Dump the signals,
@@ -777,13 +914,25 @@ void NetScope::dump(ostream&o) const
} while (cur != signals_->sig_next_);
}
// Dump the memories,
if (memories_) {
NetMemory*cur = memories_->snext_;
do {
cur->dump(o, 4);
cur = cur->snext_;
} while (cur != memories_->snext_);
// Dump specparams
typedef map<perm_string,spec_val_t>::const_iterator specparam_it_t;
for (specparam_it_t cur = specparams.begin()
; cur != specparams.end() ; cur ++ ) {
o << " specparam " << (*cur).first
<< " = ";
spec_val_t value = (*cur).second;
switch (value.type) {
case IVL_VT_REAL:
o << "R:" << value.real_val;
break;
case IVL_VT_BOOL:
o << "I:" << value.integer;
break;
default:
o << "<bad type>";
break;
}
o << endl;
}
switch (type_) {
@@ -827,7 +976,7 @@ void NetSTask::dump(ostream&o, unsigned ind) const
void NetUTask::dump(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << task_->name() << ";" << endl;
o << setw(ind) << "" << scope_path(task_) << ";" << endl;
}
void NetWhile::dump(ostream&o, unsigned ind) const
@@ -887,6 +1036,9 @@ void NetEBinary::dump(ostream&o) const
case 'O':
o << "~|";
break;
case 'p':
o << "**";
break;
case 'r':
o << ">>";
break;
@@ -937,7 +1089,7 @@ void NetEConstParam::dump(ostream&o) const
{
o << "<" << name_ << "=";
NetEConst::dump(o);
o << ">";
o << ", wid=" << expr_width() << ">";
}
void NetECReal::dump(ostream&o) const
@@ -959,7 +1111,7 @@ void NetEEvent::dump(ostream&o) const
void NetEScope::dump(ostream&o) const
{
o << "<scope=" << scope_->name() << ">";
o << "<scope=" << scope_path(scope_) << ">";
}
void NetESelect::dump(ostream&o) const
@@ -995,30 +1147,19 @@ void NetESignal::dump(ostream&o) const
{
if (has_sign())
o << "+";
o << name() << "[" << msi_<<":"<<lsi_ << "]";
}
void NetEBitSel::dump(ostream&o) const
{
sig_->dump(o);
o << "[";
idx_->dump(o);
o << "]";
}
void NetEMemory::dump(ostream&o) const
{
o << mem_->name() << "[";
if (idx_) idx_->dump(o);
o << "]";
o << name();
if (word_) o << "[word=" << *word_ << "]";
o << "[" << msi()<<":"<<lsi() << "]";
}
void NetEParam::dump(ostream&o) const
{
if (scope_ != 0)
o << "<" << scope_->name() << "." << name_ << ">";
else
o << "<" << scope_path(scope_) << "." << name_ << ">";
else if (name_)
o << "<" << name_ << ">";
else
o << "<" "???" ">";
}
void NetETernary::dump(ostream&o) const
@@ -1029,7 +1170,7 @@ void NetETernary::dump(ostream&o) const
void NetEUFunc::dump(ostream&o) const
{
o << name() << "(";
o << func_->basename() << "(";
if (parms_.count() > 0) {
parms_[0]->dump(o);
for (unsigned idx = 1 ; idx < parms_.count() ; idx += 1) {
@@ -1055,11 +1196,6 @@ void NetEUnary::dump(ostream&o) const
o << ")";
}
void NetEVariable::dump(ostream&o) const
{
o << var_->basename();
}
void Design::dump(ostream&o) const
{
o << "DESIGN TIME PRECISION: 10e" << get_precision() << endl;
@@ -1089,6 +1225,100 @@ void Design::dump(ostream&o) const
/*
* $Log: design_dump.cc,v $
* Revision 1.176 2007/06/02 03:42:12 steve
* Properly evaluate scope path expressions.
*
* Revision 1.175 2007/05/24 04:07:11 steve
* Rework the heirarchical identifier parse syntax and pform
* to handle more general combinations of heirarch and bit selects.
*
* Revision 1.174 2007/03/02 06:13:22 steve
* Add support for edge sensitive spec paths.
*
* Revision 1.173 2007/02/01 03:14:33 steve
* Detect and report arrays without index in net contexts.
*
* Revision 1.172 2007/01/16 05:44:14 steve
* Major rework of array handling. Memories are replaced with the
* more general concept of arrays. The NetMemory and NetEMemory
* classes are removed from the ivl core program, and the IVL_LPM_RAM
* lpm type is removed from the ivl_target API.
*
* Revision 1.171 2006/10/30 05:44:49 steve
* Expression widths with unsized literals are pseudo-infinite width.
*
* Revision 1.170 2006/10/03 05:06:00 steve
* Support real valued specify delays, properly scaled.
*
* Revision 1.169 2006/09/26 19:48:40 steve
* Missing PSpec.cc file.
*
* Revision 1.168 2006/09/23 04:57:19 steve
* Basic support for specify timing.
*
* Revision 1.167 2006/07/31 03:50:17 steve
* Add support for power in constant expressions.
*
* Revision 1.166 2006/06/18 04:15:50 steve
* Add support for system functions in continuous assignments.
*
* Revision 1.165 2006/04/10 00:37:42 steve
* Add support for generate loops w/ wires and gates.
*
* Revision 1.164 2006/02/02 02:43:57 steve
* Allow part selects of memory words in l-values.
*
* Revision 1.163 2005/08/27 04:32:08 steve
* Handle synthesis of fully packed case statements.
*
* Revision 1.162 2005/07/11 16:56:50 steve
* Remove NetVariable and ivl_variable_t structures.
*
* Revision 1.161 2005/07/07 16:22:49 steve
* Generalize signals to carry types.
*
* Revision 1.160 2005/05/24 01:44:27 steve
* Do sign extension of structuran nets.
*
* Revision 1.159 2005/05/17 20:56:55 steve
* Parameters cannot have their width changed.
*
* Revision 1.158 2005/05/07 03:13:30 steve
* Include delay expressions for assignments in dump.
*
* Revision 1.157 2005/03/09 05:52:03 steve
* Handle case inequality in netlists.
*
* Revision 1.156 2005/02/08 00:12:36 steve
* Add the NetRepeat node, and code generator support.
*
* Revision 1.155 2005/02/03 04:56:20 steve
* laborate reduction gates into LPM_RED_ nodes.
*
* Revision 1.154 2005/01/24 05:28:30 steve
* Remove the NetEBitSel and combine all bit/part select
* behavior into the NetESelect node and IVL_EX_SELECT
* ivl_target expression type.
*
* Revision 1.153 2005/01/22 18:16:00 steve
* Remove obsolete NetSubnet class.
*
* Revision 1.152 2005/01/09 20:16:00 steve
* Use PartSelect/PV and VP to handle part selects through ports.
*
* Revision 1.151 2004/12/29 23:55:43 steve
* Unify elaboration of l-values for all proceedural assignments,
* including assing, cassign and force.
*
* Generate NetConcat devices for gate outputs that feed into a
* vector results. Use this to hande gate arrays. Also let gate
* arrays handle vectors of gates when the outputs allow for it.
*
* Revision 1.150 2004/12/11 02:31:25 steve
* Rework of internals to carry vectors through nexus instead
* of single bits. Make the ivl, tgt-vvp and vvp initial changes
* down this path.
*
* Revision 1.149 2004/10/04 01:10:52 steve
* Clean up spurious trailing white space.
*
+8
View File
@@ -277,6 +277,7 @@ static int parse(int argc, char *argv[])
char dot_c_ext[] = ".c";
char dot_cc_ext[] = ".cc";
char dot_cpp_ext[] = ".cpp";
char dot_o_ext[] = ".o";
char name_option[] = "--name=";
char lib_option[] = "-l";
@@ -301,6 +302,13 @@ static int parse(int argc, char *argv[])
if (!*gstr.pOUT)
assignn(&gstr.pOUT,argv[idx],strlen(argv[idx])-strlen(dot_cc_ext));
}
else if (endsIn(dot_cpp_ext,argv[idx])) { /* check for C++ source files */
++srcFileCnt;
append(&gstr.pCXSRC,argv[idx]);
append(&gstr.pCXSRC," ");
if (!*gstr.pOUT)
assignn(&gstr.pOUT,argv[idx],strlen(argv[idx])-strlen(dot_cpp_ext));
}
else if (endsIn(dot_o_ext,argv[idx])) { /* check for compiled object files */
++srcFileCnt;
append(&gstr.pOBJ,argv[idx]);
+4 -4
View File
@@ -16,7 +16,7 @@
# 59 Temple Place - Suite 330
# Boston, MA 02111-1307, USA
#
#ident "$Id: Makefile.in,v 1.24 2004/10/13 22:01:34 steve Exp $"
#ident "$Id: Makefile.in,v 1.26 2007/02/06 05:07:31 steve Exp $"
#
#
SHELL = /bin/sh
@@ -50,7 +50,7 @@ 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
rm -f iverilog@EXEEXT@
rm -f iverilog@EXEEXT@ iverilog.pdf iverilog.ps
distclean: clean
rm -f Makefile
@@ -80,7 +80,7 @@ iverilog.ps: $(srcdir)/iverilog.man
iverilog.pdf: iverilog.ps
ps2pdf iverilog.ps iverilog.pdf
ifeq (@WIN32@,yes)
ifeq (@MING32@,yes)
INSTALL_DOC = $(prefix)/iverilog.pdf $(mandir)/man1/iverilog.1
INSTALL_DOCDIR = $(mandir)/man1
all: iverilog.pdf
@@ -105,4 +105,4 @@ installdirs: ../mkinstalldirs
uninstall:
rm -f $(bindir)/iverilog@EXEEXT@
rm -f $(mandir)/man1/iverilog.1
rm -f $(mandir)/man1/iverilog.1 $(prefix)/iverilog.pdf
+42 -6
View File
@@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: cflexor.lex,v 1.8 2004/10/04 01:10:56 steve Exp $"
#ident "$Id: cflexor.lex,v 1.11 2007/03/22 16:08:18 steve Exp $"
#endif
# include "cfparse.h"
@@ -37,12 +37,14 @@
YYLTYPE yylloc;
static int comment_enter;
static char* trim_trailing_white(char*txt, int trim);
%}
%x CCOMMENT
%x LCOMMENT
%x PLUS_ARGS
%x FILE_NAME
%%
@@ -76,6 +78,7 @@ static int comment_enter;
"+libext+" { BEGIN(PLUS_ARGS); return TOK_LIBEXT; }
"+integer-width+" { BEGIN(PLUS_ARGS); return TOK_INTEGER_WIDTH; }
/* If it is not any known plus-flag, return the generic form. */
"+"[^\n \t\b\f\r+]* {
@@ -112,17 +115,50 @@ static int comment_enter;
/* 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; }
"/"[\r\n] { /* Special case of file name "/" */
cflval.text = trim_trailing_white(yytext, 0);
return TOK_STRING; }
"/"[^\*\/] { /* A file name that starts with "/". */
yymore();
BEGIN(FILE_NAME); }
[^/\n \t\b\r+-][^/\n\r]* { /* A file name that starts with other than "/" */
yymore();
BEGIN(FILE_NAME); }
<FILE_NAME>"//" {
/* Found a trailing comment. Returning the terminated name. */
cflval.text = trim_trailing_white(yytext, 2);
BEGIN(LCOMMENT);
return TOK_STRING; }
<FILE_NAME>"/"?[^/\n\r]* {
yymore();
/* not a comment... continuing */; }
<FILE_NAME>[\n\r] {
/* No trailing comment. Return the file name. */
cflval.text = trim_trailing_white(yytext, 0);
BEGIN(0);
return TOK_STRING; }
/* Fallback match. */
. { return yytext[0]; }
%%
static char* trim_trailing_white(char*text, int trim)
{
char*cp = text + strlen(text);
while (cp > text && trim > 0) {
trim -= 1;
cp -= 1;
*cp = 0;
}
while (cp > text && strchr("\n\r\t\b", cp[-1]))
cp -= 1;
cp[0] = 0;
return strdup(text);
}
int yywrap()
{
return 1;
+13 -5
View File
@@ -18,7 +18,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: cfparse.y,v 1.10 2003/09/26 21:25:58 steve Exp $"
#ident "$Id: cfparse.y,v 1.12 2007/04/19 02:52:53 steve Exp $"
#endif
@@ -62,6 +62,7 @@ static void translate_file_name(char*text)
%token TOK_Da TOK_Dv TOK_Dy
%token TOK_DEFINE TOK_INCDIR TOK_LIBDIR TOK_LIBDIR_NOCASE TOK_LIBEXT
%token TOK_INTEGER_WIDTH
%token <text> TOK_PLUSARG TOK_PLUSWORD TOK_STRING
%%
@@ -83,7 +84,7 @@ item
: TOK_STRING
{ char*tmp = substitutions($1);
translate_file_name(tmp);
process_file_name(tmp);
process_file_name(tmp, 0);
free($1);
free(tmp);
}
@@ -98,9 +99,7 @@ item
| TOK_Dv TOK_STRING
{ char*tmp = substitutions($2);
translate_file_name(tmp);
process_file_name(tmp);
fprintf(stderr, "%s:%u: Ignoring -v in front of %s\n",
@1.text, @1.first_line, $2);
process_file_name(tmp, 1);
free($2);
free(tmp);
}
@@ -145,6 +144,15 @@ item
| TOK_LIBEXT libext_args
/* These are various misc flags that are supported. */
| TOK_INTEGER_WIDTH TOK_PLUSARG
{ char*tmp = substitutions($2);
free($2);
integer_width = strtoul(tmp,0,10);
free(tmp);
}
/* The +<word> tokens that are not otherwise matched, are
ignored. The skip_args rule arranges for all the argument words
to be consumed. */
+11 -2
View File
@@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: globals.h,v 1.19 2003/11/18 06:31:46 steve Exp $"
#ident "$Id: globals.h,v 1.21 2007/04/19 02:52:53 steve Exp $"
#endif
# include <stddef.h>
@@ -49,11 +49,14 @@ extern int synth_flag;
/* This is the name of the selected target. */
extern const char*targ;
/* This is the integer-width argument that will be passed to ivl. */
extern unsigned integer_width;
/* Perform variable substitutions on the string. */
extern char* substitutions(const char*str);
/* Add the name to the list of source files. */
extern void process_file_name(const char*name);
extern void process_file_name(const char*name, int lib_flag);
/* Add the name to the list of library directories. */
extern void process_library_switch(const char*name);
@@ -77,6 +80,12 @@ extern char* library_flags2;
/*
* $Log: globals.h,v $
* Revision 1.21 2007/04/19 02:52:53 steve
* Add support for -v flag in command file.
*
* Revision 1.20 2007/03/07 04:24:59 steve
* Make integer width controllable.
*
* Revision 1.19 2003/11/18 06:31:46 steve
* Remove the iverilog.conf file.
*
+30 -7
View File
@@ -1,10 +1,10 @@
.TH iverilog 1 "$Date: 2004/10/04 01:10:56 $" Version "$Date: 2004/10/04 01:10:56 $"
.TH iverilog 1 "$Date: 2007/06/05 01:56:12 $" Version "$Date: 2007/06/05 01:56:12 $"
.SH NAME
iverilog - Icarus Verilog compiler
.SH SYNOPSIS
.B iverilog
[-ESVv] [-Bpath] [-ccmdfile] [-g1|-g2|-g3.0] [-Dmacro[=defn]] [-pflag=value]
[-ESVv] [-Bpath] [-ccmdfile] [-g1|-g2|-g2x|-gspecify-gxtypes] [-Dmacro[=defn]] [-pflag=value]
[-Iincludedir] [-mmodule] [-Mfile] [-Nfile] [-ooutputfilename]
[-stopmodule] [-ttype] [-Tmin/typ/max] [-Wclass] [-ypath] sourcefile
@@ -48,15 +48,30 @@ is the Verilog input, but with file inclusions and macro references
expanded and removed. This is useful, for example, to preprocess
Verilog source for use by other compilers.
.TP 8
.B -g1\fI|\fP-g2\fI|\fP-g3.0
.B -g1\fI|\fP-g2\fI|\fP-g2x
Select the Verilog language \fIgeneration\fP to support in the
compiler. This selects between \fIIEEE1364-1995\fP(1),
\fIIEEE1364-2001\fP(2), or \fISystemVerilog 3.0\fP(3.0). Normally,
\fIIEEE1364-2001\fP(2), or \fIVerilog with extension\fP(2x). Normally,
Icarus Verilog defaults to the latest known generation of the
language. This flag is most useful to restrict the language to a set
supported by tools of specific generations, for compatibility with
other tools.
.TP 8
.B -gspecify\fI|\fP-gno-specify
Enable (default) or disable specify block support. When enabled,
specify block code is elaborated. When disabled, specify blocks are
parsed but ignored. Specify blocks are commonly not needed for RTL
simulation, and in fact can hurt performance of the
simulation. However, disabling specify blocks reduces accuracy of
full-timing simulations.
.TP 8
.B -gxtypes\fI|\fP-gno-xtypes
Enable (default) or disable support for extended types. Enabling
extended types allows for new types that are supported by Icarus
Verilog as extensions beyond the baseline Verilog. It may be necessary
to disable extended types if compiling code that clashes with the few
new keywords used to implement the type system.
.TP 8
.B -I\fIincludedir\fP
Append directory \fIincludedir\fP to list of directories searched
for Verilog include files. The \fB-I\fP switch may be used many times
@@ -74,6 +89,8 @@ leading or trailing space.
Add this module to the list of VPI modules to be loaded by the
simulation. Many modules can be specified, and all will be loaded, in
the order specified. The system module is implicit and always included.
If a System Function Table file (<module>.sft) exists for the module it
will be loaded automatically.
.TP 8
.B -N\fIpath\fP
This is used for debugging the compiler proper. Dump the final netlist
@@ -184,7 +201,7 @@ implies the synthesis \fB-S\fP flag.
.SH "WARNING TYPES"
These are the types of warnings that can be selected by the \fB-W\fP
switch. All the warning types (other then \fBall\fP) can also be
switch. All the warning types (other than \fBall\fP) can also be
prefixed with \fBno-\fP to turn off that warning. This is most useful
after a \fB-Wall\fP argument to suppress isolated warning types.
@@ -249,7 +266,7 @@ well as # comments, if the # starts the line.
.I "file name"
A simple file name or file path is taken to be the name of a Verilog
source file. The path starts with the first non-white-space
character. Variables are substitued in file names.
character. Variables are substituted in file names.
.TP 8
.B -y\ \fIlibdir\fP
@@ -304,13 +321,19 @@ become munged.
.B +tolower-filename\fP
This is similar to the \fB+toupper-filename\fP hack described above.
.TP 8
.B +integer-width+\fIvalue\fP
This allows the programmer to select the width for integer variables
in the Verilog source. The default is 32, the value can be any desired
integer value.
.SH "VARIABLES IN COMMAND FILES"
In certain cases, iverilog supports variables in command files. These
are strings of the form "$(\fIvarname\fP)", where \fIvarname\fP is the
name of the environment variable to read. The entire string is
replaced with the contents of that variable. Variables are only
substitued in contexts that explicitly support them, including file
substituted in contexts that explicitly support them, including file
and directory strings.
Variable values come from the operating system environment, and not
+164 -64
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2000-2001 Stephen Williams (steve@icarus.com)
* Copyright (c) 2000-2005 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: main.c,v 1.65 2004/06/17 14:47:22 steve Exp $"
#ident "$Id: main.c,v 1.76 2007/06/05 01:56:12 steve Exp $"
#endif
# include "config.h"
@@ -39,7 +39,7 @@ const char NOTICE[] =
;
const char HELP[] =
"Usage: iverilog [-ESvV] [-B base] [-c cmdfile] [-g1|-g2|-g3.0]\n"
"Usage: iverilog [-ESvV] [-B base] [-c cmdfile] [-g1|-g2|-g2x]\n"
" [-D macro[=defn]] [-I includedir] [-M depfile] [-m module]\n"
" [-N file] [-o filename] [-p flag=value]\n"
" [-s topmodule] [-t target] [-T min|typ|max]\n"
@@ -107,12 +107,14 @@ const char*npath = 0;
const char*targ = "vvp";
const char*depfile = 0;
const char*generation = "3.0";
const char*generation = "2x";
const char*gen_specify = "specify";
const char*gen_xtypes = "xtypes";
char warning_flags[16] = "";
char*inc_list = 0;
char*def_list = 0;
unsigned integer_width = 32;
char*mod_list = 0;
char*command_filename = 0;
@@ -123,6 +125,9 @@ char*source_path = 0;
FILE*source_file = 0;
unsigned source_count = 0;
char*defines_path = 0;
FILE*defines_file = 0;
char*iconfig_path = 0;
FILE*iconfig_file = 0;
@@ -131,7 +136,6 @@ char*iconfig_common_path = iconfig_common_path_buf;
int synth_flag = 0;
int verbose_flag = 0;
int command_file = 0;
FILE *fp;
@@ -140,6 +144,48 @@ char tmp[MAXSIZE];
static char ivl_root[MAXSIZE];
/* Structure to keep a FIFO list of the command files */
typedef struct t_command_file {
char *filename;
struct t_command_file *next;
} s_command_file, *p_command_file;
p_command_file cmd_file_head = NULL; /* The FIFO head */
p_command_file cmd_file_tail = NULL; /* The FIFO tail */
/* Function to add a comamnd file name to the FIFO. */
void add_cmd_file(const char* filename)
{
p_command_file new;
new = (p_command_file) malloc(sizeof(s_command_file));
new->filename = strdup(filename);
new->next = NULL;
if (cmd_file_head == NULL) {
cmd_file_head = new;
cmd_file_tail = new;
} else {
cmd_file_tail->next = new;
cmd_file_tail = new;
}
}
/* Function to return the top comamnd file name from the FIFO. */
char *get_cmd_file()
{
char *filename;
if (cmd_file_head == NULL) filename = NULL;
else {
p_command_file head;
filename = cmd_file_head->filename;
head = cmd_file_head;
cmd_file_head = cmd_file_head->next;
free(head);
}
return filename;
}
#ifdef __MINGW32__
# include <io.h>
# include <fcntl.h>
@@ -268,9 +314,12 @@ static int t_default(char*cmd, unsigned ncmd)
rc = system(cmd);
remove(source_path);
if ( ! getenv("IVERILOG_ICONFIG"))
if ( ! getenv("IVERILOG_ICONFIG")) {
remove(source_path);
remove(iconfig_path);
remove(defines_path);
}
if (rc != 0) {
if (rc == 127) {
fprintf(stderr, "Failed to execute: %s\n", cmd);
@@ -340,32 +389,12 @@ void process_library2_switch(const char *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);
}
fprintf(defines_file, "I:%s\n", 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);
}
fprintf(defines_file,"D:%s\n", name);
}
/*
@@ -374,7 +403,7 @@ void process_define(const char*name)
* .sft suffix, and if so pass that as a sys_func file. Otherwise, it
* is a Verilog source file to be written into the file list.
*/
void process_file_name(const char*name)
void process_file_name(const char*name, int lib_flag)
{
if (strlen(name) > 4 && strcasecmp(".sft", name+strlen(name)-4) == 0) {
fprintf(iconfig_file,"sys_func:%s\n", name);
@@ -382,6 +411,8 @@ void process_file_name(const char*name)
} else {
fprintf(source_file, "%s\n", name);
source_count += 1;
if (lib_flag)
fprintf(iconfig_file,"library_file:%s\n", name);
}
}
@@ -393,8 +424,20 @@ int process_generation(const char*name)
else if (strcmp(name,"2") == 0)
generation = "2";
else if (strcmp(name,"3.0") == 0)
generation = "3.0";
else if (strcmp(name,"2x") == 0)
generation = "2x";
else if (strcmp(name,"xtypes") == 0)
gen_xtypes = "xtypes";
else if (strcmp(name,"no-xtypes") == 0)
gen_xtypes = "no-xtypes";
else if (strcmp(name,"specify") == 0)
gen_specify = "specify";
else if (strcmp(name,"no-specify") == 0)
gen_specify = "no-specify";
else {
fprintf(stderr, "Unknown/Unsupported Language generation "
@@ -402,13 +445,30 @@ int process_generation(const char*name)
fprintf(stderr, "Supported generations are:\n");
fprintf(stderr, " 1 -- IEEE1364-1995 (Verilog 1)\n"
" 2 -- IEEE1364-2001 (Verilog 2001)\n"
" 3.0 -- SystemVerilog 3.0\n");
" 2x -- Verilog with extensions\n"
"Other generation flags:\n"
" specify | no-specify\n"
" xtypes | no-xtypes\n");
return 1;
}
return 0;
}
/*
* If it exists add the SFT file for the given module.
*/
void add_sft_file(const char *module)
{
char *file;
file = (char *) malloc(strlen(base)+1+strlen(module)+4+1);
sprintf(file, "%s%c%s.sft", base, sep, module);
if (access(file, R_OK) == 0)
fprintf(iconfig_file, "sys_func:%s\n", file);
free(file);
}
int main(int argc, char **argv)
{
char*cmd;
@@ -465,6 +525,19 @@ int main(int argc, char **argv)
return 1;
}
defines_path = strdup(my_tempfile("ivrlg2", &defines_file));
if (NULL == defines_file) {
fprintf(stderr, "%s: Error opening temporary file %s\n",
argv[0], defines_path);
fprintf(stderr, "%s: Please check TMP or TMPDIR.\n", argv[0]);
fclose(source_file);
remove(source_path);
return 1;
}
fprintf(defines_file, "D:__ICARUS__=1\n");
/* Create another temporary file for passing configuration
information to ivl. */
@@ -485,6 +558,9 @@ int main(int argc, char **argv)
fprintf(stderr, "%s: Please check TMP or TMPDIR.\n", argv[0]);
fclose(source_file);
remove(source_path);
fclose(defines_file);
remove(defines_path);
return 1;
}
@@ -503,8 +579,7 @@ int main(int argc, char **argv)
}
break;
case 'c':
command_filename = malloc(strlen(optarg)+1);
strcpy(command_filename, optarg);
add_cmd_file(optarg);
break;
case 'D':
process_define(optarg);
@@ -537,6 +612,7 @@ int main(int argc, char **argv)
case 'm':
fprintf(iconfig_file, "module:%s\n", optarg);
add_sft_file(optarg);
break;
case 'N':
@@ -616,11 +692,13 @@ int main(int argc, char **argv)
if (mtm != 0) fprintf(iconfig_file, "-T:%s\n", mtm);
fprintf(iconfig_file, "generation:%s\n", generation);
fprintf(iconfig_file, "generation:%s\n", gen_specify);
fprintf(iconfig_file, "generation:%s\n", gen_xtypes);
fprintf(iconfig_file, "warnings:%s\n", warning_flags);
fprintf(iconfig_file, "out:%s\n", opath);
if (depfile) fprintf(iconfig_file, "depfile:%s\n", depfile);
if (command_filename) {
while ( (command_filename = get_cmd_file()) ) {
int rc;
if (( fp = fopen(command_filename, "r")) == NULL ) {
@@ -636,17 +714,25 @@ int main(int argc, char **argv)
command_filename);
return 1;
}
free(command_filename);
}
if (depfile) {
fprintf(defines_file, "M:%s\n", depfile);
}
/* 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]);
process_file_name(argv[idx], 0);
fclose(source_file);
source_file = 0;
fclose(defines_file);
defines_file = 0;
if (source_count == 0) {
fprintf(stderr, "%s: No input files.\n", argv[0]);
fprintf(stderr, "%s\n", HELP);
@@ -656,33 +742,14 @@ int main(int argc, char **argv)
/* Start building the preprocess command line. */
sprintf(tmp, "%s%civlpp %s%s -D__ICARUS__=1 -f%s ", pbase,sep,
sprintf(tmp, "%s%civlpp %s%s -F%s -f%s ", pbase,sep,
verbose_flag?" -v":"",
e_flag?"":" -L", source_path);
e_flag?"":" -L", defines_path, source_path);
ncmd = strlen(tmp);
cmd = malloc(ncmd + 1);
strcpy(cmd, tmp);
if (inc_list) {
cmd = realloc(cmd, ncmd + strlen(inc_list) + 1);
strcat(cmd, inc_list);
ncmd += strlen(inc_list);
}
if (def_list) {
cmd = realloc(cmd, ncmd + strlen(def_list) + 1);
strcat(cmd, def_list);
ncmd += strlen(def_list);
}
if (depfile) {
cmd = realloc(cmd, ncmd + strlen(depfile) + 5);
strcat(cmd, " -M ");
strcat(cmd, depfile);
ncmd += strlen(depfile) + 4;
}
/* If the -E flag was given on the command line, then all we
do is run the preprocessor and put the output where the
user wants it. */
@@ -717,13 +784,13 @@ int main(int argc, char **argv)
return 0;
}
fprintf(iconfig_file, "iwidth:%u\n", integer_width);
/* Write the preprocessor command needed to preprocess a
single file. This may be used to preprocess library
files. */
fprintf(iconfig_file, "ivlpp:%s%civlpp -D__ICARUS__ -L %s %s\n",
pbase, sep,
inc_list? inc_list : "",
def_list? def_list : "");
fprintf(iconfig_file, "ivlpp:%s%civlpp -L -F%s\n",
pbase, sep, defines_path);
/* Done writing to the iconfig file. Close it now. */
fclose(iconfig_file);
@@ -735,6 +802,39 @@ int main(int argc, char **argv)
/*
* $Log: main.c,v $
* Revision 1.76 2007/06/05 01:56:12 steve
* Bring in .SFT file automatically if -m used.
*
* Revision 1.75 2007/04/19 02:52:53 steve
* Add support for -v flag in command file.
*
* Revision 1.74 2007/04/18 03:23:38 steve
* Add support for multiple command files. (Cary R.)
*
* Revision 1.73 2007/03/07 04:24:59 steve
* Make integer width controllable.
*
* Revision 1.72 2006/10/02 18:15:47 steve
* Fix handling of dep path in new argument passing method.
*
* Revision 1.71 2006/09/28 04:35:18 steve
* Support selective control of specify and xtypes features.
*
* Revision 1.70 2006/09/20 22:30:52 steve
* Do not pass -D__ICARUS__ to ivlpp.
*
* Revision 1.69 2006/07/26 00:11:40 steve
* Pass depfiles through temp defines file.
*
* Revision 1.68 2006/07/26 00:02:48 steve
* Pass defines and includes through temp file.
*
* Revision 1.67 2005/07/14 23:38:44 steve
* Display as version 0.9.devel
*
* Revision 1.66 2005/06/28 04:25:55 steve
* Remove reference to SystemVerilog.
*
* Revision 1.65 2004/06/17 14:47:22 steve
* Add a .sft file for the system functions.
*
+16 -14
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: dup_expr.cc,v 1.18 2004/06/17 16:06:18 steve Exp $"
#ident "$Id: dup_expr.cc,v 1.21 2006/11/04 06:10:13 steve Exp $"
#endif
# include "config.h"
@@ -67,7 +67,8 @@ NetEScope* NetEScope::dup_expr() const
NetESelect* NetESelect::dup_expr() const
{
return new NetESelect(expr_->dup_expr(), base_->dup_expr(),
return new NetESelect(expr_->dup_expr(),
base_? base_->dup_expr() : 0,
expr_width());
}
@@ -87,7 +88,7 @@ NetESFunc* NetESFunc::dup_expr() const
NetESignal* NetESignal::dup_expr() const
{
NetESignal*tmp = new NetESignal(net_, msi_, lsi_);
NetESignal*tmp = new NetESignal(net_);
assert(tmp);
tmp->expr_width(expr_width());
return tmp;
@@ -111,11 +112,7 @@ NetEUFunc* NetEUFunc::dup_expr() const
tmp_parms[idx] = parms_[idx]->dup_expr();
}
tmp = 0;
if (result_sig_)
tmp = new NetEUFunc(func_, result_sig_->dup_expr(), tmp_parms);
if (result_var_)
tmp = new NetEUFunc(func_, result_var_->dup_expr(), tmp_parms);
tmp = new NetEUFunc(func_, result_sig_->dup_expr(), tmp_parms);
assert(tmp);
return tmp;
@@ -135,14 +132,19 @@ NetEUReduce* NetEUReduce::dup_expr() const
return tmp;
}
NetEVariable* NetEVariable::dup_expr() const
{
NetEVariable*tmp = new NetEVariable(var_);
return tmp;
}
/*
* $Log: dup_expr.cc,v $
* Revision 1.21 2006/11/04 06:10:13 steve
* Handle dup of pad as well as normal select.
*
* Revision 1.20 2005/07/11 16:56:50 steve
* Remove NetVariable and ivl_variable_t structures.
*
* Revision 1.19 2004/12/11 02:31:25 steve
* Rework of internals to carry vectors through nexus instead
* of single bits. Make the ivl, tgt-vvp and vvp initial changes
* down this path.
*
* Revision 1.18 2004/06/17 16:06:18 steve
* Help system function signedness survive elaboration.
*
+15 -4
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: elab_anet.cc,v 1.10 2004/10/04 01:10:52 steve Exp $"
#ident "$Id: elab_anet.cc,v 1.13 2007/03/22 16:08:14 steve Exp $"
#endif
# include "config.h"
@@ -84,15 +84,18 @@ NetNet* PEConcat::elaborate_anet(Design*des, NetScope*scope) const
concat operator from least significant to most significant,
which is opposite from how they are given in the list.
Allow for a repeat count other then 1 by repeating the
Allow for a repeat count other than 1 by repeating the
connect loop as many times as necessary. */
NetNet*osig = new NetNet(scope, scope->local_symbol(),
NetNet::IMPLICIT_REG, pins);
/* Assume that all the data types are the same. */
osig->data_type(nets[0]->data_type());
pins = 0;
for (unsigned idx = nets.count() ; idx > 0 ; idx -= 1) {
NetNet*cur = nets[idx-1];
assert(cur->data_type() == osig->data_type());
for (unsigned pin = 0; pin < cur->pin_count(); pin += 1) {
connect(osig->pin(pins), cur->pin(pin));
pins += 1;
@@ -109,11 +112,10 @@ NetNet* PEIdent::elaborate_anet(Design*des, NetScope*scope) const
NetNet* sig = 0;
NetMemory* mem = 0;
NetVariable* var = 0;
const NetExpr*par = 0;
NetEvent* eve = 0;
symbol_search(des, scope, path_, sig, mem, var, par, eve);
symbol_search(des, scope, path_, sig, mem, par, eve);
if (mem != 0) {
@@ -167,6 +169,15 @@ NetNet* PEIdent::elaborate_anet(Design*des, NetScope*scope) const
/*
* $Log: elab_anet.cc,v $
* Revision 1.13 2007/03/22 16:08:14 steve
* Spelling fixes from Larry
*
* Revision 1.12 2006/05/01 20:47:58 steve
* More explicit datatype setup.
*
* Revision 1.11 2005/07/11 16:56:50 steve
* Remove NetVariable and ivl_variable_t structures.
*
* Revision 1.10 2004/10/04 01:10:52 steve
* Clean up spurious trailing white space.
*
+1178 -374
View File
File diff suppressed because it is too large Load Diff
+313 -195
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2000 Stephen Williams (steve@icarus.com)
* Copyright (c) 2000-2006 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: elab_lval.cc,v 1.29 2004/10/04 01:10:52 steve Exp $"
#ident "$Id: elab_lval.cc,v 1.44 2007/06/02 03:42:12 steve Exp $"
#endif
# include "config.h"
@@ -25,8 +25,9 @@
# include "PExpr.h"
# include "netlist.h"
# include "netmisc.h"
# include "compiler.h"
# include <iostream>
# include "ivl_assert.h"
/*
* These methods generate a NetAssign_ object for the l-value of the
@@ -66,7 +67,9 @@
* is to try to make a net elaboration, and see if the result is
* suitable for assignment.
*/
NetAssign_* PExpr::elaborate_lval(Design*des, NetScope*scope) const
NetAssign_* PExpr::elaborate_lval(Design*des,
NetScope*scope,
bool is_force) const
{
NetNet*ll = 0;
if (ll == 0) {
@@ -92,7 +95,9 @@ NetAssign_* PExpr::elaborate_lval(Design*des, NetScope*scope) const
* a is the MSB and b the LSB. Connect the LSB to the low pins of the
* NetAssign_ object.
*/
NetAssign_* PEConcat::elaborate_lval(Design*des, NetScope*scope) const
NetAssign_* PEConcat::elaborate_lval(Design*des,
NetScope*scope,
bool is_force) const
{
if (repeat_) {
cerr << get_line() << ": error: Repeat concatenations make "
@@ -112,7 +117,7 @@ NetAssign_* PEConcat::elaborate_lval(Design*des, NetScope*scope) const
continue;
}
NetAssign_*tmp = parms_[idx]->elaborate_lval(des, scope);
NetAssign_*tmp = parms_[idx]->elaborate_lval(des, scope, is_force);
/* If the l-value doesn't elaborate, the error was
already detected and printed. We just skip it and let
@@ -140,41 +145,68 @@ NetAssign_* PEConcat::elaborate_lval(Design*des, NetScope*scope) const
* Handle the ident as an l-value. This includes bit and part selects
* of that ident.
*/
NetAssign_* PEIdent::elaborate_lval(Design*des, NetScope*scope) const
NetAssign_* PEIdent::elaborate_lval(Design*des,
NetScope*scope,
bool is_force) const
{
NetNet* reg = 0;
NetMemory* mem = 0;
NetVariable* var = 0;
const NetExpr*par = 0;
NetEvent* eve = 0;
symbol_search(des, scope, path_, reg, mem, var, par, eve);
if (mem) {
return elaborate_mem_lval_(des, scope, mem);
}
if (var) {
NetAssign_*cur = new NetAssign_(var);
return cur;
}
symbol_search(des, scope, path_, reg, par, eve);
if (reg == 0) {
cerr << get_line() << ": error: Could not find variable ``"
<< path_ << "'' in ``" << scope->name() <<
<< path_ << "'' in ``" << scope_path(scope) <<
"''" << endl;
des->errors += 1;
return 0;
}
assert(reg);
ivl_assert(*this, reg);
const name_component_t&name_tail = path_.back();
index_component_t::ctype_t use_sel = index_component_t::SEL_NONE;
if (!name_tail.index.empty())
use_sel = name_tail.index.back().sel;
// This is the special case that the l-value is an entire
// memory. This is, in fact, an error.
if (reg->array_dimensions() > 0 && name_tail.index.empty()) {
cerr << get_line() << ": error: Cannot assign to array "
<< path_ << ". Did you forget a word index?" << endl;
des->errors += 1;
return 0;
}
if (reg->array_dimensions() > 0)
return elaborate_lval_net_word_(des, scope, reg);
if (use_sel == index_component_t::SEL_PART) {
NetAssign_*lv = new NetAssign_(reg);
elaborate_lval_net_part_(des, scope, lv);
return lv;
}
if (use_sel == index_component_t::SEL_IDX_UP) {
NetAssign_*lv = new NetAssign_(reg);
elaborate_lval_net_idx_up_(des, scope, lv);
return lv;
}
if (use_sel == index_component_t::SEL_IDX_DO) {
NetAssign_*lv = new NetAssign_(reg);
elaborate_lval_net_idx_do_(des, scope, lv);
return lv;
}
/* Get the signal referenced by the identifier, and make sure
it is a register. (Wires are not allows in this context. */
if (reg->type() != NetNet::REG) {
it is a register. Wires are not allows in this context,
unless this is the l-value of a force. */
if ((reg->type() != NetNet::REG) && !is_force) {
cerr << get_line() << ": error: " << path_ <<
" is not a reg/integer/time in " << scope->name() <<
" is not a valid l-value in " << scope_path(scope) <<
"." << endl;
cerr << reg->get_line() << ": : " << path_ <<
" is declared here as " << reg->type() << "." << endl;
@@ -185,57 +217,29 @@ NetAssign_* PEIdent::elaborate_lval(Design*des, NetScope*scope) const
long msb, lsb;
NetExpr*mux;
if (msb_ && lsb_) {
/* This handles part selects. In this case, there are
two bit select expressions, and both must be
constant. Evaluate them and pass the results back to
the caller. */
verinum*vl = lsb_->eval_const(des, scope);
if (vl == 0) {
cerr << lsb_->get_line() << ": error: "
"Part select expressions must be constant."
<< endl;
cerr << lsb_->get_line() << ": : This lsb expression "
"violates the rule: " << *lsb_ << endl;
des->errors += 1;
return 0;
}
verinum*vm = msb_->eval_const(des, scope);
if (vm == 0) {
cerr << msb_->get_line() << ": error: "
"Part select expressions must be constant."
<< endl;
cerr << msb_->get_line() << ": : This msb expression "
"violates the rule: " << *msb_ << endl;
des->errors += 1;
return 0;
}
if (use_sel == index_component_t::SEL_BIT) {
msb = vm->as_long();
lsb = vl->as_long();
mux = 0;
} else if (msb_) {
const index_component_t&index_tail = name_tail.index.back();
ivl_assert(*this, index_tail.msb != 0);
ivl_assert(*this, index_tail.lsb == 0);
/* If there is only a single select expression, it is a
bit select. Evaluate the constant value and treat it
as a part select with a bit width of 1. If the
expression it not constant, then return the
expression as a mux. */
assert(lsb_ == 0);
verinum*v = msb_->eval_const(des, scope);
if (v == 0) {
NetExpr*m = msb_->elaborate_expr(des, scope);
assert(m);
msb = 0;
lsb = 0;
mux = m;
NetExpr*index_expr = elab_and_eval(des, scope, index_tail.msb, -1);
if (NetEConst*index_con = dynamic_cast<NetEConst*> (index_expr)) {
msb = index_con->value().as_long();
lsb = index_con->value().as_long();
mux = 0;
} else {
msb = v->as_long();
lsb = v->as_long();
mux = 0;
msb = 0;
lsb = 0;
mux = index_expr;
}
} else {
@@ -243,8 +247,6 @@ NetAssign_* PEIdent::elaborate_lval(Design*des, NetScope*scope) const
/* No select expressions, so presume a part select the
width of the register. */
assert(msb_ == 0);
assert(lsb_ == 0);
msb = reg->msb();
lsb = reg->lsb();
mux = 0;
@@ -259,7 +261,19 @@ NetAssign_* PEIdent::elaborate_lval(Design*des, NetScope*scope) const
bmux to select the target bit. */
lv = new NetAssign_(reg);
lv->set_bmux(mux);
/* Correct the mux for the range of the vector. */
if (reg->msb() < reg->lsb())
mux = make_sub_expr(reg->lsb(), mux);
else if (reg->lsb() != 0)
mux = make_add_expr(mux, - reg->lsb());
lv->set_part(mux, 1);
} else if (msb == reg->msb() && lsb == reg->lsb()) {
/* No bit select, and part select covers the entire
vector. Simplest case. */
lv = new NetAssign_(reg);
} else {
@@ -283,7 +297,7 @@ NetAssign_* PEIdent::elaborate_lval(Design*des, NetScope*scope) const
converted to normalized form so is relative the
variable pins. */
if ((wid + loff) > reg->pin_count()) {
if ((wid + loff) > reg->vector_width()) {
cerr << get_line() << ": error: bit/part select "
<< reg->name() << "[" << msb<<":"<<lsb<<"]"
<< " is out of range." << endl;
@@ -292,57 +306,191 @@ NetAssign_* PEIdent::elaborate_lval(Design*des, NetScope*scope) const
}
lv = new NetAssign_(reg);
lv->set_part(loff, wid);
assert(moff < reg->pin_count());
lv->set_part(new NetEConst(verinum(loff)), wid);
}
return lv;
}
NetAssign_* PEIdent::elaborate_mem_lval_(Design*des, NetScope*scope,
NetMemory*mem) const
NetAssign_* PEIdent::elaborate_lval_net_word_(Design*des,
NetScope*scope,
NetNet*reg) const
{
if (msb_ == 0) {
cerr << get_line() << ": error: Assign to memory \""
<< mem->name() << "\" requires a word select index."
<< endl;
des->errors += 1;
return 0;
}
const name_component_t&name_tail = path_.back();
ivl_assert(*this, !name_tail.index.empty());
if (msb_ && lsb_) {
cerr << get_line() << ": error: Cannot use part select on "
<< "memory \"" << mem->name() << ".\"" << endl;
des->errors += 1;
return 0;
}
const index_component_t&index_head = name_tail.index.front();
ivl_assert(*this, index_head.sel == index_component_t::SEL_BIT);
ivl_assert(*this, index_head.msb != 0);
ivl_assert(*this, index_head.lsb == 0);
assert(msb_ && !lsb_);
NetExpr*word = elab_and_eval(des, scope, index_head.msb, -1);
NetExpr*ix = msb_->elaborate_expr(des, scope);
if (ix == 0)
return 0;
// If there is a non-zero base to the memory, then build an
// expression to calculate the canonical address.
if (long base = reg->array_first()) {
/* Evaluate the memory index expression down as must as
possible. Ideally, we can get it down to a constant. */
if (! dynamic_cast<NetEConst*>(ix)) {
NetExpr*tmp = ix->eval_tree();
if (tmp) {
tmp->set_line(*ix);
delete ix;
ix = tmp;
word = make_add_expr(word, 0-base);
if (NetExpr*tmp = word->eval_tree()) {
word = tmp;
}
}
NetAssign_*lv = new NetAssign_(mem);
lv->set_bmux(ix);
lv->set_part(0, mem->width());
NetAssign_*lv = new NetAssign_(reg);
lv->set_word(word);
if (debug_elaborate)
cerr << get_line() << ": debug: Set array word=" << *word << endl;
// Test for the case that the index is a constant, and is out
// of bounds. The "word" expression is the word index already
// converted to canonical address, so this just needs to check
// that the address is not too big.
if (NetEConst*word_const = dynamic_cast<NetEConst*>(word)) {
verinum word_val = word_const->value();
long index = word_val.as_long();
if (index < 0 || index >= reg->array_count()) {
cerr << get_line() << ": warning: Constant array index "
<< (index + reg->array_first())
<< " is out of range for array "
<< reg->name() << "." << endl;
}
}
/* An array word may also have part selects applied to them. */
index_component_t::ctype_t use_sel = index_component_t::SEL_NONE;
if (name_tail.index.size() > 1)
use_sel = name_tail.index.back().sel;
if (use_sel == index_component_t::SEL_PART)
elaborate_lval_net_part_(des, scope, lv);
if (use_sel == index_component_t::SEL_IDX_UP)
elaborate_lval_net_idx_up_(des, scope, lv);
if (use_sel == index_component_t::SEL_IDX_DO)
elaborate_lval_net_idx_do_(des, scope, lv);
return lv;
}
NetAssign_* PENumber::elaborate_lval(Design*des, NetScope*) const
bool PEIdent::elaborate_lval_net_part_(Design*des,
NetScope*scope,
NetAssign_*lv) const
{
long msb, lsb;
bool flag = calculate_parts_(des, scope, msb, lsb);
if (!flag)
return false;
NetNet*reg = lv->sig();
assert(reg);
if (msb == reg->msb() && lsb == reg->lsb()) {
/* No bit select, and part select covers the entire
vector. Simplest case. */
} else {
/* If the bit/part select is constant, then make the
NetAssign_ only as wide as it needs to be and connect
only to the selected bits of the reg. */
unsigned loff = reg->sb_to_idx(lsb);
unsigned moff = reg->sb_to_idx(msb);
unsigned wid = moff - loff + 1;
if (moff < loff) {
cerr << get_line() << ": error: part select "
<< reg->name() << "[" << msb<<":"<<lsb<<"]"
<< " is reversed." << endl;
des->errors += 1;
return false;
}
/* 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->vector_width()) {
cerr << get_line() << ": error: bit/part select "
<< reg->name() << "[" << msb<<":"<<lsb<<"]"
<< " is out of range." << endl;
des->errors += 1;
return false;
}
lv->set_part(new NetEConst(verinum(loff)), wid);
}
return true;
}
bool PEIdent::elaborate_lval_net_idx_up_(Design*des,
NetScope*scope,
NetAssign_*lv) const
{
const name_component_t&name_tail = path_.back();;
ivl_assert(*this, !name_tail.index.empty());
const index_component_t&index_tail = name_tail.index.back();
ivl_assert(*this, index_tail.msb != 0);
ivl_assert(*this, index_tail.lsb != 0);
NetNet*reg = lv->sig();
assert(reg);
if (reg->type() != NetNet::REG) {
cerr << get_line() << ": error: " << path_ <<
" is not a reg/integer/time in " << scope_path(scope) <<
"." << endl;
cerr << reg->get_line() << ": : " << path_ <<
" is declared here as " << reg->type() << "." << endl;
des->errors += 1;
return false;
}
unsigned long wid;
calculate_up_do_width_(des, scope, wid);
NetExpr*base = elab_and_eval(des, scope, index_tail.msb, -1);
/* Correct the mux for the range of the vector. */
if (reg->msb() < reg->lsb())
base = make_sub_expr(reg->lsb(), base);
else if (reg->lsb() != 0)
base = make_add_expr(base, - reg->lsb());
if (debug_elaborate)
cerr << get_line() << ": debug: Set part select width="
<< wid << ", base=" << *base << endl;
lv->set_part(base, wid);
return true;
}
bool PEIdent::elaborate_lval_net_idx_do_(Design*des,
NetScope*scope,
NetAssign_*lv) const
{
const name_component_t&name_tail = path_.back();;
ivl_assert(*this, !name_tail.index.empty());
const index_component_t&index_tail = name_tail.index.back();
ivl_assert(*this, index_tail.msb != 0);
ivl_assert(*this, index_tail.lsb != 0);
cerr << get_line() << ": internal error: don't know how to "
"deal with SEL_IDX_DO in lval?" << endl;
des->errors += 1;
return false;
}
NetAssign_* PENumber::elaborate_lval(Design*des, NetScope*, bool) const
{
cerr << get_line() << ": error: Constant values not allowed "
<< "in l-value expressions." << endl;
@@ -352,6 +500,66 @@ NetAssign_* PENumber::elaborate_lval(Design*des, NetScope*) const
/*
* $Log: elab_lval.cc,v $
* Revision 1.44 2007/06/02 03:42:12 steve
* Properly evaluate scope path expressions.
*
* Revision 1.43 2007/05/24 04:07:11 steve
* Rework the heirarchical identifier parse syntax and pform
* to handle more general combinations of heirarch and bit selects.
*
* Revision 1.42 2007/03/14 05:06:49 steve
* Replace some asserts with ivl_asserts.
*
* Revision 1.41 2007/03/05 05:59:10 steve
* Handle processes within generate loops.
*
* Revision 1.40 2007/02/27 05:14:38 steve
* Detect and warn about lval array index out fo bounds.
*
* Revision 1.39 2007/02/01 05:25:26 steve
* Error message better reflects more general reality.
*
* Revision 1.38 2007/01/16 05:44:15 steve
* Major rework of array handling. Memories are replaced with the
* more general concept of arrays. The NetMemory and NetEMemory
* classes are removed from the ivl core program, and the IVL_LPM_RAM
* lpm type is removed from the ivl_target API.
*
* Revision 1.37 2006/11/04 06:19:25 steve
* Remove last bits of relax_width methods, and use test_width
* to calculate the width of an r-value expression that may
* contain unsized numbers.
*
* Revision 1.36 2006/06/02 04:48:50 steve
* Make elaborate_expr methods aware of the width that the context
* requires of it. In the process, fix sizing of the width of unary
* minus is context determined sizes.
*
* Revision 1.35 2006/04/16 00:54:04 steve
* Cleanup lval part select handling.
*
* Revision 1.34 2006/04/16 00:15:43 steve
* Fix part selects in l-values.
*
* Revision 1.33 2006/02/02 02:43:57 steve
* Allow part selects of memory words in l-values.
*
* Revision 1.32 2005/07/11 16:56:50 steve
* Remove NetVariable and ivl_variable_t structures.
*
* Revision 1.31 2004/12/29 23:55:43 steve
* Unify elaboration of l-values for all proceedural assignments,
* including assing, cassign and force.
*
* Generate NetConcat devices for gate outputs that feed into a
* vector results. Use this to hande gate arrays. Also let gate
* arrays handle vectors of gates when the outputs allow for it.
*
* Revision 1.30 2004/12/11 02:31:25 steve
* Rework of internals to carry vectors through nexus instead
* of single bits. Make the ivl, tgt-vvp and vvp initial changes
* down this path.
*
* Revision 1.29 2004/10/04 01:10:52 steve
* Clean up spurious trailing white space.
*
@@ -360,95 +568,5 @@ NetAssign_* PENumber::elaborate_lval(Design*des, NetScope*) const
*
* Revision 1.27 2003/09/19 03:30:05 steve
* Fix name search in elab_lval.
*
* Revision 1.26 2003/01/27 05:09:17 steve
* Spelling fixes.
*
* Revision 1.25 2003/01/26 21:15:58 steve
* Rework expression parsing and elaboration to
* accommodate real/realtime values and expressions.
*
* Revision 1.24 2003/01/19 00:35:39 steve
* Detect null arguments to concatenation operator.
*
* Revision 1.23 2002/11/21 23:27:51 steve
* Precalculate indices to l-value arrays.
*
* Revision 1.22 2002/11/21 18:15:40 steve
* Fix const test of msb in assignment l-values.
*
* Revision 1.21 2002/11/02 01:10:49 steve
* Detect memories without work index in l-value.
*
* Revision 1.20 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.19 2002/06/04 05:38:44 steve
* Add support for memory words in l-value of
* blocking assignments, and remove the special
* NetAssignMem class.
*
* Revision 1.18 2002/03/09 04:02:26 steve
* Constant expressions are not l-values for task ports.
*
* Revision 1.17 2001/12/03 04:47:14 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
*
* Revision 1.16 2001/11/08 05:15:50 steve
* Remove string paths from PExpr elaboration.
*
* Revision 1.15 2001/11/07 04:01:59 steve
* eval_const uses scope instead of a string path.
*
* Revision 1.14 2001/08/25 23:50:02 steve
* Change the NetAssign_ class to refer to the signal
* instead of link into the netlist. This is faster
* and uses less space. Make the NetAssignNB carry
* the delays instead of the NetAssign_ lval objects.
*
* Change the vvp code generator to support multiple
* l-values, i.e. concatenations of part selects.
*
* Revision 1.13 2001/07/25 03:10:48 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
*
* Revision 1.12 2001/02/09 03:16:48 steve
* Report bit/part select out of range errors. (PR#133)
*
* Revision 1.11 2001/01/10 03:13:23 steve
* Build task outputs as lval instead of nets. (PR#98)
*
* Revision 1.10 2001/01/06 06:31:58 steve
* declaration initialization for time variables.
*
* Revision 1.9 2001/01/06 02:29:36 steve
* Support arrays of integers.
*
* Revision 1.8 2000/12/12 06:14:51 steve
* sorry for concatenated memories in l-values. (PR#76)
*
* Revision 1.7 2000/12/01 02:55:37 steve
* Detect part select errors on l-values.
*
* Revision 1.6 2000/10/31 17:49:02 steve
* Support time variables.
*
* Revision 1.5 2000/10/26 17:09:46 steve
* Fix handling of errors in behavioral lvalues. (PR#28)
*
* Revision 1.4 2000/09/10 15:43:59 steve
* Some error checking.
*
* Revision 1.3 2000/09/10 03:59:59 steve
* Agressively merge NetAssign_ within concatenations.
*
* Revision 1.2 2000/09/10 02:18:16 steve
* elaborate complex l-values
*
* Revision 1.1 2000/09/09 15:21:26 steve
* move lval elaboration to PExpr virtual methods.
*
*/
+1658 -1101
View File
File diff suppressed because it is too large Load Diff
+58 -20
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: elab_pexpr.cc,v 1.21 2004/02/20 06:22:56 steve Exp $"
#ident "$Id: elab_pexpr.cc,v 1.28 2007/06/02 03:42:12 steve Exp $"
#endif
# include "config.h"
@@ -25,6 +25,7 @@
# include "PExpr.h"
# include "compiler.h"
# include "util.h"
# include "netmisc.h"
# include <iostream>
@@ -53,7 +54,7 @@ NetExpr*PEBinary::elaborate_pexpr (Design*des, NetScope*scope) const
return 0;
}
NetEBinary*tmp = elaborate_expr_base_(des, lp, rp);
NetEBinary*tmp = elaborate_expr_base_(des, lp, rp, -1);
return tmp;
}
@@ -119,7 +120,7 @@ NetEConcat* PEConcat::elaborate_pexpr(Design*des, NetScope*scope) const
NetExpr*PEFNumber::elaborate_pexpr(Design*des, NetScope*scope) const
{
return elaborate_expr(des, scope);
return elaborate_expr(des, scope, -1, false);
}
/*
@@ -130,42 +131,53 @@ NetExpr*PEFNumber::elaborate_pexpr(Design*des, NetScope*scope) const
*/
NetExpr*PEIdent::elaborate_pexpr(Design*des, NetScope*scope) const
{
hname_t path = path_;
char*name = path.remove_tail_name();
pform_name_t path = path_;
name_component_t name_tail = path_.back();
path.pop_back();
NetScope*pscope = scope;
if (path.peek_name(0))
pscope = des->find_scope(scope, path);
if (path_.size() > 0) {
list<hname_t> tmp = eval_scope_path(des, scope, path);
pscope = des->find_scope(scope, tmp);
}
perm_string perm_name = lex_strings.make(name);
delete name;
const NetExpr*ex = pscope->get_parameter(perm_name);
const NetExpr*ex_msb;
const NetExpr*ex_lsb;
const NetExpr*ex = pscope->get_parameter(name_tail.name, ex_msb, ex_lsb);
if (ex == 0) {
cerr << get_line() << ": error: identifier ``" << path_ <<
"'' is not a parameter in " << scope->name() << "." << endl;
cerr << get_line() << ": error: identifier ``" << name_tail.name <<
"'' is not a parameter in "<< scope_path(scope)<< "." << endl;
des->errors += 1;
return 0;
}
NetExpr*res = new NetEParam(des, pscope, perm_name);
NetExpr*res = new NetEParam(des, pscope, name_tail.name);
res->set_line(*this);
assert(res);
assert(idx_ == 0);
if (msb_ && lsb_) {
index_component_t::ctype_t use_sel = index_component_t::SEL_NONE;
if (!name_tail.index.empty())
use_sel = name_tail.index.back().sel;
switch (use_sel) {
case index_component_t::SEL_NONE:
break;
default:
case index_component_t::SEL_PART:
cerr << get_line() << ": sorry: Cannot part select "
"bits of parameters." << endl;
des->errors += 1;
break;
} else if (msb_) {
case index_component_t::SEL_BIT:
/* We have here a bit select. Insert a NetESelect node
to handle it. */
NetExpr*tmp = msb_->elaborate_pexpr(des, scope);
NetExpr*tmp = name_tail.index.back().msb->elaborate_pexpr(des, scope);
if (tmp != 0) {
res = new NetESelect(res, tmp, 1);
}
break;
}
return res;
@@ -176,13 +188,13 @@ NetExpr*PEIdent::elaborate_pexpr(Design*des, NetScope*scope) const
*/
NetExpr*PENumber::elaborate_pexpr(Design*des, NetScope*sc) const
{
return elaborate_expr(des, sc);
return elaborate_expr(des, sc, -1, false);
}
NetEConst* PEString::elaborate_pexpr(Design*des, NetScope*scope) const
{
return elaborate_expr(des, scope);
return elaborate_expr(des, scope, -1, false);
}
NetETernary* PETernary::elaborate_pexpr(Design*des, NetScope*scope) const
@@ -231,6 +243,32 @@ NetExpr*PEUnary::elaborate_pexpr (Design*des, NetScope*scope) const
/*
* $Log: elab_pexpr.cc,v $
* Revision 1.28 2007/06/02 03:42:12 steve
* Properly evaluate scope path expressions.
*
* Revision 1.27 2007/05/24 04:07:11 steve
* Rework the heirarchical identifier parse syntax and pform
* to handle more general combinations of heirarch and bit selects.
*
* Revision 1.26 2007/04/26 03:06:22 steve
* Rework hname_t to use perm_strings.
*
* Revision 1.25 2006/11/04 06:19:25 steve
* Remove last bits of relax_width methods, and use test_width
* to calculate the width of an r-value expression that may
* contain unsized numbers.
*
* Revision 1.24 2006/06/02 04:48:50 steve
* Make elaborate_expr methods aware of the width that the context
* requires of it. In the process, fix sizing of the width of unary
* minus is context determined sizes.
*
* Revision 1.23 2006/02/02 02:43:58 steve
* Allow part selects of memory words in l-values.
*
* Revision 1.22 2005/11/27 05:56:20 steve
* Handle bit select of parameter with ranges.
*
* Revision 1.21 2004/02/20 06:22:56 steve
* parameter keys are per_strings.
*
+230 -73
View File
@@ -17,11 +17,12 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: elab_scope.cc,v 1.35 2004/09/10 00:15:17 steve Exp $"
#ident "$Id: elab_scope.cc,v 1.46 2007/06/02 03:42:12 steve Exp $"
#endif
# include "config.h"
# include "compiler.h"
# include "netmisc.h"
# include <iostream>
# include <stdio.h>
@@ -33,10 +34,10 @@
*/
# include "Module.h"
# include "PData.h"
# include "PEvent.h"
# include "PExpr.h"
# include "PGate.h"
# include "PGenerate.h"
# include "PTask.h"
# include "PWire.h"
# include "Statement.h"
@@ -45,11 +46,12 @@
# include <typeinfo>
# include <assert.h>
bool Module::elaborate_scope(Design*des, NetScope*scope) const
bool Module::elaborate_scope(Design*des, NetScope*scope,
const replace_t&replacements) const
{
if (debug_scopes) {
cerr << get_line() << ": debug: Elaborate scope "
<< scope->name() << "." << endl;
<< scope_path(scope) << "." << endl;
}
// Generate all the parameters that this instance of this
@@ -64,7 +66,7 @@ bool Module::elaborate_scope(Design*des, NetScope*scope) const
// place of the elaborated expression.
typedef map<perm_string,param_expr_t>::const_iterator mparm_it_t;
typedef map<hname_t,PExpr*>::const_iterator hparm_it_t;
typedef map<pform_name_t,PExpr*>::const_iterator pform_parm_it_t;
// This loop scans the parameters in the module, and creates
@@ -75,8 +77,7 @@ bool Module::elaborate_scope(Design*des, NetScope*scope) const
NetEParam*tmp = new NetEParam;
tmp->set_line(*((*cur).second.expr));
if ((*cur).second.msb)
tmp->cast_signed( (*cur).second.signed_flag );
tmp->cast_signed( (*cur).second.signed_flag );
scope->set_parameter((*cur).first, tmp, 0, 0, false);
}
@@ -107,7 +108,7 @@ bool Module::elaborate_scope(Design*des, NetScope*scope) const
NetExpr*val = ex->elaborate_pexpr(des, scope);
NetExpr*msb = 0;
NetExpr*lsb = 0;
bool signed_flag = false;
bool signed_flag = (*cur).second.signed_flag;
/* If the parameter declaration includes msb and lsb,
then use them to calculate a width for the
@@ -118,16 +119,47 @@ bool Module::elaborate_scope(Design*des, NetScope*scope) const
msb = (*cur).second.msb ->elaborate_pexpr(des, scope);
assert(msb);
lsb = (*cur).second.lsb ->elaborate_pexpr(des, scope);
signed_flag = (*cur).second.signed_flag;
}
val->cast_signed(signed_flag);
if (signed_flag) {
/* If explicitly signed, then say so. */
val->cast_signed(true);
} else if ((*cur).second.msb) {
/* If there is a range, then the signedness comes
from the type and not the expression. */
val->cast_signed(signed_flag);
} else {
/* otherwise, let the expression describe
itself. */
signed_flag = val->has_sign();
}
val = scope->set_parameter((*cur).first, val,
msb, lsb, signed_flag);
assert(val);
delete val;
}
/* run parameter replacements that were collected from the
containing scope and meant for me. */
for (replace_t::const_iterator cur = replacements.begin()
; cur != replacements.end() ; cur ++) {
NetExpr*val = (*cur).second;
if (debug_scopes) {
cerr << get_line() << ": debug: "
<< "Replace " << (*cur).first
<< " with expression " << *val
<< " from " << val->get_line() << "." << endl;
}
bool flag = scope->replace_parameter((*cur).first, val);
if (! flag) {
cerr << val->get_line() << ": warning: parameter "
<< (*cur).first << " not found in "
<< scope_path(scope) << "." << endl;
}
}
for (mparm_it_t cur = localparams.begin()
; cur != localparams.end() ; cur ++) {
@@ -168,7 +200,7 @@ bool Module::elaborate_scope(Design*des, NetScope*scope) const
// here because the parameter receiving the assignment may be
// in a scope not discovered by this pass.
for (hparm_it_t cur = defparms.begin()
for (pform_parm_it_t cur = defparms.begin()
; cur != defparms.end() ; cur ++ ) {
PExpr*ex = (*cur).second;
@@ -189,6 +221,17 @@ bool Module::elaborate_scope(Design*des, NetScope*scope) const
delete[]attr;
// Generate schemes can create new scopes in the form of
// generated code. Scan the generate schemes, and *generate*
// new scopes, which is slightly different from simple
// elaboration.
typedef list<PGenerate*>::const_iterator generate_it_t;
for (generate_it_t cur = generate_schemes.begin()
; cur != generate_schemes.end() ; cur ++ ) {
(*cur) -> generate_scope(des, scope);
}
// Tasks introduce new scopes, so scan the tasks in this
// module. Create a scope for the task and pass that to the
@@ -200,7 +243,8 @@ 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,
hname_t use_name( (*cur).first );
NetScope*task_scope = new NetScope(scope, use_name,
NetScope::TASK);
(*cur).second->elaborate_scope(des, task_scope);
}
@@ -215,7 +259,8 @@ 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,
hname_t use_name( (*cur).first );
NetScope*func_scope = new NetScope(scope, use_name,
NetScope::FUNC);
(*cur).second->elaborate_scope(des, func_scope);
}
@@ -245,7 +290,7 @@ bool Module::elaborate_scope(Design*des, NetScope*scope) const
}
// Scan through all the named events in this scope. We do not
// need anything more then the current scope to do this
// need anything more than the current scope to do this
// elaboration, so do it now. This allows for normal
// elaboration to reference these events.
@@ -255,13 +300,117 @@ bool Module::elaborate_scope(Design*des, NetScope*scope) const
(*et).second->elaborate_scope(des, scope);
}
for (map<hname_t,PData*>::const_iterator cur = datum.begin()
; cur != datum.end() ; cur ++ ) {
return des->errors == 0;
}
(*cur).second->elaborate_scope(des, scope);
bool PGenerate::generate_scope(Design*des, NetScope*container)
{
switch (scheme_type) {
case GS_LOOP:
return generate_scope_loop_(des, container);
default:
cerr << get_line() << ": sorry: Generate of this sort"
<< " is not supported yet!" << endl;
return false;
}
}
/*
* This is the elaborate scope method for a generate loop.
*/
bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
{
// We're going to need a genvar...
int genvar;
// The initial value for the genvar does not need (nor can it
// use) the genvar itself, so we can evaluate this expression
// the same way any other paramter value is evaluated.
NetExpr*init_ex = elab_and_eval(des, container, loop_init, -1);
NetEConst*init = dynamic_cast<NetEConst*> (init_ex);
if (init == 0) {
cerr << get_line() << ": error: Cannot evaluate genvar"
<< " init expression: " << *loop_init << endl;
des->errors += 1;
return false;
}
return des->errors == 0;
genvar = init->value().as_long();
delete init_ex;
if (debug_elaborate)
cerr << get_line() << ": debug: genvar init = " << genvar << endl;
container->genvar_tmp = loop_index;
container->genvar_tmp_val = 0;
NetExpr*test_ex = elab_and_eval(des, container, loop_test, -1);
NetEConst*test = dynamic_cast<NetEConst*>(test_ex);
assert(test);
while (test->value().as_long()) {
// The actual name of the scope includes the genvar so
// that each instance has a unique name in the
// container. The format of using [] is part of the
// Verilog standard.
hname_t use_name (scope_name, genvar);
if (debug_elaborate)
cerr << get_line() << ": debug: "
<< "Create generated scope " << use_name << endl;
NetScope*scope = new NetScope(container, use_name,
NetScope::GENBLOCK);
// Set in the scope a localparam for the value of the
// genvar within this instance of the generate
// block. Code within this scope thus has access to the
// genvar as a constant.
{
verinum genvar_verinum(genvar);
genvar_verinum.has_sign(true);
NetEConstParam*gp = new NetEConstParam(scope,
loop_index,
genvar_verinum);
scope->set_localparam(loop_index, gp);
if (debug_elaborate)
cerr << get_line() << ": debug: "
<< "Create implicit localparam "
<< loop_index << " = " << genvar_verinum << endl;
}
// Scan the generated scope for gates that may create
// their own scopes.
typedef list<PGate*>::const_iterator pgate_list_it_t;
for (pgate_list_it_t cur = gates.begin()
; cur != gates.end() ; cur ++) {
(*cur) ->elaborate_scope(des, scope);
}
scope_list_.push_back(scope);
// Calculate the step for the loop variable.
NetExpr*step_ex = elab_and_eval(des, container, loop_step, -1);
NetEConst*step = dynamic_cast<NetEConst*>(step_ex);
assert(step);
if (debug_elaborate)
cerr << get_line() << ": debug: genvar step from "
<< genvar << " to " << step->value().as_long() << endl;
genvar = step->value().as_long();
container->genvar_tmp_val = genvar;
delete step;
delete test_ex;
test_ex = elab_and_eval(des, container, loop_test, -1);
test = dynamic_cast<NetEConst*>(test_ex);
assert(test);
}
// Clear the genvar_tmp field in the scope to reflect that the
// genvar is no longer value for evaluating expressions.
container->genvar_tmp = perm_string();
return true;
}
void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const
@@ -280,7 +429,7 @@ void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const
// about to create, and if I find it then somebody beat me to
// it.
if (sc->child(get_name())) {
if (sc->child(hname_t(get_name()))) {
cerr << get_line() << ": error: Instance/Scope name " <<
get_name() << " already used in this context." <<
endl;
@@ -303,15 +452,17 @@ void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const
<< "module " << mod->mod_name() << " within itself." << endl;
cerr << get_line() << ": : The offending instance is "
<< sc->name() << "." << get_name() << " within "
<< scn->name() << "." << endl;
<< scope_path(sc) << "." << get_name() << " within "
<< scope_path(scn) << "." << endl;
des->errors += 1;
return;
}
verinum*msb = msb_ ? msb_->eval_const(des, sc) : 0;
verinum*lsb = lsb_ ? lsb_->eval_const(des, sc) : 0;
NetExpr*mse = msb_ ? elab_and_eval(des, sc, msb_, -1) : 0;
NetExpr*lse = lsb_ ? elab_and_eval(des, sc, lsb_, -1) : 0;
NetEConst*msb = dynamic_cast<NetEConst*> (mse);
NetEConst*lsb = dynamic_cast<NetEConst*> (lse);
assert( (msb == 0) || (lsb != 0) );
@@ -322,12 +473,15 @@ void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const
if (msb) {
instance_array = true;
instance_high = msb->as_long();
instance_low = lsb->as_long();
instance_high = msb->value().as_long();
instance_low = lsb->value().as_long();
if (instance_high > instance_low)
instance_count = instance_high - instance_low + 1;
else
instance_count = instance_low - instance_high + 1;
delete mse;
delete lse;
}
NetScope::scope_vec_t instances (instance_count);
@@ -342,24 +496,21 @@ void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const
// instantiation line.
for (int idx = 0 ; idx < instance_count ; idx += 1) {
perm_string use_name = get_name();
hname_t use_name (get_name());
if (instance_array) {
char name_buf[128];
int instance_idx = idx;
if (instance_low < instance_high)
instance_idx = instance_low + idx;
else
instance_idx = instance_low - idx;
snprintf(name_buf, sizeof name_buf,
"%s[%d]", get_name().str(), instance_idx);
use_name = lex_strings.make(name_buf);
use_name = hname_t(get_name(), instance_idx);
}
if (debug_scopes) {
cerr << get_line() << ": debug: Module instance " << use_name
<< " becomes child of " << sc->name()
<< " becomes child of " << scope_path(sc)
<< "." << endl;
}
@@ -375,13 +526,6 @@ void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const
my_scope->time_precision(mod->time_precision);
des->set_precision(mod->time_precision);
// This call actually arranges for the description of the
// module type to process this instance and handle parameters
// and sub-scopes that might occur. Parameters are also
// created in that scope, as they exist. (I'll override them
// later.)
mod->elaborate_scope(des, my_scope);
// Look for module parameter replacements. The "replace" map
// maps parameter name to replacement expression that is
// passed. It is built up by the ordered overrides or named
@@ -424,6 +568,8 @@ void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const
}
Module::replace_t replace_net;
// And here we scan the replacements we collected. Elaborate
// the expression in my context, then replace the sub-scope
// parameter value with the new expression.
@@ -433,13 +579,16 @@ void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const
PExpr*tmp = (*cur).second;
NetExpr*val = tmp->elaborate_pexpr(des, sc);
bool flag = my_scope->replace_parameter((*cur).first, val);
if (! flag) {
cerr << val->get_line() << ": warning: parameter "
<< (*cur).first << " not found in "
<< sc->name() << "." << endl;
}
replace_net[(*cur).first] = val;
}
// This call actually arranges for the description of the
// module type to process this instance and handle parameters
// and sub-scopes that might occur. Parameters are also
// created in that scope, as they exist. (I'll override them
// later.)
mod->elaborate_scope(des, my_scope, replace_net);
}
/* Stash the instance array of scopes into the parent
@@ -448,34 +597,6 @@ void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const
sc->instance_arrays[get_name()] = instances;
}
/*
* Elaborate the datum within the module. This variable may be
* within a subscope (i.e., a function or task) so use the components
* of the name to find the precise scope where this item goes.
*/
void PData::elaborate_scope(Design*des, NetScope*scope) const
{
NetScope*sub_scope = scope;
for (unsigned idx = 0 ; idx < (hname_.component_count()-1); idx += 1) {
sub_scope = sub_scope->child(hname_.peek_name(idx));
if (sub_scope == 0) {
cerr << get_line() << ": internal error: "
<< "Could not find sub-scope "
<< hname_.peek_name(idx) << " of "
<< hname_ << " in module " << scope->name()
<< endl;
des->errors += 1;
return;
}
}
const char*basename = hname_.peek_tail_name();
NetVariable*tmp = new NetVariable(lex_strings.make(basename));
tmp->set_line(*this);
sub_scope->add_variable(tmp);
}
/*
* 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
@@ -526,7 +647,7 @@ void PBlock::elaborate_scope(Design*des, NetScope*scope) const
NetScope*my_scope = scope;
if (name_ != 0) {
my_scope = new NetScope(scope, name_, bl_type_==BL_PAR
my_scope = new NetScope(scope, hname_t(name_), bl_type_==BL_PAR
? NetScope::FORK_JOIN
: NetScope::BEGIN_END);
}
@@ -635,6 +756,42 @@ void PWhile::elaborate_scope(Design*des, NetScope*scope) const
/*
* $Log: elab_scope.cc,v $
* Revision 1.46 2007/06/02 03:42:12 steve
* Properly evaluate scope path expressions.
*
* Revision 1.45 2007/05/24 04:07:11 steve
* Rework the heirarchical identifier parse syntax and pform
* to handle more general combinations of heirarch and bit selects.
*
* Revision 1.44 2007/03/22 16:08:15 steve
* Spelling fixes from Larry
*
* Revision 1.43 2007/03/08 06:11:35 steve
* Elaborate scopes of modules instantated in generate loops.
*
* Revision 1.42 2007/03/05 05:59:10 steve
* Handle processes within generate loops.
*
* Revision 1.41 2006/06/02 04:48:50 steve
* Make elaborate_expr methods aware of the width that the context
* requires of it. In the process, fix sizing of the width of unary
* minus is context determined sizes.
*
* Revision 1.40 2006/04/12 05:05:03 steve
* Use elab_and_eval to evaluate genvar expressions.
*
* Revision 1.39 2006/04/10 00:37:42 steve
* Add support for generate loops w/ wires and gates.
*
* Revision 1.38 2006/03/30 01:49:07 steve
* Fix instance arrays indexed by overridden parameters.
*
* Revision 1.37 2006/03/18 22:53:38 steve
* Support more parameter syntax.
*
* Revision 1.36 2005/07/11 16:56:50 steve
* Remove NetVariable and ivl_variable_t structures.
*
* Revision 1.35 2004/09/10 00:15:17 steve
* Missing stdio.h header for warnings.
*
+288 -90
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: elab_sig.cc,v 1.36 2004/09/27 22:34:10 steve Exp $"
#ident "$Id: elab_sig.cc,v 1.52 2007/06/02 03:42:12 steve Exp $"
#endif
# include "config.h"
@@ -27,12 +27,14 @@
# include "Module.h"
# include "PExpr.h"
# include "PGate.h"
# include "PGenerate.h"
# include "PTask.h"
# include "PWire.h"
# include "compiler.h"
# include "netlist.h"
# include "netmisc.h"
# include "util.h"
# include "ivl_assert.h"
/*
* This local function checks if a named signal is connected to a
@@ -40,8 +42,10 @@
* within the port_t that have a matching name.
*/
static bool signal_is_in_port(const svector<Module::port_t*>&ports,
const hname_t&name)
NetNet*sig)
{
perm_string name = sig->name();
for (unsigned idx = 0 ; idx < ports.count() ; idx += 1) {
Module::port_t*pp = ports[idx];
@@ -52,9 +56,15 @@ static bool signal_is_in_port(const svector<Module::port_t*>&ports,
// This port has an internal connection. In this case,
// the port has 0 or more NetEIdent objects concatenated
// together that form the port.
// Note that module ports should not have any heirarchy
// in their names: they are in the root of the module
// scope by definition.
for (unsigned cc = 0 ; cc < pp->expr.count() ; cc += 1) {
perm_string pname = peek_tail_name(pp->expr[cc]->path());
assert(pp->expr[cc]);
if (pp->expr[cc]->path() == name)
if (pname == name)
return true;
}
}
@@ -62,14 +72,28 @@ static bool signal_is_in_port(const svector<Module::port_t*>&ports,
return false;
}
#if 0
static NetNet*find_signal_in_scope(NetScope*scope, const hname_t&path)
{
NetScope*cur = scope;
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));
}
#endif
bool Module::elaborate_sig(Design*des, NetScope*scope) const
{
bool flag = true;
// Get all the explicitly declared wires of the module and
// start the signals list with them.
const map<hname_t,PWire*>&wl = get_wires();
// 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) {
@@ -77,12 +101,12 @@ bool Module::elaborate_sig(Design*des, NetScope*scope) const
if (pp == 0)
continue;
map<hname_t,PWire*>::const_iterator wt;
map<pform_name_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);
pform_name_t port_path (pp->expr[cc]->path());
wt = wires_.find(port_path);
if (wt == wl.end()) {
if (wt == wires_.end()) {
cerr << get_line() << ": error: "
<< "Port " << pp->expr[cc]->path() << " ("
<< (idx+1) << ") of module " << name_
@@ -102,14 +126,11 @@ bool Module::elaborate_sig(Design*des, NetScope*scope) const
}
}
for (map<hname_t,PWire*>::const_iterator wt = wl.begin()
; wt != wl.end()
; wt ++ ) {
for (map<pform_name_t,PWire*>::const_iterator wt = wires_.begin()
; wt != wires_.end() ; wt ++ ) {
PWire*cur = (*wt).second;
cur->elaborate_sig(des, scope);
NetNet*sig = scope->find_signal_in_child(cur->path());
NetNet*sig = cur->elaborate_sig(des, scope);
// If this wire is a signal of the module (as opposed to
// a port of a function) and is a port, then check that
@@ -121,12 +142,10 @@ bool Module::elaborate_sig(Design*des, NetScope*scope) const
if (sig && (sig->scope() == scope)
&& (cur->get_port_type() != NetNet::NOT_A_PORT)) {
hname_t name = (*wt).first;
if (! signal_is_in_port(ports, name)) {
if (! signal_is_in_port(ports, sig)) {
cerr << cur->get_line() << ": error: Signal "
<< name << " has a declared direction "
<< sig->name() << " has a declared direction "
<< "but is not a port." << endl;
des->errors += 1;
}
@@ -158,6 +177,16 @@ bool Module::elaborate_sig(Design*des, NetScope*scope) const
des->errors += 1;
}
}
// Run through all the generate schemes to enaborate the
// signals that they hold. Note that the generate schemes hold
// the scopes that they instantiated, so we don't pass any
// scope in.
typedef list<PGenerate*>::const_iterator generate_it_t;
for (generate_it_t cur = generate_schemes.begin()
; cur != generate_schemes.end() ; cur ++ ) {
(*cur) -> elaborate_sig(des);
}
// Get all the gates of the module and elaborate them by
@@ -179,11 +208,13 @@ bool Module::elaborate_sig(Design*des, NetScope*scope) const
for (mfunc_it_t cur = funcs_.begin()
; cur != funcs_.end() ; cur ++) {
NetScope*fscope = scope->child((*cur).first);
hname_t use_name ( (*cur).first );
NetScope*fscope = scope->child(use_name);
if (scope == 0) {
cerr << (*cur).second->get_line() << ": internal error: "
<< "Child scope for function " << (*cur).first
<< " missing in " << scope->name() << "." << endl;
<< " missing in " << scope_path(scope) << "." << endl;
des->errors += 1;
continue;
}
@@ -200,7 +231,7 @@ bool Module::elaborate_sig(Design*des, NetScope*scope) const
for (mtask_it_t cur = tasks_.begin()
; cur != tasks_.end() ; cur ++) {
NetScope*tscope = scope->child((*cur).first);
NetScope*tscope = scope->child( hname_t((*cur).first) );
assert(tscope);
(*cur).second->elaborate_sig(des, tscope);
}
@@ -223,9 +254,9 @@ bool PGModule::elaborate_sig_mod_(Design*des, NetScope*scope,
if (my_scope->parent() != scope) {
cerr << get_line() << ": internal error: "
<< "Instance " << my_scope->name()
<< " is in parent " << my_scope->parent()->name()
<< " instead of " << scope->name()
<< "Instance " << scope_path(my_scope)
<< " is in parent " << scope_path(my_scope->parent())
<< " instead of " << scope_path(scope)
<< endl;
}
assert(my_scope->parent() == scope);
@@ -238,6 +269,50 @@ bool PGModule::elaborate_sig_mod_(Design*des, NetScope*scope,
return flag;
}
bool PGenerate::elaborate_sig(Design*des) const
{
bool flag = true;
typedef list<NetScope*>::const_iterator scope_list_it_t;
for (scope_list_it_t cur = scope_list_.begin()
; cur != scope_list_.end() ; cur ++ ) {
if (debug_elaborate)
cerr << get_line() << ": debug: Elaborate nets in "
<< "scope " << scope_path(*cur) << endl;
flag = elaborate_sig_(des, *cur) & flag;
}
return flag;
}
bool PGenerate::elaborate_sig_(Design*des, NetScope*scope) const
{
// Scan the declared PWires to elaborate the obvious signals
// in the current scope.
typedef map<pform_name_t,PWire*>::const_iterator wires_it_t;
for (wires_it_t wt = wires.begin()
; wt != wires.end() ; wt ++ ) {
PWire*cur = (*wt).second;
if (debug_elaborate)
cerr << get_line() << ": debug: Elaborate PWire "
<< cur->path() << " in scope " << scope_path(scope) << endl;
cur->elaborate_sig(des, scope);
}
typedef list<PGate*>::const_iterator pgate_list_it_t;
for (pgate_list_it_t cur = gates.begin()
; cur != gates.end() ; cur ++) {
(*cur) ->elaborate_sig(des, scope);
}
return true;
}
/*
* A function definition exists within an elaborated module. This
* matters when elaborating signals, as the ports of the function are
@@ -261,19 +336,19 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const
}
NetNet*ret_sig = 0;
NetVariable*ret_real = 0;
/* Create the signals/variables of the return value and write
them into the function scope. */
switch (return_type_.type) {
case PTF_REG:
case PTF_REG_S:
if (return_type_.range) {
NetExpr*me = elab_and_eval(des, scope,
(*return_type_.range)[0]);
(*return_type_.range)[0], -1);
assert(me);
NetExpr*le = elab_and_eval(des, scope,
(*return_type_.range)[1]);
(*return_type_.range)[1], -1);
assert(le);
long mnum = 0, lnum = 0;
@@ -301,15 +376,18 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const
ret_sig = new NetNet(scope, fname, NetNet::REG);
}
ret_sig->set_line(*this);
ret_sig->set_signed(return_type_.type == PTF_REG_S);
ret_sig->port_type(NetNet::POUTPUT);
ret_sig->data_type(IVL_VT_LOGIC);
break;
case PTF_INTEGER:
ret_sig = new NetNet(scope, fname, NetNet::REG, INTEGER_WIDTH);
ret_sig = new NetNet(scope, fname, NetNet::REG, integer_width);
ret_sig->set_line(*this);
ret_sig->set_signed(true);
ret_sig->set_isint(true);
ret_sig->port_type(NetNet::POUTPUT);
ret_sig->data_type(IVL_VT_LOGIC);
break;
case PTF_TIME:
@@ -318,13 +396,17 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const
ret_sig->set_signed(false);
ret_sig->set_isint(false);
ret_sig->port_type(NetNet::POUTPUT);
ret_sig->data_type(IVL_VT_LOGIC);
break;
case PTF_REAL:
case PTF_REALTIME:
ret_real = new NetVariable(fname);
ret_real->set_line(*this);
scope->add_variable(ret_real);
ret_sig = new NetNet(scope, fname, NetNet::REG, 1);
ret_sig->set_line(*this);
ret_sig->set_signed(true);
ret_sig->set_isint(false);
ret_sig->port_type(NetNet::POUTPUT);
ret_sig->data_type(IVL_VT_REAL);
break;
default:
@@ -342,22 +424,24 @@ 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>. */
hname_t path = (*ports_)[idx]->path();
perm_string pname = lex_strings.make(path.peek_name(1));
perm_string ppath = lex_strings.make(path.peek_name(0));
pform_name_t path = (*ports_)[idx]->path();
ivl_assert(*this, path.size() == 2);
perm_string pname = peek_tail_name(path);
perm_string ppath = peek_head_name(path);
if (ppath != scope->basename()) {
cerr << get_line() << ": internal error: function "
<< "port " << (*ports_)[idx]->path()
<< " has wrong name for function "
<< scope->name() << "." << endl;
<< scope_path(scope) << "." << endl;
des->errors += 1;
}
NetNet*tmp = scope->find_signal(pname);
if (tmp == 0) {
cerr << get_line() << ": internal error: function "
<< scope->name() << " is missing port "
<< scope_path(scope) << " is missing port "
<< pname << "." << endl;
scope->dump(cerr);
cerr << get_line() << ": Continuing..." << endl;
@@ -370,7 +454,6 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const
NetFuncDef*def = 0;
if (ret_sig) def = new NetFuncDef(scope, ret_sig, ports);
if (ret_real) def = new NetFuncDef(scope, ret_real, ports);
assert(def);
scope->set_func_def(def);
@@ -396,36 +479,34 @@ 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>. */
hname_t path = (*ports_)[idx]->path();
assert(path.peek_name(0) && path.peek_name(1));
pform_name_t path = (*ports_)[idx]->path();
ivl_assert(*this, path.size() == 2);
perm_string scope_name = peek_head_name(path);
perm_string port_name = peek_tail_name(path);
/* 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(path.peek_name(0)) != scope) {
cerr << "internal error: task scope " << path
<< " not the same as scope " << scope->name()
<< "?!" << endl;
return;
}
ivl_assert(*this, scope->basename() == scope_name);
/* 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(path.peek_name(1));
NetNet*tmp = scope->find_signal(port_name);
if (tmp == 0) {
cerr << get_line() << ": internal error: "
<< "Could not find port " << path.peek_name(1)
<< " in scope " << scope->name() << endl;
<< "Could not find port " << port_name
<< " in scope " << scope_path(scope) << endl;
scope->dump(cerr);
}
ports[idx] = tmp;
}
NetTaskDef*def = new NetTaskDef(scope->name(), ports);
NetTaskDef*def = new NetTaskDef(scope, ports);
scope->set_task_def(def);
}
@@ -441,16 +522,19 @@ bool PGate::elaborate_sig(Design*des, NetScope*scope) const
* elaboration this creates an object in the design that represent the
* defined item.
*/
void PWire::elaborate_sig(Design*des, NetScope*scope) const
NetNet* 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. */
{ 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));
{ pform_name_t tmp_path = hname_;
tmp_path.pop_back();
while (! tmp_path.empty()) {
name_component_t cur = tmp_path.front();
tmp_path.pop_front();
scope = scope->child( hname_t(cur.name) );
if (scope == 0) {
cerr << get_line() << ": internal error: "
@@ -495,7 +579,7 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
}
NetEConst*tmp;
NetExpr*texpr = elab_and_eval(des, scope, msb_[idx]);
NetExpr*texpr = elab_and_eval(des, scope, msb_[idx], -1);
tmp = dynamic_cast<NetEConst*>(texpr);
if (tmp == 0) {
@@ -503,20 +587,20 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
"Unable to evaluate constant expression ``" <<
*msb_[idx] << "''." << endl;
des->errors += 1;
return;
return 0;
}
mnum[idx] = tmp->value().as_long();
delete texpr;
texpr = elab_and_eval(des, scope, lsb_[idx]);
texpr = elab_and_eval(des, scope, lsb_[idx], -1);
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;
return 0;
}
lnum[idx] = tmp->value().as_long();
@@ -532,7 +616,7 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
<< "'' declared both as a vector and a scalar."
<< endl;
des->errors += 1;
return;
return 0;
}
@@ -545,7 +629,7 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
" vs. [" << mnum[0] << ":" << lnum[0] << "]"
" for signal ``" << hname_ << "''" << endl;
des->errors += 1;
return;
return 0;
}
}
@@ -563,6 +647,10 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
attrib_list_t*attrib_list = evaluate_attributes(attributes, nattrib,
des, scope);
long array_s0 = 0;
long array_e0 = 0;
unsigned array_dimensions = 0;
/* If the ident has idx expressions, then this is a
memory. It can only have the idx registers after the msb
and lsb expressions are filled. And, if it has one index,
@@ -570,15 +658,15 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
if (lidx_ || ridx_) {
assert(lidx_ && ridx_);
NetExpr*lexp = elab_and_eval(des, scope, lidx_);
NetExpr*rexp = elab_and_eval(des, scope, ridx_);
NetExpr*lexp = elab_and_eval(des, scope, lidx_, -1);
NetExpr*rexp = elab_and_eval(des, scope, ridx_, -1);
if ((lexp == 0) || (rexp == 0)) {
cerr << get_line() << ": internal error: There is "
<< "a problem evaluating indices for ``"
<< hname_.peek_tail_name() << "''." << endl;
<< hname_ << "''." << endl;
des->errors += 1;
return;
return 0;
}
NetEConst*lcon = dynamic_cast<NetEConst*> (lexp);
@@ -586,10 +674,10 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
if ((lcon == 0) || (rcon == 0)) {
cerr << get_line() << ": internal error: The indices "
<< "are not constant for memory ``"
<< hname_.peek_tail_name() << "''." << endl;
<< "are not constant for array ``"
<< hname_ << "''." << endl;
des->errors += 1;
return;
return 0;
}
verinum lval = lcon->value();
@@ -598,31 +686,141 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
delete lexp;
delete rexp;
perm_string name = lex_strings.make(hname_.peek_tail_name());
long lnum = lval.as_long();
long rnum = rval.as_long();
new NetMemory(scope, name, wid, lnum, rnum);
// The constructor automatically adds the memory object
// to the scope. Do I need to set line number information?
} else {
perm_string name = lex_strings.make(hname_.peek_tail_name());
NetNet*sig = new NetNet(scope, name, wtype, msb, lsb);
sig->set_line(*this);
sig->port_type(port_type_);
sig->set_signed(get_signed());
sig->set_isint(get_isint());
for (unsigned idx = 0 ; idx < nattrib ; idx += 1)
sig->attribute(attrib_list[idx].key, attrib_list[idx].val);
array_dimensions = 1;
array_s0 = lval.as_long();
array_e0 = rval.as_long();
}
/* If the net type is supply0 or supply1, replace it
with a simple wire with a pulldown/pullup with supply
strength. In other words, transform:
supply0 foo;
to:
wire foo;
pulldown #(supply0) (foo);
This reduces the backend burden, and behaves exactly
the same. */
NetLogic*pull = 0;
if (wtype == NetNet::SUPPLY0 || wtype == NetNet::SUPPLY1) {
NetLogic::TYPE pull_type = (wtype==NetNet::SUPPLY1)
? NetLogic::PULLUP
: NetLogic::PULLDOWN;
pull = new NetLogic(scope, scope->local_symbol(),
1, pull_type, wid);
pull->set_line(*this);
pull->pin(0).drive0(Link::SUPPLY);
pull->pin(0).drive1(Link::SUPPLY);
des->add_node(pull);
wtype = NetNet::WIRE;
if (debug_elaborate) {
cerr << get_line() << ": debug: "
<< "Generate a SUPPLY pulldown for the "
<< "supply0 net." << endl;
}
}
perm_string name = peek_tail_name(hname_);
if (debug_elaborate) {
cerr << get_line() << ": debug: Create signal "
<< wtype << " ["<<msb<<":"<<lsb<<"] " << name
<< " in scope " << scope_path(scope) << endl;
}
NetNet*sig = array_dimensions > 0
? new NetNet(scope, name, wtype, msb, lsb, array_s0, array_e0)
: new NetNet(scope, name, wtype, msb, lsb);
ivl_variable_type_t use_data_type = data_type_;
if (use_data_type == IVL_VT_NO_TYPE) {
use_data_type = IVL_VT_LOGIC;
if (debug_elaborate) {
cerr << get_line() << ": debug: "
<< "Signal " << name
<< " in scope " << scope_path(scope)
<< " defaults to data type " << use_data_type << endl;
}
}
sig->data_type(use_data_type);
sig->set_line(*this);
sig->port_type(port_type_);
sig->set_signed(get_signed());
sig->set_isint(get_isint());
if (pull)
connect(sig->pin(0), pull->pin(0));
for (unsigned idx = 0 ; idx < nattrib ; idx += 1)
sig->attribute(attrib_list[idx].key, attrib_list[idx].val);
return sig;
}
/*
* $Log: elab_sig.cc,v $
* Revision 1.52 2007/06/02 03:42:12 steve
* Properly evaluate scope path expressions.
*
* Revision 1.51 2007/05/24 04:07:11 steve
* Rework the heirarchical identifier parse syntax and pform
* to handle more general combinations of heirarch and bit selects.
*
* Revision 1.50 2007/04/26 03:06:22 steve
* Rework hname_t to use perm_strings.
*
* Revision 1.49 2007/04/02 01:12:34 steve
* Seperate arrayness from word count
*
* Revision 1.48 2007/03/08 06:11:35 steve
* Elaborate scopes of modules instantated in generate loops.
*
* Revision 1.47 2007/03/07 04:24:59 steve
* Make integer width controllable.
*
* Revision 1.46 2007/03/06 05:22:49 steve
* Support signed function return values.
*
* Revision 1.45 2007/02/01 05:24:08 steve
* Include type in signal create message.
*
* Revision 1.44 2007/01/29 02:07:34 steve
* Types of task/function arguments set in multiple steps.
*
* Revision 1.43 2007/01/16 05:44:15 steve
* Major rework of array handling. Memories are replaced with the
* more general concept of arrays. The NetMemory and NetEMemory
* classes are removed from the ivl core program, and the IVL_LPM_RAM
* lpm type is removed from the ivl_target API.
*
* Revision 1.42 2006/06/02 04:48:50 steve
* Make elaborate_expr methods aware of the width that the context
* requires of it. In the process, fix sizing of the width of unary
* minus is context determined sizes.
*
* Revision 1.41 2006/04/10 00:37:42 steve
* Add support for generate loops w/ wires and gates.
*
* Revision 1.40 2005/07/11 16:56:50 steve
* Remove NetVariable and ivl_variable_t structures.
*
* Revision 1.39 2005/07/07 16:22:49 steve
* Generalize signals to carry types.
*
* Revision 1.38 2005/02/13 01:15:07 steve
* Replace supply nets with wires connected to pullup/down supply devices.
*
* Revision 1.37 2004/12/11 02:31:25 steve
* Rework of internals to carry vectors through nexus instead
* of single bits. Make the ivl, tgt-vvp and vvp initial changes
* down this path.
*
* Revision 1.36 2004/09/27 22:34:10 steve
* Cleanup and factoring of autoconf.
*
+1206 -421
View File
File diff suppressed because it is too large Load Diff
+115 -177
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998-2000 Stephen Williams (steve@icarus.com)
* Copyright (c) 1998-2005 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: emit.cc,v 1.77 2004/10/04 01:10:53 steve Exp $"
#ident "$Id: emit.cc,v 1.89 2007/01/16 05:44:15 steve Exp $"
#endif
# include "config.h"
@@ -57,18 +57,17 @@ bool NetAddSub::emit_node(struct target_t*tgt) const
return true;
}
bool NetArrayDq::emit_node(struct target_t*tgt) const
{
return tgt->lpm_array_dq(this);
}
bool NetCaseCmp::emit_node(struct target_t*tgt) const
{
tgt->net_case_cmp(this);
return true;
}
bool NetCAssign::emit_node(struct target_t*tgt) const
{
tgt->net_cassign(this);
return true;
}
bool NetCLShift::emit_node(struct target_t*tgt) const
{
tgt->lpm_clshift(this);
@@ -81,6 +80,11 @@ bool NetCompare::emit_node(struct target_t*tgt) const
return true;
}
bool NetConcat::emit_node(struct target_t*tgt) const
{
return tgt->concat(this);
}
bool NetConst::emit_node(struct target_t*tgt) const
{
return tgt->net_const(this);
@@ -98,10 +102,9 @@ bool NetFF::emit_node(struct target_t*tgt) const
return true;
}
bool NetForce::emit_node(struct target_t*tgt) const
bool NetLiteral::emit_node(struct target_t*tgt) const
{
tgt->net_force(this);
return true;
return tgt->net_literal(this);
}
bool NetModulo::emit_node(struct target_t*tgt) const
@@ -122,10 +125,29 @@ bool NetMux::emit_node(struct target_t*tgt) const
return true;
}
bool NetRamDq::emit_node(struct target_t*tgt) const
bool NetPartSelect::emit_node(struct target_t*tgt) const
{
tgt->lpm_ram_dq(this);
return true;
return tgt->part_select(this);
}
bool NetReplicate::emit_node(struct target_t*tgt) const
{
return tgt->replicate(this);
}
bool NetSignExtend::emit_node(struct target_t*tgt) const
{
return tgt->sign_extend(this);
}
bool NetUReduce::emit_node(struct target_t*tgt) const
{
return tgt->ureduce(this);
}
bool NetSysFunc::emit_node(struct target_t*tgt) const
{
return tgt->net_sysfunction(this);
}
bool NetUserFunc::emit_node(struct target_t*tgt) const
@@ -312,9 +334,6 @@ void NetScope::emit_scope(struct target_t*tgt) const
for (NetEvent*cur = events_ ; cur ; cur = cur->snext_)
tgt->event(cur);
for (NetVariable*cur = vars_ ; cur ; cur = cur->snext_)
tgt->variable(cur);
for (NetScope*cur = sub_ ; cur ; cur = cur->sib_)
cur->emit_scope(tgt);
@@ -324,15 +343,19 @@ void NetScope::emit_scope(struct target_t*tgt) const
tgt->signal(cur);
cur = cur->sig_next_;
} while (cur != signals_->sig_next_);
/* Run the signals again, but this time to connect the
delay paths. This is done as a second pass because
the paths reference other signals that may be later
in the list. We can do it here becase delay paths are
always connected within the scope. */
cur = signals_->sig_next_;
do {
tgt->signal_paths(cur);
cur = cur->sig_next_;
} while (cur != signals_->sig_next_);
}
if (memories_) {
NetMemory*cur = memories_->snext_;
do {
tgt->memory(cur);
cur = cur->snext_;
} while (cur != memories_->snext_);
}
}
bool NetScope::emit_defs(struct target_t*tgt) const
@@ -363,13 +386,12 @@ void NetWhile::emit_proc_recurse(struct target_t*tgt) const
proc_->emit_proc(tgt);
}
bool Design::emit(struct target_t*tgt) const
int Design::emit(struct target_t*tgt) const
{
bool rc = true;
int rc = 0;
rc = rc && tgt->start_design(this);
if (rc == false)
return false;
if (tgt->start_design(this) == false)
return -2;
// enumerate the scopes
for (list<NetScope*>::const_iterator scope = root_scopes_.begin();
@@ -378,27 +400,36 @@ bool Design::emit(struct target_t*tgt) const
// emit nodes
bool nodes_rc = true;
if (nodes_) {
NetNode*cur = nodes_->node_next_;
do {
rc = rc && cur->emit_node(tgt);
nodes_rc = nodes_rc && cur->emit_node(tgt);
cur = cur->node_next_;
} while (cur != nodes_->node_next_);
}
// emit task and function definitions
bool tasks_rc = true;
for (list<NetScope*>::const_iterator scope = root_scopes_.begin();
scope != root_scopes_.end(); scope++)
rc &= (*scope)->emit_defs(tgt);
tasks_rc &= (*scope)->emit_defs(tgt);
// emit the processes
bool proc_rc = true;
for (const NetProcTop*idx = procs_ ; idx ; idx = idx->next_)
rc = rc && idx->emit(tgt);
proc_rc &= idx->emit(tgt);
if (tgt->end_design(this) != 0)
rc = false;
rc = tgt->end_design(this);
if (nodes_rc == false)
return -1;
if (tasks_rc == false)
return -2;
if (proc_rc == false)
return -3;
return rc;
}
@@ -433,11 +464,6 @@ void NetECRealParam::expr_scan(struct expr_scan_t*tgt) const
tgt->expr_rparam(this);
}
void NetEMemory::expr_scan(struct expr_scan_t*tgt) const
{
tgt->expr_memory(this);
}
void NetEParam::expr_scan(struct expr_scan_t*tgt) const
{
cerr << get_line() << ":internal error: unexpected NetEParam."
@@ -474,11 +500,6 @@ void NetESignal::expr_scan(struct expr_scan_t*tgt) const
tgt->expr_signal(this);
}
void NetEBitSel::expr_scan(struct expr_scan_t*tgt) const
{
tgt->expr_subsignal(this);
}
void NetETernary::expr_scan(struct expr_scan_t*tgt) const
{
tgt->expr_ternary(this);
@@ -489,12 +510,7 @@ void NetEUnary::expr_scan(struct expr_scan_t*tgt) const
tgt->expr_unary(this);
}
void NetEVariable::expr_scan(struct expr_scan_t*tgt) const
{
tgt->expr_variable(this);
}
bool emit(const Design*des, const char*type)
int emit(const Design*des, const char*type)
{
for (unsigned idx = 0 ; target_table[idx] ; idx += 1) {
const struct target*tgt = target_table[idx];
@@ -505,12 +521,60 @@ bool emit(const Design*des, const char*type)
cerr << "error: Code generator type " << type
<< " not found." << endl;
return false;
return -1;
}
/*
* $Log: emit.cc,v $
* Revision 1.89 2007/01/16 05:44:15 steve
* Major rework of array handling. Memories are replaced with the
* more general concept of arrays. The NetMemory and NetEMemory
* classes are removed from the ivl core program, and the IVL_LPM_RAM
* lpm type is removed from the ivl_target API.
*
* Revision 1.88 2006/11/10 05:44:44 steve
* Process delay paths in second path over signals.
*
* Revision 1.87 2006/06/18 04:15:50 steve
* Add support for system functions in continuous assignments.
*
* Revision 1.86 2005/07/11 16:56:50 steve
* Remove NetVariable and ivl_variable_t structures.
*
* Revision 1.85 2005/07/07 16:22:49 steve
* Generalize signals to carry types.
*
* Revision 1.84 2005/05/24 01:44:27 steve
* Do sign extension of structuran nets.
*
* Revision 1.83 2005/02/08 00:12:36 steve
* Add the NetRepeat node, and code generator support.
*
* Revision 1.82 2005/02/03 04:56:20 steve
* laborate reduction gates into LPM_RED_ nodes.
*
* Revision 1.81 2005/01/24 05:28:30 steve
* Remove the NetEBitSel and combine all bit/part select
* behavior into the NetESelect node and IVL_EX_SELECT
* ivl_target expression type.
*
* Revision 1.80 2005/01/22 01:06:55 steve
* Change case compare from logic to an LPM node.
*
* Revision 1.79 2004/12/29 23:55:43 steve
* Unify elaboration of l-values for all proceedural assignments,
* including assing, cassign and force.
*
* Generate NetConcat devices for gate outputs that feed into a
* vector results. Use this to hande gate arrays. Also let gate
* arrays handle vectors of gates when the outputs allow for it.
*
* Revision 1.78 2004/12/11 02:31:26 steve
* Rework of internals to carry vectors through nexus instead
* of single bits. Make the ivl, tgt-vvp and vvp initial changes
* down this path.
*
* Revision 1.77 2004/10/04 01:10:53 steve
* Clean up spurious trailing white space.
*
@@ -536,131 +600,5 @@ bool emit(const Design*des, const char*type)
* Revision 1.71 2003/01/26 21:15:58 steve
* Rework expression parsing and elaboration to
* accommodate real/realtime values and expressions.
*
* Revision 1.70 2002/11/03 20:36:10 steve
* Error message for mising code generator type.
*
* Revision 1.69 2002/08/12 01:34:59 steve
* conditional ident string using autoconfig.
*
* Revision 1.68 2002/06/05 03:44:25 steve
* Add support for memory words in l-value of
* non-blocking assignments, and remove the special
* NetAssignMem_ and NetAssignMemNB classes.
*
* Revision 1.67 2002/06/04 05:38:44 steve
* Add support for memory words in l-value of
* blocking assignments, and remove the special
* NetAssignMem class.
*
* Revision 1.66 2002/03/09 02:10:22 steve
* Add the NetUserFunc netlist node.
*
* Revision 1.65 2002/01/28 00:52:41 steve
* Add support for bit select of parameters.
* This leads to a NetESelect node and the
* vvp code generator to support that.
*
* Revision 1.64 2002/01/19 19:02:08 steve
* Pass back target errors processing conditionals.
*
* Revision 1.63 2001/10/19 21:53:24 steve
* Support multiple root modules (Philip Blundell)
*
* Revision 1.62 2001/08/25 23:50:02 steve
* Change the NetAssign_ class to refer to the signal
* instead of link into the netlist. This is faster
* 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
*
* Revision 1.54 2000/09/26 01:35:42 steve
* Remove the obsolete NetEIdent class.
*
* Revision 1.53 2000/09/17 21:26:15 steve
* Add support for modulus (Eric Aardoom)
*
* Revision 1.52 2000/09/02 20:54:20 steve
* Rearrange NetAssign to make NetAssign_ separate.
*
* Revision 1.51 2000/08/14 04:39:56 steve
* add th t-dll functions for net_const, net_bufz and processes.
*
* Revision 1.50 2000/08/09 03:43:45 steve
* Move all file manipulation out of target class.
*
* Revision 1.49 2000/08/08 01:50:42 steve
* target methods need not take a file stream.
*
* Revision 1.48 2000/07/30 18:25:43 steve
* Rearrange task and function elaboration so that the
* NetTaskDef and NetFuncDef functions are created during
* signal enaboration, and carry these objects in the
* NetScope class instead of the extra, useless map in
* the Design class.
*
* Revision 1.47 2000/07/29 16:21:08 steve
* Report code generation errors through proc_delay.
*
* Revision 1.46 2000/07/27 05:13:44 steve
* Support elaboration of disable statements.
*
* Revision 1.45 2000/05/11 23:37:27 steve
* Add support for procedural continuous assignment.
*
* Revision 1.44 2000/05/04 03:37:58 steve
* Add infrastructure for system functions, move
* $time to that structure and add $random.
*
* Revision 1.43 2000/05/02 03:13:31 steve
* Move memories to the NetScope object.
*
* Revision 1.42 2000/05/02 00:58:12 steve
* Move signal tables to the NetScope class.
*
* Revision 1.41 2000/04/23 03:45:24 steve
* Add support for the procedural release statement.
*
* Revision 1.40 2000/04/22 04:20:19 steve
* Add support for force assignment.
*
* Revision 1.39 2000/04/12 04:23:58 steve
* Named events really should be expressed with PEIdent
* objects in the pform,
*
* Handle named events within the mix of net events
* and edges. As a unified lot they get caught together.
* wait statements are broken into more complex statements
* that include a conditional.
*
* Do not generate NetPEvent or NetNEvent objects in
* elaboration. NetEvent, NetEvWait and NetEvProbe
* take over those functions in the netlist.
*/
+85 -12
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: eval.cc,v 1.36 2003/06/21 01:21:43 steve Exp $"
#ident "$Id: eval.cc,v 1.47 2007/06/04 19:14:06 steve Exp $"
#endif
# include "config.h"
@@ -26,14 +26,15 @@
# include "PExpr.h"
# include "netlist.h"
# include "netmisc.h"
# include "compiler.h"
verinum* PExpr::eval_const(const Design*, const NetScope*) const
verinum* PExpr::eval_const(Design*, NetScope*) const
{
return 0;
}
verinum* PEBinary::eval_const(const Design*des, const NetScope*scope) const
verinum* PEBinary::eval_const(Design*des, NetScope*scope) const
{
verinum*l = left_->eval_const(des, scope);
if (l == 0) return 0;
@@ -142,16 +143,51 @@ verinum* PEBinary::eval_const(const Design*des, const NetScope*scope) const
delete r;
return res;
}
verinum* PEConcat::eval_const(Design*des, NetScope*scope) const
{
verinum*accum = parms_[0]->eval_const(des, scope);
if (accum == 0)
return 0;
for (unsigned idx = 1 ; idx < parms_.count() ; idx += 1) {
verinum*tmp = parms_[idx]->eval_const(des, scope);
if (tmp == 0) {
delete accum;
return 0;
}
assert(tmp);
*accum = concat(*accum, *tmp);
delete tmp;
}
return accum;
}
/*
* 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 NetScope*scope) const
verinum* PEIdent::eval_const(Design*des, NetScope*scope) const
{
assert(scope);
const NetExpr*expr = des->find_parameter(scope, path_);
NetNet*net;
NetEvent*eve;
const NetExpr*expr;
const name_component_t&name_tail = path_.back();
// Handle the special case that this ident is a genvar
// variable name. In that case, the genvar meaning preempts
// everything and we just return that value immediately.
if (scope->genvar_tmp
&& strcmp(name_tail.name,scope->genvar_tmp) == 0) {
return new verinum(scope->genvar_tmp_val);
}
symbol_search(des, scope, path_, net, expr, eve);
if (expr == 0)
return 0;
@@ -166,30 +202,30 @@ verinum* PEIdent::eval_const(const Design*des, const NetScope*scope) const
assert(eval);
if (msb_ || lsb_)
if (!name_tail.index.empty())
return 0;
return new verinum(eval->value());
}
verinum* PEFNumber::eval_const(const Design*, const NetScope*) const
verinum* PEFNumber::eval_const(Design*, NetScope*) const
{
long val = value_->as_long();
return new verinum(val);
}
verinum* PENumber::eval_const(const Design*, const NetScope*) const
verinum* PENumber::eval_const(Design*, NetScope*) const
{
return new verinum(value());
}
verinum* PEString::eval_const(const Design*, const NetScope*) const
verinum* PEString::eval_const(Design*, NetScope*) const
{
return new verinum(string(text_));
}
verinum* PETernary::eval_const(const Design*des, const NetScope*scope) const
verinum* PETernary::eval_const(Design*des, NetScope*scope) const
{
verinum*test = expr_->eval_const(des, scope);
if (test == 0)
@@ -209,7 +245,7 @@ verinum* PETernary::eval_const(const Design*des, const NetScope*scope) const
}
}
verinum* PEUnary::eval_const(const Design*des, const NetScope*scope) const
verinum* PEUnary::eval_const(Design*des, NetScope*scope) const
{
verinum*val = expr_->eval_const(des, scope);
if (val == 0)
@@ -223,7 +259,7 @@ verinum* PEUnary::eval_const(const Design*des, const NetScope*scope) const
/* We need to expand the value a bit if we are
taking the 2's complement so that we are
guaranteed to not overflow. */
verinum tmp (0UL, val->len()+1);
verinum tmp ((uint64_t)0, val->len()+1);
for (unsigned idx = 0 ; idx < val->len() ; idx += 1)
tmp.set(idx, val->get(idx));
@@ -240,6 +276,43 @@ verinum* PEUnary::eval_const(const Design*des, const NetScope*scope) const
/*
* $Log: eval.cc,v $
* Revision 1.47 2007/06/04 19:14:06 steve
* Build errors in picky GCC compilers.
*
* Revision 1.46 2007/05/24 04:07:12 steve
* Rework the heirarchical identifier parse syntax and pform
* to handle more general combinations of heirarch and bit selects.
*
* Revision 1.45 2007/03/07 00:38:15 steve
* Lint fixes.
*
* Revision 1.44 2007/01/16 05:44:15 steve
* Major rework of array handling. Memories are replaced with the
* more general concept of arrays. The NetMemory and NetEMemory
* classes are removed from the ivl core program, and the IVL_LPM_RAM
* lpm type is removed from the ivl_target API.
*
* Revision 1.43 2006/08/08 05:11:37 steve
* Handle 64bit delay constants.
*
* Revision 1.42 2006/05/19 04:07:24 steve
* eval_const is not strict.
*
* Revision 1.41 2006/05/17 16:49:30 steve
* Error message if concat expression cannot evaluate.
*
* Revision 1.40 2006/04/10 00:37:42 steve
* Add support for generate loops w/ wires and gates.
*
* Revision 1.39 2005/12/07 04:04:23 steve
* Allow constant concat expressions.
*
* Revision 1.38 2005/11/27 17:01:57 steve
* Fix for stubborn compiler.
*
* Revision 1.37 2005/11/27 05:56:20 steve
* Handle bit select of parameter with ranges.
*
* Revision 1.36 2003/06/21 01:21:43 steve
* Harmless fixup of warnings.
*
+8 -3
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: eval_attrib.cc,v 1.7 2004/02/20 18:53:35 steve Exp $"
#ident "$Id: eval_attrib.cc,v 1.9 2007/06/04 19:14:06 steve Exp $"
#endif
# include "config.h"
@@ -35,8 +35,7 @@
attrib_list_t* evaluate_attributes(const map<perm_string,PExpr*>&att,
unsigned&natt,
const Design*des,
const NetScope*scope)
Design*des, NetScope*scope)
{
natt = att.size();
if (natt == 0)
@@ -74,6 +73,12 @@ attrib_list_t* evaluate_attributes(const map<perm_string,PExpr*>&att,
/*
* $Log: eval_attrib.cc,v $
* Revision 1.9 2007/06/04 19:14:06 steve
* Build errors in picky GCC compilers.
*
* Revision 1.8 2005/11/27 17:01:57 steve
* Fix for stubborn compiler.
*
* Revision 1.7 2004/02/20 18:53:35 steve
* Addtrbute keys are perm_strings.
*
+361 -205
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: eval_tree.cc,v 1.62 2004/10/04 01:10:53 steve Exp $"
#ident "$Id: eval_tree.cc,v 1.77 2007/06/02 03:42:12 steve Exp $"
#endif
# include "config.h"
@@ -26,8 +26,9 @@
# include <iostream>
# include "netlist.h"
# include "ivl_assert.h"
NetExpr* NetExpr::eval_tree()
NetExpr* NetExpr::eval_tree(int prune_to_width)
{
return 0;
}
@@ -51,33 +52,148 @@ void NetEBinary::eval_sub_tree_()
}
}
NetEConst* NetEBAdd::eval_tree()
bool NetEBinary::get_real_arguments_(verireal&lval, verireal&rval)
{
switch (left_->expr_type()) {
case IVL_VT_REAL: {
NetECReal*lc = dynamic_cast<NetECReal*> (left_);
if (lc == 0) return false;
lval = lc->value();
break;
}
case IVL_VT_BOOL:
case IVL_VT_LOGIC: {
NetEConst*lc = dynamic_cast<NetEConst*>(left_);
if (lc == 0) return false;
verinum tmp = lc->value();
lval = verireal(tmp.as_long());
break;
}
default:
assert(0);
}
switch (right_->expr_type()) {
case IVL_VT_REAL: {
NetECReal*rc = dynamic_cast<NetECReal*> (right_);
if (rc == 0) return 0;
rval = rc->value();
break;
}
case IVL_VT_BOOL:
case IVL_VT_LOGIC: {
NetEConst*rc = dynamic_cast<NetEConst*>(right_);
if (rc == 0) return 0;
verinum tmp = rc->value();
rval = verireal(tmp.as_long());
break;
}
default:
assert(0);
}
return true;
}
NetExpr* NetEBAdd::eval_tree(int prune_to_width)
{
eval_sub_tree_();
if (left_->expr_type() == IVL_VT_REAL || right_->expr_type()==IVL_VT_REAL)
return eval_tree_real_();
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();
/* If both operands are constant, then replace the entire
expression with a constant value. */
if (lc != 0 && rc != 0) {
verinum lval = lc->value();
verinum rval = rc->value();
verinum val;
switch (op_) {
case '+':
val = lval + rval;
break;
case '-':
val = lval - rval;
break;
default:
verinum val;
switch (op_) {
case '+':
val = lval + rval;
break;
case '-':
val = lval - rval;
break;
default:
return 0;
}
return new NetEConst(val);
}
/* Try to combine a right constant value with the right
constant value of a sub-expression add. For example, the
expression (a + 2) - 1 can be rewritten as a + 1. */
NetEBAdd*se = dynamic_cast<NetEBAdd*>(left_);
lc = se? dynamic_cast<NetEConst*>(se->right_) : 0;
if (lc != 0 && rc != 0) {
assert(se != 0);
verinum lval = lc->value();
verinum rval = rc->value();
verinum val;
if (op_ == se->op_) {
/* (a + lval) + rval --> a + (rval+lval) */
/* (a - lval) - rval --> a - (rval+lval) */
val = rval + lval;
} else {
/* (a - lval) + rval --> a + (rval-lval) */
/* (a + lval) - rval --> a - (rval-lval) */
val = rval - lval;
}
NetEConst*tmp = new NetEConst(val);
left_ = se->left_->dup_expr();
delete se;
delete right_;
right_ = tmp;
/* We've changed the subexpression, but the result is
still not constant, so return nil here anyhow. */
return 0;
}
return new NetEConst(val);
/* Nothing more to be done, the value is not constant. */
return 0;
}
NetEConst* NetEBBits::eval_tree()
NetECReal* NetEBAdd::eval_tree_real_()
{
verireal lval;
verireal rval;
bool flag = get_real_arguments_(lval, rval);
if (!flag) return 0;
verireal res_val;
switch (op()) {
case '+':
res_val = lval + rval;
break;
case '-':
res_val = lval - rval;
break;
default:
ivl_assert(*this, 0);
}
NetECReal*res = new NetECReal( res_val );
res->set_line(*this);
return res;
}
NetEConst* NetEBBits::eval_tree(int prune_to_width)
{
eval_sub_tree_();
@@ -175,43 +291,6 @@ NetEConst* NetEBBits::eval_tree()
return new NetEConst(res);
}
NetEConst* NetEBComp::eval_eqeq_()
{
NetEConst*l = dynamic_cast<NetEConst*>(left_);
if (l == 0) return 0;
NetEConst*r = dynamic_cast<NetEConst*>(right_);
if (r == 0) return 0;
const verinum&lv = l->value();
const verinum&rv = r->value();
unsigned s_len = lv.len();
if (rv.len() < s_len) s_len = rv.len();
verinum result(verinum::V1, 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_()
{
@@ -224,20 +303,27 @@ NetEConst* NetEBComp::eval_less_()
return new NetEConst(result);
}
/* Detect the case where the right side is greater that or
/* Detect the case where the right side is greater than 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);
have. Use the width of the left expression as all 1's to
calculate the maximum possible width for the left_
expression. This test only works of the compare is
unsigned. */
if (! (rv.has_sign() || left_->has_sign())) {
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();
verinum lv = l->value();
if (! lv.is_defined()) {
verinum result(verinum::Vx, 1);
return new NetEConst(result);
@@ -266,7 +352,7 @@ NetEConst* NetEBComp::eval_leeq_real_()
double lv, rv;
switch (left_->expr_type()) {
case ET_REAL:
case IVL_VT_REAL:
rtmp = dynamic_cast<NetECReal*> (left_);
if (rtmp == 0)
return 0;
@@ -274,7 +360,7 @@ NetEConst* NetEBComp::eval_leeq_real_()
lv = rtmp->value().as_double();
break;
case ET_VECTOR:
case IVL_VT_LOGIC:
vtmp = dynamic_cast<NetEConst*> (left_);
if (vtmp == 0)
return 0;
@@ -288,7 +374,7 @@ NetEConst* NetEBComp::eval_leeq_real_()
switch (right_->expr_type()) {
case ET_REAL:
case IVL_VT_REAL:
rtmp = dynamic_cast<NetECReal*> (right_);
if (rtmp == 0)
return 0;
@@ -296,7 +382,7 @@ NetEConst* NetEBComp::eval_leeq_real_()
rv = rtmp->value().as_double();
break;
case ET_VECTOR:
case IVL_VT_LOGIC:
vtmp = dynamic_cast<NetEConst*> (right_);
if (vtmp == 0)
return 0;
@@ -317,9 +403,9 @@ NetEConst* NetEBComp::eval_leeq_real_()
NetEConst* NetEBComp::eval_leeq_()
{
if (right_->expr_type() == ET_REAL)
if (right_->expr_type() == IVL_VT_REAL)
return eval_leeq_real_();
if (left_->expr_type() == ET_REAL)
if (left_->expr_type() == IVL_VT_REAL)
return eval_leeq_real_();
NetEConst*r = dynamic_cast<NetEConst*>(right_);
@@ -374,8 +460,8 @@ NetEConst* NetEBComp::eval_leeq_()
NetEConst* NetEBComp::eval_gt_()
{
if ((left_->expr_type() == NetExpr::ET_REAL)
&& (right_->expr_type() == NetExpr::ET_REAL)) {
if ((left_->expr_type() == IVL_VT_REAL)
&& (right_->expr_type() == IVL_VT_REAL)) {
NetECReal*tmpl = dynamic_cast<NetECReal*>(left_);
if (tmpl == 0)
@@ -413,7 +499,7 @@ NetEConst* NetEBComp::eval_gt_()
}
/* Compare with a real value. Do it as double precision. */
if (right_->expr_type() == NetExpr::ET_REAL) {
if (right_->expr_type() == IVL_VT_REAL) {
NetECReal*tmp = dynamic_cast<NetECReal*>(right_);
if (tmp == 0)
return 0;
@@ -450,8 +536,8 @@ NetEConst* NetEBComp::eval_gt_()
NetEConst* NetEBComp::eval_gteq_()
{
if ((left_->expr_type() == NetExpr::ET_REAL)
&& (right_->expr_type() == NetExpr::ET_REAL)) {
if ((left_->expr_type() == IVL_VT_REAL)
&& (right_->expr_type() == IVL_VT_REAL)) {
NetECReal*tmpl = dynamic_cast<NetECReal*>(left_);
if (tmpl == 0)
@@ -479,7 +565,7 @@ NetEConst* NetEBComp::eval_gteq_()
/* Detect the case where the left side is greater than the
largest value the right side can possibly have. */
if (right_->expr_type() == NetExpr::ET_VECTOR) {
if (right_->expr_type() == IVL_VT_LOGIC) {
assert(right_->expr_width() > 0);
verinum rv (verinum::V1, right_->expr_width());
if (lv >= rv) {
@@ -489,7 +575,7 @@ NetEConst* NetEBComp::eval_gteq_()
}
/* Compare with a real value. Do it as double precision. */
if (right_->expr_type() == NetExpr::ET_REAL) {
if (right_->expr_type() == IVL_VT_REAL) {
NetECReal*tmp = dynamic_cast<NetECReal*>(right_);
if (tmp == 0)
return 0;
@@ -510,21 +596,25 @@ NetEConst* NetEBComp::eval_gteq_()
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.has_sign() && rv.has_sign()) {
if (lv.as_ulong() >= rv.as_ulong()) {
verinum result(verinum::V1, 1);
return new NetEConst(result);
if (lv.as_long() >= rv.as_long()) {
verinum result(verinum::V1, 1);
return new NetEConst(result);
}
} else {
if (lv.as_ulong() >= rv.as_ulong()) {
verinum result(verinum::V1, 1);
return new NetEConst(result);
}
}
verinum result(verinum::V0, 1);
return new NetEConst(result);
}
NetEConst* NetEBComp::eval_neeq_()
NetEConst* NetEBComp::eval_eqeq_(bool ne_flag)
{
NetEConst*l = dynamic_cast<NetEConst*>(left_);
if (l == 0) return 0;
@@ -534,7 +624,10 @@ NetEConst* NetEBComp::eval_neeq_()
const verinum&lv = l->value();
const verinum&rv = r->value();
verinum::V res = verinum::V0;
const verinum::V eq_res = ne_flag? verinum::V0 : verinum::V1;
const verinum::V ne_res = ne_flag? verinum::V1 : verinum::V0;
verinum::V res = eq_res;
unsigned top = lv.len();
if (rv.len() < top)
top = rv.len();
@@ -567,10 +660,18 @@ NetEConst* NetEBComp::eval_neeq_()
break;
if (rv.get(idx) != lv.get(idx))
res = verinum::V1;
res = ne_res;
}
if (res != verinum::Vx) {
verinum::V lpad = verinum::V0;
verinum::V rpad = verinum::V0;
if (lv.has_sign() && lv.get(lv.len()-1) == verinum::V1)
lpad = verinum::V1;
if (rv.has_sign() && rv.get(rv.len()-1) == verinum::V1)
rpad = verinum::V1;
for (unsigned idx = top ; idx < lv.len() ; idx += 1)
switch (lv.get(idx)) {
@@ -579,9 +680,14 @@ NetEConst* NetEBComp::eval_neeq_()
res = verinum::Vx;
break;
case verinum::V0:
if (res != verinum::Vx && rpad != verinum::V0)
res = ne_res;
break;
case verinum::V1:
if (res != verinum::Vx)
res = verinum::V1;
if (res != verinum::Vx && rpad != verinum::V1)
res = ne_res;
break;
default:
@@ -596,9 +702,14 @@ NetEConst* NetEBComp::eval_neeq_()
res = verinum::Vx;
break;
case verinum::V0:
if (res != verinum::Vx && lpad != verinum::V0)
res = ne_res;
break;
case verinum::V1:
if (res != verinum::Vx)
res = verinum::V1;
if (res != verinum::Vx && lpad != verinum::V1)
res = ne_res;
break;
default:
@@ -657,7 +768,7 @@ NetEConst* NetEBComp::eval_neeqeq_()
return res;
}
NetEConst* NetEBComp::eval_tree()
NetEConst* NetEBComp::eval_tree(int prune_to_width)
{
eval_sub_tree_();
@@ -666,7 +777,7 @@ NetEConst* NetEBComp::eval_tree()
return eval_eqeqeq_();
case 'e': // Equality (==)
return eval_eqeq_();
return eval_eqeq_(false);
case 'G': // >=
return eval_gteq_();
@@ -678,7 +789,7 @@ NetEConst* NetEBComp::eval_tree()
return eval_neeqeq_();
case 'n': // not-equal (!=)
return eval_neeq_();
return eval_eqeq_(true);
case '<': // Less than
return eval_less_();
@@ -695,11 +806,11 @@ NetEConst* NetEBComp::eval_tree()
* The NetEBDiv operator includes the / and % operators. First evaluate
* the sub-expressions, then perform the required operation.
*/
NetExpr* NetEBDiv::eval_tree()
NetExpr* NetEBDiv::eval_tree(int prune_to_width)
{
eval_sub_tree_();
if (expr_type() == NetExpr::ET_REAL) {
if (expr_type() == IVL_VT_REAL) {
NetECReal*lc = dynamic_cast<NetECReal*>(left_);
if (lc == 0) return 0;
@@ -744,7 +855,7 @@ NetExpr* NetEBDiv::eval_tree()
} else {
assert(expr_type() == NetExpr::ET_VECTOR);
assert(expr_type() == IVL_VT_LOGIC);
NetEConst*lc = dynamic_cast<NetEConst*>(left_);
if (lc == 0) return 0;
NetEConst*rc = dynamic_cast<NetEConst*>(right_);
@@ -765,7 +876,7 @@ NetExpr* NetEBDiv::eval_tree()
return 0;
}
NetEConst* NetEBLogic::eval_tree()
NetEConst* NetEBLogic::eval_tree(int prune_to_width)
{
eval_sub_tree_();
NetEConst*lc = dynamic_cast<NetEConst*>(left_);
@@ -831,50 +942,14 @@ NetEConst* NetEBLogic::eval_tree()
return new NetEConst(verinum(res, 1));
}
NetExpr* NetEBMult::eval_tree_real_()
{
verireal lval;
verireal rval;
switch (left_->expr_type()) {
case ET_REAL: {
NetECReal*lc = dynamic_cast<NetECReal*> (left_);
if (lc == 0) return 0;
lval = lc->value();
break;
}
case ET_VECTOR: {
NetEConst*lc = dynamic_cast<NetEConst*>(left_);
if (lc == 0) return 0;
verinum tmp = lc->value();
lval = verireal(tmp.as_long());
break;
}
default:
assert(0);
}
switch (right_->expr_type()) {
case ET_REAL: {
NetECReal*rc = dynamic_cast<NetECReal*> (right_);
if (rc == 0) return 0;
rval = rc->value();
break;
}
case ET_VECTOR: {
NetEConst*rc = dynamic_cast<NetEConst*>(right_);
if (rc == 0) return 0;
verinum tmp = rc->value();
rval = verireal(tmp.as_long());
break;
}
default:
assert(0);
}
bool flag = get_real_arguments_(lval, rval);
if (! flag) return 0;
NetECReal*res = new NetECReal(lval * rval);
@@ -882,14 +957,14 @@ NetExpr* NetEBMult::eval_tree_real_()
return res;
}
NetExpr* NetEBMult::eval_tree()
NetExpr* NetEBMult::eval_tree(int prune_to_width)
{
eval_sub_tree_();
if (expr_type() == ET_REAL)
if (expr_type() == IVL_VT_REAL)
return eval_tree_real_();
assert(expr_type() == ET_VECTOR);
assert(expr_type() == IVL_VT_LOGIC);
NetEConst*lc = dynamic_cast<NetEConst*>(left_);
if (lc == 0) return 0;
@@ -902,11 +977,45 @@ NetExpr* NetEBMult::eval_tree()
return new NetEConst(lval * rval);
}
NetExpr* NetEBPow::eval_tree_real_()
{
verireal lval;
verireal rval;
bool flag = get_real_arguments_(lval, rval);
if (! flag) return 0;
NetECReal*res = new NetECReal( pow(lval,rval) );
res->set_line(*this);
return res;
}
NetExpr* NetEBPow::eval_tree(int prune_to_width)
{
eval_sub_tree_();
if (expr_type() == IVL_VT_REAL)
return eval_tree_real_();
assert(expr_type() == IVL_VT_LOGIC);
NetEConst*lc = dynamic_cast<NetEConst*>(left_);
if (lc == 0) return 0;
NetEConst*rc = dynamic_cast<NetEConst*>(right_);
if (rc == 0) return 0;
verinum lval = lc->value();
verinum rval = rc->value();
return new NetEConst( pow(lval,rval) );
}
/*
* Evaluate the shift operator if possible. For this to work, both
* operands must be constant.
*/
NetEConst* NetEBShift::eval_tree()
NetEConst* NetEBShift::eval_tree(int prune_to_width)
{
eval_sub_tree_();
NetEConst*re = dynamic_cast<NetEConst*>(right_);
@@ -929,6 +1038,13 @@ NetEConst* NetEBShift::eval_tree()
unsigned shift = rv.as_ulong();
if (debug_eval_tree) {
cerr << get_line() << ": debug: "
<< "Evaluate " << lv << "<<" << op() << ">> "
<< rv << ", wid=" << wid << ", shift=" << shift
<< ", lv.has_len()=" << lv.has_len() << endl;
}
if ((wid == 0) || ! lv.has_len()) {
/* If the caller doesn't care what the width is,
then calcuate a width from the trimmed left
@@ -940,6 +1056,9 @@ NetEConst* NetEBShift::eval_tree()
wid = lv.len() + shift;
}
if (prune_to_width > 0 && wid > (unsigned)prune_to_width)
wid = prune_to_width;
assert(wid);
verinum nv (verinum::V0, wid, lv.has_len());
@@ -980,7 +1099,7 @@ NetEConst* NetEBShift::eval_tree()
return res;
}
NetEConst* NetEConcat::eval_tree()
NetEConst* NetEConcat::eval_tree(int prune_to_width)
{
unsigned repeat_val = repeat();
unsigned local_errors = 0;
@@ -1074,61 +1193,26 @@ NetEConst* NetEConcat::eval_tree()
return res;
}
/*
* There are limits to our ability to evaluate a memory reference
* expression, because the content of a memory is never
* constant. However, the index expression may be precalculated, and
* there are certain index values that do give us constant results.
*/
NetExpr* NetEMemory::eval_tree()
NetExpr* NetEParam::eval_tree(int prune_to_width)
{
/* Attempt to evaluate the index expression to a constant, if
it is not already. */
if (idx_ && !dynamic_cast<NetEConst*>(idx_)) {
NetExpr* tmp = idx_->eval_tree();
if (tmp) {
delete idx_;
idx_ = tmp;
}
}
NetEConst*itmp = dynamic_cast<NetEConst*>(idx_);
if (itmp == 0)
if (des_ == 0) {
assert(scope_ == 0);
return 0;
verinum ival = itmp->value();
/* If the index expression has any x or z bits, then we know
already that the expression result is a constant x. */
if (! ival.is_defined()) {
verinum xres (verinum::Vx, mem_->width(), false);
NetEConst*res = new NetEConst(xres);
return res;
}
/* If the index expression is outside the range of the memory,
then the result is a constant x. */
unsigned norm_idx = mem_->index_to_address(ival.as_long());
if (norm_idx >= mem_->count()) {
verinum xres (verinum::Vx, mem_->width(), false);
NetEConst*res = new NetEConst(xres);
return res;
if (debug_elaborate) {
cerr << get_line() << ": debug: evaluating expression: "
<< *this << endl;
}
return 0;
}
NetExpr* NetEParam::eval_tree()
{
if (des_ == 0)
return 0;
assert(scope_);
const NetExpr*expr = scope_->get_parameter(name_);
const NetExpr*expr_msb;
const NetExpr*expr_lsb;
const NetExpr*expr = scope_->get_parameter(name_, expr_msb, expr_lsb);
if (expr == 0) {
cerr << get_line() << ": internal error: Unable to match "
<< "parameter " << name_ << " in scope "
<< scope_->name() << endl;
<< scope_path(scope_) << endl;
return 0;
}
@@ -1175,7 +1259,8 @@ NetExpr* NetEParam::eval_tree()
switch (res->expr_type()) {
case NetExpr::ET_VECTOR:
case IVL_VT_BOOL:
case IVL_VT_LOGIC:
{ NetEConst*tmp = dynamic_cast<NetEConst*>(res);
if (tmp == 0) {
cerr << get_line() << ": internal error: parameter "
@@ -1192,7 +1277,7 @@ NetExpr* NetEParam::eval_tree()
return ptmp;
}
case NetExpr::ET_REAL:
case IVL_VT_REAL:
{ NetECReal*tmp = dynamic_cast<NetECReal*>(res);
if (tmp == 0) {
cerr << get_line() << ": internal error: parameter "
@@ -1215,7 +1300,7 @@ NetExpr* NetEParam::eval_tree()
}
}
NetEConst* NetESelect::eval_tree()
NetEConst* NetESelect::eval_tree(int prune_to_width)
{
NetEConst*expr = dynamic_cast<NetEConst*>(expr_);
if (expr == 0) {
@@ -1228,31 +1313,50 @@ NetEConst* NetESelect::eval_tree()
expr = dynamic_cast<NetEConst*>(expr_);
}
NetEConst*base = dynamic_cast<NetEConst*>(base_);
if (base == 0) {
NetExpr*tmp = base_->eval_tree();
if (tmp != 0) {
delete base_;
base_ = tmp;
long bval = 0;
if (base_) {
NetEConst*base = dynamic_cast<NetEConst*>(base_);
if (base == 0) {
NetExpr*tmp = base_->eval_tree();
if (tmp != 0) {
delete base_;
base_ = tmp;
}
base = dynamic_cast<NetEConst*>(base_);
}
base = dynamic_cast<NetEConst*>(base_);
if (base == 0)
return 0;
bval = base->value().as_long();
}
if (expr == 0)
return 0;
if (base == 0)
return 0;
verinum eval = expr->value();
verinum oval (verinum::V0, expr_width(), true);
long bval = base->value().as_long();
verinum::V pad_bit = verinum::Vx;
if (base_ == 0) {
/* If the base is NULL (different from 0) the this
select is here for sign extension. So calculate a
proper pad bit. Extend x or z or 0, and sign extend 1
if this is signed. */
unsigned top = expr->expr_width()-1;
pad_bit = eval.get(top);
if (pad_bit==verinum::V1 && !has_sign())
pad_bit = verinum::V0;
}
for (unsigned long idx = 0 ; idx < expr_width() ; idx += 1) {
if ((bval >= 0) && ((unsigned long) bval < eval.len()))
oval.set(idx, eval.get(bval));
else
oval.set(idx, verinum::Vx);
oval.set(idx, pad_bit);
bval += 1;
}
@@ -1269,7 +1373,7 @@ NetEConst* NetESelect::eval_tree()
* evaluates to x or z, then merge the constant bits of the true and
* false expressions.
*/
NetExpr* NetETernary::eval_tree()
NetExpr* NetETernary::eval_tree(int prune_to_width)
{
NetExpr*tmp;
@@ -1406,7 +1510,7 @@ void NetEUnary::eval_expr_()
expr_ = oper;
}
NetEConst* NetEUnary::eval_tree()
NetEConst* NetEUnary::eval_tree(int prune_to_width)
{
eval_expr_();
NetEConst*rval = dynamic_cast<NetEConst*>(expr_);
@@ -1463,12 +1567,12 @@ NetEConst* NetEUnary::eval_tree()
}
NetEConst* NetEUBits::eval_tree()
NetEConst* NetEUBits::eval_tree(int prune_to_width)
{
return NetEUnary::eval_tree();
return NetEUnary::eval_tree(prune_to_width);
}
NetEConst* NetEUReduce::eval_tree()
NetEConst* NetEUReduce::eval_tree(int prune_to_width)
{
eval_expr_();
NetEConst*rval = dynamic_cast<NetEConst*>(expr_);
@@ -1551,6 +1655,58 @@ NetEConst* NetEUReduce::eval_tree()
/*
* $Log: eval_tree.cc,v $
* Revision 1.77 2007/06/02 03:42:12 steve
* Properly evaluate scope path expressions.
*
* Revision 1.76 2007/05/31 18:36:06 steve
* Fix warning (ldolittle)
*
* Revision 1.75 2007/04/07 04:46:18 steve
* Handle evaluate of addition of real valued constants.
*
* Revision 1.74 2007/03/08 05:30:02 steve
* Limit the calculated widths of constants.
*
* Revision 1.73 2007/01/16 05:44:15 steve
* Major rework of array handling. Memories are replaced with the
* more general concept of arrays. The NetMemory and NetEMemory
* classes are removed from the ivl core program, and the IVL_LPM_RAM
* lpm type is removed from the ivl_target API.
*
* Revision 1.72 2006/11/04 06:16:27 steve
* Fix padding of constant eval of NetESelect.
*
* Revision 1.71 2006/10/30 05:44:49 steve
* Expression widths with unsized literals are pseudo-infinite width.
*
* Revision 1.70 2006/09/19 23:00:15 steve
* Use elab_and_eval for bit select expressions.
*
* Revision 1.69 2006/07/31 03:50:17 steve
* Add support for power in constant expressions.
*
* Revision 1.68 2006/03/18 22:52:27 steve
* Properly handle signedness in compare.
*
* Revision 1.67 2005/11/27 05:56:20 steve
* Handle bit select of parameter with ranges.
*
* Revision 1.66 2005/11/10 13:28:12 steve
* Reorganize signal part select handling, and add support for
* indexed part selects.
*
* Expand expression constant propagation to eliminate extra
* sums in certain cases.
*
* Revision 1.65 2005/09/14 02:53:14 steve
* Support bool expressions and compares handle them optimally.
*
* Revision 1.64 2005/07/11 16:56:50 steve
* Remove NetVariable and ivl_variable_t structures.
*
* Revision 1.63 2005/06/17 05:05:53 steve
* Watch out for signed constants in magnitude compare.
*
* Revision 1.62 2004/10/04 01:10:53 steve
* Clean up spurious trailing white space.
*
+8 -2
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: hello_vpi.c,v 1.3 2002/08/12 01:35:01 steve Exp $"
#ident "$Id: hello_vpi.c,v 1.5 2007/01/17 05:35:48 steve Exp $"
#endif
/*
@@ -33,7 +33,7 @@
# include <vpi_user.h>
static int my_hello_calltf(char *xx)
static PLI_INT32 my_hello_calltf(char *xx)
{
vpi_printf("Hello World, from VPI.\n");
return 0;
@@ -62,6 +62,12 @@ void (*vlog_startup_routines[])() = {
};
/*
* $Log: hello_vpi.c,v $
* Revision 1.5 2007/01/17 05:35:48 steve
* Fix typo is hello_vpi.c example.
*
* Revision 1.4 2006/10/30 22:46:25 steve
* Updates for Cygwin portability (pr1585922)
*
* Revision 1.3 2002/08/12 01:35:01 steve
* conditional ident string using autoconfig.
*
+4 -4
View File
@@ -16,13 +16,13 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
* $Id: sqrt-virtex.v,v 1.4 2003/11/25 18:35:31 steve Exp $"
* $Id: sqrt-virtex.v,v 1.5 2007/03/22 16:08:18 steve Exp $"
*/
/*
* This module is a synthesizeable square-root function. It is also a
* detailed example of how to target Xilinx Virtex parts using
* Icarus Verilog. In fact, for no particular reason other then to
* Icarus Verilog. In fact, for no particular reason other than to
* be excessively specific, I will step through the process of
* generating a design for a Spartan-II XC2S15-VQ100, and also how to
* generate a generic library part for larger Virtex designs.
@@ -129,7 +129,7 @@
* This command creates from the chip.ngd the file "chip_root.v" that
* contains Verilog code that simulates the mapped design. This output
* Verilog has the single root module "chip_root", which came from the
* name of the root module when we were making hte EDIF file in the
* name of the root module when we were making the EDIF file in the
* first place. The module has ports named just line the ports of the
* chip_root module below.
*
@@ -183,7 +183,7 @@
* where sqrt(y) is the exact square root of y and floor(N) is the
* largest integer <= N.
*
* For 32bit numbers, this will never run more then 16 iterations,
* For 32 bit numbers, this will never run more than 16 iterations,
* which amounts to 16 clocks.
*/
+2 -2
View File
@@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
* $Id: sqrt.vl,v 1.4 2004/10/04 01:10:56 steve Exp $"
* $Id: sqrt.vl,v 1.5 2007/03/22 16:08:18 steve Exp $"
*/
/*
@@ -50,7 +50,7 @@
* where sqrt(y) is the exact square root of y and floor(N) is the
* largest integer <= N.
*
* For 32bit numbers, this will never run more then 16 iterations,
* For 32 bit numbers, this will never run more than 16 iterations,
* which amounts to 16 clocks.
*/
+392 -306
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1999-2004 Stephen Williams (steve@icarus.com)
* Copyright (c) 1999-2005 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: expr_synth.cc,v 1.59 2004/06/30 02:16:26 steve Exp $"
#ident "$Id: expr_synth.cc,v 1.87 2007/06/02 03:42:12 steve Exp $"
#endif
# include "config.h"
@@ -26,6 +26,7 @@
# include "netlist.h"
# include "netmisc.h"
# include "ivl_assert.h"
NetNet* NetExpr::synthesize(Design*des)
{
@@ -45,26 +46,25 @@ NetNet* NetEBAdd::synthesize(Design*des)
NetNet*lsig = left_->synthesize(des);
NetNet*rsig = right_->synthesize(des);
assert(expr_width() >= lsig->pin_count());
assert(expr_width() >= rsig->pin_count());
assert(expr_width() >= lsig->vector_width());
assert(expr_width() >= rsig->vector_width());
lsig = pad_to_width(des, lsig, expr_width());
rsig = pad_to_width(des, rsig, expr_width());
assert(lsig->pin_count() == rsig->pin_count());
unsigned width=lsig->pin_count();
assert(lsig->vector_width() == rsig->vector_width());
unsigned width=lsig->vector_width();
perm_string path = lsig->scope()->local_symbol();
NetNet*osig = new NetNet(lsig->scope(), path, NetNet::IMPLICIT, width);
osig->local_flag(true);
osig->data_type(expr_type());
perm_string oname = osig->scope()->local_symbol();
NetAddSub *adder = new NetAddSub(lsig->scope(), oname, width);
for (unsigned idx = 0 ; idx < width; idx += 1) {
connect(lsig->pin(idx), adder->pin_DataA(idx));
connect(rsig->pin(idx), adder->pin_DataB(idx));
connect(osig->pin(idx), adder->pin_Result(idx));
}
connect(lsig->pin(0), adder->pin_DataA());
connect(rsig->pin(0), adder->pin_DataB());
connect(osig->pin(0), adder->pin_Result());
des->add_node(adder);
switch (op()) {
@@ -92,150 +92,60 @@ NetNet* NetEBBits::synthesize(Design*des)
NetScope*scope = lsig->scope();
assert(scope);
string path = des->local_symbol(scope->name());
if (lsig->pin_count() != rsig->pin_count()) {
if (lsig->vector_width() != rsig->vector_width()) {
cerr << get_line() << ": internal error: bitwise (" << op_
<< ") widths do not match: " << lsig->pin_count()
<< " != " << rsig->pin_count() << endl;
<< ") widths do not match: " << lsig->vector_width()
<< " != " << rsig->vector_width() << endl;
cerr << get_line() << ": : width="
<< lsig->pin_count() << ": " << *left_ << endl;
<< lsig->vector_width() << ": " << *left_ << endl;
cerr << get_line() << ": : width="
<< rsig->pin_count() << ": " << *right_ << endl;
<< rsig->vector_width() << ": " << *right_ << endl;
return 0;
}
assert(lsig->pin_count() == rsig->pin_count());
assert(lsig->vector_width() == rsig->vector_width());
NetNet*osig = new NetNet(scope, scope->local_symbol(),
NetNet::IMPLICIT, lsig->pin_count());
NetNet::IMPLICIT, lsig->vector_width());
osig->local_flag(true);
osig->data_type(expr_type());
for (unsigned idx = 0 ; idx < osig->pin_count() ; idx += 1) {
perm_string oname = scope->local_symbol();
NetLogic*gate;
perm_string oname = scope->local_symbol();
unsigned wid = lsig->vector_width();
NetLogic*gate;
/* If the rsig bit is constant, then look for special
cases that I can use to reduce the generated
logic. If I find one, then handle it immediately and
skip the rest of the processing of this bit. */
if (rsig->pin(idx).nexus()->drivers_constant()) {
verinum::V bval = rsig->pin(idx).nexus()->driven_value();
/* (A & 0) is (0) */
if ((op() == '&') && bval == verinum::V0) {
connect(osig->pin(idx), rsig->pin(idx));
continue;
}
/* (A & 1) is A */
if ((op() == '&') && bval == verinum::V1) {
connect(osig->pin(idx), lsig->pin(idx));
continue;
}
}
switch (op()) {
case '&':
gate = new NetLogic(scope, oname, 3, NetLogic::AND);
break;
case '|':
gate = new NetLogic(scope, oname, 3, NetLogic::OR);
break;
case '^':
gate = new NetLogic(scope, oname, 3, NetLogic::XOR);
break;
case 'O':
gate = new NetLogic(scope, oname, 3, NetLogic::NOR);
break;
case 'X':
gate = new NetLogic(scope, oname, 3, NetLogic::XNOR);
break;
default:
assert(0);
}
connect(osig->pin(idx), gate->pin(0));
connect(lsig->pin(idx), gate->pin(1));
connect(rsig->pin(idx), gate->pin(2));
des->add_node(gate);
switch (op()) {
case '&':
gate = new NetLogic(scope, oname, 3, NetLogic::AND, wid);
break;
case '|':
gate = new NetLogic(scope, oname, 3, NetLogic::OR, wid);
break;
case '^':
gate = new NetLogic(scope, oname, 3, NetLogic::XOR, wid);
break;
case 'O':
gate = new NetLogic(scope, oname, 3, NetLogic::NOR, wid);
break;
case 'X':
gate = new NetLogic(scope, oname, 3, NetLogic::XNOR, wid);
break;
default:
assert(0);
}
connect(osig->pin(0), gate->pin(0));
connect(lsig->pin(0), gate->pin(1));
connect(rsig->pin(0), gate->pin(2));
gate->set_line(*this);
des->add_node(gate);
return osig;
}
NetNet* NetEBComp::synthesize(Design*des)
{
NetEConst*lcon = reinterpret_cast<NetEConst*>(left_);
NetEConst*rcon = reinterpret_cast<NetEConst*>(right_);
/* Handle the special case where one of the inputs is constant
0. We can use an OR gate to do the comparison. Synthesize
the non-const side as normal, then or(nor) the signals
together to get result. */
if ((rcon && (rcon->value() == verinum(0UL,rcon->expr_width())))
|| (lcon && (lcon->value() == verinum(0UL,lcon->expr_width())))) {
NetNet*lsig = rcon
? left_->synthesize(des)
: right_->synthesize(des);
NetScope*scope = lsig->scope();
assert(scope);
NetNet*osig = new NetNet(scope, scope->local_symbol(),
NetNet::IMPLICIT, 1);
osig->local_flag(true);
NetLogic*gate;
switch (op_) {
case 'e':
case 'E':
gate = new NetLogic(scope, scope->local_symbol(),
lsig->pin_count()+1, NetLogic::NOR);
break;
case 'n':
case 'N':
gate = new NetLogic(scope, scope->local_symbol(),
lsig->pin_count()+1, NetLogic::OR);
break;
case '>':
/* sig > 0 is true if any bit in sig is set. This
is very much like sig != 0. (0 > sig) shouldn't
happen. */
if (rcon) {
gate = new NetLogic(scope, scope->local_symbol(),
lsig->pin_count()+1, NetLogic::OR);
} else {
assert(0);
gate = new NetLogic(scope, scope->local_symbol(),
lsig->pin_count()+1, NetLogic::NOR);
}
break;
case '<':
/* 0 < sig is handled like sig > 0. */
if (! rcon) {
gate = new NetLogic(scope, scope->local_symbol(),
lsig->pin_count()+1, NetLogic::OR);
} else {
assert(0);
gate = new NetLogic(scope, scope->local_symbol(),
lsig->pin_count()+1, NetLogic::NOR);
}
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);
@@ -243,22 +153,25 @@ NetNet* NetEBComp::synthesize(Design*des)
NetScope*scope = lsig->scope();
assert(scope);
unsigned width = lsig->pin_count();
if (rsig->pin_count() > lsig->pin_count())
width = rsig->pin_count();
unsigned width = lsig->vector_width();
if (rsig->vector_width() > width)
width = rsig->vector_width();
lsig = pad_to_width(des, lsig, width);
rsig = pad_to_width(des, rsig, width);
NetNet*osig = new NetNet(scope, scope->local_symbol(),
NetNet::IMPLICIT, 1);
osig->set_line(*this);
osig->local_flag(true);
osig->data_type(IVL_VT_LOGIC);
/* Handle the special case of a single bit equality
operation. Make an XNOR gate instead of a comparator. */
if ((width == 1) && ((op_ == 'e') || (op_ == 'E'))) {
NetLogic*gate = new NetLogic(scope, scope->local_symbol(),
3, NetLogic::XNOR);
3, NetLogic::XNOR, 1);
gate->set_line(*this);
connect(gate->pin(0), osig->pin(0));
connect(gate->pin(1), lsig->pin(0));
connect(gate->pin(2), rsig->pin(0));
@@ -271,7 +184,8 @@ NetNet* NetEBComp::synthesize(Design*des)
an XOR instead of an XNOR gate. */
if ((width == 1) && ((op_ == 'n') || (op_ == 'N'))) {
NetLogic*gate = new NetLogic(scope, scope->local_symbol(),
3, NetLogic::XOR);
3, NetLogic::XOR, 1);
gate->set_line(*this);
connect(gate->pin(0), osig->pin(0));
connect(gate->pin(1), lsig->pin(0));
connect(gate->pin(2), rsig->pin(0));
@@ -281,13 +195,11 @@ NetNet* NetEBComp::synthesize(Design*des)
NetCompare*dev = new NetCompare(scope, scope->local_symbol(), width);
dev->set_line(*this);
des->add_node(dev);
for (unsigned idx = 0 ; idx < lsig->pin_count() ; idx += 1)
connect(dev->pin_DataA(idx), lsig->pin(idx));
for (unsigned idx = 0 ; idx < rsig->pin_count() ; idx += 1)
connect(dev->pin_DataB(idx), rsig->pin(idx));
connect(dev->pin_DataA(), lsig->pin(0));
connect(dev->pin_DataB(), rsig->pin(0));
switch (op_) {
@@ -322,6 +234,14 @@ NetNet* NetEBComp::synthesize(Design*des)
return osig;
}
NetNet* NetEBPow::synthesize(Design*des)
{
cerr << get_line() << ": internal error: Do not yet know how to handle"
<< " power operator in this context." << endl;
des->errors += 1;
return 0;
}
NetNet* NetEBMult::synthesize(Design*des)
{
NetNet*lsig = left_->synthesize(des);
@@ -338,25 +258,24 @@ NetNet* NetEBMult::synthesize(Design*des)
NetMult*mult = new NetMult(scope, scope->local_symbol(),
expr_width(),
lsig->pin_count(),
rsig->pin_count());
lsig->vector_width(),
rsig->vector_width());
des->add_node(mult);
mult->set_signed( has_sign() );
mult->set_line(*this);
for (unsigned idx = 0 ; idx < lsig->pin_count() ; idx += 1)
connect(mult->pin_DataA(idx), lsig->pin(idx));
for (unsigned idx = 0 ; idx < rsig->pin_count() ; idx += 1)
connect(mult->pin_DataB(idx), rsig->pin(idx));
connect(mult->pin_DataA(), lsig->pin(0));
connect(mult->pin_DataB(), rsig->pin(0));
NetNet*osig = new NetNet(scope, scope->local_symbol(),
NetNet::IMPLICIT, expr_width());
osig->data_type(lsig->data_type());
osig->set_line(*this);
osig->data_type(expr_type());
osig->local_flag(true);
for (unsigned idx = 0 ; idx < osig->pin_count() ; idx += 1)
connect(mult->pin_Result(idx), osig->pin(idx));
connect(mult->pin_Result(), osig->pin(0));
return osig;
}
@@ -370,6 +289,8 @@ NetNet* NetEBDiv::synthesize(Design*des)
NetNet*osig = new NetNet(scope, scope->local_symbol(),
NetNet::IMPLICIT, expr_width());
osig->set_line(*this);
osig->data_type(lsig->data_type());
osig->local_flag(true);
switch (op()) {
@@ -377,32 +298,28 @@ NetNet* NetEBDiv::synthesize(Design*des)
case '/': {
NetDivide*div = new NetDivide(scope, scope->local_symbol(),
expr_width(),
lsig->pin_count(),
rsig->pin_count());
lsig->vector_width(),
rsig->vector_width());
div->set_line(*this);
des->add_node(div);
for (unsigned idx = 0 ; idx < lsig->pin_count() ; idx += 1)
connect(div->pin_DataA(idx), lsig->pin(idx));
for (unsigned idx = 0 ; idx < rsig->pin_count() ; idx += 1)
connect(div->pin_DataB(idx), rsig->pin(idx));
for (unsigned idx = 0 ; idx < osig->pin_count() ; idx += 1)
connect(div->pin_Result(idx), osig->pin(idx));
connect(div->pin_DataA(), lsig->pin(0));
connect(div->pin_DataB(), rsig->pin(0));
connect(div->pin_Result(),osig->pin(0));
break;
}
case '%': {
NetModulo*div = new NetModulo(scope, scope->local_symbol(),
expr_width(),
lsig->pin_count(),
rsig->pin_count());
lsig->vector_width(),
rsig->vector_width());
div->set_line(*this);
des->add_node(div);
for (unsigned idx = 0 ; idx < lsig->pin_count() ; idx += 1)
connect(div->pin_DataA(idx), lsig->pin(idx));
for (unsigned idx = 0 ; idx < rsig->pin_count() ; idx += 1)
connect(div->pin_DataB(idx), rsig->pin(idx));
for (unsigned idx = 0 ; idx < osig->pin_count() ; idx += 1)
connect(div->pin_Result(idx), osig->pin(idx));
connect(div->pin_DataA(), lsig->pin(0));
connect(div->pin_DataB(), rsig->pin(0));
connect(div->pin_Result(),osig->pin(0));
break;
}
@@ -436,6 +353,7 @@ NetNet* NetEBLogic::synthesize(Design*des)
NetNet*osig = new NetNet(scope, scope->local_symbol(),
NetNet::IMPLICIT, 1);
osig->data_type(expr_type());
osig->local_flag(true);
@@ -449,7 +367,7 @@ NetNet* NetEBLogic::synthesize(Design*des)
NetLogic*olog = new NetLogic(scope, oname,
lsig->pin_count()+rsig->pin_count()+1,
NetLogic::OR);
NetLogic::OR, 1);
connect(osig->pin(0), olog->pin(0));
@@ -471,7 +389,7 @@ NetNet* NetEBLogic::synthesize(Design*des)
NetLogic*olog;
perm_string oname = scope->local_symbol();
olog = new NetLogic(scope, oname, 3, NetLogic::AND);
olog = new NetLogic(scope, oname, 3, NetLogic::AND, 1);
connect(osig->pin(0), olog->pin(0));
des->add_node(olog);
@@ -528,32 +446,66 @@ NetNet* NetEBShift::synthesize(Design*des)
NetNet*osig = new NetNet(scope, scope->local_symbol(),
NetNet::IMPLICIT, expr_width());
osig->data_type(expr_type());
osig->local_flag(true);
NetConst*zcon = new NetConst(scope, scope->local_symbol(),
verinum::V0);
des->add_node(zcon);
NetNet*zsig = new NetNet(scope, scope->local_symbol(),
NetNet::WIRE, 1);
connect(zcon->pin(0), zsig->pin(0));
// ushift is the amount of pad created by the shift.
unsigned long ushift = shift>=0? shift : -shift;
if (ushift > osig->vector_width())
ushift = osig->vector_width();
if (shift > 0) {
unsigned long ushift = shift;
for (unsigned idx = 0; idx < osig->pin_count(); idx += 1)
if (idx < ushift) {
connect(osig->pin(idx), zsig->pin(0));
} else {
connect(osig->pin(idx), lsig->pin(idx-ushift));
}
} else {
unsigned long dshift = 0-shift;
for (unsigned idx = 0; idx < osig->pin_count() ; idx += 1)
if (idx+dshift < lsig->pin_count())
connect(osig->pin(idx), lsig->pin(idx+dshift));
else
connect(osig->pin(idx), zsig->pin(0));
// part_width is the bits of the vector that survive the shift.
unsigned long part_width = osig->vector_width() - ushift;
verinum znum (verinum::V0, ushift, true);
NetConst*zcon = new NetConst(scope, scope->local_symbol(),
znum);
des->add_node(zcon);
/* Detect the special case that the shift is the size of
the whole expression. Simply connect the pad to the
osig and escape. */
if (ushift >= osig->vector_width()) {
connect(zcon->pin(0), osig->pin(0));
return osig;
}
NetNet*zsig = new NetNet(scope, scope->local_symbol(),
NetNet::WIRE, znum.len());
zsig->data_type(osig->data_type());
zsig->local_flag(true);
zsig->set_line(*this);
connect(zcon->pin(0), zsig->pin(0));
/* Create a part select to reduce the width of the lsig
to the amount left by the shift. */
NetPartSelect*psel = new NetPartSelect(lsig, shift<0? ushift : 0,
part_width,
NetPartSelect::VP);
des->add_node(psel);
NetNet*psig = new NetNet(scope, scope->local_symbol(),
NetNet::IMPLICIT, part_width);
psig->data_type(expr_type());
psig->local_flag(true);
psig->set_line(*this);
connect(psig->pin(0), psel->pin(0));
NetConcat*ccat = new NetConcat(scope, scope->local_symbol(),
osig->vector_width(), 2);
ccat->set_line(*this);
des->add_node(ccat);
connect(ccat->pin(0), osig->pin(0));
if (shift > 0) {
// Left shift.
connect(ccat->pin(1), zsig->pin(0));
connect(ccat->pin(2), psig->pin(0));
} else {
// Right shift
connect(ccat->pin(1), psig->pin(0));
connect(ccat->pin(2), zsig->pin(0));
}
return osig;
}
@@ -564,24 +516,22 @@ NetNet* NetEBShift::synthesize(Design*des)
NetNet*osig = new NetNet(scope, scope->local_symbol(),
NetNet::IMPLICIT, expr_width());
osig->data_type(expr_type());
osig->local_flag(true);
assert(op() == 'l');
NetCLShift*dev = new NetCLShift(scope, scope->local_symbol(),
osig->pin_count(),
rsig->pin_count(),
osig->vector_width(),
rsig->vector_width(),
right_flag, signed_flag);
dev->set_line(*this);
des->add_node(dev);
for (unsigned idx = 0 ; idx < dev->width() ; idx += 1)
connect(dev->pin_Result(idx), osig->pin(idx));
connect(dev->pin_Result(), osig->pin(0));
assert(lsig->pin_count() >= dev->width());
for (unsigned idx = 0 ; idx < dev->width() ; idx += 1)
connect(dev->pin_Data(idx), lsig->pin(idx));
assert(lsig->vector_width() == dev->width());
connect(dev->pin_Data(), lsig->pin(0));
for (unsigned idx = 0 ; idx < dev->width_dist() ; idx += 1)
connect(dev->pin_Distance(idx), rsig->pin(idx));
connect(dev->pin_Distance(), rsig->pin(0));
return osig;
}
@@ -590,8 +540,15 @@ NetNet* NetEConcat::synthesize(Design*des)
{
/* First, synthesize the operands. */
NetNet**tmp = new NetNet*[parms_.count()];
for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1)
bool flag = true;
for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) {
tmp[idx] = parms_[idx]->synthesize(des);
if (tmp[idx] == 0)
flag = false;
}
if (flag == false)
return 0;
assert(tmp[0]);
NetScope*scope = tmp[0]->scope();
@@ -601,20 +558,16 @@ NetNet* NetEConcat::synthesize(Design*des)
perm_string path = scope->local_symbol();
NetNet*osig = new NetNet(scope, path, NetNet::IMPLICIT, expr_width());
osig->local_flag(true);
osig->data_type(tmp[0]->data_type());
/* Connect the output vector to the operands. */
unsigned obit = 0;
for (unsigned idx = parms_.count() ; idx > 0 ; idx -= 1) {
NetConcat*concat = new NetConcat(scope, scope->local_symbol(),
osig->vector_width(), parms_.count());
concat->set_line(*this);
des->add_node(concat);
connect(concat->pin(0), osig->pin(0));
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[idx-1]->local_flag() && tmp[idx-1]->get_refs() == 0)
delete tmp[idx-1];
for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) {
connect(concat->pin(idx+1), tmp[parms_.count()-idx-1]->pin(0));
}
delete[]tmp;
@@ -629,23 +582,39 @@ NetNet* NetEConst::synthesize(Design*des)
perm_string path = scope->local_symbol();
unsigned width=expr_width();
NetNet*osig = new NetNet(scope, path, NetNet::IMPLICIT, width);
NetNet*osig = new NetNet(scope, path, NetNet::IMPLICIT, width-1,0);
osig->local_flag(true);
osig->data_type(IVL_VT_LOGIC);
osig->set_signed(has_sign());
NetConst*con = new NetConst(scope, scope->local_symbol(), value());
for (unsigned idx = 0 ; idx < width; idx += 1)
connect(osig->pin(idx), con->pin(idx));
connect(osig->pin(0), con->pin(0));
des->add_node(con);
return osig;
}
/*
* Create a NetLiteral object to represent real valued constants.
*/
NetNet* NetECReal::synthesize(Design*des)
{
cerr << get_line() << ": error: Real constants are "
<< "not synthesizable." << endl;
des->errors += 1;
return 0;
NetScope*scope = des->find_root_scope();
assert(scope);
perm_string path = scope->local_symbol();
NetNet*osig = new NetNet(scope, path, NetNet::WIRE, 1);
osig->local_flag(true);
osig->data_type(IVL_VT_REAL);
osig->set_signed(has_sign());
osig->set_line(*this);
NetLiteral*con = new NetLiteral(scope, scope->local_symbol(), value_);
des->add_node(con);
con->set_line(*this);
connect(osig->pin(0), con->pin(0));
return osig;
}
/*
@@ -659,28 +628,28 @@ NetNet* NetEUBits::synthesize(Design*des)
NetScope*scope = isig->scope();
assert(scope);
unsigned width = isig->vector_width();
NetNet*osig = new NetNet(scope, scope->local_symbol(),
NetNet::IMPLICIT, isig->pin_count());
NetNet::IMPLICIT, width);
osig->data_type(expr_type());
osig->local_flag(true);
for (unsigned idx = 0 ; idx < osig->pin_count() ; idx += 1) {
perm_string oname = scope->local_symbol();
NetLogic*gate;
perm_string oname = scope->local_symbol();
NetLogic*gate;
switch (op()) {
case '~':
gate = new NetLogic(scope, oname, 2, NetLogic::NOT);
break;
default:
assert(0);
}
connect(osig->pin(idx), gate->pin(0));
connect(isig->pin(idx), gate->pin(1));
des->add_node(gate);
switch (op()) {
case '~':
gate = new NetLogic(scope, oname, 2, NetLogic::NOT, width);
break;
default:
assert(0);
}
connect(osig->pin(0), gate->pin(0));
connect(isig->pin(0), gate->pin(1));
des->add_node(gate);
return osig;
}
@@ -693,49 +662,40 @@ NetNet* NetEUReduce::synthesize(Design*des)
NetNet*osig = new NetNet(scope, scope->local_symbol(),
NetNet::IMPLICIT, 1);
osig->data_type(expr_type());
osig->local_flag(true);
perm_string oname = scope->local_symbol();
NetLogic*gate;
NetUReduce::TYPE rtype = NetUReduce::NONE;
switch (op()) {
case 'N':
case '!':
gate = new NetLogic(scope, oname, isig->pin_count()+1,
NetLogic::NOR);
rtype = NetUReduce::NOR;
break;
case '&':
gate = new NetLogic(scope, oname, isig->pin_count()+1,
NetLogic::AND);
rtype = NetUReduce::AND;
break;
case '|':
gate = new NetLogic(scope, oname, isig->pin_count()+1,
NetLogic::OR);
rtype = NetUReduce::OR;
break;
case '^':
gate = new NetLogic(scope, oname, isig->pin_count()+1,
NetLogic::XOR);
rtype = NetUReduce::XOR;
break;
case 'A':
gate = new NetLogic(scope, oname, isig->pin_count()+1,
NetLogic::NAND);
rtype = NetUReduce::XNOR;
break;
case 'X':
gate = new NetLogic(scope, oname, isig->pin_count()+1,
NetLogic::XNOR);
rtype = NetUReduce::XNOR;
break;
default:
cerr << get_line() << ": internal error: "
<< "Unable to synthesize " << *this << "." << endl;
return 0;
}
NetUReduce*gate = new NetUReduce(scope, scope->local_symbol(),
rtype, isig->vector_width());
des->add_node(gate);
connect(gate->pin(0), osig->pin(0));
for (unsigned idx = 0 ; idx < isig->pin_count() ; idx += 1)
@@ -746,37 +706,88 @@ NetNet* NetEUReduce::synthesize(Design*des)
NetNet* NetESelect::synthesize(Design *des)
{
// XXXX For now, only support pad form
assert(base_ == 0);
NetNet*sub = expr_->synthesize(des);
if (sub == 0)
return 0;
NetScope*scope = sub->scope();
NetNet*off = 0;
// This handles the case that the NetESelect exists to do an
// actual part/bit select. Generate a NetPartSelect object to
// do the work, and replace "sub" with the selected output.
if (base_ != 0) {
off = base_->synthesize(des);
NetPartSelect*sel = new NetPartSelect(sub, off, expr_width());
sel->set_line(*this);
des->add_node(sel);
NetNet*tmp = new NetNet(scope, scope->local_symbol(),
NetNet::IMPLICIT, expr_width());
tmp->data_type(sub->data_type());
tmp->local_flag(true);
tmp->set_line(*this);
sub = tmp;
connect(sub->pin(0), sel->pin(0));
}
// Now look for the case that the NetESelect actually exists
// to change the width of the expression. (i.e. to do
// padding.) If this was for an actual part select that at
// this point the output vector_width is exactly right, and we
// are done.
if (sub->vector_width() == expr_width())
return sub;
// The vector_width is not exactly right, so the source is
// probably asking for padding. Create nodes to do sign
// extension or 0 extension, depending on the has_sign() mode
// of the expression.
NetNet*net = new NetNet(scope, scope->local_symbol(),
NetNet::IMPLICIT, expr_width());
net->data_type(expr_type());
net->local_flag(true);
net->set_line(*this);
if (has_sign()) {
unsigned idx;
NetSignExtend*pad = new NetSignExtend(scope,
scope->local_symbol(),
expr_width());
pad->set_line(*this);
des->add_node(pad);
for (idx = 0 ; idx < sub->pin_count() ; idx += 1)
connect(sub->pin(idx), net->pin(idx));
for ( ; idx < net->pin_count(); idx += 1)
connect(sub->pin(sub->pin_count()-1), net->pin(idx));
connect(pad->pin(1), sub->pin(0));
connect(pad->pin(0), net->pin(0));
} else {
unsigned idx;
for (idx = 0 ; idx < sub->pin_count() ; idx += 1)
connect(sub->pin(idx), net->pin(idx));
NetConst*tmp = new NetConst(scope, scope->local_symbol(),
verinum::V0);
NetConcat*cat = new NetConcat(scope, scope->local_symbol(),
expr_width(), 2);
cat->set_line(*this);
des->add_node(cat);
for ( ; idx < net->pin_count() ; idx += 1)
connect(net->pin(idx), tmp->pin(0));
assert(expr_width() > sub->vector_width());
unsigned pad_width = expr_width() - sub->vector_width();
verinum pad((uint64_t)0, pad_width);
NetConst*con = new NetConst(scope, scope->local_symbol(),
pad);
con->set_line(*this);
des->add_node(con);
des->add_node(tmp);
NetNet*tmp = new NetNet(scope, scope->local_symbol(),
NetNet::IMPLICIT, pad_width);
tmp->data_type(expr_type());
tmp->local_flag(true);
tmp->set_line(*this);
connect(tmp->pin(0), con->pin(0));
connect(cat->pin(0), net->pin(0));
connect(cat->pin(1), sub->pin(0));
connect(cat->pin(2), con->pin(0));
}
return net;
@@ -796,28 +807,28 @@ NetNet* NetETernary::synthesize(Design *des)
perm_string path = csig->scope()->local_symbol();
assert(csig->pin_count() == 1);
assert(csig->vector_width() == 1);
unsigned width=expr_width();
NetNet*osig = new NetNet(csig->scope(), path, NetNet::IMPLICIT, width);
osig->data_type(expr_type());
osig->local_flag(true);
/* Make sure both value operands are the right width. */
tsig = pad_to_width(des, tsig, width);
fsig = pad_to_width(des, fsig, width);
tsig = crop_to_width(des, pad_to_width(des, tsig, width), width);
fsig = crop_to_width(des, pad_to_width(des, fsig, width), width);
assert(width <= tsig->pin_count());
assert(width <= fsig->pin_count());
assert(width == tsig->vector_width());
assert(width == fsig->vector_width());
perm_string oname = csig->scope()->local_symbol();
NetMux *mux = new NetMux(csig->scope(), oname, width, 2, 1);
for (unsigned idx = 0 ; idx < width; idx += 1) {
connect(tsig->pin(idx), mux->pin_Data(idx, 1));
connect(fsig->pin(idx), mux->pin_Data(idx, 0));
connect(osig->pin(idx), mux->pin_Result(idx));
}
NetMux *mux = new NetMux(csig->scope(), oname, width,
2, csig->vector_width());
connect(tsig->pin(0), mux->pin_Data(1));
connect(fsig->pin(0), mux->pin_Data(0));
connect(osig->pin(0), mux->pin_Result());
connect(csig->pin(0), mux->pin_Sel());
des->add_node(mux);
connect(csig->pin(0), mux->pin_Sel(0));
return osig;
}
@@ -854,27 +865,102 @@ NetNet* NetETernary::synthesize(Design *des)
*/
NetNet* NetESignal::synthesize(Design*des)
{
if ((lsi_ == 0) && (msi_ == (net_->pin_count() - 1)))
return net_;
assert(msi_ >= lsi_);
unsigned wid = msi_ - lsi_ + 1;
NetScope*scope = net_->scope();
assert(scope);
perm_string name = scope->local_symbol();
NetNet*tmp = new NetNet(scope, name, 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;
return net_;
}
/*
* $Log: expr_synth.cc,v $
* Revision 1.87 2007/06/02 03:42:12 steve
* Properly evaluate scope path expressions.
*
* Revision 1.86 2007/04/15 01:37:29 steve
* Allow bit/part select of vectors in continuous assignments.
*
* Revision 1.85 2007/04/12 05:21:54 steve
* fix handling of unary reduction logic in certain nets.
*
* Revision 1.84 2007/04/04 02:31:57 steve
* Remove useless assert
*
* Revision 1.83 2007/02/05 01:42:31 steve
* Set some missing local flags.
*
* Revision 1.82 2007/01/20 02:10:45 steve
* Get argument widths right for shift results.
*
* Revision 1.81 2007/01/16 05:44:15 steve
* Major rework of array handling. Memories are replaced with the
* more general concept of arrays. The NetMemory and NetEMemory
* classes are removed from the ivl core program, and the IVL_LPM_RAM
* lpm type is removed from the ivl_target API.
*
* Revision 1.80 2006/08/08 05:11:37 steve
* Handle 64bit delay constants.
*
* Revision 1.79 2006/07/31 03:50:17 steve
* Add support for power in constant expressions.
*
* Revision 1.78 2006/07/08 21:48:46 steve
* Handle real valued literals in net contexts.
*
* Revision 1.77 2006/05/01 20:47:59 steve
* More explicit datatype setup.
*
* Revision 1.76 2006/05/01 05:40:21 steve
* fix net type of multiply output.
*
* Revision 1.75 2006/04/30 05:17:48 steve
* Get the data type of part select results right.
*
* Revision 1.74 2006/01/03 05:15:33 steve
* Fix the return type of a synthesized divide.
*
* Revision 1.73 2005/09/15 23:04:09 steve
* Make sure div, mod and mult nodes have line number info.
*
* Revision 1.72 2005/08/31 05:07:31 steve
* Handle memory references is continuous assignments.
*
* Revision 1.71 2005/06/13 23:22:14 steve
* use NetPartSelect to shrink part from high bits.
*
* Revision 1.70 2005/06/13 22:26:03 steve
* Make synthesized padding vector-aware.
*
* Revision 1.69 2005/05/15 04:47:00 steve
* synthesis of Logic and shifts using vector gates.
*
* Revision 1.68 2005/05/06 00:25:13 steve
* Handle synthesis of concatenation expressions.
*
* Revision 1.67 2005/04/25 01:30:31 steve
* synthesis of add and unary get vector widths right.
*
* Revision 1.66 2005/04/24 23:44:02 steve
* Update DFF support to new data flow.
*
* Revision 1.65 2005/03/12 06:43:35 steve
* Update support for LPM_MOD.
*
* Revision 1.64 2005/02/19 02:43:38 steve
* Support shifts and divide.
*
* Revision 1.63 2005/02/12 06:25:40 steve
* Restructure NetMux devices to pass vectors.
* Generate NetMux devices from ternary expressions,
* Reduce NetMux devices to bufif when appropriate.
*
* Revision 1.62 2005/01/28 05:39:33 steve
* Simplified NetMult and IVL_LPM_MULT.
*
* Revision 1.61 2005/01/16 04:20:32 steve
* Implement LPM_COMPARE nodes as two-input vector functors.
*
* Revision 1.60 2004/12/11 02:31:26 steve
* Rework of internals to carry vectors through nexus instead
* of single bits. Make the ivl, tgt-vvp and vvp initial changes
* down this path.
*
* Revision 1.59 2004/06/30 02:16:26 steve
* Implement signed divide and signed right shift in nets.
*
+84
View File
@@ -0,0 +1,84 @@
Icarus Verilog Extensions
Icarus Verilog supports certain extensions to the baseline IEEE1364
standard. Some of these are picked from extended variants of the
language, such as SystemVerilog, and some are expressions of internal
behavior of Icarus Verilog, made available as a tool debugging aid.
* Builtin System Functions
** Extended Verilog Data Types
This feature is turned off if the generation flag "-g" is set to other
then the default "2x". For example, "iverilog -g2x" enables extended
data types, and "iverilog -g2" disables them.
Icarus Verilog adds support for extended data types. This extended
type syntax is based on a proposal by Cadence Design Systems,
originally as an update to the IEEE1364. That original proposal has
apparently been absorbed by the IEEE1800 SystemVerilog
standard. Icarus Verilog currently only takes the new primitive types
from the proposal.
Extended data types separates the concept of net/variable from the
data type. Both nets and variables can declared with any data
type. The primitive types available are:
logic - The familiar 0, 1, x and z, optionally with strength.
bool - Limited to only 0 and 1
real - 64bit real values
Nets with logic type may have multiple drivers with strength, and the
value is resolved the usual way. Only logic values may be driven to
logic nets, so bool values driven onto logic nets are implicitly
converted to logic.
Nets with any other type may not have multiple drivers. The compiler
should detect the multiple drivers and report an error.
- Declarations
The declaration of a net is extended to include the type of the wire,
with the syntax:
wire <type> <wire-assignment-list>... ;
The <type>, if omitted, is taken to be logic. The "wire" can be any of
the net keywords. Wires can be logic, bool, real, or vectors of logic
or bool. Some valid examples:
wire real foo = 1.0;
tri logic bus[31:0];
wire bool addr[23:0];
... and so on.
The declarations of variables is similar. The "reg" keyword is used to
specify that this is a variable. Variables can have the same data
types as nets.
- Ports
Module and task ports in standard verilog are restricted to logic
types. This extension removes that restriction, allowing any type to
pass through the port consistent with the continuous assignment
connectivity that is implied by the type.
- Expressions
Expressions in the face of real values is covered by the baseline
Verilog standard.
The bool type supports the same operators as the logic type, with the
obvious differences imposed by the limited domain.
Comparison operators (not case compare) return logic if either of
their operands is logic. If both are bool or real (including mix of
bool and real) then the result is bool. This is because comparison of
bools and reals always return exactly true or false.
Case comparison returns bool. This differs from baseline Verilog,
which strictly speaking returns a logic, but only 0 or 1 values.
All the arithmetic operators return bool if both of their operands are
bool or real. Otherwise, they return logic.
+38 -2
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1999-2002 Stephen Williams (steve@icarus.com)
* Copyright (c) 1999-2005 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: functor.cc,v 1.32 2004/10/04 01:10:53 steve Exp $"
#ident "$Id: functor.cc,v 1.35 2005/07/07 16:22:49 steve Exp $"
#endif
# include "config.h"
@@ -59,6 +59,10 @@ void functor_t::lpm_divide(class Design*, class NetDivide*)
{
}
void functor_t::lpm_literal(class Design*, class NetLiteral*)
{
}
void functor_t::lpm_modulo(class Design*, class NetModulo*)
{
}
@@ -79,6 +83,14 @@ void functor_t::lpm_mux(class Design*, class NetMux*)
{
}
void functor_t::sign_extend(class Design*, class NetSignExtend*)
{
}
void functor_t::lpm_ureduce(class Design*, class NetUReduce*)
{
}
void NetScope::run_functor(Design*des, functor_t*fun)
{
@@ -186,6 +198,11 @@ void NetFF::functor_node(Design*des, functor_t*fun)
fun->lpm_ff(des, this);
}
void NetLiteral::functor_node(Design*des, functor_t*fun)
{
fun->lpm_literal(des, this);
}
void NetLogic::functor_node(Design*des, functor_t*fun)
{
fun->lpm_logic(des, this);
@@ -206,6 +223,16 @@ void NetMux::functor_node(Design*des, functor_t*fun)
fun->lpm_mux(des, this);
}
void NetSignExtend::functor_node(Design*des, functor_t*fun)
{
fun->sign_extend(des, this);
}
void NetUReduce::functor_node(Design*des, functor_t*fun)
{
fun->lpm_ureduce(des, this);
}
proc_match_t::~proc_match_t()
{
}
@@ -267,6 +294,15 @@ int proc_match_t::event_wait(NetEvWait*)
/*
* $Log: functor.cc,v $
* Revision 1.35 2005/07/07 16:22:49 steve
* Generalize signals to carry types.
*
* Revision 1.34 2005/05/24 01:44:27 steve
* Do sign extension of structuran nets.
*
* Revision 1.33 2005/02/03 04:56:20 steve
* laborate reduction gates into LPM_RED_ nodes.
*
* Revision 1.32 2004/10/04 01:10:53 steve
* Clean up spurious trailing white space.
*
+19 -2
View File
@@ -1,7 +1,7 @@
#ifndef __functor_H
#define __functor_H
/*
* Copyright (c) 1999-2000 Stephen Williams (steve@icarus.com)
* Copyright (c) 1999-2005 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
@@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: functor.h,v 1.20 2002/08/12 01:34:59 steve Exp $"
#ident "$Id: functor.h,v 1.23 2005/07/07 16:22:49 steve Exp $"
#endif
/*
@@ -63,6 +63,9 @@ struct functor_t {
/* This method is called for each structural constant. */
virtual void lpm_divide(class Design*des, class NetDivide*);
/* Constant literals. */
virtual void lpm_literal(class Design*des, class NetLiteral*);
/* This method is called for each structural constant. */
virtual void lpm_modulo(class Design*des, class NetModulo*);
@@ -77,6 +80,11 @@ struct functor_t {
/* This method is called for each MUX. */
virtual void lpm_mux(class Design*des, class NetMux*);
/* This method is called for each unary reduction gate. */
virtual void lpm_ureduce(class Design*des, class NetUReduce*);
virtual void sign_extend(class Design*des, class NetSignExtend*);
};
struct proc_match_t {
@@ -92,6 +100,15 @@ struct proc_match_t {
/*
* $Log: functor.h,v $
* Revision 1.23 2005/07/07 16:22:49 steve
* Generalize signals to carry types.
*
* Revision 1.22 2005/05/24 01:44:27 steve
* Do sign extension of structuran nets.
*
* Revision 1.21 2005/02/03 04:56:20 steve
* laborate reduction gates into LPM_RED_ nodes.
*
* Revision 1.20 2002/08/12 01:34:59 steve
* conditional ident string using autoconfig.
*
+11 -2
View File
@@ -1,4 +1,7 @@
NOTE: THE CONTENTS OF THIS FILE ARE BEING MOVED TO THE DOCUMENTATION
WIKI AT http://iverilog.wikia.com. PLEASE ADD NEW ENTRIES THERE.
Icarus Verilog vs. IEEE1364
Copyright 2000 Stephen Williams
@@ -249,7 +252,7 @@ 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
is accepted. Further testing shows that any expression other than a
simple unsized constant is accepted there, even if all the operands of
all the operators that make up the expression are unsized integers.
@@ -498,8 +501,14 @@ of 4-value behavior in the dead zone, and appears more user friendly
when viewed by reasonable viewers.
$Id: ieee1364-notes.txt,v 1.17 2003/07/15 03:49:22 steve Exp $
$Id: ieee1364-notes.txt,v 1.19 2007/04/18 02:36:13 steve Exp $
$Log: ieee1364-notes.txt,v $
Revision 1.19 2007/04/18 02:36:13 steve
Put to iverilog wiki for further notes.
Revision 1.18 2007/03/22 16:08:16 steve
Spelling fixes from Larry
Revision 1.17 2003/07/15 03:49:22 steve
Spelling fixes.
+12 -4
View File
@@ -17,12 +17,12 @@
# 59 Temple Place - Suite 330
# Boston, MA 02111-1307, USA
#
#ident "$Id: iverilog-vpi.sh,v 1.14 2004/05/20 00:40:34 steve Exp $"
#ident "$Id: iverilog-vpi.sh,v 1.17 2007/02/06 05:07:31 steve Exp $"
# These are the variables used for compiling files
CC=gcc
CXX=gcc
CFLAGS="@PIC@ -O -I@INCLUDEDIR@"
CC=@IVCC@
CXX=@IVCXX@
CFLAGS="@PIC@ @IVCFLAGS@ -I@INCLUDEDIR@"
# These are used for linking...
LD=gcc
@@ -63,11 +63,19 @@ do
;;
*.cc) CXSRC="$CXSRC $parm"
LD=$CXX
if [ x$OUT = x ]; then
OUT=`basename $parm .cc`
fi
;;
*.cpp) CXSRC="$CXSRC $parm"
LD=$CXX
if [ x$OUT = x ]; then
OUT=`basename $parm .cpp`
fi
;;
*.o) OBJ="$OBJ $parm"
if [ x$OUT = x ]; then
OUT=`basename $parm .o`
+34 -35
View File
@@ -9,9 +9,10 @@ ivl_design_roots
ivl_design_time_precision
ivl_const_bits
ivl_const_pin
ivl_const_pins
ivl_const_real
ivl_const_signed
ivl_const_type
ivl_const_width
ivl_event_any
ivl_event_basename
@@ -21,14 +22,13 @@ ivl_event_neg
ivl_event_nneg
ivl_event_npos
ivl_event_pos
ivl_event_scope
ivl_expr_type
ivl_expr_bits
ivl_expr_def
ivl_expr_dvalue
ivl_expr_event
ivl_expr_lsi
ivl_expr_memory
ivl_expr_name
ivl_expr_opcode
ivl_expr_oper1
@@ -44,33 +44,34 @@ ivl_expr_signed
ivl_expr_string
ivl_expr_uvalue
ivl_expr_value
ivl_expr_variable
ivl_expr_width
ivl_logic_attr
ivl_logic_attr_cnt
ivl_logic_attr_val
ivl_logic_delay
ivl_logic_name
ivl_logic_basename
ivl_logic_scope
ivl_logic_type
ivl_logic_delay
ivl_logic_drive0
ivl_logic_drive1
ivl_logic_name
ivl_logic_pin
ivl_logic_pins
ivl_logic_scope
ivl_logic_type
ivl_logic_udp
ivl_logic_width
ivl_lpm_array
ivl_lpm_aset_value
ivl_lpm_async_clr
ivl_lpm_async_set
ivl_lpm_base
ivl_lpm_basename
ivl_lpm_clk
ivl_lpm_data
ivl_lpm_datab
ivl_lpm_data2
ivl_lpm_data2_width
ivl_lpm_define
ivl_lpm_enable
ivl_lpm_memory
ivl_lpm_name
ivl_lpm_q
ivl_lpm_scope
@@ -79,25 +80,17 @@ ivl_lpm_selects
ivl_lpm_signed
ivl_lpm_size
ivl_lpm_sset_value
ivl_lpm_string
ivl_lpm_sync_clr
ivl_lpm_sync_set
ivl_lpm_type
ivl_lpm_width
ivl_lval_idx
ivl_lval_mem
ivl_lval_mux
ivl_lval_part_off
ivl_lval_pin
ivl_lval_pins
ivl_lval_sig
ivl_lval_var
ivl_memory_basename
ivl_memory_root
ivl_memory_scope
ivl_memory_size
ivl_memory_width
ivl_lval_width
ivl_nexus_get_private
ivl_nexus_name
@@ -116,6 +109,12 @@ ivl_nexus_ptr_sig
ivl_parameter_basename
ivl_parameter_expr
ivl_path_condit
ivl_path_delay
ivl_path_source
ivl_path_source_negedge
ivl_path_source_posedge
ivl_scope_attr_cnt
ivl_scope_attr_val
ivl_scope_basename
@@ -127,8 +126,6 @@ ivl_scope_logs
ivl_scope_log
ivl_scope_lpms
ivl_scope_lpm
ivl_scope_mem
ivl_scope_mems
ivl_scope_name
ivl_scope_param
ivl_scope_params
@@ -140,23 +137,30 @@ ivl_scope_sig
ivl_scope_time_units
ivl_scope_type
ivl_scope_tname
ivl_scope_var
ivl_scope_vars
ivl_signal_array_base
ivl_signal_array_count
ivl_signal_attr
ivl_signal_attr_cnt
ivl_signal_attr_val
ivl_signal_basename
ivl_signal_data_type
ivl_signal_dimensions
ivl_signal_integer
ivl_signal_local
ivl_signal_lsb
ivl_signal_msb
ivl_signal_pin
ivl_signal_pins
ivl_signal_name
ivl_signal_nex
ivl_signal_npath
ivl_signal_path
ivl_signal_port
ivl_signal_signed
ivl_signal_type
ivl_signal_name
ivl_signal_basename
ivl_signal_width
ivl_path_delay
ivl_path_source
ivl_process_attr_cnt
ivl_process_attr_val
@@ -184,8 +188,6 @@ ivl_stmt_lvals
ivl_stmt_lwidth
ivl_stmt_name
ivl_stmt_nevent
ivl_stmt_nexus
ivl_stmt_nexus_count
ivl_stmt_parm
ivl_stmt_parm_count
ivl_stmt_rval
@@ -197,6 +199,3 @@ ivl_udp_nin
ivl_udp_row
ivl_udp_rows
ivl_udp_sequ
ivl_variable_name
ivl_variable_type
+43
View File
@@ -0,0 +1,43 @@
/*
* Copyright (c) 2007 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: ivl_assert.h,v 1.1 2007/01/31 04:21:10 steve Exp $"
#endif
#ifndef __ivl_assert_h
#define __ivl_assert_h
# include <assert.h>
#define ivl_assert(tok, expression) \
do { \
if (! (expression)) \
__ivl_assert(#expression, tok, __FILE__, __LINE__); \
} while(0)
#define __ivl_assert(expression, tok, file, line) \
do { \
cerr << (tok).get_line() << ": assert: " \
<< file << ":" << line \
<< ": failed assertion " << (expression) << endl; \
abort(); \
} while(0)
#endif
+745 -191
View File
File diff suppressed because it is too large Load Diff
+9 -9
View File
@@ -18,7 +18,7 @@
# 59 Temple Place - Suite 330
# Boston, MA 02111-1307, USA
#
#ident "$Id: Makefile.in,v 1.17 2004/10/04 01:10:56 steve Exp $"
#ident "$Id: Makefile.in,v 1.18 2006/10/30 22:45:37 steve Exp $"
#
#
SHELL = /bin/sh
@@ -44,18 +44,18 @@ CPPFLAGS = @ident_support@ -I. -I.. -I$(srcdir)/.. -I$(srcdir) @CPPFLAGS@ @DEFS@
CFLAGS = -Wall @CFLAGS@
LDFLAGS = @LDFLAGS@
all: ivlpp
all: ivlpp@EXEEXT@
clean:
rm -f *.o lexor.c parse.c parse.h parse.output ivlpp
rm -f *.o lexor.c parse.c parse.h parse.output ivlpp@EXEEXT@
distclean: clean
rm -f Makefile
O = main.o lexor.o parse.o
ivlpp: $O
$(CC) $(LDFLAGS) $O -o ivlpp @EXTRALIBS@
ivlpp@EXEEXT@: $O
$(CC) $(LDFLAGS) $O -o ivlpp@EXEEXT@ @EXTRALIBS@
lexor.c: lexor.lex
flex -s -olexor.c $(srcdir)/lexor.lex
@@ -63,16 +63,16 @@ lexor.c: lexor.lex
parse.h parse.c: parse.y
bison --verbose -t -d -o parse.c $(srcdir)/parse.y
install: all installdirs $(libdir)/ivl/ivlpp
install: all installdirs $(libdir)/ivl/ivlpp@EXEEXT@
$(libdir)/ivl/ivlpp: ivlpp
$(INSTALL_PROGRAM) ./ivlpp $(libdir)/ivl/ivlpp
$(libdir)/ivl/ivlpp@EXEEXT@: ivlpp@EXEEXT@
$(INSTALL_PROGRAM) ./ivlpp@EXEEXT@ $(libdir)/ivl/ivlpp@EXEEXT@
installdirs: ../mkinstalldirs
$(srcdir)/../mkinstalldirs $(libdir)/ivl
uninstall:
rm -f $(libdir)/ivl/ivlpp
rm -f $(libdir)/ivl/ivlpp@EXEEXT@
lexor.o: lexor.c parse.h globals.h
main.o: main.c globals.h
+1 -1
View File
@@ -37,7 +37,7 @@ valid options include:
Predefine the symbol ``name'' to have the specified
value. If the value is not specified, then ``1'' is
used. This is mostly of use for controlling conditional
compilaiton.
compilation.
This option does *not* override existing `define
directives in the source file.
+74 -6
View File
@@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: lexor.lex,v 1.46 2004/09/10 00:15:45 steve Exp $"
#ident "$Id: lexor.lex,v 1.48 2007/05/30 23:21:20 steve Exp $"
#endif
# include "config.h"
@@ -70,7 +70,14 @@ struct include_stack_t {
static void emit_pathline(struct include_stack_t *isp);
/*
* The file_queue is a singly-linked list of the files that were
* listed on the command line/file list.
*/
static struct include_stack_t*file_queue = 0;
/*
* The istack is the inclusion stack.
*/
static struct include_stack_t*istack = 0;
static struct include_stack_t*standby = 0;
@@ -111,11 +118,11 @@ static void ifdef_leave(void)
if (strcmp(istack->path,cur->path) != 0) {
fprintf(stderr, "%s:%u: warning: "
"This `endif matches an ifdef in another file.\n",
istack->path, istack->lineno);
istack->path, istack->lineno+1);
fprintf(stderr, "%s:%u: : "
"This is the odd matched `ifdef.\n",
cur->path, cur->lineno);
cur->path, cur->lineno+1);
}
free(cur->path);
@@ -309,7 +316,24 @@ W [ \t\b\f]+
yy_push_state(IFDEF_SUPR);
}
<IFDEF_TRUE>`else { BEGIN(IFDEF_FALSE); }
<IFDEF_TRUE>`elsif{W}[a-zA-Z_][a-zA-Z0-9_$]* {
BEGIN(IFDEF_SUPR);
}
<IFDEF_FALSE>`elsif{W}[a-zA-Z_][a-zA-Z0-9_$]* {
char*name = strchr(yytext, '`');
assert(name);
name += 6;
name += strspn(name, " \t\b\f");
if (is_defined(name)) {
BEGIN(IFDEF_TRUE);
} else {
BEGIN(IFDEF_FALSE);
}
}
<IFDEF_SUPR>`elsif{W}[a-zA-Z_][a-zA-Z0-9_$]* { }
<IFDEF_TRUE>`else { BEGIN(IFDEF_SUPR); }
<IFDEF_FALSE>`else { BEGIN(IFDEF_TRUE); }
<IFDEF_SUPR>`else { }
@@ -322,6 +346,42 @@ W [ \t\b\f]+
<IFDEF_FALSE,IFDEF_TRUE,IFDEF_SUPR>`endif { ifdef_leave(); yy_pop_state(); }
`ifdef {
fprintf(stderr, "%s:%u: `ifdef without a macro name - ignored.\n",
istack->path, istack->lineno+1);
error_count += 1;
}
`ifndef {
fprintf(stderr, "%s:%u: `ifndef without a macro name - ignored.\n",
istack->path, istack->lineno+1);
error_count += 1;
}
`elsif {
fprintf(stderr, "%s:%u: `elsif without a macro name - ignored.\n",
istack->path, istack->lineno+1);
error_count += 1;
}
`elsif{W}[a-zA-Z_][a-zA-Z0-9_$]* {
fprintf(stderr, "%s:%u: `elsif without a matching `ifdef - ignored.\n",
istack->path, istack->lineno+1);
error_count += 1;
}
`else {
fprintf(stderr, "%s:%u: `else without a matching `ifdef - ignored.\n",
istack->path, istack->lineno+1);
error_count += 1;
}
`endif {
fprintf(stderr, "%s:%u: `endif without a matching `ifdef - ignored.\n",
istack->path, istack->lineno+1);
error_count += 1;
}
/* This pattern notices macros and arranges for them to be replaced. */
`[a-zA-Z][a-zA-Z0-9_$]* { def_match(); }
@@ -759,7 +819,7 @@ static void lexor_done()
ifdef_stack = cur->next;
fprintf(stderr, "%s:%u: error: This `ifdef lacks an `endif.\n",
cur->path, cur->lineno);
cur->path, cur->lineno+1);
free(cur->path);
free(cur);
@@ -777,11 +837,14 @@ static int yywrap()
int line_mask_flag = 0;
struct include_stack_t*isp = istack;
istack = isp->next;
FILE *delayed_close = (FILE *) 0;
/* Delete the current input buffers, and free the cell. */
yy_delete_buffer(YY_CURRENT_BUFFER);
if (isp->file) {
fclose(isp->file);
/* Delay the close of this file, because the yyrestart
below seems to have some memory of this file. */
delayed_close = isp->file;
free(isp->path);
} else {
/* If I am printing line directives and I just finished
@@ -825,6 +888,7 @@ static int yywrap()
}
yyrestart(istack->file);
if (delayed_close) fclose(delayed_close);
return 0;
}
@@ -833,6 +897,7 @@ static int yywrap()
top. If I need to print a line directive, do so. */
yy_switch_to_buffer(istack->yybs);
if (delayed_close) fclose(delayed_close);
if (line_direct_flag && istack->path && !line_mask_flag)
fprintf(yyout, "\n`line %u \"%s\" 2\n",
@@ -854,6 +919,7 @@ void reset_lexor(FILE*out, char*paths[])
isp->path = strdup(paths[0]);
isp->file = fopen(paths[0], "r");
isp->str = 0;
isp->lineno = 0;
if (isp->file == 0) {
perror(paths[0]);
exit(1);
@@ -876,8 +942,10 @@ void reset_lexor(FILE*out, char*paths[])
for (idx = 1 ; paths[idx] ; idx += 1) {
isp = malloc(sizeof(struct include_stack_t));
isp->path = strdup(paths[idx]);
isp->file = 0;
isp->str = 0;
isp->next = 0;
isp->lineno = 0;
if (tail)
tail->next = isp;
else
+88 -34
View File
@@ -17,7 +17,7 @@ const char COPYRIGHT[] =
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: main.c,v 1.20 2004/09/10 00:15:45 steve Exp $"
#ident "$Id: main.c,v 1.23 2006/10/02 18:16:18 steve Exp $"
#endif
# include "config.h"
@@ -58,6 +58,8 @@ extern int getopt(int argc, char*argv[], const char*fmt);
extern int optind;
extern const char*optarg;
#endif
/* Path to the dependency file, if there is one. */
char *dep_path = NULL;
/*
* Keep in source_list an array of pointers to file names. The array
@@ -89,6 +91,76 @@ int line_direct_flag = 0;
unsigned error_count = 0;
FILE *depend_file = NULL;
static int flist_read_flags(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) {
/* Skip leading white space. */
char*cp = line_buf + strspn(line_buf, " \t\r\b\f");
/* Remove trailing white space. */
char*tail = cp + strlen(cp);
while (tail > cp) {
if (! isspace(tail[-1]))
break;
tail -= 1;
tail[0] = 0;
}
/* Skip empty lines */
if (*cp == 0)
continue;
/* Skip comment lines */
if (cp[0] == '#')
continue;
/* The arg points to the argument to the keyword. */
char*arg = strchr(cp, ':');
if (arg) *arg++ = 0;
if (strcmp(cp,"D") == 0) {
char*val = strchr(arg, '=');
if (val)
*val++ = 0;
else
val = "1";
define_macro(arg, val, 0);
} else if (strcmp(cp,"I") == 0) {
include_dir = realloc(include_dir,
(include_cnt+1)*sizeof(char*));
include_dir[include_cnt] = strdup(arg);
include_cnt += 1;
} else if (strcmp(cp,"keyword") == 0) {
char*buf = malloc(strlen(arg) + 2);
buf[0] = '`';
strcpy(buf+1, optarg);
define_macro(optarg, buf, 1);
free(buf);
} else if (strcmp(cp,"M") == 0) {
if (dep_path) {
fprintf(stderr, "duplicate -M flag.\n");
} else {
dep_path = strdup(arg);
}
} else {
fprintf(stderr, "%s: Invalid keyword %s\n", path, cp);
}
}
fclose(fd);
return 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
@@ -127,7 +199,6 @@ int main(int argc, char*argv[])
const char*flist_path = 0;
unsigned flag_errors = 0;
char*out_path = 0;
char *dep_path = NULL;
FILE*out;
/* Define preprocessor keywords that I plan to just pass. */
@@ -153,20 +224,11 @@ int main(int argc, char*argv[])
include_dir[0] = strdup(".");
include_cnt = 1;
while ((opt = getopt(argc, argv, "D:f:I:K:LM:o:v")) != EOF) switch (opt) {
while ((opt=getopt(argc, argv, "F:f:K:Lo:v")) != EOF) switch (opt) {
case 'D': {
char*tmp = strdup(optarg);
char*val = strchr(tmp, '=');
if (val)
*val++ = 0;
else
val = "1";
define_macro(tmp, val, 0);
free(tmp);
break;
}
case 'F':
flist_read_flags(optarg);
break;
case 'f':
if (flist_path) {
@@ -176,13 +238,6 @@ int main(int argc, char*argv[])
flist_path = optarg;
break;
case 'I':
include_dir = realloc(include_dir,
(include_cnt+1)*sizeof(char*));
include_dir[include_cnt] = strdup(optarg);
include_cnt += 1;
break;
case 'K': {
char*buf = malloc(strlen(optarg) + 2);
buf[0] = '`';
@@ -196,14 +251,6 @@ int main(int argc, char*argv[])
line_direct_flag = 1;
break;
case 'M':
if (dep_path) {
fprintf(stderr, "duplicate -M flag.\n");
} else {
dep_path = optarg;
}
break;
case 'o':
if (out_path) {
fprintf(stderr, "duplicate -o flag.\n");
@@ -225,13 +272,11 @@ int main(int argc, char*argv[])
}
if (flag_errors) {
fprintf(stderr, "\nUsage: %s [-v][-L][-I<dir>][-D<def>] <file>...\n"
" -D<def> - Predefine a value.\n"
fprintf(stderr, "\nUsage: %s [-v][-L][-F<fil>][-f<fil>] <file>...\n"
" -F<fil> - Get defines and includes from file\n"
" -f<fil> - Read the sources listed in the file\n"
" -I<dir> - Add an include file search directory\n"
" -K<def> - Define a keyword macro that I just pass\n"
" -L - Emit line number directives\n"
" -M<fil> - Write dependencies to <fil>\n"
" -o<fil> - Send the output to <fil>\n"
" -v - Print version information\n",
argv[0]);
@@ -290,6 +335,15 @@ int main(int argc, char*argv[])
/*
* $Log: main.c,v $
* Revision 1.23 2006/10/02 18:16:18 steve
* Save dep_path because arg space is overrun.
*
* Revision 1.22 2006/07/26 00:11:40 steve
* Pass depfiles through temp defines file.
*
* Revision 1.21 2006/07/26 00:02:48 steve
* Pass defines and includes through temp file.
*
* Revision 1.20 2004/09/10 00:15:45 steve
* Remove bad casts.
*
+56 -11
View File
@@ -1,4 +1,6 @@
%option never-interactive
%{
/*
* Copyright (c) 1998-2000 Stephen Williams ([email protected])
@@ -19,7 +21,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: lexor.lex,v 1.86 2004/06/13 04:56:54 steve Exp $"
#ident "$Id: lexor.lex,v 1.96 2007/06/14 03:50:00 steve Exp $"
#endif
# include "config.h"
@@ -51,6 +53,7 @@ extern YYLTYPE yylloc;
struct file_name_cell {
const char*text;
struct file_name_cell*next;
bool library_flag;
};
static struct file_name_cell*file_names = 0;
@@ -70,6 +73,13 @@ static const char* set_file_name(char*text)
cur = new struct file_name_cell;
cur->text = text;
cur->next = file_names;
/* Check this file name with the list of library file
names. If there is a match, then turn on the
pform_library_flag. This is how the parser knows that
modules declared in this file are library modules. */
cur->library_flag = library_file_map[cur->text];
pform_library_flag = cur->library_flag;
return text;
}
@@ -99,6 +109,7 @@ static int comment_enter;
%s UDPTABLE
%x PPTIMESCALE
%x PPDEFAULT_NETTYPE
%s EDGES
W [ \t\b\f\r]+
@@ -132,6 +143,7 @@ W [ \t\b\f\r]+
"<<<" { return K_LS; /* Note: Functionally, <<< is the same as <<. */}
">>" { return K_RS; }
">>>" { return K_RSS; }
"**" { return K_POW; }
"<=" { return K_LE; }
">=" { return K_GE; }
"=>" { return K_EG; }
@@ -154,13 +166,14 @@ W [ \t\b\f\r]+
/* Watch out for the tricky case of (*). Cannot parse this as "(*"
and ")", but since I know that this is really ( * ), replace it
with "*" and return that. */
"(*"{W}*")" { return '*'; }
"("{W}*"*"{W}*")" { return '*'; }
<EDGES>"]" { BEGIN(0); return yytext[0]; }
[}{;:\[\],()#=.@&!?<>%|^~+*/-] { return yytext[0]; }
\" { BEGIN(CSTRING); }
<CSTRING>\\\" { yymore(); }
<CSTRING>\\\\ { yymore(); /* Catch \\, which is a \ escaping itself */ }
<CSTRING>\\\" { yymore(); /* Catch \", which is an escaped quote */ }
<CSTRING>\n { BEGIN(0);
yylval.text = strdup(yytext);
VLerror(yylloc, "Missing close quote of string.");
@@ -179,6 +192,8 @@ W [ \t\b\f\r]+
<UDPTABLE>\(01\) { return 'r'; }
<UDPTABLE>\(0[xX]\) { return 'Q'; }
<UDPTABLE>\(b[xX]\) { return 'q'; }
<UDPTABLE>\(b0\) { return 'f'; /* b0 is 10|00, but only 10 is meaningful */}
<UDPTABLE>\(b1\) { return 'r'; /* b1 is 11|01, but only 01 is meaningful */}
<UDPTABLE>\(0\?\) { return 'P'; }
<UDPTABLE>\(10\) { return 'f'; }
<UDPTABLE>\(1[xX]\) { return 'M'; }
@@ -196,14 +211,44 @@ W [ \t\b\f\r]+
<UDPTABLE>[pP] { return 'p'; }
<UDPTABLE>[01\?\*\-] { return yytext[0]; }
<EDGES>"01" { return K_edge_descriptor; }
<EDGES>"0x" { return K_edge_descriptor; }
<EDGES>"0z" { return K_edge_descriptor; }
<EDGES>"10" { return K_edge_descriptor; }
<EDGES>"1x" { return K_edge_descriptor; }
<EDGES>"1z" { return K_edge_descriptor; }
<EDGES>"x0" { return K_edge_descriptor; }
<EDGES>"x1" { return K_edge_descriptor; }
<EDGES>"z0" { return K_edge_descriptor; }
<EDGES>"z1" { return K_edge_descriptor; }
[a-zA-Z_][a-zA-Z0-9$_]* {
int rc = lexor_keyword_code(yytext, yyleng);
if (rc == IDENTIFIER) {
switch (rc) {
case IDENTIFIER:
yylval.text = strdup(yytext);
if (strncmp(yylval.text,"PATHPULSE$", 10) == 0)
rc = PATHPULSE_IDENTIFIER;
} else {
break;
case K_bool:
case K_logic:
case K_wone:
if (! gn_cadence_types_enabled()) {
yylval.text = strdup(yytext);
rc = IDENTIFIER;
} else {
yylval.text = 0;
}
break;
case K_edge:
BEGIN(EDGES);
break;
default:
yylval.text = 0;
break;
}
return rc;
@@ -276,10 +321,10 @@ W [ \t\b\f\r]+
^{W}?`disable_portfaults{W}?.* { }
^{W}?`enable_portfaults{W}?.* { }
^{W}?`endcelldefine{W}?.* { }
^{W}?`endprotect{W}?.* { }
`endprotect { }
^{W}?`nosuppress_faults{W}?.* { }
^{W}?`nounconnected_drive{W}?.* { }
^{W}?`protect{W}?.* { }
`protect { }
^{W}?`resetall{W}?.* { }
^{W}?`suppress_faults{W}?.* { }
^{W}?`unconnected_drive{W}?.* { }
@@ -440,7 +485,7 @@ static verinum*make_unsized_binary(const char*txt)
ptr += 1;
}
verinum*out = new verinum(bits, size);
verinum*out = new verinum(bits, size, false);
out->has_sign(sign_flag);
delete[]bits;
return out;
@@ -500,7 +545,7 @@ static verinum*make_unsized_octal(const char*txt)
ptr += 1;
}
verinum*out = new verinum(bits, size);
verinum*out = new verinum(bits, size, false);
out->has_sign(sign_flag);
delete[]bits;
return out;
@@ -570,7 +615,7 @@ static verinum*make_unsized_hex(const char*txt)
ptr += 1;
}
verinum*out = new verinum(bits, size);
verinum*out = new verinum(bits, size, false);
out->has_sign(sign_flag);
delete[]bits;
return out;
+7
View File
@@ -14,6 +14,7 @@ always, K_always
and, K_and
assign, K_assign
begin, K_begin
bool, K_bool
buf, K_buf
bufif0, K_bufif0
bufif1, K_bufif1
@@ -30,6 +31,7 @@ else, K_else
end, K_end
endcase, K_endcase
endfunction, K_endfunction
endgenerate, K_endgenerate
endmodule, K_endmodule
endprimitive, K_endprimitive
endspecify, K_endspecify
@@ -41,9 +43,12 @@ force, K_force
forever, K_forever
fork, K_fork
function, K_function
generate, K_generate
genvar, K_genvar
highz0, K_highz0
highz1, K_highz1
if, K_if
ifnone, K_ifnone
initial, K_initial
inout, K_inout
input, K_input
@@ -51,6 +56,7 @@ integer, K_integer
join, K_join
large, K_large
localparam, K_localparam
logic, K_logic
macromodule, K_macromodule
medium, K_medium
module, K_module
@@ -110,6 +116,7 @@ weak0, K_weak0
weak1, K_weak1
while, K_while
wire, K_wire
wone, K_wone
wor, K_wor
xnor, K_xnor
xor, K_xor
+2 -3
View File
@@ -16,7 +16,7 @@
# 59 Temple Place - Suite 330
# Boston, MA 02111-1307, USA
#
#ident "$Id: Makefile.in,v 1.34 2004/10/04 01:10:07 steve Exp $"
#ident "$Id: Makefile.in,v 1.36 2007/02/06 05:07:32 steve Exp $"
#
#
SHELL = /bin/sh
@@ -41,7 +41,6 @@ INSTALL_DATA = @INSTALL_DATA@
CPPFLAGS = @ident_support@ -I. -I.. -I$(srcdir) -I$(srcdir)/.. @CPPFLAGS@ @DEFS@ @PICFLAG@
CFLAGS = -Wall @CFLAGS@
LDFLAGS = @LDFLAGS@
STRIP = @STRIP@
RANLIB = @RANLIB@
A = a_close.o a_compare_handles.o a_configure.o a_fetch_argc.o \
@@ -92,7 +91,7 @@ clean:
rm -rf *.o dep libveriuser.a libveriuser.o bin32
distclean: clean
rm -f Makefile config.status config.log config.cache
rm -f Makefile config.status config.log config.cache config.h
install:: all installdirs $(libdir64)/libveriuser.a $(INSTALL32)
+5 -2
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: a_next.c,v 1.3 2003/06/17 16:55:07 steve Exp $"
#ident "$Id: a_next.c,v 1.4 2006/10/30 22:45:37 steve Exp $"
#endif
#include <stdio.h>
@@ -34,7 +34,7 @@ handle acc_next(PLI_INT32 *type, handle scope, handle prev)
/* trace */
if (pli_trace) {
int *ip;
PLI_INT32 *ip;
fprintf(pli_trace, "acc_next(%p <", type);
for (ip = type; *ip; ip++) {
fprintf(pli_trace, "%s%d", ip != type ? "," : "", *ip);
@@ -94,6 +94,9 @@ handle acc_next_scope(handle scope, handle prev)
/*
* $Log: a_next.c,v $
* Revision 1.4 2006/10/30 22:45:37 steve
* Updates for Cygwin portability (pr1585922)
*
* Revision 1.3 2003/06/17 16:55:07 steve
* 1) setlinebuf() for vpi_trace
* 2) Addes error checks for trace file opens
+3 -1
View File
@@ -1,6 +1,8 @@
AC_INIT(Makefile.in)
AC_CONFIG_HEADER(config.h)
AC_CANONICAL_HOST
AC_PROG_CC
AC_PROG_INSTALL
AC_PROG_RANLIB
@@ -21,7 +23,7 @@ AC_CHECK_SIZEOF(unsigned)
# may modify CPPFLAGS and CFLAGS
AX_CPP_PRECOMP
# Compiler option for position independent code, needed whan making shared objects.
# Compiler option for position independent code, needed when making shared objects.
AX_C_PICFLAG
AC_SUBST(EXEEXT)
+5 -2
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: getinstance.c,v 1.4 2003/05/18 00:16:35 steve Exp $"
#ident "$Id: getinstance.c,v 1.5 2005/09/20 18:34:01 steve Exp $"
#endif
#include <veriuser.h>
@@ -28,11 +28,14 @@
*/
PLI_BYTE8* tf_getinstance(void)
{
return (char *)vpi_handle(vpiSysTfCall, 0 /* NULL */);
return (PLI_BYTE8 *)vpi_handle(vpiSysTfCall, 0 /* NULL */);
}
/*
* $Log: getinstance.c,v $
* Revision 1.5 2005/09/20 18:34:01 steve
* Clean up compiler warnings.
*
* Revision 1.4 2003/05/18 00:16:35 steve
* Add PLI_TRACE tracing of PLI1 modules.
*
+16 -10
View File
@@ -18,7 +18,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: veriusertfs.c,v 1.15 2004/09/10 23:13:05 steve Exp $"
#ident "$Id: veriusertfs.c,v 1.17 2007/05/08 22:01:26 steve Exp $"
#endif
/*
@@ -44,9 +44,9 @@ typedef struct t_pli_data {
int paramvc; /* parameter number for misctf */
} s_pli_data, *p_pli_data;
static int compiletf(char *);
static int calltf(char *);
static int callback(p_cb_data);
static PLI_INT32 compiletf(char *);
static PLI_INT32 calltf(char *);
static PLI_INT32 callback(p_cb_data);
/*
* Register veriusertfs routines/wrappers. Iterate over the tfcell
@@ -58,7 +58,7 @@ void veriusertfs_register_table(p_tfcell vtable)
p_tfcell tf;
s_vpi_systf_data tf_data;
p_pli_data data;
char trace_buf[1024];
static char trace_buf[1024];
if (!pli_trace && (path = getenv("PLI_TRACE"))) {
if (strcmp(path,"-") == 0)
@@ -69,8 +69,8 @@ void veriusertfs_register_table(p_tfcell vtable)
perror(path);
exit(1);
}
setvbuf(pli_trace, trace_buf, _IOLBF, sizeof(trace_buf));
}
setvbuf(pli_trace, trace_buf, _IOLBF, sizeof(trace_buf));
}
for (tf = vtable; tf; tf++) {
@@ -139,7 +139,7 @@ void veriusertfs_register_table(p_tfcell vtable)
* This function calls the veriusertfs checktf and sets up all the
* callbacks misctf requires.
*/
static int compiletf(char *data)
static PLI_INT32 compiletf(char *data)
{
p_pli_data pli;
p_tfcell tf;
@@ -221,7 +221,7 @@ static int compiletf(char *data)
/*
* This function is the wrapper for the veriusertfs calltf routine.
*/
static int calltf(char *data)
static PLI_INT32 calltf(char *data)
{
int rc = 0;
p_pli_data pli;
@@ -249,13 +249,13 @@ static int calltf(char *data)
*/
extern int async_misctf_enable;
static int callback(p_cb_data data)
static PLI_INT32 callback(p_cb_data data)
{
p_pli_data pli;
p_tfcell tf;
int reason;
int paramvc = 0;
int rc;
PLI_INT32 rc;
/* not enabled */
if (data->reason == cbValueChange && !async_misctf_enable)
@@ -389,6 +389,12 @@ PLI_INT32 tf_setrealdelay(double dly)
}
/*
* $Log: veriusertfs.c,v $
* Revision 1.17 2007/05/08 22:01:26 steve
* Trace file line buffer must be static.
*
* Revision 1.16 2006/10/30 22:45:37 steve
* Updates for Cygwin portability (pr1585922)
*
* Revision 1.15 2004/09/10 23:13:05 steve
* Compile cleanup of C code.
*
+16 -1
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: link_const.cc,v 1.17 2004/10/04 01:10:53 steve Exp $"
#ident "$Id: link_const.cc,v 1.18 2007/04/14 03:10:51 steve Exp $"
#endif
# include "config.h"
@@ -132,6 +132,8 @@ verinum::V Nexus::driven_value() const
} else if ((sig = dynamic_cast<const NetNet*>(cur->get_obj()))) {
// If we find an attached SUPPLY0/1, the we know
// from that what the driven value is. Stop now.
if (sig->type() == NetNet::SUPPLY0) {
driven_ = V0;
return verinum::V0;
@@ -140,6 +142,16 @@ verinum::V Nexus::driven_value() const
driven_ = V1;
return verinum::V1;
}
// If we find an attached TRI0/1, then this is a
// good guess for the driven value, but keep
// looking for something better.
if (sig->type() == NetNet::TRI0) {
val = verinum::V0;
}
if (sig->type() == NetNet::TRI1) {
val = verinum::V1;
}
}
}
@@ -164,6 +176,9 @@ verinum::V Nexus::driven_value() const
/*
* $Log: link_const.cc,v $
* Revision 1.18 2007/04/14 03:10:51 steve
* Properly account for tri0 connected to otherwise open mux input.
*
* Revision 1.17 2004/10/04 01:10:53 steve
* Clean up spurious trailing white space.
*
+5 -2
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: load_module.cc,v 1.12 2003/06/05 04:31:09 steve Exp $"
#ident "$Id: load_module.cc,v 1.13 2005/03/22 15:53:48 steve Exp $"
#endif
# include "config.h"
@@ -88,7 +88,7 @@ bool load_module(const char*type)
cerr << "Executing: " << cmdline << endl;
pform_parse(path, file);
fclose(file);
pclose(file);
free(cmdline);
} else {
@@ -193,6 +193,9 @@ int build_library_index(const char*path, bool key_case_sensitive)
/*
* $Log: load_module.cc,v $
* Revision 1.13 2005/03/22 15:53:48 steve
* popen must be matched by pclose.
*
* Revision 1.12 2003/06/05 04:31:09 steve
* INclude missing assert.h in load_module.
*
+119 -19
View File
@@ -1,6 +1,6 @@
const char COPYRIGHT[] =
"Copyright (c) 1998-2004 Stephen Williams ([email protected])";
"Copyright (c) 1998-2005 Stephen Williams ([email protected])";
/*
* This source code is free software; you can redistribute it
@@ -19,7 +19,7 @@ const char COPYRIGHT[] =
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: main.cc,v 1.86 2004/10/04 01:10:53 steve Exp $"
#ident "$Id: main.cc,v 1.95 2007/04/19 02:52:53 steve Exp $"
#endif
# include "config.h"
@@ -81,12 +81,20 @@ const char*basedir = ".";
const char*target = "null";
/*
* These are the language support control flags. These support which
* language features (the generation) to support. The generation_flag
* is a major moce, and the gn_* flags control specifc sub-features.
*/
generation_t generation_flag = GN_DEFAULT;
bool gn_cadence_types_flag = true;
bool gn_specify_blocks_flag = true;
map<string,const char*> flags;
char*vpi_module_list = 0;
map<perm_string,unsigned> missing_modules;
map<string,bool> library_file_map;
list<const char*> library_suff;
@@ -112,11 +120,14 @@ bool error_implicit = false;
bool debug_scopes = false;
bool debug_eval_tree = false;
bool debug_elaborate = false;
bool debug_synth2 = false;
/*
* Verbose messages enabled.
*/
bool verbose_flag = false;
unsigned integer_width = 32;
/*
* Keep a heap of identifier strings that I encounter. This is a more
* efficient way to allocate those strings.
@@ -137,7 +148,9 @@ extern void synth(Design*des);
extern void synth2(Design*des);
extern void syn_rules(Design*des);
extern void nodangle(Design*des);
#ifdef WITH_T_XNF
extern void xnfio(Design*des);
#endif
typedef void (*net_func)(Design*);
static struct net_func_map {
@@ -149,7 +162,9 @@ static struct net_func_map {
{ "synth", &synth },
{ "synth2", &synth2 },
{ "syn-rules", &syn_rules },
#ifdef WITH_T_XNF
{ "xnfio", &xnfio },
#endif
{ 0, 0 }
};
@@ -175,17 +190,29 @@ const char *net_func_to_name(const net_func func)
static void process_generation_flag(const char*gen)
{
if (strcmp(gen,"1") == 0)
if (strcmp(gen,"1") == 0) {
generation_flag = GN_VER1995;
else if (strcmp(gen,"2") == 0)
} else if (strcmp(gen,"2") == 0) {
generation_flag = GN_VER2001;
else if (strcmp(gen,"3.0") == 0)
generation_flag = GN_SYSVER30;
} else if (strcmp(gen,"2x") == 0) {
generation_flag = GN_VER2001X;
else
generation_flag = GN_DEFAULT;
} else if (strcmp(gen,"xtypes") == 0) {
gn_cadence_types_flag = true;
} else if (strcmp(gen,"no-xtypes") == 0) {
gn_cadence_types_flag = false;
} else if (strcmp(gen,"specify") == 0) {
gn_specify_blocks_flag = true;
} else if (strcmp(gen,"no-specify") == 0) {
gn_specify_blocks_flag = false;
} else {
}
}
static void parm_to_flagmap(const string&flag)
@@ -246,13 +273,22 @@ static void parm_to_flagmap(const string&flag)
* functor:<name>
* Append a named functor to the processing path.
*
* generation:<1|2|3.0>
* generation:<1|2|2x|xtypes|no-xtypes|specify|no-specify>
* This is the generation flag
*
* ivlpp:<preprocessor command>
* This specifies the ivlpp command line used to process
* library modules as I read them in.
*
* iwidth:<bits>
* This specifies the width of integer variables. (that is,
* variables declared using the "integer" keyword.)
*
* library_file:<path>
* This marks that a source file with the given path is a
* library. Any modules in that file are marked as library
* modules.
*
* module:<name>
* Load a VPI module.
*
@@ -314,6 +350,9 @@ static void read_iconfig_file(const char*ipath)
} else if (strcmp(cp,"elaborate") == 0) {
debug_elaborate = true;
cerr << "debug: Enable elaborate debug" << endl;
} else if (strcmp(cp,"synth2") == 0) {
debug_synth2 = true;
cerr << "debug: Enable synth2 debug" << endl;
} else {
}
@@ -340,6 +379,13 @@ static void read_iconfig_file(const char*ipath)
} else if (strcmp(buf, "ivlpp") == 0) {
ivlpp_string = strdup(cp);
} else if (strcmp(buf, "iwidth") == 0) {
integer_width = strtoul(cp,0,10);
} else if (strcmp(buf, "library_file") == 0) {
const char* path = strdup(cp);
library_file_map[path] = true;
} else if (strcmp(buf,"module") == 0) {
if (vpi_module_list == 0) {
vpi_module_list = strdup(cp);
@@ -540,11 +586,21 @@ int main(int argc, char*argv[])
case GN_VER2001:
cout << "IEEE1364-2001";
break;
case GN_SYSVER30:
cout << "SystemVerilog 3.0";
case GN_VER2001X:
cout << "IEEE1364-2001+Extensions";
break;
}
if (gn_specify_blocks_flag)
cout << ",specify";
else
cout << ",no-specify";
if (gn_cadence_types_flag)
cout << ",xtypes";
else
cout << ",no-xtypes";
cout << endl << "PARSING INPUT" << endl;
}
@@ -597,11 +653,20 @@ int main(int argc, char*argv[])
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());
}
/* Don't choose library modules. */
if ((*mod).second->library_flag)
continue;
/* Don't choose modules instantiated in other
modules. */
if (mentioned_p[(*mod).second->mod_name()])
continue;
/* What's left might as well be chosen as a root. */
if (verbose_flag)
cout << " " << (*mod).second->mod_name();
roots.push_back((*mod).second->mod_name());
}
if (verbose_flag)
cout << endl;
@@ -697,12 +762,18 @@ int main(int argc, char*argv[])
cout << "CODE GENERATION -t "<<target<< endl;
}
bool emit_rc;
int emit_rc;
emit_rc = emit(des, target);
if (!emit_rc) {
cerr << "error: Code generation had errors." << endl;
if (emit_rc > 0) {
cerr << "error: Code generation had "
<< emit_rc << " errors."
<< endl;
return 1;
}
if (emit_rc < 0) {
cerr << "error: Code generator failure: " << emit_rc << endl;
return -1;
}
if (verbose_flag) {
if (times_flag) {
@@ -744,6 +815,35 @@ int main(int argc, char*argv[])
/*
* $Log: main.cc,v $
* Revision 1.95 2007/04/19 02:52:53 steve
* Add support for -v flag in command file.
*
* Revision 1.94 2007/03/07 04:24:59 steve
* Make integer width controllable.
*
* Revision 1.93 2006/09/28 04:35:18 steve
* Support selective control of specify and xtypes features.
*
* Revision 1.92 2005/07/14 23:38:43 steve
* Display as version 0.9.devel
*
* Revision 1.91 2005/07/07 16:22:49 steve
* Generalize signals to carry types.
*
* Revision 1.90 2005/06/28 04:25:55 steve
* Remove reference to SystemVerilog.
*
* Revision 1.89 2005/04/24 23:44:02 steve
* Update DFF support to new data flow.
*
* Revision 1.88 2005/01/22 01:06:55 steve
* Change case compare from logic to an LPM node.
*
* Revision 1.87 2004/12/11 02:31:26 steve
* Rework of internals to carry vectors through nexus instead
* of single bits. Make the ivl, tgt-vvp and vvp initial changes
* down this path.
*
* Revision 1.86 2004/10/04 01:10:53 steve
* Clean up spurious trailing white space.
*
+109 -108
View File
@@ -2,7 +2,7 @@
MINGW PORT OF ICARUS VERILOG
Copyright 2003 Stephen Williams <[email protected]>
Copyright 2006 Stephen Williams <[email protected]>
Icarus Verilog source can be compiled with the mingw C/C++ compilers
@@ -12,13 +12,13 @@ or without Cygwin, so this is the preferred Windows distribution form.
The configure scripts automatically detect that the compilers in use
are the mingw compilers and will configure the Makefiles appropriately.
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. There are
also a few precompiled library prerequisites that you need.
The mingw patch doesn't contain tools beyond the compiler, but there
is the "msys" package that the makers of Mingw publish that has enough
extra tools to get most everything else working. There are a few extra
packages needed beyond mingw and msys, and the following instructions
explain how to get them and install them.
* Some Preliminary Comments
* Some Preliminary Comments -- PLEASE READ ME --
The Windows port of Icarus Verilog is the most difficult of all the
ports. The Windows system off the shelf is completely stripped, devoid
@@ -26,7 +26,15 @@ of any support for software development. Everything needed to compile
Icarus Verilog must be collected from various sources and stitched
together by hand. Normal human beings with a basic understanding of
software development can do this, but some patience (and access to the
Internet) is required. You may choose to print these instructions.
Internet) is required. You may choose to print these instructions. FOR
BEST RESULTS, FOLLOW THESE INSTRUCTIONS CAREFULLY.
NOTE that if you have Cygwin installed, it is best to not use a cygwin
window to do the build, as the Cygwin tools will intermix with the
mingw tools such that it is hard to be sure you are using the right
compiler. Thus, it is recommended that these steps be *not* done in a
Cygwin window. Use an MSYS window instead, and be careful that your
msys/mingw tools are not masked by paths that point to Cygwin binaries.
I have no plans to intentionally support MSVC++ compilation. Don't ask.
@@ -36,13 +44,15 @@ This is a brief list of prerequisite packages, along with the URL
where each can be found. In most cases, the specific version is not
critical, but these are the versions I use.
Cygwin <http://cygwin.com>
Mingw32-2.0.0 <http://www.mingw.org>
msys-1.0 <http://www.mingw/org>
msysDTK-1.0 <http://www.mingw.org>
Mingw32-5.x <http://www.mingw.org>
readline-4.2-20010727.zip <http://mingwrep.sourceforge.net>
bzip2-1.0.2-bin.zip <http://gnuwin32.sourceforge.net>
zlib-1.1.4-bin.zip <http://gnuwin32.sourceforge.net>
bzip2-1.0.2-lib.zip <http://gnuwin32.sourceforge.net>
zlib-1.1.4-lib.zip <http://gnuwin32.sourceforge.net>
bzip2-1.0.3 <http://gnuwin32.sourceforge.net>
zlib-1.2.3 <http://gnuwin32.sourceforge.net>
gperf-3.0.1 <http://gnuwin32.sourceforge.net>
bison-2.1 <http://gnuwin32.sourceforge.net>
flex-2.5.4a <http://gnuwin32.sourceforge.net>
The above table lists the packages required. It is convenient to
install them in the above order. Many of these packages are also
@@ -55,59 +65,38 @@ installation of Icarus Verilog is complete. These are only needed to
build the compiler. The Mingw32 package can be used to compile VPI
modules if you choose.
* Install Cygwin
* Install MSYS and msysDTK
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. There is
a convenient setup program that you download first. You execute the
setup program, and that prompts you to select the package you want.
The msys package is available from the mingw download site. This is
not the compiler but a collection of *nix tools ported to Windows and
wrapped in a convenient installer. The msys package is all the various
basic tools (shells, file utils, etc) and the msysDTK is extra
developer tools other than the compiler.
You need in particular the Cygwin base, bison (see notes) flex, make
and gperf. If you are compiling from CVS, you also need cvs, rcs and
automake packages. You will also need tar and gunzip, but these are
hard to not install. I recommend installing the "which" package as
well. Beyond the basics, be sure to install these Cygwin packages:
Download the msys-1.x.x.exe and msysdtc-1.x.x.exe binaries. These are
self-installing packages. Install msys first, and then msysDTC. Most
likely, you want to install them in c:/msys. (The msysDTK is installed
in the same location, as it is an add-on.)
bison (*not* 1.875. See Notes.)
flex
ghostscript (makes the documentation)
gperf
gzip
make
strip
tar (tar and gunzip for unpacking the source)
unzip (For unpacking zip compressed packages.)
which
This install should be easy and reliable.
NOTES:
bison-1.875 is broken, it generates invalid C/C++ code. You
don't want that version for anything you do. If you have that
version (use "bison -V" to check the version) then use the
Cygwin setup program to get a different version. I've downgraded
to 1.75 and couldn't be happier. In fact, a whole host of insane
bison bugs can be avoided that way.
There is a mingw32 runtime package included in the Cygwin
distribution. You do *not* need that, as you will be getting
everything from the mingw32 distribution itself.
Other then the install of mingw32, 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.
The installation will leave an "msys" icon on your desktop and in the
mingw sub-menu of your Start menu. This icon brings up a shell window
(a command line) that has paths all set up for executing msys and
mingw commands. This is what you will want to use while executing
commands below.
* Install Mingw32
The obvious step 2, then, is install the mingw compilers. These can be
found at the web page <http://www.mingw.org>. The Mingw-2.x.x version
comes prepackaged in a convenient, Windows style, installer. I
recommend you download this package instead of picking and choosing
bits.
found at the web page <http://www.mingw.org>. The Mingw-5.x.x package
is a convenient remote installer. Download this program and run
it. The installer will ask wich components you want to install. You
need only the base C compiler and the C++ compiler. (You may install
other languages if you wish.)
When I install Mingw32 (using the installer) I typically set a
destination directory of d:\mingw-2.0.0 or the like. You will be using
destination directory of d:\mingw or the like. You will be using
that path later.
NOTES:
@@ -115,6 +104,10 @@ that path later.
need Mingw32, even if you are using a precompiled binary. VPI
modules only require Mingw32, and none of the other libraries.
Finally, as part of installing the mingw32 compilers, remember to add
the mingw/bin directory to your path. You will need that to be able to
find the compilers later.
* Install Mingw32 Packages
There is a collection of precompiled libraries and add-on packages
@@ -123,86 +116,94 @@ with simplified Windows installers, but they are pretty easy to
install by hand. Icarus Verilog uses the readline-4.2 package from
that collection.
Since I installed Mingw32 in d:\mingw-2.0.0, I also created a
Mingw-packages directory called d:\mingw-packages. The install, then,
Since I installed Mingw32 in c:\mingw, I also created a
Mingw-packages directory called c:\mingw-packages. The install, then,
is as easy as this:
<cygwin shell>
$ cd d:/mingw-packages
<msys shell>
$ cd c:/mingw-packages
$ unzip readline-4.2-20010727.zip
[lots of inflating...]
There is no need to adjust your execution path for this package as we
are only using a library out of here. However, do remember the
directory name, as you will need it later.
Done. On to the next packages.
* Install GnuWin32 Packages
The GnuWin32 project is a collections of open source programs and
libraries ported to Windows. These also work well with the Mingw
compiler, and in fact Icarus Verilog uses a few libraries from this
compiler, and in fact Icarus Verilog uses a few pieces from this
collection.
You will need these gnuwin32 packages to compile Icarus Verilog:
<http://gnuwin32.sourceforge.net>
bzip2-1.0.2-lib.zip
bzip2-1.0.2-bin.zip
zlib-1.1.4-lib.zip
zlib-1.1.4-bin.zip
bzip2-1.0.3.exe
zlib-1.2.3.exe
gperf-3.0.1.exe
bison-2.1.exe
flex-2.5.4a.exe
I suggest creating a common directory for holding all your gnuwin32
packages. I use D:\gnuwin32.
packages. I use C:\gnuwin32. The download page at the gnuwin32 site
has a "setup" link for each of these packages. Click the setup to
download the installer for each of the desired programes, then execute
the downloaded .exe files to invoke the installer. Install into the
c:\gunwin32 directory.
After downloading these packages, put the .zip files in your gnuwin32
directory and install them like so:
NOTES:
You need the binaries and the developer files, but you do not
need the source to these packages. The installer gives you the
choice.
<cygwin shell>
$ cd d:/gnuwin32
$ unzip bzip2-1.0.2-bin.zip
[lots of inflating...]
$ unzip bzip2-1.0.2-lib.zip
[lots of inflating...]
$ unzip zlib-1.1.4-bin.zip
[lots of inflating...]
$ unzip zlib-1.1.4-lib.zip
[lots of inflating...]
Done.
After you are done installing the gnuwin32 tools, you should add the
c:\gnuwin32\bin directory (assuming you installed in c:\gnuwin32) to
your Windows path. The msys shell will pick up your Windows path.
* Unpack Icarus Verilog source
Unpack the compressed tar file (.tar.gz) of the source with a command
like this:
$ gunzip -d verilog-20030303.tar.gz | tar xvf -
$ gunzip -d verilog-xxxxxxxx.tar.gz | tar xvf -
This will create a directory "verilog-20030303" that contains all the
This will create a directory "verilog-xxxxxxxx" that contains all the
source for Icarus Verilog. Descend into that directory, as that is
where we will work from now on.
$ cd verilog-20030303
$ cd verilog-xxxxxxxx
NOTE:
NOTES:
The exact name of the file will vary according to the
snapshot. The 20030303 name is only an example.
* Select the mingw compilers
Unpack the source into a directory that has no spaces. The
makefiles included in the source get confused by white space in
directory names.
In your cygwin window, if you type "which c++" you might 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:
* Preconfigure Icarus Verilog (Not normally needed)
$ PATH=/cygdrive/d/mingw-2.0.0/bin:$PATH
Under certain cases, you may need to "preconfigure" the Icarus Verilog
source tree. You should only need to do this if you are getting the
Icarus Verilog source tree from CVS, or you are using an existing
source tree that you've patched to cause configure.in files to change.
This assumes that you installed mingw in D:\mingw-2.0.0. 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:
NOTE: If you are building from a fresh, bundled source tree that
you downloaded from an FTP site, then SKIP THIS STEP. Go on to
the "Configure Icarus Verilog" step below.
$ which c++
/cygdrive/d/mingw-2.0.0/bin/c++
First, remove any autom4te.cache directories that may exist in your
source tree. These can make a mess of autoconf runs. Then, generate
configure scripts with this command:
Good!
$ sh autoconf.sh
This script will run the "autoconf" command (part of the msysDTK) to
generate all the necessary "configure" scripts. This will take a few
minutes. This should go smoothly.
* Configure Icarus Verilog
@@ -215,10 +216,10 @@ without white space.
Now, configure the source to make the makefiles and configuration
details. Run these commands:
$ CPPFLAGS="-Id:/gnuwin32/include -Id:/mingw-packages/include"
$ LDFLAGS="-Ld:/gnuwin32/lib -Ld:/mingw-packages/include"
$ CPPFLAGS="-Ic:/gnuwin32/include -Ic:/mingw-packages/include"
$ LDFLAGS="-Lc:/gnuwin32/lib -Lc:/mingw-packages/lib"
$ export CPPFLAGS LDFLAGS
$ ./configure --prefix=d:/iverilog
$ ./configure --prefix=c:/iverilog
NOTES:
The CPPFLAGS and LDFLAGS variables tell configure where
@@ -267,10 +268,10 @@ directory you chose) and away you go.
You may find that you need to put some of the prerequisite DLLs into
the d:\iverilog\bin directory. These include:
d:\mingw-2.0.0\bin\mingw10.dll
d:\mingw-packages\bin\libreadline.dll
d:\gnuwin32\bin\bzip2.dll
d:\gnuwin32\bin\zlib.dll
c:\mingw\bin\mingw10.dll
c:\mingw-packages\bin\libreadline.dll
c:\gnuwin32\bin\bzip2.dll
c:\gnuwin32\bin\zlib.dll
If you already have these in your Windows path (i.e. your system32
directory) then you do not need to copy them into the iverilog
@@ -279,14 +280,14 @@ files.
* Running Icarus Verilog
Finally, put the D:\iverilog\bin directory in your Windows path, and
Finally, put the C:\iverilog\bin directory in your Windows path, and
you should be able to run the iverilog and vvp commands to your
heart's content.
Currently, the iverilog.exe uses the path to itself to locate the
libraries and modules associated with itself. In other words, if you
execute the D:\iverilog\bin\iverilog.exe program, it will locate its
subparts in the D:\iverilog directory and subdirectories below
execute the C:\iverilog\bin\iverilog.exe program, it will locate its
subparts in the C:\iverilog directory and subdirectories below
that. This means you can move the Icarus Verilog installation by
simply moving the root directory and all its contents.
+73 -90
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: net_assign.cc,v 1.18 2004/08/28 15:08:31 steve Exp $"
#ident "$Id: net_assign.cc,v 1.22 2007/01/16 05:44:15 steve Exp $"
#endif
# include "config.h"
@@ -39,30 +39,13 @@ unsigned count_lval_width(const NetAssign_*idx)
}
NetAssign_::NetAssign_(NetNet*s)
: sig_(s), mem_(0), var_(0), bmux_(0)
: sig_(s), word_(0), base_(0)
{
loff_ = 0;
lwid_ = sig_->pin_count();
lwid_ = sig_->vector_width();
sig_->incr_lref();
more = 0;
}
NetAssign_::NetAssign_(NetMemory*s)
: sig_(0), mem_(s), var_(0), bmux_(0)
{
loff_ = 0;
lwid_ = mem_->width();
more = 0;
}
NetAssign_::NetAssign_(NetVariable*s)
: sig_(0), mem_(0), var_(s), bmux_(0)
{
loff_ = 0;
lwid_ = 0;
more = 0;
}
NetAssign_::~NetAssign_()
{
if (sig_) {
@@ -72,38 +55,39 @@ NetAssign_::~NetAssign_()
}
assert( more == 0 );
if (bmux_) delete bmux_;
if (word_) delete word_;
}
void NetAssign_::set_bmux(NetExpr*r)
void NetAssign_::set_word(NetExpr*r)
{
assert(bmux_ == 0);
bmux_ = r;
assert(word_ == 0);
word_ = r;
}
NetExpr* NetAssign_::bmux()
NetExpr* NetAssign_::word()
{
return bmux_;
return word_;
}
const NetExpr* NetAssign_::bmux() const
const NetExpr* NetAssign_::word() const
{
return bmux_;
return word_;
}
const NetExpr* NetAssign_::get_base() const
{
return base_;
}
unsigned NetAssign_::lwidth() const
{
if (mem_) return lwid_;
else if (bmux_) return 1;
else return lwid_;
return lwid_;
}
perm_string NetAssign_::name() const
{
if (sig_) {
return sig_->name();
} else if (mem_) {
return mem_->name();
} else {
return perm_string::literal("");
}
@@ -114,32 +98,10 @@ NetNet* NetAssign_::sig() const
return sig_;
}
NetMemory* NetAssign_::mem() const
void NetAssign_::set_part(NetExpr*base, unsigned wid)
{
return mem_;
}
NetVariable* NetAssign_::var() const
{
return var_;
}
void NetAssign_::set_part(unsigned lo, unsigned lw)
{
loff_ = lo;
lwid_ = lw;
if (sig_) {
assert(sig_->pin_count() >= (lo + lw));
} else {
assert(mem_);
assert(lwid_ == mem_->width());
}
}
unsigned NetAssign_::get_loff() const
{
return loff_;
base_ = base;
lwid_ = wid;
}
/*
@@ -259,8 +221,61 @@ NetAssignNB::~NetAssignNB()
{
}
NetCAssign::NetCAssign(NetAssign_*lv, NetExpr*rv)
: NetAssignBase(lv, rv)
{
}
NetCAssign::~NetCAssign()
{
}
NetDeassign::NetDeassign(NetAssign_*l)
: NetAssignBase(l, 0)
{
}
NetDeassign::~NetDeassign()
{
}
NetForce::NetForce(NetAssign_*lv, NetExpr*rv)
: NetAssignBase(lv, rv)
{
}
NetForce::~NetForce()
{
}
NetRelease::NetRelease(NetAssign_*l)
: NetAssignBase(l, 0)
{
}
NetRelease::~NetRelease()
{
}
/*
* $Log: net_assign.cc,v $
* Revision 1.22 2007/01/16 05:44:15 steve
* Major rework of array handling. Memories are replaced with the
* more general concept of arrays. The NetMemory and NetEMemory
* classes are removed from the ivl core program, and the IVL_LPM_RAM
* lpm type is removed from the ivl_target API.
*
* Revision 1.21 2006/02/02 02:43:58 steve
* Allow part selects of memory words in l-values.
*
* Revision 1.20 2005/07/11 16:56:50 steve
* Remove NetVariable and ivl_variable_t structures.
*
* Revision 1.19 2004/12/11 02:31:26 steve
* Rework of internals to carry vectors through nexus instead
* of single bits. Make the ivl, tgt-vvp and vvp initial changes
* down this path.
*
* Revision 1.18 2004/08/28 15:08:31 steve
* Do not change reg to wire in NetAssign_ unless synthesizing.
*
@@ -270,37 +285,5 @@ NetAssignNB::~NetAssignNB()
* Revision 1.16 2003/01/26 21:15:58 steve
* Rework expression parsing and elaboration to
* accommodate real/realtime values and expressions.
*
* Revision 1.15 2002/08/12 01:34:59 steve
* conditional ident string using autoconfig.
*
* Revision 1.14 2002/08/04 18:28:15 steve
* Do not use hierarchical names of memories to
* generate vvp labels. -tdll target does not
* used hierarchical name string to look up the
* memory objects in the design.
*
* Revision 1.13 2002/07/02 03:02:57 steve
* Change the signal to a net when assignments go away.
*
* Revision 1.12 2002/06/08 23:42:46 steve
* Add NetRamDq synthsesis from memory l-values.
*
* Revision 1.11 2002/06/04 05:38:44 steve
* Add support for memory words in l-value of
* blocking assignments, and remove the special
* NetAssignMem class.
*
* Revision 1.10 2002/05/26 01:39:02 steve
* Carry Verilog 2001 attributes with processes,
* all the way through to the ivl_target API.
*
* Divide signal reference counts between rval
* and lval references.
*
* Revision 1.9 2002/04/21 22:31:02 steve
* Redo handling of assignment internal delays.
* Leave it possible for them to be calculated
* at run time.
*/
+104 -139
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: net_design.cc,v 1.45 2004/10/04 01:10:54 steve Exp $"
#ident "$Id: net_design.cc,v 1.54 2007/06/05 04:18:09 steve Exp $"
#endif
# include "config.h"
@@ -32,6 +32,7 @@
# include "netlist.h"
# include "util.h"
# include "compiler.h"
# include "netmisc.h"
# include <sstream>
Design:: Design()
@@ -67,8 +68,8 @@ int Design::get_precision() const
return des_precision_;
}
unsigned long Design::scale_to_precision(unsigned long val,
const NetScope*scope) const
uint64_t Design::scale_to_precision(uint64_t val,
const NetScope*scope) const
{
int units = scope->time_unit();
assert( units >= des_precision_ );
@@ -84,7 +85,7 @@ unsigned long Design::scale_to_precision(unsigned long val,
NetScope* Design::make_root_scope(perm_string root)
{
NetScope *root_scope_;
root_scope_ = new NetScope(0, root, NetScope::MODULE);
root_scope_ = new NetScope(0, hname_t(root), NetScope::MODULE);
/* This relies on the fact that the basename return value is
permallocated. */
root_scope_->set_module_name(root_scope_->basename());
@@ -114,26 +115,27 @@ const list<NetScope*> Design::find_root_scopes() const
* more step down the tree until the name runs out or the search
* fails.
*/
NetScope* Design::find_scope(const hname_t&path) const
NetScope* Design::find_scope(const std::list<hname_t>&path) const
{
if (path.peek_name(0) == 0)
if (path.empty())
return 0;
for (list<NetScope*>::const_iterator scope = root_scopes_.begin()
; scope != root_scopes_.end(); scope++) {
NetScope*cur = *scope;
if (strcmp(path.peek_name(0), cur->basename()) != 0)
if (path.front() != cur->fullname())
continue;
unsigned hidx = 1;
while (cur) {
const char*name = path.peek_name(hidx);
if (name == 0)
return cur;
std::list<hname_t> tmp = path;
tmp.pop_front();
cur = cur->child(name);
hidx += 1;
while (cur) {
if (tmp.empty()) return cur;
cur = cur->child( tmp.front() );
tmp.pop_front();
}
}
@@ -143,28 +145,34 @@ NetScope* Design::find_scope(const hname_t&path) const
/*
* This is a relative lookup of a scope by name. The starting point is
* the scope parameter is the place within which I start looking for
* the scope. If I do not find the scope within the passed scope,
* start looking in parent scopes until I find it, or I run out of
* parent scopes.
* the scope parameter within which I start looking for the scope. If
* I do not find the scope within the passed scope, start looking in
* parent scopes until I find it, or I run out of parent scopes.
*/
NetScope* Design::find_scope(NetScope*scope, const hname_t&path) const
NetScope* Design::find_scope(NetScope*scope, const std::list<hname_t>&path) const
{
assert(scope);
if (path.peek_name(0) == 0)
if (path.empty())
return scope;
for ( ; scope ; scope = scope->parent()) {
unsigned hidx = 0;
const char*key = path.peek_name(hidx);
std::list<hname_t> tmp = path;
NetScope*cur = scope;
do {
cur = cur->child(key);
if (cur == 0) break;
hidx += 1;
key = path.peek_name(hidx);
} while (key);
hname_t key = tmp.front();
if (cur->type() == NetScope::MODULE
&& cur->module_name()==key.peek_name()) {
/* Up references may match module name */
} else {
cur = cur->child( key );
if (cur == 0) break;
}
tmp.pop_front();
} while (!tmp.empty());
if (cur) return cur;
}
@@ -173,71 +181,6 @@ NetScope* Design::find_scope(NetScope*scope, const hname_t&path) const
return find_scope(path);
}
/*
* Find a parameter from within a specified context. If the name is
* not here, keep looking up until I run out of up to look at. The
* method works by scanning scopes, starting with the passed scope and
* working up towards the root, looking for the named parameter. The
* name in this case can be hierarchical, so there is an inner loop to
* follow the scopes of the name down to to key.
*
* The expression value of the parameter is returned as the result,
* and the scope that contains the parameter is returned in the out
* argument found_in.
*/
const NetExpr* Design::find_parameter(NetScope*scope,
const hname_t&path,
NetScope*&found_in) const
{
for ( ; scope ; scope = scope->parent()) {
unsigned hidx = 0;
NetScope*cur = scope;
while (path.peek_name(hidx+1)) {
cur = cur->child(path.peek_name(hidx));
if (cur == 0)
break;
hidx += 1;
}
if (cur == 0)
continue;
if (const NetExpr*res = cur->get_parameter(path.peek_name(hidx))) {
found_in = cur;
return res;
}
}
return 0;
}
const NetExpr* Design::find_parameter(const NetScope*scope,
const hname_t&path) const
{
for ( ; scope ; scope = scope->parent()) {
unsigned hidx = 0;
const NetScope*cur = scope;
while (path.peek_name(hidx+1)) {
cur = cur->child(path.peek_name(hidx));
if (cur == 0)
break;
hidx += 1;
}
if (cur == 0)
continue;
if (const NetExpr*res = cur->get_parameter(path.peek_name(hidx)))
return res;
}
return 0;
}
/*
* This method runs through the scope, noticing the defparam
* statements that were collected during the elaborate_scope pass and
@@ -261,18 +204,19 @@ void NetScope::run_defparams(Design*des)
}
}
map<hname_t,NetExpr*>::const_iterator pp;
map<pform_name_t,NetExpr*>::const_iterator pp;
for (pp = defparams.begin() ; pp != defparams.end() ; pp ++ ) {
NetExpr*val = (*pp).second;
hname_t path = (*pp).first;
pform_name_t path = (*pp).first;
char*tmp = path.remove_tail_name();
perm_string perm_name = lex_strings.make(tmp);
delete[]tmp;
perm_string perm_name = peek_tail_name(path);
path.pop_back();
list<hname_t> eval_path = eval_scope_path(des, this, path);
/* If there is no path on the name, then the targ_scope
is the current scope. */
NetScope*targ_scope = des->find_scope(this, path);
NetScope*targ_scope = des->find_scope(this, eval_path);
if (targ_scope == 0) {
cerr << val->get_line() << ": warning: scope of " <<
path << "." << perm_name << " not found." << endl;
@@ -283,7 +227,7 @@ void NetScope::run_defparams(Design*des)
if (! flag) {
cerr << val->get_line() << ": warning: parameter "
<< perm_name << " not found in "
<< targ_scope->name() << "." << endl;
<< scope_path(targ_scope) << "." << endl;
}
}
@@ -390,18 +334,27 @@ void NetScope::evaluate_parameters(Design*des)
assert(expr);
switch (expr->expr_type()) {
case NetExpr::ET_REAL:
case IVL_VT_REAL:
if (! dynamic_cast<const NetECReal*>(expr)) {
cerr << (*cur).second.expr->get_line()
<< ": internal error: "
"unable to evaluate real parameter values: " <<
*expr << endl;
des->errors += 1;
continue;
NetExpr*nexpr = expr->eval_tree();
if (nexpr == 0) {
cerr << (*cur).second.expr->get_line()
<< ": internal error: "
<< "unable to evaluate real parameter value: "
<< *expr << endl;
des->errors += 1;
continue;
}
assert(nexpr);
delete expr;
(*cur).second.expr = nexpr;
}
break;
case NetExpr::ET_VECTOR:
case IVL_VT_LOGIC:
case IVL_VT_BOOL:
if (! dynamic_cast<const NetEConst*>(expr)) {
// Try to evaluate the expression.
@@ -481,68 +434,52 @@ const char* 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, hname_t path)
NetNet* Design::find_signal(NetScope*scope, pform_name_t path)
{
assert(scope);
char*key = path.remove_tail_name();
if (path.peek_name(0))
scope = find_scope(scope, path);
perm_string key = peek_tail_name(path);
path.pop_back();
if (! path.empty()) {
list<hname_t> eval_path = eval_scope_path(this, scope, path);
scope = find_scope(scope, eval_path);
}
while (scope) {
if (NetNet*net = scope->find_signal(key)) {
delete key;
if (NetNet*net = scope->find_signal(key))
return net;
}
if (scope->type() == NetScope::MODULE)
break;
scope = scope->parent();
}
delete key;
return 0;
}
NetFuncDef* Design::find_function(NetScope*scope, const hname_t&name)
NetFuncDef* Design::find_function(NetScope*scope, const pform_name_t&name)
{
assert(scope);
NetScope*func = find_scope(scope, name);
std::list<hname_t> eval_path = eval_scope_path(this, scope, name);
NetScope*func = find_scope(scope, eval_path);
if (func && (func->type() == NetScope::FUNC))
return func->func_def();
return 0;
}
NetFuncDef* Design::find_function(const hname_t&key)
NetScope* Design::find_task(NetScope*scope, const pform_name_t&name)
{
NetScope*func = find_scope(key);
if (func && (func->type() == NetScope::FUNC))
return func->func_def();
return 0;
}
NetScope* Design::find_task(NetScope*scope, const hname_t&name)
{
NetScope*task = find_scope(scope, name);
std::list<hname_t> eval_path = eval_scope_path(this, scope, name);
NetScope*task = find_scope(scope, eval_path);
if (task && (task->type() == NetScope::TASK))
return task;
return 0;
}
NetScope* Design::find_task(const hname_t&key)
{
NetScope*task = find_scope(key);
if (task && (task->type() == NetScope::TASK))
return task;
return 0;
}
void Design::add_node(NetNode*net)
{
assert(net->design_ == 0);
@@ -618,6 +555,34 @@ void Design::delete_process(NetProcTop*top)
/*
* $Log: net_design.cc,v $
* Revision 1.54 2007/06/05 04:18:09 steve
* Upward names may reference modules by module_name.
*
* Revision 1.53 2007/06/02 03:42:13 steve
* Properly evaluate scope path expressions.
*
* Revision 1.52 2007/05/24 04:07:12 steve
* Rework the heirarchical identifier parse syntax and pform
* to handle more general combinations of heirarch and bit selects.
*
* Revision 1.51 2007/04/26 03:06:22 steve
* Rework hname_t to use perm_strings.
*
* Revision 1.50 2006/08/08 05:11:37 steve
* Handle 64bit delay constants.
*
* Revision 1.49 2006/07/31 03:50:17 steve
* Add support for power in constant expressions.
*
* Revision 1.48 2005/11/27 05:56:20 steve
* Handle bit select of parameter with ranges.
*
* Revision 1.47 2005/09/14 02:53:14 steve
* Support bool expressions and compares handle them optimally.
*
* Revision 1.46 2005/07/11 16:56:50 steve
* Remove NetVariable and ivl_variable_t structures.
*
* Revision 1.45 2004/10/04 01:10:54 steve
* Clean up spurious trailing white space.
*
+6 -3
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: net_event.cc,v 1.26 2004/10/04 01:10:54 steve Exp $"
#ident "$Id: net_event.cc,v 1.27 2007/06/02 03:42:13 steve Exp $"
#endif
# include "config.h"
@@ -56,10 +56,10 @@ perm_string NetEvent::name() const
return name_;
}
string NetEvent::full_name() const
NetScope* NetEvent::scope()
{
assert(scope_);
return scope_->name() + "." + string(name_);
return scope_;
}
const NetScope* NetEvent::scope() const
@@ -449,6 +449,9 @@ NetProc* NetEvWait::statement()
/*
* $Log: net_event.cc,v $
* Revision 1.27 2007/06/02 03:42:13 steve
* Properly evaluate scope path expressions.
*
* Revision 1.26 2004/10/04 01:10:54 steve
* Clean up spurious trailing white space.
*
+89 -33
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: net_expr.cc,v 1.23 2004/10/04 01:10:54 steve Exp $"
#ident "$Id: net_expr.cc,v 1.27 2006/07/31 03:50:17 steve Exp $"
#endif
# include "config.h"
@@ -25,9 +25,12 @@
# include "compiler.h"
# include <iostream>
NetExpr::TYPE NetExpr::expr_type() const
/*
* the grand default data type is a logic vector.
*/
ivl_variable_type_t NetExpr::expr_type() const
{
return ET_VECTOR;
return IVL_VT_LOGIC;
}
/*
@@ -96,15 +99,15 @@ NetEBAdd* NetEBAdd::dup_expr() const
return result;
}
NetExpr::TYPE NetEBAdd::expr_type() const
ivl_variable_type_t NetEBAdd::expr_type() const
{
if (left_->expr_type() == ET_REAL)
return ET_REAL;
if (left_->expr_type() == IVL_VT_REAL)
return IVL_VT_REAL;
if (right_->expr_type() == ET_REAL)
return ET_REAL;
if (right_->expr_type() == IVL_VT_REAL)
return IVL_VT_REAL;
return ET_VECTOR;
return IVL_VT_LOGIC;
}
/*
@@ -161,6 +164,21 @@ bool NetEBComp::has_width() const
return true;
}
ivl_variable_type_t NetEBComp::expr_type() const
{
// Case compare always returns BOOL
if (op() == 'E' || op() == 'N')
return IVL_VT_BOOL;
if (left()->expr_type() == IVL_VT_LOGIC)
return IVL_VT_LOGIC;
if (right()->expr_type() == IVL_VT_LOGIC)
return IVL_VT_LOGIC;
return IVL_VT_BOOL;
}
NetEBDiv::NetEBDiv(char op, NetExpr*l, NetExpr*r)
: NetEBinary(op, l, r)
{
@@ -183,15 +201,15 @@ NetEBDiv* NetEBDiv::dup_expr() const
return result;
}
NetExpr::TYPE NetEBDiv::expr_type() const
ivl_variable_type_t NetEBDiv::expr_type() const
{
if (left_->expr_type() == ET_REAL)
return ET_REAL;
if (left_->expr_type() == IVL_VT_REAL)
return IVL_VT_REAL;
if (right_->expr_type() == ET_REAL)
return ET_REAL;
if (right_->expr_type() == IVL_VT_REAL)
return IVL_VT_REAL;
return ET_VECTOR;
return IVL_VT_LOGIC;
}
NetEBMult::NetEBMult(char op, NetExpr*l, NetExpr*r)
@@ -219,15 +237,49 @@ NetEBMult* NetEBMult::dup_expr() const
return result;
}
NetExpr::TYPE NetEBMult::expr_type() const
ivl_variable_type_t NetEBMult::expr_type() const
{
if (left_->expr_type() == ET_REAL)
return ET_REAL;
if (left_->expr_type() == IVL_VT_REAL)
return IVL_VT_REAL;
if (right_->expr_type() == ET_REAL)
return ET_REAL;
if (right_->expr_type() == IVL_VT_REAL)
return IVL_VT_REAL;
return ET_VECTOR;
return IVL_VT_LOGIC;
}
NetEBPow::NetEBPow(char op, NetExpr*l, NetExpr*r)
: NetEBinary(op, l, r)
{
assert(op == 'p');
expr_width(l->expr_width());
cast_signed(l->has_sign() || r->has_sign());
}
NetEBPow::~NetEBPow()
{
}
NetEBPow* NetEBPow::dup_expr() const
{
NetEBPow*result = new NetEBPow(op_, left_->dup_expr(),
right_->dup_expr());
result->set_line(*this);
return result;
}
ivl_variable_type_t NetEBPow::expr_type() const
{
if (right_->expr_type() == IVL_VT_REAL)
return IVL_VT_REAL;
if (left_->expr_type() == IVL_VT_REAL)
return IVL_VT_REAL;
if (left_->has_sign())
return IVL_VT_REAL;
if (right_->has_sign())
return IVL_VT_REAL;
return IVL_VT_LOGIC;
}
NetEBShift::NetEBShift(char op, NetExpr*l, NetExpr*r)
@@ -372,9 +424,9 @@ NetECReal* NetECReal::dup_expr() const
return tmp;
}
NetExpr::TYPE NetECReal::expr_type() const
ivl_variable_type_t NetECReal::expr_type() const
{
return ET_REAL;
return IVL_VT_REAL;
}
NetECRealParam::NetECRealParam(NetScope*s, perm_string n, const verireal&v)
@@ -450,15 +502,7 @@ bool NetESelect::has_width() const
return true;
}
bool NetESelect::set_width(unsigned w)
{
if (expr_width() == 1)
return true;
else
return false;
}
NetESFunc::NetESFunc(const char*n, NetExpr::TYPE t,
NetESFunc::NetESFunc(const char*n, ivl_variable_type_t t,
unsigned width, unsigned np)
: name_(0), type_(t)
{
@@ -509,13 +553,25 @@ NetExpr* NetESFunc::parm(unsigned idx)
return parms_[idx];
}
NetExpr::TYPE NetESFunc::expr_type() const
ivl_variable_type_t NetESFunc::expr_type() const
{
return type_;
}
/*
* $Log: net_expr.cc,v $
* Revision 1.27 2006/07/31 03:50:17 steve
* Add support for power in constant expressions.
*
* Revision 1.26 2005/11/26 00:35:43 steve
* More precise about r-value width of constants.
*
* Revision 1.25 2005/09/14 02:53:14 steve
* Support bool expressions and compares handle them optimally.
*
* Revision 1.24 2005/07/11 16:56:50 steve
* Remove NetVariable and ivl_variable_t structures.
*
* Revision 1.23 2004/10/04 01:10:54 steve
* Clean up spurious trailing white space.
*
+6 -102
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: net_force.cc,v 1.12 2004/02/18 17:11:56 steve Exp $"
#ident "$Id: net_force.cc,v 1.13 2004/12/11 02:31:26 steve Exp $"
#endif
# include "config.h"
@@ -33,110 +33,14 @@
# include "netlist.h"
# include <assert.h>
/*
* Construct the procedural continuous assignment statement. This is a
* bit different from a normal assignment because the the lval is only
* intermittently connected. The deassign in particular disconnects
* the signals when they are not being assigned anymore. Because of
* this, there is no other reference to the lval to make it stay put
* so we increment the eref.
*
* XXXX I'm not sure this is the right way. Perhaps I should create
* output pins to connect to the netlist? But that would cause the
* link ring to grow, and that is not quite correct either. Hmm...
*/
NetCAssign::NetCAssign(NetScope*s, perm_string n, NetNet*l)
: NetNode(s, n, l->pin_count()), lval_(l)
{
lval_->incr_eref();
for (unsigned idx = 0 ; idx < pin_count() ; idx += 1) {
pin(idx).set_dir(Link::INPUT);
pin(idx).set_name(perm_string::literal("I"), idx);
}
}
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());
return lval_->pin(idx);
}
NetDeassign::NetDeassign(NetNet*l)
: lval_(l)
{
lval_->incr_eref();
}
NetDeassign::~NetDeassign()
{
lval_->decr_eref();
}
const NetNet*NetDeassign::lval() const
{
return lval_;
}
NetForce::NetForce(NetScope*s, perm_string n, NetNet*l)
: NetNode(s, n, l->pin_count()), lval_(l)
{
lval_->incr_eref();
for (unsigned idx = 0 ; idx < pin_count() ; idx += 1) {
pin(idx).set_dir(Link::INPUT);
pin(idx).set_name(perm_string::literal("I"), idx);
}
}
NetForce::~NetForce()
{
lval_->decr_eref();
}
const Link& NetForce::lval_pin(unsigned idx) const
{
assert(idx < lval_->pin_count());
return lval_->pin(idx);
}
const NetNet* NetForce::lval() const
{
return lval_;
}
NetRelease::NetRelease(NetNet*l)
: lval_(l)
{
/* Put myself into a release list that the net is
keeping. This is so that the NetNet can detach itself if
and when it is deleted by the optimizer. */
release_next_ = lval_->release_list_;
lval_->release_list_ = this;
}
NetRelease::~NetRelease()
{
assert(lval_ == 0);
}
const NetNet*NetRelease::lval() const
{
return lval_;
}
/*
* $Log: net_force.cc,v $
* Revision 1.13 2004/12/11 02:31:26 steve
* Rework of internals to carry vectors through nexus instead
* of single bits. Make the ivl, tgt-vvp and vvp initial changes
* down this path.
*
* Revision 1.12 2004/02/18 17:11:56 steve
* Use perm_strings for named langiage items.
*
+67 -70
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: net_func.cc,v 1.6 2004/05/31 23:34:37 steve Exp $"
#ident "$Id: net_func.cc,v 1.10 2007/06/02 03:42:13 steve Exp $"
#endif
# include "config.h"
@@ -26,42 +26,25 @@
# include "PExpr.h"
# include <iostream>
static unsigned count_def_pins(const NetFuncDef*def)
{
assert(def->return_sig());
unsigned sum = def->return_sig()->pin_count();
for (unsigned idx = 0 ; idx < def->port_count() ; idx += 1)
sum += def->port(idx)->pin_count();
return sum;
}
/*
* To make a NetUserFunc device, make as many pins as there are ports
* in the function. Get the port count from the function definition,
* which accounts for all the inputs, plus one for the phantom output
* that is the result.
*/
NetUserFunc::NetUserFunc(NetScope*s, perm_string n, NetScope*d)
: NetNode(s, n, count_def_pins(d->func_def())),
: NetNode(s, n, d->func_def()->port_count()+1),
def_(d)
{
NetFuncDef*def = def_->func_def();
pin(0).set_dir(Link::OUTPUT);
pin(0).set_name(def_->basename(), 0);
unsigned port_wid = port_width(0);
for (unsigned idx = 0 ; idx < port_wid ; idx += 1) {
pin(idx).set_dir(Link::OUTPUT);
pin(idx).set_name(def_->basename(), idx);
}
for (unsigned idx = 1 ; idx < pin_count() ; idx += 1) {
unsigned pin_base = port_wid;
for (unsigned idx = 1 ; idx < port_count() ; idx += 1) {
const NetNet*port_sig = def->port(idx-1);
unsigned bits = port_width(idx);
for (unsigned bit = 0; bit < bits; bit += 1) {
pin(pin_base+bit).set_dir(Link::INPUT);
pin(pin_base+bit).set_name(port_sig->name(), bit);
pin(pin_base+bit).drive0(Link::HIGHZ);
pin(pin_base+bit).drive1(Link::HIGHZ);
}
pin_base += bits;
pin(idx).set_dir(Link::INPUT);
pin(idx).set_name(perm_string::literal("D"), idx-1);
pin(idx).drive0(Link::HIGHZ);
pin(idx).drive1(Link::HIGHZ);
}
}
@@ -69,11 +52,6 @@ NetUserFunc::~NetUserFunc()
{
}
unsigned NetUserFunc::port_count() const
{
return def_->func_def()->port_count() + 1;
}
unsigned NetUserFunc::port_width(unsigned port) const
{
NetFuncDef*def = def_->func_def();
@@ -82,44 +60,16 @@ unsigned NetUserFunc::port_width(unsigned port) const
if (port == 0) {
const NetNet*sig = def->return_sig();
assert(sig);
return sig->pin_count();
return sig->vector_width();
}
port -= 1;
assert(port < def->port_count());
const NetNet*port_sig = def->port(port);
return port_sig->pin_count();
return port_sig->vector_width();
}
Link& NetUserFunc::port_pin(unsigned port, unsigned idx)
{
NetFuncDef*def = def_->func_def();
unsigned pin_base = 0;
const NetNet*port_sig;
if (port == 0)
return pin(idx);
port_sig = def->return_sig();
pin_base += port_sig->pin_count();
port -= 1;
assert(port < def->port_count());
for (unsigned port_idx = 0 ; port_idx < port ; port_idx += 1) {
port_sig = def->port(port_idx);
pin_base += port_sig->pin_count();
}
port_sig = def->port(port);
assert(idx < port_sig->pin_count());
assert((pin_base+idx) < pin_count());
return pin(pin_base+idx);
}
const NetScope* NetUserFunc::def() const
{
return def_;
@@ -145,14 +95,14 @@ bool PECallFunction::check_call_matches_definition_(Design*des, NetScope*dscope)
if (dscope->type() != NetScope::FUNC) {
cerr << get_line() << ": error: Attempt to call scope "
<< dscope->name() << " as a function." << endl;
<< scope_path(dscope) << " as a function." << endl;
des->errors += 1;
return false;
}
if (parms_count != dscope->func_def()->port_count()) {
cerr << get_line() << ": error: Function " << dscope->name()
<< " expects " << (dscope->func_def()->port_count()-1)
cerr << get_line() << ": error: Function " << scope_path(dscope)
<< " expects " << (dscope->func_def()->port_count())
<< " arguments, you passed " << parms_count << "."
<< endl;
des->errors += 1;
@@ -162,8 +112,55 @@ bool PECallFunction::check_call_matches_definition_(Design*des, NetScope*dscope)
return true;
}
NetSysFunc::NetSysFunc(NetScope*s, perm_string n,
const struct sfunc_return_type*def,
unsigned ports)
: NetNode(s, n, ports)
{
def_ = def;
pin(0).set_dir(Link::OUTPUT);
pin(0).set_name(perm_string::literal("Q"), 0);
for (unsigned idx = 1 ; idx < pin_count() ; idx += 1) {
pin(idx).set_dir(Link::INPUT);
pin(idx).set_name(perm_string::literal("D"), idx-1);
pin(idx).drive0(Link::HIGHZ);
pin(idx).drive1(Link::HIGHZ);
}
}
NetSysFunc::~NetSysFunc()
{
}
const char*NetSysFunc::func_name() const
{
return def_->name;
}
unsigned NetSysFunc::vector_width() const
{
return def_->wid;
}
/*
* $Log: net_func.cc,v $
* Revision 1.10 2007/06/02 03:42:13 steve
* Properly evaluate scope path expressions.
*
* Revision 1.9 2007/04/17 04:17:47 steve
* Fix argument count in function error message.
*
* Revision 1.8 2006/06/18 04:15:50 steve
* Add support for system functions in continuous assignments.
*
* Revision 1.7 2005/03/18 02:56:03 steve
* Add support for LPM_UFUNC user defined functions.
*
* Revision 1.6 2004/05/31 23:34:37 steve
* Rewire/generalize parsing an elaboration of
* function return values to allow for better
+62 -15
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: net_link.cc,v 1.14 2004/02/18 17:11:56 steve Exp $"
#ident "$Id: net_link.cc,v 1.21 2007/06/02 03:42:13 steve Exp $"
#endif
# include "config.h"
@@ -58,7 +58,10 @@ void connect(Nexus*l, Link&r)
void connect(Link&l, Link&r)
{
assert(&l != &r);
connect(l.nexus_, r);
if (r.is_linked() && !l.is_linked())
connect(r.nexus_, l);
else
connect(l.nexus_, r);
}
Link::Link()
@@ -301,18 +304,42 @@ const Link* Nexus::first_nlink() const
return list_;
}
void* Nexus::t_cookie() const
ivl_nexus_t Nexus::t_cookie() const
{
return t_cookie_;
}
void* Nexus::t_cookie(void*val)const
ivl_nexus_t Nexus::t_cookie(ivl_nexus_t val)const
{
void*tmp = t_cookie_;
ivl_nexus_t tmp = t_cookie_;
t_cookie_ = val;
return tmp;
}
unsigned Nexus::vector_width() const
{
for (const Link*cur = first_nlink() ; cur ; cur = cur->next_nlink()) {
const NetNet*sig = dynamic_cast<const NetNet*>(cur->get_obj());
if (sig == 0)
continue;
return sig->vector_width();
}
return 0;
}
NetNet* Nexus::pick_any_net()
{
for (Link*cur = first_nlink() ; cur ; cur = cur->next_nlink()) {
NetNet*sig = dynamic_cast<NetNet*>(cur->get_obj());
if (sig != 0)
return sig;
}
return 0;
}
const char* Nexus::name() const
{
if (name_)
@@ -364,7 +391,7 @@ const char* Nexus::name() const
}
assert(sig);
ostringstream tmp;
tmp << sig->name();
tmp << scope_path(sig->scope()) << "." << sig->name();
if (sig->pin_count() > 1)
tmp << "<" << pin << ">";
@@ -407,13 +434,14 @@ void NexusSet::add(Nexus*that)
}
unsigned ptr = bsearch_(that);
if ((ptr < nitems_) && (items_[ptr] == that))
if (ptr < nitems_) {
assert(items_[ptr] == that);
return;
}
assert(ptr == nitems_);
items_ = (Nexus**)realloc(items_, (nitems_+1) * sizeof(Nexus*));
for (unsigned idx = nitems_ ; idx > ptr ; idx -= 1)
items_[idx] = items_[idx-1];
items_[ptr] = that;
nitems_ += 1;
}
@@ -430,7 +458,7 @@ void NexusSet::rem(Nexus*that)
return;
unsigned ptr = bsearch_(that);
if ((ptr >= nitems_) || (items_[ptr] != that))
if (ptr >= nitems_)
return;
if (nitems_ == 1) {
@@ -462,10 +490,8 @@ Nexus* NexusSet::operator[] (unsigned idx) const
unsigned NexusSet::bsearch_(Nexus*that) const
{
for (unsigned idx = 0 ; idx < nitems_ ; idx += 1) {
if (items_[idx] < that)
continue;
return idx;
if (items_[idx] == that)
return idx;
}
return nitems_;
@@ -499,6 +525,27 @@ bool NexusSet::intersect(const NexusSet&that) const
/*
* $Log: net_link.cc,v $
* Revision 1.21 2007/06/02 03:42:13 steve
* Properly evaluate scope path expressions.
*
* Revision 1.20 2007/03/26 18:17:50 steve
* Remove pretense of general use for t_cookie.
*
* Revision 1.19 2006/02/02 02:43:58 steve
* Allow part selects of memory words in l-values.
*
* Revision 1.18 2005/09/25 23:40:11 steve
* Simplify NexusSet set handling.
*
* Revision 1.17 2005/06/13 23:22:37 steve
* Fix compile errors.
*
* Revision 1.16 2005/04/24 23:44:02 steve
* Update DFF support to new data flow.
*
* Revision 1.15 2005/01/09 20:16:01 steve
* Use PartSelect/PV and VP to handle part selects through ports.
*
* Revision 1.14 2004/02/18 17:11:56 steve
* Use perm_strings for named langiage items.
*
+32 -35
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2000-2004 Stephen Williams (steve@icarus.com)
* Copyright (c) 2000-2005 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: net_modulo.cc,v 1.7 2004/02/18 17:11:56 steve Exp $"
#ident "$Id: net_modulo.cc,v 1.9 2005/09/15 22:54:47 steve Exp $"
#endif
# include "config.h"
@@ -30,25 +30,22 @@
# include "netlist.h"
# include "compiler.h"
/*
* 0 -- Result
* 1 -- DataA
* 2 -- DataB
*/
NetModulo::NetModulo(NetScope*s, perm_string n, unsigned wr,
unsigned wa, unsigned wb)
: NetNode(s, n, wr+wa+wb),
: NetNode(s, n, 3),
width_r_(wr), width_a_(wa), width_b_(wb)
{
unsigned p = 0;
for (unsigned idx = 0 ; idx < width_r_ ; idx += 1, p += 1) {
pin(p).set_dir(Link::OUTPUT);
pin(p).set_name(perm_string::literal("Result"), idx);
}
for (unsigned idx = 0 ; idx < width_a_ ; idx += 1, p += 1) {
pin(p).set_dir(Link::INPUT);
pin(p).set_name(perm_string::literal("DataA"), idx);
}
for (unsigned idx = 0 ; idx < width_b_ ; idx += 1, p += 1) {
pin(p).set_dir(Link::INPUT);
pin(p).set_name(perm_string::literal("DataB"), idx);
}
pin(0).set_dir(Link::OUTPUT);
pin(0).set_name(perm_string::literal("Result"), 0);
pin(1).set_dir(Link::INPUT);
pin(1).set_name(perm_string::literal("DataA"), 0);
pin(2).set_dir(Link::INPUT);
pin(2).set_name(perm_string::literal("DataB"), 0);
}
NetModulo::~NetModulo()
@@ -70,44 +67,44 @@ unsigned NetModulo::width_b() const
return width_b_;
}
Link& NetModulo::pin_Result(unsigned idx)
Link& NetModulo::pin_Result()
{
assert(idx < width_r_);
return pin(idx);
return pin(0);
}
const Link& NetModulo::pin_Result(unsigned idx) const
const Link& NetModulo::pin_Result() const
{
assert(idx < width_r_);
return pin(idx);
return pin(0);
}
Link& NetModulo::pin_DataA(unsigned idx)
Link& NetModulo::pin_DataA()
{
assert(idx < width_a_);
return pin(idx+width_r_);
return pin(1);
}
const Link& NetModulo::pin_DataA(unsigned idx) const
const Link& NetModulo::pin_DataA() const
{
assert(idx < width_a_);
return pin(idx+width_r_);
return pin(1);
}
Link& NetModulo::pin_DataB(unsigned idx)
Link& NetModulo::pin_DataB()
{
assert(idx < width_b_);
return pin(idx+width_r_+width_a_);
return pin(2);
}
const Link& NetModulo::pin_DataB(unsigned idx) const
const Link& NetModulo::pin_DataB() const
{
assert(idx < width_b_);
return pin(idx+width_r_+width_a_);
return pin(2);
}
/*
* $Log: net_modulo.cc,v $
* Revision 1.9 2005/09/15 22:54:47 steve
* Fix bug configuring NetModulo pins.
*
* Revision 1.8 2005/03/12 06:43:35 steve
* Update support for LPM_MOD.
*
* Revision 1.7 2004/02/18 17:11:56 steve
* Use perm_strings for named langiage items.
*
+31 -25
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: net_nex_input.cc,v 1.12 2004/09/04 04:24:15 steve Exp $"
#ident "$Id: net_nex_input.cc,v 1.16 2007/01/16 05:44:15 steve Exp $"
#endif
# include "config.h"
@@ -54,15 +54,6 @@ NexusSet* NetEBinary::nex_input()
return result;
}
NexusSet* NetEBitSel::nex_input()
{
NexusSet*result = sig_->nex_input();
NexusSet*tmp = idx_->nex_input();
result->add(*tmp);
delete tmp;
return result;
}
NexusSet* NetEConcat::nex_input()
{
NexusSet*result = parms_[0]->nex_input();
@@ -87,12 +78,6 @@ NexusSet* NetECReal::nex_input()
return new NexusSet;
}
NexusSet* NetEMemory::nex_input()
{
NexusSet*result = idx_->nex_input();
return result;
}
/*
* A parameter by definition has no inputs. It represents a constant
* value, even if that value is a constant expression.
@@ -177,17 +162,21 @@ NexusSet* NetEUnary::nex_input()
return expr_->nex_input();
}
NexusSet* NetEVariable::nex_input()
{
return new NexusSet;
}
NexusSet* NetAssign_::nex_input()
{
if (bmux_ == 0)
return new NexusSet;
else
return bmux_->nex_input();
NexusSet*result = new NexusSet;
if (word_) {
NexusSet*tmp = word_->nex_input();
result->add(*tmp);
delete tmp;
}
if (base_) {
NexusSet*tmp = base_->nex_input();
result->add(*tmp);
delete tmp;
}
return result;
}
NexusSet* NetAssignBase::nex_input()
@@ -398,6 +387,23 @@ NexusSet* NetWhile::nex_input()
/*
* $Log: net_nex_input.cc,v $
* Revision 1.16 2007/01/16 05:44:15 steve
* Major rework of array handling. Memories are replaced with the
* more general concept of arrays. The NetMemory and NetEMemory
* classes are removed from the ivl core program, and the IVL_LPM_RAM
* lpm type is removed from the ivl_target API.
*
* Revision 1.15 2006/04/16 00:15:43 steve
* Fix part selects in l-values.
*
* Revision 1.14 2005/07/11 16:56:50 steve
* Remove NetVariable and ivl_variable_t structures.
*
* Revision 1.13 2005/01/24 05:28:30 steve
* Remove the NetEBitSel and combine all bit/part select
* behavior into the NetESelect node and IVL_EX_SELECT
* ivl_target expression type.
*
* Revision 1.12 2004/09/04 04:24:15 steve
* PR1026: assignment statements can have sensitivities in the l-values.
*
+24 -5
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: net_nex_output.cc,v 1.11 2004/09/16 03:17:33 steve Exp $"
#ident "$Id: net_nex_output.cc,v 1.14 2007/04/17 04:34:23 steve Exp $"
#endif
# include "config.h"
@@ -47,10 +47,7 @@ void NetAssignBase::nex_output(NexusSet&out)
{
for (NetAssign_*cur = lval_ ; cur ; cur = cur->more) {
if (NetNet*lsig = cur->sig()) {
for (unsigned idx = 0 ; idx < cur->lwidth() ; idx += 1) {
unsigned off = cur->get_loff() + idx;
out.add(lsig->pin(off).nexus());
}
out.add(lsig->pin(0).nexus());
} else {
/* Quoting from netlist.h comments for class NetMemory:
* "This is not a node because memory objects can only be
@@ -80,6 +77,10 @@ void NetCase::nex_output(NexusSet&out)
{
for (unsigned idx = 0 ; idx < nitems_ ; idx += 1) {
// Empty statements clearly have no output.
if (items_[idx].statement == 0)
continue;
assert(items_[idx].statement);
items_[idx].statement->nex_output(out);
}
@@ -114,6 +115,15 @@ void NetSTask::nex_output(NexusSet&out)
{
}
/*
* Consider a task call to not have any outputs. This is not quite
* right, we should be listing as outputs all the output ports, but for
* the purposes that this method is used, this will do for now.
*/
void NetUTask::nex_output(NexusSet&out)
{
}
void NetWhile::nex_output(NexusSet&out)
{
if (proc_ != 0)
@@ -122,6 +132,15 @@ void NetWhile::nex_output(NexusSet&out)
/*
* $Log: net_nex_output.cc,v $
* Revision 1.14 2007/04/17 04:34:23 steve
* Fix handling calls to tasks in combinational always block
*
* Revision 1.13 2007/04/05 01:53:52 steve
* Probe of case statement inputs can skip nul statements.
*
* Revision 1.12 2005/02/14 04:58:50 steve
* l-value input may be a vector.
*
* Revision 1.11 2004/09/16 03:17:33 steve
* net_output handles l-value concatenations.
*
+6 -3
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: net_proc.cc,v 1.6 2002/08/12 01:34:59 steve Exp $"
#ident "$Id: net_proc.cc,v 1.7 2006/08/08 05:11:37 steve Exp $"
#endif
# include "config.h"
@@ -131,7 +131,7 @@ NetForever::~NetForever()
delete statement_;
}
NetPDelay::NetPDelay(unsigned long d, NetProc*st)
NetPDelay::NetPDelay(uint64_t d, NetProc*st)
: delay_(d), expr_(0), statement_(st)
{
}
@@ -146,7 +146,7 @@ NetPDelay::~NetPDelay()
if (expr_) delete expr_;
}
unsigned long NetPDelay::delay() const
uint64_t NetPDelay::delay() const
{
assert(expr_ == 0);
return delay_;
@@ -177,6 +177,9 @@ const NetExpr* NetRepeat::expr() const
/*
* $Log: net_proc.cc,v $
* Revision 1.7 2006/08/08 05:11:37 steve
* Handle 64bit delay constants.
*
* Revision 1.6 2002/08/12 01:34:59 steve
* conditional ident string using autoconfig.
*
+38 -104
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: net_scope.cc,v 1.33 2004/10/04 01:10:54 steve Exp $"
#ident "$Id: net_scope.cc,v 1.38 2007/06/02 03:42:13 steve Exp $"
#endif
# include "config.h"
@@ -35,13 +35,11 @@
* in question.
*/
NetScope::NetScope(NetScope*up, perm_string n, NetScope::TYPE t)
NetScope::NetScope(NetScope*up, const hname_t&n, NetScope::TYPE t)
: type_(t), up_(up), sib_(0), sub_(0)
{
memories_ = 0;
signals_ = 0;
events_ = 0;
vars_ = 0;
lcounter_ = 0;
if (up) {
@@ -133,17 +131,25 @@ NetExpr* NetScope::set_localparam(perm_string key, NetExpr*expr)
* perm_string::literal method to fake the compiler into doing the
* compare without actually creating a perm_string.
*/
const NetExpr* NetScope::get_parameter(const char* key) const
const NetExpr* NetScope::get_parameter(const char* key,
const NetExpr*&msb,
const NetExpr*&lsb) const
{
map<perm_string,param_expr_t>::const_iterator idx;
idx = parameters.find(perm_string::literal(key));
if (idx != parameters.end())
if (idx != parameters.end()) {
msb = (*idx).second.msb;
lsb = (*idx).second.lsb;
return (*idx).second.expr;
}
idx = localparams.find(perm_string::literal(key));
if (idx != localparams.end())
if (idx != localparams.end()) {
msb = (*idx).second.msb;
lsb = (*idx).second.lsb;
return (*idx).second.expr;
}
return 0;
}
@@ -235,15 +241,7 @@ NetNet::Type NetScope::default_nettype() const
perm_string NetScope::basename() const
{
return name_;
}
string NetScope::name() const
{
if (up_)
return up_->name() + "." + string(name_);
else
return string(name_);
return name_.peek_name();
}
void NetScope::add_event(NetEvent*ev)
@@ -283,15 +281,6 @@ NetEvent* NetScope::find_event(const char*name)
return 0;
}
NetVariable* NetScope::find_variable(const char*name)
{
for (NetVariable*cur = vars_; cur ; cur = cur->snext_)
if (strcmp(cur->basename(), name) == 0)
return cur;
return 0;
}
void NetScope::add_signal(NetNet*net)
{
if (signals_ == 0) {
@@ -339,89 +328,16 @@ NetNet* NetScope::find_signal(const char*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) {
mem->snext_ = mem;
mem->sprev_ = mem;
} else {
mem->snext_ = memories_->snext_;
mem->sprev_ = memories_;
mem->snext_->sprev_ = mem;
mem->sprev_->snext_ = mem;
}
memories_ = mem;
mem->scope_ = this;
}
void NetScope::rem_memory(NetMemory*mem)
{
assert(mem->scope_ == this);
if (memories_ == mem)
memories_ = mem->sprev_;
if (memories_ == mem) {
memories_ = 0;
} else {
mem->sprev_->snext_ = mem->snext_;
mem->snext_->sprev_ = mem->sprev_;
}
mem->scope_ = 0;
}
NetMemory* NetScope::find_memory(const string&key)
{
if (memories_ == 0)
return 0;
NetMemory*cur = memories_;
do {
if (cur->name() == key.c_str())
return cur;
cur = cur->sprev_;
} while (cur != memories_);
return 0;
}
void NetScope::add_variable(NetVariable*var)
{
assert(var->scope_ == 0);
var->scope_ = this;
var->snext_ = vars_;
vars_ = var;
}
/*
* This method locates a child scope by name. The name is the simple
* name of the child, no hierarchy is searched.
*/
NetScope* NetScope::child(const char*name)
NetScope* NetScope::child(const hname_t&name)
{
if (sub_ == 0) return 0;
NetScope*cur = sub_;
while (strcmp(cur->name_, name) != 0) {
while (cur->name_ != name) {
if (cur->sib_ == 0) return 0;
cur = cur->sib_;
}
@@ -429,12 +345,12 @@ NetScope* NetScope::child(const char*name)
return cur;
}
const NetScope* NetScope::child(const char*name) const
const NetScope* NetScope::child(const hname_t&name) const
{
if (sub_ == 0) return 0;
NetScope*cur = sub_;
while (strcmp(cur->name_, name) != 0) {
while (cur->name_ != name) {
if (cur->sib_ == 0) return 0;
cur = cur->sib_;
}
@@ -458,15 +374,33 @@ perm_string NetScope::local_symbol()
res << "_s" << (lcounter_++);
return lex_strings.make(res.str());
}
#if 0
string NetScope::local_hsymbol()
{
return string(name()) + "." + string(local_symbol());
}
#endif
/*
* $Log: net_scope.cc,v $
* Revision 1.38 2007/06/02 03:42:13 steve
* Properly evaluate scope path expressions.
*
* Revision 1.37 2007/04/26 03:06:22 steve
* Rework hname_t to use perm_strings.
*
* Revision 1.36 2007/01/16 05:44:15 steve
* Major rework of array handling. Memories are replaced with the
* more general concept of arrays. The NetMemory and NetEMemory
* classes are removed from the ivl core program, and the IVL_LPM_RAM
* lpm type is removed from the ivl_target API.
*
* Revision 1.35 2005/11/27 05:56:20 steve
* Handle bit select of parameter with ranges.
*
* Revision 1.34 2005/07/11 16:56:50 steve
* Remove NetVariable and ivl_variable_t structures.
*
* Revision 1.33 2004/10/04 01:10:54 steve
* Clean up spurious trailing white space.
*
-82
View File
@@ -1,82 +0,0 @@
/*
* Copyright (c) 2003 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: net_variable.cc,v 1.3 2004/02/19 07:06:57 steve Exp $"
#endif
# include "config.h"
# include "netlist.h"
NetVariable::NetVariable(perm_string name)
{
name_ = name;
scope_ = 0;
snext_ = 0;
}
NetVariable::~NetVariable()
{
}
perm_string NetVariable::basename() const
{
return name_;
}
NetScope* NetVariable::scope()
{
return scope_;
}
const NetScope* NetVariable::scope() const
{
return scope_;
}
NetEVariable::NetEVariable(NetVariable*v)
: var_(v)
{
}
NetEVariable::~NetEVariable()
{
}
NetExpr::TYPE NetEVariable::expr_type() const
{
return NetExpr::ET_REAL;
}
const NetVariable* NetEVariable::variable() const
{
return var_;
}
/*
* $Log: net_variable.cc,v $
* Revision 1.3 2004/02/19 07:06:57 steve
* LPM, logic and Variables have perm_string names.
*
* Revision 1.2 2003/03/06 00:28:42 steve
* All NetObj objects have lex_string base names.
*
* Revision 1.1 2003/01/28 16:23:27 steve
* Add missing net_variable.cc to CVS.
*
*/
+904 -740
View File
File diff suppressed because it is too large Load Diff
+887 -542
View File
File diff suppressed because it is too large Load Diff
+105 -27
View File
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: netmisc.cc,v 1.8 2004/02/20 18:53:35 steve Exp $"
#ident "$Id: netmisc.cc,v 1.14 2007/06/02 03:42:13 steve Exp $"
#endif
# include "config.h"
@@ -25,12 +25,14 @@
# include "netlist.h"
# include "netmisc.h"
# include "PExpr.h"
# include "pform_types.h"
# include "ivl_assert.h"
NetNet* add_to_net(Design*des, NetNet*sig, long val)
{
if (val == 0)
return sig;
#if 0
NetScope*scope = sig->scope();
unsigned long abs_val = (val >= 0)? val : (-val);
unsigned width = sig->pin_count();
@@ -70,16 +72,67 @@ NetNet* add_to_net(Design*des, NetNet*sig, long val)
des->add_node(val_c);
return res;
#else
cerr << sig->get_line() << ": XXXX: Forgot how to implement add_to_net" << endl;
return 0;
#endif
}
NetExpr* elab_and_eval(Design*des, NetScope*scope, const PExpr*pe)
/*
* Add a signed constant to an existing expression. Generate a new
* NetEBAdd node that has the input expression and an expression made
* from the constant value.
*/
NetExpr* make_add_expr(NetExpr*expr, long val)
{
NetExpr*tmp = pe->elaborate_expr(des, scope);
if (val == 0)
return expr;
// If the value to be added is <0, then instead generate a
// SUBTRACT node and turn the value positive.
char add_op = '+';
if (val < 0) {
add_op = '-';
val = -val;
}
verinum val_v (val);
val_v.has_sign(true);
if (expr->has_width()) {
val_v = verinum(val_v, expr->expr_width());
}
NetEConst*val_c = new NetEConst(val_v);
val_c->set_line(*expr);
NetEBAdd*res = new NetEBAdd(add_op, expr, val_c);
res->set_line(*expr);
return res;
}
NetExpr* make_sub_expr(long val, NetExpr*expr)
{
verinum val_v (val, expr->expr_width());
val_v.has_sign(true);
NetEConst*val_c = new NetEConst(val_v);
val_c->set_line(*expr);
NetEBAdd*res = new NetEBAdd('-', val_c, expr);
res->set_line(*expr);
return res;
}
NetExpr* elab_and_eval(Design*des, NetScope*scope,
const PExpr*pe, int expr_wid, int prune_width)
{
NetExpr*tmp = pe->elaborate_expr(des, scope, expr_wid, false);
if (tmp == 0)
return 0;
if (NetExpr*tmp2 = tmp->eval_tree()) {
if (NetExpr*tmp2 = tmp->eval_tree(prune_width)) {
delete tmp;
tmp = tmp2;
}
@@ -87,33 +140,58 @@ NetExpr* elab_and_eval(Design*des, NetScope*scope, const PExpr*pe)
return tmp;
}
std::list<hname_t> eval_scope_path(Design*des, NetScope*scope,
const pform_name_t&path)
{
list<hname_t> res;
typedef pform_name_t::const_iterator pform_path_it;
for (pform_path_it cur = path.begin() ; cur != path.end(); cur++) {
const name_component_t&comp = *cur;
if (comp.index.empty()) {
res.push_back(hname_t(comp.name));
continue;
}
assert(comp.index.size() == 1);
const index_component_t&index = comp.index.front();
assert(index.sel == index_component_t::SEL_BIT);
NetExpr*tmp = elab_and_eval(des, scope, index.msb, -1);
ivl_assert(*index.msb, tmp);
if (NetEConst*ctmp = dynamic_cast<NetEConst*>(tmp)) {
res.push_back(hname_t(comp.name, ctmp->value().as_long()));
delete ctmp;
continue;
}
return res;
}
return res;
}
/*
* $Log: netmisc.cc,v $
* Revision 1.8 2004/02/20 18:53:35 steve
* Addtrbute keys are perm_strings.
* Revision 1.14 2007/06/02 03:42:13 steve
* Properly evaluate scope path expressions.
*
* Revision 1.7 2004/02/18 17:11:57 steve
* Use perm_strings for named langiage items.
* Revision 1.13 2007/03/08 05:30:03 steve
* Limit the calculated widths of constants.
*
* Revision 1.6 2003/03/06 00:28:42 steve
* All NetObj objects have lex_string base names.
* Revision 1.12 2006/06/02 04:48:50 steve
* Make elaborate_expr methods aware of the width that the context
* requires of it. In the process, fix sizing of the width of unary
* minus is context determined sizes.
*
* Revision 1.5 2003/02/26 01:29:24 steve
* LPM objects store only their base names.
*
* Revision 1.4 2002/08/31 03:48:50 steve
* Fix reverse bit ordered bit select in continuous assignment.
*
* Revision 1.3 2002/08/12 01:35:00 steve
* conditional ident string using autoconfig.
*
* 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.
* Revision 1.11 2005/04/08 04:50:31 steve
* Don not give to make_add express an unwanted width.
*
* Revision 1.10 2005/01/24 05:28:31 steve
* Remove the NetEBitSel and combine all bit/part select
* behavior into the NetESelect node and IVL_EX_SELECT
* ivl_target expression type.
*/
+103 -6
View File
@@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: netmisc.h,v 1.19 2004/03/07 20:04:11 steve Exp $"
#ident "$Id: netmisc.h,v 1.31 2007/06/02 03:42:13 steve Exp $"
#endif
# include "netlist.h"
@@ -33,13 +33,28 @@
* If the symbol was not found, return 0. The output arguments
* get 0 except for the pointer to the object that represents
* the located symbol.
*
* The ex1 and ex2 output arguments are extended results. If the
* symbol is a parameter (par!=0) then ex1 is the msb expression and
* ex2 is the lsb expression for the range. If there is no range, then
* these values are set to 0.
*/
extern NetScope* symbol_search(Design*des, NetScope*start, hname_t path,
extern NetScope* symbol_search(Design*des,
NetScope*start, pform_name_t path,
NetNet*&net, /* net/reg */
NetMemory*&mem, /* memory */
NetVariable*&var, /* real/realtime */
const NetExpr*&par,/* parameter */
NetEvent*&eve /* named event */);
NetEvent*&eve, /* named event */
const NetExpr*&ex1, const NetExpr*&ex2);
inline NetScope* symbol_search(Design*des,
NetScope*start, const pform_name_t&path,
NetNet*&net, /* net/reg */
const NetExpr*&par,/* parameter */
NetEvent*&eve /* named event */)
{
const NetExpr*ex1, *ex2;
return symbol_search(des, start, path, net, par, eve, ex1, ex2);
}
/*
* This function transforms an expression by padding the high bits
@@ -50,6 +65,15 @@ extern NetScope* symbol_search(Design*des, NetScope*start, hname_t path,
extern NetExpr*pad_to_width(NetExpr*expr, unsigned wid);
extern NetNet*pad_to_width(Design*des, NetNet*n, unsigned w);
extern NetNet*pad_to_width_signed(Design*des, NetNet*n, unsigned w);
/*
* This function transforms an expression by cropping the high bits
* off with a part select. The result has the width w passed in. This
* function does not pad, use pad_to_width if padding is desired.
*/
extern NetNet*crop_to_width(Design*des, NetNet*n, unsigned w);
/*
* This function takes as input a NetNet signal and adds a constant
* value to it. If the val is 0, then simply return sig. Otherwise,
@@ -57,6 +81,23 @@ extern NetNet*pad_to_width(Design*des, NetNet*n, unsigned w);
*/
extern NetNet*add_to_net(Design*des, NetNet*sig, long val);
/*
* These functions make various sorts of expressions, given operands
* of certain type. The order of the operands is preserved in cases
* where order matters.
*
* make_add_expr
* Make a NetEBAdd expression with <expr> the first argument and
* <val> the second. This may get turned into a subtract if <val> is
* less then zero. If val is exactly zero, then return <expr> as is.
*
* make_sub_expr
* Make a NetEBAdd(subtract) node that subtracts the given
* expression from the integer value.
*/
extern NetExpr*make_add_expr(NetExpr*expr, long val);
extern NetExpr*make_sub_expr(long val, NetExpr*expr);
/*
* In some cases the lval is accessible as a pointer to the head of
* a list of NetAssign_ objects. This function returns the width of
@@ -69,12 +110,68 @@ extern unsigned count_lval_width(const class NetAssign_*first);
* right away. If the expression can be evaluated, this returns a
* constant expression. If it cannot be evaluated, it returns whatever
* it can. If the expression cannot be elaborated, return 0.
*
* The expr_width is the width of the context where the expression is
* being elaborated, or -1 if the expression is self-determined width.
*
* Also, the prune_width is the maximum width of the result, and it
* passed to the eval_tree method of the expression to limit constant
* results if possible.
*/
class PExpr;
extern NetExpr* elab_and_eval(Design*des, NetScope*scope, const PExpr*pe);
extern NetExpr* elab_and_eval(Design*des, NetScope*scope,
const PExpr*pe, int expr_wid,
int prune_width =-1);
extern std::list<hname_t> eval_scope_path(Design*des, NetScope*scope,
const pform_name_t&path);
/*
* $Log: netmisc.h,v $
* Revision 1.31 2007/06/02 03:42:13 steve
* Properly evaluate scope path expressions.
*
* Revision 1.30 2007/05/24 04:07:12 steve
* Rework the heirarchical identifier parse syntax and pform
* to handle more general combinations of heirarch and bit selects.
*
* Revision 1.29 2007/03/08 05:30:03 steve
* Limit the calculated widths of constants.
*
* Revision 1.28 2007/02/26 19:49:49 steve
* Spelling fixes (larry doolittle)
*
* Revision 1.27 2007/01/16 05:44:15 steve
* Major rework of array handling. Memories are replaced with the
* more general concept of arrays. The NetMemory and NetEMemory
* classes are removed from the ivl core program, and the IVL_LPM_RAM
* lpm type is removed from the ivl_target API.
*
* Revision 1.26 2006/09/28 00:29:49 steve
* Allow specparams as constants in expressions.
*
* Revision 1.25 2006/06/02 04:48:50 steve
* Make elaborate_expr methods aware of the width that the context
* requires of it. In the process, fix sizing of the width of unary
* minus is context determined sizes.
*
* Revision 1.24 2005/11/27 05:56:20 steve
* Handle bit select of parameter with ranges.
*
* Revision 1.23 2005/07/11 16:56:51 steve
* Remove NetVariable and ivl_variable_t structures.
*
* Revision 1.22 2005/05/24 01:44:28 steve
* Do sign extension of structuran nets.
*
* Revision 1.21 2005/04/24 23:44:02 steve
* Update DFF support to new data flow.
*
* Revision 1.20 2005/01/24 05:28:31 steve
* Remove the NetEBitSel and combine all bit/part select
* behavior into the NetESelect node and IVL_EX_SELECT
* ivl_target expression type.
*
* Revision 1.19 2004/03/07 20:04:11 steve
* MOre thorough use of elab_and_eval function.
*

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